The Battle for Wesnoth  1.19.4+dev
dispatcher.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 
20 #include "utils/general.hpp"
21 
22 #include <SDL2/SDL_events.h>
23 
24 #include <functional>
25 #include <list>
26 #include <map>
27 
28 struct point;
29 
30 namespace gui2
31 {
32 class widget;
33 
34 namespace event
35 {
36 struct message;
37 
38 /**
39  * Callback function signature alias template.
40  *
41  * All callbacks take these four arguments in addition to any arguments
42  * specified by the parameter pack.
43  *
44  * Parameters:
45  * 1. The widget handling this event.
46  * 2. The event type.
47  * 3. Reference to the flag controlling whether this event has been handled.
48  * 4. Reference to the flag controlling whether to halt execution of this event.
49  */
50 template<typename... T>
51 using dispatcher_callback = std::function<void(widget&, const ui_event, bool&, bool&, T...)>;
52 
53 /**
54  * Used for events in event_category::general.
55  */
57 
58 /**
59  * Used for events in event_category::mouse.
60  *
61  * Extra parameters:
62  * 5. The x,y coordinate of the mouse when this event is fired.
63  */
65 
66 /**
67  * Used for events in event_category::keyboard.
68  *
69  * Extra parameters:
70  * 5. The keycode of the key that triggered this event.
71  * 6. Any applicable active modifer key.
72  * 7. Any applicable text associated with the key.
73  */
75 
76 /**
77  * Used for events in event_category::touch_motion.
78  *
79  * Extra parameters:
80  * 5. Origin of the touch event, in x,y format.
81  * 6. Number of pixels dragged, in x,y format.
82  */
84 
85 /**
86  * Used for events in event_category::touch_gesture.
87  *
88  * Extra parameters: (TODO: document what these actually are)
89  * 5. center
90  * 6. dTheta
91  * 7. dDist
92  * 8. numFingers
93  */
95 
96 /**
97  * Used for events in event_category::notification.
98  *
99  * Extra parameters:
100  * 5. A dummy void* parameter which will always be nullptr, used to differentiate
101  * this function from signal.
102  */
104 
105 /**
106  * Used for events in event_category::message.
107  *
108  * Extra parameters:
109  * 5. The applicable data this event requires.
110  */
112 
113 /**
114  * Used for events in event_category::raw_event.
115  *
116  * Extra parameters:
117  * 5. The raw SDL_Event.
118  */
120 
121 /**
122  * Used for eventsin event_category::text_input.
123  *
124  * Extra parameters:
125  * 5. The text entered.
126  * 6. The current input position.
127  * 7. The current text selection length.
128  */
130 
131 /** Hotkey function handler signature. */
132 using hotkey_function = std::function<void(widget& dispatcher, hotkey::HOTKEY_COMMAND id)>;
133 
134 /**
135  * Base class for event handling.
136  *
137  * A dispatcher has slots for events, when an event arrives it looks for the
138  * functions that registered themselves for that event and calls their
139  * callbacks.
140  *
141  * This class is a base class for all widgets[1], what a widget does on a
142  * callback can differ greatly, an image might ignore all events a window can
143  * track the mouse location and fire MOUSE_ENTER and MOUSE_LEAVE events to the
144  * widgets involved.
145  *
146  * [1] Not really sure whether it will be a base class for a widget or
147  * styled_widget yet.
148  */
150 {
152 
153 public:
154  dispatcher();
155  virtual ~dispatcher();
156 
157  /**
158  * Connects the dispatcher to the event handler.
159  *
160  * When a dispatcher is connected to the event handler it will get the
161  * events directly from the event handler. This is wanted for top level
162  * items like windows but not for most other widgets.
163  *
164  * So a window can call connect to register itself, it will automatically
165  * disconnect upon destruction.
166  */
167  void connect();
168 
169  /**
170  * Disconnects the dispatcher from the event handler.
171  */
172  void disconnect();
173 
174  /** Return whether the dispatcher is currently connected. */
175  bool is_connected() const
176  {
177  return connected_;
178  }
179 
180  /**
181  * Determines whether the location is inside an active widget.
182  *
183  * This is used to see whether a mouse event is inside the widget.
184  *
185  * @param coordinate The coordinate to test whether inside the
186  * widget.
187  *
188  * @result True if inside an active widget, false
189  * otherwise.
190  */
191  virtual bool is_at(const point& coordinate) const = 0;
192 
194  pre = 1,
195  child = 2,
196  post = 4
197  };
198 
199  bool has_event(const ui_event event, const event_queue_type event_type);
200 
201  /** Fires an event which has no extra parameters. */
202  bool fire(const ui_event event, widget& target);
203 
204  /**
205  * Fires an event which takes a coordinate parameter.
206  *
207  * @param event The event to fire.
208  * @param target The widget that should receive the event.
209  * @param coordinate The mouse position for the event.
210  */
211  bool fire(const ui_event event, widget& target, const point& coordinate);
212 
213  /**
214  * Fires an event which takes keyboard parameters.
215  *
216  * @param event The event to fire.
217  * @param target The widget that should receive the event.
218  * @param key The SDL key code of the key pressed.
219  * @param modifier The SDL key modifiers used.
220  * @param unicode The unicode value for the key pressed.
221  */
222  bool fire(const ui_event event,
223  widget& target,
224  const SDL_Keycode key,
225  const SDL_Keymod modifier,
226  const std::string& unicode);
227 
228  /**
229  * Fires an event which takes touch-motion parameters.
230  *
231  * @param event The event to fire.
232  * @param target The widget that should receive the event.
233  * @param pos The location touched.
234  * @param distance The distance moved.
235  */
236  bool fire(const ui_event event, widget& target, const point& pos, const point& distance);
237 
238  /**
239  * Fires an event which takes touch-gesture parameters.
240  *
241  * @param event The event to fire.
242  * @param target The widget that should receive the event.
243  * @param center The location touched.
244  * @param dTheta Probably the direction moved.
245  * @param dDist The distance moved.
246  * @param numFingers Probably the number of fingers touching the screen.
247  */
248  bool fire(const ui_event event, widget& target, const point& center, float dTheta, float dDist, uint8_t numFingers);
249 
250  /**
251  * Fires an event which takes notification parameters.
252  *
253  * @note the void* parameter is a dummy needed for SFINAE.
254  *
255  * @param event The event to fire.
256  * @param target The widget that should receive the event.
257  */
258  bool fire(const ui_event event, widget& target, void*);
259 
260  /**
261  * Fires an event which takes message parameters.
262  *
263  * @param event The event to fire.
264  * @param target The widget that should receive the event.
265  * Normally this is the window holding the
266  * widget.
267  * @param msg The extra information needed for a window
268  * (or another widget in the chain) to handle
269  * the message.
270  */
271  bool fire(const ui_event event, widget& target, const message& msg);
272 
273  /**
274  * Fires an event that's a raw SDL event
275  * @param event The event to fire.
276  * @param target The widget that should receive the event.
277  * Normally this is the window holding the
278  * widget.
279  * @param sdlevent The raw SDL event
280  */
281  bool fire(const ui_event event, widget& target, const SDL_Event& sdlevent);
282 
283  /**
284  * Fires an event which takes text input parameters
285  * @param event The event to fire.
286  * @param target The widget that should receive the event.
287  * Normally this is the window holding the
288  * widget.
289  * @param text The text involved in the event
290  * @param start The start point for IME editing
291  * @param len The selection length for IME editing
292  */
293  bool fire(const ui_event event, widget& target, const std::string& text, int32_t start, int32_t len);
294 
295  /**
296  * The position where to add a new callback in the signal handler.
297  *
298  * The signal handler has three callback queues:
299  * * pre_child These callbacks are called before a container widget sends it
300  * to the child items. Widgets without children should also use this
301  * queue.
302  * * child The callbacks for the proper child widget(s) are called.
303  * * post_child The callbacks for the parent container to be called after
304  * the child.
305  *
306  * For every queue it's possible to add a new event in the front or in the
307  * back.
308  *
309  * Whether all three queues are executed depend on the whether the
310  * callbacks modify the handled and halt flag.
311  * * When the halt flag is set execution of the current queue stops, when
312  * doing so the handled flag must be set as well.
313  * * When the handled flag is set the events in that queue are executed and
314  * no more queues afterwards.
315  *
316  * Here are some use case examples.
317  * A button that plays a sound and executes an optional user callback:
318  * * The buttons internal click handler is invoked and sets the handled
319  * flag
320  * * The callback installed by the user is in the same queue and gets
321  * executed afterwards.
322  *
323  * A toggle button may or may not be toggled:
324  * * The user inserts a callback, that validates whether the action is
325  * allowed, if not allowed it sets the halt flag (and handled), else
326  * leaves the flags untouched.
327  * * The normal buttons toggle function then might get invoked and if so
328  * sets the handled flag.
329  * * Optionally there is another user callback invoked at this point.
330  */
338  };
339 
340  /**
341  * Adds a callback to the appropriate queue based on event type.
342  *
343  * @tparam E The event the callback needs to react to.
344  * @tparam F The event signature. This must match the
345  * appropriate queue's callback signature.
346  *
347  * @param func The callback function.
348  * @param position The position to place the callback.
349  */
350  template<ui_event E, typename F>
351  void connect_signal(const F& func, const queue_position position = back_child)
352  {
353  get_signal_queue<get_event_category(E)>().connect_signal(E, position, func);
354  }
355 
356  /**
357  * Removes a callback from the appropriate queue based on event type.
358  *
359  * @tparam E The event the callback needs to react to.
360  * @tparam F The event signature. This must match the
361  * appropriate queue's callback signature.
362  *
363  * @param func The callback function.
364  * @param position The place where the function was added.
365  * Needed remove the event from the right
366  * place. (The function doesn't care whether
367  * was added in front or back.)
368  */
369  template<ui_event E, typename F>
370  void disconnect_signal(const F& func, const queue_position position = back_child)
371  {
372  get_signal_queue<get_event_category(E)>().disconnect_signal(E, position, func);
373  }
374 
375  /**
376  * The behavior of the mouse events.
377  *
378  * Normally for mouse events there's first checked whether a dispatcher has
379  * captured the mouse if so it gets the event.
380  * If not the dispatcher is searched from the back to the front in the
381  * layers and its behavior is checked.
382  * * none The event is never send to the layer and goes on the the next
383  * layer. This is used for tooltips who might cover a button but a click
384  * on the tooltips should still click the button.
385  * * all The event is always send to this layer and stops the search for a
386  * next layer.
387  * * hit If the mouse is inside the dispatcher area the event is send and
388  * no longer searched further. If not inside tests the last layer.
389  *
390  * If after these tests no dispatcher is found the event is ignored.
391  */
392  enum class mouse_behavior {
393  all,
394  hit,
395  none
396  };
397 
398  /** Captures the mouse. */
400  {
402  }
403 
404  /** Releases the mouse capture. */
406  {
408  }
409 
410  /***** ***** ***** setters/getters ***** ***** *****/
411 
413  {
415  }
416 
418  {
419  return mouse_behavior_;
420  }
421 
422  void set_want_keyboard_input(const bool want_keyboard_input)
423  {
424  want_keyboard_input_ = want_keyboard_input;
425  }
426 
428  {
429  return want_keyboard_input_;
430  }
431 
432  /**
433  * Registers a hotkey.
434  *
435  * @todo add a static function register_global_hotkey.
436  *
437  * Once that's done execute_hotkey will first try to execute a global
438  * hotkey and if that fails tries the hotkeys in this dispatcher.
439  *
440  * @param id The hotkey to register.
441  * @param function The callback function to call.
442  */
443  void register_hotkey(const hotkey::HOTKEY_COMMAND id, const hotkey_function& function);
444 
445  /**
446  * Executes a hotkey.
447  *
448  * @param id The hotkey to execute.
449  *
450  * @returns true if the hotkey is handled, false
451  * otherwise.
452  */
453  bool execute_hotkey(const hotkey::HOTKEY_COMMAND id);
454 
455 private:
456  /** Helper struct to generate the various signal types. */
457  template<class T>
458  struct signal_type
459  {
460  signal_type() = default;
461 
462  std::list<T> pre_child;
463  std::list<T> child;
464  std::list<T> post_child;
465 
466  /**
467  * Checks whether the queue of a given type is empty.
468  *
469  * @param queue_type The queue to check. This may be one or more types
470  * OR'd together (event_queue_type is bit-unique).
471  *
472  * @returns True if ALL the matching queues are empty, or false
473  * if any of the matching queues is NOT empty.
474  */
475  bool empty(const dispatcher::event_queue_type queue_type) const
476  {
477  if((queue_type & dispatcher::pre) && !pre_child.empty()) {
478  return false;
479  }
480 
481  if((queue_type & dispatcher::child) && !child.empty()) {
482  return false;
483  }
484 
485  if((queue_type & dispatcher::post) && !post_child.empty()) {
486  return false;
487  }
488 
489  return true;
490  }
491  };
492 
493  /** Helper struct to generate the various event queues. */
494  template<class T>
496  {
497  signal_queue() = default;
498 
499  signal_queue(const signal_queue&) = delete;
501 
502  using callback = T;
503  std::map<ui_event, signal_type<T>> queue;
504 
505  void connect_signal(const ui_event event, const queue_position position, const T& signal)
506  {
507  switch(position) {
508  case front_pre_child:
509  queue[event].pre_child.push_front(signal);
510  break;
511  case back_pre_child:
512  queue[event].pre_child.push_back(signal);
513  break;
514 
515  case front_child:
516  queue[event].child.push_front(signal);
517  break;
518  case back_child:
519  queue[event].child.push_back(signal);
520  break;
521 
522  case front_post_child:
523  queue[event].post_child.push_front(signal);
524  break;
525  case back_post_child:
526  queue[event].post_child.push_back(signal);
527  break;
528  }
529  }
530 
531  void disconnect_signal(const ui_event event, const queue_position position, const T& signal)
532  {
533  // This is std::function<T>::target_type()
534  const auto predicate = [&signal](const T& element) { return signal.target_type() == element.target_type(); };
535 
536  /* The function doesn't differentiate between front and back position so fall
537  * down from front to back.
538  *
539  * NOTE: This used to only remove the first signal of matching target type.
540  * That behavior could be restored in the future if needed.
541  * - vultraz, 2017-05-02
542  */
543  switch(position) {
544  case front_pre_child:
545  [[fallthrough]];
546  case back_pre_child:
547  queue[event].pre_child.remove_if(predicate);
548  break;
549 
550  case front_child:
551  [[fallthrough]];
552  case back_child:
553  queue[event].child.remove_if(predicate);
554  break;
555 
556  case front_post_child:
557  [[fallthrough]];
558  case back_post_child:
559  queue[event].post_child.remove_if(predicate);
560  break;
561  }
562  }
563  };
564 
565  /** The mouse behavior for the dispatcher. */
567 
568  /**
569  * Does the dispatcher want to receive keyboard input.
570  *
571  * @todo The entire mouse and keyboard handling can use a code review to
572  * seen whether it might be combined in one flag field. At the moment the
573  * keyboard doesn't look whether a dialog has the mouse focus before
574  * sending the event, so maybe we should add an active dispatcher to keep
575  * track of it. But since at the moment there are only non-modal windows
576  * and tooltips it's not a problem.
577  */
579 
580  /** Signal queue for callbacks in event_category::general. */
582 
583  /** Signal queue for callbacks in event_category::mouse. */
585 
586  /** Signal queue for callbacks in event_category::keyboard. */
588 
589  /** Signal queue for callbacks in event_category::touch_motion. */
591 
592  /** Signal queue for callbacks in event_category::touch_gesture. */
594 
595  /** Signal queue for callbacks in event_category::notification. */
597 
598  /** Signal queue for callbacks in event_category::message. */
600 
601  /** Signal queue for callbacks in event_category::raw_event. */
603 
604  /** Signal queue for callbacks in event_category::text_input. */
606 
607  /** Are we connected to the event handler. */
609 
610  /** The registered hotkeys for this dispatcher. */
611  std::map<hotkey::HOTKEY_COMMAND, hotkey_function> hotkeys_;
612 
613  template<event_category cat>
615  {
616  if constexpr(cat == event_category::general) {
617  return signal_queue_;
618  } else if constexpr(cat == event_category::mouse) { // Tee hee
619  return signal_mouse_queue_;
620  } else if constexpr(cat == event_category::keyboard) {
621  return signal_keyboard_queue_;
622  } else if constexpr(cat == event_category::touch_motion) {
624  } else if constexpr(cat == event_category::touch_gesture) {
626  } else if constexpr(cat == event_category::notification) {
628  } else if constexpr(cat == event_category::message) {
629  return signal_message_queue_;
630  } else if constexpr(cat == event_category::raw_event) {
632  } else if constexpr(cat == event_category::text_input) {
634  } else {
635  static_assert(utils::dependent_false_v<decltype(cat)>, "No matching signal queue for category");
636  }
637  }
638 };
639 
640 /***** ***** ***** ***** ***** Common helpers ***** ***** ***** ***** *****/
641 
642 /*
643  * These helpers can be used to easily add callbacks to a dispatcher (widget).
644  * This is just a list of common ones all others can be used as well.
645  */
646 
647 /**
648  * Connects the signal for 'snooping' on the keypress.
649  *
650  * This callback is called before the widget itself allowing you to either
651  * snoop on the input or filter it.
652  */
653 void connect_signal_pre_key_press(dispatcher& dispatcher, const signal_keyboard& signal);
654 
655 /** Connects a signal handler for a left mouse button click. */
656 void connect_signal_mouse_left_click(dispatcher& dispatcher, const signal& signal);
657 
658 /** Disconnects a signal handler for a left mouse button click. */
659 void disconnect_signal_mouse_left_click(dispatcher& dispatcher, const signal& signal);
660 
661 /** Connects a signal handler for a left mouse button release. */
662 void connect_signal_mouse_left_release(dispatcher& dispatcher, const signal& signal);
663 
664 /** Disconnects a signal handler for a left mouse button release. */
665 void disconnect_signal_mouse_left_release(dispatcher& dispatcher, const signal& signal);
666 
667 /**
668  * Connects a signal handler for a left mouse button double click.
669  *
670  * I'm not exactly sure why this works in this queue position with toggle
671  * panels, but it does. Will revisit if it becomes an issue later (ie, if
672  * this is used with other widgets and doesn't work).
673  *
674  * - vultraz, 2017-08-23
675  */
676 void connect_signal_mouse_left_double_click(dispatcher& dispatcher, const signal& signal);
677 
678 /** Connects a signal handler for getting a notification upon modification. */
679 void connect_signal_notify_modified(dispatcher& dispatcher, const signal_notification& signal);
680 
681 /** Connects a signal handler for a callback when the widget is drawn. */
682 void connect_signal_on_draw(dispatcher& dispatcher, const signal& signal);
683 
684 } // namespace event
685 
686 } // namespace gui2
Base class for event handling.
Definition: dispatcher.hpp:150
void connect_signal(const F &func, const queue_position position=back_child)
Adds a callback to the appropriate queue based on event type.
Definition: dispatcher.hpp:351
void connect()
Connects the dispatcher to the event handler.
Definition: dispatcher.cpp:49
signal_queue< signal_touch_gesture > signal_touch_gesture_queue_
Signal queue for callbacks in event_category::touch_gesture.
Definition: dispatcher.hpp:593
queue_position
The position where to add a new callback in the signal handler.
Definition: dispatcher.hpp:331
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:74
bool has_event(const ui_event event, const event_queue_type event_type)
Definition: dispatcher.cpp:63
void set_mouse_behavior(const mouse_behavior mouse_behavior)
Definition: dispatcher.hpp:412
virtual bool is_at(const point &coordinate) const =0
Determines whether the location is inside an active widget.
signal_queue< signal_message > signal_message_queue_
Signal queue for callbacks in event_category::message.
Definition: dispatcher.hpp:599
signal_queue< signal_text_input > signal_text_input_queue_
Signal queue for callbacks in event_category::text_input.
Definition: dispatcher.hpp:605
mouse_behavior
The behavior of the mouse events.
Definition: dispatcher.hpp:392
bool get_want_keyboard_input() const
Definition: dispatcher.hpp:427
signal_queue< signal_raw_event > signal_raw_event_queue_
Signal queue for callbacks in event_category::raw_event.
Definition: dispatcher.hpp:602
signal_queue< signal_notification > signal_notification_queue_
Signal queue for callbacks in event_category::notification.
Definition: dispatcher.hpp:596
void disconnect()
Disconnects the dispatcher from the event handler.
Definition: dispatcher.cpp:56
signal_queue< signal > signal_queue_
Signal queue for callbacks in event_category::general.
Definition: dispatcher.hpp:581
mouse_behavior mouse_behavior_
The mouse behavior for the dispatcher.
Definition: dispatcher.hpp:566
bool want_keyboard_input_
Does the dispatcher want to receive keyboard input.
Definition: dispatcher.hpp:578
void set_want_keyboard_input(const bool want_keyboard_input)
Definition: dispatcher.hpp:422
void capture_mouse()
Captures the mouse.
Definition: dispatcher.hpp:399
signal_queue< signal_touch_motion > signal_touch_motion_queue_
Signal queue for callbacks in event_category::touch_motion.
Definition: dispatcher.hpp:590
void disconnect_signal(const F &func, const queue_position position=back_child)
Removes a callback from the appropriate queue based on event type.
Definition: dispatcher.hpp:370
bool connected_
Are we connected to the event handler.
Definition: dispatcher.hpp:608
bool execute_hotkey(const hotkey::HOTKEY_COMMAND id)
Executes a hotkey.
Definition: dispatcher.cpp:152
mouse_behavior get_mouse_behavior() const
Definition: dispatcher.hpp:417
void register_hotkey(const hotkey::HOTKEY_COMMAND id, const hotkey_function &function)
Registers a hotkey.
Definition: dispatcher.cpp:147
bool is_connected() const
Return whether the dispatcher is currently connected.
Definition: dispatcher.hpp:175
signal_queue< signal_keyboard > signal_keyboard_queue_
Signal queue for callbacks in event_category::keyboard.
Definition: dispatcher.hpp:587
void release_mouse()
Releases the mouse capture.
Definition: dispatcher.hpp:405
signal_queue< signal_mouse > signal_mouse_queue_
Signal queue for callbacks in event_category::mouse.
Definition: dispatcher.hpp:584
std::map< hotkey::HOTKEY_COMMAND, hotkey_function > hotkeys_
The registered hotkeys for this dispatcher.
Definition: dispatcher.hpp:611
Base class for all widgets.
Definition: widget.hpp:55
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
dispatcher_callback< const point &, float, float, uint8_t > signal_touch_gesture
Used for events in event_category::touch_gesture.
Definition: dispatcher.hpp:94
std::function< void(widget &dispatcher, hotkey::HOTKEY_COMMAND id)> hotkey_function
Hotkey function handler signature.
Definition: dispatcher.hpp:132
void connect_signal_pre_key_press(dispatcher &dispatcher, const signal_keyboard &signal)
Connects the signal for 'snooping' on the keypress.
Definition: dispatcher.cpp:172
ui_event
The event sent to the dispatcher.
Definition: handler.hpp:115
void connect_signal_on_draw(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a callback when the widget is drawn.
Definition: dispatcher.cpp:208
void disconnect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Disconnects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:182
dispatcher_callback< const std::string &, int32_t, int32_t > signal_text_input
Used for eventsin event_category::text_input.
Definition: dispatcher.hpp:129
dispatcher_callback< void * > signal_notification
Used for events in event_category::notification.
Definition: dispatcher.hpp:103
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_signal_mouse_left_release(dispatcher &dispatcher, const signal &signal)
Disconnects a signal handler for a left mouse button release.
Definition: dispatcher.cpp:192
dispatcher_callback<> signal
Used for events in event_category::general.
Definition: dispatcher.hpp:56
@ 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_signal_mouse_left_release(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button release.
Definition: dispatcher.cpp:187
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.cpp:203
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:177
dispatcher_callback< const message & > signal_message
Used for events in event_category::message.
Definition: dispatcher.hpp:111
std::function< void(widget &, const ui_event, bool &, bool &, T...)> dispatcher_callback
Callback function signature alias template.
Definition: dispatcher.hpp:51
dispatcher_callback< const SDL_Event & > signal_raw_event
Used for events in event_category::raw_event.
Definition: dispatcher.hpp:119
dispatcher_callback< const point &, const point & > signal_touch_motion
Used for events in event_category::touch_motion.
Definition: dispatcher.hpp:83
dispatcher_callback< const SDL_Keycode, const SDL_Keymod, const std::string & > signal_keyboard
Used for events in event_category::keyboard.
Definition: dispatcher.hpp:74
dispatcher_callback< const point & > signal_mouse
Used for events in event_category::mouse.
Definition: dispatcher.hpp:64
void connect_signal_mouse_left_double_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button double click.
Definition: dispatcher.cpp:198
Generic file dialog.
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
constexpr bool dependent_false_v
Workaround for the fact that static_assert(false) is invalid.
Definition: general.hpp:40
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
Helper struct to generate the various event queues.
Definition: dispatcher.hpp:496
signal_queue & operator=(const signal_queue &)=delete
signal_queue(const signal_queue &)=delete
void disconnect_signal(const ui_event event, const queue_position position, const T &signal)
Definition: dispatcher.hpp:531
void connect_signal(const ui_event event, const queue_position position, const T &signal)
Definition: dispatcher.hpp:505
std::map< ui_event, signal_type< T > > queue
Definition: dispatcher.hpp:503
Helper struct to generate the various signal types.
Definition: dispatcher.hpp:459
bool empty(const dispatcher::event_queue_type queue_type) const
Checks whether the queue of a given type is empty.
Definition: dispatcher.hpp:475
The message callbacks hold a reference to a message.
Definition: message.hpp:46
Holds a 2D point.
Definition: point.hpp:25