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

Flu_Tree_Browser.h

00001 // $Id: Flu_Tree_Browser.h,v 1.94 2005/02/04 21:21:09 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   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   //inline void callback( Fl_Callback *c, void *user_data = 0 )
00196   //{ rdata.cb = c; rdata.cbd = user_data; }
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   //inline void when( unsigned int w )
00610   //{ rdata.when = w; }
00611 
00613   //inline unsigned int when() const
00614   //{ return rdata.when; }
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 );  // find the number of nodes in the list with name n
00641       Node* find( const char* n, int which = 1 );  // find the which'th node in the list with name n
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 }; // where to move a dragged node?
00679  protected:
00680 
00682   class FLU_EXPORT RData {
00683   public:
00684     // volatile objects (from the perspective of each node during a recursive descent)
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;  // force the browser to resize on the next draw (which forces a recalculation of the tree layout)
00691     unsigned int nextId;  // monotonically increasing id of each entry
00692     FluSimpleString path;  // used to construct the full path during a findPath() operation
00693     IntStack branchConnectors;
00694 
00695     // static objects (from the perspective of each node during a recursive descent)
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 };  // parameters for modify()
00747       enum { DRAW, MEASURE, MEASURE_THIS_OPEN, HANDLE, COUNT_SELECTED };  // parameters for recurse()
00748 
00749       // flags
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       // flag manipulator functions
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       // Root node constructor
01157       Node( const char *lbl = 0 );
01158 
01159       // Non-root constructor
01160       Node( bool l, const char* n, Node *p, RData &rdata, Fl_Widget *w, bool showLabel );
01161 
01162       ~Node();
01163 
01164       // add/remove/find/get
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       // handle/draw/measure/count
01176       int recurse( RData &rdata, int type, int event = 0 );
01177 
01178       void draw( RData &rdata, bool measure );
01179 
01180       // recursively finding the full path of the node identified by id
01181       bool findPath( unsigned int id, RData &rdata );
01182 
01183       // recursively finding the full path of the node containing w
01184       bool findPath( Fl_Widget *w, RData &rdata );
01185 
01186       class FLU_EXPORT WidgetInfo
01187         {
01188         public:
01189           Fl_Widget *w;
01190           int defaultW;  // the initial width of the widget
01191           void (*CB)(Fl_Widget*,void*);
01192           void *CBData;
01193         };
01194 
01195       unsigned int _id; // the unique id of this node
01196       unsigned short flags;
01197       NodeList _children;
01198       Node *_parent;
01199       Flu_Tree_Browser *tree;
01200       FluSimpleString text;
01201       WidgetInfo *_widget;  // memory overhead deferred to WidgetInfo. present only if widget is
01202       Fl_Group *_group;
01203       void *userData;
01204       int totalChildH; // needed for animation
01205       Fl_Image *cIcon[2], *bIcon[2], *lIcon;
01206       Fl_Color textColor;
01207       Fl_Font textFont;
01208       unsigned char textSize;  // the font size of the entry label text
01209       unsigned short textW, textH;  // how big the entry label actually is (stored within the node for performance reasons)
01210       int currentY; // needed for animation
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   /* override of Fl_Double_Window::draw() */
01240   void draw();
01241 
01242   Fl_Group *scrollBox;
01243   Fl_Scrollbar *scrollH, *scrollV;
01244   Fl_Group *_box;
01245   Node root;
01246   RData rdata;
01247   //int lastEvent;
01248   float autoScrollX, autoScrollY;
01249   bool scrolledTimerOn, clearing;
01250 
01251 };
01252 
01253 #endif

Generated on Mon Sep 26 07:54:04 2005 for FLTK Utility Library and Widget Collection (FLU) by doxygen 1.3.5