diff options
| author | Matthias Melcher <github@matthiasm.com> | 2022-11-01 20:45:31 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-01 20:45:31 +0100 |
| commit | 33f01ecb836f9bd70447fcd7ab0f7eda27d224db (patch) | |
| tree | 4f0c640c3199e34aa47962569d5eeafb930de051 | |
| parent | c570bd8f96902a2f290f7623b8cf3074ac8f97ca (diff) | |
Added Fl_Group::on_insert/on_remove/on_move (#527)
| -rw-r--r-- | FL/Fl_Flex.H | 2 | ||||
| -rw-r--r-- | FL/Fl_Group.H | 3 | ||||
| -rw-r--r-- | fluid/Fl_Group_Type.cxx | 2 | ||||
| -rw-r--r-- | src/Fl_Flex.cxx | 8 | ||||
| -rw-r--r-- | src/Fl_Group.cxx | 87 |
5 files changed, 98 insertions, 4 deletions
diff --git a/FL/Fl_Flex.H b/FL/Fl_Flex.H index 1224fe828..87a1c6324 100644 --- a/FL/Fl_Flex.H +++ b/FL/Fl_Flex.H @@ -168,6 +168,8 @@ protected: virtual int alloc_size(int size) const; + void on_remove(int); /* override */ + public: /** Returns the left margin size of the widget. diff --git a/FL/Fl_Group.H b/FL/Fl_Group.H index 1f6240070..6441b6149 100644 --- a/FL/Fl_Group.H +++ b/FL/Fl_Group.H @@ -74,6 +74,9 @@ protected: void update_child(Fl_Widget& widget) const; Fl_Rect *bounds(); int *sizes(); // FLTK 1.3 compatibility + virtual int on_insert(Fl_Widget*, int); + virtual int on_move(int, int); + virtual void on_remove(int); public: diff --git a/fluid/Fl_Group_Type.cxx b/fluid/Fl_Group_Type.cxx index 0ab8efcb0..5bc3525d9 100644 --- a/fluid/Fl_Group_Type.cxx +++ b/fluid/Fl_Group_Type.cxx @@ -550,7 +550,6 @@ void Fl_Table_Type::remove_child(Fl_Type* cc) { void Fl_Group_Type::move_child(Fl_Type* cc, Fl_Type* before) { Fl_Widget_Type* c = (Fl_Widget_Type*)cc; Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; - ((Fl_Group*)o)->remove(c->o); ((Fl_Group*)o)->insert(*(c->o), b); o->redraw(); } @@ -558,7 +557,6 @@ void Fl_Group_Type::move_child(Fl_Type* cc, Fl_Type* before) { void Fl_Table_Type::move_child(Fl_Type* cc, Fl_Type* before) { Fl_Widget_Type* c = (Fl_Widget_Type*)cc; Fl_Widget* b = before ? ((Fl_Widget_Type*)before)->o : 0; - ((Fl_Table*)o)->remove(*(c->o)); ((Fl_Table*)o)->insert(*(c->o), b); o->redraw(); } diff --git a/src/Fl_Flex.cxx b/src/Fl_Flex.cxx index 74e9ed13d..446d00aea 100644 --- a/src/Fl_Flex.cxx +++ b/src/Fl_Flex.cxx @@ -133,6 +133,14 @@ Fl_Flex::~Fl_Flex() { free(set_size_); } +/* + Fl_Group calls this method when a child widget is about to be removed. + Make sure that the widget is also removed from our fixed list. + */ +void Fl_Flex::on_remove(int index) { + set_size(child(index), 0); +} + void Fl_Flex::resize(int x, int y, int w, int h) { Fl_Widget::resize(x, y, w, h); diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx index f5a2d02ea..d6b346f1f 100644 --- a/src/Fl_Group.cxx +++ b/src/Fl_Group.cxx @@ -412,6 +412,7 @@ void Fl_Group::clear() { if (w->parent()==this) { // should always be true if (children_>2) { // optimized removal w->parent_ = 0; // reset child's parent + on_remove(idx); children_--; // update counter } else { // slow removal remove(idx); @@ -447,6 +448,60 @@ Fl_Group::~Fl_Group() { } /** + Allow derived groups to act when a widget is added as a child. + + Widgets derived from Fl_Group may store additional data for their children. + Overriding this method will allow derived classes to generate these data + structures just before the child is added. + + This method usually returns the same index that was given in the parameters. + By setting a new index, the position of other widgets in the child pointer + array can be preserved (e.g. Fl_Scroll keeps its scroll bars as the last + two children). + + By returning -1, Fl_Group::insert will not add the child to + array_. This is not recommended, but Fl_Table does something similar to + forward children to a hidden group. + + \param candidate the candidate will be added to the child array_ after this + method returns. + \param index add the child at this position in the array_ + \return index to position the child as planned + \return a new index to force the child to a different position + \return -1 to keep the group from adding the candidate + */ +int Fl_Group::on_insert(Fl_Widget *candidate, int index) { + (void)candidate; + return index; +} + +/** + Allow derived groups to act when a widget is moved within the group. + + Widgets derived from Fl_Group may store additional data for their children. + Overriding this method will allow derived classes to move these data + structures just before the child itself is moved. + + This method usually returns the new index that was given in the + parameters. By setting a different destination index, the position of other + widgets in the child pointer array can be preserved. + + By returning -1, Fl_Group::insert will not move the child. + + \param oldIndex the current index of the child that will be moved + \param newIndex the new index of the child, counted with the old + child already removed + \return index to position the child as planned + \return a new index to force the child to a different position + \return -1 to keep the group from moving the child + */ +int Fl_Group::on_move(int oldIndex, int newIndex) { + (void)oldIndex; + return newIndex; +} + + +/** The widget is removed from its current group (if any) and then inserted into this group. It is put at index n - or at the end, if n >= children(). This can also be used to rearrange @@ -456,12 +511,25 @@ void Fl_Group::insert(Fl_Widget &o, int index) { if (o.parent()) { Fl_Group* g = o.parent(); int n = g->find(o); - if (g == this) { + if (g == this) { // avoid expensive remove() and add() if we just move a widget within the group if (index > n) index--; - if (index == n) return; + index = on_move(n, index); + if (index == n) return; // this includes (children_ == 1) + if (index >= children_ || index < 0) return; + if (index > n) + memmove(array_+n, array_+(n+1), (index-n) * sizeof(Fl_Widget*)); + else + memmove(array_+(index+1), array_+index, (n-index) * sizeof(Fl_Widget*)); + array_[index] = &o; + init_sizes(); + return; } g->remove(n); } + + index = on_insert(&o, index); + if (index == -1) return; + o.parent_ = this; if (children_ == 0) { // use array pointer to point at single child child1_ = &o; @@ -488,6 +556,19 @@ void Fl_Group::insert(Fl_Widget &o, int index) { void Fl_Group::add(Fl_Widget &o) {insert(o, children_);} /** + Allow derived groups to act when a child widget is removed from the group. + + Widgets derived from Fl_Group may store additional data for their children. + Overriding this method will allow derived classes to remove these data + structures just before the child is removed. + + \param index remove the child at this position in the array_ + */ +void Fl_Group::on_remove(int index) { + (void)index; +} + +/** Removes the widget at \p index from the group but does not delete it. This method does nothing if \p index is out of bounds. @@ -499,6 +580,8 @@ void Fl_Group::add(Fl_Widget &o) {insert(o, children_);} */ void Fl_Group::remove(int index) { if (index < 0 || index >= children_) return; + on_remove(index); + Fl_Widget &o = *child(index); if (&o == savedfocus_) savedfocus_ = 0; if (&o == resizable_) resizable_ = this; |
