diff options
| -rw-r--r-- | FL/Fl_Grid.H | 3 | ||||
| -rw-r--r-- | fluid/Fl_Grid_Type.cxx | 48 | ||||
| -rw-r--r-- | fluid/Fl_Grid_Type.h | 2 | ||||
| -rw-r--r-- | fluid/factory.cxx | 8 | ||||
| -rw-r--r-- | src/Fl_Grid.cxx | 8 |
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. |
