The Battle for Wesnoth  1.19.0-dev
handler.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2024
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 
22 namespace gui2
23 {
24 class window;
25 
26 namespace event
27 {
28 class dispatcher;
29 
30 class manager
31 {
32 public:
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  */
55 enum 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 
96 constexpr 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  */
115 enum ui_event : uint32_t {
132 
150 
152 
153  SDL_TEXT_INPUT = encode_category(35, event_category::text_input), /**< An SDL text input (commit) event. */
154  SDL_TEXT_EDITING = encode_category(36, event_category::text_input), /**< An SDL text editing (IME) event. */
155 
162 
166 
169 
171 };
172 // clang-format on
173 
174 /**
175  * Checks if a given event is in a given category.
176  *
177  * @note Even though all events currently have only one category bitflag set, this function
178  * works correctly if they ever have multiple flags set, unlike @ref get_event_category.
179  */
180 constexpr bool is_in_category(const ui_event event, const event_category mask)
181 {
182  const uint32_t asu32 = static_cast<uint32_t>(mask);
183  return (event & asu32) == asu32;
184 }
185 
186 /**
187  * Returns the category of a given event.
188  *
189  * @note Since each event has only *one* category flag set, it is safe to simply do an
190  * equality check with this result, which would return the same as @ref is_in_category.
191  */
193 {
194  // Zero-out the first 8 bits since those encode the ui_event value, which we don't want.
195  return static_cast<event_category>((event >> 8u) << 8u);
196 }
197 
198 /**
199  * Connects a dispatcher to the event handler.
200  *
201  * @param dispatcher The dispatcher to connect.
202  */
203 void connect_dispatcher(dispatcher* dispatcher);
204 
205 /**
206  * Disconnects a dispatcher to the event handler.
207  *
208  * @param dispatcher The dispatcher to disconnect.
209  */
210 void disconnect_dispatcher(dispatcher* dispatcher);
211 
212 /**
213  * Gets all event dispatchers in the Z order.
214  */
215 std::vector<dispatcher*>& get_all_dispatchers();
216 
217 /**
218  * Initializes the location of the mouse.
219  *
220  * After a layout of the window the mouse location needs to be updated to
221  * test whether it entered or left a widget. Also after closing a window it's
222  * needed to send a dummy mouse move.
223  */
224 void init_mouse_location();
225 
226 /**
227  * Captures the mouse.
228  *
229  * A dispatcher can capture the mouse, when for example it's pressed on a
230  * button, this means all mouse events after that are send to that widget.
231  *
232  * @param dispatcher The dispatcher which should get the mouse
233  * focus.
234  */
235 void capture_mouse(dispatcher* dispatcher);
236 
237 /**
238  * Releases a captured mouse.
239  *
240  * @param dispatcher The dispatcher which should release the mouse
241  * capture.
242  */
243 void release_mouse(dispatcher* dispatcher);
244 
245 /**
246  * Captures the keyboard.
247  *
248  * A dispatcher can capture the keyboard, when for example it's pressed on a
249  * button, this means all keyboard events after that are send to that widget.
250  *
251  * @param dispatcher The dispatcher which should get the keyboard
252  * focus.
253  */
254 void capture_keyboard(dispatcher* dispatcher);
255 
256 std::ostream& operator<<(std::ostream& stream, const ui_event event);
257 
258 } // namespace event
259 
260 /**
261  * Keeps track of any open windows of any type (modal, non-modal, or tooltip) in the
262  * order in which they were opened. Currently only used as a helper for is_in_dialog(),
263  * but could potentially be useful for other things in the future.
264  */
265 extern std::vector<window*> open_window_stack;
266 
267 /** Removes a entry from the open_window_stack list. This should be used instead of pop_back. */
268 void remove_from_window_stack(window* window);
269 
270 /**
271  * Is a dialog open?
272  *
273  * @note added as backwards compatibility for gui::is_in_dialog.
274  */
275 bool is_in_dialog();
276 
277 } // namespace gui2
ui_event
The event sent to the dispatcher.
Definition: handler.hpp:115
@ MIDDLE_BUTTON_DOWN
Definition: handler.hpp:124
@ NOTIFY_REMOVE_TOOLTIP
Definition: handler.hpp:159
@ RIGHT_BUTTON_UP
Definition: handler.hpp:129
@ SDL_RIGHT_BUTTON_DOWN
Definition: handler.hpp:140
@ SDL_TOUCH_DOWN
Definition: handler.hpp:149
@ MIDDLE_BUTTON_DOUBLE_CLICK
Definition: handler.hpp:127
@ NOTIFY_MODIFIED
Definition: handler.hpp:158
@ MIDDLE_BUTTON_CLICK
Definition: handler.hpp:126
@ SDL_LEFT_BUTTON_DOWN
Definition: handler.hpp:136
@ SDL_TEXT_INPUT
An SDL text input (commit) event.
Definition: handler.hpp:153
@ SDL_WHEEL_DOWN
Definition: handler.hpp:145
@ LEFT_BUTTON_UP
Definition: handler.hpp:121
@ MIDDLE_BUTTON_UP
Definition: handler.hpp:125
@ RIGHT_BUTTON_CLICK
Definition: handler.hpp:130
@ LOSE_KEYBOARD_FOCUS
Definition: handler.hpp:161
@ SDL_MOUSE_MOTION
Definition: handler.hpp:134
@ SDL_TEXT_EDITING
An SDL text editing (IME) event.
Definition: handler.hpp:154
@ LEFT_BUTTON_DOUBLE_CLICK
Definition: handler.hpp:123
@ RIGHT_BUTTON_DOWN
Definition: handler.hpp:128
@ NOTIFY_REMOVAL
Definition: handler.hpp:157
@ RECEIVE_KEYBOARD_FOCUS
Definition: handler.hpp:160
@ SDL_TOUCH_MOTION
Definition: handler.hpp:167
@ SDL_WHEEL_RIGHT
Definition: handler.hpp:143
@ SDL_VIDEO_RESIZE
Definition: handler.hpp:133
@ LEFT_BUTTON_CLICK
Definition: handler.hpp:122
@ SDL_WHEEL_LEFT
Definition: handler.hpp:142
@ SDL_LEFT_BUTTON_UP
Definition: handler.hpp:137
@ SDL_TOUCH_MULTI_GESTURE
Definition: handler.hpp:168
@ REQUEST_PLACEMENT
Definition: handler.hpp:163
@ SDL_MIDDLE_BUTTON_UP
Definition: handler.hpp:139
@ LEFT_BUTTON_DOWN
Definition: handler.hpp:120
@ SDL_MIDDLE_BUTTON_DOWN
Definition: handler.hpp:138
@ SDL_RIGHT_BUTTON_UP
Definition: handler.hpp:141
@ RIGHT_BUTTON_DOUBLE_CLICK
Definition: handler.hpp:131
@ MESSAGE_SHOW_TOOLTIP
Definition: handler.hpp:164
@ MESSAGE_SHOW_HELPTIP
Definition: handler.hpp:165
constexpr event_category get_event_category(const ui_event event)
Returns the category of a given event.
Definition: handler.hpp:192
void capture_mouse(dispatcher *dispatcher)
Captures the mouse.
Definition: handler.cpp:893
void release_mouse(dispatcher *dispatcher)
Releases a captured mouse.
Definition: handler.cpp:900
void disconnect_dispatcher(dispatcher *dispatcher)
Disconnects a dispatcher to the event handler.
Definition: handler.cpp:867
void capture_keyboard(dispatcher *dispatcher)
Captures the keyboard.
Definition: handler.cpp:909
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:860
std::vector< dispatcher * > & get_all_dispatchers()
Gets all event dispatchers in the Z order.
Definition: handler.cpp:874
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:918
void init_mouse_location()
Initializes the location of the mouse.
Definition: handler.cpp:880
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:180
Generic file dialog.
bool is_in_dialog()
Is a dialog open?
Definition: handler.cpp:1085
void remove_from_window_stack(window *window)
Removes a entry from the open_window_stack list.
Definition: handler.cpp:1075
std::vector< window * > open_window_stack
Keeps track of any open windows of any type (modal, non-modal, or tooltip) in the order in which they...
Definition: handler.cpp:1073
The message callbacks hold a reference to a message.
Definition: message.hpp:46