The Battle for Wesnoth  1.19.10+dev
dispatcher.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 
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<bool(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  template<typename Func>
444  void register_hotkey(const hotkey::HOTKEY_COMMAND id, Func&& function)
445  {
446  hotkeys_[id] = std::move(function);
447  }
448 
449  /**
450  * Executes a hotkey.
451  *
452  * @param id The hotkey to execute.
453  *
454  * @returns true if the hotkey is handled, false
455  * otherwise.
456  */
457  bool execute_hotkey(const hotkey::HOTKEY_COMMAND id);
458 
459 private:
460  /** Helper struct to generate the various signal types. */
461  template<class T>
462  struct signal_type
463  {
464  signal_type() = default;
465 
466  std::list<T> pre_child;
467  std::list<T> child;
468  std::list<T> post_child;
469 
470  /**
471  * Checks whether the queue of a given type is empty.
472  *
473  * @param queue_type The queue to check. This may be one or more types
474  * OR'd together (event_queue_type is bit-unique).
475  *
476  * @returns True if ALL the matching queues are empty, or false
477  * if any of the matching queues is NOT empty.
478  */
479  bool empty(const dispatcher::event_queue_type queue_type) const
480  {
481  if((queue_type & dispatcher::pre) && !pre_child.empty()) {
482  return false;
483  }
484 
485  if((queue_type & dispatcher::child) && !child.empty()) {
486  return false;
487  }
488 
489  if((queue_type & dispatcher::post) && !post_child.empty()) {
490  return false;
491  }
492 
493  return true;
494  }
495  };
496 
497  /** Helper struct to generate the various event queues. */
498  template<class T>
500  {
501  signal_queue() = default;
502 
503  signal_queue(const signal_queue&) = delete;
505 
506  using callback = T;
507  std::map<ui_event, signal_type<T>> queue;
508 
509  void connect_signal(const ui_event event, const queue_position position, const T& signal)
510  {
511  switch(position) {
512  case front_pre_child:
513  queue[event].pre_child.push_front(signal);
514  break;
515  case back_pre_child:
516  queue[event].pre_child.push_back(signal);
517  break;
518 
519  case front_child:
520  queue[event].child.push_front(signal);
521  break;
522  case back_child:
523  queue[event].child.push_back(signal);
524  break;
525 
526  case front_post_child:
527  queue[event].post_child.push_front(signal);
528  break;
529  case back_post_child:
530  queue[event].post_child.push_back(signal);
531  break;
532  }
533  }
534 
535  void disconnect_signal(const ui_event event, const queue_position position, const T& signal)
536  {
537  // This is std::function<T>::target_type()
538  const auto predicate = [&signal](const T& element) { return signal.target_type() == element.target_type(); };
539 
540  /* The function doesn't differentiate between front and back position so fall
541  * down from front to back.
542  *
543  * NOTE: This used to only remove the first signal of matching target type.
544  * That behavior could be restored in the future if needed.
545  * - vultraz, 2017-05-02
546  */
547  switch(position) {
548  case front_pre_child:
549  [[fallthrough]];
550  case back_pre_child:
551  queue[event].pre_child.remove_if(predicate);
552  break;
553 
554  case front_child:
555  [[fallthrough]];
556  case back_child:
557  queue[event].child.remove_if(predicate);
558  break;
559 
560  case front_post_child:
561  [[fallthrough]];
562  case back_post_child:
563  queue[event].post_child.remove_if(predicate);
564  break;
565  }
566  }
567  };
568 
569  /** The mouse behavior for the dispatcher. */
571 
572  /**
573  * Does the dispatcher want to receive keyboard input.
574  *
575  * @todo The entire mouse and keyboard handling can use a code review to
576  * seen whether it might be combined in one flag field. At the moment the
577  * keyboard doesn't look whether a dialog has the mouse focus before
578  * sending the event, so maybe we should add an active dispatcher to keep
579  * track of it. But since at the moment there are only non-modal windows
580  * and tooltips it's not a problem.
581  */
583 
584  /** Signal queue for callbacks in event_category::general. */
586 
587  /** Signal queue for callbacks in event_category::mouse. */
589 
590  /** Signal queue for callbacks in event_category::keyboard. */
592 
593  /** Signal queue for callbacks in event_category::touch_motion. */
595 
596  /** Signal queue for callbacks in event_category::touch_gesture. */
598 
599  /** Signal queue for callbacks in event_category::notification. */
601 
602  /** Signal queue for callbacks in event_category::message. */
604 
605  /** Signal queue for callbacks in event_category::raw_event. */
607 
608  /** Signal queue for callbacks in event_category::text_input. */
610 
611  /** Are we connected to the event handler. */
613 
614  /** The registered hotkeys for this dispatcher. */
615  std::map<hotkey::HOTKEY_COMMAND, hotkey_function> hotkeys_;
616 
617  template<event_category cat>
619  {
620  if constexpr(cat == event_category::general) {
621  return signal_queue_;
622  } else if constexpr(cat == event_category::mouse) { // Tee hee
623  return signal_mouse_queue_;
624  } else if constexpr(cat == event_category::keyboard) {
625  return signal_keyboard_queue_;
626  } else if constexpr(cat == event_category::touch_motion) {
628  } else if constexpr(cat == event_category::touch_gesture) {
630  } else if constexpr(cat == event_category::notification) {
632  } else if constexpr(cat == event_category::message) {
633  return signal_message_queue_;
634  } else if constexpr(cat == event_category::raw_event) {
636  } else if constexpr(cat == event_category::text_input) {
638  } else {
639  static_assert(utils::dependent_false_v<decltype(cat)>, "No matching signal queue for category");
640  }
641  }
642 };
643 
644 /***** ***** ***** ***** ***** Common helpers ***** ***** ***** ***** *****/
645 
646 /*
647  * These helpers can be used to easily add callbacks to a dispatcher (widget).
648  * This is just a list of common ones all others can be used as well.
649  */
650 
651 /**
652  * Connects the signal for 'snooping' on the keypress.
653  *
654  * This callback is called before the widget itself allowing you to either
655  * snoop on the input or filter it.
656  */
657 void connect_signal_pre_key_press(dispatcher& dispatcher, const signal_keyboard& signal);
658 
659 /** Connects a signal handler for a left mouse button click. */
660 void connect_signal_mouse_left_click(dispatcher& dispatcher, const signal& signal);
661 
662 /** Disconnects a signal handler for a left mouse button click. */
663 void disconnect_signal_mouse_left_click(dispatcher& dispatcher, const signal& signal);
664 
665 /** Connects a signal handler for a left mouse button release. */
666 void connect_signal_mouse_left_release(dispatcher& dispatcher, const signal& signal);
667 
668 /** Disconnects a signal handler for a left mouse button release. */
669 void disconnect_signal_mouse_left_release(dispatcher& dispatcher, const signal& signal);
670 
671 /**
672  * Connects a signal handler for a left mouse button double click.
673  *
674  * I'm not exactly sure why this works in this queue position with toggle
675  * panels, but it does. Will revisit if it becomes an issue later (ie, if
676  * this is used with other widgets and doesn't work).
677  *
678  * - vultraz, 2017-08-23
679  */
680 void connect_signal_mouse_left_double_click(dispatcher& dispatcher, const signal& signal);
681 
682 /** Connects a signal handler for getting a notification upon modification. */
683 void connect_signal_notify_modified(dispatcher& dispatcher, const signal_notification& signal);
684 
685 } // namespace event
686 
687 } // 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:597
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:603
signal_queue< signal_text_input > signal_text_input_queue_
Signal queue for callbacks in event_category::text_input.
Definition: dispatcher.hpp:609
void register_hotkey(const hotkey::HOTKEY_COMMAND id, Func &&function)
Registers a hotkey.
Definition: dispatcher.hpp:444
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:606
signal_queue< signal_notification > signal_notification_queue_
Signal queue for callbacks in event_category::notification.
Definition: dispatcher.hpp:600
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:585
mouse_behavior mouse_behavior_
The mouse behavior for the dispatcher.
Definition: dispatcher.hpp:570
bool want_keyboard_input_
Does the dispatcher want to receive keyboard input.
Definition: dispatcher.hpp:582
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:594
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:612
bool execute_hotkey(const hotkey::HOTKEY_COMMAND id)
Executes a hotkey.
Definition: dispatcher.cpp:147
mouse_behavior get_mouse_behavior() const
Definition: dispatcher.hpp:417
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:591
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:588
std::map< hotkey::HOTKEY_COMMAND, hotkey_function > hotkeys_
The registered hotkeys for this dispatcher.
Definition: dispatcher.hpp:615
Base class for all widgets.
Definition: widget.hpp:55
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:199
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
void connect_signal_pre_key_press(dispatcher &dispatcher, const signal_keyboard &signal)
Connects the signal for 'snooping' on the keypress.
Definition: dispatcher.cpp:158
ui_event
The event sent to the dispatcher.
Definition: handler.hpp:115
void disconnect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Disconnects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:168
dispatcher_callback< const std::string &, int32_t, int32_t > signal_text_input
Used for eventsin event_category::text_input.
Definition: dispatcher.hpp:129
std::function< bool(widget &dispatcher, hotkey::HOTKEY_COMMAND id)> hotkey_function
Hotkey function handler signature.
Definition: dispatcher.hpp:132
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:894
void release_mouse(dispatcher *dispatcher)
Releases a captured mouse.
Definition: handler.cpp:901
void disconnect_signal_mouse_left_release(dispatcher &dispatcher, const signal &signal)
Disconnects a signal handler for a left mouse button release.
Definition: dispatcher.cpp:178
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:173
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.cpp:189
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:163
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:184
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:37
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:500
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:535
void connect_signal(const ui_event event, const queue_position position, const T &signal)
Definition: dispatcher.hpp:509
std::map< ui_event, signal_type< T > > queue
Definition: dispatcher.hpp:507
Helper struct to generate the various signal types.
Definition: dispatcher.hpp:463
bool empty(const dispatcher::event_queue_type queue_type) const
Checks whether the queue of a given type is empty.
Definition: dispatcher.hpp:479
The message callbacks hold a reference to a message.
Definition: message.hpp:46
Holds a 2D point.
Definition: point.hpp:25