HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
widget.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2019-2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
9#pragma once
10
11#include "../GFX/draw_context.hpp"
12#include "../GUI/theme.hpp"
13#include "../GUI/hitbox.hpp"
14#include "../GUI/keyboard_focus_direction.hpp"
15#include "../GUI/keyboard_focus_group.hpp"
16#include "../GUI/gui_event.hpp"
17#include "../geometry/extent.hpp"
18#include "../geometry/axis_aligned_rectangle.hpp"
19#include "../geometry/transform.hpp"
20#include "../observer.hpp"
21#include "../chrono.hpp"
22#include "../generator.hpp"
24#include "widget_layout.hpp"
25#include "widget_mode.hpp"
26#include <memory>
27#include <vector>
28#include <string>
29#include <ranges>
30
31namespace hi { inline namespace v1 {
32class gui_window;
33class font_book;
34
44class widget {
45public:
48 gui_window& window;
49
53 widget *const parent;
54
58
62 observer<widget_mode> mode = widget_mode::enabled;
63
66 observer<bool> hover = false;
67
70 observer<bool> focus = false;
71
87
96
99 widget(gui_window& window, widget *parent) noexcept;
100
101 virtual ~widget();
102 widget(const widget&) = delete;
103 widget& operator=(const widget&) = delete;
104 widget(widget&&) = delete;
105 widget& operator=(widget&&) = delete;
106
107 [[nodiscard]] bool is_gui_thread() const noexcept;
108
113 hi::theme const& theme() const noexcept;
114
119 hi::font_book& font_book() const noexcept;
120
128 [[nodiscard]] virtual hitbox hitbox_test(point3 position) const noexcept
129 {
130 return {};
131 }
132
139 [[nodiscard]] virtual hitbox hitbox_test_from_parent(point3 position) const noexcept
140 {
141 return hitbox_test(_layout.from_parent * position);
142 }
143
151 [[nodiscard]] virtual hitbox hitbox_test_from_parent(point3 position, hitbox sibling_hitbox) const noexcept
152 {
153 return std::max(sibling_hitbox, hitbox_test(_layout.from_parent * position));
154 }
155
159 [[nodiscard]] virtual bool accepts_keyboard_focus(keyboard_focus_group group) const noexcept
160 {
161 hi_axiom(is_gui_thread());
162 return false;
163 }
164
176 virtual widget_constraints const& set_constraints() noexcept = 0;
177
178 widget_constraints const& constraints() const noexcept
179 {
180 return _constraints;
181 }
182
194 virtual void set_layout(widget_layout const& layout) noexcept = 0;
195
198 widget_layout const& layout() const noexcept
199 {
200 return _layout;
201 }
202
217 virtual void draw(draw_context const& context) noexcept = 0;
218
221 virtual void request_redraw() const noexcept;
222
225 void request_relayout() const noexcept;
226
229 template<fixed_string SourceFile, int SourceLine, fixed_string Fmt, typename... Args>
230 void request_reconstrain(Args&&...args) const noexcept
231 {
232 constexpr auto FmtPlus = fixed_string{"request_reconstrain:"} + Fmt;
233
234 log_global.add<global_state_type::log_info, SourceFile, SourceLine, FmtPlus>(std::forward<Args>(args)...);
235 _request_reconstrain();
236 }
237
238#define hi_request_reconstrain(fmt, ...) \
239 hi_format_check(fmt __VA_OPT__(, ) __VA_ARGS__); \
240 this->request_reconstrain<__FILE__, __LINE__, fmt>(__VA_ARGS__)
241
244 template<fixed_string SourceFile, int SourceLine, fixed_string Fmt, typename... Args>
245 void request_resize(Args&&...args) const noexcept
246 {
247 constexpr auto FmtPlus = fixed_string{"request_resize:"} + Fmt;
248
249 log_global.add<global_state_type::log_info, SourceFile, SourceLine, FmtPlus>(std::forward<Args>(args)...);
250 _request_resize();
251 }
252
253#define hi_request_resize(fmt, ...) \
254 hi_format_check(fmt __VA_OPT__(, ) __VA_ARGS__); \
255 this->request_resize<__FILE__, __LINE__, fmt>(__VA_ARGS__)
256
261 virtual bool handle_event(gui_event const& event) noexcept;
262
271 gui_event const& event,
272 std::vector<widget const *> const& reject_list = std::vector<widget const *>{}) noexcept;
273
286 [[nodiscard]] virtual widget const *find_next_widget(
287 widget const *current_keyboard_widget,
288 keyboard_focus_group group,
289 keyboard_focus_direction direction) const noexcept;
290
291 [[nodiscard]] widget const *find_first_widget(keyboard_focus_group group) const noexcept;
292
293 [[nodiscard]] widget const *find_last_widget(keyboard_focus_group group) const noexcept;
294
297 [[nodiscard]] bool is_first(keyboard_focus_group group) const noexcept;
298
301 [[nodiscard]] bool is_last(keyboard_focus_group group) const noexcept;
302
309 virtual void scroll_to_show(hi::aarectangle rectangle) noexcept;
310
313 void scroll_to_show() noexcept
314 {
315 scroll_to_show(layout().rectangle());
316 }
317
321 [[nodiscard]] std::vector<widget const *> parent_chain() const noexcept;
322
323 virtual [[nodiscard]] color background_color() const noexcept;
324
325 virtual [[nodiscard]] color foreground_color() const noexcept;
326
327 virtual [[nodiscard]] color focus_color() const noexcept;
328
329 virtual [[nodiscard]] color accent_color() const noexcept;
330
331 virtual [[nodiscard]] color label_color() const noexcept;
332
333protected:
334 widget_constraints _constraints;
335 widget_layout _layout;
336
337 decltype(mode)::callback_token _mode_cbt;
338
339 [[nodiscard]] virtual generator<widget *> children() const noexcept
340 {
341 co_return;
342 }
343
353 [[nodiscard]] aarectangle make_overlay_rectangle(aarectangle requested_rectangle) const noexcept;
354
355private:
356 void _request_reconstrain() const noexcept;
357 void _request_resize() const noexcept;
358};
359
360}} // namespace hi::v1
Defines widget_constraints.
Defines widget_layout.
Defines widget_mode.
Definition of GUI event types.
@ enabled
The widget is fully enabled.
DOXYGEN BUG.
Definition algorithm.hpp:15
The HikoGUI namespace.
Definition ascii.hpp:19
A user interface event.
Definition gui_event.hpp:66
hi_force_inline void add(Args &&...args) noexcept
Log a message.
Definition log.hpp:122
An interactive graphical object as part of the user-interface.
Definition widget.hpp:44
widget_layout const & layout() const noexcept
Get the current layout for this widget.
Definition widget.hpp:198
bool is_first(keyboard_focus_group group) const noexcept
Is this widget the first widget in the parent container.
virtual void scroll_to_show(hi::aarectangle rectangle) noexcept
Scroll to show the given rectangle on the window.
void request_resize(Args &&...args) const noexcept
Request the window to be resize based on the preferred size of the widgets.
Definition widget.hpp:245
virtual hitbox hitbox_test_from_parent(point3 position) const noexcept
Call hitbox_test from a parent widget.
Definition widget.hpp:139
virtual widget const * find_next_widget(widget const *current_keyboard_widget, keyboard_focus_group group, keyboard_focus_direction direction) const noexcept
Find the next widget that handles keyboard focus.
virtual void set_layout(widget_layout const &layout) noexcept=0
Update the internal layout of the widget.
int logical_layer
The logical layer of the widget.
Definition widget.hpp:95
std::string id
A name of widget, should be unique between siblings.
Definition widget.hpp:57
int semantic_layer
The draw layer of the widget.
Definition widget.hpp:86
hi::font_book & font_book() const noexcept
Get the font book.
observer< bool > hover
Mouse cursor is hovering over the widget.
Definition widget.hpp:66
widget *const parent
Pointer to the parent widget.
Definition widget.hpp:53
virtual void draw(draw_context const &context) noexcept=0
Draw the widget.
widget(gui_window &window, widget *parent) noexcept
virtual bool handle_event_recursive(gui_event const &event, std::vector< widget const * > const &reject_list=std::vector< widget const * >{}) noexcept
Handle command recursive.
void request_reconstrain(Args &&...args) const noexcept
Request the window to be reconstrain on the next frame.
Definition widget.hpp:230
virtual hitbox hitbox_test_from_parent(point3 position, hitbox sibling_hitbox) const noexcept
Call hitbox_test from a parent widget.
Definition widget.hpp:151
virtual void request_redraw() const noexcept
Request the widget to be redrawn on the next frame.
hi::theme const & theme() const noexcept
Get the theme.
virtual hitbox hitbox_test(point3 position) const noexcept
Find the widget that is under the mouse cursor.
Definition widget.hpp:128
virtual widget_constraints const & set_constraints() noexcept=0
Update the constraints of the widget.
std::vector< widget const * > parent_chain() const noexcept
Get a list of parents of a given widget.
virtual bool accepts_keyboard_focus(keyboard_focus_group group) const noexcept
Check if the widget will accept keyboard focus.
Definition widget.hpp:159
virtual bool handle_event(gui_event const &event) noexcept
Handle command.
bool is_last(keyboard_focus_group group) const noexcept
Is this widget the last widget in the parent container.
void request_relayout() const noexcept
Request the window to be relayout on the next frame.
void scroll_to_show() noexcept
Scroll to show the important part of the widget.
Definition widget.hpp:313
observer< widget_mode > mode
The widget mode.
Definition widget.hpp:62
observer< bool > focus
The widget has keyboard focus.
Definition widget.hpp:70
gui_window & window
Convenient reference to the Window.
Definition widget.hpp:48
The constraints of a widget.
Definition widget_constraints.hpp:26
The layout of a widget.
Definition widget_layout.hpp:37
matrix3 from_parent
This matrix transforms parent widget's coordinates to local coordinates.
Definition widget_layout.hpp:51
T max(T... args)