Added Fl_Group::on_insert/on_remove/on_move (#527)

This commit is contained in:
Matthias Melcher 2022-11-01 20:45:31 +01:00 committed by GitHub
parent c570bd8f96
commit 33f01ecb83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 98 additions and 4 deletions

View File

@ -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.

View File

@ -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:

View File

@ -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();
}

View File

@ -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);

View File

@ -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);
@ -446,6 +447,60 @@ Fl_Group::~Fl_Group() {
clear();
}
/**
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,
@ -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;
@ -487,6 +555,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.
@ -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;