Gorgon Game Engine
RadioButtons.h
Go to the documentation of this file.
1 #pragma once
2 
3 #pragma once
4 
5 #include "../UI/ComponentStackWidget.h"
6 #include "../UI/RadioControl.h"
7 #include "../Property.h"
8 #include "Checkbox.h"
9 #include "../UI/WidgetContainer.h"
10 #include "Registry.h"
11 
12 namespace Gorgon { namespace Widgets {
13 
19  template<class T_, class W_ = Checkbox>
20  class RadioButtons : public UI::Widget, protected UI::RadioControl<T_, W_>, protected UI::WidgetContainer {
21  friend class UI::WidgetContainer;
22  public:
23  explicit RadioButtons(const UI::Template &temp) : temp(temp) {
26  this->own = true;
27  }
28 
30  }
31 
33  virtual void Resize(const Geometry::Size &size) override {
34  for(auto p : this->elements) {
35  p.second.SetWidth((GetWidth() - spacing * (GetColumns() - 1)) / GetColumns());
36  }
37 
38  contents.SetWidth(size.Width);
39  }
40 
41  virtual bool Activate() override {
42  return false;
43  }
44 
45  void SetSpacing(int value) {
46  if(spacing == value)
47  return;
48 
49  spacing = value;
50 
51  rearrange();
52  }
53 
54  void Add(const T_ value) {
55  Add(value, String::From(value));
56  }
57 
58  void Add(const T_ value, std::string text) {
59  if(Exists(value)) {
60  this->ForceRemove(this->elements[value]);
61  this->elements.Delete(value);
62  }
63 
64  auto &c = *new W_(temp, text);
66 
67  c.SetWidth((GetWidth() - spacing * (GetColumns() - 1)) / GetColumns());
68 
69  if(value == this->Get())
70  c.Check();
71 
72  if(IsVisible())
73  this->PlaceIn((UI::WidgetContainer&)*this, {0, 0}, spacing);
74 
75  contents.SetHeight(this->widgets.Last()->GetBounds().Bottom);
76 
77  boundschanged();
79  }
80 
82  void ChangeValue(const T_ &before, const T_ &after) {
83  if(before == after)
84  return;
85 
86  if(!Exists(before))
87  throw std::runtime_error("Element does not exist");
88 
89  auto &elm = this->elements[before];
90 
91  if(Exists(after)) {
92  this->ForceRemove(this->elements[after]);
93  this->elements.Delete(after);
94 
95  if(IsVisible())
96  this->PlaceIn((UI::WidgetContainer&)*this, {0, 0}, spacing);
97 
98  contents.SetHeight(this->widgets.Last()->GetBounds().Bottom);
99 
100  boundschanged();
101  childboundschanged(&elm);
102  }
103 
104  if(before == this->Get())
105  elm.Clear();
106 
107  this->elements.Remove(before);
108  this->elements.Add(after, elm);
109  this->reverse.erase(&elm);
110  this->reverse.insert({&elm, after});
111 
112  if(after == this->Get())
113  elm.Check();
114  }
115 
116  using Widget::Enable;
117 
119  void Enable(const T_ &value) {
120  SetEnabled(value, true);
121  }
122 
123  using Widget::Disable;
124 
125 
127  void Disable(const T_ &value) {
128  SetEnabled(value, false);
129  }
130 
131  using Widget::ToggleEnabled;
132 
134  void ToggleEnabled(const T_ &value) {
135  SetEnabled(value, !IsEnabled(value));
136  }
137 
138 
140  void SetEnabled(const T_ &value, bool state) {
141  for(auto p : this->elements) {
142  if(p.first == value)
143  p.second.SetEnabled(state);
144  }
145  }
146 
149  bool IsEnabled(const T_ &value) const {
150  for(auto p : this->elements)
151  if(p.first == value)
152  return p.second.IsEnabled();
153 
154  return false;
155  }
156 
157 
158  Geometry::Size GetInteriorSize() const override {
159  return GetSize();
160  }
161 
162  bool ResizeInterior(Geometry::Size size) override {
163  Resize(size);
164 
165  return size == GetSize();
166  }
167 
168  Geometry::Point GetLocation() const override {
169  return contents.GetLocation();
170  }
171 
172  Geometry::Size GetSize() const override {
173  return contents.GetSize();
174  }
175 
176  bool IsVisible() const override {
177  return contents.IsVisible();
178  }
179 
180  bool EnsureVisible(const UI::Widget &) override {
181  return EnsureVisible();
182  }
183 
184  using Widget::Resize;
185 
186  using Widget::Move;
187 
188  using Widget::EnsureVisible;
189 
190  void Move(const Geometry::Point &location) override {
191  contents.Move(location);
192  }
193 
196  RadioButtons &operator =(const T_ value) {
197  Set(value);
198 
199  return *this;
200  }
201 
203 
205 
207 
209 
210  using Widget::IsVisible;
211 
212  virtual void SetEnabled(bool value) override {
213  if(enabled == value)
214  return;
215 
216  enabled = value;
217 
218  if(!value) {
220 
221  if(HasParent() && IsFocused()) {
222  GetParent().FocusNext();
223  if(IsFocused())
225  }
226  }
227 
229  }
230 
231  virtual bool IsEnabled() const override {
232  return enabled;
233  }
234 
235  bool KeyEvent(Input::Key key, float state) override {
236  return UI::WidgetContainer::KeyEvent(key, state);
237  }
238 
240  void SetColumns(int value) {
242 
243  rearrange();
244  }
245 
247 
248  protected:
249  virtual void addto(Layer &layer) override {
250  layer.Add(contents);
251  }
252 
253 
254  virtual void removefrom(Layer &layer) override {
255  layer.Remove(contents);
256  }
257 
258 
259  virtual void setlayerorder(Layer &, int order) override {
260  contents.PlaceBefore(order);
261  }
262 
263 
264  virtual bool allowfocus() const override {
266  }
267 
268  virtual void focused() override {
269  if(!HasFocusedWidget())
270  FocusFirst();
271 
272  Widget::focused();
273  }
274 
275  Gorgon::Layer &getlayer() override {
276  return contents;
277  }
278 
279  virtual void parentenabledchanged(bool state) override {
280  if(!state && IsEnabled())
282  else if(state && IsEnabled())
284  }
285 
286  virtual bool addingwidget(Widget &widget) override {
287  for(auto p : this->elements) {
288  if(&p.second == &widget)
289  return true;
290  }
291 
292  return false;
293  }
294 
295  virtual bool removingwidget(Widget &) override { return false; }
296 
297  void rearrange() {
298  int total = 0, col = 0;
299  for(auto p : this->elements) {
300  if(col % GetColumns() == 0)
301  total += p.second.GetHeight() + spacing;
302 
303  p.second.SetWidth((GetWidth() - spacing * (GetColumns() - 1)) / GetColumns());
304  col++;
305  }
306 
307  if(total > 0) total -= spacing;
308 
309  contents.SetHeight(total);
310 
311  this->PlaceIn((UI::WidgetContainer&)*this, {0, 0}, spacing);
312  }
313 
315  if(HasParent()) {
316  auto ans = GetParent().RequestExtender(self);
317 
318  if(ans.Extender) {
319  if(!ans.Transformed) {
321  }
322 
323  return ans;
324  }
325  }
326 
327  return {false, this, self.GetLocation()};
328  }
329 
331  int spacing = 4;
333  bool enabled = true;
334 
335  private:
336  virtual void show() override {
337  contents.Show();
338  }
339 
340  virtual void hide() override {
341  contents.Hide();
342  }
343 
344 
345  FocusStrategy getparentfocusstrategy() const override {
346  if(HasParent())
347  return GetParent().CurrentFocusStrategy();
348  else
349  return AllowAll;
350  }
351 
352 
353  virtual void focuschanged() override {
354  if(HasFocusedWidget() && !IsFocused())
355  Focus();
356  else if(!HasFocusedWidget() && IsFocused() && HasParent())
358  }
359 
360  virtual void focuslost() override {
361  Widget::focuslost();
362 
363  if(HasFocusedWidget()) {
365  }
366  }
367 
368  Gorgon::Graphics::Layer contents;
369  };
370 
371 } }
Gorgon::UI::Widget::HasParent
bool HasParent() const
Returns if this widget has a parent.
Definition: Widget.h:140
Gorgon::Widgets::RadioButtons::RadioButtons
RadioButtons(const UI::Template &temp)
Definition: RadioButtons.h:23
Gorgon::Widgets::RadioButtons::Move
void Move(const Geometry::Point &location) override
Moves this widget to the given position.
Definition: RadioButtons.h:190
Gorgon::Widgets::RadioButtons::ResizeInterior
bool ResizeInterior(Geometry::Size size) override
Should resize the interior (usable) size of the container.
Definition: RadioButtons.h:162
Gorgon::Widgets::RadioButtons::GetSize
Geometry::Size GetSize() const override
Returns the size of the widget.
Definition: RadioButtons.h:172
Gorgon::Widgets::RadioButtons::SetEnabled
virtual void SetEnabled(bool value) override
Sets the enabled state of the widget.
Definition: RadioButtons.h:212
Gorgon::String::From
std::enable_if< decltype(gorgon__enum_tr_loc(T_()))::isupgradedenum, std::string >::type From(const T_ &e)
Definition: Enum.h:303
Gorgon::Widgets::RadioButtons::GetInteriorSize
Geometry::Size GetInteriorSize() const override
Should return the interior (usable) size of the container.
Definition: RadioButtons.h:158
Gorgon::UI::RadioControl< T_, Checkbox >::own
bool own
Definition: RadioControl.h:261
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::UI::RadioControl< T_, Checkbox >::elements
Containers::Hashmap< T_, Checkbox > elements
Definition: RadioControl.h:258
Gorgon::Widgets::RadioButtons::setlayerorder
virtual void setlayerorder(Layer &, int order) override
When called, widget should reorder itself in layer hierarchy.
Definition: RadioButtons.h:259
Gorgon::Layer::Add
void Add(Layer &layer)
Adds the given layer as a child.
Definition: Layer.cpp:23
Gorgon::Layer::GetLocation
Geometry::Point GetLocation() const
Returns the current location of the layer.
Definition: Layer.h:403
Gorgon::UI::RadioControl
This class is designed to turn any group of two state widgets to a radio button group,...
Definition: RadioControl.h:33
Gorgon::Widgets::RadioButtons::RadioButtons
RadioButtons(Registry::TemplateType type=Registry::Radio_Regular)
Definition: RadioButtons.h:29
Gorgon::UI::Template
This class stores visual information about a widget template.
Definition: Template.h:392
Gorgon::UI::WidgetContainer::CurrentFocusStrategy
FocusStrategy CurrentFocusStrategy() const
Returns the active focus strategy. This function will not return Inherit.
Definition: WidgetContainer.h:340
Gorgon::UI::RadioControl< T_, Checkbox >::Get
T_ Get() const
Returns the current value.
Definition: RadioControl.h:125
Gorgon::Widgets::RadioButtons::Add
void Add(const T_ value, std::string text)
Definition: RadioButtons.h:58
Gorgon::Widgets::RadioButtons::IsVisible
bool IsVisible() const override
Should return whether the container is visible.
Definition: RadioButtons.h:176
Gorgon::UI::RadioControl< T_, Checkbox >::Exists
bool Exists(const T_ value) const
Returns if the given element exists.
Definition: RadioControl.h:130
Gorgon::Widgets::RadioButtons::KeyEvent
bool KeyEvent(Input::Key key, float state) override
This function should be called whenever a key is pressed or released.
Definition: RadioButtons.h:235
Gorgon::UI::RadioControl< T_, Checkbox >::GetColumns
int GetColumns() const
Returns the number of columns when placing the widgets.
Definition: RadioControl.h:228
Gorgon::Widgets::RadioButtons::getlayer
Gorgon::Layer & getlayer() override
Returns the layer that will be used to place the contained widgets.
Definition: RadioButtons.h:275
Gorgon::UI::WidgetContainer::childboundschanged
virtual void childboundschanged(Widget *source)
The boundary of any of the children is changed. Source could be nullptr.
Definition: WidgetContainer.cpp:431
Gorgon::UI::RadioControl< T_, Checkbox >::reverse
std::map< Checkbox *, T_ > reverse
Definition: RadioControl.h:259
Gorgon::UI::WidgetContainer::FocusFirst
bool FocusFirst()
Focuses the first widget that accepts focus.
Definition: WidgetContainer.cpp:137
Gorgon::UI::WidgetContainer::KeyEvent
virtual bool KeyEvent(Input::Key key, float state)
This function should be called whenever a key is pressed or released.
Definition: WidgetContainer.h:384
Gorgon::Input::Mouse::Move
@ Move
Definition: Mouse.h:17
Gorgon::Containers::Hashmap::Add
void Add(const K_ &key, T_ &obj, bool deleteprev=false)
Adds the given item with the related key.
Definition: Hashmap.h:264
Gorgon::Widgets::RadioButtons::Resize
virtual void Resize(const Geometry::Size &size) override
Radio buttons height is automatically adjusted. Only width will be used.
Definition: RadioButtons.h:33
Gorgon::Widgets::RadioButtons::SetSpacing
void SetSpacing(int value)
Definition: RadioButtons.h:45
Gorgon::Layer::IsVisible
virtual bool IsVisible() const
Returns whether this layer is effectively visible.
Definition: Layer.h:459
Gorgon::Graphics::Layer
This layer allows drawing texture images on.
Definition: Layer.h:169
Gorgon::Containers::Hashmap::Delete
void Delete(const K_ &key)
Removes the item with the given key from the mapping and deletes it.
Definition: Hashmap.h:332
Gorgon::Widgets::RadioButtons::IsEnabled
bool IsEnabled(const T_ &value) const
Returns if given element is enabled.
Definition: RadioButtons.h:149
Gorgon::Widgets::Registry::TemplateType
TemplateType
This enum lists all possible template types.
Definition: Registry.h:18
Gorgon::Widgets::Registry::Radio_Regular
@ Radio_Regular
Definition: Registry.h:28
Gorgon::Input::Key
int Key
A type to represent an input key.
Definition: Input.h:14
Gorgon::Widgets::RadioButtons::parentenabledchanged
virtual void parentenabledchanged(bool state) override
This function is called when the parent's enabled state changes.
Definition: RadioButtons.h:279
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::Geometry::basic_Size
This class represents a 2D geometric size.
Definition: Size.h:23
Gorgon::UI::Template::GetSpacing
int GetSpacing() const
Returns the spacing required for this template.
Definition: Template.h:578
Gorgon::Widgets::RadioButtons::rearrange
void rearrange()
Definition: RadioButtons.h:297
Gorgon::Widgets::RadioButtons::location
Geometry::Point location
Definition: RadioButtons.h:330
Gorgon::UI::WidgetContainer::Widget
friend class Widget
Definition: WidgetContainer.h:38
Gorgon::Layer::PlaceBefore
void PlaceBefore(int before)
Places this layer before the given index.
Definition: Layer.h:290
Gorgon::UI::Template::GetWidth
int GetWidth() const
Returns the size of the template.
Definition: Template.h:525
Gorgon::Widgets::RadioButtons::ChangeValue
void ChangeValue(const T_ &before, const T_ &after)
Changes the value of the given element.
Definition: RadioButtons.h:82
Gorgon::Widgets::RadioButtons::spacing
int spacing
Definition: RadioButtons.h:331
Gorgon::UI::RadioControl::SetColumns
void SetColumns(int value)
Changes the number of columns when placing the widgets.
Definition: RadioControl.h:223
Gorgon::UI::WidgetContainer::ForceRemoveFocus
void ForceRemoveFocus()
Forcefully removes the focus from the focused widget.
Definition: WidgetContainer.cpp:347
Checkbox.h
Gorgon::Widgets::RadioButtons::RequestExtender
UI::ExtenderRequestResponse RequestExtender(const Layer &self) override
This function will return a container that will act as an extender.
Definition: RadioButtons.h:314
Gorgon::Widgets::RadioButtons::allowfocus
virtual bool allowfocus() const override
Should return true if the widget can be focused.
Definition: RadioButtons.h:264
Gorgon::UI::WidgetContainer::RemoveFocus
bool RemoveFocus()
Removes the focus from the focused widget.
Definition: WidgetContainer.cpp:335
Gorgon::Layer::Move
virtual void Move(const Geometry::Point &location)
Moves this layer to the given location.
Definition: Layer.h:327
Gorgon::UI::ExtenderRequestResponse
This structure is used to transfer extender request response.
Definition: WidgetContainer.h:15
Gorgon::Widgets::RadioButtons::Enable
void Enable(const T_ &value)
Enables the given element.
Definition: RadioButtons.h:119
Gorgon::UI::WidgetContainer::widgets
Containers::Collection< Widget > widgets
This container is sorted by the focus order.
Definition: WidgetContainer.h:395
Gorgon::UI::Widget::EnsureVisible
bool EnsureVisible() const
Ensures this widget is visible in its container by scrolling it into view.
Definition: Widget.cpp:55
Gorgon::Widgets::RadioButtons::SetEnabled
void SetEnabled(const T_ &value, bool state)
Sets the enabled state the given element.
Definition: RadioButtons.h:140
Gorgon::Layer::Remove
void Remove(Layer &layer)
Removes the given layer.
Definition: Layer.h:203
Gorgon::Layer
This class is the base class for all layer types.
Definition: Layer.h:79
Gorgon::UI::ExtenderRequestResponse::CoordinatesInExtender
Geometry::Point CoordinatesInExtender
Coordinates of the given point in the extender container.
Definition: WidgetContainer.h:24
Gorgon::Geometry::basic_Point
This class represents a 2D point.
Definition: Point.h:32
Gorgon::Widgets::RadioButtons::EnsureVisible
bool EnsureVisible(const UI::Widget &) override
Ensures the widget is visible.
Definition: RadioButtons.h:180
Gorgon::Widgets::RadioButtons
Allows the use of radio buttons working together.
Definition: RadioButtons.h:20
Gorgon::Widgets::RadioButtons::addto
virtual void addto(Layer &layer) override
When called, widget should locate itself on to this layer.
Definition: RadioButtons.h:249
Gorgon::Layer::SetWidth
void SetWidth(int width)
Resizes the layer to the given size.
Definition: Layer.h:347
Gorgon::UI::WidgetContainer::HasFocusedWidget
bool HasFocusedWidget() const
Returns if this container has a focused widget.
Definition: WidgetContainer.h:171
Gorgon::Widgets::RadioButtons::Disable
void Disable(const T_ &value)
Disables the given element.
Definition: RadioButtons.h:127
Gorgon::Containers::Hashmap::Remove
void Remove(const K_ &key)
Removes the item with the given key from the mapping.
Definition: Hashmap.h:326
Gorgon::Widgets::RadioButtons::Add
void Add(const T_ value)
Definition: RadioButtons.h:54
Gorgon::Widgets::RadioButtons::SetColumns
void SetColumns(int value)
Changes the number of columns.
Definition: RadioButtons.h:240
Registry.h
Gorgon::UI::Active
@ Active
This is for widgets that can be activated, like a count down timer.
Definition: Template.h:245
Gorgon::Widgets::RadioButtons::focused
virtual void focused() override
This is called after the focus is transferred to this widget.
Definition: RadioButtons.h:268
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::RadioButtons::operator=
RadioButtons & operator=(const T_ value)
Assigns a new value to the radio control.
Definition: RadioButtons.h:196
Gorgon::Widgets::RadioButtons::ToggleEnabled
void ToggleEnabled(const T_ &value)
Toggles enabled state of the given element.
Definition: RadioButtons.h:134
Gorgon::Widgets::RadioButtons::addingwidget
virtual bool addingwidget(Widget &widget) override
Definition: RadioButtons.h:286
Gorgon::UI::WidgetContainer::ForceRemove
void ForceRemove(Widget &widget)
Forcefully removes the given widget from this container.
Definition: WidgetContainer.cpp:75
Gorgon::UI::Widget::IsFocused
bool IsFocused() const
Returns if this widget is focused.
Definition: Widget.h:98
Gorgon::Layer::Hide
virtual void Hide()
Hides this layer.
Definition: Layer.h:456
Gorgon::Layer::Show
virtual void Show()
Displays this layer.
Definition: Layer.h:453
Gorgon::Geometry::basic_Size::Width
T_ Width
Width of this size object.
Definition: Size.h:258
Gorgon::UI::WidgetContainer::FocusStrategy
FocusStrategy
Defines focus strategy for the container. Default is Inherit.
Definition: WidgetContainer.h:41
Gorgon::Widgets::RadioButtons::GetLocation
Geometry::Point GetLocation() const override
Returns the location of the widget.
Definition: RadioButtons.h:168
Gorgon::UI::RadioControl< T_, Checkbox >::PlaceIn
void PlaceIn(C_ &container, Geometry::Point start, int spacing)
This function will add all widgets in this controller to the given container.
Definition: RadioControl.h:176
Gorgon::Widgets::RadioButtons::enabled
bool enabled
Definition: RadioButtons.h:333
Gorgon::UI::WidgetContainer::AllowAll
@ AllowAll
All widgets that can be focused are allowed to receive focus, including buttons but not labels.
Definition: WidgetContainer.h:48
Gorgon::UI::WidgetContainer
This class is the base class for all widget containers.
Definition: WidgetContainer.h:37
Gorgon::Widgets::RadioButtons::IsEnabled
virtual bool IsEnabled() const override
Returns whether the widget is enabled.
Definition: RadioButtons.h:231
Gorgon::UI::Widget::boundschanged
virtual void boundschanged()
Call this function when the widget bounds is changed.
Definition: Widget.cpp:62
Gorgon::Widgets::RadioButtons::removefrom
virtual void removefrom(Layer &layer) override
When called, widget should remove itself from the given layer.
Definition: RadioButtons.h:254
Gorgon::UI::WidgetContainer::FocusNext
bool FocusNext()
Focuses the next widget that accepts focus.
Definition: WidgetContainer.cpp:141
Gorgon::GL::Resize
void Resize(const Geometry::Size &size)
Resizes the active context.
Definition: OpenGL.cpp:273
Gorgon::UI::RadioControl< T_, Checkbox >::Set
bool Set(const T_ value)
Assigns a new value to the radio control.
Definition: RadioControl.h:104
Gorgon::UI::Widget::SetWidth
void SetWidth(int width)
Sets the width of the widget.
Definition: Widget.h:72
Gorgon::Layer::SetHeight
void SetHeight(int height)
Resizes the layer to the given size.
Definition: Layer.h:352
Gorgon::UI::WidgetContainer::distributeparentenabled
void distributeparentenabled(bool state)
Distributes a enabled state to children.
Definition: WidgetContainer.cpp:426
Gorgon::Widgets::RadioButtons::temp
const UI::Template & temp
Definition: RadioButtons.h:332
Gorgon::Widgets::Registry
This class stores templates for elements.
Definition: Registry.h:12
Gorgon::Widgets::RadioButtons::removingwidget
virtual bool removingwidget(Widget &) override
Definition: RadioButtons.h:295
Gorgon::Layer::GetSize
Geometry::Size GetSize() const
Returns the size of the layer.
Definition: Layer.h:362
Gorgon::UI::RadioControl::Add
void Add(const T_ value, CT_ &control)
Adds the given element to this controller.
Definition: RadioControl.h:135
Gorgon::UI::Widget
This class is the base for all widgets.
Definition: Widget.h:16
Gorgon::Widgets::RadioButtons::Activate
virtual bool Activate() override
Activates the widget.
Definition: RadioButtons.h:41