1 /*
2 GWEN
3 Copyright (c) 2010 Facepunch Studios
4 See license in Gwen.h
5 */
6
7 #include "Gwen/Controls/ListBox.h"
8 #include "Gwen/Controls/ScrollControl.h"
9 #include "Gwen/InputHandler.h"
10
11 using namespace Gwen;
12 using namespace Gwen::Controls;
13
14 class ListBoxRow : public Layout::TableRow
15 {
GWEN_CONTROL_INLINE(ListBoxRow,Layout::TableRow)16 GWEN_CONTROL_INLINE(ListBoxRow, Layout::TableRow)
17 {
18 SetMouseInputEnabled(true);
19 SetSelected(false);
20 }
21
Render(Skin::Base * skin)22 void Render(Skin::Base* skin)
23 {
24 skin->DrawListBoxLine(this, IsSelected());
25 }
26
IsSelected() const27 bool IsSelected() const
28 {
29 return m_bSelected;
30 }
31
OnMouseClickLeft(int,int,bool bDown)32 void OnMouseClickLeft(int /*x*/, int /*y*/, bool bDown)
33 {
34 if (bDown && !m_bSelected)
35 {
36 SetSelected(true);
37 onRowSelected.Call(this);
38 }
39 }
40
SetSelected(bool b)41 void SetSelected(bool b)
42 {
43 m_bSelected = b;
44
45 // TODO: Get these values from the skin.
46 if (b)
47 SetTextColor(Gwen::Colors::White);
48 else
49 SetTextColor(Gwen::Colors::Black);
50 }
51
52 private:
53 bool m_bSelected;
54 };
55
GWEN_CONTROL_CONSTRUCTOR(ListBox)56 GWEN_CONTROL_CONSTRUCTOR(ListBox)
57 {
58 m_ScrollControl = new ScrollControl(this);
59 m_ScrollControl->Dock(Pos::Fill);
60 m_ScrollControl->SetScroll(false, true);
61 m_ScrollControl->SetAutoHideBars(true);
62 m_ScrollControl->SetMargin(Margin(1, 1, 1, 1));
63
64 m_InnerPanel = m_ScrollControl;
65
66 m_Table = new Controls::Layout::Table(this);
67 m_Table->Dock(Pos::Top);
68 m_Table->SetColumnCount(1);
69
70 m_bMultiSelect = false;
71 }
72
OnChildBoundsChanged(Gwen::Rect,Base *)73 void ListBox::OnChildBoundsChanged(Gwen::Rect /*oldChildBounds*/, Base* /*pChild*/)
74 {
75 m_ScrollControl->UpdateScrollBars();
76 }
77
AddItem(const String & strLabel,const String & strName)78 Layout::TableRow* ListBox::AddItem(const String& strLabel, const String& strName)
79 {
80 return AddItem(Utility::StringToUnicode(strLabel), strName);
81 }
82
AddItem(const UnicodeString & strLabel,const String & strName)83 Layout::TableRow* ListBox::AddItem(const UnicodeString& strLabel, const String& strName)
84 {
85 ListBoxRow* pRow = new ListBoxRow(this);
86 m_Table->AddRow(pRow);
87
88 pRow->SetCellText(0, strLabel);
89 pRow->SetName(strName);
90
91 pRow->onRowSelected.Add(this, &ListBox::OnRowSelected);
92
93 m_Table->SizeToContents();
94
95 return pRow;
96 }
97
Render(Skin::Base * skin)98 void ListBox::Render(Skin::Base* skin)
99 {
100 skin->DrawListBox(this);
101 }
102
UnselectAll()103 void ListBox::UnselectAll()
104 {
105 std::list<Layout::TableRow*>::iterator it = m_SelectedRows.begin();
106 while (it != m_SelectedRows.end())
107 {
108 ListBoxRow* pRow = static_cast<ListBoxRow*>(*it);
109 it = m_SelectedRows.erase(it);
110
111 pRow->SetSelected(false);
112 }
113 }
114
OnRowSelected(Base * pControl)115 void ListBox::OnRowSelected(Base* pControl)
116 {
117 ListBoxRow* pRow = static_cast<ListBoxRow*>(pControl);
118
119 if (!AllowMultiSelect() || !Gwen::Input::IsShiftDown())
120 {
121 UnselectAll();
122 }
123
124 m_SelectedRows.push_back(pRow);
125
126 onRowSelected.Call(this);
127 }
128
GetSelectedRow()129 Layout::TableRow* ListBox::GetSelectedRow()
130 {
131 if (m_SelectedRows.empty()) return NULL;
132
133 return *m_SelectedRows.begin();
134 }
135
Clear()136 void ListBox::Clear()
137 {
138 UnselectAll();
139 m_Table->Clear();
140 }