1 //
2 // "$Id: Fl_Tree_Item.H 8340 2011-01-30 20:22:06Z greg.ercolano $"
3 //
4 
5 #ifndef FL_TREE_ITEM_H
6 #define FL_TREE_ITEM_H
7 
8 #include <FL/Fl.H>
9 #include <FL/Fl_Widget.H>
10 #include <FL/Fl_Image.H>
11 #include <FL/fl_draw.H>
12 
13 #include <FL/Fl_Tree_Item_Array.H>
14 #include <FL/Fl_Tree_Prefs.H>
15 
16 //////////////////////
17 // FL/Fl_Tree_Item.H
18 //////////////////////
19 //
20 // Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
21 // Copyright (C) 2009-2010 by Greg Ercolano.
22 //
23 // This library is free software; you can redistribute it and/or
24 // modify it under the terms of the GNU Library General Public
25 // License as published by the Free Software Foundation; either
26 // version 2 of the License, or (at your option) any later version.
27 //
28 // This library is distributed in the hope that it will be useful,
29 // but WITHOUT ANY WARRANTY; without even the implied warranty of
30 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
31 // Library General Public License for more details.
32 //
33 // You should have received a copy of the GNU Library General Public
34 // License along with this library; if not, write to the Free Software
35 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
36 // USA.
37 //
38 
39 ///
40 /// \file
41 /// \brief This file contains the definitions for Fl_Tree_Item
42 ///
43 
44 /// \brief Tree item
45 ///
46 /// This class is a single tree item, and manages all of the item's attributes.
47 /// Fl_Tree_Item is used by Fl_Tree, which is comprised of many instances of Fl_Tree_Item.
48 ///
49 /// Fl_Tree_Item is hierarchical; it dynamically manages an Fl_Tree_Item_Array of children
50 /// that are themselves instances of Fl_Tree_Item. Each item can have zero or more children.
51 /// When an item has children, close() and open() can be used to hide or show them.
52 ///
53 /// Items have their own attributes; font size, face, color.
54 /// Items maintain their own hierarchy of children.
55 ///
56 /// When you make changes to items, you'll need to tell the tree to redraw()
57 /// for the changes to show up.
58 ///
59 class FL_EXPORT Fl_Tree_Item {
60   const char             *_label;		// label (memory managed)
61   Fl_Font                 _labelfont;		// label's font face
62   Fl_Fontsize             _labelsize;		// label's font size
63   Fl_Color                _labelfgcolor;	// label's fg color
64   Fl_Color                _labelbgcolor;	// label's bg color
65   char                    _open;		// item is open?
66   char                    _visible;		// item is visible?
67   char                    _active;		// item activated?
68   char                    _selected;		// item selected?
69   int                     _xywh[4];		// xywh of this widget (if visible)
70   int                     _collapse_xywh[4];	// xywh of collapse icon (if any)
71   int                     _label_xywh[4];	// xywh of label
72   Fl_Widget              *_widget;		// item's label widget (optional)
73   Fl_Image               *_usericon;		// item's user-specific icon (optional)
74   Fl_Tree_Item_Array      _children;		// array of child items
75   Fl_Tree_Item           *_parent;		// parent item (=0 if root)
76   void                   *_userdata;    	// user data that can be associated with an item
77 protected:
78   void show_widgets();
79   void hide_widgets();
80   void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs);
81   void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs);
82 public:
83   Fl_Tree_Item(const Fl_Tree_Prefs &prefs);	// CTOR
84   ~Fl_Tree_Item();				// DTOR
85   Fl_Tree_Item(const Fl_Tree_Item *o);		// COPY CTOR
x()86   int x() const { return(_xywh[0]); }
y()87   int y() const { return(_xywh[1]); }
w()88   int w() const { return(_xywh[2]); }
h()89   int h() const { return(_xywh[3]); }
90   void draw(int X, int &Y, int W, Fl_Widget *tree, Fl_Tree_Item *itemfocus, const Fl_Tree_Prefs &prefs, int lastchild=1);
91   void show_self(const char *indent = "") const;
92   void label(const char *val);
93   const char *label() const;
94 
95   /// Set a user-data value for the item.
user_data(void * data)96   inline void user_data( void* data ) { _userdata = data; }
97 
98   /// Retrieve the user-data value that has been assigned to the item.
user_data()99   inline void* user_data() const { return _userdata; }
100 
101   /// Set item's label font face.
labelfont(Fl_Font val)102   void labelfont(Fl_Font val) {
103     _labelfont = val;
104   }
105   /// Get item's label font face.
labelfont()106   Fl_Font labelfont() const {
107     return(_labelfont);
108   }
109   /// Set item's label font size.
labelsize(Fl_Fontsize val)110   void labelsize(Fl_Fontsize val) {
111     _labelsize = val;
112   }
113   /// Get item's label font size.
labelsize()114   Fl_Fontsize labelsize() const {
115     return(_labelsize);
116   }
117   /// Set item's label foreground text color.
labelfgcolor(Fl_Color val)118   void labelfgcolor(Fl_Color val) {
119     _labelfgcolor = val;
120   }
121   /// Set item's label text color.
labelcolor(Fl_Color val)122   void labelcolor(Fl_Color val) {
123     _labelfgcolor = val;
124   }
125   /// Return item's label text color.
labelcolor()126   Fl_Color labelcolor() const {
127     return(_labelfgcolor);
128   }
129   /// Return item's label foreground text color.
labelfgcolor()130   Fl_Color labelfgcolor() const {
131     return(_labelfgcolor);
132   }
133   /// Set item's label background color.
labelbgcolor(Fl_Color val)134   void labelbgcolor(Fl_Color val) {
135     _labelbgcolor = val;
136   }
137   /// Return item's background text color.
labelbgcolor()138   Fl_Color labelbgcolor() const {
139     return(_labelbgcolor);
140   }
141   /// Assign an FLTK widget to this item.
widget(Fl_Widget * val)142   void widget(Fl_Widget *val) {
143     _widget = val;
144   }
145   /// Return FLTK widget assigned to this item.
widget()146   Fl_Widget *widget() const {
147     return(_widget);
148   }
149   /// Return the number of children this item has.
children()150   int children() const {
151     return(_children.total());
152   }
153   /// Return the child item for the given 'index'.
child(int index)154   Fl_Tree_Item *child(int index) {
155     return(_children[index]);
156   }
157   /// Return the const child item for the given 'index'.
158   const Fl_Tree_Item *child(int t) const;
159   /// See if this item has children.
has_children()160   int has_children() const {
161     return(children());
162   }
163   int find_child(const char *name);
164   int find_child(Fl_Tree_Item *item);
165   int remove_child(Fl_Tree_Item *item);
166   int remove_child(const char *new_label);
167   void clear_children();
168   void swap_children(int ax, int bx);
169   int swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b);
170   const Fl_Tree_Item *find_child_item(char **arr) const;	// const
171         Fl_Tree_Item *find_child_item(char **arr);		// non-const
172   const Fl_Tree_Item *find_item(char **arr) const;		// const
173         Fl_Tree_Item *find_item(char **arr);			// non-const
174   //////////////////
175   // Adding items
176   //////////////////
177   Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, const char *new_label);
178   Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, char **arr);
179   Fl_Tree_Item *insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos=0);
180   Fl_Tree_Item *insert_above(const Fl_Tree_Prefs &prefs, const char *new_label);
181   int depth() const;
182   Fl_Tree_Item *prev();
183   Fl_Tree_Item *next();
184   Fl_Tree_Item *next_sibling();
185   Fl_Tree_Item *prev_sibling();
186   Fl_Tree_Item *next_displayed(Fl_Tree_Prefs &prefs);
187   Fl_Tree_Item *prev_displayed(Fl_Tree_Prefs &prefs);
188 
189   /// Return the parent for this item. Returns NULL if we are the root.
parent()190   Fl_Tree_Item *parent() {
191     return(_parent);
192   }
193   /// Return the const parent for this item. Returns NULL if we are the root.
parent()194   const Fl_Tree_Item *parent() const {
195     return(_parent);
196   }
197   /// Set the parent for this item.
198   /// Should only be used by Fl_Tree's internals.
199   ///
parent(Fl_Tree_Item * val)200   void parent(Fl_Tree_Item *val) {
201     _parent = val;
202   }
203   //////////////////
204   // State
205   //////////////////
206   void open();
207   void close();
208   /// See if the item is 'open'.
is_open()209   int is_open() const {
210     return(_open?1:0);
211   }
212   /// See if the item is 'closed'.
is_close()213   int is_close() const {
214     return(_open?0:1);
215   }
216   /// Toggle the item's open/closed state.
open_toggle()217   void open_toggle() {
218     _open?close():open();
219   }
220   /// Change the item's selection state to the optionally specified 'val'.
221   /// If 'val' is not specified, the item will be selected.
222   ///
223   void select(int val=1) {
224     _selected = val;
225   }
226   /// Toggle the item's selection state.
select_toggle()227   void select_toggle() {
228     if ( is_selected() ) {
229       deselect();		// deselect if selected
230     } else {
231       select();		// select if deselected
232     }
233   }
234   /// Select self and all children
235   ///     Returns count of how many items were in the 'deselected' state,
236   ///     ie. how many items were "changed".
237   ///
select_all()238   int select_all() {
239     int count = 0;
240     if ( ! is_selected() ) {
241       select();
242       ++count;
243     }
244     for ( int t=0; t<children(); t++ ) {
245       count += child(t)->select_all();
246     }
247     return(count);
248   }
249   /// Disable the item's selection state.
deselect()250   void deselect() {
251     _selected = 0;
252   }
253   /// Deselect self and all children
254   ///     Returns count of how many items were in the 'selected' state,
255   ///     ie. how many items were "changed".
256   ///
deselect_all()257   int deselect_all() {
258     int count = 0;
259     if ( is_selected() ) {
260       deselect();
261       ++count;
262     }
263     for ( int t=0; t<children(); t++ ) {
264       count += child(t)->deselect_all();
265     }
266     return(count);
267   }
268   /// See if the item is selected.
is_selected()269   char is_selected() const {
270     return(_selected);
271   }
272   /// Change the item's activation state to the optionally specified 'val'.
273   ///
274   /// When deactivated, the item will be 'grayed out'; the callback()
275   /// won't be invoked if the user clicks on the label. If the item
276   /// has a widget() associated with the item, its activation state
277   /// will be changed as well.
278   ///
279   /// If 'val' is not specified, the item will be activated.
280   ///
281   void activate(int val=1) {
282     _active = val;
283     if ( _widget && val != (int)_widget->active() ) {
284       if ( val ) {
285 	_widget->activate();
286       } else {
287 	_widget->deactivate();
288       }
289       _widget->redraw();
290     }
291   }
292   /// Deactivate the item; the callback() won't be invoked when clicked.
293   /// Same as activate(0)
294   ///
deactivate()295   void deactivate() {
296     activate(0);
297   }
298   /// See if the item is activated.
is_activated()299   char is_activated() const {
300     return(_active);
301   }
302   /// See if the item is activated.
is_active()303   char is_active() const {
304     return(_active);
305   }
306   /// See if the item is visible.
visible()307   int visible() const {
308     return(_visible ? 1 : 0);
309   }
310   int visible_r() const;
311 
312   /// Set the user icon's image. '0' will disable.
usericon(Fl_Image * val)313   void usericon(Fl_Image *val) {
314     _usericon = val;
315   }
316   /// Get the user icon. Returns '0' if disabled.
usericon()317   Fl_Image *usericon() const {
318     return(_usericon);
319   }
320   //////////////////
321   // Events
322   //////////////////
323   const Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs) const;
324   Fl_Tree_Item *find_clicked(const Fl_Tree_Prefs &prefs);
325   int event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const;
326   int event_on_label(const Fl_Tree_Prefs &prefs) const;
327   /// Is this item the root of the tree?
is_root()328   int is_root() const {
329     return(_parent==0?1:0);
330   }
331 };
332 
333 #endif /*FL_TREE_ITEM_H*/
334 
335 //
336 // End of "$Id: Fl_Tree_Item.H 8340 2011-01-30 20:22:06Z greg.ercolano $".
337 //
338