summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbrecht Schlosser <albrechts.fltk@online.de>2009-01-08 17:12:34 +0000
committerAlbrecht Schlosser <albrechts.fltk@online.de>2009-01-08 17:12:34 +0000
commiteec7f80e949dd78874741a6c17fe66ec74cec3a5 (patch)
tree74a1d08ed3432f34d73af19b751cec2705217e4e /src
parent601a0f0d3efd46b0ef6c34a98cd738bceaae504c (diff)
Widgets now remove themselves from their parent group (if any), when destroyed
(STR #1894). Fl_Group::clear() removes widget by widget (one at a time) to allow widgets to remove other related widgets from the same group, when they are deleted. Also fixed a bug in Fl_Value_Input (added a destructor), because it used a non-Fl_Group widget as parent of another widget. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6623 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Group.cxx35
-rw-r--r--src/Fl_Value_Input.cxx6
-rw-r--r--src/Fl_Widget.cxx13
3 files changed, 39 insertions, 15 deletions
diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx
index cc2a12bf0..891e0cce8 100644
--- a/src/Fl_Group.cxx
+++ b/src/Fl_Group.cxx
@@ -383,21 +383,23 @@ Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l)
affects all child widgets and deletes them from memory.
*/
void Fl_Group::clear() {
- Fl_Widget*const* old_array = array();
- int old_children = children();
- // clear everything now, in case fl_fix_focus recursively calls us:
- children_ = 0;
- //array_ = 0; //dont do this, it will clobber old_array if only one child
savedfocus_ = 0;
resizable_ = this;
init_sizes();
// okay, now it is safe to destroy the children:
- Fl_Widget*const* a = old_array;
- for (int i=old_children; i--;) {
- Fl_Widget* o = *a++;
- if (o->parent() == this) delete o;
+ 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
+ } 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
+ }
}
- if (old_children > 1) free((void*)old_array);
}
/**
@@ -466,7 +468,18 @@ void Fl_Group::remove(Fl_Widget &o) {
int i = find(o);
if (i >= children_) return;
if (&o == savedfocus_) savedfocus_ = 0;
- o.parent_ = 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];
diff --git a/src/Fl_Value_Input.cxx b/src/Fl_Value_Input.cxx
index eb741c1c7..1ac7a6958 100644
--- a/src/Fl_Value_Input.cxx
+++ b/src/Fl_Value_Input.cxx
@@ -136,6 +136,12 @@ Fl_Value_Input::Fl_Value_Input(int X, int Y, int W, int H, const char* l)
set_flag(SHORTCUT_LABEL);
}
+Fl_Value_Input::~Fl_Value_Input() {
+
+ if (input.parent() == (Fl_Group *)this)
+ input.parent(0); // *revert* ctor kludge!
+}
+
//
// End of "$Id$".
//
diff --git a/src/Fl_Widget.cxx b/src/Fl_Widget.cxx
index 8f76527ca..550f1eb1c 100644
--- a/src/Fl_Widget.cxx
+++ b/src/Fl_Widget.cxx
@@ -135,14 +135,19 @@ extern void fl_throw_focus(Fl_Widget*); // in Fl_x.cxx
/**
Destroys the widget, taking care of throwing focus before if any.
- Destruction does not remove from any parent group! And groups when
- destroyed destroy all their children. This is convenient and fast.
- However, it is only legal to destroy a "root" such as an Fl_Window,
- and automatic destructors may be called.
+ Destruction removes the widget from any parent group! And groups when
+ destroyed destroy all their children. This is convenient and fast.
*/
Fl_Widget::~Fl_Widget() {
Fl::clear_widget_pointer(this);
if (flags() & COPIED_LABEL) free((void *)(label_.value));
+ // remove from parent group
+ if (parent_) parent_->remove(this);
+#ifdef DEBUG_DELETE
+ if (parent_) { // this should never happen
+ printf("*** Fl_Widget: parent_->remove(this) failed [%p,%p]\n",parent_,this);
+ }
+#endif // DEBUG_DELETE
parent_ = 0; // Don't throw focus to a parent widget.
fl_throw_focus(this);
}