HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
text_field_delegate.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2021-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
9#pragma once
10
11#include "../l10n/l10n.hpp"
12#include "../observer/module.hpp"
13#include "../macros.hpp"
14#include <string>
15#include <string_view>
16#include <optional>
17#include <concepts>
18
19namespace hi { inline namespace v1 {
20class text_field_widget;
21
27public:
28 using notifier_type = notifier<>;
29 using callback_token = notifier_type::callback_token;
30 using callback_proto = notifier_type::callback_proto;
31
32 virtual ~text_field_delegate() = default;
33 virtual void init(text_field_widget const& sender) noexcept {}
34 virtual void deinit(text_field_widget const& sender) noexcept {}
35
42 virtual label validate(text_field_widget& sender, gstring const &text) noexcept
43 {
44 return {};
45 }
46
54 virtual gstring text(text_field_widget& sender) noexcept
55 {
56 return {};
57 }
58
69 virtual void set_text(text_field_widget& sender, gstring const &text) noexcept {}
70
71 callback_token
72 subscribe(forward_of<callback_proto> auto&& callback, callback_flags flags = callback_flags::synchronous) noexcept
73 {
74 return _notifier.subscribe(hi_forward(callback), flags);
75 }
76
77protected:
78 notifier_type _notifier;
79};
80
86template<typename T>
88
96template<std::integral T>
98public:
99 using value_type = T;
100
102
103 default_text_field_delegate(forward_of<observer<value_type>> auto&& value) noexcept : value(hi_forward(value))
104 {
105 _value_cbt = this->value.subscribe([&](auto...) {
106 this->_notifier();
107 });
108 }
109
110 std::optional<label> validate(text_field_widget& sender, gstring const &text) noexcept override
111 {
112 try {
113 [[maybe_unused]] auto dummy = from_string<value_type>(to_string(text), 10);
114 } catch (parse_error const&) {
115 return {txt("Invalid integer")};
116 }
117
118 return {};
119 }
120
121 gstring text(text_field_widget& sender) noexcept override
122 {
123 return to_gstring(to_string(*value));
124 }
125
126 void set_text(text_field_widget& sender, gstring text) noexcept override
127 {
128 try {
129 value = from_string<value_type>(to_string(text), 10);
130 } catch (std::exception const&) {
131 // Ignore the error, don't modify the value.
132 return;
133 }
134 }
135
136private:
137 typename decltype(value)::callback_token _value_cbt;
138};
139
147template<std::floating_point T>
148class default_text_field_delegate<T> : public text_field_delegate {
149public:
150 using value_type = T;
151
153
154 default_text_field_delegate(forward_of<observer<value_type>> auto&& value) noexcept : value(hi_forward(value))
155 {
156 _value_cbt = this->value.subscribe([&](auto...) {
157 this->_notifier();
158 });
159 }
160
161 label validate(text_field_widget& sender, gstring const &text) noexcept override
162 {
163 try {
164 [[maybe_unused]] auto dummy = from_string<value_type>(to_string(text));
165 } catch (parse_error const&) {
166 return {elusive_icon::WarningSign, txt("Invalid floating point number")};
167 }
168
169 return {};
170 }
171
172 gstring text(text_field_widget& sender) noexcept override
173 {
174 return to_gstring(to_string(*value));
175 }
176
177 void set_text(text_field_widget& sender, gstring const &text) noexcept override
178 {
179 try {
180 value = from_string<value_type>(to_string(text));
181 } catch (std::exception const&) {
182 // Ignore the error, don't modify the value.
183 return;
184 }
185 }
186
187private:
188 typename decltype(value)::callback_token _value_cbt;
189};
190
199{
200 default_text_field_delegate<observer_decay_t<decltype(value)>>{hi_forward(value)};
201}
202{
203 using value_type = observer_decay_t<decltype(value)>;
204 return std::make_shared<default_text_field_delegate<value_type>>(hi_forward(value));
205}
206
207}} // namespace hi::v1
std::shared_ptr< text_field_delegate > make_default_text_field_delegate(auto &&value) noexcept
Create a shared pointer to a default text delegate.
Definition text_field_delegate.hpp:198
DOXYGEN BUG.
Definition algorithm.hpp:16
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
A localizable message.
Definition txt.hpp:100
Exception thrown during parsing on an error.
Definition exception_intf.hpp:47
A delegate that controls the state of a text_field_widget.
Definition text_field_delegate.hpp:26
virtual gstring text(text_field_widget &sender) noexcept
Get the text to show in the text field.
Definition text_field_delegate.hpp:54
virtual label validate(text_field_widget &sender, gstring const &text) noexcept
Validate the text field.
Definition text_field_delegate.hpp:42
virtual void set_text(text_field_widget &sender, gstring const &text) noexcept
Set the text as entered by the user.
Definition text_field_delegate.hpp:69
A default text delegate.
Definition text_field_delegate.hpp:87
label validate(text_field_widget &sender, gstring const &text) noexcept override
Validate the text field.
Definition text_field_delegate.hpp:161
gstring text(text_field_widget &sender) noexcept override
Get the text to show in the text field.
Definition text_field_delegate.hpp:121
std::optional< label > validate(text_field_widget &sender, gstring const &text) noexcept override
Validate the text field.
Definition text_field_delegate.hpp:110
void set_text(text_field_widget &sender, gstring const &text) noexcept override
Set the text as entered by the user.
Definition text_field_delegate.hpp:177
A single line text field.
Definition text_field_widget.hpp:63
True if T is a forwarded type of Forward.
Definition concepts.hpp:131