DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2409
Version: 1.3-feature


Progress: yes, but not yet fully tested, as I would have liked to do it.

Anyway, please test the attached patch Fl_Group_clear_v2.patch. If it
works for you, you can use it as a current workaround until the final
patch will be committed. I don't think that there will be much more
changes. Sorry for the delay. Please confirm if it works for you as
expected.


Link: http://www.fltk.org/str.php?L2409
Version: 1.3-feature
Index: src/Fl_Scroll.cxx
===================================================================
--- src/Fl_Scroll.cxx   (Revision 7713)
+++ src/Fl_Scroll.cxx   (Arbeitskopie)
@@ -32,13 +32,16 @@
 
 /** Clear all but the scrollbars... */
 void Fl_Scroll::clear() {
-  for (int i=children() - 1; i >= 0; i --) {
-    Fl_Widget* o = child(i);
-    if (o != &hscrollbar && o != &scrollbar) {
-      remove(o);
-      delete o;
-    }
-  }
+  // Note: the scrollbars are removed from the group before calling
+  // Fl_Group::clear() to take advantage of the optimized widget removal
+  // and deletion. Finally they are added to Fl_Scroll's group again. This
+  // is MUCH faster than removing the widgets one by one (STR #2409).
+
+  remove(scrollbar);
+  remove(hscrollbar);
+  Fl_Group::clear();
+  add(hscrollbar);
+  add(scrollbar);
 }
 
 /** Insure the scrollbars are the last children */
Index: src/Fl_Group.cxx
===================================================================
--- src/Fl_Group.cxx    (Revision 7713)
+++ src/Fl_Group.cxx    (Arbeitskopie)
@@ -387,16 +387,51 @@
   savedfocus_ = 0;
   resizable_ = this;
   init_sizes();
+
+  // we must change the Fl::pushed() widget, if it is one of
+  // the group's children. Otherwise fl_fix_focus() would send
+  // lots of events to children that are about to be deleted
+  // anyway.
+
+  Fl_Widget *pushed = Fl::pushed();    // save pushed() widget
+  if (contains(pushed)) pushed = this; // set it to be the group, if it's a 
child
+  Fl::pushed(this);                    // for fl_fix_focus etc.
+
   // okay, now it is safe to destroy the children:
-  while (children_) {
-    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 !
-      remove(0);               // remove it only
+
+#define REVERT_CHILDREN
+#ifdef  REVERT_CHILDREN
+  // Revert the order of the children. Doing this and deleting
+  // always the last child is much faster than the other way around.
+  if (children_ > 1) {
+    Fl_Widget *temp;
+    Fl_Widget **a = (Fl_Widget**)array();
+    for (int i=0,j=children_-1; i<children_/2; i++,j--) {
+      temp = a[i];
+      a[i] = a[j];
+      a[j] = temp;
     }
   }
+#endif // REVERT_CHILDREN
+
+  while (children_) {                  // delete all children
+    int idx = children_-1;             // last child's index
+    Fl_Widget* w = child(idx);         // last child widget
+    if (w->parent()==this) {           // should always be true
+      if (children_>2) {               // optimized removal
+        w->parent_ = 0;                        // reset child's parent
+        children_--;                   // update counter
+      } else {                         // slow removal
+        remove(idx);
+      }
+      delete w;                                // delete the child
+    } else {                           // should never happen
+      remove(idx);                     // remove it anyway
+    }
+  }
+
+  if (pushed != this) Fl::pushed(pushed); // reset pushed() widget
+
 }
 
 /**
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs

Reply via email to