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_t timer_sdl_draw_event(uint32_t, 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_t timer_sdl_poll_events(uint32_t, 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  /**
150  * Returns all dispatchers in the Z order.
151  */
152  std::vector<dispatcher*>& get_dispatchers() { return dispatchers_; }
153 
154  /** The dispatcher that captured the mouse focus. */
155  dispatcher* mouse_focus;
156 
157 private:
158  /**
159  * Reinitializes the state of all dispatchers.
160  *
161  * This is needed when the application gets activated, to make sure the
162  * state of mainly the mouse is set properly.
163  */
164  void activate();
165 
166  /***** Handlers *****/
167 
168  /** Fires a raw SDL event. */
169  void raw_event(const SDL_Event &event);
170 
171  /** Fires a draw event. */
173  void draw();
174  void draw_everything();
175 
176  /**
177  * Fires a video resize event.
178  *
179  * @param new_size The new size of the window.
180  */
181  void video_resize(const point& new_size);
182 
183  /**
184  * Fires a generic mouse event.
185  *
186  * @param event The event to fire.
187  * @param position The position of the mouse.
188  */
189  void mouse(const ui_event event, const point& position);
190 
191  /**
192  * Fires a mouse button up event.
193  *
194  * @param position The position of the mouse.
195  * @param button The SDL id of the button that caused the
196  * event.
197  */
198  void mouse_button_up(const point& position, const uint8_t button);
199 
200  /**
201  * Fires a mouse button down event.
202  *
203  * @param position The position of the mouse.
204  * @param button The SDL id of the button that caused the
205  * event.
206  */
207  void mouse_button_down(const point& position, const uint8_t button);
208 
209  /**
210  * Fires a mouse wheel event.
211  *
212  * @param position The position of the mouse.
213  * @param scrollx The amount of horizontal scrolling.
214  * @param scrolly The amount of vertical scrolling.
215  */
216  void mouse_wheel(const point& position, int scrollx, int scrolly);
217 
218  /**
219  * Gets the dispatcher that wants to receive the keyboard input.
220  *
221  * @returns The dispatcher.
222  * @retval nullptr No dispatcher found.
223  */
224  dispatcher* keyboard_dispatcher();
225 
226  /**
227  * Fires a generic touch event.
228  *
229  * @param position The position touched.
230  * @param distance The distance moved.
231  */
232  void touch_motion(const point& position, const point& distance);
233 
234  /**
235  * Handles a hat motion event.
236  *
237  * @param event The SDL joystick hat event triggered.
238  */
239  void hat_motion(const SDL_Event& event);
240 
241  /**
242  * Handles a joystick button down event.
243  *
244  * @param event The SDL joystick button event triggered.
245  */
246  void button_down(const SDL_Event& event);
247 
248  /**
249  * Fires a key down event.
250  *
251  * @param event The SDL keyboard event triggered.
252  */
253  void key_down(const SDL_Event& event);
254 
255  /**
256  * Handles the pressing of a hotkey.
257  *
258  * @param key The hotkey item pressed.
259  *
260  * @returns True if there was a valid dispatcher with
261  * which to execute the hotkey callback, false
262  * otherwise.
263  */
264  bool hotkey_pressed(const hotkey::hotkey_ptr key);
265 
266  /**
267  * Fires a key down event.
268  *
269  * @param key The SDL key code of the key pressed.
270  * @param modifier The SDL key modifiers used.
271  * @param unicode The unicode value for the key pressed.
272  */
273  void key_down(const SDL_Keycode key,
274  const SDL_Keymod modifier,
275  const utf8::string& unicode);
276 
277  /**
278  * Fires a text input event.
279  *
280  * @param unicode The unicode value for the text entered.
281  */
282  void text_input(const std::string& unicode);
283 
284  /**
285  * Fires a text editing event.
286  *
287  * @param unicode The unicode value for the text being edited.
288  * @param start The start position for the text being edited.
289  * @param len The selection length for the text being edited.
290  */
291  void text_editing(const std::string& unicode, int32_t start, int32_t len);
292 
293  /**
294  * Fires a keyboard event which has no parameters.
295  *
296  * This can happen for example when the mouse wheel is used.
297  *
298  * @param event The event to fire.
299  */
300  void keyboard(const ui_event event);
301 
302  /**
303  * Fires a CLOSE_WINDOW event for the window with the given ID.
304  *
305  * @param window_id The ID of the window to close.
306  */
307  void close_window(const unsigned window_id);
308 
309  /**
310  * The dispatchers.
311  *
312  * The order of the items in the list is also the z-order the front item
313  * being the one completely in the background and the back item the one
314  * completely in the foreground.
315  */
316  std::vector<dispatcher*> dispatchers_;
317 
318  /**
319  * Needed to determine which dispatcher gets the keyboard events.
320  *
321  * NOTE the keyboard events aren't really wired in yet so doesn't do much.
322  */
323  dispatcher* keyboard_focus_;
324  friend void capture_keyboard(dispatcher*);
325 };
326 
328  : events::sdl_handler(false)
329  , mouse_focus(nullptr)
330  , dispatchers_()
331  , keyboard_focus_(nullptr)
332 {
333  if(SDL_WasInit(SDL_INIT_TIMER) == 0) {
334  if(SDL_InitSubSystem(SDL_INIT_TIMER) == -1) {
335  assert(false);
336  }
337  }
338 
339 // The event context is created now we join it.
340 #ifdef ENABLE
341  join();
342 #endif
343 }
344 
346 {
347 #ifdef ENABLE
348  leave();
349 #endif
350 }
351 
352 void sdl_event_handler::handle_event(const SDL_Event& event)
353 {
354  /** No dispatchers drop the event. */
355  if(dispatchers_.empty()) {
356  return;
357  }
358 
359  switch(event.type) {
360  case SDL_MOUSEMOTION:
361  mouse(SDL_MOUSE_MOTION, {event.motion.x, event.motion.y});
362  break;
363 
364  case SDL_MOUSEBUTTONDOWN:
365  mouse_button_down({event.button.x, event.button.y}, event.button.button);
366  break;
367 
368  case SDL_MOUSEBUTTONUP:
369  mouse_button_up({event.button.x, event.button.y}, event.button.button);
370  break;
371 
372  case SDL_MOUSEWHEEL:
373  mouse_wheel(get_mouse_position(), event.wheel.x, event.wheel.y);
374  break;
375 
376  case SHOW_HELPTIP_EVENT:
378  break;
379 
381  // remove_popup();
382  break;
383 
384  case DRAW_EVENT:
385  draw();
386  break;
387 
388  case DRAW_ALL_EVENT:
389  draw_everything();
390  break;
391 
392  case TIMER_EVENT:
393  execute_timer(reinterpret_cast<size_t>(event.user.data1));
394  break;
395 
396  case CLOSE_WINDOW_EVENT:
397  close_window(event.user.code);
398  break;
399 
400  case SDL_JOYBUTTONDOWN:
401  button_down(event);
402  break;
403 
404  case SDL_JOYBUTTONUP:
405  break;
406 
407  case SDL_JOYAXISMOTION:
408  break;
409 
410  case SDL_JOYHATMOTION:
411  hat_motion(event);
412  break;
413 
414  case SDL_KEYDOWN:
415  key_down(event);
416  break;
417 
418  case SDL_WINDOWEVENT:
419  switch(event.window.event) {
420  case SDL_WINDOWEVENT_EXPOSED:
421  draw();
422  break;
423 
424  case SDL_WINDOWEVENT_RESIZED:
425  video_resize({event.window.data1, event.window.data2});
426  break;
427 
428  case SDL_WINDOWEVENT_ENTER:
429  case SDL_WINDOWEVENT_FOCUS_GAINED:
430  activate();
431  break;
432  }
433 
434  break;
435 
436  case SDL_TEXTINPUT:
437  key_down(event);
438  break;
439 
440  case SDL_TEXTEDITING:
441  text_editing(event.edit.text, event.edit.start, event.edit.length);
442  break;
443 
444  case SDL_FINGERMOTION:
445  touch_motion(point(event.tfinger.x, event.tfinger.y), point(event.tfinger.dx, event.tfinger.dy));
446  break;
447 
448 #if(defined(_X11) && !defined(__APPLE__)) || defined(_WIN32)
449  case SDL_SYSWMEVENT:
450  /* DO NOTHING */
451  break;
452 #endif
453 
454  // Silently ignored events.
455  case SDL_KEYUP:
456  case DOUBLE_CLICK_EVENT:
457  case SDL_FINGERUP:
458  case SDL_FINGERDOWN:
459  break;
460 
461  default:
462 #ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
463  WRN_GUI_E << "Unhandled event " << static_cast<uint32_t>(event.type)
464  << ".\n";
465 #endif
466  break;
467  }
468 
469  raw_event(event);
470 }
471 
472 void sdl_event_handler::handle_window_event(const SDL_Event& event)
473 {
474  handle_event(event);
475 }
476 
478 {
479  assert(std::find(dispatchers_.begin(), dispatchers_.end(), dispatcher)
480  == dispatchers_.end());
481 
482  if(dispatchers_.empty()) {
483  event_context = new events::event_context();
484  join();
485  }
486 
487  dispatchers_.push_back(dispatcher);
488 }
489 
491 {
492  /***** Validate pre conditions. *****/
493  auto itor = std::find(dispatchers_.begin(), dispatchers_.end(), disp);
494  assert(itor != dispatchers_.end());
495 
496  /***** Remove dispatcher. *****/
497  dispatchers_.erase(itor);
498 
499  if(disp == mouse_focus) {
500  mouse_focus = nullptr;
501  }
502  if(disp == keyboard_focus_) {
503  keyboard_focus_ = nullptr;
504  }
505 
506  /***** Set proper state for the other dispatchers. *****/
507  for(auto d : dispatchers_)
508  {
509  dynamic_cast<widget&>(*d).set_is_dirty(true);
510  }
511 
512  activate();
513 
514  /***** Validate post conditions. *****/
515  assert(std::find(dispatchers_.begin(), dispatchers_.end(), disp)
516  == dispatchers_.end());
517 
518  if(dispatchers_.empty()) {
519  leave();
520  delete event_context;
521  event_context = nullptr;
522  }
523 }
524 
526 {
527  for(auto dispatcher : dispatchers_)
528  {
529  dispatcher->fire(SDL_ACTIVATE, dynamic_cast<widget&>(*dispatcher), nullptr);
530  }
531 }
532 
534 {
535  for(auto dispatcher : dispatchers_)
536  {
537  dispatcher->fire(DRAW, dynamic_cast<widget&>(*dispatcher));
538  }
539 
540  if(!dispatchers_.empty()) {
541  CVideo& video = dynamic_cast<window&>(*dispatchers_.back()).video();
542 
543  video.flip();
544  }
545 }
546 
548 {
549  for(auto dispatcher : dispatchers_) {
550  dynamic_cast<widget&>(*dispatcher).set_is_dirty(true);
551  }
552 
553  draw();
554 }
555 
557 {
558  DBG_GUI_E << "Firing: " << SDL_VIDEO_RESIZE << ".\n";
559 
560  for(auto dispatcher : dispatchers_)
561  {
562  dispatcher->fire(SDL_VIDEO_RESIZE, dynamic_cast<widget&>(*dispatcher), new_size);
563  }
564 }
565 
566 void sdl_event_handler::raw_event(const SDL_Event& event) {
567  DBG_GUI_E << "Firing raw event\n";
568 
569  for(auto dispatcher : dispatchers_)
570  {
571  dispatcher->fire(SDL_RAW_EVENT, dynamic_cast<widget&>(*dispatcher), event);
572  }
573 }
574 
575 void sdl_event_handler::mouse(const ui_event event, const point& position)
576 {
577  DBG_GUI_E << "Firing: " << event << ".\n";
578 
579  if(mouse_focus) {
580  mouse_focus->fire(event, dynamic_cast<widget&>(*mouse_focus), position);
581  return;
582  }
583 
586  dispatcher->fire(event, dynamic_cast<widget&>(*dispatcher), position);
587  break;
588  }
589 
591  continue;
592  }
593 
594  if(dispatcher->is_at(position)) {
595  dispatcher->fire(event, dynamic_cast<widget&>(*dispatcher), position);
596  break;
597  }
598  }
599 }
600 
601 void sdl_event_handler::mouse_button_up(const point& position, const uint8_t button)
602 {
603  switch(button) {
604  case SDL_BUTTON_LEFT:
605  mouse(SDL_LEFT_BUTTON_UP, position);
606  break;
607  case SDL_BUTTON_MIDDLE:
608  mouse(SDL_MIDDLE_BUTTON_UP, position);
609  break;
610  case SDL_BUTTON_RIGHT:
611  mouse(SDL_RIGHT_BUTTON_UP, position);
612  break;
613  default:
614 #ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
615  WRN_GUI_E << "Unhandled 'mouse button up' event for button "
616  << static_cast<uint32_t>(button) << ".\n";
617 #endif
618  break;
619  }
620 }
621 
622 void sdl_event_handler::mouse_button_down(const point& position, const uint8_t button)
623 {
624  switch(button) {
625  case SDL_BUTTON_LEFT:
626  mouse(SDL_LEFT_BUTTON_DOWN, position);
627  break;
628  case SDL_BUTTON_MIDDLE:
629  mouse(SDL_MIDDLE_BUTTON_DOWN, position);
630  break;
631  case SDL_BUTTON_RIGHT:
632  mouse(SDL_RIGHT_BUTTON_DOWN, position);
633  break;
634  default:
635 #ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
636  WRN_GUI_E << "Unhandled 'mouse button down' event for button "
637  << static_cast<uint32_t>(button) << ".\n";
638 #endif
639  break;
640  }
641 }
642 
643 void sdl_event_handler::mouse_wheel(const point& position, int x, int y)
644 {
645  if(x > 0) {
646  mouse(SDL_WHEEL_RIGHT, position);
647  } else if(x < 0) {
648  mouse(SDL_WHEEL_LEFT, position);
649  }
650 
651  if(y < 0) {
652  mouse(SDL_WHEEL_DOWN, position);
653  } else if(y > 0) {
654  mouse(SDL_WHEEL_UP, position);
655  }
656 }
657 
659 {
660  if(keyboard_focus_) {
661  return keyboard_focus_;
662  }
663 
666  return dispatcher;
667  }
668  }
669 
670  return nullptr;
671 }
672 
673 void sdl_event_handler::touch_motion(const point& position, const point& distance)
674 {
676  dispatcher->fire(SDL_TOUCH_MOTION , dynamic_cast<widget&>(*dispatcher), position, distance);
677  }
678 }
679 
680 void sdl_event_handler::hat_motion(const SDL_Event& event)
681 {
682  const hotkey::hotkey_ptr& hk = hotkey::get_hotkey(event);
683  bool done = false;
684  if(!hk->null()) {
685  done = hotkey_pressed(hk);
686  }
687  if(!done) {
688  // TODO fendrin think about handling hat motions that are not bound to a
689  // hotkey.
690  }
691 }
692 
693 void sdl_event_handler::button_down(const SDL_Event& event)
694 {
695  const hotkey::hotkey_ptr hk = hotkey::get_hotkey(event);
696  bool done = false;
697  if(!hk->null()) {
698  done = hotkey_pressed(hk);
699  }
700  if(!done) {
701  // TODO fendrin think about handling button down events that are not
702  // bound to a hotkey.
703  }
704 }
705 
706 void sdl_event_handler::key_down(const SDL_Event& event)
707 {
708  const hotkey::hotkey_ptr hk = hotkey::get_hotkey(event);
709  bool done = false;
710  if(!hk->null()) {
711  done = hotkey_pressed(hk);
712  }
713  if(!done) {
714  if(event.type == SDL_TEXTINPUT) {
715  text_input(event.text.text);
716  } else {
717  key_down(event.key.keysym.sym, static_cast<SDL_Keymod>(event.key.keysym.mod), "");
718  }
719  }
720 }
721 
723 {
724  key_down(SDLK_UNKNOWN, static_cast<SDL_Keymod>(0), unicode);
725 
728  dynamic_cast<widget&>(*dispatcher),
729  unicode, -1, -1);
730  }
731 }
732 
733 void sdl_event_handler::text_editing(const std::string& unicode, int32_t start, int32_t end)
734 {
737  dynamic_cast<widget&>(*dispatcher),
738  unicode, start, end);
739  }
740 }
741 
743 {
745  return dispatcher->execute_hotkey(hotkey::get_id(key->get_command()));
746  }
747 
748  return false;
749 }
750 
751 void sdl_event_handler::key_down(const SDL_Keycode key,
752  const SDL_Keymod modifier,
753  const utf8::string& unicode)
754 {
755  DBG_GUI_E << "Firing: " << SDL_KEY_DOWN << ".\n";
756 
758  dispatcher->fire(SDL_KEY_DOWN,
759  dynamic_cast<widget&>(*dispatcher),
760  key,
761  modifier,
762  unicode);
763  }
764 }
765 
767 {
768  DBG_GUI_E << "Firing: " << event << ".\n";
769 
771  dispatcher->fire(event, dynamic_cast<widget&>(*dispatcher));
772  }
773 }
774 
775 void sdl_event_handler::close_window(const unsigned window_id)
776 {
777  DBG_GUI_E << "Firing " << CLOSE_WINDOW << ".\n";
778 
779  window* window = window::window_instance(window_id);
780  if(window) {
781  window->fire(CLOSE_WINDOW, *window);
782  }
783 }
784 
785 /***** manager class. *****/
786 
788 {
789  handler_.reset(new sdl_event_handler());
790 
791 #ifdef MAIN_EVENT_HANDLER
792  draw_interval = 30;
793  SDL_AddTimer(draw_interval, timer_sdl_draw_event, nullptr);
794 
795  event_poll_interval = 10;
796  SDL_AddTimer(event_poll_interval, timer_sdl_poll_events, nullptr);
797 #endif
798 }
799 
801 {
802  handler_.reset(nullptr);
803 
804 #ifdef MAIN_EVENT_HANDLER
805  draw_interval = 0;
806  event_poll_interval = 0;
807 #endif
808 }
809 
810 /***** free functions class. *****/
811 
813 {
814  assert(handler_);
815  assert(dispatcher);
816  handler_->connect(dispatcher);
817 }
818 
820 {
821  assert(handler_);
822  assert(dispatcher);
823  handler_->disconnect(dispatcher);
824 }
825 
826 std::vector<dispatcher*>& get_all_dispatchers()
827 {
828  assert(handler_);
829  return handler_->get_dispatchers();
830 }
831 
833 {
834  point mouse = get_mouse_position();
835 
836  SDL_Event event;
837  event.type = SDL_MOUSEMOTION;
838  event.motion.type = SDL_MOUSEMOTION;
839  event.motion.x = mouse.x;
840  event.motion.y = mouse.y;
841 
842  SDL_PushEvent(&event);
843 }
844 
846 {
847  assert(handler_);
848  assert(dispatcher);
849  handler_->mouse_focus = dispatcher;
850 }
851 
853 {
854  assert(handler_);
855  assert(dispatcher);
856  if(handler_->mouse_focus == dispatcher) {
857  handler_->mouse_focus = nullptr;
858  }
859 }
860 
862 {
863  assert(handler_);
864  assert(dispatcher);
865  assert(dispatcher->get_want_keyboard_input());
866 
867  handler_->keyboard_focus_ = dispatcher;
868 }
869 
870 std::ostream& operator<<(std::ostream& stream, const ui_event event)
871 {
872  switch(event) {
873  case DRAW:
874  stream << "draw";
875  break;
876  case CLOSE_WINDOW:
877  stream << "close window";
878  break;
879  case SDL_VIDEO_RESIZE:
880  stream << "SDL video resize";
881  break;
882  case SDL_MOUSE_MOTION:
883  stream << "SDL mouse motion";
884  break;
885  case MOUSE_ENTER:
886  stream << "mouse enter";
887  break;
888  case MOUSE_LEAVE:
889  stream << "mouse leave";
890  break;
891  case MOUSE_MOTION:
892  stream << "mouse motion";
893  break;
895  stream << "SDL left button down";
896  break;
897  case SDL_LEFT_BUTTON_UP:
898  stream << "SDL left button up";
899  break;
900  case LEFT_BUTTON_DOWN:
901  stream << "left button down";
902  break;
903  case LEFT_BUTTON_UP:
904  stream << "left button up";
905  break;
906  case LEFT_BUTTON_CLICK:
907  stream << "left button click";
908  break;
910  stream << "left button double click";
911  break;
913  stream << "SDL middle button down";
914  break;
916  stream << "SDL middle button up";
917  break;
918  case MIDDLE_BUTTON_DOWN:
919  stream << "middle button down";
920  break;
921  case MIDDLE_BUTTON_UP:
922  stream << "middle button up";
923  break;
924  case MIDDLE_BUTTON_CLICK:
925  stream << "middle button click";
926  break;
928  stream << "middle button double click";
929  break;
931  stream << "SDL right button down";
932  break;
933  case SDL_RIGHT_BUTTON_UP:
934  stream << "SDL right button up";
935  break;
936  case RIGHT_BUTTON_DOWN:
937  stream << "right button down";
938  break;
939  case RIGHT_BUTTON_UP:
940  stream << "right button up";
941  break;
942  case RIGHT_BUTTON_CLICK:
943  stream << "right button click";
944  break;
946  stream << "right button double click";
947  break;
948  case SDL_WHEEL_LEFT:
949  stream << "SDL wheel left";
950  break;
951  case SDL_WHEEL_RIGHT:
952  stream << "SDL wheel right";
953  break;
954  case SDL_WHEEL_UP:
955  stream << "SDL wheel up";
956  break;
957  case SDL_WHEEL_DOWN:
958  stream << "SDL wheel down";
959  break;
960  case SDL_KEY_DOWN:
961  stream << "SDL key down";
962  break;
963  case SDL_TEXT_INPUT:
964  stream << "SDL text input";
965  break;
966  case SDL_TEXT_EDITING:
967  stream << "SDL text editing";
968  break;
969 
970  case NOTIFY_REMOVAL:
971  stream << "notify removal";
972  break;
973  case NOTIFY_MODIFIED:
974  stream << "notify modified";
975  break;
977  stream << "receive keyboard focus";
978  break;
979  case LOSE_KEYBOARD_FOCUS:
980  stream << "lose keyboard focus";
981  break;
982  case SHOW_TOOLTIP:
983  stream << "show tooltip";
984  break;
986  stream << "notify remove tooltip";
987  break;
988  case SDL_ACTIVATE:
989  stream << "SDL activate";
990  break;
992  stream << "message show tooltip";
993  break;
994  case SHOW_HELPTIP:
995  stream << "show helptip";
996  break;
998  stream << "message show helptip";
999  break;
1000  case REQUEST_PLACEMENT:
1001  stream << "request placement";
1002  break;
1003  case SDL_TOUCH_MOTION:
1004  stream << "SDL touch motion";
1005  break;
1006  case SDL_TOUCH_UP:
1007  stream << "SDL touch up";
1008  break;
1009  case SDL_TOUCH_DOWN:
1010  stream << "SDL touch down";
1011  break;
1012  case SDL_RAW_EVENT:
1013  stream << "SDL raw event";
1014  break;
1015  }
1016 
1017  return stream;
1018 }
1019 
1020 } // namespace event
1021 
1022 std::vector<window*> open_window_stack {};
1023 
1025 {
1026  for(auto iter = open_window_stack.rbegin(); iter != open_window_stack.rend(); ++iter) {
1027  if(*iter == window) {
1028  open_window_stack.erase(std::next(iter).base());
1029  break;
1030  }
1031  }
1032 }
1033 
1035 {
1036  return !open_window_stack.empty();
1037 }
1038 
1039 } // 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:323
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:556
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:742
Base class for event handling.
Definition: dispatcher.hpp:160
See LEFT_BUTTON_CLICK.
Definition: handler.hpp:84
void activate()
Reinitializes the state of all dispatchers.
Definition: handler.cpp:525
An SDL left mouse button down event.
Definition: handler.hpp:66
Definition: video.hpp:31
void flip()
Renders the screen.
Definition: video.cpp:333
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:733
A mouse leave event for a widget.
Definition: handler.hpp:64
bool is_in_dialog()
Is a dialog open?
Definition: handler.cpp:1034
#define TIMER_EVENT
Definition: events.hpp:24
#define DRAW_EVENT
Definition: events.hpp:26
See LEFT_BUTTON_DOUBLE_CLICK.
Definition: handler.hpp:85
See LEFT_BUTTON_CLICK.
Definition: handler.hpp:77
Type that can be thrown as an exception to quit to desktop.
Definition: video.hpp:228
void capture_mouse(dispatcher *dispatcher)
Captures the mouse.
Definition: handler.cpp:845
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:861
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:693
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:680
void key_down(const SDL_Event &event)
Fires a key down event.
Definition: handler.cpp:706
-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:673
Request the widget to show its hover tooltip.
Definition: handler.hpp:110
bool get_want_keyboard_input() const
Definition: dispatcher.hpp:685
int x
x coordinate.
Definition: point.hpp:43
void init_mouse_location()
Initializes the location of the mouse.
Definition: handler.cpp:832
Generic file dialog.
Definition: field-fwd.hpp:22
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:352
#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:675
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:775
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
std::vector< dispatcher * > & get_all_dispatchers()
Gets all event dispatchers in the Z order.
Definition: handler.cpp:826
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:1024
void disconnect_dispatcher(dispatcher *dispatcher)
Disconnects a dispatcher to the event handler.
Definition: handler.cpp:819
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:812
std::vector< dispatcher * > & get_dispatchers()
Returns all dispatchers in the Z order.
Definition: handler.cpp:152
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:472
void mouse_button_up(const point &position, const uint8_t button)
Fires a mouse button up event.
Definition: handler.cpp:601
static window * window_instance(const unsigned handle)
Returns the instance of a window.
Definition: window.cpp:425
void mouse(const ui_event event, const point &position)
Fires a generic mouse event.
Definition: handler.cpp:575
#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:643
#define DOUBLE_CLICK_EVENT
Definition: events.hpp:23
void mouse_button_down(const point &position, const uint8_t button)
Fires a mouse button down event.
Definition: handler.cpp:622
void text_input(const std::string &unicode)
Fires a text input event.
Definition: handler.cpp:722
#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
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
#define WRN_GUI_E
Definition: log.hpp:36
void disconnect(dispatcher *dispatcher)
Disconnects a dispatcher.
Definition: handler.cpp:490
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:870
Contains the gui2 timer routines.
Holds a 2D point.
Definition: point.hpp:22
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:766
std::shared_ptr< hotkey_base > hotkey_ptr
Definition: hotkey_item.hpp:30
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:566
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:316
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:861
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:477
void release_mouse(dispatcher *dispatcher)
Releases a captured mouse.
Definition: handler.cpp:852
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:658
An SDL right mouse button up event.
Definition: handler.hpp:81
See LEFT_BUTTON_DOUBLE_CLICK.
Definition: handler.hpp:78
int y
y coordinate.
Definition: point.hpp:46
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:155
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
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:1022
An SDL mouse motion event.
Definition: handler.hpp:61