1 //  SuperTuxKart - a fun racing game with go-kart
2 //  Copyright (C) 2010-2015 Marianne Gagnon
3 //
4 //  This program is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU General Public License
6 //  as published by the Free Software Foundation; either version 3
7 //  of the License, or (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 
18 #ifndef HEADER_EVENT_HANDLER_HPP
19 #define HEADER_EVENT_HANDLER_HPP
20 
21 #include <vector2d.h>
22 #include <IEventReceiver.h>
23 #include "input/input.hpp"
24 #include "utils/leak_check.hpp"
25 
26 /**
27  * \ingroup guiengine
28  */
29 namespace GUIEngine
30 {
31 
32     /**
33       * \ingroup guiengine
34       */
35     enum EventPropagation
36     {
37         EVENT_BLOCK,
38         EVENT_BLOCK_BUT_HANDLED,
39         EVENT_LET
40     };
41 
42     enum NavigationDirection
43     {
44         NAV_LEFT,
45         NAV_RIGHT,
46         NAV_UP,
47         NAV_DOWN
48     };
49 
50     class Widget;
51 
52     /**
53      * \brief Class to handle irrLicht events (GUI and input as well)
54      *
55      * input events will be redirected to the input module in game mode.
56      * In menu mode, input is mapped to game actions with the help of the input
57      * module, then calls are made to move focus / trigger an event / etc.
58      *
59      * This is really only the irrLicht events bit, not to be confused with my own simple events dispatched
60      * mainly through AbstractStateManager, and also to widgets (this class is some kind of bridge between
61      * the base irrLicht GUI engine and the STK layer on top of it)
62      *
63      * \ingroup guiengine
64      */
65     class EventHandler : public irr::IEventReceiver
66     {
67         /** This variable is used to ignore events during the initial load screen, so that
68             a player cannot trigger an action by clicking on the window during loading screen
69             for example */
70         bool m_accept_events;
71 
72         EventPropagation onGUIEvent(const irr::SEvent& event);
73         EventPropagation onWidgetActivated(Widget* w, const int playerID, Input::InputType type);
74         void sendNavigationEvent(const NavigationDirection nav, const int playerID);
75         void navigate(const NavigationDirection nav, const int playerID);
76 
77         /** \brief          send an event to the GUI module user's event callback
78           * \param widget   the widget that triggerred this event
79           * \param name     the name/ID (PROP_ID) of the widget that triggerred this event
80           * \param playerID ID of the player that triggerred this event
81           */
82         void sendEventToUser(Widget* widget, std::string& name, const int playerID);
83 
84         /** Last position of the mouse cursor */
85         irr::core::vector2di     m_mouse_pos;
86 
87     public:
88 
89         LEAK_CHECK()
90 
91         EventHandler();
92         ~EventHandler();
93 
94         /**
95          * All irrLicht events will go through this (input as well GUI; input events are
96          * immediately delegated to the input module, GUI events are processed here)
97          */
98         bool OnEvent (const irr::SEvent &event);
99 
100         /**
101          * When the input module is done processing an input and mapped it to an action,
102          * and this action needs to be applied to the GUI (e.g. fire pressed, left
103          * pressed, etc.) this method is called back by the input module.
104          */
105         void processGUIAction(const PlayerAction action, int deviceID, const unsigned int value,
106                               Input::InputType type, const int playerID);
107 
108         /** Get the mouse position */
getMousePos() const109         const irr::core::vector2di& getMousePos() const { return m_mouse_pos; }
110 
111         /** singleton access */
112         static EventHandler* get();
113         static void deallocate();
114 
setAcceptEvents(bool value)115         void setAcceptEvents(bool value) { m_accept_events = value; }
116         int findIDClosestWidget(const NavigationDirection nav, const int playerID,
117                                 Widget* w, bool ignore_disabled, int recursion_counter=1);
118     };
119 
120 }
121 
122 #endif
123