Main Page | Class Hierarchy | Class List | File List | Class Members

Flu_Tree_Browser.h

00001 // $Id: Flu_Tree_Browser.h,v 1.87 2004/08/02 14:18:16 jbryan Exp $
00002 
00003 /***************************************************************
00004  *                FLU - FLTK Utility Widgets 
00005  *  Copyright (C) 2002 Ohio Supercomputer Center, Ohio State University
00006  *
00007  * This file and its content is protected by a software license.
00008  * You should have received a copy of this license with this file.
00009  * If not, please contact the Ohio Supercomputer Center immediately:
00010  * Attn: Jason Bryan Re: FLU 1224 Kinnear Rd, Columbus, Ohio 43212
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 /* fltk includes */
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 /* flu includes */
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;  // for compatibilty when not compiling DND support
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   //inline void callback( Fl_Callback *c, void *user_data = 0 )
00189   //{ rdata.cb = c; rdata.cbd = user_data; }
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   //inline void when( unsigned int w )
00586   //{ rdata.when = w; }
00587 
00589   //inline unsigned int when() const
00590   //{ return rdata.when; }
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 );  // find the number of nodes in the list with name n
00617       Node* find( const char* n, int which = 1 );  // find the which'th node in the list with name n
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 }; // where to move a dragged node?
00655  protected:
00656 
00658   class FLU_EXPORT RData {
00659   public:
00660     // volatile objects (from the perspective of each node during a recursive descent)
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;  // force the browser to resize on the next draw (which forces a recalculation of the tree layout)
00667     unsigned int nextId;  // monotonically increasing id of each entry
00668     FluSimpleString path;  // used to construct the full path during a findPath() operation
00669     IntStack branchConnectors;
00670 
00671     // static objects (from the perspective of each node during a recursive descent)
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 };  // parameters for modify()
00723       enum { DRAW, MEASURE, MEASURE_THIS_OPEN, HANDLE, COUNT_SELECTED };  // parameters for recurse()
00724 
00725       // flags
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       // flag manipulator functions
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       // Root node constructor
01080       Node( const char *lbl = 0 );
01081 
01082       // Non-root constructor
01083       Node( bool l, const char* n, Node *p, RData &rdata, Fl_Widget *w, bool showLabel );
01084 
01085       ~Node();
01086 
01087       // add/remove/find/get
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       // handle/draw/measure/count
01099       int recurse( RData &rdata, int type, int event = 0 );
01100 
01101       void draw( RData &rdata, bool measure );
01102 
01103       // recursively finding the full path of the node identified by id
01104       bool findPath( unsigned int id, RData &rdata );
01105 
01106       // recursively finding the full path of the node containing w
01107       bool findPath( Fl_Widget *w, RData &rdata );
01108 
01109       class FLU_EXPORT WidgetInfo
01110         {
01111         public:
01112           Fl_Widget *w;
01113           int defaultW;  // the initial width of the widget
01114           void (*CB)(Fl_Widget*,void*);
01115           void *CBData;
01116         };
01117 
01118       unsigned int _id; // the unique id of this node
01119       unsigned short flags;
01120       NodeList _children;
01121       Node *_parent;
01122       Flu_Tree_Browser *tree;
01123       FluSimpleString text;
01124       WidgetInfo *_widget;  // memory overhead deferred to WidgetInfo. present only if widget is
01125       Fl_Group *_group;
01126       void *userData;
01127       int totalChildH; // needed for animation
01128       Fl_Image *cIcon[2], *bIcon[2], *lIcon;
01129       Fl_Color textColor;
01130       Fl_Font textFont;
01131       unsigned char textSize;  // the font size of the entry label text
01132       unsigned short textW, textH;  // how big the entry label actually is (stored within the node for performance reasons)
01133       int currentY; // needed for animation
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   /* override of Fl_Double_Window::draw() */
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

Generated on Mon Aug 2 10:27:46 2004 for FLTK Utility Library and Widget Collection (FLU) by doxygen 1.3.5