38 template<forward_of<observer<label>> Title>
41 _toolbar = std::make_unique<toolbar_widget>(
this);
43#if HI_OPERATING_SYSTEM == HI_OS_WINDOWS
45 this->_system_menu->icon = this->title.
sub<
"icon">();
48#elif HI_OPERATING_SYSTEM == HI_OS_MACOS
52#error "Not implemented"
55 _content = std::make_unique<grid_widget>(
this);
64 hi_axiom(loop::main().on_thread());
65 return theme().color(semantic_color::fill, _layout.layer);
74 hi_axiom(loop::main().on_thread());
75 hi_assert_not_null(_content);
86 hi_axiom(loop::main().on_thread());
87 hi_assert_not_null(_toolbar);
99 hi_assert_not_null(_content);
100 hi_assert_not_null(_toolbar);
103 _content_constraints = _content->update_constraints();
104 _toolbar_constraints = _toolbar->update_constraints();
106 auto r = box_constraints{};
108 _toolbar_constraints.margins.left() + _toolbar_constraints.minimum.
width() + _toolbar_constraints.margins.right(),
109 _content_constraints.margins.left() + _content_constraints.minimum.
width() + _content_constraints.margins.right());
111 _toolbar_constraints.margins.left() + _toolbar_constraints.preferred.
width() + _toolbar_constraints.margins.right(),
112 _content_constraints.margins.left() + _content_constraints.preferred.
width() + _content_constraints.margins.right());
114 _toolbar_constraints.margins.left() + _toolbar_constraints.maximum.
width() + _toolbar_constraints.margins.right(),
115 _content_constraints.margins.left() + _content_constraints.maximum.
width() + _content_constraints.margins.right());
119 _toolbar_constraints.margins.top() +
120 _toolbar_constraints.preferred.
height() +
121 std::max(_toolbar_constraints.margins.bottom(), _content_constraints.margins.top()) +
122 _content_constraints.minimum.
height() +
123 _content_constraints.margins.bottom();
124 r.preferred.height() =
125 _toolbar_constraints.margins.top() +
126 _toolbar_constraints.preferred.
height() +
127 std::max(_toolbar_constraints.margins.bottom(), _content_constraints.margins.top()) +
128 _content_constraints.preferred.
height() +
129 _content_constraints.margins.bottom();
131 _toolbar_constraints.margins.top() +
132 _toolbar_constraints.preferred.
height() +
133 std::max(_toolbar_constraints.margins.bottom(), _content_constraints.margins.top()) +
134 _content_constraints.maximum.
height() +
135 _content_constraints.margins.bottom();
140 inplace_max(r.minimum.width(), os_settings::minimum_window_width());
141 inplace_max(r.minimum.height(), os_settings::minimum_window_height());
143 inplace_clamp(r.maximum.width(), r.minimum.width(), os_settings::maximum_window_width());
144 inplace_clamp(r.maximum.height(), r.minimum.height(), os_settings::maximum_window_height());
146 inplace_clamp(r.preferred.width(), r.minimum.width(), r.maximum.width());
147 inplace_clamp(r.preferred.height(), r.minimum.height(), r.maximum.height());
149 _can_resize_width = r.minimum.width() != r.maximum.width();
150 _can_resize_height = r.minimum.height() != r.maximum.height();
155 void set_layout(widget_layout
const&
context)
noexcept override
159 auto const between_margin =
std::max(_toolbar_constraints.margins.bottom(), _content_constraints.margins.top());
163 _toolbar_constraints.margins.left(),
context.height() -
toolbar_height - _toolbar_constraints.margins.top()},
165 context.width() - _toolbar_constraints.margins.right(),
166 context.height() - _toolbar_constraints.margins.top()}};
167 _toolbar_shape = box_shape{_toolbar_constraints,
toolbar_rectangle, theme().baseline_adjustment()};
170 point2{_content_constraints.margins.left(), _content_constraints.margins.bottom()},
172 _content_shape = box_shape{_content_constraints,
content_rectangle, theme().baseline_adjustment()};
174 _toolbar->set_layout(
context.transform(_toolbar_shape));
175 _content->set_layout(
context.transform(_content_shape));
177 void draw(draw_context
const&
context)
noexcept override
186 [[
nodiscard]] hitbox hitbox_test(point2 position)
const noexcept override
190 hi_axiom(loop::main().on_thread());
192 auto r = _toolbar->hitbox_test_from_parent(position);
193 r = _content->hitbox_test_from_parent(position, r);
202 if (_can_resize_width
and _can_resize_height) {
203 return {
id, _layout.elevation, hitbox_type::bottom_left_resize_corner};
204 }
else if (_can_resize_width) {
205 return {
id, _layout.elevation, hitbox_type::left_resize_border};
206 }
else if (_can_resize_height) {
207 return {
id, _layout.elevation, hitbox_type::bottom_resize_border};
210 if (_can_resize_width
and _can_resize_height) {
211 return {
id, _layout.elevation, hitbox_type::bottom_right_resize_corner};
212 }
else if (_can_resize_width) {
213 return {
id, _layout.elevation, hitbox_type::right_resize_border};
214 }
else if (_can_resize_height) {
215 return {
id, _layout.elevation, hitbox_type::bottom_resize_border};
218 if (_can_resize_width
and _can_resize_height) {
219 return {
id, _layout.elevation, hitbox_type::top_left_resize_corner};
220 }
else if (_can_resize_width) {
221 return {
id, _layout.elevation, hitbox_type::left_resize_border};
222 }
else if (_can_resize_height) {
223 return {
id, _layout.elevation, hitbox_type::top_resize_border};
226 if (_can_resize_width
and _can_resize_height) {
227 return {
id, _layout.elevation, hitbox_type::top_right_resize_corner};
228 }
else if (_can_resize_width) {
229 return {
id, _layout.elevation, hitbox_type::right_resize_border};
230 }
else if (_can_resize_height) {
231 return {
id, _layout.elevation, hitbox_type::top_resize_border};
236 if (r.type != hitbox_type::scroll_bar) {
238 return {
id, _layout.elevation, hitbox_type::left_resize_border};
240 return {
id, _layout.elevation, hitbox_type::right_resize_border};
242 return {
id, _layout.elevation, hitbox_type::bottom_resize_border};
244 return {
id, _layout.elevation, hitbox_type::top_resize_border};
250 bool handle_event(gui_event
const&
event)
noexcept override
254 switch (
event.type()) {
255 case gui_toolbar_open:
257 gui_event::window_set_keyboard_target(
id, keyboard_focus_group::toolbar, keyboard_focus_direction::forward));
263 bool process_event(gui_event
const&
event)
const noexcept override
266 return _window->process_event(
event);
272 void set_window(gui_window* window)
noexcept override
276 _window->set_title(*title);
285 gui_window* _window =
nullptr;
288 box_constraints _content_constraints;
289 box_shape _content_shape;
292 box_constraints _toolbar_constraints;
293 box_shape _toolbar_shape;
295 mutable bool _can_resize_width;
296 mutable bool _can_resize_height;
298#if HI_OPERATING_SYSTEM == HI_OS_WINDOWS
299 system_menu_widget* _system_menu =
nullptr;