abstractcontainer.cpp

来自「这是VCF框架的代码」· C++ 代码 · 共 857 行 · 第 1/2 页

CPP
857
字号
//AbstractContainer.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/AbstractContainer.h"#include <algorithm>using namespace VCF;AbstractContainer::AbstractContainer():	controlContainer_(NULL),	currentTabControlIndex_(0),	controlHandler_(NULL),	mouseHandler_(NULL){	init();}AbstractContainer::AbstractContainer( Component* owner ):	Container(owner),	controlContainer_(NULL),	currentTabControlIndex_(0),	controlHandler_(NULL),	mouseHandler_(NULL){	init();}AbstractContainer::~AbstractContainer(){	if ( NULL != controlContainer_ ){		controlContainer_->ControlSized -= controlHandler_;		controlContainer_->MouseDoubleClicked -= mouseHandler_;		controlContainer_->MouseClicked -= mouseHandler_;		controlContainer_->MouseMove -= mouseHandler_;		controlContainer_->MouseUp -= mouseHandler_;		controlContainer_->MouseDown -= mouseHandler_;		controlContainer_->MouseLeave -= mouseHandler_;		controlContainer_->MouseEnter -= mouseHandler_;	}	controls_.clear();}void AbstractContainer::containerResized( ControlEvent* event ){	resizeChildren( NULL );}/***Translate points to screen coords*Translate points back to client coords*for each child, pass the event to it's process mouse event*/void AbstractContainer::onMouseEvent( MouseEvent* event ){	Control* previousMouseEnteredChild = Control::getPreviousMouseOverControl();	Point tmp(0.0,0.0);	tmp = *event->getPoint();	//check for scollable to get rid of it's offsets	Scrollable* scrollable = getContainerControl()->getScrollable();	if ( NULL != scrollable ) {		tmp.x_ -= scrollable->getHorizontalPosition();		tmp.y_ -= scrollable->getVerticalPosition();	}	Rect childBounds;	Control* capturedControl = Control::getCapturedMouseControl();	if ( NULL != capturedControl ){		Control* container = getContainerControl();		Control* parent = capturedControl->getParent();		if ( parent == container ){ //then the captured control is a child of this container so keep sedning it the messages			childBounds = capturedControl->getBounds();			//if ( true == childBounds->containsPt( &tmp ) ){				capturedControl->translateToLocal( &tmp );				MouseEvent localEvent( capturedControl, event->getType(), event->getButtonMask(), event->getKeyMask(), &tmp );				capturedControl->handleEvent( &localEvent );				event->setConsumed(true);//localEvent.isConsumed());			//}		}	}	else {		std::vector<Control*>::reverse_iterator it = controls_.rbegin();		while ( it != controls_.rend() ){			Control* child = *it;			if ( NULL == child ) {				throw RuntimeException (MAKE_ERROR_MSG_2(INVALID_POINTER_ERROR)) ;			}			childBounds = child->getBounds();			if ( Control::MOUSE_LEAVE == event->getType() ) {				if ( (false == childBounds.containsPt( &tmp )) && (child->isLightWeight() && child->getVisible()) ){					if ( (NULL != previousMouseEnteredChild) && (previousMouseEnteredChild == child) ) {						//if ( child->isLightWeight() ){						child->translateToLocal( &tmp );						MouseEvent localEvent( child, event->getType(), event->getButtonMask(), event->getKeyMask(), &tmp );						child->handleEvent( &localEvent );						event->setConsumed(true);//localEvent.isConsumed());						break;					}				}			}			else if ( Control::MOUSE_ENTERED == event->getType() ) {				Rect tmpRect = child->getBounds();				tmpRect.inflate( 2, 2 );				if ( (tmpRect.containsPt( &tmp )) && (child->isLightWeight() && child->getVisible()) ){					Control::setPreviousMouseOverControl( child );					child->translateToLocal( &tmp );					MouseEvent localEvent( child, event->getType(), event->getButtonMask(), event->getKeyMask(), &tmp );					child->handleEvent( &localEvent );					event->setConsumed(true);//localEvent.isConsumed());					break;				}			}			else {				if ( (true == childBounds.containsPt( &tmp )) && (child->isLightWeight() && child->getVisible()) ){					child->translateToLocal( &tmp );					if ( Control::MOUSE_MOVE == event->getType() ) {						if ( child != previousMouseEnteredChild ) {							if ( NULL != previousMouseEnteredChild ) {								Point tmp2 = *event->getPoint();								previousMouseEnteredChild->translateToLocal( &tmp2 );								MouseEvent localEvent( previousMouseEnteredChild, Control::MOUSE_LEAVE, event->getButtonMask(), event->getKeyMask(), &tmp2 );								previousMouseEnteredChild->handleEvent( &localEvent );							}							Control::setPreviousMouseOverControl( child );							previousMouseEnteredChild = Control::getPreviousMouseOverControl();							if ( NULL != previousMouseEnteredChild ) {								Point tmp2 = *event->getPoint();								child->translateToLocal( &tmp2 );								MouseEvent localEvent( child, Control::MOUSE_ENTERED, event->getButtonMask(), event->getKeyMask(), &tmp2 );								child->handleEvent( &localEvent );							}						}					}					if ( event->getType() != Control::MOUSE_CLICK ) {						MouseEvent localEvent( child, event->getType(), event->getButtonMask(), event->getKeyMask(), &tmp );						child->handleEvent( &localEvent );						event->setConsumed(true);//localEvent.isConsumed());					}					break;				}				else if ( (Control::MOUSE_MOVE == event->getType()) && (child == previousMouseEnteredChild) ) {					Point tmp2 = *event->getPoint();					previousMouseEnteredChild->translateToLocal( &tmp2 );					MouseEvent localEvent( previousMouseEnteredChild, Control::MOUSE_LEAVE, event->getButtonMask(), event->getKeyMask(), &tmp2 );					previousMouseEnteredChild->handleEvent( &localEvent );					Control::setPreviousMouseOverControl( NULL );				}			}			it ++;		}	}}void AbstractContainer::init(){	currentTabControlIndex_ = 0;	controlHandler_ =		new ControlEventHandler<AbstractContainer>( this, &AbstractContainer::containerResized,													"AbstractContainer::containerResized");	mouseHandler_ =		new MouseEventHandler<AbstractContainer>( this,&AbstractContainer::onMouseEvent,													"AbstractContainer::onMouseEvent");	controlContainer_ = NULL;	controlsContainer_.initContainer( controls_ );}void AbstractContainer::add( Control * child ){	if ( NULL == controlContainer_ ){		throw InvalidPointerException(MAKE_ERROR_MSG(INVALID_POINTER_ERROR), __LINE__);	};	//verify we don't already have this control	std::vector<Control*>::iterator found = std::find( controls_.begin(), controls_.end(), child );	if ( found == controls_.end() ) {		//check for a previous parent, if found then remove it from the parent !		Control* parent = child->getParent();		if ( NULL != parent ) {			Container* parentContainer = parent->getContainer();			if ( NULL != parentContainer ) {				parentContainer->remove( child );			}		}		child->setParent( controlContainer_ );				child->setTabOrder( controls_.size() );		resizeChildren( child );		controls_.push_back( child );	}}void AbstractContainer::add( Control * child, const AlignmentType& alignment ){	if ( NULL == controlContainer_ ){		throw InvalidPointerException(MAKE_ERROR_MSG(INVALID_POINTER_ERROR), __LINE__);	};	std::vector<Control*>::iterator found = std::find( controls_.begin(), controls_.end(), child );	if ( found == controls_.end() ) {		//check for a previous parent, if found then remove it from the parent !		Control* parent = child->getParent();		if ( NULL != parent ) {			Container* parentContainer = parent->getContainer();			if ( NULL != parentContainer ) {				parentContainer->remove( child );			}		}		child->setParent( controlContainer_ );		child->setAlignment( alignment );		child->setTabOrder( controls_.size() );		resizeChildren( child );		controls_.push_back( child );	}}void AbstractContainer::remove( Control* child ){	std::vector<Control*>::iterator found = std::find( controls_.begin(), controls_.end(), child );	if ( found != controls_.end() ){		controls_.erase( found );		child->setParent( NULL );		resizeChildren(NULL);		std::map<long,Control*>::iterator it = tabOrderMap_.begin();		while ( it != tabOrderMap_.end() ) {			if ( child == it->second ) {				tabOrderMap_.erase( it );				break;			}			it ++;		}	}}void AbstractContainer::clear(){	controls_.clear();	tabOrderMap_.clear();	resizeChildren(NULL);}void AbstractContainer::paintChildren( GraphicsContext* context ){	Enumerator<Control*>* children = controlsContainer_.getEnumerator();	if ( NULL == controlContainer_ ){		throw InvalidPointerException(MAKE_ERROR_MSG(INVALID_POINTER_ERROR), __LINE__);	};	double originX = 0.0;	double originY = 0.0;	Scrollable* scrollable = controlContainer_->getScrollable();	Rect oldClipRect = context->getClippingRect();	Rect mainBounds;	if ( controlContainer_->getParent() ) {		mainBounds = controlContainer_->getBounds();		mainBounds.offset( -controlContainer_->getLeft(), -controlContainer_->getTop() );	}	else {		mainBounds = controlContainer_->getClientBounds();	}	Rect childClipRect;	Rect bounds;	Control* heavyWeightParent  = controlContainer_;	if ( NULL != heavyWeightParent ) {			}		while ( true == children->hasMoreElements() ){		Control* child = children->nextElement();		VCF_ASSERT( NULL != child );		if ( child->isLightWeight() && child->getVisible() ){						bounds = child->getBounds();						childClipRect.left_ = maxVal<>(bounds.left_,mainBounds.left_);			childClipRect.top_ = maxVal<>(bounds.top_,mainBounds.top_);			childClipRect.right_ = minVal<>(bounds.right_,mainBounds.right_);			childClipRect.bottom_ = minVal<>(bounds.bottom_,mainBounds.bottom_);											childClipRect.offset( -bounds.left_, -bounds.top_ );			Point oldOrigin = context->getOrigin();			originX = bounds.left_ + oldOrigin.x_;			originY = bounds.top_ + oldOrigin.y_;			if ( NULL != scrollable ) {				originX += 	scrollable->getHorizontalPosition();				originY += 	scrollable->getVerticalPosition();			}			context->setOrigin( originX, originY );						//do this to prevent matrix changes from			//screwing up the state for the child control			Matrix2D xfrm;			int gcs = context->saveState();			context->setCurrentTransform( xfrm );												context->setClippingRect( &childClipRect );			child->paintBorder( context );			child->paint( context );			context->restoreState( gcs );			context->setOrigin( oldOrigin.x_, oldOrigin.y_ );						context->setClippingRect( &oldClipRect );		}	}}Enumerator<Control*>* AbstractContainer::getChildren(){	return controlsContainer_.getEnumerator();}unsigned long AbstractContainer::getChildCount(){	return controls_.size();}Control* AbstractContainer::findControl( const String& controlName ){	Control* result = NULL;	//this is very slow !! for the moment !	std::vector<Control*>::iterator it = controls_.begin();	bool notFound = true;	while ( it != controls_.end() ){		Control* child = *it;		if ( controlName == child->getName() ){			result = child;			break;		}		it ++;	}	return result;}void AbstractContainer::updateTabOrder( Control* child, ulong32& newTabOrder ){	long currentTabOrder = child->getTabOrder();	if ( newTabOrder >= 0 ) {		if ( newTabOrder > tabOrderMap_.size() ) {			newTabOrder = tabOrderMap_.size() - 1;		}		else if ( newTabOrder < 0 ) {			newTabOrder = 0;		}		std::map<long,Control*>::iterator found = tabOrderMap_.find( currentTabOrder );		if ( found != tabOrderMap_.end() ) {			tabOrderMap_.erase( found );		}		tabOrderMap_[newTabOrder] = child;	}}void AbstractContainer::getTabList( std::vector<Control*>& tabList ){	std::map<long,Control*>::iterator it = tabOrderMap_.begin();	while ( it != tabOrderMap_.end() ) {		Control::buildTabList( it->second, tabList );		it ++;	}}Control* AbstractContainer::getControlAtIndex( const ulong32& index ){	Control* result = NULL;	if ( index < controls_.size() ) {		std::vector<Control*>::iterator found = controls_.begin() + index;		if ( found != controls_.end() ) {			result = *found;		}	}	return result;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?