The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
dispatcher.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2017 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project http://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 #pragma once
16 
20 
21 #include "utils/functional.hpp"
23 
24 #include <SDL_events.h>
25 
26 #include <boost/mpl/int.hpp>
27 
28 #include <list>
29 #include <map>
30 #include <type_traits>
31 
32 struct point;
33 
34 namespace gui2
35 {
36 class widget;
37 
38 namespace event
39 {
40 
41 template<typename K, ui_event E>
42 using has_key = boost::mpl::has_key<K, boost::mpl::int_<E>>;
43 
44 struct message;
45 
46 /**
47  * Callback function signature.
48  *
49  * There are several kinds of callback signature, this only has the parameters
50  * shared by all callbacks.
51  *
52  * This function is used for the callbacks in set_event.
53  */
54 typedef std::function<void(widget& dispatcher,
55  const ui_event event,
56  bool& handled, bool& halt)> signal_function;
57 
58 /**
59  * Callback function signature.
60  *
61  * This function is used for the callbacks in set_event_mouse.
62  */
63 typedef std::function<void(widget& dispatcher,
64  const ui_event event,
65  bool& handled,
66  bool& halt,
68 
69 /**
70  * Callback function signature.
71  *
72  * This function is used for the callbacks in set_event_keyboard.
73  */
74 typedef std::function<void(widget& dispatcher,
75  const ui_event event,
76  bool& handled,
77  bool& halt,
78  const SDL_Keycode key,
79  const SDL_Keymod modifier,
81 
82 /**
83  * Callback function signature.
84  *
85  * This function is used for the callbacks in set_event_touch.
86  */
87 typedef std::function<void(widget& dispatcher,
88  const ui_event event,
89  bool& handled,
90  bool& halt,
91  const point& pos,
92  const point& distance)> signal_touch_function;
93 
94 /**
95  * Callback function signature.
96  *
97  * This function is used for the callbacks in set_event_notification.
98  * Added the dummy void* parameter which will be nullptr to get a different
99  * signature as signal_function's callback.
100  */
101 typedef std::function<void(widget& dispatcher,
102  const ui_event event,
103  bool& handled,
104  bool& halt,
106 
107 /**
108  * Callback function signature.
109  *
110  * This function is used for the callbacks in set_event_message.
111  */
112 typedef std::function<void(widget& dispatcher,
113  const ui_event event,
114  bool& handled,
115  bool& halt,
117 
118 /**
119  * Callback function signature.
120  *
121  * This function is used for the callbacks in set_event_raw_event.
122  */
123 typedef std::function<void(widget& dispatcher,
124  const ui_event event,
125  bool& handled,
126  bool& halt,
127  const SDL_Event& sdlevent)> signal_raw_event_function;
128 
129 /**
130  * Callback function signature.
131  *
132  * This function is used for the callbacks in set_event_text_input.
133  */
134 typedef std::function<void(widget& dispatcher,
135  const ui_event event,
136  bool& handled,
137  bool& halt,
138  const std::string& text,
139  int32_t current_pos,
140  int32_t select_len)> signal_text_input_function;
141 
142 /** Hotkey function handler signature. */
143 typedef std::function<void(widget& dispatcher, hotkey::HOTKEY_COMMAND id)> hotkey_function;
144 
145 /**
146  * Base class for event handling.
147  *
148  * A dispatcher has slots for events, when an event arrives it looks for the
149  * functions that registered themselves for that event and calls their
150  * callbacks.
151  *
152  * This class is a base class for all widgets[1], what a widget does on a
153  * callback can differ greatly, an image might ignore all events a window can
154  * track the mouse location and fire MOUSE_ENTER and MOUSE_LEAVE events to the
155  * widgets involved.
156  *
157  * [1] Not really sure whether it will be a base class for a widget or
158  * styled_widget yet.
159  */
161 {
163 
164 public:
165  dispatcher();
166  virtual ~dispatcher();
167 
168  /**
169  * Connects the dispatcher to the event handler.
170  *
171  * When a dispatcher is connected to the event handler it will get the
172  * events directly from the event handler. This is wanted for top level
173  * items like windows but not for most other widgets.
174  *
175  * So a window can call connect to register itself, it will automatically
176  * disconnect upon destruction.
177  */
178  void connect();
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,
212  widget& target,
213  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 utf8::string& unicode);
229 
230  /**
231  * Fires an event which takes touch 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,
239  widget& target,
240  const point& pos,
241  const point& distance);
242 
243  /**
244  * Fires an event which takes notification parameters.
245  *
246  * @note the void* parameter is a dummy needed for SFINAE.
247  *
248  * @param event The event to fire.
249  * @param target The widget that should receive the event.
250  */
251  bool fire(const ui_event event,
252  widget& target,
253  void*);
254 
255  /**
256  * Fires an event which takes message parameters.
257  *
258  * @param event The event to fire.
259  * @param target The widget that should receive the event.
260  * Normally this is the window holding the
261  * widget.
262  * @param msg The extra information needed for a window
263  * (or another widget in the chain) to handle
264  * the message.
265  */
266  bool fire(const ui_event event,
267  widget& target,
268  message& msg);
269 
270  /**
271  * Fires an event that's a raw SDL event
272  * @param event The event to fire.
273  * @param target The widget that should receive the event.
274  * Normally this is the window holding the
275  * widget.
276  * @param sdlevent The raw SDL event
277  */
278  bool fire(const ui_event event,
279  widget& target,
280  const SDL_Event& sdlevent);
281 
282  /**
283  * Fires an event which takes text input parameters
284  * @param event The event to fire.
285  * @param target The widget that should receive the event.
286  * Normally this is the window holding the
287  * widget.
288  * @param text The text involved in the event
289  * @param start The start point for IME editing
290  * @param len The selection length for IME editing
291  */
292  bool fire(const ui_event event,
293  widget& target,
294  const std::string& text,
295  int32_t start,
296  int32_t len);
297 
298  /**
299  * The position where to add a new callback in the signal handler.
300  *
301  * The signal handler has three callback queues:
302  * * pre_child These callbacks are called before a container widget sends it
303  * to the child items. Widgets without children should also use this
304  * queue.
305  * * child The callbacks for the proper child widget(s) are called.
306  * * post_child The callbacks for the parent container to be called after
307  * the child.
308  *
309  * For every queue it's possible to add a new event in the front or in the
310  * back.
311  *
312  * Whether all three queues are executed depend on the whether the
313  * callbacks modify the handled and halt flag.
314  * * When the halt flag is set execution of the current queue stops, when
315  * doing so the handled flag must be set as well.
316  * * When the handled flag is set the events in that queue are executed and
317  * no more queues afterwards.
318  *
319  * Here are some use case examples.
320  * A button that plays a sound and executes an optional user callback:
321  * * The buttons internal click handler is invoked and sets the handled
322  * flag
323  * * The callback installed by the user is in the same queue and gets
324  * executed afterwards.
325  *
326  * A toggle button may or may not be toggled:
327  * * The user inserts a callback, that validates whether the action is
328  * allowed, if not allowed it sets the halt flag (and handled), else
329  * leaves the flags untouched.
330  * * The normal buttons toggle function then might get invoked and if so
331  * sets the handled flag.
332  * * Optionally there is another user callback invoked at this point.
333  */
341  };
342 
343  /**
344  * Connect a signal for callback in set_event.
345  *
346  * The function uses some enable_if magic to avoid registering the wrong
347  * function, but the common way to use this function is:
348  * widget->connect_signal<EVENT_ID>(
349  * std::bind(&tmy_dialog::my_member, this));
350  * This allows simply adding a member of a dialog to be used as a callback
351  * for widget without a lot of magic. Note most widgets probably will get a
352  * callback like
353  * connect_signal_mouse_left_click(const signal_function& callback)
354  * which hides this function for the average use.
355  *
356  * @tparam E The event the callback needs to react to.
357  * @param signal The callback function.
358  * @param position The position to place the callback.
359  */
360  template <ui_event E>
362  connect_signal(const signal_function& signal,
363  const queue_position position = back_child)
364  {
365  signal_queue_.connect_signal(E, position, signal);
366  }
367 
368  /**
369  * Disconnect a signal for callback in set_event.
370  *
371  * @tparam E The event the callback was used for.
372  * @param signal The callback function.
373  * @param position The place where the function was added.
374  * Needed remove the event from the right
375  * place. (The function doesn't care whether
376  * was added in front or back.)
377  */
378  template <ui_event E>
380  disconnect_signal(const signal_function& signal,
381  const queue_position position = back_child)
382  {
383  signal_queue_.disconnect_signal(E, position, signal);
384  }
385 
386  /**
387  * Connect a signal for callback in set_event_mouse.
388  *
389  * @tparam E The event the callback needs to react to.
390  * @param signal The callback function.
391  * @param position The position to place the callback.
392  */
393  template <ui_event E>
395  connect_signal(const signal_mouse_function& signal,
396  const queue_position position = back_child)
397  {
398  signal_mouse_queue_.connect_signal(E, position, signal);
399  }
400 
401  /**
402  * Disconnect a signal for callback in set_event_mouse.
403  *
404  * @tparam E The event the callback was used for.
405  * @param signal The callback function.
406  * @param position The place where the function was added.
407  * Needed remove the event from the right
408  * place. (The function doesn't care whether
409  * was added in front or back.)
410  */
411  template <ui_event E>
413  disconnect_signal(const signal_mouse_function& signal,
414  const queue_position position = back_child)
415  {
416  signal_mouse_queue_.disconnect_signal(E, position, signal);
417  }
418 
419  /**
420  * Connect a signal for callback in set_event_keyboard.
421  *
422  * @tparam E The event the callback needs to react to.
423  * @param signal The callback function.
424  * @param position The position to place the callback.
425  */
426  template <ui_event E>
428  connect_signal(const signal_keyboard_function& signal,
429  const queue_position position = back_child)
430  {
431  signal_keyboard_queue_.connect_signal(E, position, signal);
432  }
433 
434  /**
435  * Disconnect a signal for callback in set_event_keyboard.
436  *
437  * @tparam E The event the callback was used for.
438  * @param signal The callback function.
439  * @param position The place where the function was added.
440  * Needed remove the event from the right
441  * place. (The function doesn't care whether
442  * was added in front or back.)
443  */
444  template <ui_event E>
446  disconnect_signal(const signal_keyboard_function& signal,
447  const queue_position position = back_child)
448  {
449  signal_keyboard_queue_.disconnect_signal(E, position, signal);
450  }
451 
452  /**
453  * Connect a signal for callback in set_event_touch.
454  *
455  * @tparam E The event the callback needs to react to.
456  * @param signal The callback function.
457  * @param position The position to place the callback.
458  */
459  template <ui_event E>
461  connect_signal(const signal_touch_function& signal,
462  const queue_position position = back_child)
463  {
464  signal_touch_queue_.connect_signal(E, position, signal);
465  }
466 
467  /**
468  * Disconnect a signal for callback in set_event_touch.
469  *
470  * @tparam E The event the callback was used for.
471  * @param signal The callback function.
472  * @param position The place where the function was added.
473  * Needed remove the event from the right
474  * place. (The function doesn't care whether
475  * was added in front or back.)
476  */
477  template <ui_event E>
479  disconnect_signal(const signal_touch_function& signal,
480  const queue_position position = back_child)
481  {
482  signal_touch_queue_.disconnect_signal(E, position, signal);
483  }
484 
485  /**
486  * Connect a signal for callback in set_event_notification.
487  *
488  * @tparam E The event the callback needs to react to.
489  * @param signal The callback function.
490  * @param position The position to place the callback. Since
491  * the message is send to a widget directly
492  * the pre and post positions make no sense
493  * and shouldn't be used.
494  */
495  template <ui_event E>
497  connect_signal(const signal_notification_function& signal,
498  const queue_position position = back_child)
499  {
500  signal_notification_queue_.connect_signal(E, position, signal);
501  }
502 
503  /**
504  * Disconnect a signal for callback in set_event_notification.
505  *
506  * @tparam E The event the callback was used for.
507  * @param signal The callback function.
508  * @param position The place where the function was added.
509  * Needed remove the event from the right
510  * place. (The function doesn't care whether
511  * was added in front or back, but it needs
512  * to know the proper queue so it's save to
513  * add with front_child and remove with
514  * back_child. But it's not save to add with
515  * front_child and remove with
516  * front_pre_child)
517  */
518  template <ui_event E>
520  disconnect_signal(const signal_notification_function& signal,
521  const queue_position position = back_child)
522  {
523  signal_notification_queue_.disconnect_signal(E, position, signal);
524  }
525 
526  /**
527  * Connect a signal for callback in set_event_message.
528  *
529  * @tparam E The event the callback needs to react to.
530  * @param signal The callback function.
531  * @param position The position to place the callback. Since
532  * the message is send to a widget directly
533  * the pre and post positions make no sense
534  * and shouldn't be used.
535  */
536  template <ui_event E>
538  connect_signal(const signal_message_function& signal,
539  const queue_position position = back_child)
540  {
541  signal_message_queue_.connect_signal(E, position, signal);
542  }
543 
544  /**
545  * Disconnect a signal for callback in set_event_message.
546  *
547  * @tparam E The event the callback was used for.
548  * @param signal The callback function.
549  * @param position The place where the function was added.
550  * Needed remove the event from the right
551  * place. (The function doesn't care whether
552  * was added in front or back, but it needs
553  * to know the proper queue so it's save to
554  * add with front_child and remove with
555  * back_child. But it's not save to add with
556  * front_child and remove with
557  * front_pre_child)
558  */
559  template <ui_event E>
561  disconnect_signal(const signal_message_function& signal,
562  const queue_position position = back_child)
563  {
564  signal_message_queue_.disconnect_signal(E, position, signal);
565  }
566 
567  /**
568  * Connect a signal for callback in set_raw_event.
569  *
570  * @tparam E The event the callback needs to react to.
571  * @param signal The callback function.
572  * @param position The position to place the callback.
573  */
574  template <ui_event E>
576  connect_signal(const signal_raw_event_function& signal,
577  const queue_position position = back_child)
578  {
579  signal_raw_event_queue_.connect_signal(E, position, signal);
580  }
581 
582  /**
583  * Disconnect a signal for callback in set_raw_event.
584  *
585  * @tparam E The event the callback was used for.
586  * @param signal The callback function.
587  * @param position The place where the function was added.
588  * Needed remove the event from the right
589  * place. (The function doesn't care whether
590  * was added in front or back.)
591  */
592  template <ui_event E>
594  disconnect_signal(const signal_raw_event_function& signal,
595  const queue_position position = back_child)
596  {
597  signal_raw_event_queue_.disconnect_signal(E, position, signal);
598  }
599 
600  /**
601  * Connect a signal for callback in set_text_input.
602  *
603  * @tparam E The event the callback needs to react to.
604  * @param signal The callback function.
605  * @param position The position to place the callback.
606  */
607  template <ui_event E>
609  connect_signal(const signal_text_input_function& signal,
610  const queue_position position = back_child)
611  {
612  signal_text_input_queue_.connect_signal(E, position, signal);
613  }
614 
615  /**
616  * Disconnect a signal for callback in set_text_input.
617  *
618  * @tparam E The event the callback was used for.
619  * @param signal The callback function.
620  * @param position The place where the function was added.
621  * Needed remove the event from the right
622  * place. (The function doesn't care whether
623  * was added in front or back.)
624  */
625  template <ui_event E>
627  disconnect_signal(const signal_text_input_function& signal,
628  const queue_position position = back_child)
629  {
630  signal_text_input_queue_.disconnect_signal(E, position, signal);
631  }
632 
633  /**
634  * The behavior of the mouse events.
635  *
636  * Normally for mouse events there's first checked whether a dispatcher has
637  * captured the mouse if so it gets the event.
638  * If not the dispatcher is searched from the back to the front in the
639  * layers and its behavior is checked.
640  * * none The event is never send to the layer and goes on the the next
641  * layer. This is used for tooltips who might cover a button but a click
642  * on the tooltips should still click the button.
643  * * all The event is always send to this layer and stops the search for a
644  * next layer.
645  * * hit If the mouse is inside the dispatcher area the event is send and
646  * no longer searched further. If not inside tests the last layer.
647  *
648  * If after these tests no dispatcher is found the event is ignored.
649  */
654  };
655 
656  /** Captures the mouse. */
658  {
660  }
661 
662  /** Releases the mouse capture. */
664  {
666  }
667 
668  /***** ***** ***** setters/getters ***** ***** *****/
669 
671  {
673  }
674 
676  {
677  return mouse_behavior_;
678  }
679 
680  void set_want_keyboard_input(const bool want_keyboard_input)
681  {
682  want_keyboard_input_ = want_keyboard_input;
683  }
684 
686  {
687  return want_keyboard_input_;
688  }
689 
690  /** Helper struct to generate the various signal types. */
691  template <class T>
692  struct signal_type
693  {
695  {
696  }
697 
698  std::list<T> pre_child;
699  std::list<T> child;
700  std::list<T> post_child;
701  };
702 
703  /** Helper struct to generate the various event queues. */
704  template <class T>
706  {
708  {
709  }
710 
711  std::map<ui_event, signal_type<T> > queue;
712 
713  void connect_signal(const ui_event event,
714  const queue_position position,
715  const T& signal)
716  {
717  switch(position) {
718  case front_pre_child:
719  queue[event].pre_child.push_front(signal);
720  break;
721  case back_pre_child:
722  queue[event].pre_child.push_back(signal);
723  break;
724 
725  case front_child:
726  queue[event].child.push_front(signal);
727  break;
728  case back_child:
729  queue[event].child.push_back(signal);
730  break;
731 
732  case front_post_child:
733  queue[event].post_child.push_front(signal);
734  break;
735  case back_post_child:
736  queue[event].post_child.push_back(signal);
737  break;
738  }
739  }
740 
741  void disconnect_signal(const ui_event event,
742  const queue_position position,
743  const T& signal)
744  {
745  signal_type<T>& signal_queue = queue[event];
746 
747  /* The function doesn't differentiate between front and back position so fall
748  * down from front to back.
749  *
750  * NOTE: This used to only remove the first signal of matching target type.
751  * That behavior could be restored in the future if needed.
752  * - vultraz, 2017-05-02
753  */
754  switch(position) {
755  case front_pre_child:
756  case back_pre_child: {
757  signal_queue.pre_child.remove_if(
758  [&signal](T& element) { return signal.target_type() == element.target_type(); }
759  );
760  } break;
761 
762  case front_child:
763  case back_child: {
764  signal_queue.child.remove_if(
765  [&signal](T& element) { return signal.target_type() == element.target_type(); }
766  );
767  } break;
768 
769  case front_post_child:
770  case back_post_child: {
771  signal_queue.post_child.remove_if(
772  [&signal](T& element) { return signal.target_type() == element.target_type(); }
773  );
774  } break;
775  }
776  }
777  };
778 
779  /**
780  * Registers a hotkey.
781  *
782  * @todo add a static function register_global_hotkey.
783  *
784  * Once that's done execute_hotkey will first try to execute a global
785  * hotkey and if that fails tries the hotkeys in this dispatcher.
786  *
787  * @param id The hotkey to register.
788  * @param function The callback function to call.
789  */
791  const hotkey_function& function);
792 
793  /**
794  * Executes a hotkey.
795  *
796  * @param id The hotkey to execute.
797  *
798  * @returns true if the hotkey is handled, false
799  * otherwise.
800  */
801  bool execute_hotkey(const hotkey::HOTKEY_COMMAND id);
802 
803 private:
804  /** The mouse behavior for the dispatcher. */
806 
807  /**
808  * Does the dispatcher want to receive keyboard input.
809  *
810  * @todo The entire mouse and keyboard handling can use a code review to
811  * seen whether it might be combined in one flag field. At the moment the
812  * keyboard doesn't look whether a dialog has the mouse focus before
813  * sending the event, so maybe we should add an active dispatcher to keep
814  * track of it. But since at the moment there are only non-modal windows
815  * and tooltips it's not a problem.
816  */
818 
819  /** Signal queue for callbacks in set_event. */
821 
822  /** Signal queue for callbacks in set_event_mouse. */
824 
825  /** Signal queue for callbacks in set_event_keyboard. */
827 
828  /** Signal queue for callbacks in set_event_touch. */
830 
831  /** Signal queue for callbacks in set_event_notification. */
833 
834  /** Signal queue for callbacks in set_event_message. */
836 
837  /** Signal queue for callbacks in set_raw_event. */
839 
840  /** Signal queue for callbacks in set_event_text_input. */
842 
843  /** Are we connected to the event handler. */
845 
846  /** The registered hotkeys for this dispatcher. */
847  std::map<hotkey::HOTKEY_COMMAND, hotkey_function> hotkeys_;
848 };
849 
850 /***** ***** ***** ***** ***** Common helpers ***** ***** ***** ***** *****/
851 
852 /*
853  * These helpers can be used to easily add callbacks to a dispatcher (widget).
854  * This is just a list of common ones all others can be used as well.
855  */
856 
857 /**
858  * Connects the signal for 'snooping' on the keypress.
859  *
860  * This callback is called before the widget itself allowing you to either
861  * snoop on the input or filter it.
862  */
863 void connect_signal_pre_key_press(dispatcher& dispatcher, const signal_keyboard_function& signal);
864 
865 /** Connects a signal handler for a left mouse button click. */
866 void connect_signal_mouse_left_click(dispatcher& dispatcher, const signal_function& signal);
867 
868 /** Disconnects a signal handler for a left mouse button click. */
869 void disconnect_signal_mouse_left_click(dispatcher& dispatcher, const signal_function& signal);
870 
871 /**
872  * Connects a signal handler for a left mouse button double click.
873  *
874  * I'm not exactly sure why this works in this queue position with toggle
875  * panels, but it does. Will revisit if it becomes an issue later (ie, if
876  * this is used with other widgets and doesn't work).
877  *
878  * - vultraz, 2017-08-23
879  */
880 void connect_signal_mouse_left_double_click(dispatcher& dispatcher, const signal_function& signal);
881 
882 /** Connects a signal handler for getting a notification upon modification. */
883 void connect_signal_notify_modified(dispatcher& dispatcher, const signal_notification_function& signal);
884 
885 } // namespace event
886 
887 } // namespace gui2
utils::enable_if_t< has_key< set_event_text_input, E >::value > disconnect_signal(const signal_text_input_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_text_input.
Definition: dispatcher.hpp:627
std::vector< char_t > string
signal_queue< signal_text_input_function > signal_text_input_queue_
Signal queue for callbacks in set_event_text_input.
Definition: dispatcher.hpp:841
Base class for event handling.
Definition: dispatcher.hpp:160
utils::enable_if_t< has_key< set_event_message, E >::value > connect_signal(const signal_message_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_event_message.
Definition: dispatcher.hpp:538
void register_hotkey(const hotkey::HOTKEY_COMMAND id, const hotkey_function &function)
Registers a hotkey.
Definition: dispatcher.cpp:188
utils::enable_if_t< has_key< set_event_raw_event, E >::value > connect_signal(const signal_raw_event_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_raw_event.
Definition: dispatcher.hpp:576
Base class for all widgets.
Definition: widget.hpp:48
void capture_mouse(dispatcher *dispatcher)
Captures the mouse.
Definition: handler.cpp:845
std::function< void(widget &dispatcher, const ui_event event, bool &handled, bool &halt, const point &coordinate)> signal_mouse_function
Callback function signature.
Definition: dispatcher.hpp:67
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:110
boost::mpl::has_key< K, boost::mpl::int_< E >> has_key
Definition: dispatcher.hpp:42
void connect_signal(const ui_event event, const queue_position position, const T &signal)
Definition: dispatcher.hpp:713
bool get_want_keyboard_input() const
Definition: dispatcher.hpp:685
bool has_event(const ui_event event, const event_queue_type event_type)
Definition: dispatcher.cpp:55
utils::enable_if_t< has_key< set_event_keyboard, E >::value > disconnect_signal(const signal_keyboard_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_event_keyboard.
Definition: dispatcher.hpp:446
Generic file dialog.
Definition: field-fwd.hpp:22
The message callbacks hold a reference to a message.
Definition: message.hpp:46
utils::enable_if_t< has_key< set_event_message, E >::value > disconnect_signal(const signal_message_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_event_message.
Definition: dispatcher.hpp:561
utils::enable_if_t< has_key< set_event_mouse, E >::value > connect_signal(const signal_mouse_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_event_mouse.
Definition: dispatcher.hpp:395
void capture_mouse()
Captures the mouse.
Definition: dispatcher.hpp:657
std::function< void(widget &dispatcher, const ui_event event, bool &handled, bool &halt, const SDL_Keycode key, const SDL_Keymod modifier, const utf8::string &unicode)> signal_keyboard_function
Callback function signature.
Definition: dispatcher.hpp:80
void connect()
Connects the dispatcher to the event handler.
Definition: dispatcher.cpp:48
mouse_behavior get_mouse_behavior() const
Definition: dispatcher.hpp:675
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:233
signal_queue< signal_mouse_function > signal_mouse_queue_
Signal queue for callbacks in set_event_mouse.
Definition: dispatcher.hpp:823
virtual bool is_at(const point &coordinate) const =0
Determines whether the location is inside an active widget.
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:218
bool execute_hotkey(const hotkey::HOTKEY_COMMAND id)
Executes a hotkey.
Definition: dispatcher.cpp:193
std::function< void(widget &dispatcher, hotkey::HOTKEY_COMMAND id)> hotkey_function
Hotkey function handler signature.
Definition: dispatcher.hpp:143
signal_queue< signal_function > signal_queue_
Signal queue for callbacks in set_event.
Definition: dispatcher.hpp:820
utils::enable_if_t< has_key< set_event_raw_event, E >::value > disconnect_signal(const signal_raw_event_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_raw_event.
Definition: dispatcher.hpp:594
signal_queue< signal_message_function > signal_message_queue_
Signal queue for callbacks in set_event_message.
Definition: dispatcher.hpp:835
Helper struct to generate the various event queues.
Definition: dispatcher.hpp:705
void set_mouse_behavior(const mouse_behavior mouse_behavior)
Definition: dispatcher.hpp:670
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:228
signal_queue< signal_touch_function > signal_touch_queue_
Signal queue for callbacks in set_event_touch.
Definition: dispatcher.hpp:829
std::map< ui_event, signal_type< T > > queue
Definition: dispatcher.hpp:711
std::map< hotkey::HOTKEY_COMMAND, hotkey_function > hotkeys_
The registered hotkeys for this dispatcher.
Definition: dispatcher.hpp:847
bool want_keyboard_input_
Does the dispatcher want to receive keyboard input.
Definition: dispatcher.hpp:817
EXIT_STATUS start(const config &game_conf, 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
utils::enable_if_t< has_key< set_event_mouse, E >::value > disconnect_signal(const signal_mouse_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_event_mouse.
Definition: dispatcher.hpp:413
bool connected_
Are we connected to the event handler.
Definition: dispatcher.hpp:844
utils::enable_if_t< has_key< set_event_notification, E >::value > connect_signal(const signal_notification_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_event_notification.
Definition: dispatcher.hpp:497
Holds a 2D point.
Definition: point.hpp:22
utils::enable_if_t< has_key< set_event_touch, E >::value > disconnect_signal(const signal_touch_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_event_touch.
Definition: dispatcher.hpp:479
signal_queue< signal_raw_event_function > signal_raw_event_queue_
Signal queue for callbacks in set_raw_event.
Definition: dispatcher.hpp:838
std::function< void(widget &dispatcher, const ui_event event, bool &handled, bool &halt, const std::string &text, int32_t current_pos, int32_t select_len)> signal_text_input_function
Callback function signature.
Definition: dispatcher.hpp:140
std::function< void(widget &dispatcher, const ui_event event, bool &handled, bool &halt)> signal_function
Callback function signature.
Definition: dispatcher.hpp:44
queue_position
The position where to add a new callback in the signal handler.
Definition: dispatcher.hpp:334
typename std::enable_if< B, T >::type enable_if_t
signal_queue< signal_notification_function > signal_notification_queue_
Signal queue for callbacks in set_event_notification.
Definition: dispatcher.hpp:832
utils::enable_if_t< has_key< set_event, E >::value > disconnect_signal(const signal_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_event.
Definition: dispatcher.hpp:380
void connect_signal_pre_key_press(dispatcher &dispatcher, const signal_keyboard_function &signal)
Connects the signal for 'snooping' on the keypress.
Definition: dispatcher.cpp:213
utils::enable_if_t< has_key< set_event_text_input, E >::value > connect_signal(const signal_text_input_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_text_input.
Definition: dispatcher.hpp:609
mouse_behavior
The behavior of the mouse events.
Definition: dispatcher.hpp:650
signal_queue< signal_keyboard_function > signal_keyboard_queue_
Signal queue for callbacks in set_event_keyboard.
Definition: dispatcher.hpp:826
Helper struct to generate the various signal types.
Definition: dispatcher.hpp:692
utils::enable_if_t< has_key< set_event, E >::value > connect_signal(const signal_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_event.
Definition: dispatcher.hpp:362
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:223
void release_mouse(dispatcher *dispatcher)
Releases a captured mouse.
Definition: handler.cpp:852
std::function< void(widget &dispatcher, const ui_event event, bool &handled, bool &halt, const SDL_Event &sdlevent)> signal_raw_event_function
Callback function signature.
Definition: dispatcher.hpp:127
utils::enable_if_t< has_key< set_event_notification, E >::value > disconnect_signal(const signal_notification_function &signal, const queue_position position=back_child)
Disconnect a signal for callback in set_event_notification.
Definition: dispatcher.hpp:520
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:120
void release_mouse()
Releases the mouse capture.
Definition: dispatcher.hpp:663
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
std::function< void(widget &dispatcher, const ui_event event, bool &handled, bool &halt, const point &pos, const point &distance)> signal_touch_function
Callback function signature.
Definition: dispatcher.hpp:92
void set_want_keyboard_input(const bool want_keyboard_input)
Definition: dispatcher.hpp:680
std::function< void(widget &dispatcher, const ui_event event, bool &handled, bool &halt, message &message)> signal_message_function
Callback function signature.
Definition: dispatcher.hpp:116
std::function< void(widget &dispatcher, const ui_event event, bool &handled, bool &halt, void *)> signal_notification_function
Callback function signature.
Definition: dispatcher.hpp:105
utils::enable_if_t< has_key< set_event_keyboard, E >::value > connect_signal(const signal_keyboard_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_event_keyboard.
Definition: dispatcher.hpp:428
utils::enable_if_t< has_key< set_event_touch, E >::value > connect_signal(const signal_touch_function &signal, const queue_position position=back_child)
Connect a signal for callback in set_event_touch.
Definition: dispatcher.hpp:461
mouse_behavior mouse_behavior_
The mouse behavior for the dispatcher.
Definition: dispatcher.hpp:805
void disconnect_signal(const ui_event event, const queue_position position, const T &signal)
Definition: dispatcher.hpp:741
ui_event
The event send to the dispatcher.
Definition: handler.hpp:55
std::string string