7#include "abstract_toggle_button_widget.hpp"
8#include "../stencils/label_stencil.hpp"
9#include "../GUI/draw_context.hpp"
10#include "../text/font_book.hpp"
11#include "../observable.hpp"
12#include "../label.hpp"
29 using value_type =
typename super::value_type;
35 template<
typename Value = observable<value_type>>
39 value_type true_value,
40 value_type false_value,
41 Value &&value = {})
noexcept :
47 std::forward<Value>(value))
51 void init() noexcept
override
53 _true_label_callback = true_label.subscribe([
this](
auto...) {
54 this->_request_reconstrain =
true;
56 _false_label_callback = false_label.subscribe([
this](
auto...) {
57 this->_request_reconstrain =
true;
59 _other_label_callback = other_label.subscribe([
this](
auto...) {
60 this->_request_reconstrain =
true;
69 _true_label_stencil = stencil::make_unique(alignment::top_left, *true_label, theme::global->labelStyle);
70 _false_label_stencil = stencil::make_unique(alignment::top_left, *false_label, theme::global->labelStyle);
71 _other_label_stencil = stencil::make_unique(alignment::top_left, *other_label, theme::global->labelStyle);
74 {_true_label_stencil->preferred_extent().height(),
75 _false_label_stencil->preferred_extent().height(),
76 _other_label_stencil->preferred_extent().height(),
77 theme::global->smallSize});
79 ttlet minimum_width_of_labels =
std::max(
80 {_true_label_stencil->preferred_extent().width(),
81 _false_label_stencil->preferred_extent().width(),
82 _other_label_stencil->preferred_extent().width()});
83 ttlet minimum_width = theme::global->smallSize + theme::global->margin + minimum_width_of_labels;
85 this->_preferred_size = interval_extent2::make_minimum(minimum_width, minimum_height);
97 need_layout |= std::exchange(this->_request_relayout,
false);
99 _checkbox_rectangle =
aarectangle{0.0f,
std::round(this->
base_line() - theme::global->smallSize * 0.5f), theme::global->smallSize, theme::global->smallSize};
101 ttlet label_x = _checkbox_rectangle.right() + theme::global->margin;
103 _true_label_stencil->set_layout_parameters(_label_rectangle, this->
base_line());
104 _false_label_stencil->set_layout_parameters(_label_rectangle, this->
base_line());
105 _other_label_stencil->set_layout_parameters(_label_rectangle, this->
base_line());
107 _check_glyph = to_font_glyph_ids(elusive_icon::Ok);
109 _check_glyph_rectangle =
110 align(_checkbox_rectangle, scale(check_glyph_bb, theme::global->small_icon_size), alignment::middle_center);
112 _minus_glyph = to_font_glyph_ids(elusive_icon::Minus);
114 _minus_glyph_rectangle =
115 align(_checkbox_rectangle, scale(minus_glyph_bb, theme::global->small_icon_size), alignment::middle_center);
125 if (overlaps(context, this->_clipping_rectangle)) {
126 draw_check_box(context);
127 draw_check_mark(context);
135 typename decltype(true_label)::callback_ptr_type _true_label_callback;
136 typename decltype(false_label)::callback_ptr_type _false_label_callback;
137 typename decltype(other_label)::callback_ptr_type _other_label_callback;
153 void draw_check_box(
draw_context const &context)
noexcept
157 context.draw_box_with_border_inside(_checkbox_rectangle, this->background_color(), this->focus_color());
160 void draw_check_mark(draw_context context)
noexcept
165 if (this->value == this->true_value) {
166 context.draw_glyph(_check_glyph, translate_z(0.1f) * _check_glyph_rectangle, this->accent_color());
167 }
else if (this->value == this->false_value) {
170 context.draw_glyph(_minus_glyph, translate_z(0.1f) * _minus_glyph_rectangle, this->accent_color());
174 void draw_label(draw_context context)
noexcept
178 ttlet &labelCell = this->value == this->true_value ?
179 _true_label_stencil :
180 this->value == this->false_value ? _false_label_stencil : _other_label_stencil;
182 labelCell->draw(context, this->label_color());
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:18
Draw context for drawing using the TTauri shaders.
Definition draw_context.hpp:33
Definition gui_window.hpp:37
static aarectangle getBoundingBox(font_glyph_ids const &glyphs) noexcept
Get the bounding box, including draw border of a glyph.
Definition observable.hpp:20
Definition font_glyph_ids.hpp:78
int recurse_lock_count() const noexcept
This function should be used in tt_axiom() to check if the lock is held by current thread.
Definition unfair_recursive_mutex.hpp:60
An abstract toggle button widget.
Definition abstract_toggle_button_widget.hpp:15
A checkbox widget.
Definition checkbox_widget.hpp:26
void update_layout(hires_utc_clock::time_point displayTimePoint, bool need_layout) noexcept override
Update the internal layout of the widget.
Definition checkbox_widget.hpp:93
void draw(draw_context context, hires_utc_clock::time_point display_time_point) noexcept override
Draw the widget.
Definition checkbox_widget.hpp:121
bool update_constraints(hires_utc_clock::time_point display_time_point, bool need_reconstrain) noexcept override
Update the constraints of the widget.
Definition checkbox_widget.hpp:64
void init() noexcept override
Should be called right after allocating and constructing a widget.
Definition checkbox_widget.hpp:51
virtual void update_layout(hires_utc_clock::time_point display_time_point, bool need_layout) noexcept
Update the internal layout of the widget.
aarectangle rectangle() const noexcept
Get the rectangle in local coordinates.
Definition widget.hpp:342
gui_window & window
Convenient reference to the Window.
Definition widget.hpp:101
virtual float base_line() const noexcept
Return the base-line where the text should be located.
Definition widget.hpp:351
virtual void draw(draw_context context, hires_utc_clock::time_point display_time_point) noexcept
Draw the widget.
Definition widget.hpp:462
virtual bool update_constraints(hires_utc_clock::time_point display_time_point, bool need_reconstrain) noexcept
Update the constraints of the widget.
abstract_container_widget const & parent() const noexcept
Get a reference to the parent.