From e690e76da1555e61bd6bde89d00215b11352f8b2 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sun, 5 Nov 2023 22:18:56 +0100 Subject: [PATCH] FLUID: Adds undo for all grid operations. --- FL/Fl_Grid.H | 2 +- fluid/Fl_Grid_Type.cxx | 119 ++++++++++++++++++++++----------------- fluid/Fl_Grid_Type.h | 3 +- fluid/Fl_Window_Type.cxx | 6 ++ fluid/factory.cxx | 2 +- fluid/file.cxx | 2 +- fluid/widget_browser.cxx | 2 +- fluid/widget_panel.cxx | 45 ++++++++++++++- fluid/widget_panel.fl | 43 ++++++++++++-- fluid/widget_panel.h | 2 + 10 files changed, 162 insertions(+), 64 deletions(-) diff --git a/FL/Fl_Grid.H b/FL/Fl_Grid.H index 403c6c0f3..64183710c 100644 --- a/FL/Fl_Grid.H +++ b/FL/Fl_Grid.H @@ -186,7 +186,7 @@ public: ~Cell() {} - Fl_Widget *widget() { return widget_; } + Fl_Widget *widget() const { return widget_; } short row() const { return row_; } short col() const { return col_; } diff --git a/fluid/Fl_Grid_Type.cxx b/fluid/Fl_Grid_Type.cxx index 493565b6a..1565f19da 100644 --- a/fluid/Fl_Grid_Type.cxx +++ b/fluid/Fl_Grid_Type.cxx @@ -93,30 +93,25 @@ void Fl_Grid_Proxy::draw_overlay() { /** Move a cell into the grid or within the grid. + If the target cell is already taken, \p how will determine what to do: + + If \p how is 0, the existing cell at \p to_row, \p to_col will be deleted, + unlinking the occupant from the grid. \p in_child will the be inserted at the + given location. + + If \p how is 1, the old cell will remain intact, however \p in_child will be + unlinked from the grid. + + If \p how is 2, the old cell will remain intact, and \p in_child will be + removed from the grid, but it will be stored in the transient list and + resized to the target cell position and size. If \p in_child is later + moved to an unoccupied cell, it will be removed from the transient list and + relinked to the grid. Rowspan and colspan are ignored here. + \param[in] in_child must already be a child of grid \param[in] to_row, to_col move the child into this cell - \param[in] how 0: replace occupant, 1: don't replace, 2 = make transient + \param[in] how 0: replace occupant, 1: don't replace, 2: make transient if occupied - - \todo If the target cell is already taken, this function will remove the old - child from the cell and leave it in limbo (a child of grid, but with no - assigned cell). As this function is used to move children around with arrow - keys, it must be possible to move a widget past a cell that is already taken - without disturbing the existing system. - - One solution would be to make the widget "hover", meaning, it will be registered - in Fl_Grid_Proxy as using the same cell as another widget. I am not sure at all - how to implement that yet. We could return the original cell, but that may have - different minsize, etc. . It would be better to have a temporary cell to store - all the information. - - We must make sure that a hovering cell (or multiple cells) are a very temporary - solution, because all this information will be skewed if Grid::layout is - called, and all information is lost when we save the file for compilation. - - We must show a conflict grid under or around the hovering cell! - - Also mind the rowspan and colspan! */ void Fl_Grid_Proxy::move_cell(Fl_Widget *in_child, int to_row, int to_col, int how) { // the child must already be a true child of grid @@ -127,6 +122,7 @@ void Fl_Grid_Proxy::move_cell(Fl_Widget *in_child, int to_row, int to_col, int h int w = 20, h = 20; const Fl_Grid::Cell *old_cell = cell(in_child); if (old_cell) { + if (old_cell->row() == to_row && old_cell->col() == to_col) return; rowspan = old_cell->rowspan(); colspan = old_cell->colspan(); align = old_cell->align(); @@ -162,8 +158,10 @@ void Fl_Grid_Proxy::move_cell(Fl_Widget *in_child, int to_row, int to_col, int h /** Generate or replace a transient widget entry. + If the widget is in the cell list, it will be removed there. If the widget is already transient, the cell will be replaced. + \param[in] wi a child of this Fl_Grid_Proxy, that may be linked to a cell or transient cell \param[in] row, col, row_span, col_span, align cell parameters */ @@ -239,6 +237,15 @@ void Fl_Grid_Proxy::transient_remove_(Fl_Widget *w) { Fl_Grid_Proxy::Cell *Fl_Grid_Proxy::any_cell(Fl_Widget *widget) const { Cell *c = cell(widget); if (c) return c; + return transient_cell(widget); +} + +/** + Find a cell in the transient cell list. + \param[in] widget must be a child of the grid. + \return the transient cell, or NULL if it was not found. + */ +Fl_Grid_Proxy::Cell *Fl_Grid_Proxy::transient_cell(Fl_Widget *widget) const { for (int i=0; imove_cell(child, row, col); + grid->move_cell(child, row, col, 2); } -/** Insert a child widget into the first new cell we can find . +/** + Insert a child widget 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 @@ -667,17 +680,28 @@ void Fl_Grid_Type::insert_child_at(Fl_Widget *child, int x, int y) { /param[in] child */ -void Fl_Grid_Type::insert_child(Fl_Widget *child) { +void Fl_Grid_Type::insert_child_at_next_free_cell(Fl_Widget *child) { Fl_Grid_Proxy *grid = (Fl_Grid_Proxy*)o; if (grid->cell(child)) return; - for (int r=0; rrows(); r++) { - for (int c=0; ccols(); c++) { +// The code below would insert the new widget after the last selected one, but +// unfortunately the current_widget is already invalid. +// if (current_widget && (current_widget->parent == this)) { +// Fl_Grid::Cell *current_cell = grid->any_cell(current_widget->o); +// if (current_cell) { +// r = current_cell->row(); +// c = current_cell->col(); +// } +// } + for (int r = 0; r < grid->rows(); r++) { + for (int c = 0; c < grid->cols(); c++) { if (!grid->cell(r, c)) { grid->move_cell(child, r, c); return; } } } + grid->layout(grid->rows() + 1, grid->cols()); + grid->move_cell(child, grid->rows() - 1, 0); } /** Move cells around using the keyboard. @@ -712,29 +736,17 @@ void Fl_Grid_Type::layout_widget() { // ---- Widget Panel Callbacks ---------------------------------------- MARK: - -// 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 -> int Fl_Window_Type::handle(int event) -// TODO: handling of children that are themselves Groups. As it is, the children -// are not moved correctly if a parent group repositions or resizes groups. -// The same is true for Fl_Flex. // TODO: better grid overlay? // 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! extern Fluid_Coord_Input *widget_grid_row_input, *widget_grid_col_input, *widget_grid_rowspan_input, *widget_grid_colspan_input; extern Fl_Group *widget_tab_grid_child; - void grid_child_cb(Fluid_Coord_Input* i, void* v, int what) { - static Fl_Widget *prev_widget = NULL; if ( !current_widget || !current_widget->parent || !current_widget->parent->is_a(ID_Grid)) @@ -743,8 +755,7 @@ void grid_child_cb(Fluid_Coord_Input* i, void* v, int what) { } Fl_Widget *child = ((Fl_Widget_Type*)current_widget)->o; Fl_Grid_Proxy *g = ((Fl_Grid_Proxy*)((Fl_Widget_Type*)current_widget->parent)->o); - Fl_Grid::Cell *cell = g->cell(child); - bool freeze_row_col = (!cell && prev_widget==child && ((what&0x00ff)==8 || (what&0x00ff)==9)); + Fl_Grid::Cell *cell = g->any_cell(child); if (v == LOAD) { int v = -1; if (cell) { @@ -757,12 +768,10 @@ void grid_child_cb(Fluid_Coord_Input* i, void* v, int what) { case 13: cell->minimum_size(NULL, &v); break; } } - if (!cell && prev_widget!=child && what==11) - prev_widget = child; - if (!freeze_row_col) - i->value(v); + i->value(v); } else { - int v2 = -1, old_v = -1, v = i->value(); + undo_checkpoint(); + int v2 = -2, old_v = -2, v = i->value(); if (i==widget_grid_row_input) v2 = widget_grid_col_input->value(); if (i==widget_grid_col_input) v2 = widget_grid_row_input->value(); Fl_Grid::Cell *new_cell = NULL; @@ -782,19 +791,21 @@ void grid_child_cb(Fluid_Coord_Input* i, void* v, int what) { } if (old_v != v) { switch (what & 0x00ff) { - case 8: if (v>=0 && v2>=0) g->move_cell(current_widget->o, v, v2); - if (freeze_row_col) i->value(v); + case 8: + if (v2 == -1 && v >= 0) v2 = 0; + g->move_cell(current_widget->o, v, v2, 2); i->value(v); break; - case 9: if (v>=0 && v2>=0) g->move_cell(current_widget->o, v2, v); - if (freeze_row_col) i->value(v); + case 9: + if (v2 == -1 && v >= 0) v2 = 0; + g->move_cell(current_widget->o, v2, v, 2); i->value(v); break; - case 10: if (cell && cell->row()+v<=g->rows()) cell->rowspan(v); + case 10: if (cell && cell->row()+v<=g->rows() && v>0) cell->rowspan(v); break; - case 11: if (cell && cell->col()+v<=g->cols()) cell->colspan(v); + case 11: if (cell && cell->col()+v<=g->cols() && v>0) cell->colspan(v); break; - case 12: if (cell) cell->minimum_size(v, v2); + case 12: if (cell && v>=0) cell->minimum_size(v, v2); break; - case 13: if (cell) cell->minimum_size(v2, v); + case 13: if (cell && v>=0) cell->minimum_size(v2, v); break; } if (!cell && new_cell) @@ -893,6 +904,7 @@ void grid_align_horizontal_cb(Fl_Choice* i, void* v) { const Fl_Menu_Item *mi = i->find_item_with_argument(a); if (mi) i->value(mi); } else { + undo_checkpoint(); int v = FL_GRID_FILL & mask, old_v = FL_GRID_FILL & mask; const Fl_Menu_Item *mi = i->mvalue(); if (mi) v = (int)mi->argument(); @@ -927,6 +939,7 @@ void grid_align_vertical_cb(Fl_Choice* i, void* v) { const Fl_Menu_Item *mi = i->find_item_with_argument(a); if (mi) i->value(mi); } else { + undo_checkpoint(); int v = FL_GRID_FILL & mask, old_v = FL_GRID_FILL & mask; const Fl_Menu_Item *mi = i->mvalue(); if (mi) v = (int)mi->argument(); diff --git a/fluid/Fl_Grid_Type.h b/fluid/Fl_Grid_Type.h index 9780ace76..4c922f97d 100644 --- a/fluid/Fl_Grid_Type.h +++ b/fluid/Fl_Grid_Type.h @@ -40,6 +40,7 @@ public: void draw_overlay(); void move_cell(Fl_Widget *child, int to_row, int to_col, int how = 0); Cell* any_cell(Fl_Widget *widget) const; + Cell* transient_cell(Fl_Widget *widget) const; Cell* transient_widget(Fl_Widget *wi, int row, int col, int row_span, int col_span, Fl_Grid_Align align = FL_GRID_FILL); Cell* widget(Fl_Widget *wi, int row, int col, Fl_Grid_Align align = FL_GRID_FILL); Cell* widget(Fl_Widget *wi, int row, int col, int rowspan, int colspan, Fl_Grid_Align align = FL_GRID_FILL); @@ -69,7 +70,7 @@ public: void layout_widget() 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); + void insert_child_at_next_free_cell(Fl_Widget *child); void keyboard_move_child(Fl_Widget_Type*, int key); static class Fl_Grid *selected(); diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx index 793744ee7..8a5d4962e 100644 --- a/fluid/Fl_Window_Type.cxx +++ b/fluid/Fl_Window_Type.cxx @@ -47,6 +47,7 @@ #include #include +extern Fl_Window *the_panel; extern void draw_width(int x, int y, int r, Fl_Align a); extern void draw_height(int x, int y, int b, Fl_Align a); @@ -857,6 +858,7 @@ extern Fl_Menu_Item New_Menu[]; */ void Fl_Window_Type::moveallchildren(int key) { + bool update_widget_panel = false; undo_checkpoint(); Fl_Type *i; for (i=next; i && i->level>level;) { @@ -915,6 +917,7 @@ void Fl_Window_Type::moveallchildren(int key) allow_layout++; g->layout(); allow_layout--; + update_widget_panel = true; } else if (myo->parent && myo->parent->is_a(ID_Group)) { Fl_Group_Type* gt = (Fl_Group_Type*)myo->parent; ((Fl_Group*)gt->o)->init_sizes(); @@ -942,6 +945,9 @@ void Fl_Window_Type::moveallchildren(int key) dx = dy = 0; update_xywh(); + if (update_widget_panel && the_panel && the_panel->visible()) { + propagate_load(the_panel, LOAD); + } } int Fl_Window_Type::popupx = 0x7FFFFFFF; // mark as invalid (MAXINT) diff --git a/fluid/factory.cxx b/fluid/factory.cxx index cd25e96df..bb832af45 100644 --- a/fluid/factory.cxx +++ b/fluid/factory.cxx @@ -1232,7 +1232,7 @@ Fl_Type *add_new_widget_from_user(Fl_Type *inPrototype, Strategy strategy) { 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); + ((Fl_Grid_Type*)t->parent)->insert_child_at_next_free_cell(((Fl_Widget_Type*)t)->o); } } } diff --git a/fluid/file.cxx b/fluid/file.cxx index 3f0fafd47..317fc0469 100644 --- a/fluid/file.cxx +++ b/fluid/file.cxx @@ -399,7 +399,7 @@ Fl_Type *Fd_Project_Reader::read_children(Fl_Type *p, int merge, Strategy strate 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); + ((Fl_Grid_Type*)t->parent)->insert_child_at_next_free_cell(((Fl_Widget_Type*)t)->o); } } diff --git a/fluid/widget_browser.cxx b/fluid/widget_browser.cxx index 56716cf0a..993b564fb 100644 --- a/fluid/widget_browser.cxx +++ b/fluid/widget_browser.cxx @@ -423,7 +423,7 @@ int Widget_Browser::item_width(void *v) const { } /** - Callback to tell the FLuid UI when the list of selected items changed. + Callback to tell the Fluid UI when the list of selected items changed. */ void Widget_Browser::callback() { selection_changed((Fl_Type*)selection()); diff --git a/fluid/widget_panel.cxx b/fluid/widget_panel.cxx index efd19f5af..da8021a28 100644 --- a/fluid/widget_panel.cxx +++ b/fluid/widget_panel.cxx @@ -123,6 +123,26 @@ Fluid_Coord_Input *widget_grid_row_input=(Fluid_Coord_Input *)0; Fluid_Coord_Input *widget_grid_col_input=(Fluid_Coord_Input *)0; +Fl_Box *widget_grid_transient=(Fl_Box *)0; + +static void cb_widget_grid_transient(Fl_Box* o, void* v) { + if (v==LOAD) { + Fl_Widget *child = ((Fl_Widget_Type*)current_widget)->o; + Fl_Grid_Proxy *g = ((Fl_Grid_Proxy*)((Fl_Widget_Type*)current_widget->parent)->o); + Fl_Grid::Cell *cell = g->cell(child); + Fl_Grid::Cell *tcell = g->transient_cell(child); + widget_grid_transient->hide(); + widget_grid_unlinked->hide(); + if (g->transient_cell(child)) { + widget_grid_transient->show(); + } else if (!g->cell(child)) { + widget_grid_unlinked->show(); + } + } +} + +Fl_Box *widget_grid_unlinked=(Fl_Box *)0; + Fl_Menu_Item menu_Horizontal[] = { {"GRID_LEFT", 0, 0, (void*)(FL_GRID_LEFT), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, {"GRID_CENTER", 0, 0, (void*)(FL_GRID_CENTER), 0, (uchar)FL_NORMAL_LABEL, 0, 11, 0}, @@ -240,6 +260,7 @@ static void cb_Left(Fl_Value_Input* o, void* v) { int m = (int)o->value(), old_m; grid->margin(&old_m, NULL, NULL, NULL); if (m != old_m) { + undo_checkpoint(); grid->margin(m, -1, -1, -1); grid->need_layout(true); set_modflag(1); @@ -258,6 +279,7 @@ static void cb_Top(Fl_Value_Input* o, void* v) { int m = (int)o->value(), old_m; grid->margin(NULL, &old_m, NULL, NULL); if (m != old_m) { + undo_checkpoint(); grid->margin(-1, m, -1, -1); grid->need_layout(true); set_modflag(1); @@ -276,6 +298,7 @@ static void cb_Right(Fl_Value_Input* o, void* v) { int m = (int)o->value(), old_m; grid->margin(NULL, NULL, &old_m, NULL); if (m != old_m) { + undo_checkpoint(); grid->margin(-1, -1, m, -1); grid->need_layout(true); set_modflag(1); @@ -294,6 +317,7 @@ static void cb_Bottom(Fl_Value_Input* o, void* v) { int m = (int)o->value(), old_m; grid->margin(NULL, NULL, NULL, &old_m); if (m != old_m) { + undo_checkpoint(); grid->margin(-1, -1, -1, m); grid->need_layout(true); set_modflag(1); @@ -312,6 +336,7 @@ static void cb_Row(Fl_Value_Input* o, void* v) { int m = (int)o->value(), old_m, m2; grid->gap(&old_m, &m2); if (m != old_m) { + undo_checkpoint(); grid->gap(m, m2); grid->need_layout(true); set_modflag(1); @@ -330,6 +355,7 @@ static void cb_Col(Fl_Value_Input* o, void* v) { int m = (int)o->value(), old_m, m2; grid->gap(&m2, &old_m); if (m != old_m) { + undo_checkpoint(); grid->gap(m2, m); grid->need_layout(true); set_modflag(1); @@ -390,6 +416,7 @@ static void cb_Height(Fluid_Coord_Input* o, void* v) { int h = o->value(), old_h = grid->row_height(r); if (h < 0) h = 0; if (h != old_h) { + undo_checkpoint(); grid->row_height(r, h); grid->need_layout(true); set_modflag(1); @@ -407,6 +434,7 @@ static void cb_Weight(Fluid_Coord_Input* o, void* v) { int h = o->value(), old_h = grid->row_weight(r); if (h < 0) h = 0; if (h != old_h) { + undo_checkpoint(); grid->row_weight(r, h); grid->need_layout(true); set_modflag(1); @@ -424,6 +452,7 @@ static void cb_Gap(Fluid_Coord_Input* o, void* v) { int h = o->value(), old_h = grid->row_gap(r); if (h < -1) h = -1; if (h != old_h) { + undo_checkpoint(); grid->row_gap(r, h); grid->need_layout(true); set_modflag(1); @@ -473,6 +502,7 @@ static void cb_Width(Fluid_Coord_Input* o, void* v) { int h = o->value(), old_h = grid->col_width(c); if (h < 0) h = 0; if (h != old_h) { + undo_checkpoint(); grid->col_width(c, h); grid->need_layout(true); set_modflag(1); @@ -490,6 +520,7 @@ static void cb_Weight1(Fluid_Coord_Input* o, void* v) { int h = o->value(), old_h = grid->col_weight(c); if (h < 0) h = 0; if (h != old_h) { + undo_checkpoint(); grid->col_weight(c, h); grid->need_layout(true); set_modflag(1); @@ -507,6 +538,7 @@ static void cb_Gap1(Fluid_Coord_Input* o, void* v) { int h = o->value(), old_h = grid->col_gap(c); if (h < -1) h = -1; if (h != old_h) { + undo_checkpoint(); grid->col_gap(c, h); grid->need_layout(true); set_modflag(1); @@ -1415,7 +1447,9 @@ access the Widget pointer and \'v\' to access the user value."); { widget_tab_grid_child = new Fl_Group(10, 30, 400, 330, "Grid Child"); widget_tab_grid_child->labelsize(11); widget_tab_grid_child->callback((Fl_Callback*)propagate_load); + widget_tab_grid_child->hide(); { Fl_Group* o = new Fl_Group(95, 60, 315, 20, "Location:"); + o->box(FL_FLAT_BOX); o->labelfont(1); o->labelsize(11); o->callback((Fl_Callback*)propagate_load); @@ -1480,6 +1514,16 @@ access the Widget pointer and \'v\' to access the user value."); o->hide(); Fl_Group::current()->resizable(o); } // Fl_Box* o + { widget_grid_transient = new Fl_Box(250, 60, 80, 20, "TRANSIENT"); + widget_grid_transient->labelsize(11); + widget_grid_transient->labelcolor((Fl_Color)1); + widget_grid_transient->callback((Fl_Callback*)cb_widget_grid_transient); + } // Fl_Box* widget_grid_transient + { widget_grid_unlinked = new Fl_Box(250, 60, 80, 20, "UNLINKED"); + widget_grid_unlinked->labelsize(11); + widget_grid_unlinked->labelcolor((Fl_Color)1); + widget_grid_unlinked->hide(); + } // Fl_Box* widget_grid_unlinked o->end(); } // Fl_Group* o { Fl_Group* o = new Fl_Group(95, 90, 315, 30, "Align:"); @@ -1623,7 +1667,6 @@ access the Widget pointer and \'v\' to access the user value."); { widget_tab_grid = new Fl_Group(10, 30, 400, 330, "Grid"); widget_tab_grid->labelsize(11); widget_tab_grid->callback((Fl_Callback*)propagate_load); - widget_tab_grid->hide(); { Fl_Group* o = new Fl_Group(95, 60, 315, 20, "Grid Layout:"); o->labelfont(1); o->labelsize(11); diff --git a/fluid/widget_panel.fl b/fluid/widget_panel.fl index 26ec7f277..cc42315a2 100644 --- a/fluid/widget_panel.fl +++ b/fluid/widget_panel.fl @@ -44,7 +44,7 @@ decl {extern void set_modflag(int mf, int mfc=-1);} {private local } Function {make_widget_panel()} { - comment {Create a panel that can be used with all known widgets} open + comment {Create a panel that can be used with all known widgets} open selected } { Fl_Window {} { comment {Use a Double Window to avoid flickering.} open @@ -835,12 +835,12 @@ wCallback->do_callback(wCallback, v);} open Fl_Group widget_tab_grid_child { label {Grid Child} callback propagate_load open - xywh {10 30 400 330} labelsize 11 + xywh {10 30 400 330} labelsize 11 hide } { Fl_Group {} { label {Location:} callback propagate_load open - xywh {95 60 315 20} labelfont 1 labelsize 11 align 4 + xywh {95 60 315 20} box FLAT_BOX labelfont 1 labelsize 11 align 4 } { Fl_Input widget_grid_row_input { label {Row:} @@ -889,6 +889,27 @@ wCallback->do_callback(wCallback, v);} open Fl_Box {} { xywh {395 60 1 20} hide resizable } + Fl_Box widget_grid_transient { + label TRANSIENT + callback {if (v==LOAD) { + Fl_Widget *child = ((Fl_Widget_Type*)current_widget)->o; + Fl_Grid_Proxy *g = ((Fl_Grid_Proxy*)((Fl_Widget_Type*)current_widget->parent)->o); + Fl_Grid::Cell *cell = g->cell(child); + Fl_Grid::Cell *tcell = g->transient_cell(child); + widget_grid_transient->hide(); + widget_grid_unlinked->hide(); + if (g->transient_cell(child)) { + widget_grid_transient->show(); + } else if (!g->cell(child)) { + widget_grid_unlinked->show(); + } +}} + xywh {250 60 80 20} labelsize 11 labelcolor 1 + } + Fl_Box widget_grid_unlinked { + label UNLINKED + xywh {250 60 80 20} labelsize 11 labelcolor 1 hide + } } Fl_Group {} { label {Align:} @@ -943,7 +964,7 @@ wCallback->do_callback(wCallback, v);} open } MenuItem {} { label GRID_FILL - user_data FL_GRID_VERTICAL user_data_type long selected + user_data FL_GRID_VERTICAL user_data_type long xywh {10 10 31 20} labelsize 11 } } @@ -1032,7 +1053,7 @@ wCallback->do_callback(wCallback, v);} open Fl_Group widget_tab_grid { label Grid callback propagate_load open - xywh {10 30 400 330} labelsize 11 hide + xywh {10 30 400 330} labelsize 11 } { Fl_Group {} { label {Grid Layout:} @@ -1160,6 +1181,7 @@ if (v == LOAD) { int m = (int)o->value(), old_m; grid->margin(&old_m, NULL, NULL, NULL); if (m != old_m) { + undo_checkpoint(); grid->margin(m, -1, -1, -1); grid->need_layout(true); set_modflag(1); @@ -1179,6 +1201,7 @@ if (v == LOAD) { int m = (int)o->value(), old_m; grid->margin(NULL, &old_m, NULL, NULL); if (m != old_m) { + undo_checkpoint(); grid->margin(-1, m, -1, -1); grid->need_layout(true); set_modflag(1); @@ -1198,6 +1221,7 @@ if (v == LOAD) { int m = (int)o->value(), old_m; grid->margin(NULL, NULL, &old_m, NULL); if (m != old_m) { + undo_checkpoint(); grid->margin(-1, -1, m, -1); grid->need_layout(true); set_modflag(1); @@ -1217,6 +1241,7 @@ if (v == LOAD) { int m = (int)o->value(), old_m; grid->margin(NULL, NULL, NULL, &old_m); if (m != old_m) { + undo_checkpoint(); grid->margin(-1, -1, -1, m); grid->need_layout(true); set_modflag(1); @@ -1245,6 +1270,7 @@ if (v == LOAD) { int m = (int)o->value(), old_m, m2; grid->gap(&old_m, &m2); if (m != old_m) { + undo_checkpoint(); grid->gap(m, m2); grid->need_layout(true); set_modflag(1); @@ -1264,6 +1290,7 @@ if (v == LOAD) { int m = (int)o->value(), old_m, m2; grid->gap(&m2, &old_m); if (m != old_m) { + undo_checkpoint(); grid->gap(m2, m); grid->need_layout(true); set_modflag(1); @@ -1345,6 +1372,7 @@ if (v == LOAD) { int h = o->value(), old_h = grid->row_height(r); if (h < 0) h = 0; if (h != old_h) { + undo_checkpoint(); grid->row_height(r, h); grid->need_layout(true); set_modflag(1); @@ -1364,6 +1392,7 @@ if (v == LOAD) { int h = o->value(), old_h = grid->row_weight(r); if (h < 0) h = 0; if (h != old_h) { + undo_checkpoint(); grid->row_weight(r, h); grid->need_layout(true); set_modflag(1); @@ -1383,6 +1412,7 @@ if (v == LOAD) { int h = o->value(), old_h = grid->row_gap(r); if (h < -1) h = -1; if (h != old_h) { + undo_checkpoint(); grid->row_gap(r, h); grid->need_layout(true); set_modflag(1); @@ -1458,6 +1488,7 @@ if (v == LOAD) { int h = o->value(), old_h = grid->col_width(c); if (h < 0) h = 0; if (h != old_h) { + undo_checkpoint(); grid->col_width(c, h); grid->need_layout(true); set_modflag(1); @@ -1477,6 +1508,7 @@ if (v == LOAD) { int h = o->value(), old_h = grid->col_weight(c); if (h < 0) h = 0; if (h != old_h) { + undo_checkpoint(); grid->col_weight(c, h); grid->need_layout(true); set_modflag(1); @@ -1496,6 +1528,7 @@ if (v == LOAD) { int h = o->value(), old_h = grid->col_gap(c); if (h < -1) h = -1; if (h != old_h) { + undo_checkpoint(); grid->col_gap(c, h); grid->need_layout(true); set_modflag(1); diff --git a/fluid/widget_panel.h b/fluid/widget_panel.h index 437029df4..83e1f9766 100644 --- a/fluid/widget_panel.h +++ b/fluid/widget_panel.h @@ -143,6 +143,8 @@ extern void grid_set_col_cb(Fluid_Coord_Input*, void*); extern Fluid_Coord_Input *widget_grid_col_input; extern void grid_dec_col_cb(Fl_Button*, void*); extern void grid_inc_col_cb(Fl_Button*, void*); +extern Fl_Box *widget_grid_transient; +extern Fl_Box *widget_grid_unlinked; extern void grid_align_horizontal_cb(Fl_Choice*, void*); extern void grid_align_vertical_cb(Fl_Choice*, void*); extern void grid_set_min_wdt_cb(Fluid_Coord_Input*, void*);