Gorgon Game Engine
RadioControl.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "TwoStateControl.h"
4 #include "../Containers/Hashmap.h"
5 
6 namespace Gorgon { namespace UI {
7 
32  template<class T_ = int, class CT_ = TwoStateControl>
33  class RadioControl {
34  public:
36  RadioControl() : ChangedEvent(this) { }
37 
39  RadioControl(const RadioControl &) = delete;
40 
43  explicit RadioControl(std::initializer_list<std::pair<const T_, CT_&>> elm, T_ current = T_()) :
44  ChangedEvent(this),
45  elements(elm),
47  {
48  for(auto p : elements) {
49  p.second.SetState(false, true);
50  reverse.insert({&p.second, p.first});
51  }
52 
53  if(elements.Exists(current)) {
54  elements[current].SetState(true, true);
55  }
56 
57  for(auto p : elements) {
58  p.second.StateChangingEvent.Register(*this, &RadioControl::changing);
59  }
60  }
61 
64  explicit RadioControl(std::initializer_list<std::pair<const T_, CT_*>> elm, T_ current = T_()) :
65  ChangedEvent(this),
66  elements(elm),
68  {
69  for(auto p : elements) {
70  p.second.SetState(false, true);
71  reverse.insert({&p.second, p.first});
72  }
73 
74  if(elements.Exists(current)) {
75  elements[current].SetState(true, true);
76  }
77 
78  for(auto p : elements) {
79  p.second.StateChangingEvent.Register(*this, &RadioControl::changing);
80  }
81 
82  own = true;
83  }
84 
85  virtual ~RadioControl() {
86  if(own)
87  elements.DeleteAll();
88  }
89 
92  RadioControl &operator =(const T_ value) {
93  Set(value);
94  }
95 
97  operator T_() const {
98  return current;
99  }
100 
104  bool Set(const T_ value) {
105  if(value == current)
106  return true;
107 
108  clearall();
109 
110  current = value;
111 
112  if(elements.Exists(current)) {
113  bool state = elements[current].SetState(true, true);
114 
115  if(state)
117 
118  return state;
119  }
120 
121  return false;
122  }
123 
125  T_ Get() const {
126  return current;
127  }
128 
130  bool Exists(const T_ value) const {
131  return elements.Exists(value);
132  }
133 
135  void Add(const T_ value, CT_ &control) {
136  if(Exists(value) && own) {
137  elements.Delete(value);
138  }
139 
140  elements.Add(value, control);
141  reverse.insert({&control, value});
142  control.StateChangingEvent.Register(*this, &RadioControl::changing);
143  }
144 
146  void ChangeValue(const T_ &before, const T_ &after) {
147  if(before == after)
148  return;
149 
150  if(!Exists(before))
151  throw std::runtime_error("Element does not exist");
152 
153  if(Exists(after) && own) {
154  elements.Delete(after);
155  }
156 
157  auto &elm = this->elements[before];
158 
159  if(before == this->Get())
160  elm.Clear();
161 
162  this->elements.Remove(before);
163  this->elements.Add(after, elm);
164  this->reverse.erase(&elm);
165  this->reverse.insert({&elm, after});
166 
167  if(after == this->Get())
168  elm.Check();
169  }
170 
171 
175  template<class C_>
176  void PlaceIn(C_ &container, Geometry::Point start, int spacing) {
177  auto loc = start;
178 
179  int col = 0;
180  for(auto p : elements) {
181  auto w = dynamic_cast<Widget*>(&p.second);
182 
183  if(!w)
184  continue;
185 
186  container.Add(*w);
187 
188  w->Move(loc);
189 
190  col++;
191  if(col%columns == 0) {
192  loc.X = start.X;
193  loc.Y += w->GetSize().Height + spacing;
194  col = 0;
195  }
196  else {
197  loc.X += w->GetSize().Width + spacing;
198  }
199  }
200  }
201 
203  auto begin() {
204  return elements.begin();
205  }
206 
208  auto end() {
209  return elements.begin();
210  }
211 
213  auto begin() const {
214  return elements.begin();
215  }
216 
218  auto end() const {
219  return elements.begin();
220  }
221 
223  void SetColumns(int value) {
224  columns = value;
225  }
226 
228  int GetColumns() const {
229  return columns;
230  }
231 
233 
234  protected:
235  void changing(TwoStateControl &control, bool state, bool &allow) {
236  if(!state) {
237  allow = false;
238  }
239  else {
240  if(reverse[dynamic_cast<CT_*>(&control)] == current)
241  return;
242 
243  clearall();
244  current = reverse[dynamic_cast<CT_*>(&control)];
245 
247  }
248  }
249 
250  void clearall() {
251  for(auto p : elements) {
252  p.second.SetState(false, true);
253  }
254  }
255 
256  virtual void elementadded(const T_ &index) { }
257 
259  std::map<CT_ *, T_> reverse;
260 
261  bool own = false;
262 
263  T_ current = T_{};
264 
265  int columns = 1;
266  };
267 
268 } }
Gorgon::UI::RadioControl::own
bool own
Definition: RadioControl.h:261
Gorgon::UI::RadioControl::elements
Containers::Hashmap< T_, CT_ > elements
Definition: RadioControl.h:258
Gorgon::UI::RadioControl::RadioControl
RadioControl(std::initializer_list< std::pair< const T_, CT_ * >> elm, T_ current=T_())
Filling constructor that prepares RadioControl from the start.
Definition: RadioControl.h:64
Gorgon::Event
This class provides event mechanism.
Definition: Event.h:134
Gorgon::UI::RadioControl::current
T_ current
Definition: RadioControl.h:263
Gorgon::UI::Widget::Move
void Move(int x, int y)
Moves this widget to the given position.
Definition: Widget.h:45
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::Containers::Hashmap
This class is a reference based hashmap.
Definition: Hashmap.h:35
Gorgon::UI::RadioControl::columns
int columns
Definition: RadioControl.h:265
Gorgon::UI::RadioControl::begin
auto begin() const
For iteration.
Definition: RadioControl.h:213
Gorgon::UI::RadioControl::ChangeValue
void ChangeValue(const T_ &before, const T_ &after)
Changes the value of the given element.
Definition: RadioControl.h:146
Gorgon::UI::RadioControl::Get
T_ Get() const
Returns the current value.
Definition: RadioControl.h:125
Gorgon::Geometry::basic_Point::X
T_ X
X coordinate.
Definition: Point.h:368
Gorgon::UI::RadioControl::RadioControl
RadioControl(const RadioControl &)=delete
No copying.
Gorgon::UI::RadioControl::Exists
bool Exists(const T_ value) const
Returns if the given element exists.
Definition: RadioControl.h:130
Gorgon::UI::RadioControl::begin
auto begin()
For iteration.
Definition: RadioControl.h:203
Gorgon::UI::RadioControl::clearall
void clearall()
Definition: RadioControl.h:250
Gorgon::UI::RadioControl::GetColumns
int GetColumns() const
Returns the number of columns when placing the widgets.
Definition: RadioControl.h:228
Gorgon::UI::RadioControl::reverse
std::map< CT_ *, T_ > reverse
Definition: RadioControl.h:259
TwoStateControl.h
Gorgon::UI::RadioControl::changing
void changing(TwoStateControl &control, bool state, bool &allow)
Definition: RadioControl.h:235
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::UI::RadioControl::end
auto end() const
For iteration.
Definition: RadioControl.h:218
Gorgon::UI::RadioControl::SetColumns
void SetColumns(int value)
Changes the number of columns when placing the widgets.
Definition: RadioControl.h:223
Gorgon::UI::RadioControl::ChangedEvent
Event< RadioControl, T_ > ChangedEvent
Definition: RadioControl.h:232
Gorgon::Geometry::basic_Point
This class represents a 2D point.
Definition: Point.h:32
Gorgon::UI::RadioControl::RadioControl
RadioControl()
Default constructor. Use filling constructor if possible.
Definition: RadioControl.h:36
Gorgon::UI::TwoStateControl
This class is designed to be the interface class for all checkbox like UI elements.
Definition: TwoStateControl.h:13
Gorgon::UI::RadioControl::end
auto end()
For iteration.
Definition: RadioControl.h:208
Gorgon::UI::RadioControl::elementadded
virtual void elementadded(const T_ &index)
Definition: RadioControl.h:256
Gorgon::UI::RadioControl::~RadioControl
virtual ~RadioControl()
Definition: RadioControl.h:85
Gorgon::UI::RadioControl::RadioControl
RadioControl(std::initializer_list< std::pair< const T_, CT_ & >> elm, T_ current=T_())
Filling constructor that prepares RadioControl from the start.
Definition: RadioControl.h:43
Gorgon::UI::RadioControl::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::UI::RadioControl::Set
bool Set(const T_ value)
Assigns a new value to the radio control.
Definition: RadioControl.h:104
Gorgon::UI::RadioControl::operator=
RadioControl & operator=(const T_ value)
Assigns a new value to the radio control.
Definition: RadioControl.h:92
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