treelistcontrol.cpp
来自「这是VCF框架的代码」· C++ 代码 · 共 2,390 行 · 第 1/5 页
CPP
2,390 行
context->rectangle( &expanderRect ); context->strokePath(); if ( true == item->isExpanded() ) { context->moveTo( expanderRect.left_ + expanderRect.getWidth()/2.0 - expanderRect.getWidth()/4.0, expanderRect.top_ + expanderRect.getHeight()/2.0 ); context->lineTo( expanderRect.right_ - expanderRect.getWidth()/2.0 + expanderRect.getWidth()/4.0, expanderRect.top_ + expanderRect.getHeight()/2.0 ); context->strokePath(); } else { context->moveTo( expanderRect.left_ + expanderRect.getWidth()/2.0 - expanderRect.getWidth()/4.0, expanderRect.top_ + expanderRect.getHeight()/2.0 ); context->lineTo( expanderRect.right_ - expanderRect.getWidth()/2.0 + expanderRect.getWidth()/4.0, expanderRect.top_ + expanderRect.getHeight()/2.0 ); context->strokePath(); context->moveTo( expanderRect.left_ + expanderRect.getWidth()/2.0 -0.5 , expanderRect.top_ + expanderRect.getHeight()/2.0 - expanderRect.getHeight()/4.0 ); context->lineTo( expanderRect.left_ + expanderRect.getWidth()/2.0 - 0.5, expanderRect.bottom_ - expanderRect.getHeight()/2.0 + expanderRect.getHeight()/4.0 + 1.0); context->strokePath(); }#else std::vector<Point> triangle(4); if ( true == item->isExpanded() ) { //triangle width is 9, and height is 9 //triangle.resize(6); triangle[0].x_ = expanderRect.left_+spacer; triangle[0].y_ = (int)(((expanderRect.top_ + expanderRect.getHeight()/2.0) - 9.0/2.0) + 0.5); //triangle[1] = triangle[0]; //triangle[1].y_ += 1; triangle[1].x_ = (int)((triangle[0].x_ + 9.0/2.0) + 0.0); triangle[1].y_ = triangle[0].y_ + 9; triangle[2] = triangle[0]; triangle[2].x_ += 9; triangle[3] = triangle[0]; //triangle[4].x_ += 9; //triangle[5] = triangle[0]; //triangle[1] = Point( triangle[0].x_ + (expanderRect.getWidth()), triangle[0].y_ ) ); //triangle[2] = Point( triangle[0].x_ + (expanderRect.getWidth()/2.0), triangle[0].y_ + (expanderRect.getHeight()/2.0); //triangle[3] = Point( triangle[0].x_, triangle[0].y_ ); } else { //triangle width is 10, and height is 11 triangle[0].x_ = expanderRect.left_+spacer; triangle[0].y_ = (int)(((expanderRect.top_ + expanderRect.getWidth()/2.0) - 11/2.0) + 0.5); triangle[1] = triangle[0]; triangle[1].y_ += 11; triangle[2].x_ = triangle[0].x_ + 10; triangle[2].y_ = (int)((triangle[0].y_ + 11.0/2.0) + 0.5); triangle[3] = triangle[0]; } context->setColor( GraphicsToolkit::getSystemColor( SYSCOLOR_SHADOW ) ); context->polyline( triangle ); context->fillPath();/* if ( true == item->isExpanded() ) { context->setColor( GraphicsToolkit::getSystemColor( SYSCOLOR_SHADOW ) ); context->moveTo( triangle[1].x_-1, triangle[1].y_ ); context->lineTo( triangle[0].x_, triangle[0].y_ ); context->lineTo( triangle[2].x_, triangle[2].y_ ); context->strokePath(); context->setColor( GraphicsToolkit::getSystemColor( SYSCOLOR_HIGHLIGHT ) ); context->moveTo( triangle[2].x_, triangle[2].y_ ); context->lineTo( triangle[1].x_-1, triangle[1].y_ ); context->strokePath(); } else { context->setColor( GraphicsToolkit::getSystemColor( SYSCOLOR_SHADOW ) ); context->moveTo( triangle[1].x_, triangle[1].y_-1 ); context->lineTo( triangle[0].x_, triangle[0].y_ ); context->lineTo( triangle[2].x_+1, triangle[2].y_+1 ); context->strokePath(); context->setColor( GraphicsToolkit::getSystemColor( SYSCOLOR_HIGHLIGHT ) ); context->moveTo( triangle[2].x_, triangle[2].y_+1 ); context->lineTo( triangle[1].x_, triangle[1].y_ ); context->strokePath(); } */#endif}void TreeListControl::paintItemState( TreeItem* item, GraphicsContext* context, Rect* paintRect, const long& currentIndent ){ Rect stateRect = getStateRect( item, currentIndent ); stateRect.inflate( -1, -1 ); if ( NULL != stateImageList_ ) { stateImageList_->draw( context, item->getStateImageIndex(), &stateRect ); } else { stateRect.inflate( -1, -1 ); long state = item->getState(); ButtonState buttonState; buttonState.setActive( true ); buttonState.setPressed( state == Item::idsChecked ? true : false ); context->drawThemeCheckboxRect( &stateRect, buttonState );/* if ( state == Item::idsChecked ) { stateRect.inflate(-2,-2); stateRect.setRight(stateRect.getRight()-4); context->setColor(Color::getColor("blue")); context->rectangle(&stateRect); context->fillPath(); // Below draws an X for a checked entry context->setAntiAliasingOn(true); context->moveTo(stateRect.getTopLeft()); context->lineTo(stateRect.getBottomRight()); context->moveTo(stateRect.getTopRight()); context->lineTo(stateRect.getBottomLeft()); context->strokePath(); } */ }}void TreeListControl::paintItemImage( TreeItem* item, GraphicsContext* context, Rect* paintRect, const long& currentIndent ){ Rect imageRect; imageRect.left_ += currentIndent; imageRect.right_ = imageRect.left_ + imageList_->getImageWidth(); ulong32 index = item->getImageIndex(); if ( (true == item->isExpanded()) && (item->getExpandedImageIndex() < imageList_->getImageCount()) ) { index = item->getExpandedImageIndex(); } imageRect.top_ = paintRect->top_ + (paintRect->getHeight()/2.0 - imageList_->getImageHeight()/2.0); imageRect.bottom_ = imageRect.top_ + imageList_->getImageHeight(); if ( displayOptions_ & TreeListControl::tdoShowColumnHeader ) { //get the first column width ColumnItem* item = header_->getColumnModel()->getItemFromIndex(0); Rect tmp = *paintRect; tmp.left_ += item->getWidth(); if ( imageRect.right_ > tmp.left_ ) { imageRect.right_ = maxVal<double>( imageRect.left_, tmp.left_ ); } } if ( false == imageRect.isEmpty() ) { imageRect.inflate( -1, -1 ); imageList_->draw( context, index, &imageRect ); }}void TreeListControl::paint( GraphicsContext * context ){ CustomControl::paint( context ); paintChildren( context ); visibleItemsHeight_ = 0; hierarchyHeightMap_.clear(); Rect borderRect = getClientBounds(); Rect itemRect; double prevTop = borderRect.top_ + header_->getHeight(); Rect clipRect = context->getViewableBounds(); context->setClippingRect( &clipRect ); std::vector<TreeItem*> visibleItems; populateVisiblityList( visibleItems ); std::vector<TreeItem*>::iterator it = visibleItems.begin(); itemRect.left_ = borderRect.left_; itemRect.right_ = borderRect.right_; Rect tmp; Rect intersection; while ( it != visibleItems.end() ) { TreeItem* item = *it; itemRect.top_ = prevTop; itemRect.bottom_ = itemRect.top_ + getDefaultItemHeight(); tmp = itemRect; // *MASSIVE* speedup for large trees by only drawing items that are visible on screen!! -aroman intersection = clipRect.makeIntersection(&itemRect); if (intersection.getWidth() > 0 && intersection.getHeight() > 0) { paintItem( item, context, &itemRect ); } prevTop += (itemRect.bottom_ - tmp.top_); it ++; }}void TreeListControl::addItem( TreeItem* item, TreeItem* parent ){ treeModel_->addNodeItem( item, parent ); item->setControl( this ); if ( NULL != parent ) { parent->expand( true ); } repaint();}TreeItem* TreeListControl::addItem( TreeItem* parent, const String& caption, const ulong32 imageIndex ){ DefaultTreeItem* result = new DefaultTreeItem( caption, this, treeModel_ ); result->setImageIndex( imageIndex ); addItem( result, parent ); return result;}TreeItem* TreeListControl::hitTest( Point* pt ){ TreeItem* result = NULL; Enumerator<TreeItem*>* rootChildren = treeModel_->getRootItems(); while ( rootChildren->hasMoreElements() ) { TreeItem* rootItem = rootChildren->nextElement(); result = hitTest( pt, rootItem ); if ( NULL != result ) { break; } } return result;}TreeItem* TreeListControl::hitTest( Point* pt, TreeItem* itemToTest ){ TreeItem* result = NULL; if ( true == itemToTest->containsPoint( pt ) ) { if ( ! (displayOptions_ & TreeListControl::tdoShowFullRowSelection) ) { if ( displayOptions_ & TreeListControl::tdoShowColumnHeader ) { ColumnItem* column = header_->getColumnModel()->getItemFromIndex(0); Rect tmp = *itemToTest->getBounds(); tmp.right_ = tmp.left_ + column->getWidth(); if ( true == tmp.containsPt( pt ) ) { result = itemToTest; } } else { GraphicsContext* ctx = getContext(); double w = ctx->getTextWidth( itemToTest->getCaption() ); Rect tmp = *itemToTest->getBounds(); tmp.right_ = tmp.left_ + w + getCurrentIndent(itemToTest) ; if ( true == tmp.containsPt( pt ) ) { result = itemToTest; } } } else { result = itemToTest; } } else { if ( (false == itemToTest->isLeaf()) && (true == itemToTest->isExpanded()) ) { Enumerator<TreeItem*>* children = itemToTest->getChildren(); while ( true == children->hasMoreElements() ) { TreeItem* item = children->nextElement(); result = hitTest( pt, item ); if ( NULL != result ) { break; } } } } return result;}bool TreeListControl::stateHitTest( Point* pt, TreeItem* itemToTest ){ bool result = false; Rect stateRect = getStateRect( itemToTest, getCurrentIndent( itemToTest ) ); result = stateRect.containsPt( pt ); return result;}void TreeListControl::setItemIndent( const ulong32& itemIndent ){ itemIndent_ = itemIndent; repaint();}bool TreeListControl::multiSelectionChange( MouseEvent* event ){ bool result = false; TreeItem* foundItem = NULL; Enumerator<TreeItem*>* rootChildren = treeModel_->getRootItems(); TreeItem* currentlySelectedItem = getSelectedItem(); while ( rootChildren->hasMoreElements() ) { TreeItem* rootItem = rootChildren->nextElement(); foundItem = hitTest( event->getPoint(), rootItem ); if ( NULL != foundItem ) { Rect expanderRect; ulong32 level = foundItem->getLevel(); expanderRect = *foundItem->getBounds(); expanderRect.left_ += (level * itemIndent_); expanderRect.right_ = expanderRect.left_ + itemIndent_; //currentSelectedItem_ = foundItem; if ( true == expanderRect.containsPt( event->getPoint() ) ) { foundItem->expand( !foundItem->isExpanded() ); ItemEvent event( this, ITEM_EVENT_CHANGED ); ItemExpanded.fireEvent( &event ); } else if ( true == stateHitTest( event->getPoint(), foundItem ) ) { long state = foundItem->getState(); //probably need to come up with better id's //for enum values so that we can mask together //as opposed to doing a direct //assignment if ( Item::idsChecked == state ) { state = Item::idsUnChecked; } else if ( Item::idsUnChecked == state ) { state = Item::idsChecked; } foundItem->setState( state ); ItemEvent event( foundItem, TreeListControl::ITEM_STATECHANGE_REQUESTED ); ItemStateChangeRequested.fireEvent( &event ); } else if ( (true == event->hasLeftButton()) && (true == event->hasShiftKey()) && NULL!=currentlySelectedItem ) { rootChildren->reset(); clearSelectedItems(); std::vector<TreeItem*> selectedItems; bool startFound = false; Rect* bounds1 = currentlySelectedItem->getBounds(); Rect* bounds2 = foundItem->getBounds(); TreeItem* firstItem = currentlySelectedItem; TreeItem* lastItem = foundItem; if ( bounds2->top_ < bounds1->top_ ) { firstItem = foundItem; lastItem = currentlySelectedItem; } selectedItems.push_back( firstItem ); while ( rootChildren->hasMoreElements() ) { TreeItem* rootItem = rootChildren->nextElement(); bool done = listSelectedItems( selectedItems, firstItem, lastItem, rootItem, startFound ); if ( true == done ) { break; } } std::vector<TreeItem*>::iterator it = selectedItems.begin(); while ( it != selectedItems.end() ) { setSelectedItem( *it, true ); it ++; } } else { setSelectedItem( foundItem, !foundItem->isSelected() ); result = true; } repaint(); break; } else if ( (true == event->hasLeftButton()) && (false == draggingSelectionRect_) ){ //null item - start a selection drag draggingSelectionRect_ = true; dragPoint_ = *event->getPoint(); dragSelectionRect_.setRect( dragPoint_.x_, dragPoint_.y_, dragPoint_.x_, dragPoint_.y_ ); } } return result;}void TreeListControl::clearSelectedItems(){ std::vector<TreeItem*>::iterator it = selectedItems_.begin(); while ( it != selectedItems_.end() ) { TreeItem* item = *it; item->setSelected( false ); ItemEvent event( this, ITEM_EVENT_UNSELECTED ); event.setUserData( (void*)item ); ItemSelected.fireEvent( &event ); it ++; } selectedItems_.clear(); repaint();}void TreeListControl::mouseClick( MouseEvent* event ){ CustomControl::mouseClick( event ); }void TreeListControl::mouseDblClick( MouseEvent* event ){ CustomControl::mouseDblClick( event ); TreeItem* item = getSelectedItem(); if ( NULL != item ) { Rect expanderRect; ulong32 level = item->getLevel(); expanderRect = *item->getBounds(); expanderRect.left_ += (level * itemIndent_); expanderRect.right_ = expanderRect.left_ + itemIndent_; if ( !expanderRect.containsPt( event->getPoint() ) && !stateHitTest( event->getPoint(), item ) ) { item->expand( !item->isExpanded() ); ItemEvent event( this, ITEM_EVENT_CHANGED ); ItemExpanded.fireEvent( &event ); recalcScrollable(); } repaint(); }}Rect TreeListControl::getExpanderRect( TreeItem* item ){ Rect result; ulong32 level = item->getLevel(); result = *item->getBounds(); result.left_ += (level * itemIndent_); result.right_ = result.left_ + itemIndent_; return result;}bool TreeListControl::singleSelectionChange( MouseEvent* event )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?