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