summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl_Grid.H3
-rw-r--r--fluid/Fl_Grid_Type.cxx48
-rw-r--r--fluid/Fl_Grid_Type.h2
-rw-r--r--fluid/factory.cxx8
-rw-r--r--src/Fl_Grid.cxx8
5 files changed, 67 insertions, 2 deletions
diff --git a/FL/Fl_Grid.H b/FL/Fl_Grid.H
index d7d90e352..b240ca95b 100644
--- a/FL/Fl_Grid.H
+++ b/FL/Fl_Grid.H
@@ -311,6 +311,9 @@ public:
void row_gap(const int *value, size_t size);
int row_gap(int row) const;
+ int computed_col_width(int col) const;
+ int computed_row_height(int row) const;
+
/**
Enable or disable drawing of the grid helper lines for visualization.
diff --git a/fluid/Fl_Grid_Type.cxx b/fluid/Fl_Grid_Type.cxx
index 4ce0991d9..1ec831c7c 100644
--- a/fluid/Fl_Grid_Type.cxx
+++ b/fluid/Fl_Grid_Type.cxx
@@ -421,18 +421,62 @@ static void move_cell(Fl_Grid *grid, Fl_Widget *child, int to_row, int to_col) {
if (new_cell) new_cell->minimum_size(w, h);
}
+void Fl_Grid_Type::insert_child_at(Fl_Widget *child, int x, int y) {
+ Fl_Grid *grid = (Fl_Grid*)o;
+ int row = -1, col = -1, ml, mt, grg, gcg;
+ grid->margin(&ml, &mt, NULL, NULL);
+ grid->gap(&grg, &gcg);
+ int x0 = grid->x() + Fl::box_dx(grid->box()) + ml;
+ int y0 = grid->y() + Fl::box_dy(grid->box()) + mt;
+
+ for (int r = 0; r < grid->rows(); r++) {
+ if (y>y0) row = r;
+ int gap = grid->row_gap(r)>=0 ? grid->row_gap(r) : grg;
+ y0 += grid->computed_row_height(r);
+ y0 += gap;
+ }
+
+ for (int c = 0; c < grid->cols(); c++) {
+ if (x>x0) col = c;
+ int gap = grid->col_gap(c)>=0 ? grid->col_gap(c) : gcg;
+ x0 += grid->computed_col_width(c);
+ x0 += gap;
+ }
+
+ move_cell(grid, child, row, col);
+}
+
+/** Insert a child window into the first new cell we can find .
+
+ There are many other possible strategies. How about inserting to the right
+ of the last added child. Also, what happens if the grid is full? Should
+ we add a new row at the bottom?
+ */
+void Fl_Grid_Type::insert_child(Fl_Widget *child) {
+ Fl_Grid *grid = (Fl_Grid*)o;
+ if (grid->cell(child)) return;
+ for (int r=0; r<grid->rows(); r++) {
+ for (int c=0; c<grid->cols(); c++) {
+ if (!grid->cell(r, c)) {
+ move_cell(grid, child, r, c);
+ return;
+ }
+ }
+ }
+}
+
// FIXME: when changing the cell location, and another cell would be overridden,
// don't actually move the cell (hard to implement!) and activate
// a red button "replace". If clicked, user gets the option to delete
// the old widget, or just remove the cell, or cancel.
// TODO: move cells by using the arrow keys?
// TODO: move cells via drag'n'drop
-// TODO: insert cells when adding them from the menu or toolbar
// TODO: better grid overlay?
-// TODO: grid_child_cb should move all selected cells.
+// TODO: grid_child_cb should move all selected cells, not just the current_selected.
// TODO: buttons to add and delete rows and columns in the widget dialog
// TODO: ways to resize rows and columns, add and delete them in the project window, pulldown menu?
// TODO: alignment can be FL_GRID_LEFT|FL_GRID_VERTICAL?
+// TODO: we must set undo checkpoints in all callbacks!
void grid_child_cb(Fluid_Coord_Input* i, void* v, int what) {
static Fl_Widget *prev_widget = NULL;
if ( !current_widget
diff --git a/fluid/Fl_Grid_Type.h b/fluid/Fl_Grid_Type.h
index 3ad25095c..358489469 100644
--- a/fluid/Fl_Grid_Type.h
+++ b/fluid/Fl_Grid_Type.h
@@ -45,6 +45,8 @@ public:
void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE;
void remove_child(Fl_Type*) FL_OVERRIDE;
void child_resized(Fl_Widget_Type *child);
+ void insert_child_at(Fl_Widget *child, int x, int y);
+ void insert_child(Fl_Widget *child);
static class Fl_Grid *selected();
};
diff --git a/fluid/factory.cxx b/fluid/factory.cxx
index 28e71068e..7bd93f946 100644
--- a/fluid/factory.cxx
+++ b/fluid/factory.cxx
@@ -26,6 +26,7 @@
#include "fluid.h"
#include "Fl_Group_Type.h"
+#include "Fl_Grid_Type.h"
#include "Fl_Menu_Type.h"
#include "Fd_Snap_Action.h"
#include "pixmaps.h"
@@ -1225,6 +1226,13 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) {
wt->o->size(w, h);
}
}
+ if (t->parent && t->parent->is_a(ID_Grid)) {
+ if (Fl_Window_Type::popupx != 0x7FFFFFFF) {
+ ((Fl_Grid_Type*)t->parent)->insert_child_at(((Fl_Widget_Type*)t)->o, Fl_Window_Type::popupx, Fl_Window_Type::popupy);
+ } else {
+ ((Fl_Grid_Type*)t->parent)->insert_child(((Fl_Widget_Type*)t)->o);
+ }
+ }
}
if (t->is_a(ID_Window)) {
int x = 0, y = 0, w = 480, h = 320;
diff --git a/src/Fl_Grid.cxx b/src/Fl_Grid.cxx
index 9de77c7b9..ac4f9f224 100644
--- a/src/Fl_Grid.cxx
+++ b/src/Fl_Grid.cxx
@@ -1142,6 +1142,14 @@ int Fl_Grid::row_gap(int row) const {
return 0;
}
+int Fl_Grid::computed_col_width(int col) const {
+ return Cols_[col].w_;
+}
+
+int Fl_Grid::computed_row_height(int row) const {
+ return Rows_[row].h_;
+}
+
/**
Output layout information of this Fl_Grid to stderr.