Gorgon Game Engine
Dropdown.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Common.h"
4 #include "../UI/ComponentStackWidget.h"
5 #include "../Property.h"
6 #include "Registry.h"
7 #include "Listbox.h"
8 
9 namespace Gorgon { namespace Widgets {
10 
15  template <class T_, void (*TW_)(const T_ &, ListItem &), class L_>
16  class DropdownBase : public virtual UI::ComponentStackWidget, protected ListItem
17  {
18  public:
19  using ListType = L_;
20 
21  template <class ...A_>
23  DropdownBase(Registry::Active()[type])
24  {
25  List.Add(std::forward<A_>(elms)...);
26  }
27 
29  DropdownBase(Registry::Active()[type])
30  { }
31 
32  explicit DropdownBase(const UI::Template &temp) :
33  ComponentStackWidget(temp, {
35  }),
36  ListItem(temp),
38  *this->stack.GetTemplate(UI::ComponentTemplate::ListTag) :
40  ),
41  List(list)
42  {
43  stack.SetClickEvent([this](auto, auto, auto) {
44  Focus();
45  Toggle();
46  });
47  list.SetOverscroll(0.5);
48  }
49 
50  template <class ...A_>
51  explicit DropdownBase(const UI::Template &temp, A_&& ... elms) : DropdownBase(temp)
52  {
53  List.Add(std::forward<A_>(elms)...);
54  }
55 
56  protected:
58  bool opened = false;
59  bool refresh = false;
60 
61  public:
62  typename ListType::ListBase &List;
63 
68  virtual void Refresh() {
69  if(opened)
70  list.Refresh();
71  else
72  refresh = true;
73  }
74 
76  void Open() {
77  if(!HasParent())
78  return;
79  if(opened)
80  return;
81 
82  auto res = GetParent().RequestExtender(stack);
83 
84  if(!res.Extender)
85  return;
86 
87  opened = true;
88 
89  list.Move(res.CoordinatesInExtender.X, res.CoordinatesInExtender.Y + GetHeight());
90  list.SetWidth(GetWidth());
91  list.FitHeight(res.TotalSize.Height-list.GetLocation().Y);
92  res.Extender->Add(list);
93 
95  stack.SetFrameEvent(std::bind(&DropdownBase::checkfocus, this));
96 
97  if(refresh) {
98  refresh = false;
99  list.Refresh();
100  }
101  }
102 
104  void Close() {
105  if(!opened)
106  return;
107 
108  opened = false;
111  list.Remove();
112  }
113 
115  void Toggle() {
116  if(opened)
117  Close();
118  else
119  Open();
120  }
121 
123  bool IsOpened() const {
124  return opened;
125  }
126 
129  bool IsReversed() const {
131  }
132 
133  protected:
134  virtual void boundschanged() override {
135  Close();
136  }
137 
138  virtual void displaced() override {
139  Close();
140  }
141 
142  void checkfocus() {
143  if(!this->IsFocused())
144  Close();
145  }
146  };
147 
151  template <class T_, void (*TW_)(const T_ &, ListItem &), class L_>
153  public virtual UI::ComponentStackWidget,
154  public DropdownBase<T_, TW_, L_>
155  {
157  public:
158 
159  template <class ...A_>
162  {
163  this->list.Add(std::forward<A_>(elms)...);
164  }
165 
168  { }
169 
170  explicit SingleSelectionDropdown(const UI::Template &temp) :
171  ComponentStackWidget(temp, {
173  }),
174  Base(temp)
175  {
176  this->list.ChangedEvent.Register([this]() {
177  if(this->list.HasSelectedItem()) {
178  TW_(this->list.GetSelectedItem(), *this);
179  this->Close();
180  SelectionChanged(this->list.GetSelectedIndex());
181  }
182  else {
183  this->SetText("");
184  this->RemoveIcon();
185  SelectionChanged(-1);
186  }
187  });
188  }
189 
190  template <class ...A_>
191  explicit SingleSelectionDropdown(const UI::Template &temp, A_&& ... elms) : SingleSelectionDropdown(temp)
192  {
193  this->list.Add(std::forward<A_>(elms)...);
194  }
195 
196  virtual void Refresh() override {
197  Base::Refresh();
198 
199  if(this->list.HasSelectedItem()) {
200  TW_(this->list.GetSelectedItem(), *this);
201  }
202  else {
203  this->SetText("");
204  this->RemoveIcon();
205  }
206  }
207 
211  this->list.SetSelectedItem(value);
212 
213  return *this;
214  }
215 
217  void SetSelectedIndex(long index) {
218  this->list.SetSelectedIndex(index);
219  }
220 
222  operator const T_ &() const {
223  return this->list.GetSelectedItem();
224  }
225 
228  operator T_ &() {
229  return this->list.GetSelectedItem();
230  }
231 
233  };
234 
235 
236  template <class T_, void (*TW_)(const T_ &, ListItem &) = internal::SetTextUsingFrom<T_, ListItem>>
238 
239  template <class T_, void (*TW_)(const T_ &, ListItem &) = internal::SetTextUsingFrom<T_, ListItem>>
241 
242 } }
Gorgon::UI::Widget::HasParent
bool HasParent() const
Returns if this widget has a parent.
Definition: Widget.h:140
Listbox.h
Gorgon::UI::ComponentStackWidget::stack
ComponentStack & stack
Definition: ComponentStackWidget.h:76
Gorgon::Widgets::DropdownBase::List
ListType::ListBase & List
Definition: Dropdown.h:62
Gorgon::UI::Widget::GetWidth
int GetWidth() const
Returns the width of the widget.
Definition: Widget.h:66
Gorgon::UI::Widget::Focus
bool Focus()
Transfers the focus to this widget.
Definition: Widget.cpp:13
Gorgon::Event
This class provides event mechanism.
Definition: Event.h:134
Gorgon::Widgets::Registry::Listbox_Regular
@ Listbox_Regular
Definition: Registry.h:47
Gorgon::Widgets::ListItem
This widget is designed to be used by Listbox, Table, Grid and Treeview.
Definition: ListItem.h:33
Gorgon::UI::Template
This class stores visual information about a widget template.
Definition: Template.h:392
Common.h
Gorgon::Widgets::DropdownBase::Refresh
virtual void Refresh()
Refreshes the dropdown.
Definition: Dropdown.h:68
Gorgon::Widgets::SingleSelectionDropdown::SelectionChanged
Event< SingleSelectionDropdown, long > SelectionChanged
Definition: Dropdown.h:232
Gorgon::Widgets::DropdownBase::Open
void Open()
Opens the list.
Definition: Dropdown.h:76
Gorgon::Widgets::DropdownBase::Toggle
void Toggle()
Toggles open/close state of the dropdown.
Definition: Dropdown.h:115
Gorgon::Widgets::Registry::Dropdown_Regular
@ Dropdown_Regular
Definition: Registry.h:49
Gorgon::UI::Opened
@ Opened
This condition is triggered when the widget is opened like a combobox showing its list part.
Definition: Template.h:213
Gorgon::Widgets::Registry::Active
static Registry & Active()
Definition: Registry.h:73
Gorgon::UI::ComponentStack::RemoveCondition
void RemoveCondition(ComponentCondition condition, bool transition=true)
Removes a condition and its associated components.
Definition: ComponentStack.h:54
Gorgon::Widgets::Registry::TemplateType
TemplateType
This enum lists all possible template types.
Definition: Registry.h:18
Gorgon::UI::Widget::GetParent
WidgetContainer & GetParent() const
Returns the parent of this widget, throws if it does not have a parent.
Definition: Widget.cpp:30
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::UI::ComponentStack::SetFrameEvent
void SetFrameEvent(std::function< void()> handler)
Sets a function to be called before update check.
Definition: ComponentStack.h:413
Gorgon::Widgets::DropdownBase::DropdownBase
DropdownBase(A_ &&... elms, Registry::TemplateType type=Registry::Dropdown_Regular)
Definition: Dropdown.h:22
Gorgon::UI::ComponentTemplate::ListTag
@ ListTag
Definition: Template.h:879
Gorgon::Widgets::SingleSelectionDropdown::SingleSelectionDropdown
SingleSelectionDropdown(A_ &&... elms, Registry::TemplateType type=Registry::Dropdown_Regular)
Definition: Dropdown.h:160
Gorgon::Widgets::SingleSelectionDropdown
This is the dropdown base for single item selection dropdown lists.
Definition: Dropdown.h:155
Gorgon::UI::Widget::GetHeight
int GetHeight() const
Returns the height of the widget.
Definition: Widget.h:69
Gorgon::Widgets::DropdownBase::displaced
virtual void displaced() override
Call this function when the widget container causes it to be displaced.
Definition: Dropdown.h:138
Gorgon::Widgets::ListItem::RemoveIcon
void RemoveIcon()
Removes the icon on the label.
Definition: ListItem.cpp:67
Gorgon::Widgets::ListItem::ListItem
ListItem(const UI::Template &temp)
Constructor requires template. ListItem.
Definition: ListItem.cpp:6
Gorgon::UI::ComponentStack::RemoveFrameEvent
void RemoveFrameEvent()
Removes the function that will be called before update check.
Definition: ComponentStack.h:433
Gorgon::UI::ComponentStack::AddCondition
void AddCondition(ComponentCondition condition, bool transition=true)
Adds a condition and its associated components to the stack.
Definition: ComponentStack.h:48
Gorgon::Widgets::DropdownBase::refresh
bool refresh
Definition: Dropdown.h:59
Registry.h
Gorgon::UI::ComponentStack::SetClickEvent
void SetClickEvent(std::function< void(ComponentTemplate::Tag, Geometry::Point, Input::Mouse::Button)> handler)
Sets the mouse down event.
Definition: ComponentStack.h:490
Gorgon::Widgets::DropdownBase::Close
void Close()
Closes the list.
Definition: Dropdown.h:104
Gorgon::UI::Active
@ Active
This is for widgets that can be activated, like a count down timer.
Definition: Template.h:245
Gorgon::Widgets::DropdownBase::boundschanged
virtual void boundschanged() override
Call this function when the widget bounds is changed.
Definition: Dropdown.h:134
Gorgon::Widgets::SingleSelectionDropdown::Refresh
virtual void Refresh() override
Refreshes the dropdown.
Definition: Dropdown.h:196
Gorgon::Widgets::ListItem::SetText
void SetText(const std::string &value)
Changes the text displayed.
Definition: ListItem.cpp:24
Gorgon::Widgets::DropdownBase::list
ListType list
Definition: Dropdown.h:57
Gorgon::UI::WidgetContainer::RequestExtender
virtual ExtenderRequestResponse RequestExtender(const Gorgon::Layer &self)=0
This function will return a container that will act as an extender.
Gorgon::Widgets::DropdownBase
This is the dropdown base for all dropdown lists, including ones that are not for item selection (e....
Definition: Dropdown.h:17
Gorgon::UI::Widget::IsFocused
bool IsFocused() const
Returns if this widget is focused.
Definition: Widget.h:98
Gorgon::Widgets::SingleSelectionDropdown::SingleSelectionDropdown
SingleSelectionDropdown(const UI::Template &temp)
Definition: Dropdown.h:170
Gorgon::Widgets::DropdownBase::IsOpened
bool IsOpened() const
Returns whether the dropdown is opened.
Definition: Dropdown.h:123
Gorgon::Widgets::DropdownBase::ListType
L_ ListType
Definition: Dropdown.h:19
Gorgon::UI::ComponentStackWidget::ComponentStackWidget
ComponentStackWidget(const Template &temp, std::map< ComponentTemplate::Tag, std::function< Widget *(const Template &)>> generators={})
Definition: ComponentStackWidget.h:16
Gorgon::UI::ComponentStack::GetTemplate
const Template & GetTemplate() const
Returns the template used by this stack.
Definition: ComponentStack.h:256
Gorgon::Widgets::SingleSelectionDropdown::operator=
SingleSelectionDropdown & operator=(const T_ &value)
Changes selection to the given item.
Definition: Dropdown.h:210
Gorgon::Widgets::DropdownBase::opened
bool opened
Definition: Dropdown.h:58
Gorgon::UI::ComponentStackWidget
This class acts as a widget base that uses component stack to handle rendering, resizing and other op...
Definition: ComponentStackWidget.h:14
Gorgon::Widgets::SingleSelectionDropdown::SetSelectedIndex
void SetSelectedIndex(long index)
Changes the selection to the given index.
Definition: Dropdown.h:217
Gorgon::Widgets::DropdownBase::checkfocus
void checkfocus()
Definition: Dropdown.h:142
Gorgon::Widgets::SingleSelectionDropdown::SingleSelectionDropdown
SingleSelectionDropdown(Registry::TemplateType type=Registry::Dropdown_Regular)
Definition: Dropdown.h:166
Gorgon::Widgets::DropdownBase::DropdownBase
DropdownBase(const UI::Template &temp, A_ &&... elms)
Definition: Dropdown.h:51
Gorgon::Utils::NotImplemented
void NotImplemented(const std::string &what="This feature")
Definition: Assert.h:187
Gorgon::Widgets::Registry
This class stores templates for elements.
Definition: Registry.h:12
Gorgon::Widgets::DropdownBase::DropdownBase
DropdownBase(Registry::TemplateType type=Registry::Dropdown_Regular)
Definition: Dropdown.h:28
Gorgon::Widgets::SingleSelectionDropdown::SingleSelectionDropdown
SingleSelectionDropdown(const UI::Template &temp, A_ &&... elms)
Definition: Dropdown.h:191
Gorgon::Widgets::DropdownBase::DropdownBase
DropdownBase(const UI::Template &temp)
Definition: Dropdown.h:32
Gorgon::Widgets::DropdownBase::IsReversed
bool IsReversed() const
Retuns if the list will be opened above the dropdown instead of below.
Definition: Dropdown.h:129