HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
radio_button_widget.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
12#include "../macros.hpp"
13
14namespace hi { inline namespace v1 {
15
44public:
46 using delegate_type = typename super::delegate_type;
47
66
79 template<
83 radio_button_widget(widget *parent, Value&& value, OnValue&& on_value, Attributes&&...attributes) noexcept
84 requires requires
85 {
86 make_default_radio_button_delegate(hi_forward(value), hi_forward(on_value));
87 } :
89 parent,
90 make_default_radio_button_delegate(hi_forward(value), hi_forward(on_value)),
91 hi_forward(attributes)...)
92 {
93 }
94
96 [[nodiscard]] box_constraints update_constraints() noexcept override
97 {
98 _label_constraints = super::update_constraints();
99
100 // Make room for button and margin.
101 _button_size = {theme().size(), theme().size()};
102 hilet extra_size = extent2{theme().margin<float>() + _button_size.width(), 0.0f};
103
104 auto constraints = max(_label_constraints + extra_size, _button_size);
105 constraints.margins = theme().margin();
106 constraints.alignment = *alignment;
107 return constraints;
108 }
109
110 void set_layout(widget_layout const& context) noexcept override
111 {
112 if (compare_store(_layout, context)) {
113 auto alignment_ = os_settings::left_to_right() ? *alignment : mirror(*alignment);
114
116 _button_rectangle = align(context.rectangle(), _button_size, alignment_);
117 } else {
118 hi_not_implemented();
119 }
120
121 hilet label_width = context.width() - (_button_rectangle.width() + theme().margin<float>());
123 hilet label_left = _button_rectangle.right() + theme().margin<float>();
124 hilet label_rectangle = aarectangle{label_left, 0.0f, label_width, context.height()};
125 _on_label_shape = _off_label_shape = _other_label_shape =
126 box_shape{_label_constraints, label_rectangle, theme().baseline_adjustment()};
127
129 hilet label_rectangle = aarectangle{0.0f, 0.0f, label_width, context.height()};
130 _on_label_shape = _off_label_shape = _other_label_shape =
131 box_shape{_label_constraints, label_rectangle, theme().baseline_adjustment()};
132
133 } else {
134 hi_not_implemented();
135 }
136
137 _button_circle = circle{_button_rectangle};
138
139 _pip_circle = align(_button_rectangle, circle{theme().size() * 0.5f - 3.0f}, alignment::middle_center());
140 }
141 super::set_layout(context);
142 }
143
144 void draw(draw_context const& context) noexcept override
145 {
146 if (*mode > widget_mode::invisible and overlaps(context, layout())) {
147 draw_radio_button(context);
148 draw_radio_pip(context);
149 draw_button(context);
150 }
151 }
153private:
154 constexpr static std::chrono::nanoseconds _animation_duration = std::chrono::milliseconds(150);
155
156 box_constraints _label_constraints;
157
158 extent2 _button_size;
159 aarectangle _button_rectangle;
160 circle _button_circle;
161
162 animator<float> _animated_value = _animation_duration;
163 circle _pip_circle;
164
165 void draw_radio_button(draw_context const& context) noexcept
166 {
167 context.draw_circle(
168 layout(), _button_circle * 1.02f, background_color(), focus_color(), theme().border_width(), border_side::inside);
169 }
170 void draw_radio_pip(draw_context const& context) noexcept
171 {
172 _animated_value.update(state() == button_state::on ? 1.0f : 0.0f, context.display_time_point);
173 if (_animated_value.is_animating()) {
175 }
176
177 // draw pip
178 auto float_value = _animated_value.current_value();
179 if (float_value > 0.0) {
180 context.draw_circle(layout(), _pip_circle * 1.02f * float_value, accent_color());
181 }
182 }
183};
184
185}} // namespace hi::v1
Defines abstract_button_widget.
@ right
Align the text to the right side.
@ left
Align the text to the left side.
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
@ on
The 'on' state of a button.
@ invisible
The widget is invisible.
DOXYGEN BUG.
Definition algorithm.hpp:16
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
@ inside
The border is drawn inside the edge of a quad.
bool compare_store(T &lhs, U &&rhs) noexcept
Compare then store if there was a change.
Definition misc.hpp:56
constexpr horizontal_alignment mirror(horizontal_alignment const &rhs) noexcept
Mirror the horizontal alignment.
Definition alignment.hpp:203
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Horizontal/Vertical alignment combination.
Definition alignment.hpp:242
constexpr float & width() noexcept
Access the x-as-width element from the extent.
Definition extent2.hpp:104
widget_intf * parent
Pointer to the parent widget.
Definition widget_intf.hpp:28
2D constraints.
Definition box_constraints.hpp:25
Base class for implementing button widgets.
Definition abstract_button_widget.hpp:33
std::shared_ptr< delegate_type > delegate
The delegate that controls the button widget.
Definition abstract_button_widget.hpp:40
button_state state() const noexcept
Get the current state of the button.
Definition abstract_button_widget.hpp:88
observer< alignment > alignment
The alignment of the button and on/off/other label.
Definition abstract_button_widget.hpp:56
A button delegate controls the state of a button widget.
Definition button_delegate.hpp:45
A graphical control element that allows the user to choose only one of a predefined set of mutually e...
Definition radio_button_widget.hpp:43
radio_button_widget(widget *parent, std::shared_ptr< delegate_type > delegate, button_widget_attribute auto &&...attributes) noexcept
Construct a radio button widget.
Definition radio_button_widget.hpp:57
radio_button_widget(widget *parent, Value &&value, OnValue &&on_value, Attributes &&...attributes) noexcept
Construct a radio button widget with a default button delegate.
Definition radio_button_widget.hpp:83
An interactive graphical object as part of the user-interface.
Definition widget.hpp:37
widget_layout const & layout() const noexcept override
Get the current layout for this widget.
Definition widget.hpp:169
void request_redraw() const noexcept override
Request the widget to be redrawn on the next frame.
Definition widget.hpp:189
observer< widget_mode > mode
The widget mode.
Definition widget.hpp:42
Definition concepts.hpp:54
True if T is a forwarded type of Forward.
Definition concepts.hpp:131
Definition abstract_button_widget.hpp:27
T align(T... args)
T max(T... args)
T move(T... args)