27class window_traffic_lights_widget final :
public widget {
30 constexpr static auto prefix = Name /
"traffic-lights";
32 window_traffic_lights_widget(widget *
parent) noexcept : super(
parent) {}
37 if (operating_system::current == operating_system::windows) {
38 hilet theme_size =
theme<prefix /
"windows.size",
int>{}(
this);
39 hilet size =
extent2{theme_size * 3, theme_size};
40 return {size, size, size};
42 }
else if (operating_system::current == operating_system::macos) {
43 hilet theme_size =
theme<prefix /
"macos.size",
int>{}(
this);
44 hilet margin =
theme<prefix /
"margin",
int>{}(
this);
46 hilet size =
extent2{theme_size * 3 + 2 * margin + 2 * spacing, theme_size + 2 * spacing};
47 return {size, size, size};
54 void set_layout(
widget_layout const& context)
noexcept override
57 auto extent = context.size();
58 auto y = context.height() - extent.height();
60 if (operating_system::current == operating_system::windows) {
62 aarectangle{point2(extent.width() * 2 / 3, y),
extent2{extent.width() * 1 / 3, extent.height()}};
65 aarectangle{point2(extent.width() * 1 / 3, y),
extent2{extent.width() * 1 / 3, extent.height()}};
67 minimizeRectangle = aarectangle{point2(0, y),
extent2{extent.width() * 1 / 3, extent.height()}};
69 }
else if (operating_system::current == operating_system::macos) {
70 hilet size =
theme<prefix /
"macos.size",
int>{}(
this);
71 hilet margin =
theme<prefix /
"margin",
int>{}(
this);
74 closeRectangle = aarectangle{point2{margin,
std::floor((extent.height() - size) / 2.0f)},
extent2{size, size}};
77 aarectangle{point2{margin + size + spacing,
std::floor((extent.height() - size) / 2.0f)},
extent2{size, size}};
79 maximizeRectangle = aarectangle{
80 point2{margin + size + spacing + size + spacing,
std::floor((extent.height() - size) / 2.0f)},
extent2{size, size}};
85 closeWindowGlyph = find_glyph(hikogui_icon::CloseWindow);
86 minimizeWindowGlyph = find_glyph(hikogui_icon::MinimizeWindow);
88 if (operating_system::current == operating_system::windows) {
89 maximizeWindowGlyph = find_glyph(hikogui_icon::MaximizeWindowMS);
90 restoreWindowGlyph = find_glyph(hikogui_icon::RestoreWindowMS);
92 }
else if (operating_system::current == operating_system::macos) {
93 maximizeWindowGlyph = find_glyph(hikogui_icon::MaximizeWindowMacOS);
94 restoreWindowGlyph = find_glyph(hikogui_icon::RestoreWindowMacOS);
99 hilet glyph_size = operating_system::current == operating_system::macos ?
100 theme<prefix /
"macos.icon.size",
float>{}(
this) :
101 theme<prefix /
"windows.icon.size",
float>{}(
this);
103 hilet closeWindowGlyphBB = closeWindowGlyph.get_bounding_rectangle() * glyph_size;
104 hilet minimizeWindowGlyphBB = minimizeWindowGlyph.get_bounding_rectangle() * glyph_size;
105 hilet maximizeWindowGlyphBB = maximizeWindowGlyph.get_bounding_rectangle() * glyph_size;
106 hilet restoreWindowGlyphBB = restoreWindowGlyph.get_bounding_rectangle() * glyph_size;
108 closeWindowGlyphRectangle = align(closeRectangle, closeWindowGlyphBB, alignment::middle_center());
109 minimizeWindowGlyphRectangle = align(minimizeRectangle, minimizeWindowGlyphBB, alignment::middle_center());
110 maximizeWindowGlyphRectangle = align(maximizeRectangle, maximizeWindowGlyphBB, alignment::middle_center());
111 restoreWindowGlyphRectangle = align(maximizeRectangle, restoreWindowGlyphBB, alignment::middle_center());
118 if (operating_system::current == operating_system::macos) {
121 }
else if (operating_system::current == operating_system::windows) {
122 drawWindows(context);
130 bool handle_event(
gui_event const& event)
noexcept override
132 switch (event.
type()) {
133 case gui_event_type::mouse_move:
134 case gui_event_type::mouse_drag:
137 auto state_has_changed =
false;
141 if (state_has_changed) {
147 case gui_event_type::mouse_exit:
149 hoverMinimize =
false;
150 hoverMaximize =
false;
154 case gui_event_type::mouse_down:
159 }
else if (minimizeRectangle.contains(event.
mouse().
position)) {
160 pressedMinimize =
true;
162 }
else if (maximizeRectangle.contains(event.
mouse().
position)) {
163 pressedMaximize =
true;
170 case gui_event_type::mouse_up:
172 pressedClose =
false;
173 pressedMinimize =
false;
174 pressedMaximize =
false;
180 }
else if (minimizeRectangle.contains(event.
mouse().
position)) {
183 }
else if (maximizeRectangle.contains(event.
mouse().
position)) {
184 switch (layout.window_size_state) {
185 case gui_window_size::normal:
188 case gui_window_size::maximized:
204 [[nodiscard]] hitbox hitbox_test(point2 position)
const noexcept override
209 (closeRectangle.contains(position) or minimizeRectangle.contains(position) or maximizeRectangle.contains(position))) {
210 return hitbox{
id, layout.elevation, hitbox_type::button};
217 aarectangle closeRectangle;
218 aarectangle minimizeRectangle;
219 aarectangle maximizeRectangle;
221 font_book::font_glyph_type closeWindowGlyph;
222 font_book::font_glyph_type minimizeWindowGlyph;
223 font_book::font_glyph_type maximizeWindowGlyph;
224 font_book::font_glyph_type restoreWindowGlyph;
226 aarectangle closeWindowGlyphRectangle;
227 aarectangle minimizeWindowGlyphRectangle;
228 aarectangle maximizeWindowGlyphRectangle;
229 aarectangle restoreWindowGlyphRectangle;
231 bool hoverClose =
false;
232 bool hoverMinimize =
false;
233 bool hoverMaximize =
false;
235 bool pressedClose =
false;
236 bool pressedMinimize =
false;
237 bool pressedMaximize =
false;
245 corner_radii{closeRectangle.height() / 2.0f});
251 corner_radii{minimizeRectangle.height() / 2.0f});
257 corner_radii{maximizeRectangle.height() / 2.0f});
262 translate_z(0.1f) * narrow_cast<aarectangle>(closeWindowGlyphRectangle),
267 translate_z(0.1f) * narrow_cast<aarectangle>(minimizeWindowGlyphRectangle),
271 if (layout.window_size_state == gui_window_size::maximized) {
274 translate_z(0.1f) * narrow_cast<aarectangle>(restoreWindowGlyphRectangle),
280 translate_z(0.1f) * narrow_cast<aarectangle>(maximizeWindowGlyphRectangle),
295 translate_z(0.1f) * narrow_cast<aarectangle>(closeWindowGlyphRectangle),
301 translate_z(0.1f) * narrow_cast<aarectangle>(minimizeWindowGlyphRectangle),
305 if (layout.window_size_state == gui_window_size::maximized) {
308 translate_z(0.1f) * narrow_cast<aarectangle>(restoreWindowGlyphRectangle),
314 translate_z(0.1f) * narrow_cast<aarectangle>(maximizeWindowGlyphRectangle),