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 }