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 #define USE_FLU_DND
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
00072 Node* add( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00073
00075
00077 inline Node* add( Node* n, const char* name, Fl_Widget *w = 0, bool showLabel = true )
00078 { return n->add( name, w, showLabel ); }
00079
00081 Node* add_branch( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00082
00084 Node* add_branch( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00085
00087 inline Node* add_branch( Node* n, const char* name, Fl_Widget *w = 0, bool showLabel = true )
00088 { return n->add_branch( name, w, showLabel ); }
00089
00091 Node* add_leaf( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00092
00094 Node* add_leaf( const char* path, const char* name, Fl_Widget *w = 0, bool showLabel = true );
00095
00097 inline Node* add_leaf( Node* n, const char* name, Fl_Widget *w = 0, bool showLabel = true )
00098 { return n->add_leaf( name, w, showLabel ); }
00099
00101 inline void all_branches_always_open( bool b )
00102 { rdata.allBranchesAlwaysOpen = b; }
00103
00105 inline bool all_branches_always_open()
00106 { return rdata.allBranchesAlwaysOpen; }
00107
00109 inline void allow_leaf_duplication( bool b )
00110 { rdata.allowDuplication = b; }
00111
00113 inline bool allow_leaf_duplication()
00114 { return rdata.allowDuplication; }
00115
00117 inline bool have_dnd()
00118 {
00119 #ifdef USE_FLU_DND
00120 return true;
00121 #else
00122 return false;
00123 #endif
00124 }
00125
00127
00130 inline void allow_dnd( bool b )
00131 { rdata.dnd = b; }
00132
00134 inline bool allow_dnd()
00135 { return rdata.dnd; }
00136
00138 inline void always_open( bool b )
00139 { root.always_open( b ); }
00140
00142 inline bool always_open()
00143 { return root.always_open(); }
00144
00146 inline void animate( bool b )
00147 { rdata.animate = b; }
00148
00150 inline bool animate()
00151 { return rdata.animate; }
00152
00154 void auto_branches( bool b );
00155
00157 inline bool auto_branches() const
00158 { return rdata.autoBranches; }
00159
00161 inline Fl_Color branch_color() const
00162 { return rdata.defBranchColor; }
00163
00165 inline Fl_Font branch_font() const
00166 { return rdata.defBranchFont; }
00167
00169 inline int branch_size() const
00170 { return rdata.defBranchSize; }
00171
00173 inline void branch_text( Fl_Color color, Fl_Font font, int size )
00174 { rdata.defBranchColor = color; rdata.defBranchFont = font; rdata.defBranchSize = size; }
00175
00177 void branch_icons( Fl_Image *closed, Fl_Image *open );
00178
00180 inline Fl_Boxtype box() const
00181 { return _box->box(); }
00182
00184 inline void box( Fl_Boxtype b )
00185 { _box->box( b ); }
00186
00188
00189
00190
00192 inline int callback_reason() const
00193 { return rdata.cbReason; }
00194
00196
00197 inline Node* callback_node() const
00198 { return rdata.cbNode; }
00199
00201 void clear();
00202
00204 void collapse_icons( Fl_Image *closed, Fl_Image *open );
00205
00207 inline float collapse_time() const
00208 { return rdata.collapseTime; }
00209
00211 inline void collapse_time( float t )
00212 { rdata.collapseTime = t; }
00213
00215 inline Fl_Color color() const
00216 { return _box->color(); }
00217
00219 inline void color( Fl_Color c )
00220 { _box->color( c ); }
00221
00223 inline void color( unsigned c )
00224 { _box->color( (Fl_Color)c ); }
00225
00227 inline void connector_style( Fl_Color color, int style, int width = 1 )
00228 { rdata.defLineColor = color; rdata.lineStyle = style; rdata.lineWidth = width; }
00229
00231 inline Fl_Color connector_color() const
00232 { return rdata.defLineColor; }
00233
00235 inline int connector_style() const
00236 { return rdata.lineStyle; }
00237
00239 inline int connector_width() const
00240 { return rdata.lineWidth; }
00241
00243 inline void double_click_opens( bool b )
00244 { rdata.doubleClickToOpen = b; }
00245
00247 inline bool double_click_opens()
00248 { return rdata.doubleClickToOpen; }
00249
00251 inline Fl_Color even_shaded_entry_color() const
00252 { return rdata.shadedColors[0]; }
00253
00255
00256 inline Node* find( const char *fullpath )
00257 { return find_next( fullpath ); }
00258
00260
00261 Node* find( const char *path, const char *name );
00262
00264
00265 Node* find( unsigned int id );
00266
00268
00269 inline Node* find( Node *n )
00270 { if( !n ) return NULL; else return find( n->id() ); }
00271
00273
00274 Node* find( Fl_Widget *w );
00275
00277
00278 Node* find_next( const char *fullpath, Node* startNode = NULL );
00279
00281
00282 Node* find_next( const char *path, const char *name );
00283
00285 int find_number( const char *fullpath );
00286
00288 int find_number( const char *path, const char *name );
00289
00291
00292 const char* find_path( unsigned int id );
00293
00295
00296 const char* find_path( Fl_Widget *w );
00297
00299
00300 inline const char* find_path( Node *n )
00301 { if( !n ) return ""; else return find_path( n->id() ); }
00302
00304 inline Node* first() { return root.first(); }
00305
00307 inline Node* first_branch() { return root.first_branch(); }
00308
00310 inline Node* first_leaf() { return root.first_leaf(); }
00311
00313 inline float frame_rate() const
00314 { return rdata.fps; }
00315
00317 inline void frame_rate( float f )
00318 { if( f <= 0.0f ) rdata.fps = 0.001f; else rdata.fps = f; }
00319
00321 inline Node *get_root() { return &root; }
00322
00324
00325 Node* get_selected( int index );
00326
00328 int handle( int event );
00329
00331 inline void horizontal_gap( int g )
00332 { rdata.hGap = g; rdata.forceResize = true; }
00333
00335 inline int horizontal_gap() const
00336 { return rdata.hGap; }
00337
00339 void insertion_mode( int m );
00340
00342 inline int insertion_mode()
00343 { return rdata.insertionMode; }
00344
00346 bool Flu_Tree_Browser :: inside_entry_area( int x, int y );
00347
00349 inline void label( const char *l )
00350 { root.text = l; }
00351
00353 inline const char* label() const
00354 { return root.text.c_str(); }
00355
00357 inline Node* last() { return root.last(); }
00358
00360 inline Node* last_branch() { return root.last_branch(); }
00361
00363 inline Node* last_leaf() { return root.last_leaf(); }
00364
00366 inline Fl_Color leaf_color() const
00367 { return rdata.defLeafColor; }
00368
00370 inline Fl_Font leaf_font() const
00371 { return rdata.defLeafFont; }
00372
00374 inline int leaf_size() const
00375 { return rdata.defLeafSize; }
00376
00378 void leaf_icon( Fl_Image *icon );
00379
00381 inline void leaf_text( Fl_Color color, Fl_Font font, int size )
00382 { rdata.defLeafColor = color; rdata.defLeafFont = font; rdata.defLeafSize = size; }
00383
00385 inline void move_only_same_group( bool b )
00386 { rdata.moveOnlySameGroup = b; }
00387
00389 inline bool move_only_same_group()
00390 { return rdata.moveOnlySameGroup; }
00391
00393 int num_selected();
00394
00396 inline Fl_Color odd_shaded_entry_color() const
00397 { return rdata.shadedColors[1]; }
00398
00400 inline void only_one_open_branch( bool b )
00401 { rdata.singleBranchOpen = b; }
00402
00404 inline bool only_one_open_branch()
00405 { return rdata.singleBranchOpen; }
00406
00408 inline void open( bool b )
00409 { root.open( b ); }
00410
00412 inline bool open() const
00413 { return root.open(); }
00414
00416 inline void open_without_children( bool b )
00417 { rdata.openWOChildren = b; }
00418
00420 inline bool open_without_children() const
00421 { return rdata.openWOChildren; }
00422
00424 inline void open_on_select( bool b )
00425 { rdata.openOnSelect = b; }
00426
00428 inline bool open_on_select() const
00429 { return rdata.openOnSelect; }
00430
00432 void print();
00433
00435
00436 unsigned int remove( const char *fullpath );
00437
00439
00440 unsigned int remove( const char *path, const char *name );
00441
00443
00444 unsigned int remove( unsigned int id );
00445
00447
00448 unsigned int remove( Fl_Widget *w );
00449
00451
00452 inline unsigned int remove( Node* n )
00453 { if( !n ) return 0; else return remove( n->id() ); }
00454
00456 void resize( int X, int Y, int W, int H );
00457
00459 inline void root_color( Fl_Color c )
00460 { get_root()->label_color( c ); }
00461
00463 inline Fl_Color root_color()
00464 { return get_root()->label_color(); }
00465
00467 inline void root_font( Fl_Font f )
00468 { get_root()->label_font( f ); }
00469
00471 inline Fl_Font root_font()
00472 { return get_root()->label_font(); }
00473
00475 inline void root_size( unsigned char s )
00476 { get_root()->label_size( s ); }
00477
00479 inline unsigned char root_size()
00480 { return get_root()->label_size(); }
00481
00483 inline void select_all()
00484 { root.select_all(); }
00485
00487 inline Fl_Color selection_color() const
00488 { return rdata.defSelectionColor; }
00489
00491 inline void selection_color( Fl_Color c )
00492 { rdata.defSelectionColor = c; }
00493
00495 inline void selection_color( unsigned c )
00496 { selection_color( (Fl_Color)c ); }
00497
00499 inline void selection_drag_mode( int m )
00500 { rdata.selectionDragMode = m; }
00501
00503 inline int selection_drag_mode() const
00504 { return rdata.selectionDragMode; }
00505
00507 inline void selection_mode( int m )
00508 { rdata.selectionMode = m; root.unselect_all(); }
00509
00511 inline int selection_mode() const
00512 { return rdata.selectionMode; }
00513
00514 inline void select_under_mouse( bool b )
00515 { rdata.selectUnderMouse = b; }
00516
00517 inline bool select_under_mouse() const
00518 { return rdata.selectUnderMouse; }
00519
00521 void set_hilighted( Node* n );
00522
00524
00525 Node* set_root( const char *label, Fl_Widget *w = 0, bool showLabel = true );
00526
00528 inline void shaded_entry_colors( Fl_Color even, Fl_Color odd )
00529 { rdata.shadedColors[0] = even; rdata.shadedColors[1] = odd; }
00530
00532 inline void show_branches( bool b )
00533 { rdata.showBranches = b; rdata.forceResize = true; }
00534
00536 inline bool show_branches() const
00537 { return rdata.showBranches; }
00538
00540 inline void show_connectors( bool b )
00541 { rdata.showConnectors = b; }
00542
00544 inline bool show_connectors() const
00545 { return rdata.showConnectors; }
00546
00548 inline void show_root( bool b )
00549 { rdata.showRoot = b; rdata.forceResize = true; }
00550
00552 inline bool show_root() const
00553 { return rdata.showRoot; }
00554
00556 inline void show_leaves( bool b )
00557 { rdata.showLeaves = b; rdata.forceResize = true; }
00558
00560 inline bool show_leaves() const
00561 { return rdata.showLeaves; }
00562
00564 inline void sort()
00565 { root.sort(); }
00566
00568 inline void unselect_all()
00569 { root.unselect_all(); }
00570
00571 inline static void use_FLU_WIDGET_CALLBACK( bool b )
00572 { USE_FLU_WIDGET_CALLBACK = b; }
00573
00575 inline void vertical_gap( int g )
00576 { rdata.vGap = g; rdata.forceResize = true; }
00577
00579 inline int vertical_gap() const
00580 { return rdata.vGap; }
00581
00583
00585
00586
00587
00589
00590
00591
00593 inline void widget_gap( int g )
00594 { rdata.wGap = g; rdata.forceResize = true; }
00595
00597 inline int widget_gap() const
00598 { return rdata.wGap; }
00599
00600 protected:
00601
00602 class RData;
00603
00605 class FLU_EXPORT NodeList
00606 {
00607 public:
00608 NodeList();
00609 ~NodeList();
00610 void add( Node* n, int position = -1 );
00611 inline Node* child( int n ) const { return _nodes[n]; }
00612 int erase( Node* n );
00613 int erase( const char* n );
00614 void erase( int n );
00615 void clear();
00616 int findNum( const char *n );
00617 Node* find( const char* n, int which = 1 );
00618 inline int size() const { return _nNodes; };
00619 void sort();
00620 static bool move( Node* n1, int where, Node* n2 );
00621 private:
00622 friend class Node;
00623 static int compareNodes( const void *arg1, const void* arg2 );
00624 static int reverseCompareNodes( const void *arg1, const void* arg2 );
00625 bool search( Node *n, int &index );
00626 bool search( const char *n, int &index );
00627 bool linSearch( Node *n, int &index );
00628 bool linSearch( const char *n, int &index );
00629 bool binSearch( Node *n, int &index );
00630 bool binSearch( const char *n, int &index );
00631 Node **_nodes;
00632 int _nNodes, _size;
00633 };
00634
00636 class FLU_EXPORT IntStack
00637 {
00638 public:
00639 IntStack();
00640 IntStack( const IntStack& s );
00641 ~IntStack();
00642 void push( int i );
00643 int pop();
00644 void clear();
00645 inline int operator [](int i) { return _list[i]; }
00646 inline int size() { return _size; }
00647 IntStack& operator =( const IntStack& s );
00648 private:
00649 int *_list;
00650 int _size, _bufferSize;
00651 };
00652
00653 public:
00654 enum { MOVE_BEFORE, MOVE_INSIDE, MOVE_AFTER };
00655 protected:
00656
00658 class FLU_EXPORT RData {
00659 public:
00660
00661 int x, y, totalW, totalH;
00662 bool first, last, dragging, shiftSelect, shiftSelectAll, visibilityChanged;
00663 Node *hilighted, *lastHilighted, *previous, *grabbed, *dragNode, *animatedNode;
00664 int delta, shadedIndex, counter, searchIndex, branchIconW, dragPos, dragWhere;
00665 Fl_Color lineColor, bgColor, selectionColor;
00666 bool forceResize;
00667 unsigned int nextId;
00668 FluSimpleString path;
00669 IntStack branchConnectors;
00670
00671
00672 int insertionMode;
00673 Fl_Image *defaultCollapseIcons[2], *defaultBranchIcons[2];
00674 Fl_Image *collapseIcons[2], *branchIcons[2], *leafIcon;
00675 int hGap, vGap, wGap;
00676 int lineStyle, lineWidth, selectionMode, selectionDragMode;
00677 bool showRoot, showConnectors, showLeaves, showBranches, openOnSelect,
00678 allowDuplication, animate, animating, singleBranchOpen, moveOnlySameGroup, justOpenedClosed,
00679 isMoveValid, doubleClickToOpen, dnd, allBranchesAlwaysOpen, autoBranches, openWOChildren,
00680 selectUnderMouse;
00681 float collapseTime, fps, animationDelta, animationOffset;
00682 Fl_Color defLineColor, defSelectionColor, shadedColors[2];
00683 Fl_Color defLeafColor, defBranchColor;
00684 Fl_Font defLeafFont, defBranchFont;
00685 int defLeafSize, defBranchSize;
00686 int browserX, browserY, browserW, browserH;
00687 Node *root;
00688 Flu_Tree_Browser *tree;
00689 unsigned int cbReason;
00690 Node *cbNode, *lastOpenBranch;
00691 };
00692
00693 public:
00694
00695 #ifdef USE_FLU_DND
00696
00697
00699 class FLU_EXPORT DND_Object : public Flu_DND
00700 {
00701 public:
00702
00704 DND_Object();
00705
00707 inline void grab()
00708 { dnd_grab( this, "DND_Object" ); }
00709
00711 virtual const char* name() = 0;
00712
00713 };
00714 #endif
00715
00717 class FLU_EXPORT Node
00718 {
00719
00720 protected:
00721
00722 enum { ADD, REMOVE, FIND, FIND_NUMBER, GET_SELECTED };
00723 enum { DRAW, MEASURE, MEASURE_THIS_OPEN, HANDLE, COUNT_SELECTED };
00724
00725
00726 enum { SELECTED = 0x0001, COLLAPSED = 0x0002, LEAF = 0x0004, SHOW_LABEL = 0x0008,
00727 ACTIVE = 0x0010, EXPAND_TO_WIDTH = 0x0020, ALWAYS_OPEN = 0x0040,
00728 SOME_VISIBLE_CHILDREN = 0x0080, MOVABLE = 0x0100, DROPPABLE = 0x0200 };
00729
00730
00731 inline bool CHECK( unsigned short flag ) const { return flags & flag; }
00732 inline void SET( unsigned short flag ) { flags |= flag; }
00733 inline void SET( unsigned short flag, bool b ) { if(b) SET(flag); else CLEAR(flag); }
00734 inline void CLEAR( unsigned short flag ) { flags &= ~flag; }
00735
00736 public:
00737
00739 inline bool active() const
00740 { return CHECK(ACTIVE); }
00741
00743 void active( bool b );
00744
00746 inline void activate()
00747 { active(true); }
00748
00750
00751 inline Node* add( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true )
00752 { return( modify( fullpath, ADD, tree->rdata, w, showLabel ) ); }
00753
00755 Node* add_branch( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00756
00758 Node* add_leaf( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true );
00759
00761 inline void always_open( bool b )
00762 { if( b ) open(true); SET(ALWAYS_OPEN,b); tree->rdata.forceResize = true; }
00763
00765 inline bool always_open() const
00766 { return CHECK(ALWAYS_OPEN); }
00767
00769 void branch_icons( Fl_Image *closed, Fl_Image *open );
00770
00772 inline void branch_icon( Fl_Image *icon )
00773 { branch_icons( icon, icon ); }
00774
00776 Node* child( int i ) const;
00777
00779 inline int children() const
00780 { return _children.size(); }
00781
00783 void clear();
00784
00786 inline void close()
00787 { open( false ); }
00788
00790 inline bool closed()
00791 { return !open(); }
00792
00794
00795 void collapse_icons( Fl_Image *closed, Fl_Image *open );
00796
00798 inline void deactivate()
00799 { active(false); }
00800
00802 unsigned short depth() const;
00803
00805 void do_callback( int reason );
00806
00808 inline void droppable( bool b )
00809 { SET(DROPPABLE,b); }
00810
00812 inline bool droppable()
00813 { return CHECK(DROPPABLE); }
00814
00816 inline void expand_to_width( bool b )
00817 { SET(EXPAND_TO_WIDTH,b); tree->rdata.forceResize = true; }
00818
00820 inline bool expand_to_width() const
00821 { return CHECK(EXPAND_TO_WIDTH); }
00822
00824
00825 inline Node* find( const char *fullpath )
00826 { return( modify( fullpath, FIND, tree->rdata ) ); }
00827
00829
00830 Node* find( unsigned int id );
00831
00833
00834 Node* find( Fl_Widget *w );
00835
00837
00838 inline Node* find( Node *n )
00839 { if( !n ) return NULL; else return find( n->id() ); }
00840
00842
00843 inline const char* find_path()
00844 { return tree->find_path( this ); }
00845
00847 Node* first();
00848
00850 Node* first_branch();
00851
00853 Node* first_leaf();
00854
00856
00857 Node* get_selected( int index );
00858
00860 inline unsigned int id() const
00861 { return _id; }
00862
00864
00865 int index() const;
00866
00868 Node* insert( const char* fullpath, int pos );
00869
00871 Node* insert_branch( const char* fullpath, int pos );
00872
00874 Node* insert_leaf( const char* fullpath, int pos );
00875
00877 bool is_ancestor( Node* n );
00878
00880 bool is_branch() const;
00881
00883 bool is_descendent( Node* n );
00884
00886 bool is_leaf() const;
00887
00889 inline bool is_root() const
00890 { return( _parent == 0 ); }
00891
00893 inline void label( const char *l )
00894 { text = l; tree->redraw(); }
00895
00897 inline const char* label() const
00898 { return text.c_str(); }
00899
00901 inline void label_color( Fl_Color c )
00902 { textColor = c; }
00903
00905 inline Fl_Color label_color() const
00906 { return textColor; }
00907
00909 inline void label_font( Fl_Font f )
00910 { textFont = f; tree->rdata.forceResize = true; }
00911
00913 inline Fl_Font label_font() const
00914 { return textFont; }
00915
00917 inline void label_size( unsigned char s )
00918 { textSize = s; tree->rdata.forceResize = true; }
00919
00921 inline unsigned char label_size() const
00922 { return textSize; }
00923
00925 inline bool label_visible() const
00926 { return CHECK(SHOW_LABEL); }
00927
00929 inline void label_visible( bool b )
00930 { SET(SHOW_LABEL,b); tree->rdata.forceResize = true; }
00931
00933 Node* last();
00934
00936 Node* last_branch();
00937
00939 Node* last_leaf();
00940
00942 void leaf_icon( Fl_Image *icon );
00943
00945 inline void movable( bool b )
00946 { SET(MOVABLE,b); }
00947
00949 inline bool movable()
00950 { return CHECK(MOVABLE); }
00951
00953
00955 bool move( int pos );
00956
00958
00961 inline bool move( int where, Node* n )
00962 { return( move( this, where, n ) ); }
00963
00965
00968 static bool move( Node* n1, int where, Node* n2 );
00969
00971 Node* next();
00972
00974 Node* next_branch();
00975
00977 Node* next_leaf();
00978
00980 Node* next_sibling();
00981
00983 int num_selected();
00984
00986 inline bool open() const
00987 { return( !CHECK(COLLAPSED) || tree->rdata.allBranchesAlwaysOpen ); }
00988
00990 void open( bool b );
00991
00993 inline Node* parent() const
00994 { return _parent; }
00995
00997 Node* previous();
00998
01000 Node* previous_branch();
01001
01003 Node* previous_leaf();
01004
01006 Node* previous_sibling();
01007
01009 void print( int spaces = 0 );
01010
01012
01013 inline unsigned int remove( const char *fullpath )
01014 { return( (unsigned int)modify( fullpath, REMOVE, tree->rdata ) ); }
01015
01017
01018 unsigned int remove( unsigned int id );
01019
01021
01022 unsigned int remove( Fl_Widget *w );
01023
01025
01026 inline unsigned int remove( Node* n )
01027 { if( !n ) return 0; else return remove( n->id() ); }
01028
01030 void select_all();
01031
01033 inline bool selected() const
01034 { return CHECK(SELECTED); }
01035
01037 void select( bool b );
01038
01040 inline void select_only()
01041 { tree->unselect_all(); select(true); }
01042
01044 inline void sort_children()
01045 { sort(); }
01046
01048
01049 inline bool swap( Node* n )
01050 { swap( this, n ); }
01051
01053
01054 static bool swap( Node* n1, Node* n2 );
01055
01057 void unselect_all( Node* except = NULL );
01058
01060 inline void* user_data()
01061 { return userData; }
01062
01064 inline void user_data( void *d )
01065 { userData = d; }
01066
01068 inline Fl_Widget* widget() const
01069 { return( _widget ? _widget->w : NULL ); }
01070
01072 void widget( Fl_Widget *w );
01073
01074 protected:
01075
01076 friend class Flu_Tree_Browser;
01077 friend class NodeList;
01078
01079
01080 Node( const char *lbl = 0 );
01081
01082
01083 Node( bool l, const char* n, Node *p, RData &rdata, Fl_Widget *w, bool showLabel );
01084
01085 ~Node();
01086
01087
01088 Node* modify( const char* path, int what, RData &rdata, Fl_Widget *w = 0, bool showLabel = true );
01089
01090 void initType();
01091
01092 void sort();
01093
01094 void determineVisibility( bool parentVisible = true );
01095
01096 static bool isMoveValid( Node* &n1, int &where, Node* &n2 );
01097
01098
01099 int recurse( RData &rdata, int type, int event = 0 );
01100
01101 void draw( RData &rdata, bool measure );
01102
01103
01104 bool findPath( unsigned int id, RData &rdata );
01105
01106
01107 bool findPath( Fl_Widget *w, RData &rdata );
01108
01109 class FLU_EXPORT WidgetInfo
01110 {
01111 public:
01112 Fl_Widget *w;
01113 int defaultW;
01114 void (*CB)(Fl_Widget*,void*);
01115 void *CBData;
01116 };
01117
01118 unsigned int _id;
01119 unsigned short flags;
01120 NodeList _children;
01121 Node *_parent;
01122 Flu_Tree_Browser *tree;
01123 FluSimpleString text;
01124 WidgetInfo *_widget;
01125 Fl_Group *_group;
01126 void *userData;
01127 int totalChildH;
01128 Fl_Image *cIcon[2], *bIcon[2], *lIcon;
01129 Fl_Color textColor;
01130 Fl_Font textFont;
01131 unsigned char textSize;
01132 unsigned short textW, textH;
01133 int currentY;
01134 unsigned short currentH;
01135
01136 inline static void _widgetCB( Fl_Widget* w, void* arg )
01137 { ((Node*)arg)->widgetCB(); }
01138 void widgetCB();
01139 };
01140
01141 protected:
01142
01143 inline static void _scrollCB( Fl_Widget* w, void* arg )
01144 { ((Flu_Tree_Browser*)arg)->redraw(); }
01145
01146 inline static void _timerRedrawCB( void *arg )
01147 { ((Flu_Tree_Browser*)arg)->timerRedrawCB(); }
01148 void timerRedrawCB();
01149
01150 inline static void _timerScrollCB( void *arg )
01151 { ((Flu_Tree_Browser*)arg)->timerScrollCB(); }
01152 void timerScrollCB();
01153
01154 void on_dnd_leave();
01155
01156 void on_dnd_release();
01157
01158 bool on_dnd_drag( int X, int Y );
01159
01160 void on_dnd_drop( const Flu_DND_Event *e );
01161
01162
01163 void draw();
01164
01165 Fl_Group *scrollBox;
01166 Fl_Scrollbar *scrollH, *scrollV;
01167 Fl_Group *_box;
01168 Node root;
01169 RData rdata;
01170 int lastEvent;
01171 float autoScrollX, autoScrollY;
01172 bool scrolledTimerOn;
01173
01174 };
01175
01176 #endif