2 // "$Id: Fl_Tree.H 8632 2011-05-04 02:59:50Z greg.ercolano $"
9 #include <FL/Fl_Group.H>
10 #include <FL/Fl_Scrollbar.H>
11 #include <FL/fl_draw.H>
13 #include <FL/Fl_Tree_Item.H>
14 #include <FL/Fl_Tree_Prefs.H>
16 //////////////////////
18 //////////////////////
20 // Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
21 // Copyright (C) 2009-2010 by Greg Ercolano.
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.
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.
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
41 /// \brief This file contains the definitions of the Fl_Tree class
46 /// \brief Tree widget.
48 /// \image html tree-simple.png "Fl_Tree example program"
49 /// \image latex tree-simple.png "Fl_Tree example program" width=4cm
52 /// Fl_Tree // Top level widget
53 /// |--- Fl_Tree_Item // Items in the tree
54 /// |--- Fl_Tree_Prefs // Preferences for the tree
55 /// |--- Fl_Tree_Connector (enum) // Connection modes
56 /// |--- Fl_Tree_Select (enum) // Selection modes
57 /// |--- Fl_Tree_Sort (enum) // Sort behavior
60 /// Similar to Fl_Browser, Fl_Tree is a browser of Fl_Tree_Item's, which is arranged
61 /// in a parented hierarchy, or 'tree'. Subtrees can be expanded or closed. Items can be
62 /// added, deleted, inserted, sorted and re-ordered.
64 /// The tree items may also contain other FLTK widgets, like buttons, input fields,
65 /// or even "custom" widgets.
67 /// The callback() is invoked depending on the value of when():
69 /// - FL_WHEN_RELEASE -- callback invoked when left mouse button is released on an item
70 /// - FL_WHEN_CHANGED -- callback invoked when left mouse changes selection state
72 /// The simple way to define a tree:
74 /// #include <FL/Fl_Tree.H>
76 /// Fl_Tree tree(X,Y,W,H);
78 /// tree.add("Flintstones/Fred");
79 /// tree.add("Flintstones/Wilma");
80 /// tree.add("Flintstones/Pebbles");
81 /// tree.add("Simpsons/Homer");
82 /// tree.add("Simpsons/Marge");
83 /// tree.add("Simpsons/Bart");
84 /// tree.add("Simpsons/Lisa");
88 /// Items can be added with add(),
89 /// removed with remove(),
90 /// completely cleared with clear(),
91 /// inserted with insert() and insert_above(),
92 /// selected/deselected with select() and deselect(),
93 /// open/closed with open() and closed().
94 /// Children of an item can be swapped around with Fl_Tree_Item::swap_children(),
95 /// sorting can be controlled when items are add()ed via sortorder().
96 /// You can walk the entire tree with first() and next().
97 /// You can walk selected items with first_selected_item() and
98 /// next_selected_item().
99 /// Items can be found by their pathname using find_item(const char*),
100 /// and an item's pathname can be found with item_pathname().
101 /// The selected items' colors are controlled by selection_color() (inherited from Fl_Widget).
103 /// The tree can have different selection behaviors controlled by selectmode().
105 /// FLTK widgets (including custom widgets) can be assigned to tree items via
106 /// Fl_Tree_Item::widget().
108 /// Icons for individual items can be changed with
109 /// Fl_Tree_Item::openicon(),
110 /// Fl_Tree_Item::closeicon(),
111 /// Fl_Tree_Item::usericon().
113 /// Various default preferences can be globally manipulated via Fl_Tree_Prefs,
114 /// including colors, margins, icons, connection lines.
116 /// The tree's callback() will be invoked when items change state or are open/closed.
117 /// when() controls when mouse/keyboard events invoke the callback.
118 /// callback_item() and callback_reason() can be used to determine the cause of the callback. eg:
121 /// void MyTreeCallback(Fl_Widget *w, void *data) {
122 /// Fl_Tree *tree = (Fl_Tree*)w;
123 /// Fl_Tree_Item *item = (Fl_Tree_Item*)tree->callback_item(); // get selected item
124 /// switch ( tree->callback_reason() ) {
125 /// case FL_TREE_REASON_SELECTED: [..]
126 /// case FL_TREE_REASON_DESELECTED: [..]
127 /// case FL_TREE_REASON_OPENED: [..]
128 /// case FL_TREE_REASON_CLOSED: [..]
132 /// To get the item's full menu pathname, you can use Fl_Tree_Item::item_pathname(), eg:
135 /// char pathname[256] = "???";
136 /// tree->item_pathname(pathname, sizeof(pathname), item); // eg. "Parent/Child/Item"
139 /// To walk all the items of the tree from top to bottom:
141 /// // Walk all the items in the tree, and print their labels
142 /// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->next(item) ) {
143 /// printf("Item: %s\n", item->label());
147 /// To recursively walk all the children of a particular item,
148 /// define a function that uses recursion:
150 /// // Find all of the item's children and print an indented report of their labels
151 /// void my_print_all_children(Fl_Tree_Item *item, int indent=0) {
152 /// for ( int t=0; t<item->children(); t++ ) {
153 /// printf("%*s Item: %s\n", indent, "", item->child(t)->label());
154 /// my_print_all_children(item->child(t), indent+4); // recurse
159 /// To change the default label font and color for creating new items:
161 /// tree = new Fl_Tree(..);
162 /// tree->item_labelfont(FL_COURIER); // Use Courier font for all new items
163 /// tree->item_labelfgcolor(FL_RED); // Use red color for labels of all new items
165 /// // Now create the items in the tree using the above defaults.
166 /// tree->add("Aaa");
167 /// tree->add("Bbb");
171 /// To change the font and color of all items in the tree:
173 /// // Change the font and color of all items currently in the tree
174 /// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->next(item) ) {
175 /// item->labelfont(FL_COURIER);
176 /// item->labelcolor(FL_RED);
180 /// The following image shows the tree's various visual elements
181 /// and the methods that control them:
183 /// \image html tree-elements.png
184 /// \image latex tree-elements.png "Fl_Tree dimensions" width=6cm
187 /// \enum Fl_Tree_Reason
188 /// The reason the callback was invoked.
190 enum Fl_Tree_Reason {
191 FL_TREE_REASON_NONE=0, ///< unknown reason
192 FL_TREE_REASON_SELECTED, ///< an item was selected
193 FL_TREE_REASON_DESELECTED, ///< an item was de-selected
194 FL_TREE_REASON_OPENED, ///< an item was opened
195 FL_TREE_REASON_CLOSED ///< an item was closed
199 class FL_EXPORT Fl_Tree : public Fl_Group {
200 Fl_Tree_Item *_root; // can be null!
201 Fl_Tree_Item *_item_focus; // item that has focus box
202 Fl_Tree_Item *_callback_item; // item invoked during callback (can be NULL)
203 Fl_Tree_Reason _callback_reason; // reason for the callback
204 Fl_Tree_Prefs _prefs; // all the tree's settings
205 int _scrollbar_size; // size of scrollbar trough
208 /// Vertical scrollbar
209 Fl_Scrollbar *_vscroll;
212 void item_clicked(Fl_Tree_Item* val);
213 /// Do the callback for the item, setting the item and reason
214 void do_callback_for_item(Fl_Tree_Item* item, Fl_Tree_Reason reason) {
215 callback_reason(reason);
217 do_callback((Fl_Widget*)this, user_data());
219 Fl_Tree_Item *next_visible_item(Fl_Tree_Item *start, int dir);
222 Fl_Tree(int X, int Y, int W, int H, const char *L=0);
227 ///////////////////////
229 ///////////////////////
231 /// Set the label for the root item.
233 /// Makes an internally managed copy of 'new_label'.
235 void root_label(const char *new_label) {
236 if ( ! _root ) return;
237 _root->label(new_label);
239 /// Returns the root item.
240 Fl_Tree_Item* root() {
244 ////////////////////////////////
245 // Item creation/removal methods
246 ////////////////////////////////
247 Fl_Tree_Item *add(const char *path);
248 Fl_Tree_Item* add(Fl_Tree_Item *item, const char *name);
249 Fl_Tree_Item *insert_above(Fl_Tree_Item *above, const char *name);
250 Fl_Tree_Item* insert(Fl_Tree_Item *item, const char *name, int pos);
252 /// Remove the specified \p item from the tree.
253 /// \p item may not be NULL.
254 /// If it has children, all those are removed too.
255 /// \returns 0 if done, -1 if 'item' not found.
257 int remove(Fl_Tree_Item *item) {
258 if ( item == _root ) {
261 Fl_Tree_Item *parent = item->parent(); // find item's parent
262 if ( ! parent ) return(-1);
263 parent->remove_child(item); // remove child + children
267 /// Clear all children from the tree.
268 /// The tree will be left completely empty.
271 if ( ! _root ) return;
272 _root->clear_children();
273 delete _root; _root = 0;
275 /// Clear all the children of a particular node in the tree specified by \p item.
276 /// Item may not be NULL.
278 void clear_children(Fl_Tree_Item *item) {
279 if ( item->has_children() ) {
280 item->clear_children();
281 redraw(); // redraw only if there were children to clear
285 ////////////////////////
286 // Item lookup methods
287 ////////////////////////
288 Fl_Tree_Item *find_item(const char *path);
289 const Fl_Tree_Item *find_item(const char *path) const;
290 int item_pathname(char *pathname, int pathnamelen, const Fl_Tree_Item *item) const;
292 const Fl_Tree_Item *find_clicked() const;
294 /// Return the item that was last clicked.
296 /// Valid only from within the callback().
298 /// Deprecated: use callback_item() instead.
300 /// \returns the item clicked, or 0 if none.
301 /// 0 may also be used to indicate several items were clicked/changed.
303 Fl_Tree_Item *item_clicked() {
304 return(_callback_item);
306 Fl_Tree_Item *first();
307 Fl_Tree_Item *next(Fl_Tree_Item *item=0);
308 Fl_Tree_Item *prev(Fl_Tree_Item *item=0);
309 Fl_Tree_Item *last();
310 Fl_Tree_Item *first_selected_item();
311 Fl_Tree_Item *next_selected_item(Fl_Tree_Item *item=0);
313 //////////////////////////
314 // Item open/close methods
315 //////////////////////////
317 /// Open the specified 'item'.
318 /// This causes the item's children (if any) to be shown.
319 /// Handles redrawing if anything was actually changed.
320 /// Invokes the callback depending on the value of optional parameter \p docallback.
322 /// The callback can use callback_item() and callback_reason() respectively to determine
323 /// the item changed and the reason the callback was called.
325 /// \param[in] item -- the item to be opened. Must not be NULL.
326 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
327 /// - 0 - callback() is not invoked
328 /// - 1 - callback() is invoked if item changed,
329 /// callback_reason() will be FL_TREE_REASON_OPENED
331 /// - 1 -- item was opened
332 /// - 0 -- item was already open, no change
334 /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
336 int open(Fl_Tree_Item *item, int docallback=1) {
337 if ( item->is_open() ) return(0);
341 do_callback_for_item(item, FL_TREE_REASON_OPENED);
345 /// Opens the item specified by \p path (eg: "Parent/child/item").
346 /// This causes the item's children (if any) to be shown.
347 /// Handles redrawing if anything was actually changed.
348 /// Invokes the callback depending on the value of optional parameter \p docallback.
350 /// Items or submenus that themselves contain slashes ('/' or '\')
351 /// should be escaped, e.g. open("Holidays/12\\/25\//2010").
353 /// The callback can use callback_item() and callback_reason() respectively to determine
354 /// the item changed and the reason the callback was called.
356 /// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
357 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
358 /// - 0 - callback() is not invoked
359 /// - 1 - callback() is invoked if item changed,
360 /// callback_reason() will be FL_TREE_REASON_OPENED
362 /// - 1 -- OK: item opened
363 /// - 0 -- OK: item was already open, no change
364 /// - -1 -- ERROR: item was not found
366 /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
368 int open(const char *path, int docallback=1) {
369 Fl_Tree_Item *item = find_item(path);
370 if ( ! item ) return(-1);
371 return(open(item, docallback));
373 /// Toggle the open state of \p item.
374 /// Handles redrawing if anything was actually changed.
375 /// Invokes the callback depending on the value of optional parameter \p docallback.
377 /// The callback can use callback_item() and callback_reason() respectively to determine
378 /// the item changed and the reason the callback was called.
380 /// \param[in] item -- the item whose open state is to be toggled. Must not be NULL.
381 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
382 /// - 0 - callback() is not invoked
383 /// - 1 - callback() is invoked, callback_reason() will be either
384 /// FL_TREE_REASON_OPENED or FL_TREE_REASON_CLOSED
386 /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
388 void open_toggle(Fl_Tree_Item *item, int docallback=1) {
389 if ( item->is_open() ) {
390 close(item, docallback);
392 open(item, docallback);
395 /// Closes the specified \p item.
396 /// Handles redrawing if anything was actually changed.
397 /// Invokes the callback depending on the value of optional parameter \p docallback.
399 /// The callback can use callback_item() and callback_reason() respectively to determine
400 /// the item changed and the reason the callback was called.
402 /// \param[in] item -- the item to be closed. Must not be NULL.
403 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
404 /// - 0 - callback() is not invoked
405 /// - 1 - callback() is invoked if item changed,
406 /// callback_reason() will be FL_TREE_REASON_CLOSED
408 /// - 1 -- item was closed
409 /// - 0 -- item was already closed, no change
411 /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
413 int close(Fl_Tree_Item *item, int docallback=1) {
414 if ( item->is_close() ) return(0);
418 do_callback_for_item(item, FL_TREE_REASON_CLOSED);
422 /// Closes the item specified by \p path, eg: "Parent/child/item".
423 /// Handles redrawing if anything was actually changed.
424 /// Invokes the callback depending on the value of optional parameter \p docallback.
426 /// Items or submenus that themselves contain slashes ('/' or '\')
427 /// should be escaped, e.g. close("Holidays/12\\/25\//2010").
429 /// The callback can use callback_item() and callback_reason() respectively to determine
430 /// the item changed and the reason the callback was called.
432 /// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
433 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
434 /// - 0 - callback() is not invoked
435 /// - 1 - callback() is invoked if item changed,
436 /// callback_reason() will be FL_TREE_REASON_CLOSED
438 /// - 1 -- OK: item closed
439 /// - 0 -- OK: item was already closed, no change
440 /// - -1 -- ERROR: item was not found
442 /// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
444 int close(const char *path, int docallback=1) {
445 Fl_Tree_Item *item = find_item(path);
446 if ( ! item ) return(-1);
447 return(close(item, docallback));
449 /// See if \p item is open.
451 /// Items that are 'open' are themselves not necessarily visible;
452 /// one of the item's parents might be closed.
454 /// \param[in] item -- the item to be tested. Must not be NULL.
456 /// - 1 : item is open
457 /// - 0 : item is closed
459 int is_open(Fl_Tree_Item *item) const {
460 return(item->is_open()?1:0);
462 /// See if item specified by \p path (eg: "Parent/child/item") is open.
464 /// Items or submenus that themselves contain slashes ('/' or '\')
465 /// should be escaped, e.g. is_open("Holidays/12\\/25\//2010").
467 /// Items that are 'open' are themselves not necessarily visible;
468 /// one of the item's parents might be closed.
470 /// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
472 /// - 1 - OK: item is open
473 /// - 0 - OK: item is closed
474 /// - -1 - ERROR: item was not found
476 int is_open(const char *path) const {
477 const Fl_Tree_Item *item = find_item(path);
478 if ( ! item ) return(-1);
479 return(item->is_open()?1:0);
481 /// See if the specified \p item is closed.
483 /// \param[in] item -- the item to be tested. Must not be NULL.
485 /// - 1 : item is open
486 /// - 0 : item is closed
488 int is_close(Fl_Tree_Item *item) const {
489 return(item->is_close());
491 /// See if item specified by \p path (eg: "Parent/child/item") is closed.
493 /// Items or submenus that themselves contain slashes ('/' or '\')
494 /// should be escaped, e.g. is_close("Holidays/12\\/25\//2010").
496 /// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
498 /// - 1 - OK: item is closed
499 /// - 0 - OK: item is open
500 /// - -1 - ERROR: item was not found
502 int is_close(const char *path) const {
503 const Fl_Tree_Item *item = find_item(path);
504 if ( ! item ) return(-1);
505 return(item->is_close()?1:0);
508 /// Select the specified \p item. Use 'deselect()' to de-select it.
509 /// Handles redrawing if anything was actually changed.
510 /// Invokes the callback depending on the value of optional parameter \p docallback.
512 /// The callback can use callback_item() and callback_reason() respectively to determine
513 /// the item changed and the reason the callback was called.
515 /// \param[in] item -- the item to be selected. Must not be NULL.
516 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
517 /// - 0 - the callback() is not invoked
518 /// - 1 - the callback() is invoked if item changed state,
519 /// callback_reason() will be FL_TREE_REASON_SELECTED
521 /// - 1 - item's state was changed
522 /// - 0 - item was already selected, no change was made
524 int select(Fl_Tree_Item *item, int docallback=1) {
525 if ( ! item->is_selected() ) {
529 do_callback_for_item(item, FL_TREE_REASON_SELECTED);
536 /// Select the item specified by \p path (eg: "Parent/child/item").
537 /// Handles redrawing if anything was actually changed.
538 /// Invokes the callback depending on the value of optional parameter \p docallback.
540 /// Items or submenus that themselves contain slashes ('/' or '\')
541 /// should be escaped, e.g. select("Holidays/12\\/25\//2010").
543 /// The callback can use callback_item() and callback_reason() respectively to determine
544 /// the item changed and the reason the callback was called.
546 /// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
547 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
548 /// - 0 - the callback() is not invoked
549 /// - 1 - the callback() is invoked if item changed state,
550 /// callback_reason() will be FL_TREE_REASON_SELECTED
552 /// - 1 : OK: item's state was changed
553 /// - 0 : OK: item was already selected, no change was made
554 /// - -1 : ERROR: item was not found
556 int select(const char *path, int docallback=1) {
557 Fl_Tree_Item *item = find_item(path);
558 if ( ! item ) return(-1);
559 return(select(item, docallback));
561 /// Toggle the select state of the specified \p item.
562 /// Handles redrawing if anything was actually changed.
563 /// Invokes the callback depending on the value of optional parameter \p docallback.
565 /// The callback can use callback_item() and callback_reason() respectively to determine
566 /// the item changed and the reason the callback was called.
568 /// \param[in] item -- the item to be selected. Must not be NULL.
569 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
570 /// - 0 - the callback() is not invoked
571 /// - 1 - the callback() is invoked, callback_reason() will be
572 /// either FL_TREE_REASON_SELECTED or FL_TREE_REASON_DESELECTED
574 void select_toggle(Fl_Tree_Item *item, int docallback=1) {
575 item->select_toggle();
578 do_callback_for_item(item, item->is_selected() ? FL_TREE_REASON_SELECTED
579 : FL_TREE_REASON_DESELECTED);
583 /// De-select the specified \p item.
584 /// Handles redrawing if anything was actually changed.
585 /// Invokes the callback depending on the value of optional parameter \p docallback.
587 /// The callback can use callback_item() and callback_reason() respectively to determine
588 /// the item changed and the reason the callback was called.
590 /// \param[in] item -- the item to be selected. Must not be NULL.
591 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
592 /// - 0 - the callback() is not invoked
593 /// - 1 - the callback() is invoked if item changed state,
594 /// callback_reason() will be FL_TREE_REASON_DESELECTED
596 /// - 0 - item was already deselected, no change was made
597 /// - 1 - item's state was changed
599 int deselect(Fl_Tree_Item *item, int docallback=1) {
600 if ( item->is_selected() ) {
604 do_callback_for_item(item, FL_TREE_REASON_DESELECTED);
611 /// Deselect an item specified by \p path (eg: "Parent/child/item").
612 /// Handles redrawing if anything was actually changed.
613 /// Invokes the callback depending on the value of optional parameter \p docallback.
615 /// Items or submenus that themselves contain slashes ('/' or '\')
616 /// should be escaped, e.g. deselect("Holidays/12\\/25\//2010").
618 /// The callback can use callback_item() and callback_reason() respectively to determine
619 /// the item changed and the reason the callback was called.
621 /// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
622 /// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
623 /// - 0 - the callback() is not invoked
624 /// - 1 - the callback() is invoked if item changed state,
625 /// callback_reason() will be FL_TREE_REASON_DESELECTED
627 /// - 1 - OK: item's state was changed
628 /// - 0 - OK: item was already deselected, no change was made
629 /// - -1 - ERROR: item was not found
631 int deselect(const char *path, int docallback=1) {
632 Fl_Tree_Item *item = find_item(path);
633 if ( ! item ) return(-1);
634 return(deselect(item, docallback));
637 int deselect_all(Fl_Tree_Item *item=0, int docallback=1);
638 int select_only(Fl_Tree_Item *selitem, int docallback=1);
639 int select_all(Fl_Tree_Item *item=0, int docallback=1);
640 void set_item_focus(Fl_Tree_Item *o);
642 /// See if the specified \p item is selected.
644 /// \param[in] item -- the item to be tested. Must not be NULL.
647 /// - 1 : item selected
648 /// - 0 : item deselected
650 int is_selected(Fl_Tree_Item *item) const {
651 return(item->is_selected()?1:0);
653 /// See if item specified by \p path (eg: "Parent/child/item") is selected.
655 /// Items or submenus that themselves contain slashes ('/' or '\')
656 /// should be escaped, e.g. is_selected("Holidays/12\\/25\//2010").
658 /// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
660 /// - 1 : item selected
661 /// - 0 : item deselected
662 /// - -1 : item was not found
664 int is_selected(const char *path) {
665 Fl_Tree_Item *item = find_item(path);
666 if ( ! item ) return(-1);
667 return(is_selected(item));
669 /// Print the tree as 'ascii art' to stdout.
670 /// Used mainly for debugging.
673 if ( ! _root ) return;
677 /////////////////////////////////
678 // Item attribute related methods
679 /////////////////////////////////
681 /// Get the default label fontsize used for creating new items.
682 Fl_Fontsize item_labelsize() const {
683 return(_prefs.labelsize());
685 /// Set the default label font size used for creating new items.
686 /// To change the font size on a per-item basis, use Fl_Tree_Item::labelsize(Fl_Fontsize)
688 void item_labelsize(Fl_Fontsize val) {
689 _prefs.labelsize(val);
691 /// Get the default font face used for creating new items.
692 Fl_Font item_labelfont() const {
693 return(_prefs.labelfont());
695 /// Set the default font face used for creating new items.
696 /// To change the font face on a per-item basis, use Fl_Tree_Item::labelfont(Fl_Font)
698 void item_labelfont(Fl_Font val) {
699 _prefs.labelfont(val);
701 /// Get the default label foreground color used for creating new items.
702 Fl_Color item_labelfgcolor(void) const {
703 return(_prefs.labelfgcolor());
705 /// Set the default label foreground color used for creating new items.
706 /// To change the foreground color on a per-item basis, use Fl_Tree_Item::labelfgcolor(Fl_Color)
708 void item_labelfgcolor(Fl_Color val) {
709 _prefs.labelfgcolor(val);
711 /// Get the default label background color used for creating new items.
712 Fl_Color item_labelbgcolor(void) const {
713 return(_prefs.labelbgcolor());
715 /// Set the default label background color used for creating new items.
716 /// To change the background color on a per-item basis, use Fl_Tree_Item::labelbgcolor(Fl_Color)
718 void item_labelbgcolor(Fl_Color val) {
719 _prefs.labelbgcolor(val);
721 /// Get the connector color used for tree connection lines.
722 Fl_Color connectorcolor() const {
723 return(_prefs.connectorcolor());
725 /// Set the connector color used for tree connection lines.
726 void connectorcolor(Fl_Color val) {
727 _prefs.connectorcolor(val);
729 /// Get the amount of white space (in pixels) that should appear
730 /// between the widget's left border and the tree's contents.
732 int marginleft() const {
733 return(_prefs.marginleft());
735 /// Set the amount of white space (in pixels) that should appear
736 /// between the widget's left border and the left side of the tree's contents.
738 void marginleft(int val) {
739 _prefs.marginleft(val);
742 /// Get the amount of white space (in pixels) that should appear
743 /// between the widget's top border and the top of the tree's contents.
745 int margintop() const {
746 return(_prefs.margintop());
748 /// Sets the amount of white space (in pixels) that should appear
749 /// between the widget's top border and the top of the tree's contents.
751 void margintop(int val) {
752 _prefs.margintop(val);
755 /// Get the amount of white space (in pixels) that should appear
756 /// below an open child tree's contents.
758 int openchild_marginbottom() const {
759 return(_prefs.openchild_marginbottom());
761 /// Set the amount of white space (in pixels) that should appear
762 /// below an open child tree's contents.
764 void openchild_marginbottom(int val) {
765 _prefs.openchild_marginbottom(val);
768 /// Gets the width of the horizontal connection lines (in pixels)
769 /// that appear to the left of each tree item's label.
771 int connectorwidth() const {
772 return(_prefs.connectorwidth());
774 /// Sets the width of the horizontal connection lines (in pixels)
775 /// that appear to the left of each tree item's label.
777 void connectorwidth(int val) {
778 _prefs.connectorwidth(val);
781 /// Returns the Fl_Image being used as the default user icon for all
782 /// newly created items.
783 /// Returns zero if no icon has been set, which is the default.
785 Fl_Image *usericon() const {
786 return(_prefs.usericon());
788 /// Sets the Fl_Image to be used as the default user icon for all
789 /// newly created items.
791 /// If you want to specify user icons on a per-item basis,
792 /// use Fl_Tree_Item::usericon() instead.
794 /// \param[in] val -- The new image to be used, or
795 /// zero to disable user icons.
797 void usericon(Fl_Image *val) {
798 _prefs.usericon(val);
801 /// Returns the icon to be used as the 'open' icon.
802 /// If none was set, the internal default is returned,
803 /// a simple '[+]' icon.
805 Fl_Image *openicon() const {
806 return(_prefs.openicon());
808 /// Sets the icon to be used as the 'open' icon.
809 /// This overrides the built in default '[+]' icon.
811 /// \param[in] val -- The new image, or zero to use the default [+] icon.
813 void openicon(Fl_Image *val) {
814 _prefs.openicon(val);
817 /// Returns the icon to be used as the 'close' icon.
818 /// If none was set, the internal default is returned,
819 /// a simple '[-]' icon.
821 Fl_Image *closeicon() const {
822 return(_prefs.closeicon());
824 /// Sets the icon to be used as the 'close' icon.
825 /// This overrides the built in default '[-]' icon.
827 /// \param[in] val -- The new image, or zero to use the default [-] icon.
829 void closeicon(Fl_Image *val) {
830 _prefs.closeicon(val);
833 /// Returns 1 if the collapse icon is enabled, 0 if not.
834 int showcollapse() const {
835 return(_prefs.showcollapse());
837 /// Set if we should show the collapse icon or not.
838 /// If collapse icons are disabled, the user will not be able
839 /// to interactively collapse items in the tree, unless the application
840 /// provides some other means via open() and close().
842 /// \param[in] val 1: shows collapse icons (default),\n
843 /// 0: hides collapse icons.
845 void showcollapse(int val) {
846 _prefs.showcollapse(val);
849 /// Returns 1 if the root item is to be shown, or 0 if not.
850 int showroot() const {
851 return(_prefs.showroot());
853 /// Set if the root item should be shown or not.
854 /// \param[in] val 1 -- show the root item (default)\n
855 /// 0 -- hide the root item.
857 void showroot(int val) {
858 _prefs.showroot(val);
861 /// Returns the line drawing style for inter-connecting items.
862 Fl_Tree_Connector connectorstyle() const {
863 return(_prefs.connectorstyle());
865 /// Sets the line drawing style for inter-connecting items.
866 void connectorstyle(Fl_Tree_Connector val) {
867 _prefs.connectorstyle(val);
870 /// Set the default sort order used when items are added to the tree.
871 /// See Fl_Tree_Sort for possible values.
873 Fl_Tree_Sort sortorder() const {
874 return(_prefs.sortorder());
876 /// Gets the sort order used to add items to the tree.
877 void sortorder(Fl_Tree_Sort val) {
878 _prefs.sortorder(val);
879 // no redraw().. only affects new add()itions
881 /// Sets the style of box used to draw selected items.
882 /// This is an fltk Fl_Boxtype.
883 /// The default is influenced by FLTK's current Fl::scheme()
885 Fl_Boxtype selectbox() const {
886 return(_prefs.selectbox());
888 /// Gets the style of box used to draw selected items.
889 /// This is an fltk Fl_Boxtype.
890 /// The default is influenced by FLTK's current Fl::scheme()
892 void selectbox(Fl_Boxtype val) {
893 _prefs.selectbox(val);
896 /// Gets the tree's current selection mode.
897 Fl_Tree_Select selectmode() const {
898 return(_prefs.selectmode());
900 /// Sets the tree's selection mode.
901 void selectmode(Fl_Tree_Select val) {
902 _prefs.selectmode(val);
904 int displayed(Fl_Tree_Item *item);
905 void show_item(Fl_Tree_Item *item, int yoff);
906 void show_item(Fl_Tree_Item *item);
907 void show_item_bottom(Fl_Tree_Item *item);
908 void show_item_middle(Fl_Tree_Item *item);
909 void show_item_top(Fl_Tree_Item *item);
910 void display(Fl_Tree_Item *item);
911 int vposition() const;
912 void vposition(int ypos);
914 /// See if widget \p w is one of the Fl_Tree widget's scrollbars.
915 /// Use this to skip over the scrollbars when walking the child() array. Example:
917 /// for ( int i=0; i<tree->children(); i++ ) { // walk children
918 /// Fl_Widget *w= tree->child(i);
919 /// if ( brow->is_scrollbar(w) ) continue; // skip scrollbars
923 /// \param[in] w Widget to test
924 /// \returns 1 if \p w is a scrollbar, 0 if not.
926 int is_scrollbar(Fl_Widget *w) {
927 return( ( w == _vscroll ) ? 1 : 0 );
929 /// Gets the current size of the scrollbars' troughs, in pixels.
931 /// If this value is zero (default), this widget will use the global
932 /// Fl::scrollbar_size() value as the scrollbar's width.
934 /// \returns Scrollbar size in pixels, or 0 if the global Fl::scrollsize() is being used.
935 /// \see Fl::scrollbar_size(int)
937 int scrollbar_size() const {
938 return(_scrollbar_size);
940 /// Sets the pixel size of the scrollbars' troughs to the \p size, in pixels.
942 /// Normally you should not need this method, and should use the global
943 /// Fl::scrollbar_size(int) instead to manage the size of ALL
944 /// your widgets' scrollbars. This ensures your application
945 /// has a consistent UI, is the default behavior, and is normally
948 /// Only use THIS method if you really need to override the global
949 /// scrollbar size. The need for this should be rare.
951 /// Setting \p size to the special value of 0 causes the widget to
952 /// track the global Fl::scrollbar_size(), which is the default.
954 /// \param[in] size Sets the scrollbar size in pixels.\n
955 /// If 0 (default), scrollbar size tracks the global Fl::scrollbar_size()
956 /// \see Fl::scrollbar_size()
958 void scrollbar_size(int size) {
959 _scrollbar_size = size;
960 int scrollsize = _scrollbar_size ? _scrollbar_size : Fl::scrollbar_size();
961 if ( _vscroll->w() != scrollsize ) {
962 _vscroll->resize(x()+w()-scrollsize, h(), scrollsize, _vscroll->h());
966 ///////////////////////
968 ///////////////////////
970 /// Sets the item that was changed for this callback.
971 /// Used internally to pass the item that invoked the callback.
973 void callback_item(Fl_Tree_Item* item) {
974 _callback_item = item;
976 /// Gets the item that caused the callback.
977 /// The callback() can use this value to see which item changed.
979 Fl_Tree_Item* callback_item() {
980 return(_callback_item);
982 /// Sets the reason for this callback.
983 /// Used internally to pass the reason the callback was invoked.
985 void callback_reason(Fl_Tree_Reason reason) {
986 _callback_reason = reason;
988 /// Gets the reason for this callback.
990 /// The callback() can use this value to see why it was called. Example:
992 /// void MyTreeCallback(Fl_Widget *w, void *userdata) {
993 /// Fl_Tree *tree = (Fl_Tree*)w;
994 /// Fl_Tree_Item *item = tree->callback_item(); // the item changed (can be NULL if more than one item was changed!)
995 /// switch ( tree->callback_reason() ) { // reason callback was invoked
996 /// case FL_TREE_REASON_OPENED: ..item was opened..
997 /// case FL_TREE_REASON_CLOSED: ..item was closed..
998 /// case FL_TREE_REASON_SELECTED: ..item was selected..
999 /// case FL_TREE_REASON_DESELECTED: ..item was deselected..
1004 Fl_Tree_Reason callback_reason() const {
1005 return(_callback_reason);
1008 /// Load FLTK preferences
1009 void load(class Fl_Preferences&);
1012 #endif /*FL_TREE_H*/
1015 // End of "$Id: Fl_Tree.H 8632 2011-05-04 02:59:50Z greg.ercolano $".