35 constexpr static auto prefix = Name /
"radio-menu";
52 this->alignment = alignment::middle_flush();
53 this->set_attributes<0>(
hi_forward(attributes)...);
69 different_from<std::shared_ptr<delegate_type>> Value,
70 forward_of<observer<observer_decay_t<Value>>> OnValue,
85 _label_constraints = _label_widget.update_constraints();
86 _mark_label_constraints = _mark_label_widget.update_constraints();
87 _shortcut_label_constraints = _shortcut_label_widget.update_constraints();
89 auto constraints = max(_label_constraints, _mark_label_constraints, _shortcut_label_constraints);
90 inplace_max(constraints.margins, theme<prefix>.margin(
this));
91 _padding = constraints.margins;
95 constraints.margins.left() +
96 theme<prefix /
"mark">.width(
this) +
97 _label_constraints.margins.left() +
99 _label_constraints.margins.right() +
100 theme<prefix /
"short-cut">.width(
this) +
101 constraints.margins.right();
106 constraints.minimum.width() = _label_constraints.minimum.
width() + extra_width;
107 constraints.preferred.width() = _label_constraints.preferred.
width() + extra_width;
108 constraints.maximum.width() = _label_constraints.maximum.
width() + extra_width;
109 constraints.minimum.height() += constraints.margins.top() + constraints.margins.bottom();
110 constraints.preferred.height() += constraints.margins.top() + constraints.margins.bottom();
111 constraints.maximum.height() += constraints.margins.top() + constraints.margins.bottom();
112 constraints.margins = {};
116 void set_layout(widget_layout
const& context)
noexcept override
119 hilet outline = context.rectangle() - _padding;
121 if (os_settings::left_to_right()) {
122 hilet mark_outline_size =
extent2{
theme<prefix /
"mark">.width(), outline.height()};
123 hilet shortcut_outline_size =
extent2{
theme<prefix /
"short-cut">.width(), outline.height()};
125 hilet mark_shape = aarectangle{get<0>(outline), get<0>(outline) + mark_outline_size};
126 hilet shortcut_shape = aarectangle{get<3>(outline) - shortcut_outline_size, get<3>(outline)};
127 hilet label_shape = aarectangle{
128 point2{get<1>(mark_outline).
x() + _label_constraint.margin.left(), get<1>(mark_outline).y()},
129 point2{get<2>(shortcut_outline).
x() - _label_constraint.margin.right(), get<2>(shortcut_outline.y())}};
131 _mark_widget->set_layout(context.transform(mark_shape, 0.1f));
132 _shortcut_widget->set_layout(context.transform(shortcut_shape, 0.1f));
133 _label_widget->set_layout(context.transform(label_shape, 0.1f));
136 _short_cut_rectangle =
align(inside_rectangle, _short_cut_size, alignment::middle_left());
137 _check_rectangle =
align(inside_rectangle, _check_size, alignment::middle_right());
138 hilet label_rectangle = aarectangle{
139 point2{_short_cut_rectangle.right() + spacing, 0},
140 point2{_check_rectangle.left() - spacing, context.height()}};
141 this->_on_label_shape = this->_off_label_shape = this->_other_label_shape =
142 box_shape{_label_constraints, label_rectangle, cap_height};
147 void draw(widget_draw_context& context)
noexcept override
150 draw_button(context);
153 _label_widget->draw(context);
156 [[nodiscard]] generator<widget const&> children(
bool include_invisible)
const noexcept override
158 co_yield *_label_widget;
161 [[nodiscard]] hitbox hitbox_test(point2 position)
const noexcept final
166 return {
id, layout.elevation, hitbox_type::button};
172 [[nodiscard]]
bool accepts_keyboard_focus(keyboard_focus_group group)
const noexcept override
177 void activate() noexcept
180 delegate->activate(*
this);
181 this->_state_changed();
184 bool handle_event(gui_event
const& event)
noexcept override
188 switch (event.type()) {
191 this->process_event(gui_event::window_set_keyboard_target(
192 nullptr, keyboard_focus_group::menu, keyboard_focus_direction::forward));
199 this->process_event(gui_event::window_set_keyboard_target(
200 nullptr, keyboard_focus_group::menu, keyboard_focus_direction::backward));
208 this->process_event(gui_event::window_set_keyboard_target(
209 nullptr, keyboard_focus_group::normal, keyboard_focus_direction::forward));
210 this->process_event(gui_event::window_set_keyboard_target(
211 nullptr, keyboard_focus_group::normal, keyboard_focus_direction::backward));
224 box_constraints _label_constraints;
226 notifier<>::callback_token _delegate_cbt;
228 font_book::font_glyph_type _check_glyph;
229 aarectangle _check_glyph_rectangle;
231 void draw_button(widget_draw_context& context)
noexcept
235 this->layout.rectangle(),
236 theme<prefix>.background_color(
this),
237 theme<prefix>.border_color(
this),
238 theme<prefix>.border_width(
this),
242 void draw_check(widget_draw_context& context)
noexcept
247 translate_z(0.1f) * _check_glyph_rectangle,
250 theme<prefix>.fill_color(
this));