/* GWEN Copyright (c) 2010 Facepunch Studios See license in Gwen.h */ #include "gwen_listbox.h" #include "gwen_scrollcontrol.h" #include "../gwen_inputhandler.h" using namespace Gwen; using namespace Gwen::Controls; class ListBoxRow : public Layout::TableRow { GWEN_CONTROL_INLINE( ListBoxRow, Layout::TableRow ) { SetMouseInputEnabled( true ); SetSelected( false ); } void Render( Skin::Base* skin ) { skin->DrawListBoxLine( this, IsSelected(), GetEven() ); } bool IsSelected() const { return m_bSelected; } void OnMouseClickLeft( int /*x*/, int /*y*/, bool bDown ) { if ( bDown ) { SetSelected( true ); onRowSelected.Call( this ); Redraw(); } } void SetSelected( bool b ) { m_bSelected = b; // TODO: Get these values from the skin. if ( b ) SetTextColor( Gwen::Colors::White ); else SetTextColor( Gwen::Colors::Black ); } private: bool m_bSelected; }; GWEN_CONTROL_CONSTRUCTOR( ListBox ) { SetScroll( false, true ); SetAutoHideBars( true ); SetMargin( Margin( 1, 1, 1, 1 ) ); m_InnerPanel->SetPadding( Padding( 2, 2, 2, 2 ) ); m_Table = new Controls::Layout::Table( this ); m_Table->SetColumnCount( 1 ); m_bMultiSelect = false; } Layout::TableRow* ListBox::AddItem( const TextObject& strLabel, const String& strName ) { ListBoxRow* pRow = new ListBoxRow( this ); m_Table->AddRow( pRow ); pRow->SetCellText( 0, strLabel ); pRow->SetName( strName ); pRow->onRowSelected.Add( this, &ListBox::OnRowSelected ); return pRow; } void ListBox::RemoveItem( Layout::TableRow * row ) { m_SelectedRows.erase( stl::find( m_SelectedRows.begin(), m_SelectedRows.end(), row ) ); m_Table->Remove( row ); } void ListBox::Render( Skin::Base* skin ) { skin->DrawListBox( this ); } void ListBox::Layout( Skin::Base* skin ) { BaseClass::Layout( skin ); const Gwen::Rect& inner = m_InnerPanel->GetInnerBounds(); m_Table->SetPos( inner.x, inner.y ); m_Table->SetWidth( inner.w ); m_Table->SizeToChildren( false, true ); BaseClass::Layout( skin ); } void ListBox::UnselectAll() { stl::list::iterator it = m_SelectedRows.begin(); while ( it != m_SelectedRows.end() ) { ListBoxRow* pRow = static_cast(*it); it = m_SelectedRows.erase( it ); pRow->SetSelected( false ); } } void ListBox::OnRowSelected( Base* pControl ) { bool bClear = !Gwen::Input::IsShiftDown(); if ( !AllowMultiSelect() ) bClear = true; SetSelectedRow( pControl, bClear ); } Layout::TableRow* ListBox::GetSelectedRow() { if ( m_SelectedRows.empty() ) return NULL; return *m_SelectedRows.begin(); } Gwen::String ListBox::GetSelectedRowName() { Layout::TableRow* row = GetSelectedRow(); if ( !row ) return ""; return row->GetName(); } void ListBox::Clear() { UnselectAll(); m_Table->Clear(); } void ListBox::SetSelectedRow( Gwen::Controls::Base* pControl, bool bClearOthers ) { if ( bClearOthers ) UnselectAll(); ListBoxRow* pRow = gwen_cast( pControl ); if ( !pRow ) return; // TODO: make sure this is one of our rows! pRow->SetSelected( true ); m_SelectedRows.push_back( pRow ); onRowSelected.Call( this ); } void ListBox::SelectByString( const TextObject& strName, bool bClearOthers ) { if ( bClearOthers ) UnselectAll(); Base::List& children = m_Table->GetChildren(); for ( Base::List::iterator iter = children.begin(); iter != children.end(); ++iter ) { ListBoxRow* pChild = gwen_cast(*iter); if ( !pChild ) continue; if ( Utility::Strings::Wildcard( strName, pChild->GetText( 0 ) ) ) SetSelectedRow( pChild, false ); } }