1 /*
2 	GWEN
3 	Copyright (c) 2010 Facepunch Studios
4 	See license in Gwen.h
5 */
6 
7 #include "Gwen/Controls/ComboBox.h"
8 #include "Gwen/Controls/Menu.h"
9 
10 using namespace Gwen;
11 using namespace Gwen::Controls;
12 using namespace Gwen::ControlsInternal;
13 
14 class GWEN_EXPORT DownArrow : public Controls::Base
15 {
16 public:
GWEN_CONTROL_INLINE(DownArrow,Controls::Base)17 	GWEN_CONTROL_INLINE(DownArrow, Controls::Base)
18 	{
19 		SetMouseInputEnabled(true);
20 		SetSize(15, 15);
21 	}
22 
Render(Skin::Base * skin)23 	void Render(Skin::Base* skin)
24 	{
25 		skin->DrawArrowDown(this->m_Bounds);
26 	}
27 
SetComboBox(ComboBox * p)28 	void SetComboBox(ComboBox* p) { m_ComboBox = p; }
29 
30 protected:
31 	ComboBox* m_ComboBox;
32 };
33 
GWEN_CONTROL_CONSTRUCTOR(ComboBox)34 GWEN_CONTROL_CONSTRUCTOR(ComboBox)
35 {
36 	SetSize(100, 20);
37 	SetMouseInputEnabled(true);
38 
39 	m_Menu = new Menu(this);
40 	m_Menu->SetHidden(true);
41 	m_Menu->SetDisableIconMargin(true);
42 	m_Menu->SetTabable(false);
43 
44 	ComboBoxButton* m_OpenButton = new ComboBoxButton(this);
45 
46 	m_OpenButton->onDown.Add(this, &ComboBox::OpenButtonPressed);
47 
48 	m_OpenButton->Dock(Pos::Right);
49 	m_OpenButton->SetMargin(Margin(2, 2, 2, 2));
50 	m_OpenButton->SetWidth(16);
51 	m_OpenButton->SetTabable(false);
52 
53 	m_SelectedItem = NULL;
54 
55 	SetAlignment(Gwen::Pos::Left | Gwen::Pos::CenterV);
56 	SetText(L"");
57 	SetMargin(Margin(3, 0, 0, 0));
58 
59 	SetTabable(true);
60 }
61 
AddItem(const UnicodeString & strLabel,const String & strName,Gwen::Event::Handler * pHandler,Gwen::Event::Handler::Function fn)62 MenuItem* ComboBox::AddItem(const UnicodeString& strLabel, const String& strName, Gwen::Event::Handler* pHandler, Gwen::Event::Handler::Function fn)
63 {
64 	MenuItem* pItem = m_Menu->AddItem(strLabel, L"", pHandler, fn);
65 	pItem->SetName(strName);
66 
67 	pItem->onMenuItemSelected.Add(this, &ComboBox::OnItemSelected);
68 
69 	//Default
70 	if (m_SelectedItem == NULL)
71 		OnItemSelected(pItem);
72 
73 	return pItem;
74 }
75 
Render(Skin::Base * skin)76 void ComboBox::Render(Skin::Base* skin)
77 {
78 	skin->DrawComboBox(this);
79 }
80 
OpenButtonPressed(Controls::Base *)81 void ComboBox::OpenButtonPressed(Controls::Base* /*pControl*/)
82 {
83 	OnPress();
84 }
85 
OnPress()86 void ComboBox::OnPress()
87 {
88 	bool bWasMenuHidden = m_Menu->Hidden();
89 
90 	GetCanvas()->CloseMenus();
91 
92 	if (bWasMenuHidden)
93 	{
94 		OpenList();
95 	}
96 	else
97 	{
98 		m_Menu->SetHidden(true);
99 	}
100 }
101 
ClearItems()102 void ComboBox::ClearItems()
103 {
104 	if (m_Menu)
105 	{
106 		m_Menu->ClearItems();
107 	}
108 }
OnItemSelected(Controls::Base * pControl)109 void ComboBox::OnItemSelected(Controls::Base* pControl)
110 {
111 	//Convert selected to a menu item
112 	MenuItem* pItem = pControl->DynamicCastMenuItem();
113 	if (!pItem) return;
114 
115 	m_SelectedItem = pItem;
116 	SetText(m_SelectedItem->GetText());
117 	m_Menu->SetHidden(true);
118 
119 	onSelection.Call(this);
120 
121 	Focus();
122 	Invalidate();
123 }
124 
OnLostKeyboardFocus()125 void ComboBox::OnLostKeyboardFocus()
126 {
127 	SetTextColor(Color(0, 0, 0, 255));
128 }
129 
OnKeyboardFocus()130 void ComboBox::OnKeyboardFocus()
131 {
132 	//Until we add the blue highlighting again
133 	SetTextColor(Color(0, 0, 0, 255));
134 	//m_SelectedText->SetTextColor( Color( 255, 255, 255, 255 ) );
135 }
136 
GetSelectedItem()137 Gwen::Controls::Label* ComboBox::GetSelectedItem()
138 {
139 	return m_SelectedItem;
140 }
141 
IsMenuOpen()142 bool ComboBox::IsMenuOpen()
143 {
144 	return m_Menu && !m_Menu->Hidden();
145 }
146 
OpenList()147 void ComboBox::OpenList()
148 {
149 	if (!m_Menu) return;
150 
151 	m_Menu->SetParent(GetCanvas());
152 	m_Menu->SetHidden(false);
153 	m_Menu->BringToFront();
154 
155 	Gwen::Point p = LocalPosToCanvas(Gwen::Point(0, 0));
156 
157 	m_Menu->SetBounds(Gwen::Rect(p.x, p.y + Height(), Width(), m_Menu->Height()));
158 }
159 
CloseList()160 void ComboBox::CloseList()
161 {
162 }
163 
OnKeyUp(bool bDown)164 bool ComboBox::OnKeyUp(bool bDown)
165 {
166 	if (bDown)
167 	{
168 		Base::List& children = m_Menu->GetChildren();
169 		Base::List::reverse_iterator it = std::find(children.rbegin(), children.rend(), m_SelectedItem);
170 
171 		if (it != children.rend() && (++it != children.rend()))
172 		{
173 			Base* pUpElement = *it;
174 			OnItemSelected(pUpElement);
175 		}
176 	}
177 	return true;
178 }
OnKeyDown(bool bDown)179 bool ComboBox::OnKeyDown(bool bDown)
180 {
181 	if (bDown)
182 	{
183 		Base::List& children = m_Menu->GetChildren();
184 		Base::List::iterator it = std::find(children.begin(), children.end(), m_SelectedItem);
185 
186 		if (it != children.end() && (++it != children.end()))
187 		{
188 			Base* pDownElement = *it;
189 			OnItemSelected(pDownElement);
190 		}
191 	}
192 	return true;
193 }
194 
RenderFocus(Gwen::Skin::Base *)195 void ComboBox::RenderFocus(Gwen::Skin::Base* /*skin*/)
196 {
197 }