The Battle for Wesnoth  1.15.6+dev
dispatcher.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2018 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
18 
20 #include "gui/core/log.hpp"
21 
22 namespace gui2
23 {
24 namespace event
25 {
26 /***** dispatcher class. *****/
27 
29  : mouse_behavior_(all)
30  , want_keyboard_input_(true)
31  , signal_queue_()
32  , signal_mouse_queue_()
33  , signal_keyboard_queue_()
34  , signal_touch_motion_queue_()
35  , signal_touch_gesture_queue_()
36  , signal_notification_queue_()
37  , signal_message_queue_()
38  , connected_(false)
39  , hotkeys_()
40 {
41 }
42 
44 {
45  if(connected_) {
47  }
48 }
49 
51 {
52  assert(!connected_);
53  connected_ = true;
54  connect_dispatcher(this);
55 }
56 
57 bool dispatcher::has_event(const ui_event event, const event_queue_type event_type)
58 {
59 #if 0
60  const bool res = dispatcher_implementation::has_handler(*this, event_type, event);
61  std::cerr << "Event '" << event << " '" << (res ? "found" : "not found") << "in queue\n";
62  return res;
63 #else
64  return dispatcher_implementation::has_handler(*this, event_type, event);
65 #endif
66 }
67 
68 bool dispatcher::fire(const ui_event event, widget& target)
69 {
70  assert(is_general_event(event));
71  switch(event) {
75 
78  &event_executor::wants_mouse_middle_double_click, signal_function>(this, &target);
79 
82  &event_executor::wants_mouse_right_double_click, signal_function>(this, &target);
83 
84  default:
85  return fire_event<signal_function>(event, this, &target);
86  }
87 }
88 
89 bool dispatcher::fire(const ui_event event, widget& target, const point& coordinate)
90 {
91  assert(is_mouse_event(event));
92  return fire_event<signal_mouse_function>(event, this, &target, coordinate);
93 }
94 
95 bool dispatcher::fire(const ui_event event,
96  widget& target,
97  const SDL_Keycode key,
98  const SDL_Keymod modifier,
99  const std::string& unicode)
100 {
101  assert(is_keyboard_event(event));
102  return fire_event<signal_keyboard_function>(event, this, &target, key, modifier, unicode);
103 }
104 
105 bool dispatcher::fire(const ui_event event, widget& target, const point& pos, const point& distance)
106 {
107  assert(is_touch_motion_event(event));
108  return fire_event<signal_touch_motion_function>(event, this, &target, pos, distance);
109 }
110 
111 bool dispatcher::fire(const ui_event event, widget& target, const point& center, float dTheta, float dDist, uint8_t numFingers)
112 {
113  assert(is_touch_gesture_event(event));
114  return fire_event<signal_touch_gesture_function>(event, this, &target, center, dTheta, dDist, numFingers);
115 }
116 
117 bool dispatcher::fire(const ui_event event, widget& target, const SDL_Event& sdlevent)
118 {
119  assert(is_raw_event_event(event));
120  return fire_event<signal_raw_event_function>(event, this, &target, sdlevent);
121 }
122 
123 bool dispatcher::fire(const ui_event event, widget& target, const std::string& text, int32_t start, int32_t len)
124 {
125  assert(is_text_input_event(event));
126  return fire_event<signal_text_input_function>(event, this, &target, text, start, len);
127 }
128 
129 bool dispatcher::fire(const ui_event event, widget& target, void*)
130 {
131  assert(is_notification_event(event));
132  return fire_event<signal_notification_function>(event, this, &target, nullptr);
133 }
134 
135 bool dispatcher::fire(const ui_event event, widget& target, const message& msg)
136 {
137  assert(is_message_event(event));
138  return fire_event<signal_message_function>(event, this, &target, msg);
139 }
140 
142 {
143  hotkeys_[id] = function;
144 }
145 
147 {
149 
150  if(itor == hotkeys_.end()) {
151  return false;
152  }
153 
154  itor->second(dynamic_cast<widget&>(*this), id);
155 
156  /* NOTE: hotkey events used to return bool to indicate was-handled status. However,
157  * every single usecase was returning true and cluttering up the code. I changed
158  * the signature to return void, but if there's ever a need to restore the bool
159  * retval on the hotkey functions, this is where it should be handled.
160  *
161  * -- vultraz, 2017-11-27
162  */
163  return true;
164 }
165 
167 {
169 }
170 
172 {
173  dispatcher.connect_signal<LEFT_BUTTON_CLICK>(signal);
174 }
175 
177 {
178  dispatcher.disconnect_signal<LEFT_BUTTON_CLICK>(signal);
179 }
180 
182 {
184 }
185 
187 {
188  dispatcher.connect_signal<NOTIFY_MODIFIED>(signal);
189 }
190 
192 {
193  // TODO: evaluate whether draw events need go in this queue position.
194  dispatcher.connect_signal<DRAW>(signal, dispatcher::front_child);
195 }
196 
197 } // namespace event
198 
199 } // namespace gui2
200 
201 /**
202  * @page event_dispatching Event dispatching.
203  *
204  * @section introduction Introduction
205  *
206  * This page describes how the new event handling system works, since the
207  * system is still work in progress it might be out of date with the actual
208  * code. It also contains some ideas that might change later on. Some parts are
209  * explained in the interface and will be integrated in this document later.
210  *
211  * Since the event handling code hasn't been cast in stone yet some scenarios
212  * for solving the problem are discussed first and then the solution that is
213  * chosen in more detail.
214  *
215  * After SDL has generated and event it needs to be turned into an event which
216  * the widgets can use.
217  *
218  * @section handling_solution The implementation solutions.
219  *
220  * For the event handling we use a few use case scenarios and show the possible
221  * solutions.
222  *
223  * @subsection sample The sample window
224  *
225  * In our samples we use this sample window with the following components:
226  * - a window W
227  * - a container C
228  * - a button B
229  *
230  * These are arranged accordingly:
231  * @code
232  *
233  * ---------------------
234  * |W |
235  * | |
236  * | ----------------- |
237  * | |C |^| |
238  * | | |-| |
239  * | | ---------- |#| |
240  * | | |B | | | |
241  * | | ---------- | | |
242  * | | |-| |
243  * | | |v| |
244  * | ----------------- |
245  * | |
246  * ---------------------
247  *
248  * @endcode
249  *
250  * @subsection scenarios Possible scenarios
251  *
252  * The scenarios are:
253  * - An event that is wanted by none.
254  * - A mouse down event that should focus C and set the pressed state in B.
255  * - A mouse wheel event, which first should be offered to B and if not handled
256  * by B should be handled by C.
257  *
258  * @subsection all_queues Pass the event through all queues
259  *
260  * In this solution the event will be passed through all possible queues and
261  * tries sees where the event sticks. This following sections describe how the
262  * events are tried for this usage scenario.
263  *
264  * @subsubsection unhandled Unhandled event
265  *
266  * - W pre child
267  * - C pre child
268  * - B pre child
269  * - W child
270  * - C child
271  * - B child
272  * - W post child
273  * - C post child
274  * - B post child
275  *
276  * @subsubsection mouse_down Mouse down
277  *
278  * - W pre child
279  * - C pre child -> set focus -> !handled
280  * - B pre child -> set pressed state -> handled
281  *
282  * @subsubsection mouse_wheel Mouse wheel
283  *
284  * - W pre child
285  * - C pre child
286  * - B pre child -> We can't scroll so ignore
287  * - W child
288  * - C child
289  * - B child
290  * - W post child
291  * - C post child -> Scroll -> handled
292  *
293  * @subsection chain Pass the events in a chain like fashion
294  *
295  * In this solution the events are send to the pre- and post queue of all but
296  * the last possible widget and to the child of the last widget. The pre queue
297  * will be send from top to bottom, the post queue from bottom to top.
298  *
299  * @subsubsection unhandled Unhandled event
300  *
301  * - W pre child
302  * - C pre child
303  * - B child
304  * - C post child
305  * - W post child
306  *
307  * @subsubsection mouse_down Mouse down
308  *
309  * - W pre child
310  * - C pre child -> set focus -> !handled
311  * - B child -> set pressed state -> handled
312  *
313  * @subsubsection mouse_wheel Mouse wheel
314  *
315  * - W pre child
316  * - C pre child
317  * - B child -> We can't scroll so ignore
318  * - C post child -> Scroll -> handled
319  *
320  * @subsection evaluation Evaluation
321  *
322  * When using the first solution it's possible to drop the child queue since
323  * everything falls in pre or post. But there is a scenario that's a bit ugly
324  * to solve with the first solution:
325  *
326  * Assume there is a listbox with toggle panels and on the panel there are a
327  * few buttons, the wanted behavior is:
328  * - if clicked on the panel it should toggle, which may or may not be allowed.
329  * - if clicked on a button in the panel, we want to make sure the panel is
330  * selected, which again may or may not be allowed.
331  *
332  * With solution 2 it's rather easy:
333  *
334  * Click on panel:
335  * - W pre child
336  * - C child -> Test whether we can toggle -> handled, halt = !toggled
337  *
338  * Click on button in panel:
339  * - W pre child
340  * - C pre child -> Test whether we can select -> handled = halt = !selected
341  * - B child -> do button stuff -> handled
342  *
343  * Since for the different clicks, different queues are triggered it's easy to
344  * add a different handler there.
345  *
346  * With solution 1:
347  *
348  * Click on panel:
349  * - W pre child
350  * - C pre child -> handler 1 -> if last in queue -> solution 2 C child
351  *
352  * Click on button in panel:
353  * - W pre child
354  * - C pre child -> handler 2 -> if !last in queue -> solution 2 C pre child
355  * - B pre child -> do button stuff -> handled
356  *
357  * Not that different from solution 2, the two handlers are installed in the C
358  * pre event. But we need to manually check whether we're really the last,
359  * which means the code to check whether there are more handlers at a lower
360  * level is needed for both solutions. In solution 1 this test needs to be done
361  * twice versus once in solution 2. Also the fact that the queues for the
362  * events are processed in reverse order on the way back sounds more
363  * initiative.
364  *
365  * @section processing_raw_events Processing the raw events.
366  *
367  * This section describes how the events generated by SDL are send as our own
368  * events to the various widgets. The first step in sending an event is to
369  * decode it and send it to a registered dispatcher.
370  *
371  * - gui2::event::sdl_event_handler handles the SDL events.
372  * - gui2::event::dispatcher has the registered dispatchers.
373  *
374  * In general a dispatcher is a window which then needs to send this event to
375  * the widgets. The dispatcher is just a simple part which fires events and
376  * finds a handler for the event. This is not to the liking of most widgets,
377  * they don't want to handle raw events but get a polished and clean event. No
378  * button up and down and then try to figure out whether it needs to act as if
379  * it was clicked upon, no simply op and down to change the appearance and a
380  * click event to do the clicking actions. And don't even try to convince a
381  * widget to determine whether this up event was a single or double click.
382  * Widgets like to sleep with nice dreams and not having nightmares where SDL
383  * events haunt them.
384  *
385  * In order to remedy that problem there's the gui2::event::distributor
386  * class, it's the class to do the dirty job of converting the raw event into
387  * these nice polished events. The distributor is in general linked to a window,
388  * but a widget can install it's own distributor if it needs to know more of the
389  * raw events as still left in the polished events. At the time of this writing
390  * no widget needs this feature, but the toggle panel might need it.
391  *
392  * After the distributor has polished the event and send it on its way to the
393  * widget the dispatcher needs to make sure the event is properly dispatched to
394  * the widget in question and also notify its parents by means of the previously
395  * described event chain.
396  *
397  * @subsection sdl_event Get the SDL events
398  *
399  * The first step in event handling is getting the events in the first place.
400  * Events are generated by SDL and placed in a queue. The Wesnoth code processes
401  * this queue and thus handles the events. The part which does the first
402  * handling isn't described here since it's (secretly) intended to be replaced
403  * by the @ref gui2::event::sdl_event_handler class. Instead we directly jump to this
404  * class and explain what it does.
405  *
406  * The main handling function is @ref gui2::event::sdl_event_handler::handle_event which
407  * as no real surprise handles the events. The function is a simple multiplexer
408  * which lets other subfunctions to the handling of specific events.
409  *
410  * @todo Describe drawing and resizing once the code is stable and working as
411  * wanted in these areas.
412  *
413  * @subsubsection handler_mouse Mouse motion events
414  *
415  * If a dispatcher has captured the mouse it gets the event, no questions asked.
416  * If not it goes through all dispatchers and finds the first one willing to
417  * accept the mouse event.
418  *
419  * This means a mouse event is send to one dispatcher.
420  *
421  * @subsubsection handler_mouse_button_down Mouse button down events
422  *
423  * Turning the mouse wheel on a mouse generates both an down and up event. It
424  * has been decided to handle the wheel event in the button up code so wheel
425  * events are here directly dropped on the floor and forgotten.
426  *
427  * The other buttons are handled as if they're normal mouse events but are
428  * decoded per button so instead of a button_down(id) you get button_down_id.
429  *
430  * @subsubsection handler_mouse_button_up Mouse button up events
431  *
432  * The mouse wheel event is handled as if it's a keyboard event and like the
433  * button_down they are send as wheel_id events.
434  *
435  * The other mouse buttons are handled the same as the down buttons.
436  *
437  * @subsubsection handler_keyboard Keyboard events
438  *
439  * There are three types of keyboard events, the already mentioned mouse wheel
440  * events, the key down and key up event. When a key is pressed for a longer
441  * time several key down events are generated and only one key up, this means
442  * the key up is rather useless. Guess what, the multiplexer already drops that
443  * event so we never get it.
444  *
445  * If the keyboard event is a mouse wheel event it's directly send to the
446  * dispachting queue; either the dispatcher that captured the keyboard or the
447  * last dispatcher in the queue.
448  *
449  * If the event is a real keyboard action it's first tried as hotkey. In order
450  * to do so the target dispatcher is first determined, either the dispatcher
451  * that captured the keyboard or the last dispatcher in the queue. Then it's
452  * tried whether a hotkey and whether the hotkey can be processed. If the
453  * hotkey isn't processed the keyboard event is send to the dispatcher as
454  * normal keyboard event.
455  *
456  * The hotkey processing will have several queues (to be implemented in 1.9):
457  * - global hotkeys that always work eg toggling fullscreen mode.
458  * - main screen hotkeys, these work when one of the dialogs is shown without
459  * other dialogs on top of them. These hotkeys are for example
460  * preferences. The main screens are:
461  * - title screen
462  * - game
463  * - editor
464  * - mp lobby
465  * - map screen hotkeys, these work when a map is shown eg toggle grid. The
466  * screens are:
467  * - game
468  * - editor
469  * - local hotkeys, these are hotkeys that only work in a specific dialog eg
470  * recruit unit only works in the game screen.
471  *
472  * The queues are processed in from bottom to top in the list above, this
473  * allows an item to use a hotkey but have another handler function. Eg
474  * preferences in the editor might open another preferences dialog.
475  *
476  * @todo The hotkeys need to be implemented like above in 1.9.
477  *
478  * @todo This might change in the near future.
479  *
480  * @subsection distributor Event polishing and distribution
481  *
482  * The event distributor has the job to find the widget that should receive the
483  * event and which event(s) to send from a single event. In general an event is
484  * first send to the widget as-is, sending the raw events allows other
485  * distributors to be nested between this distributor and the intended target
486  * widget. Or the intended widget might not really be the intended widget but
487  * another distributor that wants to dispatch the event internally.
488  *
489  * However in the common cases this raw event isn't handled and the distributor
490  * needs to send the polished events. In the following sections the details of
491  * the conversion from raw to polished is described, it intentionally lacks the
492  * part of sending the raw events as well since it adds no value.
493  *
494  * A widget can capture the mouse, which means all mouse events are send to this
495  * widget, regardless where the mouse is. This is normally done in a mouse down
496  * event (for a button) so all events following it are send to that widget.
497  *
498  * @subsection mouse_motion Mouse motion
499  *
500  * This section describes the conversion from a raw mouse motion to the polished
501  * events it can generate:
502  * - @ref gui2::event::MOUSE_ENTER "MOUSE_ENTER"
503  * - @ref gui2::event::MOUSE_LEAVE "MOUSE_LEAVE"
504  * - @ref gui2::event::MOUSE_MOTION "MOUSE_MOTION"
505  *
506  * When the mouse is captured that widget will only receive motion events.
507  *
508  * If not captured the code checks whether the widget underneath the mouse is
509  * the same widget as at the last motion if event. If so that widget gets a
510  * motion event.
511  * If not the widget that before was underneath the mouse pointer (if any) gets
512  * a leave event and the widget newly underneath the mouse pointer (if any) gets
513  * an enter event.
514  *
515  * @subsection mouse_button Mouse buttons
516  *
517  * The mouse button code is a bit more complex and is separated in the various
518  * events to be send.
519  *
520  * @subsubsection mouse_button_down Mouse button down
521  *
522  * Some things start simple, so does the event of pressing down a mouse button.
523  * All it does is send the event to the widget as one of the following events:
524  * - @ref gui2::event::LEFT_BUTTON_DOWN "LEFT_BUTTON_DOWN"
525  * - @ref gui2::event::MIDDLE_BUTTON_DOWN "MIDDLE_BUTTON_DOWN"
526  * - @ref gui2::event::RIGHT_BUTTON_DOWN "RIGHT_BUTTON_DOWN"
527  *
528  * @todo Validate the code it seems a down event with a captured mouse doesn't
529  * really work as wanted. (Rare case but should work properly.) In general the
530  * mouse event handling needs testing to see whether the proper events are send
531  * all the time.
532  *
533  * @subsubsection mouse_button_up Mouse button up
534  *
535  * Simplicity ends here.
536  *
537  * @todo Document further.
538  *
539  * @subsubsection mouse_click Mouse click
540  *
541  * So the button up event has asked for mouse click, now we need to test whether
542  * the click will be a click or a double click. A double click is generated when
543  * the same widget is clicked twice in a short time and causes the following
544  * events:
545  * - @ref gui2::event::LEFT_BUTTON_DOUBLE_CLICK "LEFT_BUTTON_DOUBLE_CLICK"
546  * - @ref gui2::event::MIDDLE_BUTTON_DOUBLE_CLICK "MIDDLE_BUTTON_DOUBLE_CLICK"
547  * - @ref gui2::event::RIGHT_BUTTON_DOUBLE_CLICK "RIGHT_BUTTON_DOUBLE_CLICK"
548  *
549  * Otherwise one of the following single clicks is generated:
550  * - @ref gui2::event::LEFT_BUTTON_CLICK "LEFT_BUTTON_CLICK"
551  * - @ref gui2::event::MIDDLE_BUTTON_CLICK "MIDDLE_BUTTON_CLICK"
552  * - @ref gui2::event::RIGHT_BUTTON_CLICK "RIGHT_BUTTON_CLICK"
553  *
554  * @subsubsection double_click To double click or not to double click
555  *
556  * Wait a second, a widget has a field whether or not it wants a double click
557  * for a certain mouse button and now I see that it's bluntly ignored by the
558  * distributor. Indeed the distributor doesn't care about what the widget wants,
559  * it does what it wants and leaves the sorting out what's wanted to the
560  * dispatcher.
561  *
562  * The problem is that in the chain events are send to one widget that may not
563  * be interested in a double click, but another widget in the chain is. There
564  * are several solutions to this problem:
565  * -# Sending a click followed by a double click.
566  * -# Sending a click with a tag field that it actually is a double click.
567  * -# Send a double click and turn it into a click if the double click is
568  * unwanted.
569  *
570  * The first solution has the disadvantage that a toggle panel likes a click and
571  * double click, the first click selects the second deselects and now the
572  * deselected panel gets a double click. When the panel now checks whether it's
573  * selected it's not and might take the wrong action upon it.
574  *
575  * The second option is possible but would be rather intrusive in the code,
576  * since it would generate another event signature. Adding a signature just for
577  * this special case seemed a bit too much effort vs. gain. Also the widget
578  * needs to check whether a click is a click or a double click and choose a
579  * different code path for it. This in turn would mean a signal handler
580  * secretly might handle two events and lowers the transparency of the code.
581  *
582  * The third option also adds some special case handling but the scope is
583  * limited and only one part knows about the tricks done.
584  *
585  * The last option has been chosen and the dispatcher build the event chain and
586  * while building the chain it looks whether the widget wants the double click
587  * or not. It does this test by looking at the wants double click function and
588  * not test for a handler. The double click test function is made for this
589  * purpose and depending on the handler might again do the wrong thing.
590  * (A certain toggle panel might not want to do something on a double click but
591  * also not being deselected upon a double click. The latter to keep the UI
592  * consistent, a double click on a toggle panel might execute a special function
593  * or not, but always keep the panel selected. (That is if the panel can be
594  * selected.))
595  */
Define the common log macros for the gui toolkit.
dispatcher_callback_func< const SDL_Keycode, const SDL_Keymod, const std::string & > signal_keyboard_function
Callback function signature.
Definition: dispatcher.hpp:219
Base class for event handling.
Definition: dispatcher.hpp:306
constexpr bool is_message_event(const ui_event event)
Helper for catching use error of dispatcher::connect_signal.
Definition: dispatcher.hpp:148
void register_hotkey(const hotkey::HOTKEY_COMMAND id, const hotkey_function &function)
Registers a hotkey.
Definition: dispatcher.cpp:141
See LEFT_BUTTON_CLICK.
Definition: handler.hpp:76
bool fire_event_double_click(dispatcher *dsp, widget *wgt, F &&... params)
An SDL key down event.
Definition: handler.hpp:83
dispatcher_callback_func< void * > signal_notification_function
Callback function signature.
Definition: dispatcher.hpp:254
Base class for all widgets.
Definition: widget.hpp:49
See LEFT_BUTTON_DOUBLE_CLICK.
Definition: handler.hpp:77
See LEFT_BUTTON_CLICK.
Definition: handler.hpp:69
static bool has_handler(dispatcher &dispatcher, const dispatcher::event_queue_type queue_type, ui_event event)
A helper to test whether dispatcher has an handler for a certain event.
constexpr bool is_general_event(const ui_event event)
Helper for catching use error of dispatcher::connect_signal.
Definition: dispatcher.hpp:46
std::enable_if_t< is_general_event(E)> disconnect_signal(const signal_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_event.
Definition: dispatcher.hpp:522
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
dispatcher_callback_func<> signal_function
Callback function signature.
Definition: dispatcher.hpp:197
constexpr bool is_touch_motion_event(const ui_event event)
Helper for catching use error of dispatcher::connect_signal.
Definition: dispatcher.hpp:108
bool has_event(const ui_event event, const event_queue_type event_type)
Definition: dispatcher.cpp:57
Generic file dialog.
Definition: field-fwd.hpp:22
Sent by a widget to notify others its contents or state are modified.
Definition: handler.hpp:88
The message callbacks hold a reference to a message.
Definition: message.hpp:45
size_t len
Definition: result_set.cpp:277
std::function< void(widget &dispatcher, hotkey::HOTKEY_COMMAND id)> hotkey_function
Hotkey function handler signature.
Definition: dispatcher.hpp:289
void connect()
Connects the dispatcher to the event handler.
Definition: dispatcher.cpp:50
constexpr bool is_keyboard_event(const ui_event event)
Helper for catching use error of dispatcher::connect_signal.
Definition: dispatcher.hpp:98
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification_function &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.cpp:186
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal_function &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:171
Periodic redraw request.
Definition: handler.hpp:49
bool execute_hotkey(const hotkey::HOTKEY_COMMAND id)
Executes a hotkey.
Definition: dispatcher.cpp:146
constexpr bool is_mouse_event(const ui_event event)
Helper for catching use error of dispatcher::connect_signal.
Definition: dispatcher.hpp:71
void disconnect_dispatcher(dispatcher *dispatcher)
Disconnects a dispatcher to the event handler.
Definition: handler.cpp:900
This file contains the definitions for the gui2::event::message class.
void connect_dispatcher(dispatcher *dispatcher)
Connects a dispatcher to the event handler.
Definition: handler.cpp:893
constexpr bool is_touch_gesture_event(const ui_event event)
Helper for catching use error of dispatcher::connect_signal.
Definition: dispatcher.hpp:118
void connect_signal_mouse_left_double_click(dispatcher &dispatcher, const signal_function &signal)
Connects a signal handler for a left mouse button double click.
Definition: dispatcher.cpp:181
bool wants_mouse_right_double_click() const
std::map< hotkey::HOTKEY_COMMAND, hotkey_function > hotkeys_
The registered hotkeys for this dispatcher.
std::enable_if_t< is_general_event(E)> connect_signal(const signal_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_event.
Definition: dispatcher.hpp:505
bool connected_
Are we connected to the event handler.
A left mouse button double click event for a widget.
Definition: handler.hpp:63
Holds a 2D point.
Definition: point.hpp:23
hotkey_list hotkeys_
Definition: hotkey_item.cpp:40
bool wants_mouse_left_double_click() const
void connect_signal_pre_key_press(dispatcher &dispatcher, const signal_keyboard_function &signal)
Connects the signal for &#39;snooping&#39; on the keypress.
Definition: dispatcher.cpp:166
void disconnect_signal_mouse_left_click(dispatcher &dispatcher, const signal_function &signal)
Disconnects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:176
constexpr bool is_raw_event_event(const ui_event event)
Helper for catching use error of dispatcher::connect_signal.
Definition: dispatcher.hpp:160
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:68
constexpr bool is_notification_event(const ui_event event)
Helper for catching use error of dispatcher::connect_signal.
Definition: dispatcher.hpp:130
EXIT_STATUS start(const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
Definition: editor_main.cpp:28
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
constexpr bool is_text_input_event(const ui_event event)
Helper for catching use error of dispatcher::connect_signal.
Definition: dispatcher.hpp:170
See LEFT_BUTTON_DOUBLE_CLICK.
Definition: handler.hpp:70
bool wants_mouse_middle_double_click() const
A left mouse button click event for a widget.
Definition: handler.hpp:62
std::string::const_iterator iterator
Definition: tokenizer.hpp:24
ui_event
The event send to the dispatcher.
Definition: handler.hpp:47
void connect_signal_on_draw(dispatcher &dispatcher, const signal_function &signal)
Connects a signal handler for a callback when the widget is drawn.
Definition: dispatcher.cpp:191