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