The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
handler.cpp
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 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
18 
20 #include "gui/core/timer.hpp"
21 #include "gui/core/log.hpp"
22 #include "gui/widgets/helper.hpp"
23 #include "gui/widgets/widget.hpp"
24 #include "gui/widgets/window.hpp"
25 #include "hotkey/hotkey_item.hpp"
26 #include "video.hpp"
28 #include "sdl/userevent.hpp"
29 
30 #include <cassert>
31 
32 #include <boost/range/adaptor/reversed.hpp>
33 
34 /**
35  * @todo The items below are not implemented yet.
36  *
37  * - Tooltips have a fixed short time until showing up.
38  * - Tooltips are shown until the widget is exited.
39  * - Help messages aren't shown yet.
40  *
41  * @note it might be that tooltips will be shown independent of a window and in
42  * their own window, therefore the code will be cleaned up after that has been
43  * determined.
44  */
45 
46 /*
47  * At some point in the future this event handler should become the main event
48  * handler. This switch controls the experimental switch for that change.
49  */
50 //#define MAIN_EVENT_HANDLER
51 
52 /* Since this code is still very experimental it's not enabled yet. */
53 //#define ENABLE
54 
55 namespace gui2
56 {
57 
58 namespace event
59 {
60 
61 /***** Static data. *****/
62 static std::unique_ptr<class sdl_event_handler> handler_ = nullptr;
64 
65 #ifdef MAIN_EVENT_HANDLER
66 static unsigned draw_interval = 0;
67 static unsigned event_poll_interval = 0;
68 
69 /***** Static functions. *****/
70 
71 /**
72  * SDL_AddTimer() callback for the draw event.
73  *
74  * When this callback is called it pushes a new draw event in the event queue.
75  *
76  * @returns The new timer interval, 0 to stop.
77  */
78 static Uint32 timer_sdl_draw_event(Uint32, void*)
79 {
80  // DBG_GUI_E << "Pushing draw event in queue.\n";
81 
82  SDL_Event event;
84 
85  event.type = DRAW_EVENT;
86  event.user = data;
87 
88  SDL_PushEvent(&event);
89  return draw_interval;
90 }
91 
92 /**
93  * SDL_AddTimer() callback for the poll event.
94  *
95  * When this callback is called it will run the events in the SDL event queue.
96  *
97  * @returns The new timer interval, 0 to stop.
98  */
99 static Uint32 timer_sdl_poll_events(Uint32, void*)
100 {
101  try
102  {
103  events::pump();
104  }
105  catch(CVideo::quit&)
106  {
107  return 0;
108  }
109  return event_poll_interval;
110 }
111 #endif
112 
113 /***** handler class. *****/
114 
115 /**
116  * This singleton class handles all events.
117  *
118  * It's a new experimental class.
119  */
121 {
122  friend bool gui2::is_in_dialog();
123 
124 public:
126 
128 
129  /** Inherited from events::sdl_handler. */
130  void handle_event(const SDL_Event& event);
131 
132  /** Inherited from events::sdl_handler. */
133  void handle_window_event(const SDL_Event& event);
134 
135  /**
136  * Connects a dispatcher.
137  *
138  * @param dispatcher The dispatcher to connect.
139  */
141 
142  /**
143  * Disconnects a dispatcher.
144  *
145  * @param dispatcher The dispatcher to disconnect.
146  */
147  void disconnect(dispatcher* dispatcher);
148 
149  /** The dispatcher that captured the mouse focus. */
150  dispatcher* mouse_focus;
151 
152 private:
153  /**
154  * Reinitializes the state of all dispatchers.
155  *
156  * This is needed when the application gets activated, to make sure the
157  * state of mainly the mouse is set properly.
158  */
159  void activate();
160 
161  /***** Handlers *****/
162 
163  /** Fires a raw SDL event. */
164  void raw_event(const SDL_Event &event);
165 
166  /** Fires a draw event. */
168  void draw(const bool force);
169 
170  /**
171  * Fires a video resize event.
172  *
173  * @param new_size The new size of the window.
174  */
175  void video_resize(const point& new_size);
176 
177  /**
178  * Fires a generic mouse event.
179  *
180  * @param event The event to fire.
181  * @param position The position of the mouse.
182  */
183  void mouse(const ui_event event, const point& position);
184 
185  /**
186  * Fires a mouse button up event.
187  *
188  * @param position The position of the mouse.
189  * @param button The SDL id of the button that caused the
190  * event.
191  */
192  void mouse_button_up(const point& position, const Uint8 button);
193 
194  /**
195  * Fires a mouse button down event.
196  *
197  * @param position The position of the mouse.
198  * @param button The SDL id of the button that caused the
199  * event.
200  */
201  void mouse_button_down(const point& position, const Uint8 button);
202 
203  /**
204  * Fires a mouse wheel event.
205  *
206  * @param position The position of the mouse.
207  * @param scrollx The amount of horizontal scrolling.
208  * @param scrolly The amount of vertical scrolling.
209  */
210  void mouse_wheel(const point& position, int scrollx, int scrolly);
211 
212  /**
213  * Gets the dispatcher that wants to receive the keyboard input.
214  *
215  * @returns The dispatcher.
216  * @retval nullptr No dispatcher found.
217  */
218  dispatcher* keyboard_dispatcher();
219 
220  /**
221  * Fires a generic touch event.
222  *
223  * @param position The position touched.
224  * @param distance The distance moved.
225  */
226  void touch_motion(const point& position, const point& distance);
227 
228  /**
229  * Handles a hat motion event.
230  *
231  * @param event The SDL joystick hat event triggered.
232  */
233  void hat_motion(const SDL_Event& event);
234 
235  /**
236  * Handles a joystick button down event.
237  *
238  * @param event The SDL joystick button event triggered.
239  */
240  void button_down(const SDL_Event& event);
241 
242  /**
243  * Fires a key down event.
244  *
245  * @param event The SDL keyboard event triggered.
246  */
247  void key_down(const SDL_Event& event);
248 
249  /**
250  * Handles the pressing of a hotkey.
251  *
252  * @param key The hotkey item pressed.
253  *
254  * @returns True if the hotkey is handled false otherwise.
255  */
256  bool hotkey_pressed(const hotkey::hotkey_ptr key);
257 
258  /**
259  * Fires a key down event.
260  *
261  * @param key The SDL key code of the key pressed.
262  * @param modifier The SDL key modifiers used.
263  * @param unicode The unicode value for the key pressed.
264  */
265  void key_down(const SDL_Keycode key,
266  const SDL_Keymod modifier,
267  const utf8::string& unicode);
268 
269  /**
270  * Fires a text input event.
271  *
272  * @param unicode The unicode value for the text entered.
273  */
274  void text_input(const std::string& unicode);
275 
276  /**
277  * Fires a text editing event.
278  *
279  * @param unicode The unicode value for the text being edited.
280  * @param start The start position for the text being edited.
281  * @param len The selection length for the text being edited.
282  */
283  void text_editing(const std::string& unicode, int32_t start, int32_t len);
284 
285  /**
286  * Fires a keyboard event which has no parameters.
287  *
288  * This can happen for example when the mouse wheel is used.
289  *
290  * @param event The event to fire.
291  */
292  void keyboard(const ui_event event);
293 
294  /**
295  * Fires a CLOSE_WINDOW event for the window with the given ID.
296  *
297  * @param window_id The ID of the window to close.
298  */
299  void close_window(const unsigned window_id);
300 
301  /**
302  * The dispatchers.
303  *
304  * The order of the items in the list is also the z-order the front item
305  * being the one completely in the background and the back item the one
306  * completely in the foreground.
307  */
308  std::vector<dispatcher*> dispatchers_;
309 
310  /**
311  * Needed to determine which dispatcher gets the keyboard events.
312  *
313  * NOTE the keyboard events aren't really wired in yet so doesn't do much.
314  */
315  dispatcher* keyboard_focus_;
316  friend void capture_keyboard(dispatcher*);
317 };
318 
320  : events::sdl_handler(false)
321  , mouse_focus(nullptr)
322  , dispatchers_()
323  , keyboard_focus_(nullptr)
324 {
325  if(SDL_WasInit(SDL_INIT_TIMER) == 0) {
326  if(SDL_InitSubSystem(SDL_INIT_TIMER) == -1) {
327  assert(false);
328  }
329  }
330 
331 // The event context is created now we join it.
332 #ifdef ENABLE
333  join();
334 #endif
335 }
336 
338 {
339 #ifdef ENABLE
340  leave();
341 #endif
342 }
343 
344 void sdl_event_handler::handle_event(const SDL_Event& event)
345 {
346  /** No dispatchers drop the event. */
347  if(dispatchers_.empty()) {
348  return;
349  }
350 
351  switch(event.type) {
352  case SDL_MOUSEMOTION:
353  mouse(SDL_MOUSE_MOTION, {event.motion.x, event.motion.y});
354  break;
355 
356  case SDL_MOUSEBUTTONDOWN:
357  mouse_button_down({event.button.x, event.button.y}, event.button.button);
358  break;
359 
360  case SDL_MOUSEBUTTONUP:
361  mouse_button_up({event.button.x, event.button.y}, event.button.button);
362  break;
363 
364  case SDL_MOUSEWHEEL:
365  mouse_wheel(get_mouse_position(), event.wheel.x, event.wheel.y);
366  break;
367 
368  case SHOW_HELPTIP_EVENT:
370  break;
371 
373  // remove_popup();
374  break;
375 
376  case DRAW_EVENT:
377  draw(false);
378  break;
379  case DRAW_ALL_EVENT:
380  draw(true);
381  break;
382 
383  case TIMER_EVENT:
384  execute_timer(reinterpret_cast<size_t>(event.user.data1));
385  break;
386 
387  case CLOSE_WINDOW_EVENT:
388  close_window(event.user.code);
389  break;
390 
391  case SDL_JOYBUTTONDOWN:
392  button_down(event);
393  break;
394 
395  case SDL_JOYBUTTONUP:
396  break;
397 
398  case SDL_JOYAXISMOTION:
399  break;
400 
401  case SDL_JOYHATMOTION:
402  hat_motion(event);
403  break;
404 
405  case SDL_KEYDOWN:
406  key_down(event);
407  break;
408 
409  case SDL_WINDOWEVENT:
410  switch(event.window.event) {
411  case SDL_WINDOWEVENT_EXPOSED:
412  draw(true);
413  break;
414 
415  case SDL_WINDOWEVENT_RESIZED:
416  video_resize({event.window.data1, event.window.data2});
417  break;
418 
419  case SDL_WINDOWEVENT_ENTER:
420  case SDL_WINDOWEVENT_FOCUS_GAINED:
421  activate();
422  break;
423  }
424 
425  break;
426 
427  case SDL_TEXTINPUT:
428  key_down(event);
429  break;
430 
431  case SDL_TEXTEDITING:
432  text_editing(event.edit.text, event.edit.start, event.edit.length);
433  break;
434 
435  case SDL_FINGERMOTION:
436  touch_motion(point(event.tfinger.x, event.tfinger.y), point(event.tfinger.dx, event.tfinger.dy));
437  break;
438 
439 #if(defined(_X11) && !defined(__APPLE__)) || defined(_WIN32)
440  case SDL_SYSWMEVENT:
441  /* DO NOTHING */
442  break;
443 #endif
444 
445  // Silently ignored events.
446  case SDL_KEYUP:
447  case DOUBLE_CLICK_EVENT:
448  case SDL_FINGERUP:
449  case SDL_FINGERDOWN:
450  break;
451 
452  default:
453 #ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
454  WRN_GUI_E << "Unhandled event " << static_cast<Uint32>(event.type)
455  << ".\n";
456 #endif
457  break;
458  }
459 
460  raw_event(event);
461 }
462 
463 void sdl_event_handler::handle_window_event(const SDL_Event& event)
464 {
465  handle_event(event);
466 }
467 
469 {
470  assert(std::find(dispatchers_.begin(), dispatchers_.end(), dispatcher)
471  == dispatchers_.end());
472 
473  if(dispatchers_.empty()) {
474  event_context = new events::event_context();
475  join();
476  }
477 
478  dispatchers_.push_back(dispatcher);
479 }
480 
482 {
483  /***** Validate pre conditions. *****/
484  auto itor = std::find(dispatchers_.begin(), dispatchers_.end(), disp);
485  assert(itor != dispatchers_.end());
486 
487  /***** Remove dispatcher. *****/
488  dispatchers_.erase(itor);
489 
490  if(disp == mouse_focus) {
491  mouse_focus = nullptr;
492  }
493  if(disp == keyboard_focus_) {
494  keyboard_focus_ = nullptr;
495  }
496 
497  /***** Set proper state for the other dispatchers. *****/
498  for(auto d : dispatchers_)
499  {
500  dynamic_cast<widget&>(*d).set_is_dirty(true);
501  }
502 
503  activate();
504 
505  /***** Validate post conditions. *****/
506  assert(std::find(dispatchers_.begin(), dispatchers_.end(), disp)
507  == dispatchers_.end());
508 
509  if(dispatchers_.empty()) {
510  leave();
511  delete event_context;
512  event_context = nullptr;
513  }
514 }
515 
517 {
518  for(auto dispatcher : dispatchers_)
519  {
520  dispatcher->fire(SDL_ACTIVATE, dynamic_cast<widget&>(*dispatcher), nullptr);
521  }
522 }
523 
524 void sdl_event_handler::draw(const bool force)
525 {
526  // Don't display this event since it floods the screen
527  // DBG_GUI_E << "Firing " << DRAW << ".\n";
528 
529  /*
530  * In normal draw mode the first window in not forced to be drawn the
531  * others are. So for forced mode we only need to force the first window to
532  * be drawn the others are already handled.
533  */
534  bool first = !force;
535 
536  /**
537  * @todo Need to evaluate which windows really to redraw.
538  *
539  * For now we use a hack, but would be nice to rewrite it for 1.9/1.11.
540  */
541  for(auto dispatcher : dispatchers_)
542  {
543  if(!first) {
544  /*
545  * This leaves glitches on window borders if the window beneath it
546  * has changed, on the other hand invalidating twindown::restorer_
547  * causes black borders around the window. So there's the choice
548  * between two evils.
549  */
550  dynamic_cast<widget&>(*dispatcher).set_is_dirty(true);
551  } else {
552  first = false;
553  }
554 
555  dispatcher->fire(DRAW, dynamic_cast<widget&>(*dispatcher));
556  }
557 
558  if(!dispatchers_.empty()) {
559  CVideo& video = dynamic_cast<window&>(*dispatchers_.back()).video();
560 
561  video.flip();
562  }
563 }
564 
566 {
567  DBG_GUI_E << "Firing: " << SDL_VIDEO_RESIZE << ".\n";
568 
569  for(auto dispatcher : dispatchers_)
570  {
571  dispatcher->fire(SDL_VIDEO_RESIZE, dynamic_cast<widget&>(*dispatcher), new_size);
572  }
573 }
574 
575 void sdl_event_handler::raw_event(const SDL_Event& event) {
576  DBG_GUI_E << "Firing raw event\n";
577 
578  for(auto dispatcher : dispatchers_)
579  {
580  dispatcher->fire(SDL_RAW_EVENT, dynamic_cast<widget&>(*dispatcher), event);
581  }
582 }
583 
584 void sdl_event_handler::mouse(const ui_event event, const point& position)
585 {
586  DBG_GUI_E << "Firing: " << event << ".\n";
587 
588  if(mouse_focus) {
589  mouse_focus->fire(event, dynamic_cast<widget&>(*mouse_focus), position);
590  return;
591  }
592 
595  dispatcher->fire(event, dynamic_cast<widget&>(*dispatcher), position);
596  break;
597  }
598 
600  continue;
601  }
602 
603  if(dispatcher->is_at(position)) {
604  dispatcher->fire(event, dynamic_cast<widget&>(*dispatcher), position);
605  break;
606  }
607  }
608 }
609 
610 void sdl_event_handler::mouse_button_up(const point& position, const Uint8 button)
611 {
612  switch(button) {
613  case SDL_BUTTON_LEFT:
614  mouse(SDL_LEFT_BUTTON_UP, position);
615  break;
616  case SDL_BUTTON_MIDDLE:
617  mouse(SDL_MIDDLE_BUTTON_UP, position);
618  break;
619  case SDL_BUTTON_RIGHT:
620  mouse(SDL_RIGHT_BUTTON_UP, position);
621  break;
622  default:
623 #ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
624  WRN_GUI_E << "Unhandled 'mouse button up' event for button "
625  << static_cast<Uint32>(button) << ".\n";
626 #endif
627  break;
628  }
629 }
630 
631 void sdl_event_handler::mouse_button_down(const point& position, const Uint8 button)
632 {
633  switch(button) {
634  case SDL_BUTTON_LEFT:
635  mouse(SDL_LEFT_BUTTON_DOWN, position);
636  break;
637  case SDL_BUTTON_MIDDLE:
638  mouse(SDL_MIDDLE_BUTTON_DOWN, position);
639  break;
640  case SDL_BUTTON_RIGHT:
641  mouse(SDL_RIGHT_BUTTON_DOWN, position);
642  break;
643  default:
644 #ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
645  WRN_GUI_E << "Unhandled 'mouse button down' event for button "
646  << static_cast<Uint32>(button) << ".\n";
647 #endif
648  break;
649  }
650 }
651 
652 void sdl_event_handler::mouse_wheel(const point& position, int x, int y)
653 {
654  if(x > 0) {
655  mouse(SDL_WHEEL_RIGHT, position);
656  } else if(x < 0) {
657  mouse(SDL_WHEEL_LEFT, position);
658  }
659 
660  if(y < 0) {
661  mouse(SDL_WHEEL_DOWN, position);
662  } else if(y > 0) {
663  mouse(SDL_WHEEL_UP, position);
664  }
665 }
666 
668 {
669  if(keyboard_focus_) {
670  return keyboard_focus_;
671  }
672 
675  return dispatcher;
676  }
677  }
678 
679  return nullptr;
680 }
681 
682 void sdl_event_handler::touch_motion(const point& position, const point& distance)
683 {
685  dispatcher->fire(SDL_TOUCH_MOTION , dynamic_cast<widget&>(*dispatcher), position, distance);
686  }
687 }
688 
689 void sdl_event_handler::hat_motion(const SDL_Event& event)
690 {
691  const hotkey::hotkey_ptr& hk = hotkey::get_hotkey(event);
692  bool done = false;
693  if(!hk->null()) {
694  done = hotkey_pressed(hk);
695  }
696  if(!done) {
697  // TODO fendrin think about handling hat motions that are not bound to a
698  // hotkey.
699  }
700 }
701 
702 void sdl_event_handler::button_down(const SDL_Event& event)
703 {
704  const hotkey::hotkey_ptr hk = hotkey::get_hotkey(event);
705  bool done = false;
706  if(!hk->null()) {
707  done = hotkey_pressed(hk);
708  }
709  if(!done) {
710  // TODO fendrin think about handling button down events that are not
711  // bound to a hotkey.
712  }
713 }
714 
715 void sdl_event_handler::key_down(const SDL_Event& event)
716 {
717  const hotkey::hotkey_ptr hk = hotkey::get_hotkey(event);
718  bool done = false;
719  if(!hk->null()) {
720  done = hotkey_pressed(hk);
721  }
722  if(!done) {
723  if(event.type == SDL_TEXTINPUT) {
724  text_input(event.text.text);
725  } else {
726  key_down(event.key.keysym.sym, static_cast<const SDL_Keymod>(event.key.keysym.mod), "");
727  }
728  }
729 }
730 
732 {
733  key_down(SDLK_UNKNOWN, static_cast<SDL_Keymod>(0), unicode);
734 
737  dynamic_cast<widget&>(*dispatcher),
738  unicode, -1, -1);
739  }
740 }
741 
742 void sdl_event_handler::text_editing(const std::string& unicode, int32_t start, int32_t end)
743 {
746  dynamic_cast<widget&>(*dispatcher),
747  unicode, start, end);
748  }
749 }
750 
752 {
754 
755  if(!dispatcher) {
756  return false;
757  }
758 
759  return dispatcher->execute_hotkey(hotkey::get_id(key->get_command()));
760 }
761 
762 void sdl_event_handler::key_down(const SDL_Keycode key,
763  const SDL_Keymod modifier,
764  const utf8::string& unicode)
765 {
766  DBG_GUI_E << "Firing: " << SDL_KEY_DOWN << ".\n";
767 
769  dispatcher->fire(SDL_KEY_DOWN,
770  dynamic_cast<widget&>(*dispatcher),
771  key,
772  modifier,
773  unicode);
774  }
775 }
776 
778 {
779  DBG_GUI_E << "Firing: " << event << ".\n";
780 
782  dispatcher->fire(event, dynamic_cast<widget&>(*dispatcher));
783  }
784 }
785 
786 void sdl_event_handler::close_window(const unsigned window_id)
787 {
788  DBG_GUI_E << "Firing " << CLOSE_WINDOW << ".\n";
789 
790  window* window = window::window_instance(window_id);
791  if(window) {
792  window->fire(CLOSE_WINDOW, *window);
793  }
794 }
795 
796 /***** manager class. *****/
797 
799 {
800  handler_.reset(new sdl_event_handler());
801 
802 #ifdef MAIN_EVENT_HANDLER
803  draw_interval = 30;
804  SDL_AddTimer(draw_interval, timer_sdl_draw_event, nullptr);
805 
806  event_poll_interval = 10;
807  SDL_AddTimer(event_poll_interval, timer_sdl_poll_events, nullptr);
808 #endif
809 }
810 
812 {
813  handler_.reset(nullptr);
814 
815 #ifdef MAIN_EVENT_HANDLER
816  draw_interval = 0;
817  event_poll_interval = 0;
818 #endif
819 }
820 
821 /***** free functions class. *****/
822 
824 {
825  assert(handler_);
826  assert(dispatcher);
827  handler_->connect(dispatcher);
828 }
829 
831 {
832  assert(handler_);
833  assert(dispatcher);
834  handler_->disconnect(dispatcher);
835 }
836 
838 {
839  point mouse = get_mouse_position();
840 
841  SDL_Event event;
842  event.type = SDL_MOUSEMOTION;
843  event.motion.type = SDL_MOUSEMOTION;
844  event.motion.x = mouse.x;
845  event.motion.y = mouse.y;
846 
847  SDL_PushEvent(&event);
848 }
849 
851 {
852  assert(handler_);
853  assert(dispatcher);
854  handler_->mouse_focus = dispatcher;
855 }
856 
858 {
859  assert(handler_);
860  assert(dispatcher);
861  if(handler_->mouse_focus == dispatcher) {
862  handler_->mouse_focus = nullptr;
863  }
864 }
865 
867 {
868  assert(handler_);
869  assert(dispatcher);
870  assert(dispatcher->get_want_keyboard_input());
871 
872  handler_->keyboard_focus_ = dispatcher;
873 }
874 
875 std::ostream& operator<<(std::ostream& stream, const ui_event event)
876 {
877  switch(event) {
878  case DRAW:
879  stream << "draw";
880  break;
881  case CLOSE_WINDOW:
882  stream << "close window";
883  break;
884  case SDL_VIDEO_RESIZE:
885  stream << "SDL video resize";
886  break;
887  case SDL_MOUSE_MOTION:
888  stream << "SDL mouse motion";
889  break;
890  case MOUSE_ENTER:
891  stream << "mouse enter";
892  break;
893  case MOUSE_LEAVE:
894  stream << "mouse leave";
895  break;
896  case MOUSE_MOTION:
897  stream << "mouse motion";
898  break;
900  stream << "SDL left button down";
901  break;
902  case SDL_LEFT_BUTTON_UP:
903  stream << "SDL left button up";
904  break;
905  case LEFT_BUTTON_DOWN:
906  stream << "left button down";
907  break;
908  case LEFT_BUTTON_UP:
909  stream << "left button up";
910  break;
911  case LEFT_BUTTON_CLICK:
912  stream << "left button click";
913  break;
915  stream << "left button double click";
916  break;
918  stream << "SDL middle button down";
919  break;
921  stream << "SDL middle button up";
922  break;
923  case MIDDLE_BUTTON_DOWN:
924  stream << "middle button down";
925  break;
926  case MIDDLE_BUTTON_UP:
927  stream << "middle button up";
928  break;
929  case MIDDLE_BUTTON_CLICK:
930  stream << "middle button click";
931  break;
933  stream << "middle button double click";
934  break;
936  stream << "SDL right button down";
937  break;
938  case SDL_RIGHT_BUTTON_UP:
939  stream << "SDL right button up";
940  break;
941  case RIGHT_BUTTON_DOWN:
942  stream << "right button down";
943  break;
944  case RIGHT_BUTTON_UP:
945  stream << "right button up";
946  break;
947  case RIGHT_BUTTON_CLICK:
948  stream << "right button click";
949  break;
951  stream << "right button double click";
952  break;
953  case SDL_WHEEL_LEFT:
954  stream << "SDL wheel left";
955  break;
956  case SDL_WHEEL_RIGHT:
957  stream << "SDL wheel right";
958  break;
959  case SDL_WHEEL_UP:
960  stream << "SDL wheel up";
961  break;
962  case SDL_WHEEL_DOWN:
963  stream << "SDL wheel down";
964  break;
965  case SDL_KEY_DOWN:
966  stream << "SDL key down";
967  break;
968  case SDL_TEXT_INPUT:
969  stream << "SDL text input";
970  break;
971  case SDL_TEXT_EDITING:
972  stream << "SDL text editing";
973  break;
974 
975  case NOTIFY_REMOVAL:
976  stream << "notify removal";
977  break;
978  case NOTIFY_MODIFIED:
979  stream << "notify modified";
980  break;
982  stream << "receive keyboard focus";
983  break;
984  case LOSE_KEYBOARD_FOCUS:
985  stream << "lose keyboard focus";
986  break;
987  case SHOW_TOOLTIP:
988  stream << "show tooltip";
989  break;
991  stream << "notify remove tooltip";
992  break;
993  case SDL_ACTIVATE:
994  stream << "SDL activate";
995  break;
997  stream << "message show tooltip";
998  break;
999  case SHOW_HELPTIP:
1000  stream << "show helptip";
1001  break;
1002  case MESSAGE_SHOW_HELPTIP:
1003  stream << "message show helptip";
1004  break;
1005  case REQUEST_PLACEMENT:
1006  stream << "request placement";
1007  break;
1008  case SDL_TOUCH_MOTION:
1009  stream << "SDL touch motion";
1010  break;
1011  case SDL_TOUCH_UP:
1012  stream << "SDL touch up";
1013  break;
1014  case SDL_TOUCH_DOWN:
1015  stream << "SDL touch down";
1016  break;
1017  case SDL_RAW_EVENT:
1018  stream << "SDL raw event";
1019  break;
1020  }
1021 
1022  return stream;
1023 }
1024 
1025 } // namespace event
1026 
1027 std::vector<window*> open_window_stack {};
1028 
1030 {
1031  for(auto iter = open_window_stack.rbegin(); iter != open_window_stack.rend(); ++iter) {
1032  if(*iter == window) {
1033  open_window_stack.erase(std::next(iter).base());
1034  break;
1035  }
1036  }
1037 }
1038 
1040 {
1041  return !open_window_stack.empty();
1042 }
1043 
1044 } // namespace gui2
Define the common log macros for the gui toolkit.
dispatcher * keyboard_focus_
Needed to determine which dispatcher gets the keyboard events.
Definition: handler.cpp:315
Request the widget to show its hover helptip.
Definition: handler.hpp:113
static std::unique_ptr< class sdl_event_handler > handler_
Definition: handler.cpp:62
An SDL text editing (IME) event.
Definition: handler.hpp:93
std::vector< char_t > string
A left mouse button down event for a widget.
Definition: handler.hpp:68
Widget loses keyboard focus.
Definition: handler.hpp:108
void video_resize(const point &new_size)
Fires a video resize event.
Definition: handler.cpp:565
An SDL wheel right event.
Definition: handler.hpp:88
bool hotkey_pressed(const hotkey::hotkey_ptr key)
Handles the pressing of a hotkey.
Definition: handler.cpp:751
Base class for event handling.
Definition: dispatcher.hpp:161
See LEFT_BUTTON_CLICK.
Definition: handler.hpp:84
void activate()
Reinitializes the state of all dispatchers.
Definition: handler.cpp:516
int x
x coordinate.
Definition: point.hpp:34
An SDL left mouse button down event.
Definition: handler.hpp:66
Definition: video.hpp:29
void flip()
Definition: video.cpp:321
An SDL resize request, coordinate is the new window size.
Definition: handler.hpp:59
This file contains the window object, this object is a top level container which has the event manage...
An SDL key down event.
Definition: handler.hpp:91
Base class for all widgets.
Definition: widget.hpp:48
void text_editing(const std::string &unicode, int32_t start, int32_t len)
Fires a text editing event.
Definition: handler.cpp:742
A mouse leave event for a widget.
Definition: handler.hpp:64
bool is_in_dialog()
Is a dialog open?
Definition: handler.cpp:1039
#define TIMER_EVENT
Definition: events.hpp:24
#define DRAW_EVENT
Definition: events.hpp:26
Holds a 2D point.
Definition: point.hpp:23
See LEFT_BUTTON_DOUBLE_CLICK.
Definition: handler.hpp:85
See LEFT_BUTTON_CLICK.
Definition: handler.hpp:77
int y
y coordinate.
Definition: point.hpp:37
void capture_mouse(dispatcher *dispatcher)
Captures the mouse.
Definition: handler.cpp:850
An SDL right mouse button down event.
Definition: handler.hpp:80
virtual void draw()
Definition: events.hpp:78
void capture_keyboard(dispatcher *dispatcher)
Captures the keyboard.
Definition: handler.cpp:866
See LEFT_BUTTON_DOWN.
Definition: handler.hpp:75
#define d
void button_down(const SDL_Event &event)
Handles a joystick button down event.
Definition: handler.cpp:702
Request to show a helptip based on the data sent.
Definition: handler.hpp:114
void hat_motion(const SDL_Event &event)
Handles a hat motion event.
Definition: handler.cpp:689
void key_down(const SDL_Event &event)
Fires a key down event.
Definition: handler.cpp:715
-file util.hpp
An SDL wheel down event.
Definition: handler.hpp:90
See LEFT_BUTTON_UP.
Definition: handler.hpp:83
Widget gains keyboard focus.
Definition: handler.hpp:107
void touch_motion(const point &position, const point &distance)
Fires a generic touch event.
Definition: handler.cpp:682
Request the widget to show its hover tooltip.
Definition: handler.hpp:110
void mouse_button_down(const point &position, const Uint8 button)
Fires a mouse button down event.
Definition: handler.cpp:631
bool get_want_keyboard_input() const
Definition: dispatcher.hpp:686
void init_mouse_location()
Initializes the location of the mouse.
Definition: handler.cpp:837
Generic file dialog.
Definition: text.hpp:37
Sent by a widget to notify others its contents or state are modified.
Definition: handler.hpp:96
void handle_event(const SDL_Event &event)
Inherited from events::sdl_handler.
Definition: handler.cpp:344
#define CLOSE_WINDOW_EVENT
Definition: events.hpp:27
Request the widget to remove its hover tooltip.
Definition: handler.hpp:111
mouse_behavior get_mouse_behavior() const
Definition: dispatcher.hpp:676
Request to place the widget.
Definition: handler.hpp:102
static events::event_context * event_context
Definition: handler.cpp:63
const hotkey_ptr get_hotkey(const SDL_Event &event)
Iterate through the list of hotkeys and return a hotkey that matches the SDL_Event and the current ke...
virtual bool is_at(const point &coordinate) const =0
Determines whether the location is inside an active widget.
This singleton class handles all events.
Definition: handler.cpp:120
void close_window(const unsigned window_id)
Fires a CLOSE_WINDOW event for the window with the given ID.
Definition: handler.cpp:786
A left mouse button up event for a widget.
Definition: handler.hpp:69
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:469
Periodic redraw request.
Definition: handler.hpp:57
Sent by a widget to notify others it's being destroyed.
Definition: handler.hpp:95
bool execute_hotkey(const hotkey::HOTKEY_COMMAND id)
Executes a hotkey.
Definition: dispatcher.cpp:193
void remove_from_window_stack(window *window)
Removes a entry from the open_window_stack list.
Definition: handler.cpp:1029
void disconnect_dispatcher(dispatcher *dispatcher)
Disconnects a dispatcher to the event handler.
Definition: handler.cpp:830
An SDL middle mouse button down event.
Definition: handler.hpp:73
virtual void join()
Definition: events.cpp:232
void connect_dispatcher(dispatcher *dispatcher)
Connects a dispatcher to the event handler.
Definition: handler.cpp:823
void pump()
Definition: events.cpp:409
An SDL wheel up event.
Definition: handler.hpp:89
void handle_window_event(const SDL_Event &event)
Inherited from events::sdl_handler.
Definition: handler.cpp:463
static window * window_instance(const unsigned handle)
Returns the instance of a window.
Definition: window.cpp:432
void mouse(const ui_event event, const point &position)
Fires a generic mouse event.
Definition: handler.cpp:584
void mouse_button_up(const point &position, const Uint8 button)
Fires a mouse button up event.
Definition: handler.cpp:610
#define DRAW_ALL_EVENT
Definition: events.hpp:29
An SDL middle mouse button up event.
Definition: handler.hpp:74
void mouse_wheel(const point &position, int scrollx, int scrolly)
Fires a mouse wheel event.
Definition: handler.cpp:652
#define DOUBLE_CLICK_EVENT
Definition: events.hpp:23
void text_input(const std::string &unicode)
Fires a text input event.
Definition: handler.cpp:731
#define DBG_GUI_E
Definition: log.hpp:34
An SDL wheel left event.
Definition: handler.hpp:87
#define SHOW_HELPTIP_EVENT
Definition: events.hpp:28
A mouse motion event for a widget.
Definition: handler.hpp:63
#define WRN_GUI_E
Definition: log.hpp:36
void disconnect(dispatcher *dispatcher)
Disconnects a dispatcher.
Definition: handler.cpp:481
A left mouse button double click event for a widget.
Definition: handler.hpp:71
A mouse enter event for a widget.
Definition: handler.hpp:62
std::ostream & operator<<(std::ostream &stream, const ui_event event)
Definition: handler.cpp:875
Contains the gui2 timer routines.
Request to show a tooltip based on the data sent.
Definition: handler.hpp:112
#define HOVER_REMOVE_POPUP_EVENT
Definition: events.hpp:25
void keyboard(const ui_event event)
Fires a keyboard event which has no parameters.
Definition: handler.cpp:777
std::shared_ptr< hotkey_base > hotkey_ptr
Definition: hotkey_item.hpp:31
The main application window is activated.
Definition: handler.hpp:56
void raw_event(const SDL_Event &event)
Fires a raw SDL event.
Definition: handler.cpp:575
Handling of system events.
Definition: manager.hpp:39
#define next(ls)
Definition: llex.cpp:32
An SDL left mouse button up event.
Definition: handler.hpp:67
point get_mouse_position()
Returns the current mouse position.
Definition: helper.cpp:131
std::vector< dispatcher * > dispatchers_
The dispatchers.
Definition: handler.cpp:308
bool execute_timer(const size_t id)
Executes a timer.
Definition: timer.cpp:174
friend void capture_keyboard(dispatcher *)
Captures the keyboard.
Definition: handler.cpp:866
bool find(E event, F functor)
Tests whether an event handler is available.
An SDL text input (commit) event.
Definition: handler.hpp:92
void connect(dispatcher *dispatcher)
Connects a dispatcher.
Definition: handler.cpp:468
void release_mouse(dispatcher *dispatcher)
Releases a captured mouse.
Definition: handler.cpp:857
Simple push button.
Definition: button.hpp:35
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
Definition: dispatcher.cpp:120
See LEFT_BUTTON_DOWN.
Definition: handler.hpp:82
static void reverse(lua_State *L, StkId from, StkId to)
Definition: lapi.cpp:193
virtual void leave()
Definition: events.cpp:278
A request to close the current window.
Definition: handler.hpp:58
dispatcher * keyboard_dispatcher()
Gets the dispatcher that wants to receive the keyboard input.
Definition: handler.cpp:667
An SDL right mouse button up event.
Definition: handler.hpp:81
See LEFT_BUTTON_DOUBLE_CLICK.
Definition: handler.hpp:78
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
A left mouse button click event for a widget.
Definition: handler.hpp:70
dispatcher * mouse_focus
The dispatcher that captured the mouse focus.
Definition: handler.cpp:150
See LEFT_BUTTON_UP.
Definition: handler.hpp:76
HOTKEY_COMMAND get_id(const std::string &command)
returns get_hotkey_command(command).id
ui_event
The event send to the dispatcher.
Definition: handler.hpp:55
std::string string
EXIT_STATUS start(const config &game_conf, CVideo &video, 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
std::vector< window * > open_window_stack
Keeps track of any open windows of any type (modal, non-modal, or tooltip) in the order in which they...
Definition: handler.cpp:1027
An SDL mouse motion event.
Definition: handler.hpp:61