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