From a657069cc53cc05245762e9323efa040a9f70da2 Mon Sep 17 00:00:00 2001 From: Greg Ercolano Date: Tue, 8 Dec 2009 08:06:44 +0000 Subject: [PATCH] Checked in SebHoll's API mods, fixed indents. o Added user_data() to Fl_Tree_Item o Added insert() and add() methods that allow specification of Fl_Tree_Prefs o Changed Fl_Pixmap args to Fl_Image for more flexibility o Fixes for positioning of items in the presence of user icons o find_children() changed from protected -> public git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6956 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- FL/Fl_Tree.H | 77 +++++++------- FL/Fl_Tree_Item.H | 41 ++++---- FL/Fl_Tree_Item_Array.H | 6 +- FL/Fl_Tree_Prefs.H | 40 ++++---- src/Fl_Tree.cxx | 70 ++++++++----- src/Fl_Tree_Item.cxx | 203 +++++++++++++++++++------------------ src/Fl_Tree_Item_Array.cxx | 14 +-- src/Fl_Tree_Prefs.cxx | 22 ++-- 8 files changed, 251 insertions(+), 222 deletions(-) diff --git a/FL/Fl_Tree.H b/FL/Fl_Tree.H index 68d40bb02..00d92e88e 100644 --- a/FL/Fl_Tree.H +++ b/FL/Fl_Tree.H @@ -101,12 +101,12 @@ /// class Fl_Tree : public Fl_Group { - Fl_Tree_Item *_root; // can be null! + Fl_Tree_Item *_root; // can be null! Fl_Tree_Item *_item_clicked; - Fl_Tree_Prefs _prefs; // all the tree's settings + Fl_Tree_Prefs _prefs; // all the tree's settings Fl_Scrollbar *_vscroll; -protected: +public: /// Find the item that was clicked. /// You probably want to use item_clicked() instead, which is fast. /// @@ -122,6 +122,7 @@ protected: if ( ! _root ) return(0); return(_root->find_clicked(_prefs)); } +protected: /// Set the item that was last clicked. /// Should only be used by subclasses needing to change this value. /// Normally Fl_Tree manages this value. @@ -157,7 +158,9 @@ public: // Item creation/removal methods //////////////////////////////// Fl_Tree_Item *add(const char *path); + Fl_Tree_Item* add(Fl_Tree_Item *item, const char *name); Fl_Tree_Item *insert_above(Fl_Tree_Item *above, const char *name); + Fl_Tree_Item* insert(Fl_Tree_Item *item, const char *name, int pos); /// Remove the specified 'item' from the tree. /// If it has children, all those are removed too. @@ -166,11 +169,11 @@ public: int remove(Fl_Tree_Item *item) { if ( !item ) return(0); if ( item == _root ) { - clear(); + clear(); } else { - Fl_Tree_Item *parent = item->parent(); // find item's parent - if ( ! parent ) return(-1); - parent->remove_child(item); // remove child + children + Fl_Tree_Item *parent = item->parent(); // find item's parent + if ( ! parent ) return(-1); + parent->remove_child(item); // remove child + children } return(0); } @@ -185,8 +188,8 @@ public: /// Clear all the children of a particular node in the tree. void clear_children(Fl_Tree_Item *item) { if ( item->has_children() ) { - item->clear_children(); - redraw(); // redraw only if there were children to clear + item->clear_children(); + redraw(); // redraw only if there were children to clear } } @@ -242,7 +245,7 @@ public: if ( ! _root ) return(0); Fl_Tree_Item *item = _root; while ( item->has_children() ) { - item = item->child(item->children()-1); + item = item->child(item->children()-1); } return(item); } @@ -257,8 +260,8 @@ public: /// void open(Fl_Tree_Item *item) { if ( ! item->is_open() ) { - item->open(); - redraw(); + item->open(); + redraw(); } } /// Opens the item specified by a 'menu item' style pathname (eg: "Parent/child/item"). @@ -272,8 +275,8 @@ public: int open(const char *path) { Fl_Tree_Item *item = find_item(path); if ( item ) { - open(item); - return(0); + open(item); + return(0); } return(-1); } @@ -282,8 +285,8 @@ public: /// void close(Fl_Tree_Item *item) { if ( ! item->is_close() ) { - item->close(); - redraw(); + item->close(); + redraw(); } } /// Closes the item specified by 'path', eg: "Parent/child/item". @@ -297,8 +300,8 @@ public: int close(const char *path) { Fl_Tree_Item *item = find_item(path); if ( item ) { - close(item); - return(0); + close(item); + return(0); } return(-1); } @@ -359,8 +362,8 @@ public: /// void select(Fl_Tree_Item *item) { if ( ! item->is_selected() ) { - item->select(); - redraw(); + item->select(); + redraw(); } } /// Select an item specified by 'path' (eg: "Parent/child/item"). @@ -373,8 +376,8 @@ public: int select(const char *path) { Fl_Tree_Item *item = find_item(path); if ( item ) { - select(item); - return(0); + select(item); + return(0); } return(-1); } @@ -390,8 +393,8 @@ public: /// void deselect(Fl_Tree_Item *item) { if ( item->is_selected() ) { - item->deselect(); - redraw(); + item->deselect(); + redraw(); } } /// De-select an item specified by 'path' (eg: "Parent/child/item"). @@ -404,8 +407,8 @@ public: int deselect(const char *path) { Fl_Tree_Item *item = find_item(path); if ( item ) { - deselect(item); - return(0); + deselect(item); + return(0); } return(-1); } @@ -524,22 +527,22 @@ public: _prefs.connectorwidth(val); redraw(); } - /// Returns the Fl_Pixmap being used as the default user icon for newly created items. + /// Returns the Fl_Image being used as the default user icon for newly created items. /// Returns zero if no icon has been set, which is the default. /// - Fl_Pixmap *usericon() const { + Fl_Image *usericon() const { return(_prefs.usericon()); } - /// Sets the Fl_Pixmap to be used as the default user icon for all + /// Sets the Fl_Image to be used as the default user icon for all /// newly created items. /// /// If you want to specify user icons on a per-item basis, /// use Fl_Tree_Item::usericon() instead. /// - /// \param[in] val -- The new pixmap to be used, or + /// \param[in] val -- The new image to be used, or /// zero to disable user icons. /// - void usericon(Fl_Pixmap *val) { + void usericon(Fl_Image *val) { _prefs.usericon(val); redraw(); } @@ -547,15 +550,15 @@ public: /// If none was set, the internal default is returned, /// a simple '[+]' icon. /// - Fl_Pixmap *openicon() const { + Fl_Image *openicon() const { return(_prefs.openicon()); } /// Sets the icon to be used as the 'open' icon. /// This overrides the built in default '[+]' icon. /// - /// \param[in] val -- The new pixmap, or zero to use the default [+] icon. + /// \param[in] val -- The new image, or zero to use the default [+] icon. /// - void openicon(Fl_Pixmap *val) { + void openicon(Fl_Image *val) { _prefs.openicon(val); redraw(); } @@ -563,15 +566,15 @@ public: /// If none was set, the internal default is returned, /// a simple '[-]' icon. /// - Fl_Pixmap *closeicon() const { + Fl_Image *closeicon() const { return(_prefs.closeicon()); } /// Sets the icon to be used as the 'close' icon. /// This overrides the built in default '[-]' icon. /// - /// \param[in] val -- The new pixmap, or zero to use the default [-] icon. + /// \param[in] val -- The new image, or zero to use the default [-] icon. /// - void closeicon(Fl_Pixmap *val) { + void closeicon(Fl_Image *val) { _prefs.closeicon(val); redraw(); } diff --git a/FL/Fl_Tree_Item.H b/FL/Fl_Tree_Item.H index 55023d38b..674955cd4 100644 --- a/FL/Fl_Tree_Item.H +++ b/FL/Fl_Tree_Item.H @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include @@ -70,9 +70,10 @@ class Fl_Tree_Item { int _collapse_xywh[4]; // xywh of collapse icon (if any) int _label_xywh[4]; // xywh of label Fl_Widget *_widget; // item's label widget (optional) - Fl_Pixmap *_usericon; // item's user-specific icon (optional) + Fl_Image *_usericon; // item's user-specific icon (optional) 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 protected: void show_widgets(); void hide_widgets(); @@ -81,11 +82,17 @@ protected: public: Fl_Tree_Item(const Fl_Tree_Prefs &prefs); // CTOR ~Fl_Tree_Item(); // DTOR - Fl_Tree_Item(const Fl_Tree_Item *o); // COPY CTOR + Fl_Tree_Item(const Fl_Tree_Item *o); // COPY CTOR void draw(int X, int &Y, int W, Fl_Widget *tree, const Fl_Tree_Prefs &prefs, int lastchild=1); void show_self(const char *indent = "") const; void label(const char *val); const char *label() const; + + /// Set a user-data value for the item. + inline void user_data( void* data ) { _userdata = data; } + + /// Retrieve the user-data value that has been assigned to the item. + inline void* user_data() const { return _userdata; } /// Set item's label font face. void labelfont(int val) { @@ -209,9 +216,9 @@ public: /// Toggle the item's selection state. void select_toggle() { if ( is_selected() ) { - deselect(); // deselect if selected + deselect(); // deselect if selected } else { - select(); // select if deselected + select(); // select if deselected } } /// Disable the item's selection state. @@ -225,11 +232,11 @@ public: int deselect_all() { int count = 0; if ( is_selected() ) { - deselect(); - ++count; + deselect(); + ++count; } for ( int t=0; tdeselect_all(); + count += child(t)->deselect_all(); } return(count); } @@ -249,12 +256,12 @@ public: void activate(int val=1) { _active = val; if ( _widget && val != (int)_widget->active() ) { - if ( val ) { - _widget->activate(); - } else { - _widget->deactivate(); - } - _widget->redraw(); + if ( val ) { + _widget->activate(); + } else { + _widget->deactivate(); + } + _widget->redraw(); } } /// Deactivate the item; the callback() won't be invoked when clicked. @@ -271,12 +278,12 @@ public: char is_active() const { return(_active); } - /// Set the user icon's pixmap. '0' will disable. - void usericon(Fl_Pixmap *val) { + /// Set the user icon's image. '0' will disable. + void usericon(Fl_Image *val) { _usericon = val; } /// Get the user icon. Returns '0' if disabled. - Fl_Pixmap *usericon() const { + Fl_Image *usericon() const { return(_usericon); } ////////////////// diff --git a/FL/Fl_Tree_Item_Array.H b/FL/Fl_Tree_Item_Array.H index 68e34db28..19a28b4dc 100644 --- a/FL/Fl_Tree_Item_Array.H +++ b/FL/Fl_Tree_Item_Array.H @@ -6,11 +6,11 @@ #define _FL_TREE_ITEM_ARRAY_H class Fl_Tree_Item; // forward decl must *precede* first doxygen comment block -// or doxygen will not document our class.. + // or doxygen will not document our class.. -////////////////////// +////////////////////////// // FL/Fl_Tree_Item_Array.H -////////////////////// +////////////////////////// // // Fl_Tree -- This file is part of the Fl_Tree widget for FLTK // Copyright (C) 2009 by Greg Ercolano. diff --git a/FL/Fl_Tree_Prefs.H b/FL/Fl_Tree_Prefs.H index 7d9f2521a..05e2eef6e 100644 --- a/FL/Fl_Tree_Prefs.H +++ b/FL/Fl_Tree_Prefs.H @@ -88,11 +88,11 @@ class Fl_Tree_Prefs { int _margintop; // -- int _marginleft; // |- tree's margins //int _marginright; // | - //int _marginbottom; // -- - int _openchild_marginbottom; // extra space below an open child tree + //int _marginbottom; // -- + int _openchild_marginbottom; // extra space below an open child tree int _usericonmarginleft; // space to left of user icon (if any) - int _labelmarginleft; // space to left of label - int _connectorwidth; // connector width (right of open/close icon) + int _labelmarginleft; // space to left of label + int _connectorwidth; // connector width (right of open/close icon) int _linespacing; // vertical space between lines // Colors Fl_Color _fgcolor; // label's foreground color @@ -101,9 +101,9 @@ class Fl_Tree_Prefs { Fl_Color _inactivecolor; // inactive color Fl_Color _connectorcolor; // connector dotted line color Fl_Tree_Connector _connectorstyle; // connector line style - Fl_Pixmap *_openpixmap; // the 'open' icon [+] - Fl_Pixmap *_closepixmap; // the 'close' icon [-] - Fl_Pixmap *_userpixmap; // user's own icon + Fl_Image *_openimage; // the 'open' icon [+] + Fl_Image *_closeimage; // the 'close' icon [-] + Fl_Image *_userimage; // user's own icon char _showcollapse; // 1=show collapse icons, 0=don't char _showroot; // show the root item as part of the tree Fl_Tree_Sort _sortorder; // none, ascening, descending, etc. @@ -268,28 +268,28 @@ public: // Icons //////////////////////////// /// Get the current default 'open' icon. - /// Returns the Fl_Pixmap* of the icon, or 0 if none. + /// Returns the Fl_Image* of the icon, or 0 if none. /// - inline Fl_Pixmap *openicon() const { - return(_openpixmap); + inline Fl_Image *openicon() const { + return(_openimage); } - void openicon(Fl_Pixmap *val); + void openicon(Fl_Image *val); /// Gets the default 'close' icon - /// Returns the Fl_Pixmap* of the icon, or 0 if none. + /// Returns the Fl_Image* of the icon, or 0 if none. /// - inline Fl_Pixmap *closeicon() const { - return(_closepixmap); + inline Fl_Image *closeicon() const { + return(_closeimage); } - void closeicon(Fl_Pixmap *val); + void closeicon(Fl_Image *val); /// Gets the default 'user icon' (default is 0) - inline Fl_Pixmap *usericon() const { - return(_userpixmap); + inline Fl_Image *usericon() const { + return(_userimage); } /// Sets the default 'user icon' - /// Returns the Fl_Pixmap* of the icon, or 0 if none (default). + /// Returns the Fl_Image* of the icon, or 0 if none (default). /// - inline void usericon(Fl_Pixmap *val) { - _userpixmap = val; + inline void usericon(Fl_Image *val) { + _userimage = val; } //////////////////////////// diff --git a/src/Fl_Tree.cxx b/src/Fl_Tree.cxx index 843439e11..e946ccaf5 100644 --- a/src/Fl_Tree.cxx +++ b/src/Fl_Tree.cxx @@ -123,6 +123,18 @@ Fl_Tree_Item* Fl_Tree::insert_above(Fl_Tree_Item *above, const char *name) { return(above->insert_above(_prefs, name)); } +/// Insert a new item into a tree-item's children at a specified position. +/// \returns the item that was added. +Fl_Tree_Item* Fl_Tree::insert(Fl_Tree_Item *item, const char *name, int pos) { + return(item->insert(_prefs, name, pos)); +} + +/// Add a new child to a tree-item. +/// \returns the item that was added. +Fl_Tree_Item* Fl_Tree::add(Fl_Tree_Item *item, const char *name) { + return(item->add(_prefs, name)); +} + /// Find the item, given a menu style path, eg: "/Parent/Child/item". /// /// There is both a const and non-const version of this method. @@ -209,11 +221,11 @@ int Fl_Tree::handle(int e) { if ( ! _root ) return(ret); switch ( e ) { case FL_PUSH: { - lastselect = 0; - item_clicked(0); // assume no item was clicked - Fl_Tree_Item *o = _root->find_clicked(_prefs); - if ( o ) { - ret |= 1; // handled + lastselect = 0; + item_clicked(0); // assume no item was clicked + Fl_Tree_Item *o = _root->find_clicked(_prefs); + if ( o ) { + ret |= 1; // handled if ( Fl::event_button() == FL_LEFT_MOUSE ) { // Was collapse icon clicked? if ( o->event_on_collapse_icon(_prefs) ) { @@ -226,9 +238,10 @@ int Fl_Tree::handle(int e) { callback() && (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { item_clicked(o); // save item clicked + // Handle selection behavior switch ( _prefs.selectmode() ) { - case FL_TREE_SELECT_NONE: { // no selection changes + case FL_TREE_SELECT_NONE: { // no selection changes break; } case FL_TREE_SELECT_SINGLE: { @@ -243,7 +256,7 @@ int Fl_Tree::handle(int e) { changed = 1; // changed } } else if ( state & FL_CTRL ) { - changed = 1; // changed + changed = 1; // changed o->select_toggle(); // toggle selection state lastselect = o; // save we toggled it (prevents oscillation) } else { @@ -252,8 +265,9 @@ int Fl_Tree::handle(int e) { break; } } + if ( changed ) { - redraw(); // make change(s) visible + redraw(); // make change(s) visible if ( when() & FL_WHEN_CHANGED ) { set_changed(); do_callback((Fl_Widget*)this, user_data()); // item callback @@ -261,22 +275,22 @@ int Fl_Tree::handle(int e) { } } } - } - break; + } + break; } case FL_DRAG: { - Fl_Tree_Item *o = _root->find_clicked(_prefs); - if ( o ) { + Fl_Tree_Item *o = _root->find_clicked(_prefs); + if ( o ) { ret |= 1; // handled // Item's label clicked? if ( o->event_on_label(_prefs) && - (!o->widget() || !Fl::event_inside(o->widget())) && - callback() && - (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { + (!o->widget() || !Fl::event_inside(o->widget())) && + callback() && + (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { item_clicked(o); // save item clicked // Handle selection behavior switch ( _prefs.selectmode() ) { - case FL_TREE_SELECT_NONE: { // no selection changes + case FL_TREE_SELECT_NONE: { // no selection changes break; } case FL_TREE_SELECT_SINGLE: { @@ -301,20 +315,20 @@ int Fl_Tree::handle(int e) { } } if ( changed ) { - redraw(); // make change(s) visible + redraw(); // make change(s) visible if ( when() & FL_WHEN_CHANGED ) { set_changed(); do_callback((Fl_Widget*)this, user_data()); // item callback } } } - } + } } case FL_RELEASE: { - if ( Fl::event_button() == FL_LEFT_MOUSE ) { + if ( Fl::event_button() == FL_LEFT_MOUSE ) { ret |= 1; - } - break; + } + break; } } return(ret); @@ -327,7 +341,7 @@ int Fl_Tree::handle(int e) { /// ie. how many items were "changed". /// int Fl_Tree::deselect_all(Fl_Tree_Item *item) { - item = item ? item : root(); // NULL? use root() + item = item ? item : root(); // NULL? use root() int count = item->deselect_all(); if ( count ) redraw(); // anything changed? cause redraw return(count); @@ -343,17 +357,17 @@ int Fl_Tree::select_only(Fl_Tree_Item *selitem) { int changed = 0; for ( Fl_Tree_Item *item = first(); item; item = item->next() ) { if ( item == selitem ) { - if ( item->is_selected() ) continue; // don't count if already selected - item->select(); - ++changed; + if ( item->is_selected() ) continue; // don't count if already selected + item->select(); + ++changed; } else { - if ( item->is_selected() ) { + if ( item->is_selected() ) { item->deselect(); ++changed; - } + } } } - if ( changed ) redraw(); // anything changed? redraw + if ( changed ) redraw(); // anything changed? redraw return(changed); } diff --git a/src/Fl_Tree_Item.cxx b/src/Fl_Tree_Item.cxx index 9d93f6d9e..cf92b7078 100644 --- a/src/Fl_Tree_Item.cxx +++ b/src/Fl_Tree_Item.cxx @@ -74,7 +74,7 @@ Fl_Tree_Item::~Fl_Tree_Item() { _label = 0; } _widget = 0; // Fl_Group will handle destruction - _usericon = 0; // user handled allocation + _usericon = 0; // user handled allocation //_children.clear(); // array's destructor handles itself } @@ -103,6 +103,7 @@ Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Item *o) { _label_xywh[2] = o->_label_xywh[2]; _label_xywh[3] = o->_label_xywh[3]; _usericon = o->usericon(); + _userdata = 0; _parent = o->_parent; } @@ -119,7 +120,7 @@ void Fl_Tree_Item::show_self(const char *indent) const { strcpy(i2, indent); strcat(i2, " |"); for ( int t=0; tshow_self(i2); + child(t)->show_self(i2); } } fflush(stdout); @@ -153,11 +154,11 @@ void Fl_Tree_Item::clear_children() { int Fl_Tree_Item::find_child(const char *name) { if ( name ) { for ( int t=0; tlabel() ) { + if ( child(t)->label() ) { if ( strcmp(child(t)->label(), name) == 0 ) { return(t); } - } + } } } return(-1); @@ -171,13 +172,13 @@ int Fl_Tree_Item::find_child(const char *name) { const Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) const { for ( int t=0; tlabel() ) { - if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? + if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? if ( *(arr+1) ) { // more in arr? descend return(_children[t]->find_item(arr+1)); } else { // end of arr? done return(_children[t]); } - } + } } } return(0); @@ -191,13 +192,13 @@ const Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) const { Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) { for ( int t=0; tlabel() ) { - if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? + if ( strcmp(child(t)->label(), *arr) == 0 ) { // match? if ( *(arr+1) ) { // more in arr? descend return(_children[t]->find_item(arr+1)); } else { // end of arr? done return(_children[t]); } - } + } } } return(0); @@ -211,7 +212,7 @@ Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) { int Fl_Tree_Item::find_child(Fl_Tree_Item *item) { for ( int t=0; t_parent = this; switch ( prefs.sortorder() ) { case FL_TREE_SORT_NONE: { - _children.add(item); - return(item); + _children.add(item); + return(item); } case FL_TREE_SORT_ASCENDING: { - for ( int t=0; t<_children.total(); t++ ) { + for ( int t=0; t<_children.total(); t++ ) { Fl_Tree_Item *c = _children[t]; if ( c->label() && strcmp(c->label(), new_label) > 0 ) { _children.insert(t, item); return(item); } - } - _children.add(item); - return(item); + } + _children.add(item); + return(item); } case FL_TREE_SORT_DESCENDING: { - for ( int t=0; t<_children.total(); t++ ) { + for ( int t=0; t<_children.total(); t++ ) { Fl_Tree_Item *c = _children[t]; if ( c->label() && strcmp(c->label(), new_label) < 0 ) { _children.insert(t, item); return(item); } - } - _children.add(item); - return(item); + } + _children.add(item); + return(item); } } return(item); @@ -292,7 +293,7 @@ Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char for ( int t=0; tchildren(); t++ ) { Fl_Tree_Item *c = p->child(t); if ( this == c ) { - return(p->insert(prefs, new_label, t)); + return(p->insert(prefs, new_label, t)); } } return(0); @@ -304,9 +305,9 @@ Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char int Fl_Tree_Item::remove_child(Fl_Tree_Item *item) { for ( int t=0; tclear_children(); - _children.remove(t); - return(0); + item->clear_children(); + _children.remove(t); + return(0); } } return(-1); @@ -318,10 +319,10 @@ int Fl_Tree_Item::remove_child(Fl_Tree_Item *item) { int Fl_Tree_Item::remove_child(const char *name) { for ( int t=0; tlabel() ) { - if ( strcmp(child(t)->label(), name) == 0 ) { + if ( strcmp(child(t)->label(), name) == 0 ) { _children.remove(t); return(0); - } + } } } return(-1); @@ -368,17 +369,17 @@ void Fl_Tree_Item::draw_horizontal_connector(int x1, int x2, int y, const Fl_Tre fl_color(prefs.connectorcolor()); switch ( prefs.connectorstyle() ) { case FL_TREE_CONNECTOR_SOLID: - y |= 1; // force alignment w/dot pattern - fl_line(x1,y,x2,y); - return; + y |= 1; // force alignment w/dot pattern + fl_line(x1,y,x2,y); + return; case FL_TREE_CONNECTOR_DOTTED: - y |= 1; // force alignment w/dot pattern - for ( int xx=x1; xx<=x2; xx++ ) { + y |= 1; // force alignment w/dot pattern + for ( int xx=x1; xx<=x2; xx++ ) { if ( !(xx & 1) ) fl_point(xx, y); - } - return; + } + return; case FL_TREE_CONNECTOR_NONE: - return; + return; } } @@ -387,19 +388,19 @@ void Fl_Tree_Item::draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_ fl_color(prefs.connectorcolor()); switch ( prefs.connectorstyle() ) { case FL_TREE_CONNECTOR_SOLID: - y1 |= 1; // force alignment w/dot pattern - y2 |= 1; // force alignment w/dot pattern - fl_line(x,y1,x,y2); - return; + y1 |= 1; // force alignment w/dot pattern + y2 |= 1; // force alignment w/dot pattern + fl_line(x,y1,x,y2); + return; case FL_TREE_CONNECTOR_DOTTED: - y1 |= 1; // force alignment w/dot pattern - y2 |= 1; // force alignment w/dot pattern - for ( int yy=y1; yy<=y2; yy++ ) { + y1 |= 1; // force alignment w/dot pattern + y2 |= 1; // force alignment w/dot pattern + for ( int yy=y1; yy<=y2; yy++ ) { if ( yy & 1 ) fl_point(x, yy); - } - return; + } + return; case FL_TREE_CONNECTOR_NONE: - return; + return; } } @@ -418,15 +419,15 @@ const Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) const } else { // See if event is over us if ( event_inside(_xywh) ) { // event within this item? - return(this); // found + return(this); // found } } if ( is_open() ) { // open? check children of this item for ( int t=0; tfind_clicked(prefs) ) != NULL) { // check child and its descendents + const Fl_Tree_Item *item; + if ( ( item = _children[t]->find_clicked(prefs) ) != NULL) { // check child and its descendents return(item); // found? - } + } } } return(0); @@ -448,15 +449,15 @@ Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) { } else { // See if event is over us if ( event_inside(_xywh) ) { // event within this item? - return(this); // found + return(this); // found } } if ( is_open() ) { // open? check children of this item for ( int t=0; tfind_clicked(prefs) ) != NULL ) { // check child and its descendents + Fl_Tree_Item *item; + if ( ( item = _children[t]->find_clicked(prefs) ) != NULL ) { // check child and its descendents return(item); // found? - } + } } } return(0); @@ -467,7 +468,9 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree, const Fl_Tree_Prefs &prefs, int lastchild) { if ( ! _visible ) return; fl_font(_labelfont, _labelsize); - int H = _labelsize + fl_descent() + prefs.linespacing(); + int H = _labelsize; + if(usericon() && H < usericon()->h()) H = usericon()->h(); + H += prefs.linespacing() + fl_descent(); // Colors, fonts Fl_Color fg = _selected ? prefs.bgcolor() : _labelfgcolor; Fl_Color bg = _selected ? prefs.selectcolor() : _labelbgcolor; @@ -500,95 +503,97 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree, if ( drawthis ) { // Draw connectors if ( prefs.connectorstyle() != FL_TREE_CONNECTOR_NONE ) { - // Horiz connector between center of icon and text - draw_horizontal_connector(hstartx, hendx, textycenter, prefs); - if ( has_children() && is_open() ) { + // Horiz connector between center of icon and text + draw_horizontal_connector(hstartx, hendx, textycenter, prefs); + if ( has_children() && is_open() ) { // Small vertical line down to children draw_vertical_connector(hcenterx, textycenter, Y+H, prefs); - } - // Connectors for last child - if ( ! is_root() ) { + } + // Connectors for last child + if ( ! is_root() ) { if ( lastchild ) { draw_vertical_connector(hstartx, Y, textycenter, prefs); } else { draw_vertical_connector(hstartx, Y, Y+H, prefs); } - } + } } // Draw collapse icon if ( has_children() && prefs.showcollapse() ) { - // Draw icon image - if ( is_open() ) { + // Draw icon image + if ( is_open() ) { prefs.closeicon()->draw(icon_x,icon_y); - } else { + } else { prefs.openicon()->draw(icon_x,icon_y); - } + } } // Background for this item int &bx = _label_xywh[0] = X+(icon_w/2-1+prefs.connectorwidth()); int &by = _label_xywh[1] = Y; int &bw = _label_xywh[2] = W-(icon_w/2-1+prefs.connectorwidth()); - int &bh = _label_xywh[3] = texth; + int &bh = _label_xywh[3] = H; // Draw bg only if different from tree's bg if ( bg != tree->color() || is_selected() ) { - if ( is_selected() ) { + if ( is_selected() ) { // Selected? Use selectbox() style fl_draw_box(prefs.selectbox(), bx, by, bw, bh, bg); - } else { + } else { // Not Selected? use plain filled rectangle fl_color(bg); fl_rectf(bx, by, bw, bh); - } + } } // Draw user icon (if any) int useroff = (icon_w/2-1+prefs.connectorwidth()); if ( usericon() ) { - // Item has user icon? Use it - useroff += prefs.usericonmarginleft(); - usericon()->draw(X+useroff,icon_y); - useroff += usericon()->w(); + // Item has user icon? Use it + useroff += prefs.usericonmarginleft(); + icon_y = textycenter - (usericon()->h() >> 1); + usericon()->draw(X+useroff,icon_y); + useroff += usericon()->w(); } else if ( prefs.usericon() ) { - // Prefs has user icon? Use it - useroff += prefs.usericonmarginleft(); - prefs.usericon()->draw(X+useroff,icon_y); - useroff += prefs.usericon()->w(); + // Prefs has user icon? Use it + useroff += prefs.usericonmarginleft(); + icon_y = textycenter - (prefs.usericon()->h() >> 1); + prefs.usericon()->draw(X+useroff,icon_y); + useroff += prefs.usericon()->w(); } useroff += prefs.labelmarginleft(); // Draw label if ( widget() ) { - // Widget? Draw it - int lx = X+useroff; - int ly = by; - int lw = widget()->w(); - int lh = bh; - if ( widget()->x() != lx || widget()->y() != ly || + // Widget? Draw it + int lx = X+useroff; + int ly = by; + int lw = widget()->w(); + int lh = bh; + if ( widget()->x() != lx || widget()->y() != ly || widget()->w() != lw || widget()->h() != lh ) { widget()->resize(lx, ly, lw, lh); // fltk will handle drawing this - } + } } else { - // No label widget? Draw text label - if ( _label ) { + // No label widget? Draw text label + if ( _label ) { fl_color(fg); fl_draw(_label, X+useroff, Y+H-fl_descent()-1); - } + } } Y += H; } // end drawthis // Draw children if ( has_children() && is_open() ) { - int child_x = drawthis ? // offset children to right, - (hcenterx - (icon_w/2) + 1) : X; // unless didn't drawthis + int child_x = drawthis ? // offset children to right, + (hcenterx - (icon_w/2) + 1) : X; // unless didn't drawthis int child_w = W - (child_x-X); int child_y_start = Y; for ( int t=0; tdraw(child_x, Y, child_w, tree, prefs, lastchild); + int lastchild = ((t+1)==children()) ? 1 : 0; + _children[t]->draw(child_x, Y, child_w, tree, prefs, lastchild); } if ( has_children() && is_open() ) { - Y += prefs.openchild_marginbottom(); // offset below open child tree + Y += prefs.openchild_marginbottom(); // offset below open child tree } if ( ! lastchild ) { - draw_vertical_connector(hstartx, child_y_start, Y, prefs); + draw_vertical_connector(hstartx, child_y_start, Y, prefs); } } } @@ -620,7 +625,7 @@ void Fl_Tree_Item::show_widgets() { if ( _widget ) _widget->show(); if ( is_open() ) { for ( int t=0; t<_children.total(); t++ ) { - _children[t]->show_widgets(); + _children[t]->show_widgets(); } } } @@ -681,9 +686,9 @@ Fl_Tree_Item *Fl_Tree_Item::next() { return(c->child(0)); } while ( ( p = c->parent() ) != NULL ) { // loop upwards through parents - int t = p->find_child(c); // find our position in parent's children[] array - if ( ++t < p->children() ) // not last child? - return(p->child(t)); // return next child + int t = p->find_child(c); // find our position in parent's children[] array + if ( ++t < p->children() ) // not last child? + return(p->child(t)); // return next child c = p; // child becomes parent to move up generation } // loop: moves up to next parent return(0); // hit root? done @@ -698,13 +703,13 @@ Fl_Tree_Item *Fl_Tree_Item::next() { /// Fl_Tree_Item *Fl_Tree_Item::prev() { Fl_Tree_Item *p=parent(); // start with parent - if ( ! p ) return(0); // hit root? done - int t = p->find_child(this); // find our position in parent's children[] array + if ( ! p ) return(0); // hit root? done + int t = p->find_child(this); // find our position in parent's children[] array if ( --t == -1 ) { // are we first child? - return(p); // return immediate parent + return(p); // return immediate parent } p = p->child(t); // take parent's previous child - while ( p->has_children() ) { // has children? + while ( p->has_children() ) { // has children? p = p->child(p->children()-1); // take last child } return(p); diff --git a/src/Fl_Tree_Item_Array.cxx b/src/Fl_Tree_Item_Array.cxx index be0216b44..5f37ce8e2 100644 --- a/src/Fl_Tree_Item_Array.cxx +++ b/src/Fl_Tree_Item_Array.cxx @@ -68,8 +68,8 @@ Fl_Tree_Item_Array::Fl_Tree_Item_Array(const Fl_Tree_Item_Array* o) { void Fl_Tree_Item_Array::clear() { if ( _items ) { for ( int t=0; t<_total; t++ ) { - delete _items[t]; - _items[t] = 0; + delete _items[t]; + _items[t] = 0; } free((void*)_items); _items = 0; } @@ -88,9 +88,9 @@ void Fl_Tree_Item_Array::enlarge(int count) { int newsize = _size + _chunksize; Fl_Tree_Item **newitems = (Fl_Tree_Item**)malloc(newsize * sizeof(Fl_Tree_Item*)); if ( _items ) { - // Copy old array -> new, delete old - memmove(newitems, _items, _size * sizeof(Fl_Tree_Item*)); - free((void*)_items); _items = 0; + // Copy old array -> new, delete old + memmove(newitems, _items, _size * sizeof(Fl_Tree_Item*)); + free((void*)_items); _items = 0; } // Adjust items/sizeitems _items = newitems; @@ -145,8 +145,8 @@ void Fl_Tree_Item_Array::remove(int index) { int Fl_Tree_Item_Array::remove(Fl_Tree_Item *item) { for ( int t=0; t<_total; t++ ) { if ( item == _items[t] ) { - remove(t); - return(0); + remove(t); + return(0); } } return(-1); diff --git a/src/Fl_Tree_Prefs.cxx b/src/Fl_Tree_Prefs.cxx index 2c81c7ab9..4adee203d 100644 --- a/src/Fl_Tree_Prefs.cxx +++ b/src/Fl_Tree_Prefs.cxx @@ -73,19 +73,19 @@ static Fl_Pixmap L_closepixmap(L_close_xpm); /// when items are add()ed to the tree. /// This overrides the built in default '[+]' icon. /// -/// \param[in] val -- The new pixmap, or zero to use the default [+] icon. +/// \param[in] val -- The new image, or zero to use the default [+] icon. /// -void Fl_Tree_Prefs::openicon(Fl_Pixmap *val) { - _openpixmap = val ? val : &L_openpixmap; +void Fl_Tree_Prefs::openicon(Fl_Image *val) { + _openimage = val ? val : &L_openpixmap; } /// Sets the icon to be used as the 'close' icon. /// This overrides the built in default '[-]' icon. /// -/// \param[in] val -- The new pixmap, or zero to use the default [-] icon. +/// \param[in] val -- The new image, or zero to use the default [-] icon. /// -void Fl_Tree_Prefs::closeicon(Fl_Pixmap *val) { - _closepixmap = val ? val : &L_closepixmap; +void Fl_Tree_Prefs::closeicon(Fl_Image *val) { + _closeimage = val ? val : &L_closepixmap; } /// Fl_Tree_Prefs constructor @@ -106,9 +106,9 @@ Fl_Tree_Prefs::Fl_Tree_Prefs() { _inactivecolor = FL_GRAY; _connectorcolor = Fl_Color(43); _connectorstyle = FL_TREE_CONNECTOR_DOTTED; - _openpixmap = &L_openpixmap; - _closepixmap = &L_closepixmap; - _userpixmap = 0; + _openimage = &L_openpixmap; + _closeimage = &L_closepixmap; + _userimage = 0; _showcollapse = 1; _showroot = 1; _connectorwidth = 17; @@ -118,9 +118,9 @@ Fl_Tree_Prefs::Fl_Tree_Prefs() { // Let fltk's current 'scheme' affect defaults if ( Fl::scheme() ) { if ( strcmp(Fl::scheme(), "gtk+") == 0 ) { - _selectbox = _FL_GTK_THIN_UP_BOX; + _selectbox = _FL_GTK_THIN_UP_BOX; } else if ( strcmp(Fl::scheme(), "plastic") == 0 ) { - _selectbox = _FL_PLASTIC_THIN_UP_BOX; + _selectbox = _FL_PLASTIC_THIN_UP_BOX; } } }