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 = super::update_constraints();
88 _short_cut_size = _check_size =
89 extent2i{theme<prefix>.line_height(
this), theme<prefix>.line_height(
this)};
93 theme<prefix>.margin_left(
this) + _check_size.
width() + theme<prefix>.spacing_horizontal(
this) +
94 theme<prefix>.spacing_horizontal(
this) + _short_cut_size.
width() + theme<prefix>.margin_right(
this),
95 theme<prefix>.margin_top(
this) + theme<prefix>.margin_bottom(
this)};
97 auto constraints = _label_constraints + extra_size;
98 constraints.margins = 0;
102 void set_layout(widget_layout
const& context)
noexcept override
105 hilet spacing = theme<prefix>.spacing_horizontal(
this);
106 hilet cap_height = theme<prefix>.cap_height(
this);
108 hilet inside_rectangle = context.rectangle() - spacing;
110 if (os_settings::left_to_right()) {
111 _check_rectangle =
align(inside_rectangle, _check_size, alignment::middle_left());
112 _short_cut_rectangle =
align(inside_rectangle, _short_cut_size, alignment::middle_right());
113 hilet label_rectangle = aarectanglei{
114 point2i{_check_rectangle.right() + spacing, 0},
115 point2i{_short_cut_rectangle.left() - spacing, context.height()}};
116 this->_on_label_shape = this->_off_label_shape = this->_other_label_shape =
117 box_shape{_label_constraints, label_rectangle, cap_height};
120 _short_cut_rectangle =
align(inside_rectangle, _short_cut_size, alignment::middle_left());
121 _check_rectangle =
align(inside_rectangle, _check_size, alignment::middle_right());
122 hilet label_rectangle = aarectanglei{
123 point2i{_short_cut_rectangle.right() + spacing, 0},
124 point2i{_check_rectangle.left() - spacing, context.height()}};
125 this->_on_label_shape = this->_off_label_shape = this->_other_label_shape =
126 box_shape{_label_constraints, label_rectangle, cap_height};
130 hilet check_glyph_bb =
131 narrow_cast<aarectanglei>(_check_glyph.get_bounding_rectangle() * theme<prefix>.line_height(
this));
132 _check_glyph_rectangle =
align(_check_rectangle, check_glyph_bb, alignment::middle_center());
135 super::set_layout(context);
138 void draw(widget_draw_context& context)
noexcept override
141 draw_menu_button(context);
142 draw_check_mark(context);
143 this->draw_button(context);
147 [[nodiscard]]
bool accepts_keyboard_focus(keyboard_focus_group group)
const noexcept override
152 bool handle_event(gui_event
const& event)
noexcept override
156 switch (event.type()) {
159 this->process_event(gui_event::window_set_keyboard_target(
160 nullptr, keyboard_focus_group::menu, keyboard_focus_direction::forward));
167 this->process_event(gui_event::window_set_keyboard_target(
168 nullptr, keyboard_focus_group::menu, keyboard_focus_direction::backward));
176 this->process_event(gui_event::window_set_keyboard_target(
177 nullptr, keyboard_focus_group::normal, keyboard_focus_direction::forward));
178 this->process_event(gui_event::window_set_keyboard_target(
179 nullptr, keyboard_focus_group::normal, keyboard_focus_direction::backward));
187 return super::handle_event(event);
191 box_constraints _label_constraints;
193 font_book::font_glyph_type _check_glyph;
195 aarectanglei _check_rectangle;
196 aarectanglei _check_glyph_rectangle;
198 aarectanglei _short_cut_rectangle;
200 void draw_menu_button(widget_draw_context& context)
noexcept
204 this->layout.rectangle(),
205 theme<prefix>.background_color(
this),
206 theme<prefix>.border_color(
this),
207 theme<prefix>.border_width(
this),
211 void draw_check_mark(widget_draw_context& context)
noexcept
214 if (*this->
state != hi::widget_state::off) {
217 translate_z(0.1f) * narrow_cast<aarectangle>(_check_glyph_rectangle),
219 theme<prefix>.fill_color(
this));