Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/MouseAPI_FS19/src/modules/MouseAPI/mouseapi.h @ 12362

Last change on this file since 12362 was 12362, checked in by mkarpf, 5 years ago

cleanup (minor)

File size: 9.8 KB
Line 
1#ifndef MOUSEAPI_H
2#define MOUSEAPI_H
3
4#include "OrxonoxPrereqs.h"
5#include "util/OgreForwardRefs.h"
6#include "graphics/Camera.h"
7#include <util/Math.h>
8#include <list>
9#include <core/input/InputHandler.h>
10#include <graphics/Camera.h>
11#include <core/GraphicsManager.h>
12#include <core/input/InputState.h>
13#include <OgreCamera.h>
14#include <OgreViewport.h>
15#include "CameraManager.h"
16#include <functional>
17#include "core/GUIManager.h"
18#include "core/input/KeyBinderManager.h"
19#include "tools/interfaces/Tickable.h"
20#include "core/singleton/ScopedSingletonIncludes.h"
21
22/* this class implements a basic mouse-api
23 * supported are mouse-clicks (left, right, mousewheel, ...) and scrolling
24 *
25 * mouse-clicks always are asscociated with an ingame element that has a position and a sphere with a certain radius around it
26 * if the cursor is inside this sphere and a button is pressed, a user-defined function will be called
27 *
28 * scrolling can either be global (independent of where the cursor is) or local (same as a mouse-click)
29 * in both cases a user-defined function will be called
30 *
31 * in short the class works by storing every element that can be clicked / scrolled on in a list
32 * everytime a button is clicked or the mousewheel is turned, the list gets traversed and every element checked if it is clicked / scrolled on
33 * checking happens by casting a ray from the camera through the mouse-cursor and testing if it intersects the sphere of the element
34 *
35 * to make it work, one has to add mouseapi in LINK_LIBRARIES in the file CMakeLists.txt of the level
36 * see CMakeLists.txt in MouseAPIExample
37 */
38
39namespace orxonox
40{
41typedef uint ClickableElementID;
42typedef uint ScrollableElementID;
43
44class MouseAPI : public InputHandler, public Singleton<MouseAPI>,public Tickable
45{
46friend class Singleton<MouseAPI>;
47
48private:
49
50    // Elements that can be clicked on are stored as clickableElement
51    struct clickableElement
52    {
53        ClickableElementID id;
54        Vector3 position;
55        float radius;
56        std::list<MouseButtonCode::ByEnum> buttons;
57        std::function<void(MouseButtonCode::ByEnum button)> onClickedFunction;
58        clickableElement(ClickableElementID id,const Vector3& position,float radius,const std::list<MouseButtonCode::ByEnum>& buttons,std::function<void(MouseButtonCode::ByEnum button)> onClickedFunction):id(id),position(position),
59            radius(radius), buttons(buttons), onClickedFunction(onClickedFunction){}
60    };
61
62    /* Elements that can be "scrolled on" are stored as scrollElement
63     * there are 2 diffrent types, hence the overloaded constructor:
64     *      1) the function is called whenever one scrolls, independet from position of element and cursor
65     *      2) the function is only called when the cursor is placed over the element (identical to the clickableElement)
66     */
67    struct scrollElement
68    {
69        ScrollableElementID id;
70        bool considerPosition;
71        Vector3 position;
72        float radius;
73        std::function<void(int abs,int rel,const IntVector2& mousePos)> onScrolledFunction;
74        // constructor for scrollElement type 1
75        scrollElement(ScrollableElementID id,std::function<void(int abs,int rel,const IntVector2& mousePos)> onScrolledFunction):id(id),considerPosition(false),
76            onScrolledFunction(onScrolledFunction){}
77        // constructor fro scrollElement type 2
78        scrollElement(ScrollableElementID id,const Vector3& position, float radius, std::function<void(int abs,int rel,const IntVector2& mousePos)> onScrolledFunction):id(id),considerPosition(true),
79            position(position), radius(radius), onScrolledFunction(onScrolledFunction){}
80    };
81
82    // pointer to our class (required by singleton)
83    static MouseAPI* singletonPtr_s;
84
85    // lists with all our Elements that can be clicked / scrolled on
86    std::list<clickableElement> clickEvents;
87    std::list<scrollElement> scrollEvents;
88
89    // pointer to the game-camera
90    Ogre::Camera *cam ;
91
92    // pointer to our input-state
93    InputState* state;
94
95    // true => MouseAPI has been activated, false => MouseAPI has not been activated
96    bool active = false;
97
98public:
99
100    MouseAPI();
101    ~MouseAPI();
102
103    virtual void tick(float dt) override;
104
105    /* everytime a mousebutton is pressed, this function is called and checks if the cursor is over an element that can be clicked on
106     * if yes, the function associated with this element will be called with the corresponding button as argument
107     */
108    virtual void buttonPressed (MouseButtonCode::ByEnum button) override;
109
110    // not used
111    virtual void buttonReleased(MouseButtonCode::ByEnum button)  override{}
112
113    // not used
114    virtual void buttonHeld    (MouseButtonCode::ByEnum button) override{}
115
116    // not used
117    virtual void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) override;
118
119    /* everytime someone scrolls, this function is called and checks for all scrollElements, wheter a position is required and wheter the curser is over said position
120     * if yes, the function associated with this element will be called
121     * if there is an element without position-requirement and an element the cursor is over, both their functions will be called
122     */
123    virtual void mouseScrolled (int abs, int rel) override;
124
125    /* add a clickableElement to the list
126     * see mouseapiexample for an example-implementation
127     * Arguments:
128     *      position: the point that needs to be clicked
129     *      radius: radius of the sphere around the position; if the cursor is inside this radius, the function will be executed (because clicking on a single point is pretty hard)
130     *      buttons: the function will only be called, if one of these buttons is pressed
131     *      onClickedFunction: the function that will be called
132     */
133    ClickableElementID addClickableElement(const Vector3& position,float radius,const std::list<MouseButtonCode::ByEnum>& buttons,std::function<void(MouseButtonCode::ByEnum button)>  onClickedFunction);
134
135    /* add a scrollElement to the list
136     * see mouseapiexample for an example-implementation
137     * Arguments:
138     *      position: the point the cursor needs to be over
139     *      radius: radius of the sphere around the position; if the cursor is inside this radius, the function will be executed
140     *      onScrolledFunction: the function that will be called
141     */
142    ScrollableElementID addScrollElement(const Vector3& position,float radius,std::function<void(int abs,int rel,const IntVector2& mousePos)> onScrolledFunction);
143
144    /* add a scrollElement to the list
145     * Arguments:
146     *      onScrolledFunction: the function that will be called, no matter where the cursor is
147     */
148    ScrollableElementID addScrollElement(std::function<void(int abs,int rel,const IntVector2& mousePos)> onScrolledFunction);
149
150    /* change the position of a clickableElement
151     * Arguments:
152     *      id: the ClickableElementID of the element
153     *      position: the new position of the element
154     * Return:
155     *      true if successfull
156     *      false if not successfull
157     */
158    bool changePositionOfClickableElement(ClickableElementID id,const Vector3& position);
159
160    /* change the position of a scrollElement
161     * Arguments:
162     *      id: the ScrollableElementID of the element
163     *      position: the new position of the element
164     * Return:
165     *      true if successfull
166     *      false if not successfull
167     */
168    bool changePositionOfScrollableElement(ScrollableElementID id,const Vector3& position);
169
170    /* change the radius of a clickableElement
171     * Arguments:
172     *      id: the ClickableElementID of the element
173     *      radius: the new radius of the element
174     * Return:
175     *      true if successfull
176     *      false if not successfull
177     */
178    bool changeRadiusOfClickableElement(ClickableElementID id,float radius);
179
180    /* change the radius of a scrollElement
181     * Arguments:
182     *      id: the ScrollableElementID of the element
183     *      radius: the new radius of the element
184     * Return:
185     *      true if successfull
186     *      false if not successfull
187     */
188    bool changeRadiusOfScrollableElement(ScrollableElementID id,float radius);
189
190    /* remove a clickableElement
191     * Arguments:
192     *      id: the ClickableElementID of the element
193     * Return:
194     *      true if successfull
195     *      false if not successfull
196     */
197    bool deleteClickableElement(ClickableElementID id);
198
199    /* remove a scrollElement
200     * Arguments:
201     *      id: the ScrollableElementID of the element
202     * Return:
203     *      true if successfull
204     *      false if not successfull
205     */
206    bool deleteScrollableElement(ScrollableElementID id);
207
208    /* get the current radius of a clickableElement
209     * Arguments:
210     *      id: the ClickableElementID of the element
211     */
212    float getRadiusClick(ClickableElementID id);
213
214    /* get the current radius of a scrollElement
215     * Arguments:
216     *      id: the ScrollableElementID of the element
217     */
218    float getRadiusScroll(ScrollableElementID id);
219
220    /* get the current relative Position of the cursor
221     * returns a value between 0 and 1 for both x and y component
222     * (0,0) top left corner, (1,1) bottom right corner
223     */
224    Vector2 getMousePosition();
225
226    /* activate the MouseAPI
227     * has to be called after the level has been created (i.e. inside the xml-port
228     * can be called multiple times, since the function checks the status of MouseAPI and does nothing if it already is active
229     */
230    void activate();
231
232    // returns true if MouseAPI is active, false otherwise
233    static bool isActive(){return singletonPtr_s != nullptr && getInstance().active;}
234
235    /* deactivate the MouseAPI
236     * has to be called, when the level gets closed (i.e. inside the level-destructor)
237     * the function does nothing if MouseAPI is not active
238     */
239    void deactivate();
240};
241}
242#endif // MOUSEAPI_H
Note: See TracBrowser for help on using the repository browser.