The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
handler.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2009 - 2025
3 by Mark de Wever <koraq@xs4all.nl>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#define GETTEXT_DOMAIN "wesnoth-lib"
17
19
20#include "events.hpp"
22#include "gui/core/timer.hpp"
23#include "gui/core/log.hpp"
28#include "video.hpp"
29#include "utils/ranges.hpp"
30
31#include <SDL3/SDL_events.h>
32
33#include <cassert>
34
35/**
36 * @todo The items below are not implemented yet.
37 *
38 * - Tooltips have a fixed short time until showing up.
39 * - Tooltips are shown until the widget is exited.
40 * - Help messages aren't shown yet.
41 *
42 * @note it might be that tooltips will be shown independent of a window and in
43 * their own window, therefore the code will be cleaned up after that has been
44 * determined.
45 */
46
47/*
48 * At some point in the future this event handler should become the main event
49 * handler. This switch controls the experimental switch for that change.
50 */
51//#define MAIN_EVENT_HANDLER
52
53/* Since this code is still very experimental it's not enabled yet. */
54//#define ENABLE
55
56namespace gui2
57{
58
59namespace event
60{
61
62/***** Static data. *****/
63static std::unique_ptr<class sdl_event_handler> handler_ = nullptr;
64static std::unique_ptr<events::event_context> event_context = nullptr;
65
66#ifdef MAIN_EVENT_HANDLER
67static unsigned draw_interval = 0;
68static unsigned event_poll_interval = 0;
69
70/***** Static functions. *****/
71
72/**
73 * SDL_AddTimer() callback for the draw event.
74 *
75 * When this callback is called it pushes a new draw event in the event queue.
76 *
77 * @returns The new timer interval, 0 to stop.
78 */
79static uint32_t timer_sdl_draw_event(void*, SDL_TimerID, uint32_t)
80{
81 // DBG_GUI_E << "Pushing draw event in queue.";
82
83 SDL_Event event;
85
86 event.type = DRAW_EVENT;
87 event.user = data;
88
89 SDL_PushEvent(&event);
90 return draw_interval;
91}
92
93/**
94 * SDL_AddTimer() callback for the poll event.
95 *
96 * When this callback is called it will run the events in the SDL event queue.
97 *
98 * @returns The new timer interval, 0 to stop.
99 */
100static uint32_t timer_sdl_poll_events(uint32_t, void*)
101{
102 try
103 {
104 events::pump();
105 }
106 catch(video::quit&)
107 {
108 return 0;
109 }
110 return event_poll_interval;
111}
112#endif
113
114/***** handler class. *****/
115
116/**
117 * This singleton class handles all events.
118 *
119 * It's a new experimental class.
120 */
122{
123 friend bool gui2::is_in_dialog();
124
125public:
127
129
130 /** Inherited from events::sdl_handler. */
131 void handle_event(const SDL_Event& event) override;
132
133 /** Inherited from events::sdl_handler. */
134 void handle_window_event(const SDL_Event& event) override;
135
136 /**
137 * Connects a dispatcher.
138 *
139 * @param dispatcher The dispatcher to connect.
140 */
142
143 /**
144 * Disconnects a dispatcher.
145 *
146 * @param dispatcher The dispatcher to disconnect.
147 */
149
150 /**
151 * Returns all dispatchers in the Z order.
152 */
153 std::vector<dispatcher*>& get_dispatchers() { return dispatchers_; }
154
155 /** The dispatcher that captured the mouse focus. */
157
158private:
159 /**
160 * Reinitializes the state of all dispatchers.
161 *
162 * This is needed when the application gets activated, to make sure the
163 * state of mainly the mouse is set properly.
164 */
165 void activate();
166
167 /***** Handlers *****/
168
169 /** Fires a raw SDL event. */
170 void raw_event(const SDL_Event &event);
171
172 /**
173 * Fires a video resize event.
174 *
175 * @param new_size The new size of the window.
176 */
177 void video_resize(const point& new_size);
178
179 /** Fires an event indicating the window has entered full-screen. */
181
182 /** Fires an event indicating the window has left full-screen. */
184
185 /**
186 * Fires a generic mouse event.
187 *
188 * @param event The event to fire.
189 * @param position The position of the mouse.
190 */
191 void mouse(const ui_event event, const point& position);
192
193 /**
194 * Fires a mouse button up event.
195 *
196 * @param position The position of the mouse.
197 * @param button The SDL id of the button that caused the
198 * event.
199 */
200 void mouse_button_up(const point& position, const uint8_t button);
201
202 /**
203 * Fires a mouse button down event.
204 *
205 * @param position The position of the mouse.
206 * @param button The SDL id of the button that caused the
207 * event.
208 */
209 void mouse_button_down(const point& position, const uint8_t button);
210
211 /**
212 * Fires a mouse wheel event.
213 *
214 * @param position The position of the mouse.
215 * @param scrollx The amount of horizontal scrolling.
216 * @param scrolly The amount of vertical scrolling.
217 */
218 void mouse_wheel(const point& position, int scrollx, int scrolly);
219
220 /**
221 * Gets the dispatcher that wants to receive the keyboard input.
222 *
223 * @returns The dispatcher.
224 * @retval nullptr No dispatcher found.
225 */
227
228 /**
229 * Fires a touch-moved event.
230 *
231 * @param position The position touched.
232 * @param distance The distance moved.
233 */
234 void touch_motion(const point& position, const point& distance);
235
236 /**
237 * Fires a touch "finger down" event.
238 *
239 * @param position The position touched.
240 */
241 void touch_down(const point& position);
242
243 /**
244 * Fires a touch "finger up" event.
245 *
246 * @param position The position touched.
247 */
248 void touch_up(const point& position);
249
250 /**
251 * Fires a touch gesture event.
252 * @param center the center of gesture
253 * @param dTheta the amount that the fingers rotated during this motion
254 * @param dDist the amount that the fingers pinched during this motion
255 * @param numFingers the number of fingers used in the gesture
256 */
257 void touch_multi_gesture(const point& center, float dTheta, float dDist, uint8_t numFingers);
258
259 /**
260 * Handles a hat motion event.
261 *
262 * @param event The SDL joystick hat event triggered.
263 */
264 void hat_motion(const SDL_Event& event);
265
266 /**
267 * Handles a joystick button down event.
268 *
269 * @param event The SDL joystick button event triggered.
270 */
271 void button_down(const SDL_Event& event);
272
273 /**
274 * Fires a key down event.
275 *
276 * @param event The SDL keyboard event triggered.
277 */
278 void key_down(const SDL_Event& event);
279
280 /**
281 * Handles the pressing of a hotkey.
282 *
283 * @param key The hotkey item pressed.
284 *
285 * @returns True if there was a valid dispatcher with
286 * which to execute the hotkey callback, false
287 * otherwise.
288 */
289 bool hotkey_pressed(const hotkey::hotkey_ptr& key);
290
291 /**
292 * Fires a key down event.
293 *
294 * @param key The SDL key code of the key pressed.
295 * @param modifier The SDL key modifiers used.
296 * @param unicode The unicode value for the key pressed.
297 */
298 void key_down(const SDL_Keycode key,
299 const SDL_Keymod modifier,
300 const std::string& unicode);
301
302 /**
303 * Fires a text input event.
304 *
305 * @param unicode The unicode value for the text entered.
306 */
307 void text_input(const std::string& unicode);
308
309 /**
310 * Fires a text editing event.
311 *
312 * @param unicode The unicode value for the text being edited.
313 * @param start The start position for the text being edited.
314 * @param len The selection length for the text being edited.
315 */
316 void text_editing(const std::string& unicode, int32_t start, int32_t len);
317
318 /**
319 * Fires a keyboard event which has no parameters.
320 *
321 * This can happen for example when the mouse wheel is used.
322 *
323 * @param event The event to fire.
324 */
325 void keyboard(const ui_event event);
326
327 /**
328 * Fires a CLOSE_WINDOW event for the window with the given ID.
329 *
330 * @param window_id The ID of the window to close.
331 */
332 void close_window(const unsigned window_id);
333
334 /**
335 * The dispatchers.
336 *
337 * The order of the items in the list is also the z-order the front item
338 * being the one completely in the background and the back item the one
339 * completely in the foreground.
340 */
341 std::vector<dispatcher*> dispatchers_;
342
343 /**
344 * Needed to determine which dispatcher gets the keyboard events.
345 *
346 * NOTE the keyboard events aren't really wired in yet so doesn't do much.
347 */
350};
351
353 : events::sdl_handler(false)
354 , mouse_focus(nullptr)
355 , dispatchers_()
356 , keyboard_focus_(nullptr)
357{
358// The event context is created now we join it.
359#ifdef ENABLE
360 join();
361#endif
362}
363
365{
366#ifdef ENABLE
367 leave();
368#endif
369}
370
371void sdl_event_handler::handle_event(const SDL_Event& event)
372{
373 /** No dispatchers drop the event. */
374 if(dispatchers_.empty()) {
375 return;
376 }
377
378 uint8_t button = event.button.button;
379
380 switch(event.type) {
381 case SDL_EVENT_MOUSE_MOTION:
382#ifdef MOUSE_TOUCH_EMULATION
383 // There's no finger motion when it's not down.
384 if (event.motion.state != 0)
385#endif
386 {
387 mouse(SDL_MOUSE_MOTION, {static_cast<int>(event.motion.x), static_cast<int>(event.motion.y)});
388 }
389 break;
390
391 case SDL_EVENT_MOUSE_BUTTON_DOWN:
392 {
393 mouse_button_down({static_cast<int>(event.button.x), static_cast<int>(event.button.y)}, button);
394 }
395 break;
396
397 case SDL_EVENT_MOUSE_BUTTON_UP:
398 {
399 mouse_button_up({static_cast<int>(event.button.x), static_cast<int>(event.button.y)}, button);
400 }
401 break;
402
403 case SDL_EVENT_MOUSE_WHEEL:
404 mouse_wheel(get_mouse_position(), event.wheel.x, event.wheel.y);
405 break;
406
409 break;
410
412 // remove_popup();
413 break;
414
415 case TIMER_EVENT:
416 execute_timer(reinterpret_cast<std::size_t>(event.user.data1));
417 break;
418
420 close_window(event.user.code);
421 break;
422
423 case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
424 button_down(event);
425 break;
426
427 case SDL_EVENT_JOYSTICK_BUTTON_UP:
428 break;
429
430 case SDL_EVENT_JOYSTICK_AXIS_MOTION:
431 break;
432
433 case SDL_EVENT_JOYSTICK_HAT_MOTION:
434 hat_motion(event);
435 break;
436
437 case SDL_EVENT_KEY_DOWN:
438 key_down(event);
439 break;
440
441 // Always precedes SDL_EVENT_WINDOW_RESIZED, but the latter does not always
442 // happen; in particular when we change the game resolution via
443 // SDL_SetWindowSize() <https://github.com/wesnoth/wesnoth/issues/7436>
444 case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
446 break;
447
448 case SDL_EVENT_WINDOW_ENTER_FULLSCREEN:
450 break;
451
452 case SDL_EVENT_WINDOW_LEAVE_FULLSCREEN:
454 break;
455
456 case SDL_EVENT_WINDOW_MOUSE_ENTER:
457 case SDL_EVENT_WINDOW_FOCUS_GAINED:
458 activate();
459 break;
460
461 case SDL_EVENT_TEXT_INPUT:
462 key_down(event);
463 break;
464
465 case SDL_EVENT_TEXT_EDITING:
466 text_editing(event.edit.text, event.edit.start, event.edit.length);
467 break;
468
469 case SDL_EVENT_FINGER_MOTION:
470 {
473 point(event.tfinger.x * c.x, event.tfinger.y * c.y),
474 point(event.tfinger.dx * c.x, event.tfinger.dy * c.y)
475 );
476 }
477 break;
478
479 case SDL_EVENT_FINGER_UP:
480 {
482 touch_up(point(event.tfinger.x * c.x, event.tfinger.y * c.y));
483 }
484 break;
485
486 case SDL_EVENT_FINGER_DOWN:
487 {
489 touch_down(point(event.tfinger.x * c.x, event.tfinger.y * c.y));
490 }
491 break;
492
493 // Silently ignored events.
494 case SDL_EVENT_KEY_UP:
495 break;
496
497 default:
498#ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
499 WRN_GUI_E << "Unhandled event " << static_cast<uint32_t>(event.type)
500 << ".";
501#endif
502 break;
503 }
504
505 raw_event(event);
506}
507
508void sdl_event_handler::handle_window_event(const SDL_Event& event)
509{
510 handle_event(event);
511}
512
514{
516 DBG_GUI_E << "adding dispatcher " << static_cast<void*>(dispatcher);
517
518 if(dispatchers_.empty()) {
519 LOG_GUI_E << "creating new dispatcher event context";
520 event_context = std::make_unique<events::event_context>();
521 join();
522 }
523
524 dispatchers_.push_back(dispatcher);
525}
526
528{
529 /***** Validate pre conditions. *****/
530 auto itor = std::find(dispatchers_.begin(), dispatchers_.end(), disp);
531 assert(itor != dispatchers_.end());
532
533 DBG_GUI_E << "removing dispatcher " << static_cast<void*>(disp);
534
535 /***** Remove dispatcher. *****/
536 dispatchers_.erase(itor);
537
538 if(disp == mouse_focus) {
539 mouse_focus = nullptr;
540 }
541 if(disp == keyboard_focus_) {
542 keyboard_focus_ = nullptr;
543 }
544
545 // TODO: draw_manager - Why TF was this "activate"ing on "disconnect"? Seriously WTF?
546 //activate();
547
548 /***** Validate post conditions. *****/
549 assert(!utils::contains(dispatchers_, disp));
550
551 if(dispatchers_.empty()) {
552 LOG_GUI_E << "deleting unused dispatcher event context";
553 leave();
554 event_context = nullptr;
555 }
556}
557
559{
560 for(auto dispatcher : dispatchers_)
561 {
562 dispatcher->fire(SDL_ACTIVATE, dynamic_cast<widget&>(*dispatcher), nullptr);
563 }
564}
565
567{
568 for(auto dispatcher : dispatchers_)
569 {
570 dispatcher->fire(SDL_WINDOW_ENTER_FULLSCREEN, dynamic_cast<widget&>(*dispatcher), nullptr);
571 }
572}
573
575{
576 for(auto dispatcher : dispatchers_)
577 {
578 dispatcher->fire(SDL_WINDOW_LEAVE_FULLSCREEN, dynamic_cast<widget&>(*dispatcher), nullptr);
579 }
580}
581
583{
584 DBG_GUI_E << "Firing: " << SDL_VIDEO_RESIZE << ".";
585
586 for(auto dispatcher : dispatchers_)
587 {
588 dispatcher->fire(SDL_VIDEO_RESIZE, dynamic_cast<widget&>(*dispatcher), new_size);
589 }
590}
591
592void sdl_event_handler::raw_event(const SDL_Event& event) {
593 DBG_GUI_E << "Firing raw event";
594
595 for(auto dispatcher : dispatchers_)
596 {
597 dispatcher->fire(SDL_RAW_EVENT, dynamic_cast<widget&>(*dispatcher), event);
598 }
599}
600
601void sdl_event_handler::mouse(const ui_event event, const point& position)
602{
603 DBG_GUI_E << "Firing: " << event << ".";
604
605 if(mouse_focus) {
606 mouse_focus->fire(event, dynamic_cast<widget&>(*mouse_focus), position);
607 return;
608 }
609
612 dispatcher->fire(event, dynamic_cast<widget&>(*dispatcher), position);
613 break;
614 }
615
617 continue;
618 }
619
620 if(dispatcher->is_at(position)) {
621 dispatcher->fire(event, dynamic_cast<widget&>(*dispatcher), position);
622 break;
623 }
624 }
625}
626
627void sdl_event_handler::mouse_button_up(const point& position, const uint8_t button)
628{
629 switch(button) {
630 case SDL_BUTTON_LEFT:
631 mouse(SDL_LEFT_BUTTON_UP, position);
632 break;
633 case SDL_BUTTON_MIDDLE:
634 mouse(SDL_MIDDLE_BUTTON_UP, position);
635 break;
636 case SDL_BUTTON_RIGHT:
637 mouse(SDL_RIGHT_BUTTON_UP, position);
638 break;
639 case SDL_BUTTON_X1:
640 mouse(SDL_BACK_BUTTON_UP, position);
641 break;
642 case SDL_BUTTON_X2:
643 mouse(SDL_FORWARD_BUTTON_UP, position);
644 break;
645 default:
646#ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
647 WRN_GUI_E << "Unhandled 'mouse button up' event for button "
648 << static_cast<uint32_t>(button) << ".";
649#endif
650 break;
651 }
652}
653
654void sdl_event_handler::mouse_button_down(const point& position, const uint8_t button)
655{
656 switch(button) {
657 case SDL_BUTTON_LEFT:
658 mouse(SDL_LEFT_BUTTON_DOWN, position);
659 break;
660 case SDL_BUTTON_MIDDLE:
661 mouse(SDL_MIDDLE_BUTTON_DOWN, position);
662 break;
663 case SDL_BUTTON_RIGHT:
664 mouse(SDL_RIGHT_BUTTON_DOWN, position);
665 break;
666 case SDL_BUTTON_X1:
667 mouse(SDL_BACK_BUTTON_DOWN, position);
668 break;
669 case SDL_BUTTON_X2:
671 break;
672 default:
673#ifdef GUI2_SHOW_UNHANDLED_EVENT_WARNINGS
674 WRN_GUI_E << "Unhandled 'mouse button down' event for button "
675 << static_cast<uint32_t>(button) << ".";
676#endif
677 break;
678 }
679}
680
681void sdl_event_handler::mouse_wheel(const point& position, int x, int y)
682{
683 if(x > 0) {
684 mouse(SDL_WHEEL_RIGHT, position);
685 } else if(x < 0) {
686 mouse(SDL_WHEEL_LEFT, position);
687 }
688
689 if(y < 0) {
690 mouse(SDL_WHEEL_DOWN, position);
691 } else if(y > 0) {
692 mouse(SDL_WHEEL_UP, position);
693 }
694}
695
697{
698 if(keyboard_focus_) {
699 return keyboard_focus_;
700 }
701
704 return dispatcher;
705 }
706 }
707
708 return nullptr;
709}
710
711void sdl_event_handler::touch_motion(const point& position, const point& distance)
712{
714 dispatcher->fire(SDL_TOUCH_MOTION , dynamic_cast<widget&>(*dispatcher), position, distance);
715 }
716}
717
719{
721 dispatcher->fire(SDL_TOUCH_UP, dynamic_cast<widget&>(*dispatcher), position);
722 }
723}
724
726{
728 dispatcher->fire(SDL_TOUCH_DOWN, dynamic_cast<widget&>(*dispatcher), position);
729 }
730}
731
732void sdl_event_handler::touch_multi_gesture(const point& center, float dTheta, float dDist, uint8_t numFingers)
733{
735 dispatcher->fire(SDL_TOUCH_MULTI_GESTURE, dynamic_cast<widget&>(*dispatcher), center, dTheta, dDist, numFingers);
736 }
737}
738
739void sdl_event_handler::hat_motion(const SDL_Event& event)
740{
741 const hotkey::hotkey_ptr& hk = hotkey::get_hotkey(event);
742 bool done = false;
743 if(!hk->null()) {
744 done = hotkey_pressed(hk);
745 }
746 if(!done) {
747 // TODO fendrin think about handling hat motions that are not bound to a
748 // hotkey.
749 }
750}
751
752void sdl_event_handler::button_down(const SDL_Event& event)
753{
754 const hotkey::hotkey_ptr hk = hotkey::get_hotkey(event);
755 bool done = false;
756 if(!hk->null()) {
757 done = hotkey_pressed(hk);
758 }
759 if(!done) {
760 // TODO fendrin think about handling button down events that are not
761 // bound to a hotkey.
762 }
763}
764
765void sdl_event_handler::key_down(const SDL_Event& event)
766{
767 const hotkey::hotkey_ptr hk = hotkey::get_hotkey(event);
768 bool done = false;
769 if(!hk->null()) {
770 done = hotkey_pressed(hk);
771 }
772 if(!done) {
773 if(event.type == SDL_EVENT_TEXT_INPUT) {
774 text_input(event.text.text);
775 } else {
776 key_down(event.key.key, static_cast<SDL_Keymod>(event.key.mod), "");
777 }
778 }
779}
780
781void sdl_event_handler::text_input(const std::string& unicode)
782{
783 key_down(SDLK_UNKNOWN, static_cast<SDL_Keymod>(0), unicode);
784
787 dynamic_cast<widget&>(*dispatcher),
788 unicode, -1, -1);
789 }
790}
791
792void sdl_event_handler::text_editing(const std::string& unicode, int32_t start, int32_t len)
793{
796 dynamic_cast<widget&>(*dispatcher),
797 unicode, start, len);
798 }
799}
800
802{
804 return dispatcher->execute_hotkey(hotkey::get_hotkey_command(key->get_command()).command);
805 }
806
807 return false;
808}
809
810void sdl_event_handler::key_down(const SDL_Keycode key,
811 const SDL_Keymod modifier,
812 const std::string& unicode)
813{
814 DBG_GUI_E << "Firing: " << SDL_KEY_DOWN << ".";
815
818 dynamic_cast<widget&>(*dispatcher),
819 key,
820 modifier,
821 unicode);
822 }
823}
824
826{
827 DBG_GUI_E << "Firing: " << event << ".";
828
830 dispatcher->fire(event, dynamic_cast<widget&>(*dispatcher));
831 }
832}
833
834void sdl_event_handler::close_window(const unsigned window_id)
835{
836 DBG_GUI_E << "Firing " << CLOSE_WINDOW << ".";
837
839 if(window) {
841 }
842}
843
844/***** manager class. *****/
845
847{
848 handler_.reset(new sdl_event_handler());
849
850#ifdef MAIN_EVENT_HANDLER
851 draw_interval = 30;
852 SDL_AddTimer(draw_interval, timer_sdl_draw_event, nullptr);
853
854 event_poll_interval = 10;
855 SDL_AddTimer(event_poll_interval, timer_sdl_poll_events, nullptr);
856#endif
857}
858
860{
861 handler_.reset(nullptr);
862
863#ifdef MAIN_EVENT_HANDLER
864 draw_interval = 0;
865 event_poll_interval = 0;
866#endif
867}
868
869/***** free functions class. *****/
870
872{
873 assert(handler_);
874 assert(dispatcher);
875 handler_->connect(dispatcher);
876}
877
879{
880 assert(handler_);
881 assert(dispatcher);
882 handler_->disconnect(dispatcher);
883}
884
885std::vector<dispatcher*>& get_all_dispatchers()
886{
887 assert(handler_);
888 return handler_->get_dispatchers();
889}
890
892{
894
895 SDL_Event event{};
896 event.type = SDL_EVENT_MOUSE_MOTION;
897 event.motion.type = SDL_EVENT_MOUSE_MOTION;
898 event.motion.x = mouse.x;
899 event.motion.y = mouse.y;
900
901 SDL_PushEvent(&event);
902}
903
905{
906 assert(handler_);
907 assert(dispatcher);
908 handler_->mouse_focus = dispatcher;
909}
910
912{
913 assert(handler_);
914 assert(dispatcher);
915 if(handler_->mouse_focus == dispatcher) {
916 handler_->mouse_focus = nullptr;
917 }
918}
919
921{
922 assert(handler_);
923 assert(dispatcher);
925
926 handler_->keyboard_focus_ = dispatcher;
927}
928
929std::ostream& operator<<(std::ostream& stream, const ui_event event)
930{
931 switch(event) {
932 case DRAW:
933 stream << "draw";
934 break;
935 case CLOSE_WINDOW:
936 stream << "close window";
937 break;
938 case SDL_VIDEO_RESIZE:
939 stream << "SDL video resize";
940 break;
941 case SDL_MOUSE_MOTION:
942 stream << "SDL mouse motion";
943 break;
944 case MOUSE_ENTER:
945 stream << "mouse enter";
946 break;
947 case MOUSE_LEAVE:
948 stream << "mouse leave";
949 break;
950 case MOUSE_MOTION:
951 stream << "mouse motion";
952 break;
954 stream << "SDL left button down";
955 break;
957 stream << "SDL left button up";
958 break;
959 case LEFT_BUTTON_DOWN:
960 stream << "left button down";
961 break;
962 case LEFT_BUTTON_UP:
963 stream << "left button up";
964 break;
966 stream << "left button click";
967 break;
969 stream << "left button double click";
970 break;
972 stream << "SDL middle button down";
973 break;
975 stream << "SDL middle button up";
976 break;
978 stream << "middle button down";
979 break;
980 case MIDDLE_BUTTON_UP:
981 stream << "middle button up";
982 break;
984 stream << "middle button click";
985 break;
987 stream << "middle button double click";
988 break;
990 stream << "SDL right button down";
991 break;
993 stream << "SDL right button up";
994 break;
996 stream << "right button down";
997 break;
998 case RIGHT_BUTTON_UP:
999 stream << "right button up";
1000 break;
1001 case RIGHT_BUTTON_CLICK:
1002 stream << "right button click";
1003 break;
1005 stream << "right button double click";
1006 break;
1008 stream << "SDL forward/5 button down";
1009 break;
1011 stream << "SDL forward/5 button up";
1012 break;
1014 stream << "forward/5 button down";
1015 break;
1016 case FORWARD_BUTTON_UP:
1017 stream << "forward/5 button up";
1018 break;
1020 stream << "forward/5 button click";
1021 break;
1023 stream << "forward/5 button double click";
1024 break;
1026 stream << "SDL back/4 button down";
1027 break;
1028 case SDL_BACK_BUTTON_UP:
1029 stream << "SDL back/4 button up";
1030 break;
1031 case BACK_BUTTON_DOWN:
1032 stream << "back/4 button down";
1033 break;
1034 case BACK_BUTTON_UP:
1035 stream << "back/4 button up";
1036 break;
1037 case BACK_BUTTON_CLICK:
1038 stream << "back/4 button click";
1039 break;
1041 stream << "back/4 button double click";
1042 break;
1043 case SDL_WHEEL_LEFT:
1044 stream << "SDL wheel left";
1045 break;
1046 case SDL_WHEEL_RIGHT:
1047 stream << "SDL wheel right";
1048 break;
1049 case SDL_WHEEL_UP:
1050 stream << "SDL wheel up";
1051 break;
1052 case SDL_WHEEL_DOWN:
1053 stream << "SDL wheel down";
1054 break;
1055 case SDL_KEY_DOWN:
1056 stream << "SDL key down";
1057 break;
1058 case SDL_TEXT_INPUT:
1059 stream << "SDL text input";
1060 break;
1061 case SDL_TEXT_EDITING:
1062 stream << "SDL text editing";
1063 break;
1064
1065 case NOTIFY_REMOVAL:
1066 stream << "notify removal";
1067 break;
1068 case NOTIFY_MODIFIED:
1069 stream << "notify modified";
1070 break;
1072 stream << "receive keyboard focus";
1073 break;
1075 stream << "lose keyboard focus";
1076 break;
1077 case SHOW_TOOLTIP:
1078 stream << "show tooltip";
1079 break;
1081 stream << "notify remove tooltip";
1082 break;
1083 case SDL_ACTIVATE:
1084 stream << "SDL activate";
1085 break;
1087 stream << "SDL window enters fullscreen";
1088 break;
1090 stream << "SDL window leaves fullscreen";
1091 break;
1093 stream << "message show tooltip";
1094 break;
1095 case SHOW_HELPTIP:
1096 stream << "show helptip";
1097 break;
1099 stream << "message show helptip";
1100 break;
1101 case REQUEST_PLACEMENT:
1102 stream << "request placement";
1103 break;
1104 case SDL_TOUCH_MOTION:
1105 stream << "SDL touch motion";
1106 break;
1107 case SDL_TOUCH_UP:
1108 stream << "SDL touch up";
1109 break;
1110 case SDL_TOUCH_DOWN:
1111 stream << "SDL touch down";
1112 break;
1114 stream << "SDL multi-touch gesture";
1115 break;
1116 case SDL_RAW_EVENT:
1117 stream << "SDL raw event";
1118 break;
1119 }
1120
1121 return stream;
1122}
1123
1124} // namespace event
1125
1127{
1128 return !event::get_all_dispatchers().empty();
1129}
1130
1131} // namespace gui2
virtual void join()
Definition events.cpp:305
virtual void leave()
Definition events.cpp:350
Simple push button.
Definition button.hpp:36
button(const implementation::builder_button &builder)
Definition button.cpp:44
Base class for event handling.
bool fire(const ui_event event, widget &target)
Fires an event which has no extra parameters.
virtual bool is_at(const point &coordinate) const =0
Determines whether the location is inside an active widget.
bool get_want_keyboard_input() const
bool execute_hotkey(const hotkey::HOTKEY_COMMAND id)
Executes a hotkey.
mouse_behavior get_mouse_behavior() const
This singleton class handles all events.
Definition handler.cpp:122
void touch_down(const point &position)
Fires a touch "finger down" event.
Definition handler.cpp:725
void keyboard(const ui_event event)
Fires a keyboard event which has no parameters.
Definition handler.cpp:825
void activate()
Reinitializes the state of all dispatchers.
Definition handler.cpp:558
std::vector< dispatcher * > & get_dispatchers()
Returns all dispatchers in the Z order.
Definition handler.cpp:153
void disconnect(dispatcher *dispatcher)
Disconnects a dispatcher.
Definition handler.cpp:527
void mouse_button_up(const point &position, const uint8_t button)
Fires a mouse button up event.
Definition handler.cpp:627
void close_window(const unsigned window_id)
Fires a CLOSE_WINDOW event for the window with the given ID.
Definition handler.cpp:834
void handle_window_event(const SDL_Event &event) override
Inherited from events::sdl_handler.
Definition handler.cpp:508
void video_resize(const point &new_size)
Fires a video resize event.
Definition handler.cpp:582
void text_editing(const std::string &unicode, int32_t start, int32_t len)
Fires a text editing event.
Definition handler.cpp:792
void touch_up(const point &position)
Fires a touch "finger up" event.
Definition handler.cpp:718
dispatcher * keyboard_dispatcher()
Gets the dispatcher that wants to receive the keyboard input.
Definition handler.cpp:696
friend void capture_keyboard(dispatcher *dispatcher)
Captures the keyboard.
Definition handler.cpp:920
void text_input(const std::string &unicode)
Fires a text input event.
Definition handler.cpp:781
void touch_motion(const point &position, const point &distance)
Fires a touch-moved event.
Definition handler.cpp:711
bool hotkey_pressed(const hotkey::hotkey_ptr &key)
Handles the pressing of a hotkey.
Definition handler.cpp:801
void mouse_button_down(const point &position, const uint8_t button)
Fires a mouse button down event.
Definition handler.cpp:654
void hat_motion(const SDL_Event &event)
Handles a hat motion event.
Definition handler.cpp:739
dispatcher * keyboard_focus_
Needed to determine which dispatcher gets the keyboard events.
Definition handler.cpp:348
void window_leave_fullscreen()
Fires an event indicating the window has left full-screen.
Definition handler.cpp:574
void connect(dispatcher *dispatcher)
Connects a dispatcher.
Definition handler.cpp:513
void key_down(const SDL_Event &event)
Fires a key down event.
Definition handler.cpp:765
void mouse(const ui_event event, const point &position)
Fires a generic mouse event.
Definition handler.cpp:601
void touch_multi_gesture(const point &center, float dTheta, float dDist, uint8_t numFingers)
Fires a touch gesture event.
Definition handler.cpp:732
void mouse_wheel(const point &position, int scrollx, int scrolly)
Fires a mouse wheel event.
Definition handler.cpp:681
std::vector< dispatcher * > dispatchers_
The dispatchers.
Definition handler.cpp:341
void window_enter_fullscreen()
Fires an event indicating the window has entered full-screen.
Definition handler.cpp:566
void button_down(const SDL_Event &event)
Handles a joystick button down event.
Definition handler.cpp:752
dispatcher * mouse_focus
The dispatcher that captured the mouse focus.
Definition handler.cpp:156
void raw_event(const SDL_Event &event)
Fires a raw SDL event.
Definition handler.cpp:592
void handle_event(const SDL_Event &event) override
Inherited from events::sdl_handler.
Definition handler.cpp:371
Base class for all widgets.
Definition widget.hpp:55
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition window.hpp:59
static window * window_instance(const unsigned handle)
Returns the instance of a window.
Definition window.cpp:407
Type that can be thrown as an exception to quit to desktop.
Definition video.hpp:328
#define DRAW_EVENT
Definition events.hpp:31
#define CLOSE_WINDOW_EVENT
Definition events.hpp:32
#define SHOW_HELPTIP_EVENT
Definition events.hpp:33
#define TIMER_EVENT
Definition events.hpp:29
#define HOVER_REMOVE_POPUP_EVENT
Definition events.hpp:30
Define the common log macros for the gui toolkit.
#define WRN_GUI_E
Definition log.hpp:37
#define LOG_GUI_E
Definition log.hpp:36
#define DBG_GUI_E
Definition log.hpp:35
This file contains the window object, this object is a top level container which has the event manage...
Handling of system events.
void pump()
Process all events currently in the queue.
Definition events.cpp:480
ui_event
The event sent to the dispatcher.
Definition handler.hpp:115
@ MIDDLE_BUTTON_DOWN
Definition handler.hpp:124
@ SDL_FORWARD_BUTTON_DOWN
Definition handler.hpp:156
@ NOTIFY_REMOVE_TOOLTIP
Definition handler.hpp:176
@ FORWARD_BUTTON_DOUBLE_CLICK
Definition handler.hpp:141
@ FORWARD_BUTTON_CLICK
Definition handler.hpp:140
@ SDL_RIGHT_BUTTON_DOWN
Definition handler.hpp:150
@ MIDDLE_BUTTON_DOUBLE_CLICK
Definition handler.hpp:127
@ FORWARD_BUTTON_DOWN
Definition handler.hpp:138
@ BACK_BUTTON_CLICK
Definition handler.hpp:136
@ MIDDLE_BUTTON_CLICK
Definition handler.hpp:126
@ SDL_LEFT_BUTTON_DOWN
Definition handler.hpp:146
@ SDL_TEXT_INPUT
An SDL text input (commit) event.
Definition handler.hpp:170
@ RIGHT_BUTTON_CLICK
Definition handler.hpp:130
@ LOSE_KEYBOARD_FOCUS
Definition handler.hpp:178
@ SDL_TEXT_EDITING
An SDL text editing (IME) event.
Definition handler.hpp:171
@ LEFT_BUTTON_DOUBLE_CLICK
Definition handler.hpp:123
@ RIGHT_BUTTON_DOWN
Definition handler.hpp:128
@ RECEIVE_KEYBOARD_FOCUS
Definition handler.hpp:177
@ BACK_BUTTON_DOUBLE_CLICK
Definition handler.hpp:137
@ LEFT_BUTTON_CLICK
Definition handler.hpp:122
@ SDL_LEFT_BUTTON_UP
Definition handler.hpp:147
@ SDL_TOUCH_MULTI_GESTURE
Definition handler.hpp:187
@ REQUEST_PLACEMENT
Definition handler.hpp:182
@ SDL_MIDDLE_BUTTON_UP
Definition handler.hpp:149
@ SDL_BACK_BUTTON_DOWN
Definition handler.hpp:154
@ SDL_BACK_BUTTON_UP
Definition handler.hpp:155
@ FORWARD_BUTTON_UP
Definition handler.hpp:139
@ SDL_WINDOW_ENTER_FULLSCREEN
Definition handler.hpp:179
@ SDL_MIDDLE_BUTTON_DOWN
Definition handler.hpp:148
@ SDL_RIGHT_BUTTON_UP
Definition handler.hpp:151
@ RIGHT_BUTTON_DOUBLE_CLICK
Definition handler.hpp:131
@ MESSAGE_SHOW_TOOLTIP
Definition handler.hpp:183
@ MESSAGE_SHOW_HELPTIP
Definition handler.hpp:184
@ SDL_FORWARD_BUTTON_UP
Definition handler.hpp:157
@ SDL_WINDOW_LEAVE_FULLSCREEN
Definition handler.hpp:180
void capture_mouse(dispatcher *dispatcher)
Captures the mouse.
Definition handler.cpp:904
void release_mouse(dispatcher *dispatcher)
Releases a captured mouse.
Definition handler.cpp:911
void disconnect_dispatcher(dispatcher *dispatcher)
Disconnects a dispatcher to the event handler.
Definition handler.cpp:878
static std::unique_ptr< class sdl_event_handler > handler_
Definition handler.cpp:63
void capture_keyboard(dispatcher *dispatcher)
Captures the keyboard.
Definition handler.cpp:920
@ keyboard
Callbacks with the keyboard values (these haven't been determined yet).
@ mouse
Callbacks with a coordinate as extra parameter.
void connect_dispatcher(dispatcher *dispatcher)
Connects a dispatcher to the event handler.
Definition handler.cpp:871
std::vector< dispatcher * > & get_all_dispatchers()
Gets all event dispatchers in the Z order.
Definition handler.cpp:885
std::ostream & operator<<(std::ostream &stream, const ui_event event)
Definition handler.cpp:929
static std::unique_ptr< events::event_context > event_context
Definition handler.cpp:64
void init_mouse_location()
Initializes the location of the mouse.
Definition handler.cpp:891
Generic file dialog.
bool is_in_dialog()
Is a dialog open?
Definition handler.cpp:1126
point get_mouse_position()
Returns the current mouse position.
Definition helper.cpp:167
bool execute_timer(const std::size_t id)
Executes a timer.
Definition timer.cpp:197
std::shared_ptr< class hotkey_base > hotkey_ptr
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...
const hotkey_command & get_hotkey_command(std::string_view command)
Returns the hotkey_command with the given id.
constexpr auto reverse
Definition ranges.hpp:44
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition general.hpp:88
point game_canvas_size()
The size of the game canvas, in drawing coordinates / game pixels.
Definition video.cpp:432
std::string_view data
Definition picture.cpp:188
HOTKEY_COMMAND command
The command associated with this hotkey.
Holds a 2D point.
Definition point.hpp:25
Contains the gui2 timer routines.
#define c