comboboxcontrol.cpp

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

CPP
1,419
字号
//ComboBoxControl.cpp/*Copyright 2000-2004 The VCF Project.Please see License.txt in the top level directorywhere you installed the VCF.*///ComboBoxControl#include "vcf/ApplicationKit/ApplicationKit.h"#include "vcf/ApplicationKit/ComboBoxControl.h"#include "vcf/ApplicationKit/ListBoxControl.h"#include "vcf/ApplicationKit/DefaultListModel.h"#include "vcf/ApplicationKit/TextControl.h"#include "vcf/ApplicationKit/DefaultListItem.h"#include "vcf/ApplicationKit/Containers.h"#include "vcf/GraphicsKit/DrawUIState.h"using namespace VCF;class DropDownListBox : public ListBoxControl {public:	DropDownListBox( ComboBoxControl* comboBoxControl ) :		ListBoxControl( comboBoxControl->getListModel() ){		comboBoxControl_ = comboBoxControl;		// Remark: selectedItem_ differs from comboBoxControl->getListModel()->getSelectedItem() because of the DropDownListBox::mouseMove() action		comboBoxControl->selectItems( false );		ScrollbarManager* scrollBarMgr = new ScrollbarManager();		scrollBarMgr->setTarget( this );		addComponent( scrollBarMgr );		scrollBarMgr->setHasHorizontalScrollbar( false );		scrollBarMgr->setHasVerticalScrollbar( true );		//scrollBarMgr->setVirtualViewVertStep( getDefaultItemHeight() );		scrollBarMgr->setDiscreteScroll( false, comboBoxControl->getDiscreteScroll() );		setUseColorForBackground( true );		setFont( comboBoxControl->getFont() );	}	virtual ~DropDownListBox(){	};	virtual void paint( GraphicsContext* ctx ) {		ListBoxControl::paint( ctx );	}	virtual void mouseDown( MouseEvent* event ) {	}	virtual void mouseMove( MouseEvent* event ) {		CustomControl::mouseMove( event );		if ( (Component::csNormal == getComponentState()) ) {			ListItem* foundItem = findSingleSelectedItem( event->getPoint() );			if ( NULL != foundItem ) {				comboBoxControl_->selectItems( false );				if ( true == allowsMultiSelect_ ) {				}				else {					if ( foundItem != singleSelectedItem_ ) {						setSelectedItem( foundItem );					}				}			}		}	}	virtual void setBounds( Rect* rect, const bool& anchorDeltasNeedUpdating=true ) {		ListBoxControl::setBounds( rect, anchorDeltasNeedUpdating );		getScrollable()->setVirtualViewWidth( rect->getWidth() );		double h = getDefaultItemHeight();		int count = getListModel()->getCount();		h = count * h;		getScrollable()->setVirtualViewHeight( h );	}	virtual void ensureVisible( ListItem* item, const bool& partialOK ) {		// makes sure that item will be visible through scrolling		DefaultListModel* listModel = (DefaultListModel*)comboBoxControl_->getListModel();		ulong32 index = listModel->getItemIndex( item );		double verticalPosition = index * getDefaultItemHeight();		getScrollable()->setVerticalPosition( verticalPosition );		// Note: in the future we should call then		//getScrollable()->getAdjustedPositions();		//       in order to know the Window's adjustments for the scroll quantity	}public:	std::vector<ListItem*> originalSelectedItems_;	ComboBoxControl* comboBoxControl_;};class ComboBoxDropDown : public Window {public:	class Container : public StandardContainer {	public:		Container() {			setBorderWidth( 1 );		}		virtual void resizeChildren(Control* control) {						StandardContainer::resizeChildren( control );		}	};	ComboBoxDropDown( ComboBoxControl* comboBoxControl, EventHandler* closeHandler ) {		setContainer( new ComboBoxDropDown::Container() );		selectedItem_ = NULL;		closeHandler_ = closeHandler;		comboBoxControl_ = comboBoxControl;		listBox_ = new DropDownListBox( comboBoxControl );		add( listBox_, AlignClient );		listBox_->MouseUp.addHandler( new MouseEventHandler<ComboBoxDropDown>( this, &ComboBoxDropDown::onListboxMouseUp, "onListboxMouseUp" ) );		setColor( Color::getColor( "black" ) );		setUseColorForBackground( true );		setFrameStyle( fstNoBorderFixed );		setFrameTopmost( true );		Rect itemRect = comboBoxControl_->getBounds();		comboBoxControl_->getParent()->translateToScreenCoords( &itemRect );		ulong32 desktopH = Desktop::getDesktop()->getHeight();		ulong32 desktopW = Desktop::getDesktop()->getWidth();		int count = minVal<>( listBox_->getListModel()->getCount(), comboBoxControl_->getDropDownCount() );				int winHeight = ( listBox_->getDefaultItemHeight() ) * count;		if ( desktopH < winHeight ) {			winHeight = desktopH;		}		if ( (itemRect.bottom_ + winHeight) > desktopH ) {			if ( winHeight <= itemRect.top_ ) {				itemRect.top_ = itemRect.top_ - winHeight;				itemRect.bottom_ = itemRect.top_ + winHeight;			} else if ( false == comboBoxControl_->getDropDownExtendFullScreen() ) {				if ( desktopH / 2 < itemRect.top_ ) {					itemRect.bottom_ = itemRect.top_;					itemRect.top_ = 0;				} else {					itemRect.top_ += comboBoxControl_->getBounds().getHeight();					itemRect.bottom_ = desktopH;				}			} else {				if ( itemRect.top_ > desktopH - itemRect.bottom_ ) {					itemRect.top_ = 0;					itemRect.bottom_ = winHeight;				} else {					itemRect.top_ = desktopH - winHeight;					itemRect.bottom_ = desktopH;				}			}		}		else {			itemRect.top_ += comboBoxControl_->getBounds().getHeight();			itemRect.bottom_ = itemRect.top_ + winHeight;			// this fixes the bug that scrollbar is always there even when itemsCount < dropDownCount			// +=2 comes from the viewable bounds are one pixel on the top and one pixel on the bottom 			// less than the height of the listbox control itself ( see Control::adjustViewableBoundsAndOriginForScrollable() )			// +=1 comes from rounding reasons.			// Any value less than listBox_->getDefaultItemHeight() would fix the problem.			// See also: DropDownListBox::setBounds()			itemRect.bottom_ += 3;		}		if ( 0 < comboBoxControl_->getDropDownWidth() ) {			itemRect.right_ = itemRect.left_ + comboBoxControl_->getDropDownWidth();		}		setBounds( &itemRect );		selectedItem_ = comboBoxControl_->getSelectedItem();		if ( NULL != selectedItem_ ) {			selectedItem_->setSelected( true );			ensureVisible( selectedItem_, false );		}	}	virtual ~ComboBoxDropDown() {		//StringUtils::trace( Format( "ComboBoxDropDown::~ComboBoxDropDown() @ %p\n" ) % this );	}	virtual void destroy() {		listBox_->setListModel( NULL );		// bugfix [ 1099910 ] commented away. The combobox		// may have been already destroyed by another control		// since the time dropDown_->close() has been called.		//comboBoxControl_->repaint();		Window::destroy();	}	virtual void beforeDestroy( ComponentEvent* e ) {		Window::beforeDestroy( e );	}	void onListboxMouseUp( MouseEvent* e ) {		Rect clientRect = listBox_->getClientBounds();		Scrollable* scrollable = listBox_->getScrollable();		if ( NULL != scrollable ) {			clientRect.offset( 0, scrollable->getVerticalPosition() );		}		if ( clientRect.containsPt( e->getPoint() ) ) {			selectedItem_ = listBox_->getSelectedItem();		}		else {			selectedItem_ = NULL;		}		Event* closeEvent = new Event( this,666777 );		UIToolkit::postEvent( closeHandler_, closeEvent, false );	}	ListItem* getSelectedItem() {		return selectedItem_;	}	ListBoxControl* getListBox() {		return listBox_;	}	void ensureVisible( ListItem* item, const bool& partialOK ) {		DropDownListBox* listBox = (DropDownListBox*)listBox_;		listBox->ensureVisible( item, false );	}protected:	ListItem* selectedItem_;	ComboBoxControl* comboBoxControl_;	ListBoxControl* listBox_;	EventHandler* closeHandler_;};class ComboBoxEdit : public TextControl {public:	ComboBoxEdit() {		setBorder( NULL );	}	virtual bool keepsArrowKeys() {		return true;	}};class ComboBoxContainer : public StandardContainer {public:	virtual void resizeChildren( Control* control ) {		Rect bounds = ((ComboBoxControl*)controlContainer_)->getEditBounds();		std::vector<Control*>::iterator it = controls_.begin();		while ( it != controls_.end() ) {			(*it)->setBounds( &bounds );			it ++;		}	}};ComboBoxControl::ComboBoxControl():	CustomControl( true ),//make this a heavyweight control !	listModel_(NULL){	init();}void ComboBoxControl::init(){	comboBoxStyle_ = cbsDropDown;	selectedItem_ = NULL;	dropDown_ = NULL;	dropDownCount_ = 6;	dropDownWidth_ = 0;	dropDownExtendFullScreen_ = false;	discreteScroll_ = true; // for a combo and any listbox it should be true by default	dropDownSelected_ = false;	autoLookup_ = true;	autoLookupIgnoreCase_ = true;	setListModel( new DefaultListModel() );	addComponent( getViewModel() );	setContainer( new ComboBoxContainer() );	selectedIndex_ = 0;	arrowPressed_ = false;	mouseOver_ = false;	setColor( GraphicsToolkit::getSystemColor( SYSCOLOR_WINDOW ) );	edit_ = new ComboBoxEdit();	edit_->setBounds( &Rect(0,0,0,0) );	getContainer()->add( edit_ );	edit_->setVisible( (comboBoxStyle_ == cbsDropDownWithEdit) );	edit_->setEnabled( (comboBoxStyle_ == cbsDropDownWithEdit) );	edit_->setKeepTabbingCharacters( true );	edit_->KeyPressed.addHandler(		new KeyboardEventHandler<ComboBoxControl>( this, &ComboBoxControl::onEditKeyPressed, "ComboBoxControl::onEditKeyPressed" ) );	updateEditBounds();	FocusGained.addHandler( new FocusEventHandler<ComboBoxControl>( this, &ComboBoxControl::onFocusGained, "ComboBoxControl::onFocusGained" ) );	setUseColorForBackground( true );	Basic3DBorder* border = new Basic3DBorder();	border->setInverted( true );	setBorder( border );}ComboBoxControl::~ComboBoxControl(){}void ComboBoxControl::destroy(){	CustomControl::destroy();	/*	if ( NULL != listModel_ ){		listModel_->release();		listModel_ = NULL;	}	*/	/*	Model* model = this->getViewModel();	if ( NULL != model ) {		model->release();	}	*/	listModel_ = NULL;}ListModel* ComboBoxControl::getListModel(){	return listModel_;}void ComboBoxControl::setListModel(ListModel * model){	EventHandler* changed = getEventHandler( "ComboBox_onListModelContentsChanged" );	if ( NULL == changed ) {		changed =			new ListModelEventHandler<ComboBoxControl>( this,														&ComboBoxControl::onListModelContentsChanged,														"ComboBox_onListModelContentsChanged" );	}	EventHandler* itemAdded = getEventHandler( "ComboBox_onItemAdded" );	if ( NULL == itemAdded ) {		itemAdded =			new ListModelEventHandler<ComboBoxControl>( this,														&ComboBoxControl::onItemAdded,														"ComboBox_onItemAdded" );	}	EventHandler* itemDeleted = getEventHandler( "ComboBox_onItemDeleted" );	if ( NULL == itemDeleted ) {		itemDeleted =			new ListModelEventHandler<ComboBoxControl>( this,														&ComboBoxControl::onItemDeleted,														"ComboBox_onItemDeleted" );	}	if ( NULL != listModel_ ) {		listModel_->removeContentsChangedHandler( changed );		listModel_->removeItemAddedHandler( itemAdded );		listModel_->removeItemDeletedHandler( itemDeleted );	}	listModel_ = model;	if ( NULL != listModel_ ) {				listModel_->addContentsChangedHandler( changed );		listModel_->addItemAddedHandler( itemAdded );		listModel_->addItemDeletedHandler( itemDeleted );	}	setViewModel( dynamic_cast<Model*>(listModel_) );}void ComboBoxControl::mouseEnter( MouseEvent* event ){	mouseOver_ = true;	repaint();}void ComboBoxControl::mouseLeave( MouseEvent* event ){	mouseOver_ = false;	repaint();}void ComboBoxControl::paint( GraphicsContext* context ){	CustomControl::paint( context );/*	Rect clientRect = getClientBounds();	arrowRect_ = clientRect;		arrowRect_.left_ = clientRect.right_ - sz.width_;*/		ButtonState state;	Rect clientRect = getClientBounds();	state.setActive( this->isActive() );	state.setEnabled( this->isEnabled() );	state.setPressed( arrowPressed_ );	state.setFocused( this->isFocused() );	ListItem* selectedItem = getSelectedItem();	if ( NULL != selectedItem ){		state.buttonCaption_ = selectedItem->getCaption();	}		context->drawThemeComboboxRect( &clientRect, state );	if ( NULL != selectedItem ){				if ( selectedItem->canPaint() ) {			Rect r = clientRect;			Size sz = UIToolkit::getUIMetricsManager()->getDefaultVerticalScrollButtonDimensions();			r.right_ -= sz.width_;			selectedItem->paint( context, &r );		}

⌨️ 快捷键说明

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