HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
gui_event.hpp
Go to the documentation of this file.
1// Copyright Take Vos 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 "widget_id.hpp"
12#include "gui_event_type.hpp"
13#include "gui_event_variant.hpp"
14#include "keyboard_virtual_key_intf.hpp"
15#include "keyboard_state.hpp"
16#include "keyboard_modifiers.hpp"
17#include "keyboard_focus_group.hpp"
18#include "keyboard_focus_direction.hpp"
19#include "mouse_buttons.hpp"
20#include "hitbox.hpp"
21#include "../unicode/unicode.hpp"
22#include "../geometry/geometry.hpp"
23#include "../time/time.hpp"
24#include "../macros.hpp"
25#include <chrono>
26#include <memory>
27
28hi_export_module(hikogui.GUI : gui_event);
29
30hi_export namespace hi { inline namespace v1 {
31
38 hi::hitbox hitbox = {};
39
44 point2 position = {};
45
52 point2 down_position = {};
53
59
62 mouse_buttons cause = {};
63
66 mouse_buttons down = {};
67
70 uint8_t click_count = 0;
71};
72
74 hi::widget_id widget_id = {};
75 keyboard_focus_group group = keyboard_focus_group::normal;
76 keyboard_focus_direction direction = keyboard_focus_direction::here;
77};
78
82class gui_event {
83public:
86 utc_nanoseconds time_point;
87
93
97
105 constexpr gui_event(
107 utc_nanoseconds time_point,
108 hi::keyboard_modifiers keyboard_modifiers,
109 hi::keyboard_state keyboard_state) noexcept :
110 _type(gui_event_type::none),
114 {
115 set_type(type);
116 }
117
120 constexpr gui_event() noexcept :
121 gui_event(gui_event_type::none, utc_nanoseconds{}, keyboard_modifiers::none, keyboard_state::idle)
122 {
123 }
124
130 gui_event(type, std::chrono::utc_clock::now(), keyboard_modifiers::none, keyboard_state::idle)
131 {
132 }
133
140 gui_event(type, std::chrono::utc_clock::now(), keyboard_modifiers::none, keyboard_state::idle)
141 {
142 hi_assert(variant() == gui_event_variant::rectangle);
143 this->rectangle() = rectangle;
144 }
145
155 keyboard_virtual_key key,
156 hi::keyboard_modifiers keyboard_modifiers = keyboard_modifiers::none,
157 hi::keyboard_state keyboard_state = keyboard_state::idle) noexcept :
158 gui_event(type, std::chrono::utc_clock::now(), keyboard_modifiers, keyboard_state)
159 {
160 hi_assert(variant() == gui_event_variant::keyboard);
161 this->key() = key;
162 }
163
164 constexpr ~gui_event() = default;
165 constexpr gui_event(gui_event const&) noexcept = default;
166 constexpr gui_event(gui_event&&) noexcept = default;
167 constexpr gui_event& operator=(gui_event const&) noexcept = default;
168 constexpr gui_event& operator=(gui_event&&) noexcept = default;
169
174 [[nodiscard]] static gui_event make_mouse_enter(point2 position) noexcept
175 {
176 auto r = gui_event{gui_event_type::mouse_enter};
177 r.mouse().position = position;
178 return r;
179 }
180
181 [[nodiscard]] static gui_event keyboard_grapheme(hi::grapheme grapheme) noexcept
182 {
183 auto r = gui_event{gui_event_type::keyboard_grapheme};
184 r.grapheme() = grapheme;
185 return r;
186 }
187
188 [[nodiscard]] static gui_event keyboard_partial_grapheme(hi::grapheme grapheme) noexcept
189 {
190 auto r = gui_event{gui_event_type::keyboard_partial_grapheme};
191 r.grapheme() = grapheme;
192 return r;
193 }
194
195 [[nodiscard]] static gui_event window_set_keyboard_target(
196 widget_id id,
197 keyboard_focus_group group = keyboard_focus_group::normal,
198 keyboard_focus_direction direction = keyboard_focus_direction::here) noexcept
199 {
201 r.keyboard_target().widget_id = id;
202 r.keyboard_target().group = group;
203 r.keyboard_target().direction = direction;
204 return r;
205 }
206
212 [[nodiscard]] static gui_event make_clipboard_event(gui_event_type type, gstring_view text) noexcept
213 {
214 auto r = gui_event{type};
215 r.clipboard_data() = text;
216 return r;
217 }
218
221 [[nodiscard]] constexpr gui_event_type type() const noexcept
222 {
223 return _type;
224 }
225
231 constexpr void set_type(gui_event_type type) noexcept
232 {
233 auto const previous_variant = variant();
234
235 _type = type;
236 if (previous_variant != variant()) {
237 switch (variant()) {
239 _data = mouse_event_data{};
240 break;
242 _data = hi::grapheme{};
243 break;
245 _data = keyboard_virtual_key{};
246 break;
248 _data = keyboard_target_data{};
249 break;
251 _data = aarectangle{};
252 break;
254 _data = gstring{};
255 default:;
256 }
257 }
258 }
259
264 [[nodiscard]] mouse_event_data& mouse() noexcept
265 {
266 hi_assert(variant() == gui_event_variant::mouse);
267 return std::get<mouse_event_data>(_data);
268 }
269
274 [[nodiscard]] mouse_event_data const& mouse() const noexcept
275 {
276 hi_assert(variant() == gui_event_variant::mouse);
277 return std::get<mouse_event_data>(_data);
278 }
279
284 [[nodiscard]] keyboard_virtual_key& key() noexcept
285 {
286 hi_assert(variant() == gui_event_variant::keyboard);
287 return std::get<keyboard_virtual_key>(_data);
288 }
289
294 [[nodiscard]] keyboard_virtual_key const& key() const noexcept
295 {
296 hi_assert(variant() == gui_event_variant::keyboard);
297 return std::get<keyboard_virtual_key>(_data);
298 }
299
304 [[nodiscard]] hi::grapheme& grapheme() noexcept
305 {
306 hi_assert(variant() == gui_event_variant::grapheme);
307 return std::get<hi::grapheme>(_data);
308 }
309
314 [[nodiscard]] hi::grapheme const& grapheme() const noexcept
315 {
316 hi_assert(variant() == gui_event_variant::grapheme);
317 return std::get<hi::grapheme>(_data);
318 }
319
320 [[nodiscard]] aarectangle& rectangle() noexcept
321 {
322 hi_assert(variant() == gui_event_variant::rectangle);
323 return std::get<aarectangle>(_data);
324 }
325
326 [[nodiscard]] aarectangle const& rectangle() const noexcept
327 {
328 hi_assert(variant() == gui_event_variant::rectangle);
329 return std::get<aarectangle>(_data);
330 }
331
332 [[nodiscard]] keyboard_target_data& keyboard_target() noexcept
333 {
334 hi_assert(variant() == gui_event_variant::keyboard_target);
335 return std::get<keyboard_target_data>(_data);
336 }
337
338 [[nodiscard]] keyboard_target_data const& keyboard_target() const noexcept
339 {
340 hi_assert(variant() == gui_event_variant::keyboard_target);
341 return std::get<keyboard_target_data>(_data);
342 }
343
344 [[nodiscard]] gstring& clipboard_data() noexcept
345 {
346 hi_assert(variant() == gui_event_variant::clipboard_data);
347 return std::get<gstring>(_data);
348 }
349
350 [[nodiscard]] gstring const& clipboard_data() const noexcept
351 {
352 hi_assert(variant() == gui_event_variant::clipboard_data);
353 return std::get<gstring>(_data);
354 }
355
356 [[nodiscard]] constexpr bool operator==(gui_event_type event_type) const noexcept
357 {
358 return type() == event_type;
359 }
360
361 [[nodiscard]] constexpr bool operator==(gui_event_variant event_variant) const noexcept
362 {
363 return variant() == event_variant;
364 }
365
366 [[nodiscard]] constexpr bool empty() const noexcept
367 {
368 return type() == gui_event_type::none;
369 }
370
371 constexpr operator bool() const noexcept
372 {
373 return not empty();
374 }
375
376 [[nodiscard]] constexpr gui_event_variant variant() const noexcept
377 {
378 return to_gui_event_variant(type());
379 }
380
383 [[nodiscard]] constexpr bool is_left_button_up(aarectangle active_area) const noexcept
384 {
385 using enum gui_event_type;
386 return type() == mouse_up and mouse().cause.left_button and active_area.contains(mouse().position);
387 }
388
391 [[nodiscard]] constexpr vector2 drag_delta() const noexcept
392 {
393 using enum gui_event_type;
394 return type() == mouse_drag ? mouse().position - mouse().down_position : vector2{};
395 }
396
405 [[nodiscard]] constexpr friend gui_event operator*(translate2 const& transform, gui_event const& rhs) noexcept
406 {
407 auto r = rhs;
408 if (rhs == gui_event_variant::mouse) {
409 r.mouse().position = transform * rhs.mouse().position;
410 r.mouse().down_position = transform * rhs.mouse().down_position;
411 }
412 return r;
413 }
414
415private:
416 using data_type =
417 std::variant<mouse_event_data, keyboard_virtual_key, keyboard_target_data, hi::grapheme, aarectangle, gstring>;
418
419 gui_event_type _type;
420 data_type _data;
421};
422
423}} // namespace hi::v1
424
425// XXX #617 MSVC bug does not handle partial specialization in modules.
426hi_export template<>
427struct std::formatter<hi::gui_event, char> : std::formatter<std::string_view, char> {
428 auto format(hi::gui_event const& t, auto& fc) const
429 {
430 return std::formatter<std::string_view, char>::format(hi::gui_event_type_metadata[t.type()], fc);
431 }
432};
Definition of a GUI event variant.
Definition of GUI event type.
gui_event_type
GUI event type.
Definition gui_event_type.hpp:24
constexpr gui_event_variant to_gui_event_variant(gui_event_type type) noexcept
Convert a gui event type, to an gui event variant.
Definition gui_event_variant.hpp:54
gui_event_variant
A granular gui event type.
Definition gui_event_variant.hpp:21
@ window_set_keyboard_target
Change the keyboard target widget for this window.
@ keyboard
The gui_event has keyboard data.
@ mouse
The gui_event has mouse data.
@ keyboard_target
The gui_event has keyboard target data.
@ grapheme
The gui_event has grapheme data.
@ rectangle
The gui_event has rectangle data.
@ clipboard_data
The gui_event has clipboard data.
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Class which represents an axis-aligned rectangle.
Definition aarectangle.hpp:33
A rectangle / parallelogram in 3D space.
Definition rectangle.hpp:25
Definition translate2.hpp:18
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector2.hpp:27
Information for a mouse event.
Definition gui_event.hpp:35
point2 position
The current position of the mouse pointer.
Definition gui_event.hpp:44
uint8_t click_count
Number of clicks from the last button clicked.
Definition gui_event.hpp:70
vector2 wheel_delta
Change in wheel rotation, in points (pt).
Definition gui_event.hpp:58
hi::hitbox hitbox
Information about which widget is underneath the mouse pointer.
Definition gui_event.hpp:38
mouse_buttons down
Buttons that are also held down.
Definition gui_event.hpp:66
mouse_buttons cause
Buttons which have caused this event.
Definition gui_event.hpp:62
point2 down_position
The position the last time a button was pressed.
Definition gui_event.hpp:52
Definition gui_event.hpp:73
A user interface event.
Definition gui_event.hpp:82
utc_nanoseconds time_point
The time when the event was created.
Definition gui_event.hpp:86
constexpr vector2 drag_delta() const noexcept
Get the location of the mouse relative to the start of a drag.
Definition gui_event.hpp:391
constexpr friend gui_event operator*(translate2 const &transform, gui_event const &rhs) noexcept
Transform a gui-event to another coordinate system.
Definition gui_event.hpp:405
mouse_event_data const & mouse() const noexcept
Get the mouse event information.
Definition gui_event.hpp:274
static gui_event make_clipboard_event(gui_event_type type, gstring_view text) noexcept
Create clipboard event.
Definition gui_event.hpp:212
constexpr void set_type(gui_event_type type) noexcept
Change the type of the gui_event.
Definition gui_event.hpp:231
constexpr gui_event() noexcept
Create an empty GUI event.
Definition gui_event.hpp:120
hi::grapheme & grapheme() noexcept
Get the grapheme entered on the keyboard.
Definition gui_event.hpp:304
keyboard_modifiers keyboard_modifiers
Keyboard modifiers: shift, ctrl, alt, etc.
Definition gui_event.hpp:92
static gui_event make_mouse_enter(point2 position) noexcept
Create a mouse enter event.
Definition gui_event.hpp:174
gui_event(gui_event_type type, aarectangle rectangle) noexcept
Create a rectangle event.
Definition gui_event.hpp:139
keyboard_state keyboard_state
State of the keyboard; caps-lock, num-lock, scroll-lock.
Definition gui_event.hpp:96
hi::grapheme const & grapheme() const noexcept
Get the grapheme entered on the keyboard.
Definition gui_event.hpp:314
constexpr bool is_left_button_up(aarectangle active_area) const noexcept
Check if this event is for a left-button-up event while the mouse pointer is in the given area.
Definition gui_event.hpp:383
constexpr gui_event_type type() const noexcept
Get the event type.
Definition gui_event.hpp:221
keyboard_virtual_key const & key() const noexcept
Get the key from the keyboard event.
Definition gui_event.hpp:294
mouse_event_data & mouse() noexcept
Get the mouse event information.
Definition gui_event.hpp:264
gui_event(gui_event_type type, keyboard_virtual_key key, hi::keyboard_modifiers keyboard_modifiers=keyboard_modifiers::none, hi::keyboard_state keyboard_state=keyboard_state::idle) noexcept
Create a GUI event.
Definition gui_event.hpp:153
constexpr gui_event(gui_event_type type, utc_nanoseconds time_point, hi::keyboard_modifiers keyboard_modifiers, hi::keyboard_state keyboard_state) noexcept
Create a GUI event.
Definition gui_event.hpp:105
gui_event(gui_event_type type) noexcept
Create am empty GUI event.
Definition gui_event.hpp:129
keyboard_virtual_key & key() noexcept
Get the key from the keyboard event.
Definition gui_event.hpp:284