HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
checkbox_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 "../telemetry/telemetry.hpp"
13#include "../macros.hpp"
14
15namespace hi { inline namespace v1 {
16
44public:
46 using delegate_type = typename super::delegate_type;
47
66
80 button_widget_attribute auto&&...attributes) noexcept requires requires
81 {
82 make_default_toggle_button_delegate(hi_forward(value));
83 } : checkbox_widget(parent, make_default_toggle_button_delegate(hi_forward(value)), hi_forward(attributes)...) {}
84
96 template<
99 button_widget_attribute... Attributes>
100 checkbox_widget(widget *parent, Value&& value, OnValue&& on_value, Attributes&&...attributes) noexcept
101 requires requires
102 {
103 make_default_toggle_button_delegate(hi_forward(value), hi_forward(on_value));
104 } :
106 parent,
107 make_default_toggle_button_delegate(hi_forward(value), hi_forward(on_value)),
108 hi_forward(attributes)...)
109 {
110 }
111
124 template<
128 button_widget_attribute... Attributes>
130 widget *parent,
131 Value&& value,
132 OnValue&& on_value,
133 OffValue&& off_value,
134 Attributes&&...attributes) noexcept requires requires
135 {
136 make_default_toggle_button_delegate(hi_forward(value), hi_forward(on_value), hi_forward(off_value));
137 } :
139 parent,
140 make_default_toggle_button_delegate(hi_forward(value), hi_forward(on_value), hi_forward(off_value)),
141 hi_forward(attributes)...)
142 {
143 }
144
146 [[nodiscard]] box_constraints update_constraints() noexcept override
147 {
148 _label_constraints = super::update_constraints();
149
150 _button_size = {theme().size(), theme().size()};
151 hilet extra_size = extent2{theme().margin<float>() + _button_size.width(), 0};
152
153 auto constraints = max(_label_constraints + extra_size, _button_size);
154 constraints.margins = theme().margin();
155 constraints.alignment = *alignment;
156 return constraints;
157 }
158
159 void set_layout(widget_layout const& context) noexcept override
160 {
161 if (compare_store(_layout, context)) {
162 auto alignment_ = os_settings::left_to_right() ? *alignment : mirror(*alignment);
163
165 _button_rectangle = align(context.rectangle(), _button_size, alignment_);
166 } else {
167 hi_not_implemented();
168 }
169
170 hilet label_width = context.width() - (_button_rectangle.width() + theme().margin<float>());
172 hilet label_left = _button_rectangle.right() + theme().margin<float>();
173 hilet label_rectangle = aarectangle{label_left, 0.0f, label_width, context.height()};
174 _on_label_shape = _off_label_shape = _other_label_shape =
175 box_shape(_label_constraints, label_rectangle, theme().baseline_adjustment());
176
178 hilet label_rectangle = aarectangle{0.0f, 0.0f, label_width, context.height()};
179 _on_label_shape = _off_label_shape = _other_label_shape =
180 box_shape(_label_constraints, label_rectangle, theme().baseline_adjustment());
181 } else {
182 hi_not_implemented();
183 }
184
185 _check_glyph = find_glyph(elusive_icon::Ok);
186 hilet check_glyph_bb = _check_glyph.get_metrics().bounding_rectangle * theme().icon_size();
187 _check_glyph_rectangle = align(_button_rectangle, check_glyph_bb, alignment::middle_center());
188
189 _minus_glyph = find_glyph(elusive_icon::Minus);
190 hilet minus_glyph_bb = _minus_glyph.get_metrics().bounding_rectangle * theme().icon_size();
191 _minus_glyph_rectangle = align(_button_rectangle, minus_glyph_bb, alignment::middle_center());
192 }
193 super::set_layout(context);
194 }
195
196 void draw(draw_context const& context) noexcept override
197 {
198 if (*mode > widget_mode::invisible and overlaps(context, layout())) {
199 draw_check_box(context);
200 draw_check_mark(context);
201 draw_button(context);
202 }
203 }
205private:
206 box_constraints _label_constraints;
207
208 extent2 _button_size;
209 aarectangle _button_rectangle;
210 font_book::font_glyph_type _check_glyph;
211 aarectangle _check_glyph_rectangle;
212 font_book::font_glyph_type _minus_glyph;
213 aarectangle _minus_glyph_rectangle;
214
215 void draw_check_box(draw_context const& context) noexcept
216 {
217 context.draw_box(
218 layout(), _button_rectangle, background_color(), focus_color(), theme().border_width(), border_side::inside);
219 }
220
221 void draw_check_mark(draw_context const& context) noexcept
222 {
223 auto state_ = state();
224
225 // Checkmark or tristate.
226 if (state_ == hi::button_state::on) {
227 context.draw_glyph(layout(), translate_z(0.1f) * _check_glyph_rectangle, _check_glyph, accent_color());
228
229 } else if (state_ == hi::button_state::off) {
230 ;
231
232 } else {
233 context.draw_glyph(layout(), translate_z(0.1f) * _minus_glyph_rectangle, _minus_glyph, accent_color());
234 }
235 }
236};
237
238}} // 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_toggle_button_delegate(auto &&value, auto &&...args) noexcept
Make a shared pointer to a toggle-button delegate.
Definition button_delegate.hpp:245
@ invisible
The widget is invisible.
DOXYGEN BUG.
Definition algorithm.hpp:16
hi_export auto find_glyph(font const &font, grapheme grapheme) noexcept
Find a glyph using the given code-point.
Definition font_book.hpp:437
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 GUI widget that permits the user to make a binary choice.
Definition checkbox_widget.hpp:43
checkbox_widget(widget *parent, std::shared_ptr< delegate_type > delegate, button_widget_attribute auto &&...attributes) noexcept
Construct a checkbox widget.
Definition checkbox_widget.hpp:57
checkbox_widget(widget *parent, Value &&value, OnValue &&on_value, Attributes &&...attributes) noexcept
Construct a checkbox widget with a default button delegate.
Definition checkbox_widget.hpp:100
checkbox_widget(widget *parent, Value &&value, OnValue &&on_value, OffValue &&off_value, Attributes &&...attributes) noexcept
Construct a checkbox widget with a default button delegate.
Definition checkbox_widget.hpp:129
checkbox_widget(widget *parent, different_from< std::shared_ptr< delegate_type > > auto &&value, button_widget_attribute auto &&...attributes) noexcept
Construct a checkbox widget with a default button delegate.
Definition checkbox_widget.hpp:77
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
observer< widget_mode > mode
The widget mode.
Definition widget.hpp:42
Definition concepts.hpp:54
Definition abstract_button_widget.hpp:27
T align(T... args)
T max(T... args)
T move(T... args)