HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
default_button_delegate.hpp
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
5#pragma once
6
7#include "button_delegate.hpp"
8#include "button_type.hpp"
9#include "../observable.hpp"
10#include <type_traits>
11#include <memory>
12
13namespace hi::inline v1 {
14
24template<button_type ButtonType, typename T>
26public:
27 static_assert(ButtonType == button_type::radio or ButtonType == button_type::toggle);
28
29 using value_type = T;
30 static constexpr button_type button_type = ButtonType;
31 static constexpr bool can_make_defaults =
32 std::is_same_v<value_type, bool> or std::is_integral_v<value_type> or std::is_enum_v<value_type>;
33
36 observable<value_type> off_value;
37
44 default_button_delegate(auto &&value, auto &&on_value, auto &&off_value) noexcept :
45 value(hi_forward(value)), on_value(hi_forward(on_value)), off_value(hi_forward(off_value))
46 {
47 // clang-format off
48 _value_cbt = this->value.subscribe([&](auto...){ this->_notifier(); });
49 _on_value_cbt = this->on_value.subscribe([&](auto...){ this->_notifier(); });
50 _off_value_cbt = this->off_value.subscribe([&](auto...){ this->_notifier(); });
51 // clang-format on
52 }
53
59 default_button_delegate(auto &&value, auto &&on_value) noexcept
60 requires(can_make_defaults or button_type == button_type::radio) :
61 default_button_delegate(hi_forward(value), hi_forward(on_value), value_type{})
62 {
63 }
64
69 default_button_delegate(auto &&value) noexcept requires(can_make_defaults) :
70 default_button_delegate(hi_forward(value), value_type{1}, value_type{})
71 {
72 }
73
75 [[nodiscard]] button_state state(abstract_button_widget const &sender) const noexcept override
76 {
77 if (*value == *on_value) {
78 return button_state::on;
79 } else if (*value == *off_value) {
80 return button_state::off;
81 } else {
82 return button_state::other;
83 }
84 }
85
86 void activate(abstract_button_widget &sender) noexcept override
87 {
88 if constexpr (button_type == button_type::toggle) {
89 if (*value == *off_value) {
90 value = *on_value;
91 } else {
92 value = *off_value;
93 }
94 } else if constexpr (button_type == button_type::radio) {
95 value = *on_value;
96 }
97 }
99private:
100 typename decltype(value)::token_type _value_cbt;
101 typename decltype(on_value)::token_type _on_value_cbt;
102 typename decltype(off_value)::token_type _off_value_cbt;
103};
104
105template<button_type ButtonType, typename Value, typename... Args>
106default_button_delegate(Value &&, Args &&...)
107 -> default_button_delegate<ButtonType, observable_argument_t<std::remove_cvref_t<Value>>>;
108
109template<button_type ButtonType, typename Value, typename... Args>
110std::unique_ptr<button_delegate> make_unique_default_button_delegate(Value &&value, Args &&...args) noexcept
111{
112 using value_type = observable_argument_t<std::remove_cvref_t<Value>>;
113 return std::make_unique<default_button_delegate<ButtonType, value_type>>(
114 std::forward<Value>(value), std::forward<Args>(args)...);
115}
116
117} // namespace hi::inline v1
#define hi_forward(x)
Forward a value, based on the decltype of the value.
Definition required.hpp:29
button_state
The state of a button.
Definition button_state.hpp:13
button_type
The type of button.
Definition button_type.hpp:13
An observable value.
Definition observable.hpp:356
Definition abstract_button_widget.hpp:23
Definition button_delegate.hpp:14
A default button delegate.
Definition default_button_delegate.hpp:25
default_button_delegate(auto &&value, auto &&on_value, auto &&off_value) noexcept
Construct a delegate.
Definition default_button_delegate.hpp:44
default_button_delegate(auto &&value, auto &&on_value) noexcept
Construct a delegate.
Definition default_button_delegate.hpp:59
default_button_delegate(auto &&value) noexcept
Construct a delegate.
Definition default_button_delegate.hpp:69