1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
|
//
// "$Id$"
//
#ifndef FL_TREE_H
#define FL_TREE_H
#include <FL/Fl.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Scrollbar.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Tree_Item.H>
#include <FL/Fl_Tree_Prefs.H>
//////////////////////
// FL/Fl_Tree.H
//////////////////////
//
// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
// Copyright (C) 2009 by Greg Ercolano.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
///
/// \file
/// \brief This file contains the definitions of the Fl_Tree class
///
/// \class Fl_Tree
///
/// \brief Tree widget.
///
/// \code
/// Fl_Tree // Top level widget
/// |--- Fl_Tree_Item // Items in the tree
/// |--- Fl_Tree_Prefs // Preferences for the tree
/// |--- Fl_Tree_Connector (enum) // Connection modes
/// |--- Fl_Tree_Select (enum) // Selection modes
/// |--- Fl_Tree_Sort (enum) // Sort behavior
/// \endcode
///
/// An expandable tree widget.
///
/// Similar to Fl_Browser, Fl_Tree is browser of Fl_Tree_Item's, which can be
/// in a parented hierarchy. Subtrees can be expanded or closed. Items can be
/// added, deleted, inserted, sorted and re-ordered.
///
/// The tree items may also contain other FLTK widgets, like buttons, input fields,
/// or even "custom" widgets.
///
/// The callback() is invoked depending on the value of when():
///
/// - FL_WHEN_RELEASE -- callback invoked when left mouse button is released on an item
/// - FL_WHEN_CHANGED -- callback invoked when left mouse changes selection state
///
/// The simple way to define a tree:
/// \code
/// #include <FL/Fl_Tree.H>
/// [..]
/// Fl_Tree tree(X,Y,W,H);
/// tree.begin();
/// tree.add("Flintstones/Fred");
/// tree.add("Flintstones/Wilma");
/// tree.add("Flintstones/Pebbles");
/// tree.add("Simpsons/Homer");
/// tree.add("Simpsons/Marge");
/// tree.add("Simpsons/Bart");
/// tree.add("Simpsons/Lisa");
/// tree.end();
/// \endcode
///
/// Items can be added with add(),
/// removed with remove(),
/// completely cleared with clear(),
/// inserted with insert() and insert_above(),
/// selected/deselected with select() and deselect(),
/// open/closed with open() and closed().
/// Children of an item can be swapped around with Fl_Tree_Item::swap_children(),
/// sorting can be controlled when items are add()ed via sortorder().
/// You can walk the entire tree with first() and next().
/// You can walk selected items with first_selected_item() and
/// next_selected_item().
/// Items can be found by their pathname using find_item(const char*),
/// and an item's pathname can be found with item_pathname().
///
/// The tree can have different selection behaviors controlled by selectmode().
///
/// FLTK widgets (including custom widgets) can be assigned to tree items via
/// Fl_Tree_Item::widget().
///
/// Icons for individual items can be changed with
/// Fl_Tree_Item::openicon(),
/// Fl_Tree_Item::closeicon(),
/// Fl_Tree_Item::usericon().
///
/// Various default preferences can be globally manipulated via Fl_Tree_Prefs,
/// including colors, margins, icons, connection lines.
///
/// The tree's callback() will be invoked when items change state or are open/closed.
/// when() controls when mouse/keyboard events invoke the callback.
/// callback_item() and callback_reason() can be used to determine the cause of the callback.
///
/// \image html tree-elements.png
///
/// \enum Fl_Tree_Reason
/// The reason the callback was invoked.
///
enum Fl_Tree_Reason {
FL_TREE_REASON_NONE=0, ///< unknown reason
FL_TREE_REASON_SELECTED, ///< an item was selected
FL_TREE_REASON_DESELECTED, ///< an item was de-selected
FL_TREE_REASON_OPENED, ///< an item was opened
FL_TREE_REASON_CLOSED ///< an item was closed
};
class FL_EXPORT Fl_Tree : public Fl_Group {
Fl_Tree_Item *_root; // can be null!
Fl_Tree_Item *_item_focus; // item that has focus box
Fl_Tree_Item *_callback_item; // item invoked during callback (can be NULL)
Fl_Tree_Reason _callback_reason; // reason for the callback
Fl_Tree_Prefs _prefs; // all the tree's settings
int _scrollbar_size; // size of scrollbar trough
protected:
/// Vertical scrollbar
Fl_Scrollbar *_vscroll;
protected:
void item_clicked(Fl_Tree_Item* val);
/// Do the callback for the item, setting the item and reason
void do_callback_for_item(Fl_Tree_Item* item, Fl_Tree_Reason reason) {
callback_reason(reason);
callback_item(item);
do_callback((Fl_Widget*)this, user_data());
}
Fl_Tree_Item *next_visible_item(Fl_Tree_Item *start, int dir);
public:
Fl_Tree(int X, int Y, int W, int H, const char *L=0);
~Fl_Tree();
int handle(int e);
void draw();
///////////////////////
// root methods
///////////////////////
/// Set the label for the root item.
///
/// Makes an internally managed copy of 'new_label'.
///
void root_label(const char *new_label) {
if ( ! _root ) return;
_root->label(new_label);
}
/// Returns the root item.
Fl_Tree_Item* root() {
return(_root);
}
////////////////////////////////
// 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 \p item from the tree.
/// If it has children, all those are removed too.
/// \returns 0 if done, -1 if 'item' not found.
///
int remove(Fl_Tree_Item *item) {
if ( !item ) return(0);
if ( item == _root ) {
clear();
} else {
Fl_Tree_Item *parent = item->parent(); // find item's parent
if ( ! parent ) return(-1);
parent->remove_child(item); // remove child + children
}
return(0);
}
/// Clear all children from the tree.
/// The tree will be left completely empty.
///
void clear() {
if ( ! _root ) return;
_root->clear_children();
delete _root; _root = 0;
}
/// Clear all the children of a particular node in the tree specified by \p item.
void clear_children(Fl_Tree_Item *item) {
if ( item->has_children() ) {
item->clear_children();
redraw(); // redraw only if there were children to clear
}
}
////////////////////////
// Item lookup methods
////////////////////////
Fl_Tree_Item *find_item(const char *path);
const Fl_Tree_Item *find_item(const char *path) const;
int item_pathname(char *pathname, int pathnamelen, const Fl_Tree_Item *item) const;
const Fl_Tree_Item *find_clicked() const;
/// Return the item that was last clicked.
///
/// Valid only from within the callback().
///
/// Deprecated: use callback_item() instead.
///
/// \returns the item clicked, or 0 if none.
/// 0 may also be used to indicate several items were clicked/changed.
///
Fl_Tree_Item *item_clicked() {
return(_callback_item);
}
Fl_Tree_Item *first();
Fl_Tree_Item *next(Fl_Tree_Item *item=0);
Fl_Tree_Item *prev(Fl_Tree_Item *item=0);
Fl_Tree_Item *last();
Fl_Tree_Item *first_selected_item();
Fl_Tree_Item *next_selected_item(Fl_Tree_Item *item=0);
//////////////////////////
// Item open/close methods
//////////////////////////
/// Open the specified 'item'.
/// This causes the item's children (if any) to be shown.
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] item -- the item to be opened
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
/// - 1 - callback() is invoked if item changed,
/// callback_reason() will be FL_TREE_REASON_OPENED
///
/// \returns
/// - 1 -- item was opened
/// - 0 -- item was already open, no change
///
/// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
///
int open(Fl_Tree_Item *item, int docallback=1) {
if ( item->is_open() ) return(0);
item->open();
redraw();
if ( docallback ) {
do_callback_for_item(item, FL_TREE_REASON_OPENED);
}
return(1);
}
/// Opens the item specified by \p path (eg: "Parent/child/item").
/// This causes the item's children (if any) to be shown.
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
/// - 1 - callback() is invoked if item changed,
/// callback_reason() will be FL_TREE_REASON_OPENED
///
/// \returns
/// - 1 -- OK: item opened
/// - 0 -- OK: item was already open, no change
/// - -1 -- ERROR: item was not found
///
/// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
///
int open(const char *path, int docallback=1) {
Fl_Tree_Item *item = find_item(path);
if ( ! item ) return(-1);
return(open(item, docallback));
}
/// Toggle the open state of \p item.
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] item -- the item to be opened
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
/// - 1 - callback() is invoked, callback_reason() will be either
/// FL_TREE_REASON_OPENED or FL_TREE_REASON_CLOSED
///
/// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
///
void open_toggle(Fl_Tree_Item *item, int docallback=1) {
if ( item->is_open() ) {
close(item, docallback);
} else {
open(item, docallback);
}
}
/// Closes the specified \p item.
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] item -- the item to be closed
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
/// - 1 - callback() is invoked if item changed,
/// callback_reason() will be FL_TREE_REASON_CLOSED
///
/// \returns
/// - 1 -- item was closed
/// - 0 -- item was already closed, no change
///
/// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
///
int close(Fl_Tree_Item *item, int docallback=1) {
if ( item->is_close() ) return(0);
item->close();
redraw();
if ( docallback ) {
do_callback_for_item(item, FL_TREE_REASON_CLOSED);
}
return(1);
}
/// Closes the item specified by \p path, eg: "Parent/child/item".
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
/// - 1 - callback() is invoked if item changed,
/// callback_reason() will be FL_TREE_REASON_CLOSED
///
/// \returns
/// - 1 -- OK: item closed
/// - 0 -- OK: item was already closed, no change
/// - -1 -- ERROR: item was not found
///
/// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
///
int close(const char *path, int docallback=1) {
Fl_Tree_Item *item = find_item(path);
if ( ! item ) return(-1);
return(close(item, docallback));
}
/// See if \p item is open.
///
/// Items that are 'open' are themselves not necessarily visible;
/// one of the item's parents might be closed.
///
/// \param[in] item -- the item to be tested
///
/// \returns
/// - 1 : item is open
/// - 0 : item is closed
///
int is_open(Fl_Tree_Item *item) const {
return(item->is_open()?1:0);
}
/// See if item specified by \p path (eg: "Parent/child/item") is open.
///
/// Items that are 'open' are themselves not necessarily visible;
/// one of the item's parents might be closed.
///
/// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
///
/// \returns
/// - 1 - OK: item is open
/// - 0 - OK: item is closed
/// - -1 - ERROR: item was not found
///
int is_open(const char *path) const {
const Fl_Tree_Item *item = find_item(path);
if ( ! item ) return(-1);
return(item->is_open()?1:0);
}
/// See if the specified \p item is closed.
///
/// \param[in] item -- the item to be tested
///
/// \returns
/// - 1 : item is open
/// - 0 : item is closed
///
int is_close(Fl_Tree_Item *item) const {
return(item->is_close());
}
/// See if item specified by \p path (eg: "Parent/child/item") is closed.
///
/// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
///
/// \returns
/// - 1 - OK: item is closed
/// - 0 - OK: item is open
/// - -1 - ERROR: item was not found
///
int is_close(const char *path) const {
const Fl_Tree_Item *item = find_item(path);
if ( ! item ) return(-1);
return(item->is_close()?1:0);
}
/// Select the specified \p item. Use 'deselect()' to de-select it.
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] item -- the item to be selected
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
/// - 1 - the callback() is invoked if item changed state,
/// callback_reason() will be FL_TREE_REASON_SELECTED
///
/// \returns
/// - 1 - item's state was changed
/// - 0 - item was already selected, no change was made
///
int select(Fl_Tree_Item *item, int docallback=1) {
if ( ! item->is_selected() ) {
item->select();
set_changed();
if ( docallback ) {
do_callback_for_item(item, FL_TREE_REASON_SELECTED);
}
redraw();
return(1);
}
return(0);
}
/// Select the item specified by \p path (eg: "Parent/child/item").
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
/// - 1 - the callback() is invoked if item changed state,
/// callback_reason() will be FL_TREE_REASON_SELECTED
///
/// \returns
/// - 1 : OK: item's state was changed
/// - 0 : OK: item was already selected, no change was made
/// - -1 : ERROR: item was not found
///
int select(const char *path, int docallback=1) {
Fl_Tree_Item *item = find_item(path);
if ( ! item ) return(-1);
return(select(item, docallback));
}
/// Toggle the select state of the specified \p item.
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] item -- the item to be selected
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
/// - 1 - the callback() is invoked, callback_reason() will be
/// either FL_TREE_REASON_SELECTED or FL_TREE_REASON_DESELECTED
///
void select_toggle(Fl_Tree_Item *item, int docallback=1) {
item->select_toggle();
set_changed();
if ( docallback ) {
do_callback_for_item(item, item->is_selected() ? FL_TREE_REASON_SELECTED
: FL_TREE_REASON_DESELECTED);
}
redraw();
}
/// De-select the specified \p item.
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] item -- the item to be selected
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
/// - 1 - the callback() is invoked if item changed state,
/// callback_reason() will be FL_TREE_REASON_DESELECTED
///
/// \returns
/// - 0 - item was already deselected, no change was made
/// - 1 - item's state was changed
///
int deselect(Fl_Tree_Item *item, int docallback=1) {
if ( item->is_selected() ) {
item->deselect();
set_changed();
if ( docallback ) {
do_callback_for_item(item, FL_TREE_REASON_DESELECTED);
}
redraw();
return(1);
}
return(0);
}
/// Deselect an item specified by \p path (eg: "Parent/child/item").
/// Handles redrawing if anything was actually changed.
/// Invokes the callback depending on the value of optional parameter \p docallback.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
///
/// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
/// - 1 - the callback() is invoked if item changed state,
/// callback_reason() will be FL_TREE_REASON_DESELECTED
///
/// \returns
/// - 1 - OK: item's state was changed
/// - 0 - OK: item was already deselected, no change was made
/// - -1 - ERROR: item was not found
///
int deselect(const char *path, int docallback=1) {
Fl_Tree_Item *item = find_item(path);
if ( ! item ) return(-1);
return(deselect(item, docallback));
}
int deselect_all(Fl_Tree_Item *item=0, int docallback=1);
int select_only(Fl_Tree_Item *selitem, int docallback=1);
int select_all(Fl_Tree_Item *item=0, int docallback=1);
void set_item_focus(Fl_Tree_Item *o);
/// See if the specified \p item is selected.
///
/// \param[in] item -- the item to be tested
///
/// \return
/// - 1 : item selected
/// - 0 : item deselected
///
int is_selected(Fl_Tree_Item *item) const {
return(item->is_selected()?1:0);
}
/// See if item specified by \p path (eg: "Parent/child/item") is selected.
///
/// \param[in] path -- the tree item's pathname (eg. "Flintstones/Fred")
///
/// \returns
/// - 1 : item selected
/// - 0 : item deselected
/// - -1 : item was not found
///
int is_selected(const char *path) {
Fl_Tree_Item *item = find_item(path);
if ( ! item ) return(-1);
return(is_selected(item));
}
/// Print the tree as 'ascii art' to stdout.
/// Used mainly for debugging.
///
void show_self() {
if ( ! _root ) return;
_root->show_self();
}
/////////////////////////////////
// Item attribute related methods
/////////////////////////////////
/// Get the default label fontsize used for creating new items.
int labelsize() const {
return(_prefs.labelsize());
}
/// Set the default label font size used for creating new items.
/// To change the font size on a per-item basis, use Fl_Tree_Item::labelsize(int)
///
void labelsize(int val) {
_prefs.labelsize(val);
}
/// Get the default font face used for item's labels when new items are created.
///
/// Don't use this if you want to change an existing label() size; use
/// item->labelfont() instead.
///
int labelfont() const {
return(_prefs.labelfont());
}
/// Set the default font face used for item's labels when new items are created.
///
/// Don't use this if you want to change an existing label() size; use
/// item->labelfont(int) instead.
///
void labelfont(int val) {
_prefs.labelfont(val);
}
/// Get the amount of white space (in pixels) that should appear
/// between the widget's left border and the tree's contents.
///
int marginleft() const {
return(_prefs.marginleft());
}
/// Set the amount of white space (in pixels) that should appear
/// between the widget's left border and the left side of the tree's contents.
///
void marginleft(int val) {
_prefs.marginleft(val);
redraw();
}
/// Get the amount of white space (in pixels) that should appear
/// between the widget's top border and the top of the tree's contents.
///
int margintop() const {
return(_prefs.margintop());
}
/// Sets the amount of white space (in pixels) that should appear
/// between the widget's top border and the top of the tree's contents.
///
void margintop(int val) {
_prefs.margintop(val);
redraw();
}
/// Get the amount of white space (in pixels) that should appear
/// below an open child tree's contents.
///
int openchild_marginbottom() const {
return(_prefs.openchild_marginbottom());
}
/// Set the amount of white space (in pixels) that should appear
/// below an open child tree's contents.
///
void openchild_marginbottom(int val) {
_prefs.openchild_marginbottom(val);
redraw();
}
/// Gets the width of the horizontal connection lines (in pixels)
/// that appear to the left of each tree item's label.
///
int connectorwidth() const {
return(_prefs.connectorwidth());
}
/// Sets the width of the horizontal connection lines (in pixels)
/// that appear to the left of each tree item's label.
///
void connectorwidth(int val) {
_prefs.connectorwidth(val);
redraw();
}
/// 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_Image *usericon() const {
return(_prefs.usericon());
}
/// 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 image to be used, or
/// zero to disable user icons.
///
void usericon(Fl_Image *val) {
_prefs.usericon(val);
redraw();
}
/// Returns the icon to be used as the 'open' icon.
/// If none was set, the internal default is returned,
/// a simple '[+]' icon.
///
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 image, or zero to use the default [+] icon.
///
void openicon(Fl_Image *val) {
_prefs.openicon(val);
redraw();
}
/// Returns the icon to be used as the 'close' icon.
/// If none was set, the internal default is returned,
/// a simple '[-]' icon.
///
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 image, or zero to use the default [-] icon.
///
void closeicon(Fl_Image *val) {
_prefs.closeicon(val);
redraw();
}
/// Returns 1 if the collapse icon is enabled, 0 if not.
int showcollapse() const {
return(_prefs.showcollapse());
}
/// Set if we should show the collapse icon or not.
/// If collapse icons are disabled, the user will not be able
/// to interactively collapse items in the tree, unless the application
/// provides some other means via open() and close().
///
/// \param[in] val 1: shows collapse icons (default),\n
/// 0: hides collapse icons.
///
void showcollapse(int val) {
_prefs.showcollapse(val);
redraw();
}
/// Returns 1 if the root item is to be shown, or 0 if not.
int showroot() const {
return(_prefs.showroot());
}
/// Set if the root item should be shown or not.
/// \param[in] val 1 -- show the root item (default)\n
/// 0 -- hide the root item.
///
void showroot(int val) {
_prefs.showroot(val);
redraw();
}
/// Returns the line drawing style for inter-connecting items.
Fl_Tree_Connector connectorstyle() const {
return(_prefs.connectorstyle());
}
/// Sets the line drawing style for inter-connecting items.
void connectorstyle(Fl_Tree_Connector val) {
_prefs.connectorstyle(val);
redraw();
}
/// Set the default sort order used when items are added to the tree.
/// See Fl_Tree_Sort for possible values.
///
Fl_Tree_Sort sortorder() const {
return(_prefs.sortorder());
}
/// Gets the sort order used to add items to the tree.
void sortorder(Fl_Tree_Sort val) {
_prefs.sortorder(val);
// no redraw().. only affects new add()itions
}
/// Sets the style of box used to draw selected items.
/// This is an fltk Fl_Boxtype.
/// The default is influenced by FLTK's current Fl::scheme()
///
Fl_Boxtype selectbox() const {
return(_prefs.selectbox());
}
/// Gets the style of box used to draw selected items.
/// This is an fltk Fl_Boxtype.
/// The default is influenced by FLTK's current Fl::scheme()
///
void selectbox(Fl_Boxtype val) {
_prefs.selectbox(val);
redraw();
}
/// Gets the tree's current selection mode.
Fl_Tree_Select selectmode() const {
return(_prefs.selectmode());
}
/// Sets the tree's selection mode.
void selectmode(Fl_Tree_Select val) {
_prefs.selectmode(val);
}
int displayed(Fl_Tree_Item *item);
void show_item(Fl_Tree_Item *item, int yoff);
void show_item(Fl_Tree_Item *item);
void show_item_bottom(Fl_Tree_Item *item);
void show_item_middle(Fl_Tree_Item *item);
void show_item_top(Fl_Tree_Item *item);
void display(Fl_Tree_Item *item);
int vposition() const;
void vposition(int ypos);
/// See if widget \p w is one of the Fl_Tree widget's scrollbars.
/// Use this to skip over the scrollbars when walking the child() array. Example:
/// \code
/// for ( int i=0; i<tree->children(); i++ ) { // walk children
/// Fl_Widget *w= tree->child(i);
/// if ( brow->is_scrollbar(w) ) continue; // skip scrollbars
/// ..do work here..
/// }
/// \endcode
/// \param[in] w Widget to test
/// \returns 1 if \p w is a scrollbar, 0 if not.
///
int is_scrollbar(Fl_Widget *w) {
return( ( w == _vscroll ) ? 1 : 0 );
}
/// Gets the current size of the scrollbars' troughs, in pixels.
///
/// If this value is zero (default), this widget will use the global
/// Fl::scrollbar_size() value as the scrollbar's width.
///
/// \returns Scrollbar size in pixels, or 0 if the global Fl::scrollsize() is being used.
/// \see Fl::scrollbar_size(int)
///
int scrollbar_size() const {
return(_scrollbar_size);
}
/// Sets the pixel size of the scrollbars' troughs to the \p size, in pixels.
///
/// Normally you should not need this method, and should use the global
/// Fl::scrollbar_size(int) instead to manage the size of ALL
/// your widgets' scrollbars. This ensures your application
/// has a consistent UI, is the default behavior, and is normally
/// what you want.
///
/// Only use THIS method if you really need to override the global
/// scrollbar size. The need for this should be rare.
///
/// Setting \p size to the special value of 0 causes the widget to
/// track the global Fl::scrollbar_size(), which is the default.
///
/// \param[in] size Sets the scrollbar size in pixels.\n
/// If 0 (default), scrollbar size tracks the global Fl::scrollbar_size()
/// \see Fl::scrollbar_size()
///
void scrollbar_size(int size) {
_scrollbar_size = size;
int scrollsize = _scrollbar_size ? _scrollbar_size : Fl::scrollbar_size();
if ( _vscroll->w() != scrollsize ) {
_vscroll->resize(x()+w()-scrollsize, h(), scrollsize, _vscroll->h());
}
}
///////////////////////
// callback related
///////////////////////
/// Sets the item that was changed for this callback.
/// Used internally to pass the item that invoked the callback.
///
void callback_item(Fl_Tree_Item* item) {
_callback_item = item;
}
/// Gets the item that caused the callback.
/// The callback() can use this value to see which item changed.
///
Fl_Tree_Item* callback_item() {
return(_callback_item);
}
/// Sets the reason for this callback.
/// Used internally to pass the reason the callback was invoked.
///
void callback_reason(Fl_Tree_Reason reason) {
_callback_reason = reason;
}
/// Gets the reason for this callback.
///
/// The callback() can use this value to see why it was called. Example:
/// \code
/// void MyTreeCallback(Fl_Widget *w, void *userdata) {
/// Fl_Tree *tree = (Fl_Tree*)w;
/// Fl_Tree_Item *item = tree->callback_item(); // the item changed (can be NULL if more than one item was changed!)
/// switch ( tree->callback_reason() ) { // reason callback was invoked
/// case FL_TREE_REASON_OPENED: ..item was opened..
/// case FL_TREE_REASON_CLOSED: ..item was closed..
/// case FL_TREE_REASON_SELECTED: ..item was selected..
/// case FL_TREE_REASON_DESELECTED: ..item was deselected..
/// }
/// }
/// \endcode
///
Fl_Tree_Reason callback_reason() const {
return(_callback_reason);
}
/// Load FLTK preferences
void load(class Fl_Preferences&);
};
#endif /*FL_TREE_H*/
//
// End of "$Id$".
//
|