HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
gui_window.hpp
1// Copyright Take Vos 2019-2021.
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
5#pragma once
6
7#include "gui_window_size.hpp"
8#include "gui_window_delegate.hpp"
9#include "mouse_cursor.hpp"
10#include "hitbox.hpp"
11#include "mouse_event.hpp"
12#include "keyboard_event.hpp"
13#include "keyboard_focus_direction.hpp"
14#include "keyboard_focus_group.hpp"
15#include "theme.hpp"
17#include "../geometry/axis_aligned_rectangle.hpp"
18#include "../widgets/window_widget.hpp"
19#include "../widgets/grid_widget.hpp"
20#include "../widgets/toolbar_widget.hpp"
21#include "../chrono.hpp"
22#include "../label.hpp"
23#include "../animator.hpp"
24#include <unordered_set>
25#include <memory>
26#include <mutex>
27
28namespace hi::inline v1 {
29class gfx_device;
30class gfx_system;
31class gfx_surface;
32class gui_system;
33class keyboard_bindings;
34
41public:
43
44 gui_system &gui;
45
47
58
66 mouse_cursor current_mouse_cursor = mouse_cursor::None;
67
72 bool resizing = false;
73
77 bool active = false;
78
79 label title;
80
85 float dpi = 72.0;
86
90 hi::theme theme = {};
91
95
99
104
105 gui_window(gui_system &gui, label const &title, std::weak_ptr<delegate_type> delegate = {}) noexcept;
106
107 virtual ~gui_window();
108
109 gui_window(gui_window const &) = delete;
110 gui_window &operator=(gui_window const &) = delete;
111 gui_window(gui_window &&) = delete;
112 gui_window &operator=(gui_window &&) = delete;
113
120 virtual void init();
121
124 [[nodiscard]] bool is_gui_thread() const noexcept;
125
126 void set_device(gfx_device *device) noexcept;
127
130 hi::keyboard_bindings const &keyboard_bindings() const noexcept;
131
134 void request_redraw(aarectangle redraw_rectangle) noexcept
135 {
136 _redraw_rectangle |= redraw_rectangle;
137 }
138
141 void request_redraw() noexcept
142 {
143 hi_axiom(is_gui_thread());
144 request_redraw(aarectangle{rectangle.size()});
145 }
146
147 void request_relayout() noexcept
148 {
149 _relayout.store(true, std::memory_order::relaxed);
150 }
151
152 void request_reconstrain() noexcept
153 {
154 _reconstrain.store(true, std::memory_order::relaxed);
155 }
156
157 void request_resize() noexcept
158 {
159 _resize.store(true, std::memory_order::relaxed);
160 }
161
165 virtual void render(utc_nanoseconds displayTimePoint);
166
171 [[nodiscard]] grid_widget &content() noexcept
172 {
173 hi_axiom(is_gui_thread());
174 hi_axiom(widget);
175 return widget->content();
176 }
177
182 [[nodiscard]] toolbar_widget &toolbar() noexcept
183 {
184 hi_axiom(is_gui_thread());
185 hi_axiom(widget);
186 return widget->toolbar();
187 }
188
191 virtual void set_cursor(mouse_cursor cursor) = 0;
192
193 void set_resize_border_priority(bool left, bool right, bool bottom, bool top) noexcept;
194
197 virtual void close_window() = 0;
198
204 virtual void set_size_state(gui_window_size state) noexcept = 0;
205
208 virtual aarectangle workspace_rectangle() const noexcept = 0;
209
212 virtual aarectangle fullscreen_rectangle() const noexcept = 0;
213
214 virtual hi::subpixel_orientation subpixel_orientation() const noexcept = 0;
215
218 gui_window_size size_state() const noexcept
219 {
220 return _size_state;
221 }
222
227 virtual void open_system_menu() = 0;
228
231 virtual void set_window_size(extent2 extent) = 0;
232
235 [[nodiscard]] virtual std::string get_text_from_clipboard() const noexcept = 0;
236
239 virtual void set_text_on_clipboard(std::string str) noexcept = 0;
240
241 void update_mouse_target(hi::widget const *new_target_widget, point2 position = {}) noexcept;
242
249 void update_keyboard_target(hi::widget const *widget, keyboard_focus_group group = keyboard_focus_group::normal) noexcept;
250
259 void
260 update_keyboard_target(hi::widget const *widget, keyboard_focus_group group, keyboard_focus_direction direction) noexcept;
261
269 void update_keyboard_target(keyboard_focus_group group, keyboard_focus_direction direction) noexcept;
270
271 [[nodiscard]] translate2 window_to_screen() const noexcept
272 {
273 return translate2{rectangle.left(), rectangle.bottom()};
274 }
275
276 [[nodiscard]] translate2 screen_to_window() const noexcept
277 {
278 return ~window_to_screen();
279 }
280
281protected:
282 static constexpr std::chrono::nanoseconds _animation_duration = std::chrono::milliseconds(150);
283
285
286 std::atomic<aarectangle> _redraw_rectangle = aarectangle{};
287 std::atomic<bool> _relayout = true;
288 std::atomic<bool> _reconstrain = true;
289 std::atomic<bool> _resize = true;
290
293 gui_window_size _size_state = gui_window_size::normal;
294
297 aarectangle _restore_rectangle;
298
306 utc_nanoseconds last_forced_redraw = {};
307
310 animator<float> _animated_active = _animation_duration;
311
315 virtual void create_window(extent2 new_size) = 0;
316
320 [[nodiscard]] virtual bool handle_event(hi::command command) noexcept;
321
322 [[nodiscard]] virtual bool handle_event(std::vector<hi::command> const &commands) noexcept
323 {
324 for (hilet command : commands) {
325 if (handle_event(command)) {
326 return true;
327 }
328 }
329 return false;
330 }
331
335 [[nodiscard]] virtual bool handle_event(mouse_event const &event) noexcept
336 {
337 return false;
338 }
339
343 [[nodiscard]] virtual bool handle_event(keyboard_event const &event) noexcept
344 {
345 return false;
346 }
347
353 bool send_event(mouse_event const &event) noexcept;
354
359 bool send_event(keyboard_event const &event) noexcept;
360
361 bool send_event(KeyboardState _state, keyboard_modifiers modifiers, keyboard_virtual_key key) noexcept;
362
363 bool send_event(grapheme grapheme, bool full = true) noexcept;
364
365private:
366 notifier<>::token_type _setting_change_token;
367 observable<std::string>::token_type _selected_theme_token;
368
373 hi::widget const *_mouse_target_widget = nullptr;
374
378 hi::widget const *_keyboard_target_widget = nullptr;
379
384 void widget_is_destructing(hi::widget const *sender) noexcept
385 {
386 if (_mouse_target_widget == sender) {
387 _mouse_target_widget = nullptr;
388 }
389 if (_keyboard_target_widget == sender) {
390 _keyboard_target_widget = nullptr;
391 }
392 }
393
402 template<typename Event>
403 bool send_event_to_widget(hi::widget const *target_widget, Event const &event) noexcept;
404
405 friend class widget;
406};
407
408} // namespace hi::inline v1
subpixel_orientation
The orientation of the RGB sub-pixels of and LCD/LED panel.
Definition subpixel_orientation.hpp:18
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
STL namespace.
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:20
constexpr extent2 size() const noexcept
The size, or length of the right and up vectors.
Definition rectangle.hpp:154
Definition translate.hpp:15
Definition gfx_device.hpp:22
Graphics system.
Definition gui_system.hpp:30
Definition gui_window.hpp:40
void update_keyboard_target(hi::widget const *widget, keyboard_focus_group group=keyboard_focus_group::normal) noexcept
Change the keyboard focus to the given widget.
virtual void set_cursor(mouse_cursor cursor)=0
Set the mouse cursor icon.
virtual void open_system_menu()=0
Open the system menu of the window.
void update_keyboard_target(keyboard_focus_group group, keyboard_focus_direction direction) noexcept
Change the keyboard focus to the given, previous or next widget.
void update_keyboard_target(hi::widget const *widget, keyboard_focus_group group, keyboard_focus_direction direction) noexcept
Change the keyboard focus to the previous or next widget from the given widget.
toolbar_widget & toolbar() noexcept
Get a reference to window's toolbar widget.
Definition gui_window.hpp:182
grid_widget & content() noexcept
Get a reference to the window's content widget.
Definition gui_window.hpp:171
virtual void set_size_state(gui_window_size state) noexcept=0
Set the size-state of the window.
aarectangle rectangle
The current rectangle of the window relative to the screen.
Definition gui_window.hpp:57
extent2 widget_size
The size of the widget.
Definition gui_window.hpp:94
bool is_gui_thread() const noexcept
Check if the current thread is the same as the gui_system loop.
virtual void render(utc_nanoseconds displayTimePoint)
Update window.
std::unique_ptr< window_widget > widget
The widget covering the complete window.
Definition gui_window.hpp:98
virtual void init()
2 phase constructor.
notifier< void()> closing
Notifier used when the window is closing.
Definition gui_window.hpp:103
virtual void close_window()=0
Ask the operating system to close this window.
void request_redraw() noexcept
Request a rectangle on the window to be redrawn.
Definition gui_window.hpp:141
virtual void set_window_size(extent2 extent)=0
Ask the operating system to set the size of this window.
virtual std::string get_text_from_clipboard() const noexcept=0
Retrieve a text string from the operating system's clip-board.
virtual aarectangle workspace_rectangle() const noexcept=0
The rectangle of the workspace of the screen where the window is currently located.
Definition gui_window_delegate.hpp:12
Definition keyboard_bindings.hpp:17
Definition theme.hpp:22
A label consisting of localizable text and an icon.
Definition label.hpp:27
A notifier which can be used to call a set of registered callbacks.
Definition notifier.hpp:23
A GUI widget that lays out child-widgets in a grid with variable sized cells.
Definition grid_widget.hpp:37
A toolbar widget is located at the top of a window and lays out its children horizontally.
Definition toolbar_widget.hpp:28
An interactive graphical object as part of the user-interface.
Definition widget.hpp:40