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 "../observer/module.hpp"
12#include <type_traits>
13#include <memory>
14
15namespace hi { inline namespace v1 {
16
17class abstract_button_widget;
18
22enum class button_state {
25 off,
26
29 on,
30
38 other
39};
40
45public:
46 using notifier_type = notifier<>;
47 using callback_token = notifier_type::callback_token;
48 using callback_proto = notifier_type::callback_proto;
49
50 virtual ~button_delegate() = default;
51
52 virtual void init(abstract_button_widget& sender) noexcept {}
53
54 virtual void deinit(abstract_button_widget& sender) noexcept {}
55
58 virtual void activate(abstract_button_widget& sender) noexcept {};
59
62 [[nodiscard]] virtual button_state state(abstract_button_widget const& sender) const noexcept
63 {
64 return button_state::off;
65 }
66
69 [[nodiscard]] callback_token
70 subscribe(forward_of<callback_proto> auto&& callback, callback_flags flags = callback_flags::synchronous) noexcept
71 {
72 return _notifier.subscribe(hi_forward(callback), flags);
73 }
74
75protected:
76 notifier_type _notifier;
77};
78
87template<typename T>
89public:
90 using value_type = T;
91
92 observer<value_type> value;
93 observer<value_type> on_value;
94
101 forward_of<observer<value_type>> auto&& value,
102 forward_of<observer<value_type>> auto&& on_value) noexcept :
103 value(hi_forward(value)), on_value(hi_forward(on_value))
104 {
105 // clang-format off
106 _value_cbt = this->value.subscribe([&](auto...){ this->_notifier(); });
107 _on_value_cbt = this->on_value.subscribe([&](auto...){ this->_notifier(); });
108 // clang-format on
109 }
110
112 [[nodiscard]] button_state state(abstract_button_widget const& sender) const noexcept override
113 {
114 if (*value == *on_value) {
115 return button_state::on;
116 } else {
117 return button_state::off;
118 }
119 }
120
121 void activate(abstract_button_widget& sender) noexcept override
122 {
123 value = *on_value;
124 }
126private:
127 typename decltype(value)::callback_token _value_cbt;
128 typename decltype(on_value)::callback_token _on_value_cbt;
129};
130
139template<typename T>
141public:
142 using value_type = T;
143 static constexpr bool can_make_defaults =
144 std::is_same_v<value_type, bool> or std::is_integral_v<value_type> or std::is_enum_v<value_type>;
145
146 observer<value_type> value;
147 observer<value_type> on_value;
148 observer<value_type> off_value;
149
157 forward_of<observer<value_type>> auto&& value,
158 forward_of<observer<value_type>> auto&& on_value,
159 forward_of<observer<value_type>> auto&& off_value) noexcept :
160 value(hi_forward(value)), on_value(hi_forward(on_value)), off_value(hi_forward(off_value))
161 {
162 // clang-format off
163 _value_cbt = this->value.subscribe([&](auto...){ this->_notifier(); });
164 _on_value_cbt = this->on_value.subscribe([&](auto...){ this->_notifier(); });
165 _off_value_cbt = this->off_value.subscribe([&](auto...){ this->_notifier(); });
166 // clang-format on
167 }
168
175 forward_of<observer<value_type>> auto&& value,
176 forward_of<observer<value_type>> auto&& on_value) noexcept requires can_make_defaults :
177 default_toggle_button_delegate(hi_forward(value), hi_forward(on_value), value_type{})
178 {
179 }
180
185 default_toggle_button_delegate(forward_of<observer<value_type>> auto&& value) noexcept requires can_make_defaults :
186 default_toggle_button_delegate(hi_forward(value), value_type{1}, value_type{})
187 {
188 }
189
191 [[nodiscard]] button_state state(abstract_button_widget const& sender) const noexcept override
192 {
193 if (*value == *on_value) {
194 return button_state::on;
195 } else if (*value == *off_value) {
196 return button_state::off;
197 } else {
198 return button_state::other;
199 }
200 }
201
202 void activate(abstract_button_widget& sender) noexcept override
203 {
204 if (*value == *off_value) {
205 value = *on_value;
206 } else {
207 value = *off_value;
208 }
209 }
211private:
212 typename decltype(value)::callback_token _value_cbt;
213 typename decltype(on_value)::callback_token _on_value_cbt;
214 typename decltype(off_value)::callback_token _off_value_cbt;
215};
216
226make_default_radio_button_delegate(auto&& value, auto&& on_value) noexcept requires requires
227{
228 default_radio_button_delegate<observer_decay_t<decltype(value)>>{hi_forward(value), hi_forward(on_value)};
229}
230{
231 return std::make_shared<default_radio_button_delegate<observer_decay_t<decltype(value)>>>(
232 hi_forward(value), hi_forward(on_value));
233}
234
244make_default_toggle_button_delegate(auto&& value, auto&&...args) noexcept requires requires
245{
246 default_toggle_button_delegate<observer_decay_t<decltype(value)>>{hi_forward(value), hi_forward(args)...};
247}
248{
249 return std::make_shared<default_toggle_button_delegate<observer_decay_t<decltype(value)>>>(
250 hi_forward(value), hi_forward(args)...);
251}
252
253}} // 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:244
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:226
button_state
The state of a button.
Definition button_delegate.hpp:22
@ 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:13
geometry/margins.hpp
Definition cache.hpp:11
@ on
The border is drawn on the edge of a quad.
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:44
virtual void activate(abstract_button_widget &sender) noexcept
Called when the button is pressed by the user.
Definition button_delegate.hpp:58
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:70
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:62
A default radio button delegate.
Definition button_delegate.hpp:88
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:100
A default toggle button delegate.
Definition button_delegate.hpp:140
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:156
default_toggle_button_delegate(forward_of< observer< value_type > > auto &&value) noexcept
Construct a delegate.
Definition button_delegate.hpp:185
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:174
T make_shared(T... args)