#ifndef MOUSEAPI_H #define MOUSEAPI_H #include "OrxonoxPrereqs.h" #include "util/OgreForwardRefs.h" #include "graphics/Camera.h" #include #include #include #include #include #include #include #include #include "CameraManager.h" #include #include "core/GUIManager.h" #include "core/input/KeyBinderManager.h" #include "tools/interfaces/Tickable.h" /* This class implements a basic mouse-api * supported are mouse-clicks (left, right, mousewheel, ...) and scrolling * * mouse-clicks always are asscociated with an ingame element that has a position and a sphere with a certain radius around it * if the cursor is inside this sphere and a button is pressed, a user-defined function will be called * * scrolling can either be global (independent of where the cursor is) or local (same as a mouse-click) * in both cases a user-defined function will be called * * in short the class works by storing every element that can be clicked / scrolled on in a list * everytime a button is clicked or the mousewheel is turned, the list gets traversed and every element checked wheter it is clicked / scrolled on * checking happens by casting a ray from the camera through the mouse-cursor and testing wheter it intersects the sphere of the element */ namespace orxonox { typedef uint ClickableObjectID; typedef uint ScrollableElementID; class MouseAPI : public InputHandler, public Singleton,public Tickable { friend class Singleton; private: // Elements that can be clicked on are stored as clickableElement struct clickableElement { ClickableObjectID id; Vector3 position; float radius; std::list buttons; std::function onClickedFunction; clickableElement(ClickableObjectID id,const Vector3& position,float radius,const std::list& buttons,std::function onClickedFunction):id(id),position(position), radius(radius), buttons(buttons), onClickedFunction(onClickedFunction){} }; /* Elements that can be "scrolled on" are stored as scrollElement * there are 2 diffrent types, hence the overloaded constructor: * 1) the function is called whenever one scrolls, independet from position of object and cursor * 2) the function is only called when the cursor is over the object (same as with a clickElement) */ struct scrollElement { ScrollableElementID id; bool considerPosition; Vector3 position; float radius; std::function onScrolledFunction; // constructor for scrollElement type 1 scrollElement(ScrollableElementID id,std::function onScrolledFunction):id(id),considerPosition(false), onScrolledFunction(onScrolledFunction){} // constructor fro scrollElement type 2 scrollElement(ScrollableElementID id,const Vector3& position, float radius, std::function onScrolledFunction):id(id),considerPosition(true), position(position), radius(radius), onScrolledFunction(onScrolledFunction){} }; // pointer to our class (required by singleton) static MouseAPI* singletonPtr_s; // lists with all our Elements that can be clicked / scrolled on std::list clickEvents; std::list scrollEvents; // pointer to the game-camera Ogre::Camera *cam ; //IntVector2 mousePos; // pointer to our input-state InputState* state; // true => MouseAPI has been activated, false => MouseAPI has not been activated bool active = false; public: MouseAPI(); ~MouseAPI(); virtual void tick(float dt) override; /* everytime a mousebutton is pressed, this function is called and checks if the cursor is over an element that can be clicked on * if yes, the function associated with this element will be called with the corresponding button as argument */ virtual void buttonPressed (MouseButtonCode::ByEnum button) override; // not used virtual void buttonReleased(MouseButtonCode::ByEnum button) override{} // not used virtual void buttonHeld (MouseButtonCode::ByEnum button) override{} // not used virtual void mouseMoved (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) override; /* 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 * if yes, the function associated with this element will be called * if there is an element without position-requirement and an element the cursor is over, both their functions will be called */ virtual void mouseScrolled (int abs, int rel) override; /* add a clickableElement to the list * see mouseapiexample for an example-implementation * Arguments: * position: the point that needs to be clicked * 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) * buttons: the function will only be called, if one of these buttons is pressed * onClickedFunction: the function that will be called * */ ClickableObjectID addClickableObject(const Vector3& position,float radius,const std::list& buttons,std::function onClickedFunction); /* * */ ScrollableElementID addScrollElement(const Vector3& position,float radius,std::function onScrolledFunction); /* * */ ScrollableElementID addScrollElement(std::function onScrolledFunction); //true: success; false: element not found bool changePositionOfClickableObject(ClickableObjectID id,const Vector3& position); bool changePositionOfScrollableElement(ScrollableElementID id,const Vector3& position); bool changeRadiusOfClickableObject(ClickableObjectID id,float radius); bool changeRadiusOfScrollableElement(ScrollableElementID id,float radius); bool deleteClickableObject(ClickableObjectID id); bool deleteScrollableElement(ScrollableElementID id); float getRadiusClick(ClickableObjectID id); float getRadiusScroll(ScrollableElementID id); Vector2 getMousePosition(); void activate(); static bool isActive(){return singletonPtr_s != nullptr && getInstance().active;} void deactivate(); }; } #endif // MOUSEAPI_H