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 + -
显示快捷键?