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 }