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