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.allowDuplication = b; }
00109
00111 inline bool allow_leaf_duplication()
00112 { return rdata.allowDuplication; }
00113
00115 inline bool have_dnd()
00116 {
00117 #ifdef USE_FLU_DND
00118 return true;
00119 #else
00120 return false;
00121 #endif
00122 }
00123
00125
00128 inline void allow_dnd( bool b )
00129 { rdata.dnd = b; }
00130
00132 inline bool allow_dnd()
00133 { return rdata.dnd; }
00134
00136 inline void always_open( bool b )
00137 { root.always_open( b ); }
00138
00140 inline bool always_open()
00141 { return root.always_open(); }
00142
00144 inline void animate( bool b )
00145 { rdata.animate = b; }
00146
00148 inline bool animate()
00149 { return rdata.animate; }
00150
00152 void auto_branches( bool b );
00153
00155 inline bool auto_branches() const
00156 { return rdata.autoBranches; }
00157
00159 inline Fl_Color branch_color() const
00160 { return rdata.defBranchColor; }
00161
00163 inline Fl_Font branch_font() const
00164 { return rdata.defBranchFont; }
00165
00167 inline int branch_size() const
00168 { return rdata.defBranchSize; }
00169
00171 inline void branch_text( Fl_Color color, Fl_Font font, int size )
00172 { rdata.defBranchColor = color; rdata.defBranchFont = font; rdata.defBranchSize = size; }
00173
00175
00176 void branch_icons( Fl_Image *closed, Fl_Image *open );
00177
00179 inline Fl_Boxtype box() const
00180 { return _box->box(); }
00181
00183 inline void box( Fl_Boxtype b )
00184 { _box->box( b ); }
00185
00187
00188
00189
00191 inline int callback_reason() const
00192 { return rdata.cbReason; }
00193
00195
00196 inline Node* callback_node() const
00197 { return rdata.cbNode; }
00198
00200 void clear();
00201
00203 void collapse_icons( Fl_Image *closed, Fl_Image *open );
00204
00206 inline float collapse_time() const
00207 { return rdata.collapseTime; }
00208
00210 inline void collapse_time( float t )
00211 { rdata.collapseTime = t; }
00212
00214 inline Fl_Color color() const
00215 { return _box->color(); }
00216
00218 inline void color( Fl_Color c )
00219 { _box->color( c ); }
00220
00222 inline void color( unsigned c )
00223 { _box->color( (Fl_Color)c ); }
00224
00226 inline void connector_style( Fl_Color color, int style, int width = 1 )
00227 { rdata.defLineColor = color; rdata.lineStyle = style; rdata.lineWidth = width; }
00228
00230 inline Fl_Color connector_color() const
00231 { return rdata.defLineColor; }
00232
00234 inline int connector_style() const
00235 { return rdata.lineStyle; }
00236
00238 inline int connector_width() const
00239 { return rdata.lineWidth; }
00240
00242 inline void double_click_opens( bool b )
00243 { rdata.doubleClickToOpen = b; }
00244
00246 inline bool double_click_opens()
00247 { return rdata.doubleClickToOpen; }
00248
00250 inline Fl_Color even_shaded_entry_color() const
00251 { return rdata.shadedColors[0]; }
00252
00254
00255 inline Node* find( const char *fullpath )
00256 { return find_next( fullpath ); }
00257
00259
00260 Node* find( const char *path, const char *name );
00261
00263
00264 Node* find( unsigned int id );
00265
00267
00268 inline Node* find( Node *n )
00269 { if( !n ) return NULL; else return find( n->id() ); }
00270
00272
00273 Node* find( Fl_Widget *w );
00274
00276
00277 Node* find_next( const char *fullpath, Node* startNode = NULL );
00278
00280
00281 Node* find_next( const char *path, const char *name );
00282
00284 int find_number( const char *fullpath );
00285
00287 int find_number( const char *path, const char *name );
00288
00290
00291 const char* find_path( unsigned int id );
00292
00294
00295 const char* find_path( Fl_Widget *w );
00296
00298
00299 inline const char* find_path( Node *n )
00300 { if( !n ) return ""; else return find_path( n->id() ); }
00301
00303 inline Node* first() { return root.first(); }
00304
00306 inline Node* first_branch() { return root.first_branch(); }
00307
00309 inline Node* first_leaf() { return root.first_leaf(); }
00310
00312 inline float frame_rate() const
00313 { return rdata.fps; }
00314
00316 inline void frame_rate( float f )
00317 { if( f <= 0.0f ) rdata.fps = 0.001f; else rdata.fps = f; }
00318
00320 inline Node* get_hilighted()
00321 { return rdata.hilighted; }
00322
00324 inline Node *get_root() { return &root; }
00325
00327
00328 Node* get_selected( int index );
00329
00331 int handle( int event );
00332
00334 inline void horizontal_gap( int g )
00335 { rdata.hGap = g; rdata.forceResize = true; }
00336
00338 inline int horizontal_gap() const
00339 { return rdata.hGap; }
00340
00342 void insertion_mode( int m );
00343
00345 inline int insertion_mode()
00346 { return rdata.insertionMode; }
00347
00349 bool Flu_Tree_Browser :: inside_entry_area( int x, int y );
00350
00352 inline void label( const char *l )
00353 { root.text = l; }
00354
00356 inline const char* label() const
00357 { return root.text.c_str(); }
00358
00360 inline Node* last() { return root.last(); }
00361
00363 inline Node* last_branch() { return root.last_branch(); }
00364
00366 inline Node* last_leaf() { return root.last_leaf(); }
00367
00369 inline Fl_Color leaf_color() const
00370 { return rdata.defLeafColor; }
00371
00373 inline Fl_Font leaf_font() const
00374 { return rdata.defLeafFont; }
00375
00377 inline int leaf_size() const
00378 { return rdata.defLeafSize; }
00379
00381 void leaf_icon( Fl_Image *icon );
00382
00384 inline void leaf_text( Fl_Color color, Fl_Font font, int size )
00385 { rdata.defLeafColor = color; rdata.defLeafFont = font; rdata.defLeafSize = size; }
00386
00388 inline void move_only_same_group( bool b )
00389 { rdata.moveOnlySameGroup = b; }
00390
00392 inline bool move_only_same_group()
00393 { return rdata.moveOnlySameGroup; }
00394
00396 int num_selected();
00397
00399 inline Fl_Color odd_shaded_entry_color() const
00400 { return rdata.shadedColors[1]; }
00401
00403 inline void only_one_open_branch( bool b )
00404 { rdata.singleBranchOpen = b; }
00405
00407 inline bool only_one_open_branch()
00408 { return rdata.singleBranchOpen; }
00409
00411 inline void open( bool b )
00412 { root.open( b ); }
00413
00415 inline bool open() const
00416 { return root.open(); }
00417
00419 inline void open_without_children( bool b )
00420 { rdata.openWOChildren = b; }
00421
00423 inline bool open_without_children() const
00424 { return rdata.openWOChildren; }
00425
00427 inline void open_on_select( bool b )
00428 { rdata.openOnSelect = b; }
00429
00431 inline bool open_on_select() const
00432 { return rdata.openOnSelect; }
00433
00435 void print();
00436
00438
00439 unsigned int remove( const char *fullpath );
00440
00442
00443 unsigned int remove( const char *path, const char *name );
00444
00446
00447 unsigned int remove( unsigned int id );
00448
00450
00451 unsigned int remove( Fl_Widget *w );
00452
00454
00455 inline unsigned int remove( Node* n )
00456 { if( !n ) return 0; else return remove( n->id() ); }
00457
00459 void resize( int X, int Y, int W, int H );
00460
00462 inline void root_color( Fl_Color c )
00463 { get_root()->label_color( c ); }
00464
00466 inline Fl_Color root_color()
00467 { return get_root()->label_color(); }
00468
00470 inline void root_font( Fl_Font f )
00471 { get_root()->label_font( f ); }
00472
00474 inline Fl_Font root_font()
00475 { return get_root()->label_font(); }
00476
00478 inline void root_size( unsigned char s )
00479 { get_root()->label_size( s ); }
00480
00482 inline unsigned char root_size()
00483 { return get_root()->label_size(); }
00484
00486 inline void select_all()
00487 { root.select_all(); }
00488
00490 inline Fl_Color selection_color() const
00491 { return rdata.defSelectionColor; }
00492
00494 inline void selection_color( Fl_Color c )
00495 { rdata.defSelectionColor = c; }
00496
00498 inline void selection_color( unsigned c )
00499 { selection_color( (Fl_Color)c ); }
00500
00502 inline void selection_drag_mode( int m )
00503 { rdata.selectionDragMode = m; }
00504
00506 inline int selection_drag_mode() const
00507 { return rdata.selectionDragMode; }
00508
00510 inline void selection_follows_hilight( bool b )
00511 { rdata.selectionFollowsHilight = b; if( b && rdata.hilighted ) rdata.hilighted->select(true); }
00512
00514 inline bool selection_follows_hilight()
00515 { return rdata.selectionFollowsHilight; }
00516
00518 inline void selection_mode( int m )
00519 { rdata.selectionMode = m; root.unselect_all(); }
00520
00522 inline int selection_mode() const
00523 { return rdata.selectionMode; }
00524
00526 inline void select_under_mouse( bool b )
00527 { rdata.selectUnderMouse = b; }
00528
00530 inline bool select_under_mouse() const
00531 { return rdata.selectUnderMouse; }
00532
00534 void set_default_branch_icons();
00535
00537 void set_hilighted( Node* n );
00538
00540
00541 Node* set_root( const char *label, Fl_Widget *w = 0, bool showLabel = true );
00542
00544 inline void shaded_entry_colors( Fl_Color even, Fl_Color odd )
00545 { rdata.shadedColors[0] = even; rdata.shadedColors[1] = odd; }
00546
00548 inline void show_branches( bool b )
00549 { rdata.showBranches = b; rdata.forceResize = true; }
00550
00552 inline bool show_branches() const
00553 { return rdata.showBranches; }
00554
00556 inline void show_connectors( bool b )
00557 { rdata.showConnectors = b; }
00558
00560 inline bool show_connectors() const
00561 { return rdata.showConnectors; }
00562
00564 inline void show_root( bool b )
00565 { rdata.showRoot = b; rdata.forceResize = true; }
00566
00568 inline bool show_root() const
00569 { return rdata.showRoot; }
00570
00572 inline void show_leaves( bool b )
00573 { rdata.showLeaves = b; rdata.forceResize = true; }
00574
00576 inline bool show_leaves() const
00577 { return rdata.showLeaves; }
00578
00580 inline void sort()
00581 { root.sort(); }
00582
00584 inline void unselect_all()
00585 { root.unselect_all(); }
00586
00587 inline static void use_FLU_WIDGET_CALLBACK( bool b )
00588 { USE_FLU_WIDGET_CALLBACK = b; }
00589
00591 inline void vertical_gap( int g )
00592 { rdata.vGap = g; rdata.forceResize = true; }
00593
00595 inline int vertical_gap() const
00596 { return rdata.vGap; }
00597
00599
00601
00602
00603
00605
00606
00607
00609 inline void widget_gap( int g )
00610 { rdata.wGap = g; rdata.forceResize = true; }
00611
00613 inline int widget_gap() const
00614 { return rdata.wGap; }
00615
00616 protected:
00617
00618 class RData;
00619
00621 class FLU_EXPORT NodeList
00622 {
00623 public:
00624 NodeList();
00625 ~NodeList();
00626 void add( Node* n, int position = -1 );
00627 inline Node* child( int n ) const { return _nodes[n]; }
00628 int erase( Node* n );
00629 int erase( const char* n );
00630 void erase( int n );
00631 void clear();
00632 int findNum( const char *n );
00633 Node* find( const char* n, int which = 1 );
00634 inline int size() const { return _nNodes; };
00635 void sort();
00636 static bool move( Node* n1, int where, Node* n2 );
00637 private:
00638 friend class Node;
00639 static int compareNodes( const void *arg1, const void* arg2 );
00640 static int reverseCompareNodes( const void *arg1, const void* arg2 );
00641 bool search( Node *n, int &index );
00642 bool search( const char *n, int &index );
00643 bool linSearch( Node *n, int &index );
00644 bool linSearch( const char *n, int &index );
00645 bool binSearch( Node *n, int &index );
00646 bool binSearch( const char *n, int &index );
00647 Node **_nodes;
00648 int _nNodes, _size;
00649 };
00650
00652 class FLU_EXPORT IntStack
00653 {
00654 public:
00655 IntStack();
00656 IntStack( const IntStack& s );
00657 ~IntStack();
00658 void push( int i );
00659 int pop();
00660 void clear();
00661 inline int operator [](int i) { return _list[i]; }
00662 inline int size() { return _size; }
00663 IntStack& operator =( const IntStack& s );
00664 private:
00665 int *_list;
00666 int _size, _bufferSize;
00667 };
00668
00669 public:
00670 enum { MOVE_BEFORE, MOVE_INSIDE, MOVE_AFTER };
00671 protected:
00672
00674 class FLU_EXPORT RData {
00675 public:
00676
00677 int x, y, totalW, totalH;
00678 bool first, last, dragging, shiftSelect, shiftSelectAll, visibilityChanged, selectionFollowsHilight;
00679 Node *hilighted, *previous, *grabbed, *dragNode, *animatedNode;
00680 int delta, shadedIndex, counter, searchIndex, branchIconW, dragPos, dragWhere;
00681 Fl_Color lineColor, bgColor, selectionColor;
00682 bool forceResize;
00683 unsigned int nextId;
00684 FluSimpleString path;
00685 IntStack branchConnectors;
00686
00687
00688 int insertionMode;
00689 Fl_Image *defaultCollapseIcons[2], *defaultBranchIcons[2];
00690 Fl_Image *collapseIcons[2], *branchIcons[2], *leafIcon;
00691 int hGap, vGap, wGap;
00692 int lineStyle, lineWidth, selectionMode, selectionDragMode;
00693 bool showRoot, showConnectors, showLeaves, showBranches, openOnSelect,
00694 allowDuplication, animate, animating, singleBranchOpen, moveOnlySameGroup, justOpenedClosed,
00695 isMoveValid, doubleClickToOpen, dnd, allBranchesAlwaysOpen, autoBranches, openWOChildren,
00696 selectUnderMouse;
00697 float collapseTime, fps, animationDelta, animationOffset;
00698 Fl_Color defLineColor, defSelectionColor, shadedColors[2];
00699 Fl_Color defLeafColor, defBranchColor;
00700 Fl_Font defLeafFont, defBranchFont;
00701 int defLeafSize, defBranchSize;
00702 int browserX, browserY, browserW, browserH;
00703 Node *root;
00704 Flu_Tree_Browser *tree;
00705 unsigned int cbReason;
00706 Node *cbNode, *lastOpenBranch;
00707 };
00708
00709 public:
00710
00711 #ifdef USE_FLU_DND
00712
00713
00715 class FLU_EXPORT DND_Object : public Flu_DND
00716 {
00717 public:
00718
00720 DND_Object();
00721
00723 inline void grab()
00724 { dnd_grab( this, "DND_Object" ); }
00725
00727 virtual const char* name() = 0;
00728
00729 };
00730 #endif
00731
00733 class FLU_EXPORT Node
00734 {
00735
00736 protected:
00737
00738 enum { ADD, REMOVE, FIND, FIND_NUMBER, GET_SELECTED };
00739 enum { DRAW, MEASURE, MEASURE_THIS_OPEN, HANDLE, COUNT_SELECTED };
00740
00741
00742 enum { SELECTED = 0x0001, COLLAPSED = 0x0002, LEAF = 0x0004, SHOW_LABEL = 0x0008,
00743 ACTIVE = 0x0010, EXPAND_TO_WIDTH = 0x0020, ALWAYS_OPEN = 0x0040,
00744 SOME_VISIBLE_CHILDREN = 0x0080, MOVABLE = 0x0100, DROPPABLE = 0x0200,
00745 AUTO_LABEL_COLOR = 0x0400, AUTO_COLOR = 0x0800, AUTO_LABEL = 0x1000,
00746 SWAP_LABEL_AND_WIDGET = 0x2000, ICON_AT_END = 0x4000 };
00747
00748
00749 inline bool CHECK( unsigned short flag ) const { return flags & flag; }
00750 inline void SET( unsigned short flag ) { flags |= flag; }
00751 inline void SET( unsigned short flag, bool b ) { if(b) SET(flag); else CLEAR(flag); }
00752 inline void CLEAR( unsigned short flag ) { flags &= ~flag; }
00753
00754 public:
00755
00757 inline bool active() const
00758 { return CHECK(ACTIVE); }
00759
00761 void active( bool b );
00762
00764 inline void activate()
00765 { active(true); }
00766
00768
00769 inline Node* add( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true )
00770 { return( modify( fullpath, ADD, tree->rdata, w, showLabel ) ); }
00771
00773 Node* add_branch( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00774
00776 Node* add_leaf( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00777
00779 Node* add( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00780
00782 Node* add_branch( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00783
00785 Node* add_leaf( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00786
00788 inline void always_open( bool b )
00789 { if( b ) open(true); SET(ALWAYS_OPEN,b); tree->rdata.forceResize = true; }
00790
00792 inline bool always_open() const
00793 { return CHECK(ALWAYS_OPEN); }
00794
00796 inline void auto_color( bool b )
00797 { SET(AUTO_COLOR,b); }
00798
00800 inline bool auto_color()
00801 { return CHECK(AUTO_COLOR); }
00802
00804 inline void auto_label( bool b )
00805 { SET(AUTO_LABEL,b); }
00806
00808 inline bool auto_label()
00809 { return CHECK(AUTO_LABEL); }
00810
00812 inline void auto_label_color( bool b )
00813 { SET(AUTO_LABEL_COLOR,b); }
00814
00816 inline bool auto_label_color()
00817 { return CHECK(AUTO_LABEL_COLOR); }
00818
00820 void branch_icons( Fl_Image *closed, Fl_Image *open );
00821
00823 inline void branch_icon( Fl_Image *icon )
00824 { branch_icons( icon, icon ); }
00825
00827 Node* child( int i ) const;
00828
00830 inline int children() const
00831 { return _children.size(); }
00832
00834 void clear();
00835
00837 inline void close()
00838 { open( false ); }
00839
00841 inline bool closed()
00842 { return !open(); }
00843
00845
00846 void collapse_icons( Fl_Image *closed, Fl_Image *open );
00847
00849 inline void deactivate()
00850 { active(false); }
00851
00853 unsigned short depth() const;
00854
00856 void do_callback( int reason );
00857
00859 inline void droppable( bool b )
00860 { SET(DROPPABLE,b); }
00861
00863 inline bool droppable()
00864 { return CHECK(DROPPABLE); }
00865
00867 inline void expand_to_width( bool b )
00868 { SET(EXPAND_TO_WIDTH,b); tree->rdata.forceResize = true; }
00869
00871 inline bool expand_to_width() const
00872 { return CHECK(EXPAND_TO_WIDTH); }
00873
00875
00876 inline Node* find( const char *fullpath )
00877 { return( modify( fullpath, FIND, tree->rdata ) ); }
00878
00880
00881 Node* find( unsigned int id );
00882
00884
00885 Node* find( Fl_Widget *w );
00886
00888
00889 inline Node* find( Node *n )
00890 { if( !n ) return NULL; else return find( n->id() ); }
00891
00893
00894 inline const char* find_path()
00895 { return tree->find_path( this ); }
00896
00898 Node* first();
00899
00901 Node* first_branch();
00902
00904 Node* first_leaf();
00905
00907 inline void swap_label_and_widget( bool b )
00908 { SET(SWAP_LABEL_AND_WIDGET,b); }
00909
00911 inline bool swap_label_and_widget()
00912 { return CHECK(SWAP_LABEL_AND_WIDGET); }
00913
00915
00916 Node* get_selected( int index );
00917
00919 inline void icon_at_end( bool b )
00920 { SET(ICON_AT_END,b); }
00921
00923 inline bool icon_at_end()
00924 { return CHECK(ICON_AT_END); }
00925
00927 inline unsigned int id() const
00928 { return _id; }
00929
00931
00932 int index() const;
00933
00935 Node* insert( const char* fullpath, int pos );
00936
00938 Node* insert_branch( const char* fullpath, int pos );
00939
00941 Node* insert_leaf( const char* fullpath, int pos );
00942
00944 bool is_ancestor( Node* n );
00945
00947 bool is_branch() const;
00948
00950 bool is_descendent( Node* n );
00951
00953 bool is_leaf() const;
00954
00956 inline bool is_root() const
00957 { return( _parent == 0 ); }
00958
00960 inline void label( const char *l )
00961 { text = l; tree->redraw(); }
00962
00964 inline const char* label() const
00965 { return text.c_str(); }
00966
00968 inline void label_color( Fl_Color c )
00969 { textColor = c; }
00970
00972 inline Fl_Color label_color() const
00973 { return textColor; }
00974
00976 inline void label_font( Fl_Font f )
00977 { textFont = f; tree->rdata.forceResize = true; }
00978
00980 inline Fl_Font label_font() const
00981 { return textFont; }
00982
00984 inline void label_size( unsigned char s )
00985 { textSize = s; tree->rdata.forceResize = true; }
00986
00988 inline unsigned char label_size() const
00989 { return textSize; }
00990
00992 inline bool label_visible() const
00993 { return CHECK(SHOW_LABEL); }
00994
00996 inline void label_visible( bool b )
00997 { SET(SHOW_LABEL,b); tree->rdata.forceResize = true; }
00998
01000 Node* last();
01001
01003 Node* last_branch();
01004
01006 Node* last_leaf();
01007
01009 void leaf_icon( Fl_Image *icon );
01010
01012 inline void movable( bool b )
01013 { SET(MOVABLE,b); }
01014
01016 inline bool movable()
01017 { return CHECK(MOVABLE); }
01018
01020
01022 bool move( int pos );
01023
01025
01028 inline bool move( int where, Node* n )
01029 { return( move( this, where, n ) ); }
01030
01032
01035 static bool move( Node* n1, int where, Node* n2 );
01036
01038 Node* next();
01039
01041 Node* next_branch();
01042
01044 Node* next_leaf();
01045
01047 Node* next_sibling();
01048
01050 int num_selected();
01051
01053 inline bool open() const
01054 { return( !CHECK(COLLAPSED) || tree->rdata.allBranchesAlwaysOpen ); }
01055
01057 void open( bool b );
01058
01060 inline Node* parent() const
01061 { return _parent; }
01062
01064 Node* previous();
01065
01067 Node* previous_branch();
01068
01070 Node* previous_leaf();
01071
01073 Node* previous_sibling();
01074
01076 void print( int spaces = 0 );
01077
01079
01080 inline unsigned int remove( const char *fullpath )
01081 { return( (unsigned int)modify( fullpath, REMOVE, tree->rdata ) ); }
01082
01084
01085 unsigned int remove( unsigned int id );
01086
01088
01089 unsigned int remove( Fl_Widget *w );
01090
01092
01093 inline unsigned int remove( Node* n )
01094 { if( !n ) return 0; else return remove( n->id() ); }
01095
01097 void select_all();
01098
01100 inline bool selected() const
01101 { return CHECK(SELECTED); }
01102
01104 void select( bool b );
01105
01107 inline void select_only()
01108 { tree->unselect_all(); select(true); }
01109
01111 inline void sort_children()
01112 { sort(); }
01113
01115
01116 inline bool swap( Node* n )
01117 { return swap( this, n ); }
01118
01120
01121 static bool swap( Node* n1, Node* n2 );
01122
01124 void unselect_all( Node* except = NULL );
01125
01127 inline void* user_data()
01128 { return userData; }
01129
01131 inline void user_data( void *d )
01132 { userData = d; }
01133
01135 inline Fl_Widget* widget() const
01136 { return( _widget ? _widget->w : NULL ); }
01137
01139 void widget( Fl_Widget *w );
01140
01141 protected:
01142
01143 friend class Flu_Tree_Browser;
01144 friend class NodeList;
01145
01146
01147 Node( const char *lbl = 0 );
01148
01149
01150 Node( bool l, const char* n, Node *p, RData &rdata, Fl_Widget *w, bool showLabel );
01151
01152 ~Node();
01153
01154
01155 Node* modify( const char* path, int what, RData &rdata, Fl_Widget *w = 0, bool showLabel = true );
01156
01157 void initType();
01158
01159 void sort();
01160
01161 void determineVisibility( bool parentVisible = true );
01162
01163 static bool isMoveValid( Node* &n1, int &where, Node* &n2 );
01164
01165
01166 int recurse( RData &rdata, int type, int event = 0 );
01167
01168 void draw( RData &rdata, bool measure );
01169
01170
01171 bool findPath( unsigned int id, RData &rdata );
01172
01173
01174 bool findPath( Fl_Widget *w, RData &rdata );
01175
01176 class FLU_EXPORT WidgetInfo
01177 {
01178 public:
01179 Fl_Widget *w;
01180 int defaultW;
01181 void (*CB)(Fl_Widget*,void*);
01182 void *CBData;
01183 };
01184
01185 unsigned int _id;
01186 unsigned short flags;
01187 NodeList _children;
01188 Node *_parent;
01189 Flu_Tree_Browser *tree;
01190 FluSimpleString text;
01191 WidgetInfo *_widget;
01192 Fl_Group *_group;
01193 void *userData;
01194 int totalChildH;
01195 Fl_Image *cIcon[2], *bIcon[2], *lIcon;
01196 Fl_Color textColor;
01197 Fl_Font textFont;
01198 unsigned char textSize;
01199 unsigned short textW, textH;
01200 int currentY;
01201 unsigned short currentH;
01202
01203 inline static void _widgetCB( Fl_Widget* w, void* arg )
01204 { ((Node*)arg)->widgetCB(); }
01205 void widgetCB();
01206 };
01207
01208 protected:
01209
01210 inline static void _scrollCB( Fl_Widget* w, void* arg )
01211 { ((Flu_Tree_Browser*)arg)->redraw(); }
01212
01213 inline static void _timerRedrawCB( void *arg )
01214 { ((Flu_Tree_Browser*)arg)->timerRedrawCB(); }
01215 void timerRedrawCB();
01216
01217 inline static void _timerScrollCB( void *arg )
01218 { ((Flu_Tree_Browser*)arg)->timerScrollCB(); }
01219 void timerScrollCB();
01220
01221 void on_dnd_leave();
01222
01223 void on_dnd_release();
01224
01225 bool on_dnd_drag( int X, int Y );
01226
01227 void on_dnd_drop( const Flu_DND_Event *e );
01228
01229
01230 void draw();
01231
01232 Fl_Group *scrollBox;
01233 Fl_Scrollbar *scrollH, *scrollV;
01234 Fl_Group *_box;
01235 Node root;
01236 RData rdata;
01237
01238 float autoScrollX, autoScrollY;
01239 bool scrolledTimerOn;
01240
01241 };
01242
01243 #endif