/* GWEN Copyright (c) 2010 Facepunch Studios See license in Gwen.h */ #include "Gwen/Controls/ComboBox.h" #include "Gwen/Controls/Menu.h" using namespace Gwen; using namespace Gwen::Controls; using namespace Gwen::ControlsInternal; class GWEN_EXPORT DownArrow : public Controls::Base { public: GWEN_CONTROL_INLINE( DownArrow, Controls::Base ) { SetMouseInputEnabled( true ); SetSize( 15, 15 ); } void Render( Skin::Base* skin ) { skin->DrawArrowDown(this->m_Bounds); } void SetComboBox( ComboBox* p ){ m_ComboBox = p; } protected: ComboBox* m_ComboBox; }; GWEN_CONTROL_CONSTRUCTOR( ComboBox ) { SetSize( 100, 20 ); SetMouseInputEnabled( true ); m_Menu = new Menu( this ); m_Menu->SetHidden( true ); m_Menu->SetDisableIconMargin( true ); m_Menu->SetTabable( false ); ComboBoxButton* m_OpenButton = new ComboBoxButton( this ); m_OpenButton->onDown.Add( this, &ComboBox::OpenButtonPressed ); m_OpenButton->Dock( Pos::Right ); m_OpenButton->SetMargin( Margin( 2, 2, 2, 2 ) ); m_OpenButton->SetWidth( 16 ); m_OpenButton->SetTabable( false ); m_SelectedItem = NULL; SetAlignment( Gwen::Pos::Left | Gwen::Pos::CenterV ); SetText( L"" ); SetMargin( Margin( 3, 0, 0, 0 ) ); SetTabable( true ); } MenuItem* ComboBox::AddItem( const UnicodeString& strLabel, const String& strName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn ) { MenuItem* pItem = m_Menu->AddItem( strLabel, L"", pHandler, fn ); pItem->SetName( strName ); pItem->onMenuItemSelected.Add( this, &ComboBox::OnItemSelected ); //Default if ( m_SelectedItem == NULL ) OnItemSelected( pItem ); return pItem; } void ComboBox::Render( Skin::Base* skin ) { skin->DrawComboBox( this ); } void ComboBox::OpenButtonPressed( Controls::Base* /*pControl*/ ) { OnPress(); } void ComboBox::OnPress() { bool bWasMenuHidden = m_Menu->Hidden(); GetCanvas()->CloseMenus(); if ( bWasMenuHidden ) { OpenList(); } else { m_Menu->SetHidden( true ); } } void ComboBox::ClearItems() { if ( m_Menu ) { m_Menu->ClearItems(); } } void ComboBox::OnItemSelected( Controls::Base* pControl ) { //Convert selected to a menu item MenuItem* pItem = pControl->DynamicCastMenuItem(); if ( !pItem ) return; m_SelectedItem = pItem; SetText( m_SelectedItem->GetText() ); m_Menu->SetHidden( true ); onSelection.Call( this ); Focus(); Invalidate(); } void ComboBox::OnLostKeyboardFocus() { SetTextColor( Color( 0, 0, 0, 255 ) ); } void ComboBox::OnKeyboardFocus() { //Until we add the blue highlighting again SetTextColor( Color( 0, 0, 0, 255 ) ); //m_SelectedText->SetTextColor( Color( 255, 255, 255, 255 ) ); } Gwen::Controls::Label* ComboBox::GetSelectedItem() { return m_SelectedItem; } bool ComboBox::IsMenuOpen() { return m_Menu && !m_Menu->Hidden(); } void ComboBox::OpenList() { if ( !m_Menu ) return; m_Menu->SetParent( GetCanvas() ); m_Menu->SetHidden( false ); m_Menu->BringToFront(); Gwen::Point p = LocalPosToCanvas( Gwen::Point( 0, 0 ) ); m_Menu->SetBounds( Gwen::Rect ( p.x, p.y + Height(), Width(), m_Menu->Height()) ); } void ComboBox::CloseList() { } bool ComboBox::OnKeyUp( bool bDown ) { if ( bDown ) { Base::List & children = m_Menu->GetChildren(); Base::List::reverse_iterator it = std::find( children.rbegin(), children.rend(), m_SelectedItem ); if ( it != children.rend() && ( ++it != children.rend() ) ) { Base* pUpElement = *it; OnItemSelected( pUpElement ); } } return true; } bool ComboBox::OnKeyDown( bool bDown ) { if ( bDown ) { Base::List & children = m_Menu->GetChildren(); Base::List::iterator it = std::find( children.begin(), children.end(), m_SelectedItem ); if ( it != children.end() && ( ++it != children.end() ) ) { Base* pDownElement = *it; OnItemSelected( pDownElement ); } } return true; } void ComboBox::RenderFocus( Gwen::Skin::Base* /*skin*/ ) { }