00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef _FLU_TREE_BROWSER_H
00017 #define _FLU_TREE_BROWSER_H
00018
00019 #include <stdio.h>
00020 #include <string.h>
00021 #include <stdlib.h>
00022
00023
00024
00025
00026 #include <FL/Fl.H>
00027 #include <FL/Fl_Box.H>
00028 #include <FL/Fl_Pixmap.H>
00029 #include <FL/Fl_Image.H>
00030 #include <FL/Fl_Scrollbar.H>
00031 #include <FL/Fl_Group.H>
00032 #include <FL/Fl_Menu_Button.H>
00033
00034
00035 #include "FLU/Flu_Enumerations.h"
00036 #include "FLU/FluSimpleString.h"
00037 #ifdef USE_FLU_DND
00038 #include "FLU/Flu_DND.h"
00039 #else
00040 typedef struct { bool dummy; } Flu_DND_Event;
00041 #endif
00042
00044 #ifdef USE_FLU_DND
00045 class FLU_EXPORT Flu_Tree_Browser : public Fl_Group, public Flu_DND
00046 #else
00047 class FLU_EXPORT Flu_Tree_Browser : public Fl_Group
00048 #endif
00049 {
00050
00051 static bool USE_FLU_WIDGET_CALLBACK;
00052
00053 public:
00054
00055 class Node;
00056 friend class Node;
00057
00059 Flu_Tree_Browser( int x, int y, int w, int h, const char *label = 0 );
00060
00062 virtual ~Flu_Tree_Browser();
00063
00065
00067 Node* add( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00068
00070 Node* add( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00071
00073
00075 inline Node* add( Node* n, const char* name, Fl_Widget *w = 0, bool showLabel = true )
00076 { return n->add( name, w, showLabel ); }
00077
00079 Node* add_branch( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00080
00082 Node* add_branch( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00083
00085 inline Node* add_branch( Node* n, const char* name, Fl_Widget *w = 0, bool showLabel = true )
00086 { return n->add_branch( name, w, showLabel ); }
00087
00089 Node* add_leaf( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00090
00092 Node* add_leaf( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00093
00095 inline Node* add_leaf( Node* n, const char* name, Fl_Widget *w = 0, bool showLabel = true )
00096 { return n->add_leaf( name, w, showLabel ); }
00097
00099 inline void all_branches_always_open( bool b )
00100 { rdata.allBranchesAlwaysOpen = b; }
00101
00103 inline bool all_branches_always_open()
00104 { return rdata.allBranchesAlwaysOpen; }
00105
00107 inline void allow_leaf_duplication( bool b )
00108 { rdata.allowLeafDuplication = b; }
00109
00111 inline bool allow_leaf_duplication()
00112 { return rdata.allowLeafDuplication; }
00113
00115 inline void allow_branch_duplication( bool b )
00116 { rdata.allowBranchDuplication = b; }
00117
00119 inline bool allow_branch_duplication()
00120 { return rdata.allowBranchDuplication; }
00121
00123 inline bool have_dnd()
00124 {
00125 #ifdef USE_FLU_DND
00126 return true;
00127 #else
00128 return false;
00129 #endif
00130 }
00131
00133
00136 inline void allow_dnd( bool b )
00137 { rdata.dnd = b; }
00138
00140 inline bool allow_dnd()
00141 { return rdata.dnd; }
00142
00144 inline void always_open( bool b )
00145 { root.always_open( b ); }
00146
00148 inline bool always_open()
00149 { return root.always_open(); }
00150
00152 inline void animate( bool b )
00153 { rdata.animate = b; }
00154
00156 inline bool animate()
00157 { return rdata.animate; }
00158
00160 void auto_branches( bool b );
00161
00163 inline bool auto_branches() const
00164 { return rdata.autoBranches; }
00165
00167 inline Fl_Color branch_color() const
00168 { return rdata.defBranchColor; }
00169
00171 inline Fl_Font branch_font() const
00172 { return rdata.defBranchFont; }
00173
00175 inline int branch_size() const
00176 { return rdata.defBranchSize; }
00177
00179 inline void branch_text( Fl_Color color, Fl_Font font, int size )
00180 { rdata.defBranchColor = color; rdata.defBranchFont = font; rdata.defBranchSize = size; }
00181
00183
00184 void branch_icons( Fl_Image *closed, Fl_Image *open );
00185
00187 inline Fl_Boxtype box() const
00188 { return _box->box(); }
00189
00191 inline void box( Fl_Boxtype b )
00192 { _box->box( b ); }
00193
00195
00196
00197
00199 inline int callback_reason() const
00200 { return rdata.cbReason; }
00201
00203
00204 inline Node* callback_node() const
00205 { return rdata.cbNode; }
00206
00208 void clear();
00209
00211 void collapse_icons( Fl_Image *closed, Fl_Image *open );
00212
00214 inline float collapse_time() const
00215 { return rdata.collapseTime; }
00216
00218 inline void collapse_time( float t )
00219 { rdata.collapseTime = t; }
00220
00222 inline Fl_Color color() const
00223 { return _box->color(); }
00224
00226 inline void color( Fl_Color c )
00227 { _box->color( c ); }
00228
00230 inline void color( unsigned c )
00231 { _box->color( (Fl_Color)c ); }
00232
00234 inline void connector_style( Fl_Color color, int style, int width = 1 )
00235 { rdata.defLineColor = color; rdata.lineStyle = style; rdata.lineWidth = width; }
00236
00238 inline Fl_Color connector_color() const
00239 { return rdata.defLineColor; }
00240
00242 inline int connector_style() const
00243 { return rdata.lineStyle; }
00244
00246 inline int connector_width() const
00247 { return rdata.lineWidth; }
00248
00250 inline void double_click_opens( bool b )
00251 { rdata.doubleClickToOpen = b; }
00252
00254 inline bool double_click_opens()
00255 { return rdata.doubleClickToOpen; }
00256
00258 inline Fl_Color even_shaded_entry_color() const
00259 { return rdata.shadedColors[0]; }
00260
00262
00263 inline Node* find( const char *fullpath )
00264 { return find_next( fullpath ); }
00265
00267
00268 Node* find( const char *path, const char *name );
00269
00271
00272 Node* find( unsigned int id );
00273
00275
00276 inline Node* find( Node *n )
00277 { if( !n ) return NULL; else return find( n->id() ); }
00278
00280
00281 Node* find( Fl_Widget *w );
00282
00284
00285 Node* find_next( const char *fullpath, Node* startNode = NULL );
00286
00288
00289 Node* find_next( const char *path, const char *name );
00290
00292 int find_number( const char *fullpath );
00293
00295 int find_number( const char *path, const char *name );
00296
00298
00299 const char* find_path( unsigned int id );
00300
00302
00303 const char* find_path( Fl_Widget *w );
00304
00306
00307 inline const char* find_path( Node *n )
00308 { if( !n ) return ""; else return find_path( n->id() ); }
00309
00311 inline Node* first() { return root.first(); }
00312
00314 inline Node* first_branch() { return root.first_branch(); }
00315
00317 inline Node* first_leaf() { return root.first_leaf(); }
00318
00320 inline float frame_rate() const
00321 { return rdata.fps; }
00322
00324 inline void frame_rate( float f )
00325 { if( f <= 0.0f ) rdata.fps = 0.001f; else rdata.fps = f; }
00326
00328 inline Node* get_hilighted()
00329 { return rdata.hilighted; }
00330
00332 inline Node *get_root() { return &root; }
00333
00335
00336 Node* get_selected( int index );
00337
00339 int handle( int event );
00340
00342 inline void horizontal_gap( int g )
00343 { rdata.hGap = g; rdata.forceResize = true; }
00344
00346 inline int horizontal_gap() const
00347 { return rdata.hGap; }
00348
00350 void insertion_mode( int m );
00351
00353 inline int insertion_mode()
00354 { return rdata.insertionMode; }
00355
00357 bool Flu_Tree_Browser :: inside_entry_area( int x, int y );
00358
00360 inline void label( const char *l )
00361 { root.text = l; }
00362
00364 inline const char* label() const
00365 { return root.text.c_str(); }
00366
00368 inline Node* last() { return root.last(); }
00369
00371 inline Node* last_branch() { return root.last_branch(); }
00372
00374 inline Node* last_leaf() { return root.last_leaf(); }
00375
00377 inline Fl_Color leaf_color() const
00378 { return rdata.defLeafColor; }
00379
00381 inline Fl_Font leaf_font() const
00382 { return rdata.defLeafFont; }
00383
00385 inline int leaf_size() const
00386 { return rdata.defLeafSize; }
00387
00389 void leaf_icon( Fl_Image *icon );
00390
00392 inline void leaf_text( Fl_Color color, Fl_Font font, int size )
00393 { rdata.defLeafColor = color; rdata.defLeafFont = font; rdata.defLeafSize = size; }
00394
00396 inline void move_only_same_group( bool b )
00397 { rdata.moveOnlySameGroup = b; }
00398
00400 inline bool move_only_same_group()
00401 { return rdata.moveOnlySameGroup; }
00402
00404 int num_selected();
00405
00407 inline Fl_Color odd_shaded_entry_color() const
00408 { return rdata.shadedColors[1]; }
00409
00411 inline void only_one_open_branch( bool b )
00412 { rdata.singleBranchOpen = b; }
00413
00415 inline bool only_one_open_branch()
00416 { return rdata.singleBranchOpen; }
00417
00419 inline void open( bool b )
00420 { root.open( b ); }
00421
00423 inline bool open() const
00424 { return root.open(); }
00425
00427 inline void open_without_children( bool b )
00428 { rdata.openWOChildren = b; }
00429
00431 inline bool open_without_children() const
00432 { return rdata.openWOChildren; }
00433
00435 inline void open_on_select( bool b )
00436 { rdata.openOnSelect = b; }
00437
00439 inline bool open_on_select() const
00440 { return rdata.openOnSelect; }
00441
00443 void print();
00444
00446
00447 unsigned int remove( const char *fullpath );
00448
00450
00451 unsigned int remove( const char *path, const char *name );
00452
00454
00455 unsigned int remove( unsigned int id );
00456
00458
00459 unsigned int remove( Fl_Widget *w );
00460
00462
00463 inline unsigned int remove( Node* n )
00464 { if( !n ) return 0; else return remove( n->id() ); }
00465
00467 void resize( int X, int Y, int W, int H );
00468
00470 inline void root_color( Fl_Color c )
00471 { get_root()->label_color( c ); }
00472
00474 inline Fl_Color root_color()
00475 { return get_root()->label_color(); }
00476
00478 inline void root_font( Fl_Font f )
00479 { get_root()->label_font( f ); }
00480
00482 inline Fl_Font root_font()
00483 { return get_root()->label_font(); }
00484
00486 inline void root_size( unsigned char s )
00487 { get_root()->label_size( s ); }
00488
00490 inline unsigned char root_size()
00491 { return get_root()->label_size(); }
00492
00494 inline void select_all()
00495 { root.select_all(); }
00496
00498 inline Fl_Color selection_color() const
00499 { return rdata.defSelectionColor; }
00500
00502 inline void selection_color( Fl_Color c )
00503 { rdata.defSelectionColor = c; }
00504
00506 inline void selection_color( unsigned c )
00507 { selection_color( (Fl_Color)c ); }
00508
00510 inline void selection_drag_mode( int m )
00511 { rdata.selectionDragMode = m; }
00512
00514 inline int selection_drag_mode() const
00515 { return rdata.selectionDragMode; }
00516
00518 inline void selection_follows_hilight( bool b )
00519 { rdata.selectionFollowsHilight = b; if( b && rdata.hilighted ) rdata.hilighted->select(true); }
00520
00522 inline bool selection_follows_hilight()
00523 { return rdata.selectionFollowsHilight; }
00524
00526 inline void selection_mode( int m )
00527 { rdata.selectionMode = m; root.unselect_all(); }
00528
00530 inline int selection_mode() const
00531 { return rdata.selectionMode; }
00532
00534 inline void select_under_mouse( bool b )
00535 { rdata.selectUnderMouse = b; }
00536
00538 inline bool select_under_mouse() const
00539 { return rdata.selectUnderMouse; }
00540
00542 void set_default_branch_icons();
00543
00545 void set_hilighted( Node* n );
00546
00548
00549 Node* set_root( const char *label, Fl_Widget *w = 0, bool showLabel = true );
00550
00552 inline void shaded_entry_colors( Fl_Color even, Fl_Color odd )
00553 { rdata.shadedColors[0] = even; rdata.shadedColors[1] = odd; }
00554
00556 inline void show_branches( bool b )
00557 { rdata.showBranches = b; rdata.forceResize = true; }
00558
00560 inline bool show_branches() const
00561 { return rdata.showBranches; }
00562
00564 inline void show_connectors( bool b )
00565 { rdata.showConnectors = b; }
00566
00568 inline bool show_connectors() const
00569 { return rdata.showConnectors; }
00570
00572 inline void show_root( bool b )
00573 { rdata.showRoot = b; rdata.forceResize = true; }
00574
00576 inline bool show_root() const
00577 { return rdata.showRoot; }
00578
00580 inline void show_leaves( bool b )
00581 { rdata.showLeaves = b; rdata.forceResize = true; }
00582
00584 inline bool show_leaves() const
00585 { return rdata.showLeaves; }
00586
00588 inline void sort()
00589 { root.sort(); }
00590
00592 inline void unselect_all()
00593 { root.unselect_all(); }
00594
00595 inline static void use_FLU_WIDGET_CALLBACK( bool b )
00596 { USE_FLU_WIDGET_CALLBACK = b; }
00597
00599 inline void vertical_gap( int g )
00600 { rdata.vGap = g; rdata.forceResize = true; }
00601
00603 inline int vertical_gap() const
00604 { return rdata.vGap; }
00605
00607
00609
00610
00611
00613
00614
00615
00617 inline void widget_gap( int g )
00618 { rdata.wGap = g; rdata.forceResize = true; }
00619
00621 inline int widget_gap() const
00622 { return rdata.wGap; }
00623
00624 protected:
00625
00626 class RData;
00627
00629 class FLU_EXPORT NodeList
00630 {
00631 public:
00632 NodeList();
00633 ~NodeList();
00634 void add( Node* n, int position = -1 );
00635 inline Node* child( int n ) const { return _nodes[n]; }
00636 int erase( Node* n );
00637 int erase( const char* n );
00638 void erase( int n );
00639 void clear();
00640 int findNum( const char *n );
00641 Node* find( const char* n, int which = 1 );
00642 inline int size() const { return _nNodes; };
00643 void sort();
00644 static bool move( Node* n1, int where, Node* n2 );
00645 private:
00646 friend class Node;
00647 static int compareNodes( const void *arg1, const void* arg2 );
00648 static int reverseCompareNodes( const void *arg1, const void* arg2 );
00649 bool search( Node *n, int &index );
00650 bool search( const char *n, int &index );
00651 bool linSearch( Node *n, int &index );
00652 bool linSearch( const char *n, int &index );
00653 bool binSearch( Node *n, int &index );
00654 bool binSearch( const char *n, int &index );
00655 Node **_nodes;
00656 int _nNodes, _size;
00657 };
00658
00660 class FLU_EXPORT IntStack
00661 {
00662 public:
00663 IntStack();
00664 IntStack( const IntStack& s );
00665 ~IntStack();
00666 void push( int i );
00667 int pop();
00668 void clear();
00669 inline int operator [](int i) { return _list[i]; }
00670 inline int size() { return _size; }
00671 IntStack& operator =( const IntStack& s );
00672 private:
00673 int *_list;
00674 int _size, _bufferSize;
00675 };
00676
00677 public:
00678 enum { MOVE_BEFORE, MOVE_INSIDE, MOVE_AFTER };
00679 protected:
00680
00682 class FLU_EXPORT RData {
00683 public:
00684
00685 int x, y, totalW, totalH;
00686 bool first, last, dragging, shiftSelect, shiftSelectAll, visibilityChanged, selectionFollowsHilight;
00687 Node *hilighted, *previous, *grabbed, *dragNode, *animatedNode;
00688 int delta, shadedIndex, counter, searchIndex, branchIconW, dragPos, dragWhere;
00689 Fl_Color lineColor, bgColor, selectionColor;
00690 bool forceResize;
00691 unsigned int nextId;
00692 FluSimpleString path;
00693 IntStack branchConnectors;
00694
00695
00696 int insertionMode;
00697 Fl_Image *defaultCollapseIcons[2], *defaultBranchIcons[2];
00698 Fl_Image *collapseIcons[2], *branchIcons[2], *leafIcon;
00699 int hGap, vGap, wGap;
00700 int lineStyle, lineWidth, selectionMode, selectionDragMode;
00701 bool showRoot, showConnectors, showLeaves, showBranches, openOnSelect,
00702 allowLeafDuplication, animate, animating, singleBranchOpen, moveOnlySameGroup, justOpenedClosed,
00703 isMoveValid, doubleClickToOpen, dnd, allBranchesAlwaysOpen, autoBranches, openWOChildren,
00704 selectUnderMouse, allowBranchDuplication;
00705 float collapseTime, fps, animationDelta, animationOffset;
00706 Fl_Color defLineColor, defSelectionColor, shadedColors[2];
00707 Fl_Color defLeafColor, defBranchColor;
00708 Fl_Font defLeafFont, defBranchFont;
00709 int defLeafSize, defBranchSize;
00710 int browserX, browserY, browserW, browserH;
00711 Node *root;
00712 Flu_Tree_Browser *tree;
00713 unsigned int cbReason;
00714 Node *cbNode, *lastOpenBranch;
00715 };
00716
00717 public:
00718
00719 #ifdef USE_FLU_DND
00720
00721
00723 class FLU_EXPORT DND_Object : public Flu_DND
00724 {
00725 public:
00726
00728 DND_Object();
00729
00731 inline void grab()
00732 { dnd_grab( this, "DND_Object" ); }
00733
00735 virtual const char* name() = 0;
00736
00737 };
00738 #endif
00739
00741 class FLU_EXPORT Node
00742 {
00743
00744 protected:
00745
00746 enum { ADD, REMOVE, FIND, FIND_NUMBER, GET_SELECTED };
00747 enum { DRAW, MEASURE, MEASURE_THIS_OPEN, HANDLE, COUNT_SELECTED };
00748
00749
00750 enum { SELECTED = 0x0001, COLLAPSED = 0x0002, LEAF = 0x0004, SHOW_LABEL = 0x0008,
00751 ACTIVE = 0x0010, EXPAND_TO_WIDTH = 0x0020, ALWAYS_OPEN = 0x0040,
00752 SOME_VISIBLE_CHILDREN = 0x0080, MOVABLE = 0x0100, DROPPABLE = 0x0200,
00753 AUTO_LABEL_COLOR = 0x0400, AUTO_COLOR = 0x0800, AUTO_LABEL = 0x1000,
00754 SWAP_LABEL_AND_WIDGET = 0x2000, ICON_AT_END = 0x4000 };
00755
00756
00757 inline bool CHECK( unsigned short flag ) const { return flags & flag; }
00758 inline void SET( unsigned short flag ) { flags |= flag; }
00759 inline void SET( unsigned short flag, bool b ) { if(b) SET(flag); else CLEAR(flag); }
00760 inline void CLEAR( unsigned short flag ) { flags &= ~flag; }
00761
00762 public:
00763
00765 inline bool active() const
00766 { return CHECK(ACTIVE); }
00767
00769 void active( bool b );
00770
00772 inline void activate()
00773 { active(true); }
00774
00776
00777 inline Node* add( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true )
00778 { return( modify( fullpath, ADD, tree->rdata, w, showLabel ) ); }
00779
00781 Node* add_branch( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00782
00784 Node* add_leaf( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00785
00787 Node* add( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00788
00790 Node* add_branch( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00791
00793 Node* add_leaf( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00794
00796 inline void always_open( bool b )
00797 { if( b ) open(true); SET(ALWAYS_OPEN,b); tree->rdata.forceResize = true; }
00798
00800 inline bool always_open() const
00801 { return CHECK(ALWAYS_OPEN); }
00802
00804 inline void auto_color( bool b )
00805 { SET(AUTO_COLOR,b); }
00806
00808 inline bool auto_color()
00809 { return CHECK(AUTO_COLOR); }
00810
00812 inline void auto_label( bool b )
00813 { SET(AUTO_LABEL,b); }
00814
00816 inline bool auto_label()
00817 { return CHECK(AUTO_LABEL); }
00818
00820 inline void auto_label_color( bool b )
00821 { SET(AUTO_LABEL_COLOR,b); }
00822
00824 inline bool auto_label_color()
00825 { return CHECK(AUTO_LABEL_COLOR); }
00826
00828 void branch_icons( Fl_Image *closed, Fl_Image *open );
00829
00831 inline void branch_icon( Fl_Image *icon )
00832 { branch_icons( icon, icon ); }
00833
00835 Node* child( int i ) const;
00836
00838 inline int children() const
00839 { return _children.size(); }
00840
00842 void clear();
00843
00845 inline void close()
00846 { open( false ); }
00847
00849 inline bool closed()
00850 { return !open(); }
00851
00853
00854 void collapse_icons( Fl_Image *closed, Fl_Image *open );
00855
00857 inline void deactivate()
00858 { active(false); }
00859
00861 unsigned short depth() const;
00862
00864 void do_callback( int reason );
00865
00867 inline void droppable( bool b )
00868 { SET(DROPPABLE,b); }
00869
00871 inline bool droppable()
00872 { return CHECK(DROPPABLE); }
00873
00875 inline void expand_to_width( bool b )
00876 { SET(EXPAND_TO_WIDTH,b); tree->rdata.forceResize = true; }
00877
00879 inline bool expand_to_width() const
00880 { return CHECK(EXPAND_TO_WIDTH); }
00881
00883
00884 inline Node* find( const char *fullpath )
00885 { return( modify( fullpath, FIND, tree->rdata ) ); }
00886
00888
00889 Node* find( unsigned int id );
00890
00892
00893 Node* find( Fl_Widget *w );
00894
00896
00897 inline Node* find( Node *n )
00898 { if( !n ) return NULL; else return find( n->id() ); }
00899
00901
00902 inline const char* find_path()
00903 { return tree->find_path( this ); }
00904
00906 Node* first();
00907
00909 Node* first_branch();
00910
00912 Node* first_leaf();
00913
00915 inline void swap_label_and_widget( bool b )
00916 { SET(SWAP_LABEL_AND_WIDGET,b); }
00917
00919 inline bool swap_label_and_widget()
00920 { return CHECK(SWAP_LABEL_AND_WIDGET); }
00921
00923
00924 Node* get_selected( int index );
00925
00927 inline void icon_at_end( bool b )
00928 { SET(ICON_AT_END,b); }
00929
00931 inline bool icon_at_end()
00932 { return CHECK(ICON_AT_END); }
00933
00935 inline unsigned int id() const
00936 { return _id; }
00937
00939
00940 int index() const;
00941
00943 Node* insert( const char* fullpath, int pos );
00944
00946 Node* insert_branch( const char* fullpath, int pos );
00947
00949 Node* insert_leaf( const char* fullpath, int pos );
00950
00952 bool is_ancestor( Node* n );
00953
00955 bool is_branch() const;
00956
00958 bool is_descendent( Node* n );
00959
00961 bool is_leaf() const;
00962
00964 inline bool is_root() const
00965 { return( _parent == 0 ); }
00966
00968 inline void label( const char *l )
00969 { text = l; tree->redraw(); }
00970
00972 inline const char* label() const
00973 { return text.c_str(); }
00974
00976 inline void label_color( Fl_Color c )
00977 { textColor = c; }
00978
00980 inline Fl_Color label_color() const
00981 { return textColor; }
00982
00984 inline void label_font( Fl_Font f )
00985 { textFont = f; tree->rdata.forceResize = true; }
00986
00988 inline Fl_Font label_font() const
00989 { return textFont; }
00990
00992 inline void label_size( unsigned char s )
00993 { textSize = s; tree->rdata.forceResize = true; }
00994
00996 inline unsigned char label_size() const
00997 { return textSize; }
00998
01000 inline bool label_visible() const
01001 { return CHECK(SHOW_LABEL); }
01002
01004 inline void label_visible( bool b )
01005 { SET(SHOW_LABEL,b); tree->rdata.forceResize = true; }
01006
01008 Node* last();
01009
01011 Node* last_branch();
01012
01014 Node* last_leaf();
01015
01017 void leaf_icon( Fl_Image *icon );
01018
01020 inline void movable( bool b )
01021 { SET(MOVABLE,b); }
01022
01024 inline bool movable()
01025 { return CHECK(MOVABLE); }
01026
01028
01030 bool move( int pos );
01031
01033
01036 inline bool move( int where, Node* n )
01037 { return( move( this, where, n ) ); }
01038
01040
01043 static bool move( Node* n1, int where, Node* n2 );
01044
01046 Node* next();
01047
01049 Node* next_branch();
01050
01052 Node* next_leaf();
01053
01055 Node* next_sibling();
01056
01058 int num_selected();
01059
01061 inline bool open() const
01062 { return( !CHECK(COLLAPSED) || tree->rdata.allBranchesAlwaysOpen ); }
01063
01065 void open( bool b );
01066
01068 inline Node* parent() const
01069 { return _parent; }
01070
01072 Node* previous();
01073
01075 Node* previous_branch();
01076
01078 Node* previous_leaf();
01079
01081 Node* previous_sibling();
01082
01084 void print( int spaces = 0 );
01085
01087
01088 inline unsigned int remove( const char *fullpath )
01089 { return( (unsigned int)modify( fullpath, REMOVE, tree->rdata ) ); }
01090
01092
01093 unsigned int remove( unsigned int id );
01094
01096
01097 unsigned int remove( Fl_Widget *w );
01098
01100
01101 inline unsigned int remove( Node* n )
01102 { if( !n ) return 0; else return remove( n->id() ); }
01103
01105 void select_all();
01106
01108 inline bool selected() const
01109 { return CHECK(SELECTED); }
01110
01112 void select( bool b );
01113
01115 inline void select_only()
01116 { tree->unselect_all(); select(true); }
01117
01119 inline void sort_children()
01120 { sort(); }
01121
01122 void sort_widgets();
01123
01125
01126 inline bool swap( Node* n )
01127 { return swap( this, n ); }
01128
01130
01131 static bool swap( Node* n1, Node* n2 );
01132
01134 void unselect_all( Node* except = NULL );
01135
01137 inline void* user_data()
01138 { return userData; }
01139
01141 inline void user_data( void *d )
01142 { userData = d; }
01143
01145 inline Fl_Widget* widget() const
01146 { return( _widget ? _widget->w : NULL ); }
01147
01149 void widget( Fl_Widget *w );
01150
01151 protected:
01152
01153 friend class Flu_Tree_Browser;
01154 friend class NodeList;
01155
01156
01157 Node( const char *lbl = 0 );
01158
01159
01160 Node( bool l, const char* n, Node *p, RData &rdata, Fl_Widget *w, bool showLabel );
01161
01162 ~Node();
01163
01164
01165 Node* modify( const char* path, int what, RData &rdata, Fl_Widget *w = 0, bool showLabel = true );
01166
01167 void initType();
01168
01169 void sort();
01170
01171 void determineVisibility( bool parentVisible = true );
01172
01173 static bool isMoveValid( Node* &n1, int &where, Node* &n2 );
01174
01175
01176 int recurse( RData &rdata, int type, int event = 0 );
01177
01178 void draw( RData &rdata, bool measure );
01179
01180
01181 bool findPath( unsigned int id, RData &rdata );
01182
01183
01184 bool findPath( Fl_Widget *w, RData &rdata );
01185
01186 class FLU_EXPORT WidgetInfo
01187 {
01188 public:
01189 Fl_Widget *w;
01190 int defaultW;
01191 void (*CB)(Fl_Widget*,void*);
01192 void *CBData;
01193 };
01194
01195 unsigned int _id;
01196 unsigned short flags;
01197 NodeList _children;
01198 Node *_parent;
01199 Flu_Tree_Browser *tree;
01200 FluSimpleString text;
01201 WidgetInfo *_widget;
01202 Fl_Group *_group;
01203 void *userData;
01204 int totalChildH;
01205 Fl_Image *cIcon[2], *bIcon[2], *lIcon;
01206 Fl_Color textColor;
01207 Fl_Font textFont;
01208 unsigned char textSize;
01209 unsigned short textW, textH;
01210 int currentY;
01211 unsigned short currentH;
01212
01213 inline static void _widgetCB( Fl_Widget* w, void* arg )
01214 { ((Node*)arg)->widgetCB(); }
01215 void widgetCB();
01216 };
01217
01218 protected:
01219
01220 inline static void _scrollCB( Fl_Widget* w, void* arg )
01221 { ((Flu_Tree_Browser*)arg)->redraw(); }
01222
01223 inline static void _timerRedrawCB( void *arg )
01224 { ((Flu_Tree_Browser*)arg)->timerRedrawCB(); }
01225 void timerRedrawCB();
01226
01227 inline static void _timerScrollCB( void *arg )
01228 { ((Flu_Tree_Browser*)arg)->timerScrollCB(); }
01229 void timerScrollCB();
01230
01231 void on_dnd_leave();
01232
01233 void on_dnd_release();
01234
01235 bool on_dnd_drag( int X, int Y );
01236
01237 void on_dnd_drop( const Flu_DND_Event *e );
01238
01239
01240 void draw();
01241
01242 Fl_Group *scrollBox;
01243 Fl_Scrollbar *scrollH, *scrollV;
01244 Fl_Group *_box;
01245 Node root;
01246 RData rdata;
01247
01248 float autoScrollX, autoScrollY;
01249 bool scrolledTimerOn, clearing;
01250
01251 };
01252
01253 #endif