Greg Ercolano wrote:
>> You can see the problem with the test/tree demo program. If you
>> clear a tree item while it (and thus its widget) is shown, then
>> the widget stays at its current position forever.
>> [[Example 1]]
>
> Right; I think some extra code added to the Fl_Tree_Item
> destructor can take care of that. It's basically an omission.
> Currently the destructor just NULLs out the widget() instead
> of telling the parent group to remove it.
>
> I'll see about adding that.
I've attached a patch that will probably solve all of that.
Here, the patch adds:
1) a 'group' pointer to the Fl_Tree_Items so that it can talk to the
parent group.
2) Appropriate destructor code for the item to clear the widget(s) it
owns
3) Fixed the test/tree.cxx code so that the widgets are no longer static
The tree.fl will need the final fixes, and at some point tree.cxx will
need to be removed from svn and replaced with just tree.fl.
Arguably the Fl_Tree_Item should keep a pointer back to the parent Fl_Tree
instead of just the group, but was trying to prevent a backwards association
that is too tight. There might be a better way to do this association, not
sure.
Input welcome.
Index: src/Fl_Tree.cxx
===================================================================
--- src/Fl_Tree.cxx (revision 7658)
+++ src/Fl_Tree.cxx (working copy)
@@ -79,6 +79,7 @@
/// Constructor.
Fl_Tree::Fl_Tree(int X, int Y, int W, int H, const char *L) : Fl_Group(X,Y,W,H,L) {
_root = new Fl_Tree_Item(_prefs);
+ _root->group(this);
_root->parent(0); // we are root of tree
_root->label("ROOT");
_item_clicked = 0;
@@ -106,6 +107,7 @@
Fl_Tree_Item* Fl_Tree::add(const char *path) {
if ( ! _root ) { // Create root if none
_root = new Fl_Tree_Item(_prefs);
+ _root->group(this);
_root->parent(0);
_root->label("ROOT");
}
Index: src/Fl_Tree_Item.cxx
===================================================================
--- src/Fl_Tree_Item.cxx (revision 7658)
+++ src/Fl_Tree_Item.cxx (working copy)
@@ -66,6 +66,7 @@
_usericon = 0;
_userdata = 0;
_parent = 0;
+ _group = 0;
}
// DTOR
@@ -74,7 +75,13 @@
free((void*)_label);
_label = 0;
}
- _widget = 0; // Fl_Group will handle destruction
+ if ( _group && _widget ) {
+ // Remove widget from group
+ _group->remove(_widget);
+ delete(_widget);
+ }
+ _widget = 0;
+ _group = 0;
_usericon = 0; // user handled allocation
//_children.clear(); // array's destructor handles itself
}
@@ -106,6 +113,7 @@
_usericon = o->usericon();
_userdata = o->user_data();
_parent = o->_parent;
+ _group = o->_group;
}
/// Print the tree as 'ascii art' to stdout.
@@ -113,8 +121,8 @@
///
void Fl_Tree_Item::show_self(const char *indent) const {
if ( label() ) {
- printf("%s-%s (%d children, this=%p, parent=%p depth=%d)\n",
- indent,label(),children(),(void*)this, (void*)_parent, depth());
+ printf("%s-%s (%d children, this=%p, parent=%p widget=%p depth=%d)\n",
+ indent,label(),children(),(void*)this, (void*)_parent, (void*)_widget, depth());
}
if ( children() ) {
char *i2 = (char*)malloc(strlen(indent) + 2);
@@ -225,6 +233,7 @@
///
Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, const char *new_label) {
Fl_Tree_Item *item = new Fl_Tree_Item(prefs);
+ if ( _group ) item->group(_group);
item->label(new_label);
item->_parent = this;
switch ( prefs.sortorder() ) {
@@ -283,6 +292,7 @@
///
Fl_Tree_Item *Fl_Tree_Item::insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos) {
Fl_Tree_Item *item = new Fl_Tree_Item(prefs);
+ if ( _group ) item->group(_group);
item->label(new_label);
item->_parent = this;
_children.insert(pos, item);
Index: FL/Fl_Tree_Item.H
===================================================================
--- FL/Fl_Tree_Item.H (revision 7658)
+++ FL/Fl_Tree_Item.H (working copy)
@@ -7,6 +7,7 @@
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
+#include <FL/Fl_Group.H>
#include <FL/Fl_Image.H>
#include <FL/fl_draw.H>
@@ -57,6 +58,7 @@
/// for the changes to show up.
///
class Fl_Tree_Item {
+private:
const char *_label; // label (memory managed)
int _labelfont; // label's font face
int _labelsize; // label's font size
@@ -74,6 +76,7 @@
Fl_Tree_Item_Array _children; // array of child items
Fl_Tree_Item *_parent; // parent item (=0 if root)
void *_userdata; // user data that can be associated with an item
+ Fl_Group *_group; // pointer to parent Fl_Tree's group
protected:
void show_widgets();
void hide_widgets();
@@ -312,6 +315,15 @@
int is_root() const {
return(_parent==0?1:0);
}
+
+ /// Return the parent group.
+ Fl_Group *group() const {
+ return(_group);
+ }
+ /// Set the parent group.
+ void group(Fl_Group *val) {
+ _group = val;
+ }
};
#endif /*FL_TREE_ITEM_H*/
Index: test/tree.cxx
===================================================================
--- test/tree.cxx (revision 7658)
+++ test/tree.cxx (working copy)
@@ -26,13 +26,11 @@
// Assign an FLTK widget to one of the items
Fl_Tree_Item *i;
if ( ( i = tree->find_item("Bbb/child-03") ) != NULL ) {
- if ( !but ) { // only do this once at program startup
- tree->begin();
- but = new Fl_Button(1,1,140,1,"ccc button"); // we control w() only
- but->labelsize(10);
- but->callback(Button_CB);
- }
- i->widget(but);
+ tree->begin();
+ but = new Fl_Button(1,1,140,1,"ccc button"); // we control w() only
+ but->labelsize(10);
+ but->callback(Button_CB);
+ i->widget(but); // associate button widget with this tree item
tree->end();
}
}
@@ -40,23 +38,20 @@
// Assign an FLTK group to one of the items with widgets
Fl_Tree_Item *i;
if ( ( i = tree->find_item("Bbb/child-04") ) != NULL ) {
- static Fl_Group *grp = 0;
- if ( !grp ) { // only do this once at program startup
- tree->begin();
- grp = new Fl_Group(100,100,140,18); // build group.. tree handles position
- grp->color(FL_WHITE);
- grp->begin();
- Fl_Button *abut = new Fl_Button(grp->x()+0 ,grp->y()+2,65,15,"D1");
- abut->labelsize(10);
- abut->callback(Button_CB);
- Fl_Button *bbut = new Fl_Button(grp->x()+75,grp->y()+2,65,15,"D2");
- bbut->labelsize(10);
- bbut->callback(Button_CB);
- grp->end();
- grp->resizable(grp);
- tree->end();
- }
- i->widget(grp);
+ tree->begin();
+ Fl_Group *grp = new Fl_Group(100,100,140,18); // build group.. tree handles position
+ grp->color(FL_WHITE);
+ grp->begin();
+ Fl_Button *abut = new Fl_Button(grp->x()+0 ,grp->y()+2,65,15,"D1");
+ abut->labelsize(10);
+ abut->callback(Button_CB);
+ Fl_Button *bbut = new Fl_Button(grp->x()+75,grp->y()+2,65,15,"D2");
+ bbut->labelsize(10);
+ bbut->callback(Button_CB);
+ grp->end();
+ grp->resizable(grp);
+ tree->end();
+ i->widget(grp); // associate widget group with this tree item
}
}
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev