From 0c35212467f3b0d1aa632a1febb06c09f4b170f1 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sat, 21 Oct 2023 17:45:30 +0200 Subject: [PATCH] FLUID: grid becomes a bit more interactive --- FL/Fl_Grid.H | 15 +++++++--- fluid/Fl_Grid_Type.cxx | 62 ++++++++++++++++++++++++++++++++++++++-- fluid/Fl_Grid_Type.h | 1 + fluid/Fl_Window_Type.cxx | 5 ++++ fluid/widget_panel.cxx | 12 ++++++-- fluid/widget_panel.fl | 20 +++++++++---- fluid/widget_panel.h | 6 ++++ src/Fl_Grid.cxx | 4 +++ 8 files changed, 111 insertions(+), 14 deletions(-) diff --git a/FL/Fl_Grid.H b/FL/Fl_Grid.H index 2cf2392d0..fbcc1ce1f 100644 --- a/FL/Fl_Grid.H +++ b/FL/Fl_Grid.H @@ -141,6 +141,7 @@ const Fl_Grid_Align FL_GRID_BOTTOM_RIGHT = FL_GRID_BOTTOM | FL_GRID_RIGHT; \image latex Fl_Grid.png "Simple 3x3 Fl_Grid" width=7cm */ class Fl_Grid : public Fl_Group { + friend class Fl_Grid_Type; public: class Cell { @@ -172,13 +173,18 @@ public: ~Cell() {} + Fl_Widget *widget() { return widget_; } + short row() const { return row_; } short col() const { return col_; } - Fl_Widget *widget() { return widget_; } - void align(Fl_Grid_Align align) { - align_ = align; - } + void rowspan(short v) { rowspan_ = v; } + void colspan(short v) { colspan_ = v; } + short rowspan() const { return rowspan_; } + short colspan() const { return colspan_; } + + void align(Fl_Grid_Align align) { align_ = align; } + Fl_Grid_Align align() const { return align_; } }; // class Cell private: @@ -289,6 +295,7 @@ public: void row_height(int row, int value); void row_height(const int *value, size_t size); + int row_height(int row) const; void row_weight(int row, int value); void row_weight(const int *value, size_t size); diff --git a/fluid/Fl_Grid_Type.cxx b/fluid/Fl_Grid_Type.cxx index 73b36fdda..415a2dab5 100644 --- a/fluid/Fl_Grid_Type.cxx +++ b/fluid/Fl_Grid_Type.cxx @@ -44,6 +44,7 @@ Fl_Grid_Type::Fl_Grid_Type() { Fl_Widget *Fl_Grid_Type::widget(int X,int Y,int W,int H) { Fl_Grid *g = new Fl_Grid(X,Y,W,H); g->layout(3, 3); +// g->show_grid(1, FL_RED); Fl_Group::current(0); return g; } @@ -182,6 +183,23 @@ void Fl_Grid_Type::remove_child(Fl_Type* a) { grid->redraw(); } +/** Update the initial size of a child widget. + Fl_Grid keeps track of the size of children when they are first added. In + FLUID, users will want to resize children. So we need to trick Fl_Grid into + taking the new size as the initial size. + */ +void Fl_Grid_Type::child_resized(Fl_Widget_Type *child_type) { + Fl_Grid *grid = (Fl_Grid*)o; + Fl_Widget *child = child_type->o; + Fl_Grid::Cell *cell = grid->cell(child); + if (cell) { + short r = cell->row(), c = cell->col(), rs = cell->rowspan(), cs = cell->colspan(); + Fl_Grid_Align a = cell->align(); + grid->remove_cell(r, c); + grid->widget(child, r, c, rs, cs, a); + } // else unmanaged by Fl_Grid +} + void grid_cb(Fl_Value_Input* i, void* v, int what) { if (v == LOAD) { if (current_widget->is_a(ID_Grid)) { @@ -295,6 +313,8 @@ void grid_child_cb(Fluid_Coord_Input* i, void* v, int what) { switch (what) { case 8: v = cell->row(); break; case 9: v = cell->col(); break; + case 10: v = cell->rowspan(); break; + case 11: v = cell->colspan(); break; } } i->value(v); @@ -306,12 +326,16 @@ void grid_child_cb(Fluid_Coord_Input* i, void* v, int what) { switch (what) { case 8: old_v = cell->row(); v2 = cell->col(); break; case 9: old_v = cell->col(); v2 = cell->row(); break; + case 10: old_v = cell->rowspan(); break; + case 11: old_v = cell->colspan(); break; } } if (old_v != v) { switch (what) { case 8: g->widget(current_widget->o, v, v2); break; case 9: g->widget(current_widget->o, v2, v); break; + case 10: cell->rowspan(v); break; + case 11: cell->colspan(v); break; } g->need_layout(true); g->redraw(); @@ -326,11 +350,45 @@ void grid_set_row_cb(Fluid_Coord_Input* i, void* v) { void grid_set_col_cb(Fluid_Coord_Input* i, void* v) { grid_child_cb(i, v, 9); } -void grid_set_colspan_cb(Fluid_Coord_Input* i, void* v) { +void grid_set_rowspan_cb(Fluid_Coord_Input* i, void* v) { grid_child_cb(i, v, 10); } -void grid_set_rowspan_cb(Fluid_Coord_Input* i, void* v) { +void grid_set_colspan_cb(Fluid_Coord_Input* i, void* v) { grid_child_cb(i, v, 11); } void grid_align_cb(Fl_Choice* i, void* v) { } + +void grid_row_height(Fluid_Coord_Input* i, void* v) { + if ( !current_widget + || !current_widget->parent + || !current_widget->parent->is_a(ID_Grid)) + { + return; + } + Fl_Grid *g = ((Fl_Grid*)((Fl_Widget_Type*)current_widget->parent)->o); + Fl_Grid::Cell *cell = g->cell(current_widget->o); + if (v == LOAD) { + if (cell) { + i->value(g->row_height(cell->row())); + i->activate(); + } else { + i->deactivate(); + } + } else { + if (cell) { + g->row_height(cell->row(), i->value()); + } + } +} +void grid_row_weight(Fluid_Coord_Input* i, void* v) { +} +void grid_row_gap(Fluid_Coord_Input* i, void* v) { +} + +void grid_col_width(Fluid_Coord_Input* i, void* v) { +} +void grid_col_weight(Fluid_Coord_Input* i, void* v) { +} +void grid_col_gap(Fluid_Coord_Input* i, void* v) { +} diff --git a/fluid/Fl_Grid_Type.h b/fluid/Fl_Grid_Type.h index 5ce325043..6ee1831ab 100644 --- a/fluid/Fl_Grid_Type.h +++ b/fluid/Fl_Grid_Type.h @@ -44,6 +44,7 @@ public: void add_child(Fl_Type*, Fl_Type*) FL_OVERRIDE; void move_child(Fl_Type*, Fl_Type*) FL_OVERRIDE; void remove_child(Fl_Type*) FL_OVERRIDE; + void child_resized(Fl_Widget_Type *child); }; #endif // _FLUID_FL_GRID_TYPE_H diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx index 99ca02b3a..433fc5863 100644 --- a/fluid/Fl_Window_Type.cxx +++ b/fluid/Fl_Window_Type.cxx @@ -21,6 +21,7 @@ #include "Fl_Window_Type.h" #include "Fl_Group_Type.h" +#include "Fl_Grid_Type.h" #include "fluid.h" #include "widget_browser.h" #include "undo.h" @@ -837,6 +838,10 @@ void Fl_Window_Type::moveallchildren() } } } + if (myo->parent && myo->parent->is_a(ID_Grid)) { + Fl_Grid_Type* gt = (Fl_Grid_Type*)myo->parent; + gt->child_resized(myo); + } // move all the children, whether selected or not: Fl_Type* p; for (p = myo->next; p && p->level>myo->level; p = p->next) diff --git a/fluid/widget_panel.cxx b/fluid/widget_panel.cxx index ed9e17edd..fc907946d 100644 --- a/fluid/widget_panel.cxx +++ b/fluid/widget_panel.cxx @@ -1141,7 +1141,7 @@ access the Widget pointer and \'v\' to access the user value."); { Fl_Group* o = new Fl_Group(96, 110, 314, 20, "Location:"); o->labelfont(1); o->labelsize(11); - o->callback((Fl_Callback*)position_group_cb); + o->callback((Fl_Callback*)propagate_load); o->align(Fl_Align(FL_ALIGN_LEFT)); { Fluid_Coord_Input* o = new Fluid_Coord_Input(96, 110, 55, 20, "Row:"); o->box(FL_DOWN_BOX); @@ -1191,7 +1191,7 @@ access the Widget pointer and \'v\' to access the user value."); { Fl_Group* o = new Fl_Group(96, 145, 314, 20, "Size:"); o->labelfont(1); o->labelsize(11); - o->callback((Fl_Callback*)position_group_cb); + o->callback((Fl_Callback*)propagate_load); o->align(Fl_Align(FL_ALIGN_LEFT)); { Fl_Box* o = new Fl_Box(400, 145, 1, 20); o->hide(); @@ -1233,6 +1233,7 @@ access the Widget pointer and \'v\' to access the user value."); { Fl_Group* o = new Fl_Group(96, 215, 314, 20, "Row:"); o->labelfont(1); o->labelsize(11); + o->callback((Fl_Callback*)propagate_load); o->align(Fl_Align(FL_ALIGN_LEFT)); { Fluid_Coord_Input* o = new Fluid_Coord_Input(96, 215, 55, 20, "Index"); o->box(FL_DOWN_BOX); @@ -1256,6 +1257,7 @@ access the Widget pointer and \'v\' to access the user value."); o->labelsize(11); o->labelcolor(FL_FOREGROUND_COLOR); o->textsize(11); + o->callback((Fl_Callback*)grid_row_height); o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->when(FL_WHEN_RELEASE); } // Fluid_Coord_Input* o @@ -1268,6 +1270,7 @@ access the Widget pointer and \'v\' to access the user value."); o->labelsize(11); o->labelcolor(FL_FOREGROUND_COLOR); o->textsize(11); + o->callback((Fl_Callback*)grid_row_weight); o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->when(FL_WHEN_RELEASE); } // Fluid_Coord_Input* o @@ -1280,6 +1283,7 @@ access the Widget pointer and \'v\' to access the user value."); o->labelsize(11); o->labelcolor(FL_FOREGROUND_COLOR); o->textsize(11); + o->callback((Fl_Callback*)grid_row_gap); o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->when(FL_WHEN_RELEASE); } // Fluid_Coord_Input* o @@ -1292,6 +1296,7 @@ access the Widget pointer and \'v\' to access the user value."); { Fl_Group* o = new Fl_Group(96, 250, 314, 20, "Column:"); o->labelfont(1); o->labelsize(11); + o->callback((Fl_Callback*)propagate_load); o->align(Fl_Align(FL_ALIGN_LEFT)); { Fluid_Coord_Input* o = new Fluid_Coord_Input(96, 250, 55, 20, "Index"); o->box(FL_DOWN_BOX); @@ -1315,6 +1320,7 @@ access the Widget pointer and \'v\' to access the user value."); o->labelsize(11); o->labelcolor(FL_FOREGROUND_COLOR); o->textsize(11); + o->callback((Fl_Callback*)grid_col_width); o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->when(FL_WHEN_RELEASE); } // Fluid_Coord_Input* o @@ -1327,6 +1333,7 @@ access the Widget pointer and \'v\' to access the user value."); o->labelsize(11); o->labelcolor(FL_FOREGROUND_COLOR); o->textsize(11); + o->callback((Fl_Callback*)grid_col_weight); o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->when(FL_WHEN_RELEASE); } // Fluid_Coord_Input* o @@ -1339,6 +1346,7 @@ access the Widget pointer and \'v\' to access the user value."); o->labelsize(11); o->labelcolor(FL_FOREGROUND_COLOR); o->textsize(11); + o->callback((Fl_Callback*)grid_col_gap); o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->when(FL_WHEN_RELEASE); } // Fluid_Coord_Input* o diff --git a/fluid/widget_panel.fl b/fluid/widget_panel.fl index cdafc553c..6c3b199e4 100644 --- a/fluid/widget_panel.fl +++ b/fluid/widget_panel.fl @@ -23,7 +23,7 @@ comment {// decl {\#include "Fl_Widget_Type.h"} {private global } -decl {\#include } {selected private global +decl {\#include } {private global } decl {\#include "custom_widgets.h"} {public global @@ -874,7 +874,7 @@ wCallback->do_callback(wCallback, v);} open } } } - Fl_Tabs widget_tabs_repo { + Fl_Tabs widget_tabs_repo {selected xywh {10 10 400 350} hide code0 {o->hide();} } { @@ -888,7 +888,7 @@ wCallback->do_callback(wCallback, v);} open } { Fl_Group {} { label {Location:} - callback position_group_cb open + callback propagate_load open xywh {96 110 314 20} labelfont 1 labelsize 11 align 4 } { Fl_Input {} { @@ -984,7 +984,7 @@ wCallback->do_callback(wCallback, v);} open } Fl_Group {} { label {Size:} - callback position_group_cb open + callback propagate_load open xywh {96 145 314 20} labelfont 1 labelsize 11 align 4 } { Fl_Box {} { @@ -1008,7 +1008,8 @@ wCallback->do_callback(wCallback, v);} open xywh {96 179 155 20} labelfont 1 labelsize 12 align 20 } Fl_Group {} { - label {Row:} open + label {Row:} + callback propagate_load open xywh {96 215 314 20} labelfont 1 labelsize 11 align 4 } { Fl_Input {} { @@ -1018,16 +1019,19 @@ wCallback->do_callback(wCallback, v);} open } Fl_Input {} { label {Height:} + callback grid_row_height xywh {156 215 55 20} labelsize 11 align 5 textsize 11 class Fluid_Coord_Input } Fl_Input {} { label {Weight:} + callback grid_row_weight xywh {216 215 55 20} labelsize 11 align 5 textsize 11 class Fluid_Coord_Input } Fl_Input {} { label {Gap:} + callback grid_row_gap xywh {276 215 55 20} labelsize 11 align 5 textsize 11 class Fluid_Coord_Input } @@ -1036,7 +1040,8 @@ wCallback->do_callback(wCallback, v);} open } } Fl_Group {} { - label {Column:} open + label {Column:} + callback propagate_load open xywh {96 250 314 20} labelfont 1 labelsize 11 align 4 } { Fl_Input {} { @@ -1046,16 +1051,19 @@ wCallback->do_callback(wCallback, v);} open } Fl_Input {} { label {Width:} + callback grid_col_width xywh {156 250 55 20} labelsize 11 align 5 textsize 11 class Fluid_Coord_Input } Fl_Input {} { label {Weight:} + callback grid_col_weight xywh {216 250 55 20} labelsize 11 align 5 textsize 11 class Fluid_Coord_Input } Fl_Input {} { label {Gap:} + callback grid_col_gap xywh {276 250 55 20} labelsize 11 align 5 textsize 11 class Fluid_Coord_Input } diff --git a/fluid/widget_panel.h b/fluid/widget_panel.h index 4440175c3..67158c9df 100644 --- a/fluid/widget_panel.h +++ b/fluid/widget_panel.h @@ -150,6 +150,12 @@ extern void grid_set_col_cb(Fluid_Coord_Input*, void*); extern void grid_align_cb(Fl_Choice*, void*); extern void grid_set_rowspan_cb(Fluid_Coord_Input*, void*); extern void grid_set_colspan_cb(Fluid_Coord_Input*, void*); +extern void grid_row_height(Fluid_Coord_Input*, void*); +extern void grid_row_weight(Fluid_Coord_Input*, void*); +extern void grid_row_gap(Fluid_Coord_Input*, void*); +extern void grid_col_width(Fluid_Coord_Input*, void*); +extern void grid_col_weight(Fluid_Coord_Input*, void*); +extern void grid_col_gap(Fluid_Coord_Input*, void*); extern void live_mode_cb(Fl_Button*, void*); extern Fl_Button *wLiveMode; extern void overlay_cb(Fl_Button*, void*); diff --git a/src/Fl_Grid.cxx b/src/Fl_Grid.cxx index da9c34ebc..3928b52a1 100644 --- a/src/Fl_Grid.cxx +++ b/src/Fl_Grid.cxx @@ -1030,6 +1030,10 @@ void Fl_Grid::row_height(int row, int value) { need_layout(1); } +int Fl_Grid::row_height(int row) const { + if (row >= 0 && row < rows_) return Rows_[row].minh_; +} + /** Set the minimal row height of more than one row.