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