flu_tree_browser.cpp
来自「ncbi源码」· C++ 代码 · 共 2,583 行 · 第 1/5 页
CPP
2,583 行
{ rdata.lastHilighted = rdata.hilighted; } set_hilighted( NULL ); lastEvent = event; Fl_Group::handle( event ); redraw(); return 1; } if( !rdata.dragging ) { if( ! (event == FL_MOVE || event == FL_ENTER || event == FL_LEAVE ) ) _box->redraw(); if( Fl_Group::handle( event ) ) { //if( event == FL_KEYDOWN || event == FL_KEYUP ) // redraw(); return 1; } } if( event == FL_RELEASE ) { Fl::focus(this); rdata.dragging = false; rdata.grabbed = 0; rdata.dragNode = 0; redraw(); } int dx = Fl::box_dx(box()), dy = Fl::box_dy(box()); // set some initial values for the recursive data structure // account for the scrollbar positions rdata.x = x()+dx; rdata.y = y()+dy; if( scrollH->visible() ) rdata.x -= scrollH->value(); if( scrollV->visible() ) rdata.y -= scrollV->value(); rdata.previous = NULL; rdata.delta = 0; rdata.visibilityChanged = false; // catch cursor keys for moving the hilighted entry or selecting all entries if( event == FL_KEYDOWN ) { // move hilighted entry up if( Fl::event_key() == FL_Up ) { rdata.delta = -1; Fl::focus(this); redraw(); } // move hilighted entry down else if( Fl::event_key() == FL_Down ) { rdata.delta = 1; Fl::focus(this); redraw(); } // select all else if( Fl::event_state(FL_CTRL) && Fl::event_key() == 'a' ) { select_all(); Fl::focus(this); redraw(); return 1; } // check for the Home key else if( Fl::event_key() == FL_Home ) { // set the hilighted entry to be the first entry if( rdata.showRoot || ( rdata.root->_children.size() == 0 ) ) set_hilighted( rdata.root ); else if( rdata.root->_children.size() > 0 ) set_hilighted( rdata.root->_children.child(0) ); redraw(); } // check for the End key else if( Fl::event_key() == FL_End ) { // set the hilighted entry to be the last visible entry if( rdata.showRoot && ( rdata.root->_children.size() == 0 ) ) set_hilighted( rdata.root ); else { // find the last node by repeatedly looking for the last child until there are no more branches Node *n = &root; while( n->_children.size() && n->open() ) n = n->_children.child( n->_children.size()-1 ); set_hilighted( n ); } redraw(); } } // pass the event down the tree int val = root.recurse( rdata, Node::HANDLE, event ); if( val ) { redraw(); if( rdata.visibilityChanged ) root.determineVisibility(); if( val == 1 ) return 1; } // special case: if multi-select or single-select and user clicks on no items, unselect all items else if( (rdata.selectionMode != FLU_NO_SELECT) && (event == FL_PUSH) && (!Fl::event_state(FL_CTRL)) ) { unselect_all(); set_hilighted( NULL ); rdata.forceResize = true; redraw(); return 1; } if( event == FL_SHOW || event == FL_HIDE ) root.determineVisibility(); return Fl_Group::handle( event ); //return 0;}void Flu_Tree_Browser :: insertion_mode( int m ){ rdata.insertionMode = m; root.sort();}void Flu_Tree_Browser :: set_hilighted( Flu_Tree_Browser::Node* n ){ if( rdata.hilighted == n && rdata.when != FL_WHEN_NOT_CHANGED ) return; if( rdata.hilighted ) rdata.hilighted->do_callback( FLU_UNHILIGHTED ); rdata.hilighted = n; if( rdata.hilighted ) rdata.hilighted->do_callback( FLU_HILIGHTED ); if( rdata.hilighted ) { int extraH = scrollH->visible() ? scrollH->h() : 0; // if the hilighted entry is below the visible bounds of the browser, move the vertical scrollbar // so the hilighted entry is the last visible entry if( rdata.hilighted->currentY-y()+rdata.hilighted->currentH > scrollV->value()+h()-extraH ) ((Fl_Valuator*)scrollV)->value( rdata.hilighted->currentY-y() - h()+extraH + rdata.hilighted->currentH ); // if the hilighted entry is above the visible bounds of the browser, move the vertical scrollbar // so the hilighted entry is the first visible entry if( rdata.hilighted->currentY-y() < scrollV->value() ) ((Fl_Valuator*)scrollV)->value( rdata.hilighted->currentY-y() ); } redraw();}int Flu_Tree_Browser :: num_selected(){ return root.recurse( rdata, Node::COUNT_SELECTED );}Flu_Tree_Browser::Node* Flu_Tree_Browser :: get_selected( int index ){ rdata.counter = 0; rdata.searchIndex = index; Node *n = root.modify( 0, Node::GET_SELECTED, rdata ); rdata.searchIndex = 1; return n;}Flu_Tree_Browser :: Node :: Node( const char *lbl ){ flags = 0; userData = 0; _parent = 0; _widget = 0; SET(ACTIVE); CLEAR(LEAF); _id = 0; CLEAR(ALWAYS_OPEN); SET(COLLAPSED); SET(MOVABLE); SET(DROPPABLE); currentY = currentH = 0; totalChildH = 0; CLEAR(SELECTED); CLEAR(EXPAND_TO_WIDTH); SET(SHOW_LABEL); if( lbl == 0 ) text = ""; else text = lbl; cIcon[0] = cIcon[1] = bIcon[0] = bIcon[1] = lIcon = 0;}Flu_Tree_Browser :: Node :: Node( bool l, const char* n, Node *p, RData &rdata, Fl_Widget *w, bool showLbl ){ flags = 0; userData = 0; SET(LEAF,l); text = n; _id = 0; SET(ACTIVE); _parent = p; CLEAR(ALWAYS_OPEN); SET(COLLAPSED); CLEAR(SELECTED); CLEAR(EXPAND_TO_WIDTH); SET(MOVABLE); SET(DROPPABLE); _widget = 0; totalChildH = 0; currentY = currentH = 0; cIcon[0] = cIcon[1] = bIcon[0] = bIcon[1] = lIcon = 0; SET( SHOW_LABEL, showLbl ); tree = rdata.tree; initType(); _id = rdata.nextId++; widget( w );}void Flu_Tree_Browser :: Node :: initType(){ if( is_leaf() ) { lIcon = tree->rdata.leafIcon; textColor = tree->rdata.defLeafColor; textFont = tree->rdata.defLeafFont; textSize = tree->rdata.defLeafSize; } else { cIcon[0] = tree->rdata.collapseIcons[0]; cIcon[1] = tree->rdata.collapseIcons[1]; bIcon[0] = tree->rdata.branchIcons[0]; bIcon[1] = tree->rdata.branchIcons[1]; textColor = tree->rdata.defBranchColor; textFont = tree->rdata.defBranchFont; textSize = tree->rdata.defBranchSize; }}Flu_Tree_Browser :: Node :: ~Node(){ // if this node is in a tree, make sure it isn't holding a reference to us if( tree ) { if( tree->rdata.hilighted == this ) tree->rdata.hilighted = NULL; if( tree->rdata.lastHilighted == this ) tree->rdata.lastHilighted = NULL; if( tree->rdata.grabbed == this ) tree->rdata.grabbed = NULL; if( tree->rdata.dragNode == this ) tree->rdata.dragNode = NULL; } clear();}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: first(){ return this;}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: first_branch(){ Node *n = first(); while( n ) { if( n->is_branch() ) return n; else n = n->next(); } return NULL;}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: first_leaf(){ Node *n = first(); while( n ) { if( n->is_leaf() ) return n; else n = n->next(); } return NULL;}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: last(){ if( children() == 0 ) return this; else return( child( children() - 1 )->last() );}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: last_branch(){ Node *n = last(); while( n ) { if( n->is_branch() ) return n; else n = n->previous(); } return NULL;}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: last_leaf(){ Node *n = last(); while( n ) { if( n->is_leaf() ) return n; else n = n->previous(); } return NULL;}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: next_sibling(){ if( is_root() ) return NULL; int index; for( index = 0; index < _parent->children(); index++ ) if( _parent->child(index) == this ) break; // if we are the last child of our parent, then we have no next sibling if( index == _parent->children()-1 ) return NULL; // otherwise return our next sibling else return( _parent->child(index+1) );}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: previous_sibling(){ if( is_root() ) return NULL; int index; for( index = 0; index < _parent->children(); index++ ) if( _parent->child(index) == this ) break; // if we are the first child of our parent, then we have no previous sibling if( index == 0 ) return NULL; // otherwise return our previous sibling else return( _parent->child(index-1) );}int Flu_Tree_Browser :: Node :: index() const{ if( is_root() ) return -1; int index; for( index = 0; index < _parent->children(); index++ ) if( _parent->child(index) == this ) return index; return -1;}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: next(){ // take care of the root node as a special case if( is_root() ) { if( children() ) return child(0); else return NULL; } // if we are a branch, then the next node is our first child, unless we don't have any children if( is_branch() && _children.size() ) return _children.child(0); else { // otherwise, the next node is our next sibling. if there is no next sibling (because we // are the last child of our parent), then the next node is the next sibling of our parent (and so on...) Node *p = parent(), *n = next_sibling(); while( p ) { if( n ) return n; else { n = p->next_sibling(); p = p->parent(); } } return NULL; }}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: next_branch(){ Node *n = next(); while( n ) { if( n->is_branch() ) return n; else n = n->next(); } return NULL;}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: next_leaf(){ Node *n = next(); while( n ) { if( n->is_leaf() ) return n; else n = n->next(); } return NULL;}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: previous(){ // take care of the root node as a special case if( is_root() ) return NULL; // the previous node is either our parent's // previous sibling (if that sibling exists and is a leaf or a branch with no children), // or the last child of our parent's previous sibling (if that sibling exists and is // a branch with children). if there is no previous sibling, then the previous node // is our parent Node *n = previous_sibling(); if( !n ) return _parent; else { if( n->is_leaf() ) // is leaf, so that is the previous node return n; else if( n->children() ) // is branch with some children, so previous node is last child return( n->last() ); else // is branch with no children, so that is the previous node return n; }}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: previous_branch(){ Node *n = previous(); while( n ) { if( n->is_branch() ) return n; else n = n->previous(); } return NULL;}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: previous_leaf(){ Node *n = previous(); while( n ) { if( n->is_leaf() ) return n; else n = n->previous(); } return NULL;}void Flu_Tree_Browser :: Node :: determineVisibility( bool parentVisible ){ if( _widget ) { if( parentVisible ) _widget->w->show(); else _widget->w->hide(); } for( int i = 0; i < _children.size(); i++ ) _children.child(i)->determineVisibility( parentVisible && open() );}Flu_Tree_Browser::Node* Flu_Tree_Browser :: Node :: child( int i ) const{ if( i < 0 || i >= _children.size() ) return 0; else return _children.child(i);}void Flu_Tree_Browser :: Node :: clear(){ widget(NULL); for( int i = 0; i < _children.size(); i++ ) { //if( tree->rdata.cbNode == _children.child(i) ) //tree->rdata.cbNode = NULL; delete _children.child(i); } _children.clear();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?