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

Flu_Tree_Browser.h

00001 // $Id: Flu_Tree_Browser.h,v 1.91 2004/11/05 17:03:20 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.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   //inline void callback( Fl_Callback *c, void *user_data = 0 )
00188   //{ rdata.cb = c; rdata.cbd = user_data; }
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   //inline void when( unsigned int w )
00602   //{ rdata.when = w; }
00603 
00605   //inline unsigned int when() const
00606   //{ return rdata.when; }
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 );  // find the number of nodes in the list with name n
00633       Node* find( const char* n, int which = 1 );  // find the which'th node in the list with name n
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 }; // where to move a dragged node?
00671  protected:
00672 
00674   class FLU_EXPORT RData {
00675   public:
00676     // volatile objects (from the perspective of each node during a recursive descent)
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;  // force the browser to resize on the next draw (which forces a recalculation of the tree layout)
00683     unsigned int nextId;  // monotonically increasing id of each entry
00684     FluSimpleString path;  // used to construct the full path during a findPath() operation
00685     IntStack branchConnectors;
00686 
00687     // static objects (from the perspective of each node during a recursive descent)
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 };  // parameters for modify()
00739       enum { DRAW, MEASURE, MEASURE_THIS_OPEN, HANDLE, COUNT_SELECTED };  // parameters for recurse()
00740 
00741       // flags
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       // flag manipulator functions
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       // Root node constructor
01147       Node( const char *lbl = 0 );
01148 
01149       // Non-root constructor
01150       Node( bool l, const char* n, Node *p, RData &rdata, Fl_Widget *w, bool showLabel );
01151 
01152       ~Node();
01153 
01154       // add/remove/find/get
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       // handle/draw/measure/count
01166       int recurse( RData &rdata, int type, int event = 0 );
01167 
01168       void draw( RData &rdata, bool measure );
01169 
01170       // recursively finding the full path of the node identified by id
01171       bool findPath( unsigned int id, RData &rdata );
01172 
01173       // recursively finding the full path of the node containing w
01174       bool findPath( Fl_Widget *w, RData &rdata );
01175 
01176       class FLU_EXPORT WidgetInfo
01177         {
01178         public:
01179           Fl_Widget *w;
01180           int defaultW;  // the initial width of the widget
01181           void (*CB)(Fl_Widget*,void*);
01182           void *CBData;
01183         };
01184 
01185       unsigned int _id; // the unique id of this node
01186       unsigned short flags;
01187       NodeList _children;
01188       Node *_parent;
01189       Flu_Tree_Browser *tree;
01190       FluSimpleString text;
01191       WidgetInfo *_widget;  // memory overhead deferred to WidgetInfo. present only if widget is
01192       Fl_Group *_group;
01193       void *userData;
01194       int totalChildH; // needed for animation
01195       Fl_Image *cIcon[2], *bIcon[2], *lIcon;
01196       Fl_Color textColor;
01197       Fl_Font textFont;
01198       unsigned char textSize;  // the font size of the entry label text
01199       unsigned short textW, textH;  // how big the entry label actually is (stored within the node for performance reasons)
01200       int currentY; // needed for animation
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   /* override of Fl_Double_Window::draw() */
01230   void draw();
01231 
01232   Fl_Group *scrollBox;
01233   Fl_Scrollbar *scrollH, *scrollV;
01234   Fl_Group *_box;
01235   Node root;
01236   RData rdata;
01237   //int lastEvent;
01238   float autoScrollX, autoScrollY;
01239   bool scrolledTimerOn;
01240 
01241 };
01242 
01243 #endif

Generated on Fri Nov 5 12:41:32 2004 for FLTK Utility Library and Widget Collection (FLU) by doxygen 1.3.5