From 5a3aced3ab97ff110e44d2ed8ff6e5c47c7064d7 Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Tue, 31 Aug 2010 10:01:59 +0000 Subject: [PATCH] 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 --- FL/Fl_Group.H | 1 + src/Fl_Group.cxx | 76 +++++++++++++++++++++++++++--------------------- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/FL/Fl_Group.H b/FL/Fl_Group.H index cde3e8cb2..f519a7111 100644 --- a/FL/Fl_Group.H +++ b/FL/Fl_Group.H @@ -106,6 +106,7 @@ public: widget if \p before is not in the group. */ void insert(Fl_Widget& o, Fl_Widget* before) {insert(o,find(before));} + void remove(int index); void remove(Fl_Widget&); /** Removes the widget \p o from the group. diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx index 46de470e4..edc2036e7 100644 --- a/src/Fl_Group.cxx +++ b/src/Fl_Group.cxx @@ -389,16 +389,12 @@ void Fl_Group::clear() { init_sizes(); // okay, now it is safe to destroy the children: while (children_) { - Fl_Widget* o = child(0); // *first* child widget - if (o->parent() == this) { // should always be true - remove(o); // remove child widget first - delete o; // then delete it + Fl_Widget* w = child(0); // *first* child widget + if (w->parent() == this) { // should always be true + remove(0); // remove child widget first + delete w; // then delete it } else { // this should never happen ! -#ifdef DEBUG_CLEAR - printf ("Fl_Group::clear() widget:%p, parent: %p != this (%p)\n", - o, o->parent(), this); fflush(stdout); -#endif // DEBUG_CLEAR - remove(o); // remove it + remove(0); // remove it only } } } @@ -435,7 +431,7 @@ void Fl_Group::insert(Fl_Widget &o, int index) { if (index > n) index--; if (index == n) return; } - g->remove(o); + g->remove(n); } o.parent_ = this; 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_);} +/** + 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. @@ -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 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) { if (!children_) return; int i = find(o); - if (i >= children_) return; - 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(); + if (i < children_) remove(i); } ////////////////////////////////////////////////////////////////