summaryrefslogtreecommitdiff
path: root/fluid
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2023-10-23 01:36:55 +0200
committerMatthias Melcher <github@matthiasm.com>2023-10-23 01:36:55 +0200
commit17baeceb7ab90251f99c7909eb9eeca92aec5a05 (patch)
tree76fc446e2060f38dfda5e769640c2277d2010eb6 /fluid
parentab6ef9d52f60ac991baafc7af33775e34484f358 (diff)
FLUID: Positioning grid cells intuitively.
User can now drag widgets from the toolbox into the grid or use the context menu to add them into the corresponding cell. If no position is indicated, now children are added at the first free cell.
Diffstat (limited to 'fluid')
-rw-r--r--fluid/Fl_Grid_Type.cxx48
-rw-r--r--fluid/Fl_Grid_Type.h2
-rw-r--r--fluid/factory.cxx8
3 files changed, 56 insertions, 2 deletions
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;