treelistcontrol.cpp
来自「这是VCF框架的代码」· C++ 代码 · 共 2,390 行 · 第 1/5 页
CPP
2,390 行
//TreeListControl.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*/#include "vcf/ApplicationKit/ApplicationKit.h"#include "vcf/ApplicationKit/TreeListControl.h"#include "vcf/ApplicationKit/HeaderControl.h"#include "vcf/ApplicationKit/DefaultTreeModel.h"#include "vcf/ApplicationKit/DefaultTreeItem.h"#include "vcf/ApplicationKit/Containers.h"#include "vcf/GraphicsKit/DrawUIState.h"using namespace VCF;#define EXPANDER_SPACER 5.0TreeListControl::TreeListControl(): CustomControl(), header_(NULL), imageList_(NULL), stateImageList_(NULL), treeModel_(NULL), itemHeight_(25.0), columnHeight_(0.0), itemIndent_(19.0), displayOptions_(TreeListControl::tdoNone), allowLabelEditing_(false), allowMultipleSelection_(false), stateItemIndent_(19.0), draggingSelectionRect_(false), currentEditColumn_(-1), currentEditingControl_(NULL){ setContainerDelegate( this ); setContainer( new StandardContainer() ); init();}TreeListControl::~TreeListControl(){ if ( NULL != treeModel_ ) {// treeModel_->release(); }}void TreeListControl::init(){ draggingSelectionRect_ = false; treeModel_ = NULL; header_ = NULL; imageList_ = NULL; stateImageList_ = NULL; selectedItemContainer_.initContainer( selectedItems_ ); allowMultipleSelection_ = false; allowLabelEditing_ = false; setTreeModel( new DefaultTreeModel() ); addComponent( getViewModel() ); itemHeight_ = getContext()->getTextHeight("EM") + 2.0; itemIndent_ = 19; stateItemIndent_ = 19; visibleItemsHeight_ = 0.0; setColor( GraphicsToolkit::getSystemColor( SYSCOLOR_WINDOW ) ); rowLineColor_ = *GraphicsToolkit::getSystemColor( SYSCOLOR_SHADOW ); columnLineColor_ = *GraphicsToolkit::getSystemColor( SYSCOLOR_SHADOW ); header_ = new HeaderControl(); columnHeight_ = header_->getHeight(); add( header_, AlignTop ); header_->setIgnoreForParentScrolling( true ); header_->ColumnWidthChanged.addHandler( new ItemEventHandler<TreeListControl>( this, &TreeListControl::onColumnWidthChanged, "TreeListControl::onColumnWidthChanged" ) ); setDisplayOptions( TreeListControl::tdoNone ); setUseColorForBackground( true ); EventHandler* ev = new GenericEventHandler<TreeListControl>( this, &TreeListControl::onEditorFocusLost, "TreeListControl::onEditorFocusLost" ); ev = new KeyboardEventHandler<TreeListControl>( this, &TreeListControl::onEditingControlKeyPressed, "TreeListControl::onEditingControlKeyPressed" );}void TreeListControl::setTreeModel(TreeModel * model){ if ( NULL != treeModel_ ) { EventHandler* handler = getEventHandler( "TreeListControl::onModelChanged" ); if ( NULL != handler ) { treeModel_->removeTreeNodeAddedHandler( handler ); treeModel_->removeTreeNodeDeletedHandler( handler ); } getViewModel()->removeView( this ); } treeModel_ = model; if ( NULL != treeModel_ ) { Model* tm = dynamic_cast<Model*>(treeModel_); tm->addView( this ); EventHandler* handler = getEventHandler( "TreeListControl::onModelChanged" ); if ( NULL == handler ) { handler = new TreeModelEventHandler<TreeListControl>( this, &TreeListControl::onModelChanged, "TreeListControl::onModelChanged" ); //JC - commented this out - this is unneccesary //addEventHandler( "TreeListControl::onModelChanged", handler ); } treeModel_->addTreeNodeAddedHandler( handler ); treeModel_->addTreeNodeDeletedHandler( handler ); handler = getEventHandler( "TreeListControl::onModelEmptied" ); if ( NULL == handler ) { handler = new GenericEventHandler<TreeListControl>( this, &TreeListControl::onModelEmptied, "TreeListControl::onModelEmptied" ); } tm->addModelHandler( handler ); } else { setViewModel( NULL ); }}TreeModel* TreeListControl::getTreeModel(){ return treeModel_;}void TreeListControl::onModelEmptied( Event* event ){ if ( Model::MODEL_EMPTIED == event->getType() ) { selectedItems_.clear(); cancelEditing(); recalcScrollable(); }}void TreeListControl::onModelChanged( TreeModelEvent* event ){ switch ( event->getType() ) { case TreeModel::TREEITEM_DELETED : { std::vector<TreeItem*>::iterator found = std::find( selectedItems_.begin(), selectedItems_.end(), event->getTreeItem() ); if ( found != selectedItems_.end() ) { selectedItems_.erase( found ); repaint(); } } break; case TreeModel::TREEITEM_ADDED : { event->getTreeItem()->setControl( this ); } break; } recalcScrollable(); }void TreeListControl::recalcScrollable(){ Scrollable* scrollable = getScrollable(); if ( NULL != scrollable ) { double oldVisibleHeight = visibleItemsHeight_; visibleItemsHeight_ = 0; if ( header_->getVisible() ) { visibleItemsHeight_ += header_->getHeight(); } std::vector<TreeItem*> visibleItems; populateVisiblityList( visibleItems ); std::vector<TreeItem*>::iterator it = visibleItems.begin(); while ( it != visibleItems.end() ) { TreeItem* item = *it; visibleItemsHeight_ += item->getBounds()->getHeight(); it ++; } scrollable->setVirtualViewHeight( visibleItemsHeight_ ); if ( (getHeight() > visibleItemsHeight_) && (scrollable->getVerticalPosition() > 0.0) ) { scrollable->setVerticalPosition( 0.0 ); } else if ( oldVisibleHeight > visibleItemsHeight_ ) { double newPos = minVal<double>( abs((long)(visibleItemsHeight_ - getHeight()))+1.0, scrollable->getVerticalPosition() ); scrollable->setVerticalPosition( newPos ); } }}void TreeListControl::paintItem( TreeItem* item, GraphicsContext* context, Rect* paintRect ){ bool isALeaf = item->isLeaf(); visibleItemsHeight_ += paintRect->getHeight(); if ( displayOptions_ & TreeListControl::tdoShowRowLines ) { context->setColor( &rowLineColor_ ); context->moveTo( paintRect->left_, paintRect->bottom_ ); context->lineTo( paintRect->right_, paintRect->bottom_ ); context->strokePath(); } item->setBounds( paintRect ); TreeModel* treeModel = getTreeModel(); ColumnModel* columnModel = header_->getColumnModel(); double indent = getCurrentIndent( item ); Rect captionRect = *paintRect; captionRect.left_ = paintRect->left_ + indent + itemHeight_; if ( columnModel->getCount() > 0 ) { ColumnItem* col = columnModel->getItemFromIndex( 0 ); if ( displayOptions_ & TreeListControl::tdoShowColumnHeader ) { captionRect.right_ = maxVal<double>( captionRect.left_ + 1.0, paintRect->left_ + col->getWidth() ); } else { captionRect.right_ = captionRect.left_ + context->getTextWidth( item->getCaption() ) + 5; } } else { captionRect.right_ = captionRect.left_ + context->getTextWidth( item->getCaption() ) + 5; } captionRect.right_ -= 3; double textH = context->getTextHeight( item->getCaption() ); captionRect.top_ = captionRect.top_ + ((captionRect.getHeight() / 2.0) - textH/2.0); captionRect.bottom_ = captionRect.top_ + textH; if ( TreeListControl::tdoShowHierarchyLines & displayOptions_ ) { hierarchyHeightMap_[item] = paintRect->top_ + itemHeight_/2.0; if ( false == item->isRoot() ) { TreeItem* parent = item->getParent(); std::map<TreeItem*,double>::iterator found = hierarchyHeightMap_.find( parent ); if ( found != hierarchyHeightMap_.end() ) { double baseIndent = getItemIndent() * item->getLevel() - 1; double parentIndent = getItemIndent() * parent->getLevel() - 1; Color oldColor = *(context->getColor()); Color* selectedColor = GraphicsToolkit::getSystemColor( SYSCOLOR_SHADOW ); context->setColor( selectedColor ); context->moveTo( paintRect->left_ + baseIndent + itemHeight_/2.0, paintRect->top_ + itemHeight_/2.0 ); context->lineTo( paintRect->left_ + parentIndent + itemHeight_/2.0, paintRect->top_ + itemHeight_/2.0 ); context->lineTo( paintRect->left_ + parentIndent + itemHeight_/2.0, found->second ); context->strokePath(); context->setColor( &oldColor ); } } } if ( true == item->isSelected() ) { Color oldColor = *(context->getColor()); Color* selectedColor = GraphicsToolkit::getSystemColor( SYSCOLOR_SELECTION ); context->setColor( selectedColor ); Rect tmp = *paintRect; if ( displayOptions_ & TreeListControl::tdoShowFullRowSelection ) { //tmp.inflate( -2, -2 ); } else { tmp.left_ = paintRect->left_ + indent + itemHeight_ - 1; tmp.right_ = captionRect.right_; //tmp.inflate( 0, -2 ); } tmp.right_ = maxVal<double>( tmp.left_, tmp.right_ ); context->rectangle( &tmp ); if ( true == isFocused() ) { context->fillPath(); DrawUIState state; state.setFocused( true ); state.setActive( true ); context->drawThemeSelectionRect( &tmp, state ); } else { context->strokePath(); } context->setColor( &oldColor ); } bool stateNeedsDrawing = false; bool imageNeedsDrawing = false; //determine if we have an image list present if ( NULL != imageList_ ) { imageNeedsDrawing = true; } if ( Item::idsNone != item->getState() ) { stateNeedsDrawing = true; } if ( true == stateNeedsDrawing ) { paintItemState( item, context, paintRect, (long)indent ); } if ( true == imageNeedsDrawing ) { paintItemImage( item, context, paintRect, (long)indent ); } if ( false == isALeaf ) { paintExpander( item, context, paintRect ); } long drawOptions = GraphicsContext::tdoNone; drawOptions |= GraphicsContext::tdoLeftAlign; Color oldColor = *(context->getCurrentFont()->getColor()); if ( (true == item->isSelected()) && (true == isFocused()) ) { Color* selectedColor = GraphicsToolkit::getSystemColor( SYSCOLOR_SELECTION_TEXT ); context->getCurrentFont()->setColor( selectedColor ); } else { context->getCurrentFont()->setColor( item->getTextColor() ); } context->getCurrentFont()->setBold( item->getTextBold() ); captionRect.right_ -= 5; context->textBoundedBy( &captionRect, item->getCaption(), drawOptions ); context->getCurrentFont()->setColor( &oldColor ); if ( item->canPaint() ) { item->paint( context, paintRect ); } if ( displayOptions_ & TreeListControl::tdoShowColumnHeader ) { Enumerator<ColumnItem*>* columns = columnModel->getItems(); int columnIndex = 0; if ( NULL != columns ) { Rect subItemRect = *paintRect; subItemRect.left_ -= 2; while ( true == columns->hasMoreElements() ) { ColumnItem* col = columns->nextElement(); if ( columnIndex > 0 ) { subItemRect.right_ = subItemRect.left_ + col->getWidth(); paintSubItem( item, context, columnIndex, &subItemRect ); } subItemRect.left_ += col->getWidth(); columnIndex++; } } }}void TreeListControl::paintSubItem( TreeItem* item, GraphicsContext* context, const ulong32& subItemIndex, Rect* paintRect ){ if ( displayOptions_ & TreeListControl::tdoShowColumnLines ) { context->setColor( &columnLineColor_ ); ColumnModel* columnModel = header_->getColumnModel(); context->moveTo( paintRect->left_, paintRect->top_ ); context->lineTo( paintRect->left_, paintRect->bottom_ ); context->strokePath(); if ( (columnModel->getCount()-1) == subItemIndex ) { context->moveTo( paintRect->right_, paintRect->top_ ); context->lineTo( paintRect->right_, paintRect->bottom_ ); context->strokePath(); } } if ( subItemIndex > 0 ) { if ( (true == item->isSelected()) && (true == isFocused()) ) { Color* selectedColor = GraphicsToolkit::getSystemColor( SYSCOLOR_SELECTION_TEXT ); context->getCurrentFont()->setColor( selectedColor ); } else { context->getCurrentFont()->setColor( item->getTextColor() ); } TreeItem::SubItem* subItem = item->getSubItem( subItemIndex-1 ); if ( NULL != subItem ) { long drawOptions = GraphicsContext::tdoNone; drawOptions |= GraphicsContext::tdoLeftAlign; Rect captionRect = *paintRect; captionRect.left_ += 5; captionRect.right_ -= 5; double textH = context->getTextHeight( "EM" ); captionRect.top_ = captionRect.top_ + ((captionRect.getHeight() / 2.0) - textH/2.0); captionRect.bottom_ = captionRect.top_ + textH; context->textBoundedBy( &captionRect, subItem->getCaption(), drawOptions ); if ( subItem->canPaint() ) { subItem->paint( context, paintRect ); } } }}void TreeListControl::paintExpander( TreeItem* item, GraphicsContext* context, Rect* paintRect ){ double spacer = EXPANDER_SPACER; Rect expanderRect = *paintRect; double dy = expanderRect.getHeight() - getFont()->getHeight(); expanderRect.left_ = getItemIndent() * item->getLevel() + 1; expanderRect.inflate( 0.0, -(dy/2.0) ); expanderRect.right_ = expanderRect.left_ + expanderRect.getHeight();#define TRIANGLE_BTN#ifndef TRIANGLE_BTN //expanderRect.inflate( -expanderRect.getWidth()/4.0, -expanderRect.getHeight()/4.0 ); context->setColor( Color::getColor("white") ); context->rectangle( &expanderRect ); context->fillPath(); context->setColor( Color::getColor("black") );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?