📄 flu_tree_browser.h
字号:
{ root.sort(); } //! Unselect all entries in the tree inline void unselect_all() { root.unselect_all(); } //! Set the vertical gap between tree entries. Default is 0 inline void vertical_gap( int g ) { rdata.vGap = g; rdata.forceResize = true; } //! Get the vertical gap between tree entries inline int vertical_gap() const { return rdata.vGap; } //! Override of Fl_Widget::when. Currently only FL_WHEN_NEVER, FL_WHEN_CHANGED, and FL_WHEN_NOT_CHANGED are supported. Default value is FL_WHEN_CHANGED /*! When the callback occurs, you can use callback_reason() to determine exactly what cause the callback and callback_node() to get the node that was affected. */ inline void when( unsigned int w ) { rdata.when = w; } //! Override of Fl_Widget::when inline unsigned int when() const { return rdata.when; } //! Set the gap between the widget and the icon that precedes it. Default is 2 inline void widget_gap( int g ) { rdata.wGap = g; rdata.forceResize = true; } //! Get the gap between the widget and the icon that precedes it inline int widget_gap() const { return rdata.wGap; } protected: class RData; //! Internal class holding an (alphabetically) ordered list of nodes class NCBI_GUIWIDGETS_FLU_EXPORT NodeList { public: NodeList(); ~NodeList(); void add( Node* n, int position = -1 ); inline Node* child( int n ) const { return _nodes[n]; } int erase( Node* n ); int erase( const char* n ); void erase( int n ); void clear(); int findNum( const char *n ); // find the number of nodes in the list with name n Node* find( const char* n, int which = 1 ); // find the which'th node in the list with name n inline int size() const { return _nNodes; }; void sort(); static bool move( Node* n1, int where, Node* n2 ); private: friend class Node; static int compareNodes( const void *arg1, const void* arg2 ); static int reverseCompareNodes( const void *arg1, const void* arg2 ); bool search( Node *n, int &index ); bool search( const char *n, int &index ); bool linSearch( Node *n, int &index ); bool linSearch( const char *n, int &index ); bool binSearch( Node *n, int &index ); bool binSearch( const char *n, int &index ); Node **_nodes; int _nNodes, _size; }; public: //! Internal class holding a stack of integers class NCBI_GUIWIDGETS_FLU_EXPORT IntStack { public: IntStack(); IntStack( const IntStack& s ); ~IntStack(); void push( int i ); int pop(); void clear(); inline int operator [](int i) { return _list[i]; } inline int size() { return _size; } IntStack& operator =( const IntStack& s ); private: int *_list; int _size, _bufferSize; }; public: enum { MOVE_BEFORE, MOVE_INSIDE, MOVE_AFTER }; // where to move a dragged node? protected: //! Recursive data structure passed down through the node tree class NCBI_GUIWIDGETS_FLU_EXPORT RData { public: // volatile objects (from the perspective of each node during a recursive descent) int x, y, totalW, totalH; bool first, last, dragging, shiftSelect, shiftSelectAll, visibilityChanged; Node *hilighted, *lastHilighted, *previous, *grabbed, *dragNode, *animatedNode; int delta, shadedIndex, counter, searchIndex, branchIconW, dragPos, dragWhere; Fl_Color lineColor, bgColor, selectionColor; bool forceResize; // force the browser to resize on the next draw (which forces a recalculation of the tree layout) unsigned int nextId; // monotonically increasing id of each entry FluSimpleString path; // used to construct the full path during a findPath() operation IntStack branchConnectors; // static objects (from the perspective of each node during a recursive descent) int insertionMode; Fl_Image *defaultCollapseIcons[2], *defaultBranchIcons[2]; Fl_Image *collapseIcons[2], *branchIcons[2], *leafIcon; int hGap, vGap, wGap; int lineStyle, lineWidth, selectionMode, selectionDragMode; bool showRoot, showConnectors, showLeaves, showBranches, openOnSelect, allowDuplication, animate, animating, singleBranchOpen, moveOnlySameGroup, justOpenedClosed, isMoveValid, doubleClickToOpen, dnd, allBranchesAlwaysOpen, autoBranches; float collapseTime, fps, animationDelta, animationOffset; Fl_Color defLineColor, defSelectionColor, shadedColors[2]; Fl_Color defLeafColor, defBranchColor; Fl_Font defLeafFont, defBranchFont; int defLeafSize, defBranchSize; int browserX, browserY, browserW, browserH; Node *root; Flu_Tree_Browser *tree; Fl_Callback *cb; void *cbd; unsigned int when, cbReason; Node *cbNode, *lastOpenBranch; //int (*sortCB)(Node*,Node*); }; public:#ifdef USE_FLU_DND //! This class can be subclassed to make an object which can be dropped on a tree to make a new node /*! When the object is dropped, the tree will name the object according to what the function \b name() returns */ class NCBI_GUIWIDGETS_FLU_EXPORT DND_Object : public Flu_DND { public: //! Default constructor DND_Object(); //! The descendent should call this when the user grabs the object to start dragging it (e.g. on the FL_PUSH event) inline void grab() { dnd_grab( this, "DND_Object" ); } //! Descendents MUST implement this function to return the name of the dropped object virtual const char* name() = 0; };#endif //! This class holds a single entry in the tree class NCBI_GUIWIDGETS_FLU_EXPORT Node { protected: enum { ADD, REMOVE, FIND, FIND_NUMBER, GET_SELECTED }; // parameters for modify() enum { DRAW, MEASURE, MEASURE_THIS_OPEN, HANDLE, COUNT_SELECTED }; // parameters for recurse() // flags enum { SELECTED = 0x0001, COLLAPSED = 0x0002, LEAF = 0x0004, SHOW_LABEL = 0x0008, ACTIVE = 0x0010, EXPAND_TO_WIDTH = 0x0020, ALWAYS_OPEN = 0x0040, SOME_VISIBLE_CHILDREN = 0x0080, MOVABLE = 0x0100, DROPPABLE = 0x0200 }; // flag manipulator functions inline bool CHECK( unsigned short flag ) const { return (flags & flag) ? true : false; } inline void SET( unsigned short flag ) { flags |= flag; } inline void SET( unsigned short flag, bool b ) { if(b) SET(flag); else CLEAR(flag); } inline void CLEAR( unsigned short flag ) { flags &= ~flag; } public: //! Is this node currently active? inline bool active() const { return CHECK(ACTIVE); } //! Activate or deactivate this node void active( bool b ); //! Activate this node inline void activate() { active(true); } //! Add the entry specified by \b fullpath to this node. If \b w is not \c NULL then that widget is the entry and the label (as specified in \b fullPath) is visible depending on the value of \b showLabel. Note that the widget is destroyed by the tree/node on clear() or the destructor /*! \return a pointer to the Node of the added entry or NULL if the add failed */ inline Node* add( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true ) { return( modify( fullpath, ADD, tree->rdata, w, showLabel ) ); } //! Convenience function that is the same as add() except it appends a '/' to \b fullpath if one does not exist Node* add_branch( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true ); //! Convenience function that is the same as add() except it removes any '/' at the end of \b fullpath Node* add_leaf( const char* fullpath, Fl_Widget *w = 0, bool showLabel = true ); //! Set whether a branch node is always open (only for branch nodes). Default is \c false inline void always_open( bool b ) { if( b ) open(true); SET(ALWAYS_OPEN,b); tree->rdata.forceResize = true; } //! Get whether a branch node is always open (only for branches) inline bool always_open() const { return CHECK(ALWAYS_OPEN); } //! Set the branch icons to use for this node (only for branch nodes) void branch_icons( Fl_Image *closed, Fl_Image *open ); //! Convenience routine to set both branch icons at once inline void branch_icon( Fl_Image *icon ) { branch_icons( icon, icon ); } //! \return child \b i of this node. Bounds checking is performed and NULL is returned if the child cannot be found Node* child( int i ) const; //! \return the number of child nodes beneath this node inline int children() const { return _children.size(); } //! Clear all child entries from this node (does not change the entry of this node) void clear(); //! Close this node (only for branches) inline void close() { open( false ); } //! Is this node closed? (only for branches) inline bool closed() { return !open(); } //! Set the collapse icons to use for this node (only for branch nodes) /*! \note if a NULL icon is passed, the default plus/minus icons are chosen */ void collapse_icons( Fl_Image *closed, Fl_Image *open ); //! Deactivate this node inline void deactivate() { active(false); } //! Get the depth of this node in the tree unsigned short depth() const; //! Do the tree browser callback. \b reason should be one of FLU_HILIGHTED, FLU_UNHILIGHTED, FLU_SELECTED, FLU_UNSELECTED, FLU_OPENED, FLU_CLOSED, FLU_DOUBLE_CLICK, FLU_WIDGET_CALLBACK void do_callback( int reason ); //! Set whether this node can receive new nodes as a result of dragging-and-dropping (only for branch nodes). Default is \c true inline void droppable( bool b ) { SET(DROPPABLE,b); } //! Get whether this node can receive new nodes as a result of dragging-and-dropping (only for branch nodes). inline bool droppable() { return CHECK(DROPPABLE); } //! Set whether to force the size of the widget to expand to fill the visible width of the browser. Default is \c false inline void expand_to_width( bool b ) { SET(EXPAND_TO_WIDTH,b); tree->rdata.forceResize = true; } //! Get whether to force the size of the widget to expand to fill the visible width of the browser inline bool expand_to_width() const { return CHECK(EXPAND_TO_WIDTH); } //! Find the entry identified by \b fullpath /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ inline Node* find( const char *fullpath ) { return( modify( fullpath, FIND, tree->rdata ) ); } //! Find the entry identified by unique id \b id /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ Node* find( unsigned int id ); //! Find the entry containing the widget \b w /*! \return a pointer to the Node of the found entry, or NULL if no matching entry was found */ Node* find( Fl_Widget *w ); //! Search for Node \b n /*! \return a pointer to \b n if it is found, or NULL if it is not present */ inline Node* find( Node *n ) { if( !n ) return NULL; else return find( n->id() ); } //! \return the full path of this node /*! \note the returned value is only valid until the next time find_path() is called */ inline const char* find_path() { return tree->find_path( this ); } //! \return the first node in this hierarchy (i.e. this node) Node* first(); //! \return the first branch encountered in a depth-first traversal (or this node if it is a branch). NULL means there are no branches Node* first_branch(); //! \return the first leaf encountered in a depth-first traversal (or this node if it is a leaf). NULL means there are no leaves Node* first_leaf();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -