HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
button_delegate.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2021.
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 "../notifier.hpp"
12#include "../observer.hpp"
13#include <type_traits>
14#include <memory>
15
16namespace hi { inline namespace v1 {
17
18class abstract_button_widget;
19
23enum class button_state {
26 off,
27
30 on,
31
39 other
40};
41
46public:
47 using notifier_type = notifier<>;
48 using callback_token = notifier_type::callback_token;
49 using callback_proto = notifier_type::callback_proto;
50
51 virtual ~button_delegate() = default;
52
53 virtual void init(abstract_button_widget& sender) noexcept {}
54
55 virtual void deinit(abstract_button_widget& sender) noexcept {}
56
59 virtual void activate(abstract_button_widget& sender) noexcept {};
60
63 [[nodiscard]] virtual button_state state(abstract_button_widget const& sender) const noexcept
64 {
65 return button_state::off;
66 }
67
70 [[nodiscard]] callback_token
71 subscribe(forward_of<callback_proto> auto&& callback, callback_flags flags = callback_flags::synchronous) noexcept
72 {
73 return _notifier.subscribe(hi_forward(callback), flags);
74 }
75
76protected:
77 notifier_type _notifier;
78};
79
88template<typename T>
90public:
91 using value_type = T;
92
93 observer<value_type> value;
94 observer<value_type> on_value;
95
102 forward_of<observer<value_type>> auto&& value,
103 forward_of<observer<value_type>> auto&& on_value) noexcept :
104 value(hi_forward(value)), on_value(hi_forward(on_value))
105 {
106 // clang-format off
107 _value_cbt = this->value.subscribe([&](auto...){ this->_notifier(); });
108 _on_value_cbt = this->on_value.subscribe([&](auto...){ this->_notifier(); });
109 // clang-format on
110 }
111
113 [[nodiscard]] button_state state(abstract_button_widget const& sender) const noexcept override
114 {
115 if (*value == *on_value) {
116 return button_state::on;
117 } else {
118 return button_state::off;
119 }
120 }
121
122 void activate(abstract_button_widget& sender) noexcept override
123 {
124 value = *on_value;
125 }
127private:
128 typename decltype(value)::callback_token _value_cbt;
129 typename decltype(on_value)::callback_token _on_value_cbt;
130};
131
140template<typename T>
142public:
143 using value_type = T;
144 static constexpr bool can_make_defaults =
145 std::is_same_v<value_type, bool> or std::is_integral_v<value_type> or std::is_enum_v<value_type>;
146
147 observer<value_type> value;
148 observer<value_type> on_value;
149 observer<value_type> off_value;
150
158 forward_of<observer<value_type>> auto&& value,
159 forward_of<observer<value_type>> auto&& on_value,
160 forward_of<observer<value_type>> auto&& off_value) noexcept :
161 value(hi_forward(value)), on_value(hi_forward(on_value)), off_value(hi_forward(off_value))
162 {
163 // clang-format off
164 _value_cbt = this->value.subscribe([&](auto...){ this->_notifier(); });
165 _on_value_cbt = this->on_value.subscribe([&](auto...){ this->_notifier(); });
166 _off_value_cbt = this->off_value.subscribe([&](auto...){ this->_notifier(); });
167 // clang-format on
168 }
169
176 forward_of<observer<value_type>> auto&& value,
177 forward_of<observer<value_type>> auto&& on_value) noexcept requires can_make_defaults :
178 default_toggle_button_delegate(hi_forward(value), hi_forward(on_value), value_type{})
179 {
180 }
181
186 default_toggle_button_delegate(forward_of<observer<value_type>> auto&& value) noexcept requires can_make_defaults :
187 default_toggle_button_delegate(hi_forward(value), value_type{1}, value_type{})
188 {
189 }
190
192 [[nodiscard]] button_state state(abstract_button_widget const& sender) const noexcept override
193 {
194 if (*value == *on_value) {
195 return button_state::on;
196 } else if (*value == *off_value) {
197 return button_state::off;
198 } else {
199 return button_state::other;
200 }
201 }
202
203 void activate(abstract_button_widget& sender) noexcept override
204 {
205 if (*value == *off_value) {
206 value = *on_value;
207 } else {
208 value = *off_value;
209 }
210 }
212private:
213 typename decltype(value)::callback_token _value_cbt;
214 typename decltype(on_value)::callback_token _on_value_cbt;
215 typename decltype(off_value)::callback_token _off_value_cbt;
216};
217
227make_default_radio_button_delegate(auto&& value, auto&& on_value) noexcept requires requires
228{
229 default_radio_button_delegate<observer_decay_t<decltype(value)>>{hi_forward(value), hi_forward(on_value)};
230}
231{
232 return std::make_shared<default_radio_button_delegate<observer_decay_t<decltype(value)>>>(
233 hi_forward(value), hi_forward(on_value));
234}
235
245make_default_toggle_button_delegate(auto&& value, auto&&...args) noexcept requires requires
246{
247 default_toggle_button_delegate<observer_decay_t<decltype(value)>>{hi_forward(value), hi_forward(args)...};
248}
249{
250 return std::make_shared<default_toggle_button_delegate<observer_decay_t<decltype(value)>>>(
251 hi_forward(value), hi_forward(args)...);
252}
253
254}} // namespace hi::v1
#define hi_forward(x)
Forward a value, based on the decltype of the value.
Definition utility.hpp:29
@ other
The gui_event does not have associated data.
std::shared_ptr< button_delegate > make_default_toggle_button_delegate(auto &&value, auto &&...args) noexcept
Make a shared pointer to a toggle-button delegate.
Definition button_delegate.hpp:245
std::shared_ptr< button_delegate > make_default_radio_button_delegate(auto &&value, auto &&on_value) noexcept
Make a shared pointer to a radio-button delegate.
Definition button_delegate.hpp:227
button_state
The state of a button.
Definition button_delegate.hpp:23
@ off
The 'off' state of a button.
@ other
The other state of a button.
@ on
The 'on' state of a button.
DOXYGEN BUG.
Definition algorithm.hpp:15
geometry/margins.hpp
Definition assert.hpp:18
Base class for implementing button widgets.
Definition abstract_button_widget.hpp:32
A button delegate controls the state of a button widget.
Definition button_delegate.hpp:45
virtual void activate(abstract_button_widget &sender) noexcept
Called when the button is pressed by the user.
Definition button_delegate.hpp:59
callback_token subscribe(forward_of< callback_proto > auto &&callback, callback_flags flags=callback_flags::synchronous) noexcept
Subscribe a callback for notifying the widget of a data change.
Definition button_delegate.hpp:71
virtual button_state state(abstract_button_widget const &sender) const noexcept
Used by the widget to check the state of the button.
Definition button_delegate.hpp:63
A default radio button delegate.
Definition button_delegate.hpp:89
default_radio_button_delegate(forward_of< observer< value_type > > auto &&value, forward_of< observer< value_type > > auto &&on_value) noexcept
Construct a delegate.
Definition button_delegate.hpp:101
A default toggle button delegate.
Definition button_delegate.hpp:141
default_toggle_button_delegate(forward_of< observer< value_type > > auto &&value, forward_of< observer< value_type > > auto &&on_value, forward_of< observer< value_type > > auto &&off_value) noexcept
Construct a delegate.
Definition button_delegate.hpp:157
default_toggle_button_delegate(forward_of< observer< value_type > > auto &&value) noexcept
Construct a delegate.
Definition button_delegate.hpp:186
default_toggle_button_delegate(forward_of< observer< value_type > > auto &&value, forward_of< observer< value_type > > auto &&on_value) noexcept
Construct a delegate.
Definition button_delegate.hpp:175
T make_shared(T... args)