The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
handler.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2009 - 2025
3 by Mark de Wever <koraq@xs4all.nl>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#pragma once
17
18#include <cstdint>
19#include <iosfwd>
20#include <vector>
21
22namespace gui2
23{
24class window;
25
26namespace event
27{
28class dispatcher;
29
31{
32public:
33 manager();
34 ~manager();
35};
36
37// clang-format off
38
39/**
40 * Event category masks.
41 *
42 * These begin at 2^8 to allow for 8 bits for the event identifiers themselves.
43 * This means ui_event can have up to 256 unique members. Since each mask needs
44 * its own place value, we can have 24 categories since ui_event's underlying
45 * type is 32 bits:
46 *
47 * USABLE CATEGORY BITS NULL
48 * |------------------------|--------|
49 * MASK 000000000000000000000000 00000000
50 *
51 * ENCODED CATEGORY EVENT
52 * |------------------------|--------|
53 * UI_EVENT 000000000000000000000000 00000000
54 */
55enum class event_category : uint32_t {
56 /**
57 * Callbacks without extra parameters.
58 * @note Some mouse events like MOUSE_ENTER don't send the mouse coordinates
59 * to the callback function so they are also in this category.
60 */
61 general = 1u << 8,
62
63 /**
64 * Callbacks with a coordinate as extra parameter.
65 */
66 mouse = 1u << 9,
67
68 /**
69 * Callbacks with the keyboard values (these haven't been determined yet).
70 */
71 keyboard = 1u << 10,
72
73 touch_motion = 1u << 11,
74 touch_gesture = 1u << 12,
75
76 /**
77 * Callbacks with a sender aka notification messages. Like general events
78 * it has no extra parameters, but this version is only sent to the target
79 * and does not use the pre and post queue.
80 */
81 notification = 1u << 13,
82
83 /**
84 * Callbacks with a sender aka notification messages.
85 * Unlike the notifications this message is send through the chain. The event
86 * is sent from a widget all the way up to the window, who is always the
87 * receiver of the message (unless somebody grabbed it before).
88 */
89 message = 1u << 14,
90
91 raw_event = 1u << 15,
92 text_input = 1u << 16,
93};
94// clang-format on
95
96constexpr uint32_t encode_category(const uint32_t input, const event_category mask)
97{
98 return input | static_cast<uint32_t>(mask);
99}
100
101// clang-format off
102
103/**
104 * The event sent to the dispatcher.
105 *
106 * Events prefixed by SDL are (semi)-real SDL events. The handler does some
107 * minor decoding like splitting the button down event to the proper event but
108 * nothing more. Events without an SDL prefix are generated by another signal
109 * eg the windows signal handler for SDL_MOUSE_MOTION can generate a
110 * MOUSE_ENTER, MOUSE_MOTION and MOUSE_LEAVE event and send that to it's
111 * children.
112 *
113 * @note When adding a new entry to the enum also add a unit test.
114 */
115enum ui_event : uint32_t {
132
133 // Mouse forward/back buttons (buttons 4 and 5, SDL_BUTTON_X1/SDL_BUTTON_X2)
142
152
153 // Raw mouse forward/back button events
158
167
169
170 SDL_TEXT_INPUT = encode_category(35, event_category::text_input), /**< An SDL text input (commit) event. */
171 SDL_TEXT_EDITING = encode_category(36, event_category::text_input), /**< An SDL text editing (IME) event. */
172
181
185
188
191// clang-format on
192
193/**
194 * Checks if a given event is in a given category.
195 *
196 * @note Even though all events currently have only one category bitflag set, this function
197 * works correctly if they ever have multiple flags set, unlike @ref get_event_category.
198 */
199constexpr bool is_in_category(const ui_event event, const event_category mask)
200{
201 const uint32_t asu32 = static_cast<uint32_t>(mask);
202 return (event & asu32) == asu32;
203}
204
205/**
206 * Returns the category of a given event.
207 *
208 * @note Since each event has only *one* category flag set, it is safe to simply do an
209 * equality check with this result, which would return the same as @ref is_in_category.
210 */
212{
213 // Zero-out the first 8 bits since those encode the ui_event value, which we don't want.
214 return static_cast<event_category>((event >> 8u) << 8u);
215}
216
217/**
218 * Connects a dispatcher to the event handler.
219 *
220 * @param dispatcher The dispatcher to connect.
221 */
222void connect_dispatcher(dispatcher* dispatcher);
223
224/**
225 * Disconnects a dispatcher to the event handler.
226 *
227 * @param dispatcher The dispatcher to disconnect.
228 */
229void disconnect_dispatcher(dispatcher* dispatcher);
230
231/**
232 * Gets all event dispatchers in the Z order.
233 */
234std::vector<dispatcher*>& get_all_dispatchers();
235
236/**
237 * Initializes the location of the mouse.
238 *
239 * After a layout of the window the mouse location needs to be updated to
240 * test whether it entered or left a widget. Also after closing a window it's
241 * needed to send a dummy mouse move.
242 */
244
245/**
246 * Captures the mouse.
247 *
248 * A dispatcher can capture the mouse, when for example it's pressed on a
249 * button, this means all mouse events after that are send to that widget.
250 *
251 * @param dispatcher The dispatcher which should get the mouse
252 * focus.
253 */
254void capture_mouse(dispatcher* dispatcher);
255
256/**
257 * Releases a captured mouse.
258 *
259 * @param dispatcher The dispatcher which should release the mouse
260 * capture.
261 */
262void release_mouse(dispatcher* dispatcher);
263
264/**
265 * Captures the keyboard.
266 *
267 * A dispatcher can capture the keyboard, when for example it's pressed on a
268 * button, this means all keyboard events after that are send to that widget.
269 *
270 * @param dispatcher The dispatcher which should get the keyboard
271 * focus.
272 */
273void capture_keyboard(dispatcher* dispatcher);
274
275std::ostream& operator<<(std::ostream& stream, const ui_event event);
276
277} // namespace event
278
279/**
280 * Is a dialog open?
281 *
282 * @note added as backwards compatibility for gui::is_in_dialog.
283 */
284bool is_in_dialog();
285
286} // namespace gui2
ui_event
The event sent to the dispatcher.
Definition handler.hpp:115
@ MIDDLE_BUTTON_DOWN
Definition handler.hpp:124
@ SDL_FORWARD_BUTTON_DOWN
Definition handler.hpp:156
@ NOTIFY_REMOVE_TOOLTIP
Definition handler.hpp:176
@ FORWARD_BUTTON_DOUBLE_CLICK
Definition handler.hpp:141
@ FORWARD_BUTTON_CLICK
Definition handler.hpp:140
@ SDL_RIGHT_BUTTON_DOWN
Definition handler.hpp:150
@ MIDDLE_BUTTON_DOUBLE_CLICK
Definition handler.hpp:127
@ FORWARD_BUTTON_DOWN
Definition handler.hpp:138
@ BACK_BUTTON_CLICK
Definition handler.hpp:136
@ MIDDLE_BUTTON_CLICK
Definition handler.hpp:126
@ SDL_LEFT_BUTTON_DOWN
Definition handler.hpp:146
@ SDL_TEXT_INPUT
An SDL text input (commit) event.
Definition handler.hpp:170
@ RIGHT_BUTTON_CLICK
Definition handler.hpp:130
@ LOSE_KEYBOARD_FOCUS
Definition handler.hpp:178
@ SDL_TEXT_EDITING
An SDL text editing (IME) event.
Definition handler.hpp:171
@ LEFT_BUTTON_DOUBLE_CLICK
Definition handler.hpp:123
@ RIGHT_BUTTON_DOWN
Definition handler.hpp:128
@ RECEIVE_KEYBOARD_FOCUS
Definition handler.hpp:177
@ BACK_BUTTON_DOUBLE_CLICK
Definition handler.hpp:137
@ LEFT_BUTTON_CLICK
Definition handler.hpp:122
@ SDL_LEFT_BUTTON_UP
Definition handler.hpp:147
@ SDL_TOUCH_MULTI_GESTURE
Definition handler.hpp:187
@ REQUEST_PLACEMENT
Definition handler.hpp:182
@ SDL_MIDDLE_BUTTON_UP
Definition handler.hpp:149
@ SDL_BACK_BUTTON_DOWN
Definition handler.hpp:154
@ SDL_BACK_BUTTON_UP
Definition handler.hpp:155
@ FORWARD_BUTTON_UP
Definition handler.hpp:139
@ SDL_WINDOW_ENTER_FULLSCREEN
Definition handler.hpp:179
@ SDL_MIDDLE_BUTTON_DOWN
Definition handler.hpp:148
@ SDL_RIGHT_BUTTON_UP
Definition handler.hpp:151
@ RIGHT_BUTTON_DOUBLE_CLICK
Definition handler.hpp:131
@ MESSAGE_SHOW_TOOLTIP
Definition handler.hpp:183
@ MESSAGE_SHOW_HELPTIP
Definition handler.hpp:184
@ SDL_FORWARD_BUTTON_UP
Definition handler.hpp:157
@ SDL_WINDOW_LEAVE_FULLSCREEN
Definition handler.hpp:180
constexpr event_category get_event_category(const ui_event event)
Returns the category of a given event.
Definition handler.hpp:211
void capture_mouse(dispatcher *dispatcher)
Captures the mouse.
Definition handler.cpp:904
void release_mouse(dispatcher *dispatcher)
Releases a captured mouse.
Definition handler.cpp:911
void disconnect_dispatcher(dispatcher *dispatcher)
Disconnects a dispatcher to the event handler.
Definition handler.cpp:878
void capture_keyboard(dispatcher *dispatcher)
Captures the keyboard.
Definition handler.cpp:920
event_category
Event category masks.
Definition handler.hpp:55
@ notification
Callbacks with a sender aka notification messages.
@ keyboard
Callbacks with the keyboard values (these haven't been determined yet).
@ mouse
Callbacks with a coordinate as extra parameter.
@ message
Callbacks with a sender aka notification messages.
@ general
Callbacks without extra parameters.
void connect_dispatcher(dispatcher *dispatcher)
Connects a dispatcher to the event handler.
Definition handler.cpp:871
std::vector< dispatcher * > & get_all_dispatchers()
Gets all event dispatchers in the Z order.
Definition handler.cpp:885
constexpr uint32_t encode_category(const uint32_t input, const event_category mask)
Definition handler.hpp:96
std::ostream & operator<<(std::ostream &stream, const ui_event event)
Definition handler.cpp:929
void init_mouse_location()
Initializes the location of the mouse.
Definition handler.cpp:891
constexpr bool is_in_category(const ui_event event, const event_category mask)
Checks if a given event is in a given category.
Definition handler.hpp:199
Generic file dialog.
bool is_in_dialog()
Is a dialog open?
Definition handler.cpp:1126
The message callbacks hold a reference to a message.
Definition message.hpp:46