New method: Fl_Group::remove(int index) to speed up the removal

of widgets if the widget's index is known. Thanks to Greg for the
patch. See also STR #2409.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7693 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Albrecht Schlosser 2010-08-31 10:01:59 +00:00
parent 95aa651325
commit 5a3aced3ab
2 changed files with 44 additions and 33 deletions

View File

@ -106,6 +106,7 @@ public:
widget if \p before is not in the group. widget if \p before is not in the group.
*/ */
void insert(Fl_Widget& o, Fl_Widget* before) {insert(o,find(before));} void insert(Fl_Widget& o, Fl_Widget* before) {insert(o,find(before));}
void remove(int index);
void remove(Fl_Widget&); void remove(Fl_Widget&);
/** /**
Removes the widget \p o from the group. Removes the widget \p o from the group.

View File

@ -389,16 +389,12 @@ void Fl_Group::clear() {
init_sizes(); init_sizes();
// okay, now it is safe to destroy the children: // okay, now it is safe to destroy the children:
while (children_) { while (children_) {
Fl_Widget* o = child(0); // *first* child widget Fl_Widget* w = child(0); // *first* child widget
if (o->parent() == this) { // should always be true if (w->parent() == this) { // should always be true
remove(o); // remove child widget first remove(0); // remove child widget first
delete o; // then delete it delete w; // then delete it
} else { // this should never happen ! } else { // this should never happen !
#ifdef DEBUG_CLEAR remove(0); // remove it only
printf ("Fl_Group::clear() widget:%p, parent: %p != this (%p)\n",
o, o->parent(), this); fflush(stdout);
#endif // DEBUG_CLEAR
remove(o); // remove it
} }
} }
} }
@ -435,7 +431,7 @@ void Fl_Group::insert(Fl_Widget &o, int index) {
if (index > n) index--; if (index > n) index--;
if (index == n) return; if (index == n) return;
} }
g->remove(o); g->remove(n);
} }
o.parent_ = this; o.parent_ = this;
if (children_ == 0) { // use array pointer to point at single child if (children_ == 0) { // use array pointer to point at single child
@ -462,6 +458,37 @@ void Fl_Group::insert(Fl_Widget &o, int index) {
*/ */
void Fl_Group::add(Fl_Widget &o) {insert(o, children_);} void Fl_Group::add(Fl_Widget &o) {insert(o, children_);}
/**
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.
This method differs from the clear() method in that it only affects
a single widget and does not delete it from memory.
\since FLTK 1.3.0
*/
void Fl_Group::remove(int index) {
if (index < 0 || index >= children_) return;
Fl_Widget &o = *child(index);
if (&o == savedfocus_) savedfocus_ = 0;
if (o.parent_ == this) { // this should always be true
o.parent_ = 0;
}
// remove the widget from the group
children_--;
if (children_ == 1) { // go from 2 to 1 child
Fl_Widget *t = array_[!index];
free((void*)array_);
array_ = (Fl_Widget**)t;
} else if (children_ > 1) { // delete from array
for (; index < children_; index++) array_[index] = array_[index+1];
}
init_sizes();
}
/** /**
Removes a widget from the group but does not delete it. Removes a widget from the group but does not delete it.
@ -469,33 +496,16 @@ void Fl_Group::add(Fl_Widget &o) {insert(o, children_);}
This method differs from the clear() method in that it only affects This method differs from the clear() method in that it only affects
a single widget and does not delete it from memory. a single widget and does not delete it from memory.
\note If you have the child's index anyway, use remove(int index)
instead, because this doesn't need a child lookup in the group's
table of children. This can be much faster, if there are lots of
children.
*/ */
void Fl_Group::remove(Fl_Widget &o) { void Fl_Group::remove(Fl_Widget &o) {
if (!children_) return; if (!children_) return;
int i = find(o); int i = find(o);
if (i >= children_) return; if (i < children_) remove(i);
if (&o == savedfocus_) savedfocus_ = 0;
if (o.parent_ == this) { // this should always be true
o.parent_ = 0;
}
#ifdef DEBUG_REMOVE
else { // this should never happen !
printf ("Fl_Group::remove(): widget %p, parent_ (%p) != this (%p)\n",
&o, o.parent_, this);
}
#endif // DEBUG_REMOVE
// remove the widget from the group
children_--;
if (children_ == 1) { // go from 2 to 1 child
Fl_Widget *t = array_[!i];
free((void*)array_);
array_ = (Fl_Widget**)t;
} else if (children_ > 1) { // delete from array
for (; i < children_; i++) array_[i] = array_[i+1];
}
init_sizes();
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////