Gorgon Game Engine
Inputbox.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <functional>
4 #include <string>
5 
6 #include "../Event.h"
7 #include "../Property.h"
8 #include "../UI/Validators.h"
9 #include "../UI/ComponentStackWidget.h"
10 #include "../UI/Helpers.h"
11 #include "../Input/KeyRepeater.h"
12 #include "Registry.h"
13 
14 namespace Gorgon { namespace Widgets {
15 
17  namespace internal {
18  class Inputbox_base : public UI::ComponentStackWidget {
19  protected:
20  Inputbox_base(const UI::Template &temp);
21 
22  //for keeping selection both in bytes and glyphs
23  struct glyphbyte {
24  int glyph, byte;
25 
26  glyphbyte &operator +=(const glyphbyte &other) {
27  glyph += other.glyph;
28  byte += other.byte;
29 
30  return *this;
31  }
32 
33  glyphbyte operator +(const glyphbyte &other) const {
34  return {glyph + other.glyph, byte + other.byte};
35  }
36  };
37 
38  static constexpr int allselected = std::numeric_limits<int>::max();
39 
40 
41  public:
42 
44  int Length() const {
45  return glyphcount;
46  }
47 
50  std::string GetText() const {
51  return display;
52  }
53 
54  std::string GetSelectedText() const {
55  if(sellen.byte < 0)
56  return display.substr(selstart.byte + sellen.byte, -sellen.byte);
57  else if(sellen.byte > 0)
58  return display.substr(selstart.byte, sellen.byte);
59  else
60  return "";
61  }
62 
65 
67  void SelectAll() {
68  selstart = {0, 0};
69  sellen = {allselected, allselected};
70  updateselection();
71  }
72 
75  void SelectNone() {
76  sellen = {0, 0};
77  updateselection();
78  }
79 
81  int SelectionStart() const {
82  return selstart.glyph;
83  }
84 
87  int SelectionLength() const {
88  return sellen.glyph;
89  }
90 
92  int CaretLocation() const {
93  return selstart.glyph + sellen.glyph;
94  }
95 
97 
98 
99  bool Activate() override {
100  return Focus();
101  }
102 
103  bool Done() override;
104 
105  bool CharacterEvent(Gorgon::Char c) override;
106 
107  virtual bool KeyEvent(Input::Key key, float state) override;
108 
109  virtual void SetEnabled(bool value) override {
110  ComponentStackWidget::SetEnabled(value);
111 
112  if(readonly) {
113  if(!value) {
114  stack.RemoveCondition(UI::ComponentCondition::Readonly);
115  }
116  else {
117  stack.AddCondition(UI::ComponentCondition::Readonly);
118  }
119  }
120  }
121 
124  void SetAutoSelectAll(const bool &value) {
125  autoselectall = value;
126  if(!IsFocused() && value) {
127  SelectAll();
128  }
129  }
130 
133  bool GetAutoSelectAll() const {
134  return autoselectall;
135  }
136 
139  void SetBlockEnterKey(const bool &value) {
140  blockenter = value;
141  }
142 
145  bool GetBlockEnterKey() const {
146  return blockenter;
147  }
148 
151  void SetReadonly(const bool &value) {
152  if(value == readonly)
153  return;
154 
155  readonly = value;
156 
157  if(readonly && IsEnabled()) {
158  stack.AddCondition(UI::ComponentCondition::Readonly);
159  }
160  else {
161  stack.RemoveCondition(UI::ComponentCondition::Readonly);
162  }
163  }
164 
167  bool GetReadonly() const {
168  return readonly;
169  }
170 
173  BooleanProperty< Inputbox_base, bool,
174  &Inputbox_base::GetAutoSelectAll,
175  &Inputbox_base::SetAutoSelectAll> AutoSelectAll;
176 
179  BooleanProperty< Inputbox_base, bool,
180  &Inputbox_base::GetBlockEnterKey,
181  &Inputbox_base::SetBlockEnterKey> BlockEnterKey;
182 
185  BooleanProperty< Inputbox_base, bool,
186  &Inputbox_base::GetReadonly,
187  &Inputbox_base::SetReadonly> Readonly;
188 
189 
190  protected:
191 
193  void updateselection();
194 
196  virtual void updatevalue() = 0;
197 
199  virtual void updatevaluedisplay(bool updatedisplay = true) = 0;
200 
201  virtual void changed() = 0;
202 
203  void moveselleft() {
204  if(selstart.glyph > 0) {
205  selstart.glyph--;
206  selstart.byte--;
207 
208  //if previous byte is unicode continuation point, go further before
209  while(selstart.byte && (display[selstart.byte] & 0b11000000) == 0b10000000)
210  selstart.byte--;
211  }
212  }
213 
214  void moveselright() {
215  if(selstart.glyph < glyphcount) {
216  selstart.glyph++;
217  selstart.byte += String::UTF8Bytes(display[selstart.byte]);
218  }
219  }
220 
221  void eraseselected() {
222  if(sellen.byte < 0) {
223  dirty = true;
224 
225  int pos = selstart.byte + sellen.byte;
226 
227  display.erase(pos, -sellen.byte);
228 
229  glyphcount += sellen.glyph;
230  selstart += sellen;
231  sellen = {0, 0};
232  }
233  else if(sellen.byte > 0) {
234  dirty = true;
235 
236  int pos = selstart.byte;
237 
238  display.erase(pos, sellen.byte);
239 
240  glyphcount -= sellen.glyph;
241  sellen = {0, 0};
242 
243  updatevaluedisplay(false);
244  updateselection();
245  }
246  }
247 
248  void focuslost() override;
249 
250  void focused() override;
251 
252  void mousedown(UI::ComponentTemplate::Tag tag, Geometry::Point location, Input::Mouse::Button button);
253 
254  void mouseup(UI::ComponentTemplate::Tag tag, Geometry::Point location, Input::Mouse::Button button);
255 
256  void mousemove(UI::ComponentTemplate::Tag tag, Geometry::Point location);
257 
258 
259  std::string display;
260 
261  glyphbyte selstart = {0, 0};
262  glyphbyte sellen = {0, 0};
263  int glyphcount = 0;
264  int pglyph = 0;
265  int scrolloffset = 0;
266 
267  bool ismousedown = false;
268  bool autoselectall = false;
269  bool blockenter = false;
270  bool readonly = false;
271  bool dirty = false;
272 
273  Input::KeyRepeater repeater;
274 
275  };
276  }
278 
279  /*template<class V_>
280  struct validatorextras {
281  protected:
282  void transfer(V_ &) {
283  }
284  };
285 
286  class StringValidator {
287  public:
288 
289  void SetMaxChars(int value) {
290  maxchars = value;
291  }
292 
293 
294  private:
295  int maxchars = 0;
296  };
297 
298  template<>
299  struct validatorextras<StringValidor> {
300  void SetMaxChars(int value) {
301  maxchars = value;
302  }
303 
304  int GetMaxChars() const {
305  return maxchars;
306  }
307 
308  protected:
309  void transfer(V_ &validator) {
310  validator.SetMaxChars(maxchars);
311  }
312 
313  private:
314  int maxchars = 0;
315  };
316  //derive from validator extras and class transfer
317  */
318 
325  template<class T_, class V_ = UI::ConversionValidator<T_>, template<class C_, class PT_, PT_(C_::*Getter_)() const, void(C_::*Setter_)(const PT_ &)> class P_ = Gorgon::Property, Widgets::Registry::TemplateType DEFTMP_ = Widgets::Registry::Inputbox_Regular>
326  class Inputbox :
327  public internal::Inputbox_base,
328  public P_<UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>, T_, &UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>::get_, &UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>::set_> {
329 
330 
331  public:
332 
333  using Type = T_;
334  using PropType = P_<UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>, T_, &UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>::get_, &UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>::set_>;
335 
336  friend class P_<UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>, T_, &UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>::get_, &UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>::set_>;
337  template<class T1_, class V1_, template<class C_, class PT_, PT_(C_::*Getter_)() const, void(C_::*Setter_)(const PT_&)> class P1_, Widgets::Registry::TemplateType DEFTMP1_>
338  friend class Inputbox;
339  friend struct UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>;
340 
342  explicit Inputbox(const UI::Template &temp, T_ value = T_()) :
343  internal::Inputbox_base(temp), PropType(&helper), value(value)
344  {
345  display = validator.ToString(value);
346 
348  updateselection();
349  }
350 
352  explicit Inputbox(const UI::Template &temp, std::function<void()> changedevent) : Inputbox(temp) {
353  ChangedEvent.Register(changedevent);
354  }
355 
357  explicit Inputbox(const UI::Template &temp, T_ value, std::function<void()> changedevent) : Inputbox(temp, value)
358  {
359  ChangedEvent.Register(changedevent);
360  }
361 
363  explicit Inputbox(T_ value = T_(), Registry::TemplateType type = DEFTMP_) :
364  Inputbox(Registry::Active()[type], value) { }
365 
367  explicit Inputbox(std::function<void()> changedevent, Registry::TemplateType type = DEFTMP_) :
368  Inputbox(Registry::Active()[type], changedevent) { }
369 
371  explicit Inputbox(T_ value, std::function<void()> changedevent, Registry::TemplateType type = DEFTMP_) :
372  Inputbox(Registry::Active()[type], value, changedevent) { }
373 
375  Inputbox &operator =(const T_ value) {
376  set(value);
377 
378  return *this;
379  }
380 
382  Inputbox &operator =(const Inputbox &value) {
383  set(value.Get());
384 
385  return *this;
386  }
387 
388 
390  operator T_() const {
391  return value;
392  }
393 
400 
405 
406 
407  protected:
408 
410  T_ get() const {
411  return value;
412  }
413 
415  void set(const T_ &val) {
416  if(value == val)
417  return;
418 
419  value = val;
420 
422  updateselection();
423 
424  dirty = false;
425  }
426 
427  void updatevalue() override {
428  value = validator.From(display);
429 
430  EditedEvent();
431  }
432 
433  void changed() override {
434  ChangedEvent(value);
435  }
436 
438  void updatevaluedisplay(bool updatedisplay = true) override {
439  if(updatedisplay) {
440  display = validator.ToString(value);
441  glyphcount = String::UnicodeGlyphCount(display);
442  }
443 
444  stack.SetData(UI::ComponentTemplate::Text, display);
445  }
446 
447 
448  private:
449  V_ validator;
450  T_ value;
451 
452  struct UI::internal::prophelper<Inputbox<T_, V_, P_>, T_> helper = UI::internal::prophelper<Inputbox<T_, V_, P_>, T_>(this);
453  };
454 
455 
456 } }
Gorgon::String::UTF8Bytes
int UTF8Bytes(char c)
Returns the number of bytes used by the next UTF8 codepoint.
Definition: String.h:569
Gorgon::Input::Keyboard::Keycodes::Numpad_Enter
constexpr Key Numpad_Enter
Definition: Keyboard.h:131
Gorgon::Input::Keyboard::Keycodes::Enter
constexpr Key Enter
Definition: Keyboard.h:56
Gorgon::Input::Mouse::None
@ None
Definition: Mouse.h:32
Gorgon::UI::TextholderTemplate
Textholder is designed to hold text data.
Definition: Template.h:1422
Gorgon::UI::ComponentTemplate::ContentsTag
@ ContentsTag
Definition: Template.h:872
Gorgon::Widgets::Inputbox::EditedEvent
Event< Inputbox > EditedEvent
Fired after the value of in the inputbox is edited.
Definition: Inputbox.h:404
Gorgon::Event
This class provides event mechanism.
Definition: Event.h:134
Gorgon::Widgets::Inputbox::Inputbox
Inputbox(std::function< void()> changedevent, Registry::TemplateType type=DEFTMP_)
Initializes the inputbox.
Definition: Inputbox.h:367
Gorgon::UI::ComponentTemplate::SelectionTag
@ SelectionTag
Definition: Template.h:874
Gorgon::Widgets::Inputbox::updatevalue
void updatevalue() override
Definition: Inputbox.h:427
Gorgon::Input::AllowCharEvent
bool AllowCharEvent
During keyevent this variable can be set to true, if done so, it will allow character events even if ...
Definition: Input.cpp:11
Gorgon::Input::Keyboard::CurrentModifier
Modifier CurrentModifier
Current keyboard modifier, this is a global value.
Definition: Input.cpp:7
Gorgon::UI::Template
This class stores visual information about a widget template.
Definition: Template.h:392
Gorgon::BooleanProperty
Supports logic operators.
Definition: Property.h:230
Gorgon::Widgets::Inputbox::updatevaluedisplay
void updatevaluedisplay(bool updatedisplay=true) override
updates the value display
Definition: Inputbox.h:438
Gorgon::Geometry::basic_Point::X
T_ X
X coordinate.
Definition: Point.h:368
Gorgon::UI::ComponentStackWidget::focused
virtual void focused() override
This is called after the focus is transferred to this widget.
Definition: ComponentStackWidget.h:93
Gorgon::Widgets::Inputbox::operator=
Inputbox & operator=(const T_ value)
Assignment to the value type.
Definition: Inputbox.h:375
Gorgon::Input::Keyboard::Modifier
This class represents a modifier key. These keys can be.
Definition: Keyboard.h:167
Gorgon::UI::TopLeft
@ TopLeft
Top left.
Definition: Template.h:41
Inputbox.h
Gorgon::Widgets::Registry::Inputbox_Regular
@ Inputbox_Regular
Definition: Registry.h:30
Gorgon::Input::Keyboard::Keycodes::Escape
constexpr Key Escape
Definition: Keyboard.h:60
Gorgon::Input::Keyboard::Keycodes::Tab
constexpr Key Tab
Definition: Keyboard.h:57
Gorgon::Input::Keyboard::Keycodes::Shift
constexpr Key Shift
Definition: Keyboard.h:30
Gorgon::UI::ComponentTemplate::CaretTag
@ CaretTag
Definition: Template.h:875
Gorgon::Widgets::Registry::TemplateType
TemplateType
This enum lists all possible template types.
Definition: Registry.h:18
Gorgon::UI::ComponentTemplate::Text
@ Text
Works only for TextholderTemplate, data will affect the text that is displayed.
Definition: Template.h:651
Gorgon::Input::Key
int Key
A type to represent an input key.
Definition: Input.h:14
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::Char
uint32_t Char
Definition: Types.h:46
Gorgon::Property
This is generic property that can be set and retrieved good for enums mostly, its ok to use with POD ...
Definition: Property.h:30
Gorgon::UI::ComponentTemplate::ViewPortTag
@ ViewPortTag
Definition: Template.h:873
Gorgon::Widgets::Inputbox::Inputbox
Inputbox(T_ value=T_(), Registry::TemplateType type=DEFTMP_)
Initializes the inputbox.
Definition: Inputbox.h:363
Gorgon::Widgets::Inputbox::set
void set(const T_ &val)
Changes the value in the box.
Definition: Inputbox.h:415
Gorgon::Widgets::Inputbox
This class allows users to enter any value to an inputbox.
Definition: Inputbox.h:328
Gorgon::UI::BottomLeft
@ BottomLeft
Bottom left.
Definition: Template.h:56
Gorgon::WindowManager::GetClipboardText
std::string GetClipboardText(Resource::GID::Type type=Resource::GID::Text)
Returns the clipboard text.
Definition: Clipboard.cpp:249
Gorgon::String::UnicodeGlyphCount
int UnicodeGlyphCount(const std::string &s)
Definition: String.h:595
Gorgon::Widgets::Inputbox::Inputbox
Inputbox(const UI::Template &temp, T_ value, std::function< void()> changedevent)
Initializes the inputbox.
Definition: Inputbox.h:357
Gorgon::String::UnicodeUTF8Bytes
int UnicodeUTF8Bytes(Char c)
Definition: String.h:583
Gorgon::Widgets::Inputbox::Inputbox
Inputbox(T_ value, std::function< void()> changedevent, Registry::TemplateType type=DEFTMP_)
Initializes the inputbox.
Definition: Inputbox.h:371
Gorgon::Input::Keyboard::Keycodes::End
constexpr Key End
Definition: Keyboard.h:41
Gorgon::operator+
T_ operator+(TextualProperty< C_, T_, Setter_, Getter_ > &t, const T_ &v)
Definition: Property.h:801
Gorgon::Input::Keyboard::Keycodes::Delete
constexpr Key Delete
Definition: Keyboard.h:43
Gorgon::UI::internal::prophelper
Definition: Helpers.h:7
Gorgon::Geometry::basic_Point
This class represents a 2D point.
Definition: Point.h:32
Registry.h
Gorgon::String::InsertUnicode
bool InsertUnicode(std::string &s, std::size_t pos, Char c)
Appends a unicode code point to the string.
Definition: String.h:650
Gorgon::Widgets::Inputbox::changed
void changed() override
Definition: Inputbox.h:433
Gorgon::UI::Active
@ Active
This is for widgets that can be activated, like a count down timer.
Definition: Template.h:245
Gorgon::Input::Keyboard::Keycodes::V
constexpr Key V
Definition: Keyboard.h:101
Gorgon::Input::Keyboard::Keycodes::C
constexpr Key C
Definition: Keyboard.h:82
Gorgon::Property< UI::internal::prophelper< Inputbox< T_, UI::ConversionValidator< T_ >, Gorgon::Property >, T_ >, T_, &UI::internal::prophelper< Inputbox< T_, UI::ConversionValidator< T_ >, Gorgon::Property >, T_ >::get_, &UI::internal::prophelper< Inputbox< T_, UI::ConversionValidator< T_ >, Gorgon::Property >, T_ >::set_ >::Type
T_ Type
Definition: Property.h:32
Gorgon::Geometry::basic_Point::Y
T_ Y
Y coordinate.
Definition: Point.h:371
Gorgon::Widgets::Inputbox::ChangedEvent
Event< Inputbox, const T_ & > ChangedEvent
Fired after the value of the inputbox is changed.
Definition: Inputbox.h:399
Gorgon::Widgets::Inputbox::Inputbox
Inputbox(const UI::Template &temp, std::function< void()> changedevent)
Initializes the inputbox.
Definition: Inputbox.h:352
Gorgon::Input::KeyRepeater
This class simplifies the use of repeated keystrokes when a key is pressed.
Definition: KeyRepeater.h:54
Gorgon::Geometry::basic_Size::Width
T_ Width
Width of this size object.
Definition: Size.h:258
Gorgon::Property::Get
T_ Get() const
Definition: Property.h:59
Gorgon::Input::Mouse::Button
Button
Lists the mouse button constants.
Definition: Mouse.h:31
Gorgon::UI::TextholderTemplate::GetRenderer
const Graphics::TextRenderer & GetRenderer() const
Returns the renderer for this textholder.
Definition: Template.h:1445
Gorgon::Input::Keyboard::Keycodes::Right
constexpr Key Right
Definition: Keyboard.h:64
Gorgon::Input::Keyboard::Keycodes::Backspace
constexpr Key Backspace
Definition: Keyboard.h:58
Gorgon::UI::Textholder
@ Textholder
Definition: Template.h:163
Gorgon::WindowManager::SetClipboardText
void SetClipboardText(const std::string &text, Resource::GID::Type type=Resource::GID::Text, bool unicode=true, bool append=false)
Sets the clipboard text to given string.
Definition: Clipboard.cpp:350
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::UI::ComponentTemplate::Tag
Tag
Tags mark a component to be modified in a way meaningful to specific widgets.
Definition: Template.h:850
Gorgon::Widgets::Inputbox::get
T_ get() const
Returns the value in the box.
Definition: Inputbox.h:410
Gorgon::UI::ComponentStackWidget::focuslost
virtual void focuslost() override
This is called after the focus is lost.
Definition: ComponentStackWidget.h:99
Gorgon::Input::Keyboard::Keycodes::Left
constexpr Key Left
Definition: Keyboard.h:62
Gorgon::Input::Keyboard::Keycodes::A
constexpr Key A
Definition: Keyboard.h:80
Gorgon::String::AppendUnicode
bool AppendUnicode(std::string &s, Char c)
Appends a unicode code point to the string.
Definition: String.h:609
Gorgon::Widgets::Registry
This class stores templates for elements.
Definition: Registry.h:12
Gorgon::Input::Keyboard::Keycodes::Home
constexpr Key Home
Definition: Keyboard.h:40
Gorgon::Input::Keyboard::Modifier::IsModified
bool IsModified() const
Checks if this modifier really modifies the key state so that no printable characters can be formed.
Definition: Keyboard.h:209
Gorgon::UI::Readonly
@ Readonly
Component is visible when the widget is readonly.
Definition: Template.h:187