From d552a658c0d88955e7a3a1815e9550cfbea3d4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 20 Dec 2012 15:38:11 +0100 Subject: [PATCH] Platform: reworked GlutApplication events to mimic SDL and NaClApplication. --- src/Platform/AbstractXApplication.h | 5 +- src/Platform/GlutApplication.cpp | 20 ++- src/Platform/GlutApplication.h | 235 +++++++++++++++++++--------- src/Platform/NaClApplication.h | 3 +- src/Platform/Sdl2Application.h | 35 ++--- 5 files changed, 196 insertions(+), 102 deletions(-) diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 4b6d4d836..38121ce75 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -300,8 +300,9 @@ class AbstractXApplication { @brief Entry point for X11-based applications @param className Class name -Can be used as equivalent to the following code to achieve better portability, -see @ref portability-applications for more information. +Can be used with AbstractXApplication subclasses as equivalent to the +following code to achieve better portability, see @ref portability-applications +for more information. @code int main(int argc, char** argv) { className app(argc, argv); diff --git a/src/Platform/GlutApplication.cpp b/src/Platform/GlutApplication.cpp index 85eab4416..6a8b6dabc 100644 --- a/src/Platform/GlutApplication.cpp +++ b/src/Platform/GlutApplication.cpp @@ -35,7 +35,7 @@ GlutApplication::GlutApplication(int& argc, char** argv, const std::string& titl glutReshapeFunc(staticViewportEvent); glutSpecialFunc(staticKeyEvent); glutMouseFunc(staticMouseEvent); - glutMotionFunc(staticMouseMotionEvent); + glutMotionFunc(staticMouseMoveEvent); glutDisplayFunc(staticDrawEvent); ExtensionWrangler::initialize(); @@ -47,4 +47,22 @@ GlutApplication::~GlutApplication() { delete c; } +void GlutApplication::staticKeyEvent(int key, int x, int y){ + KeyEvent e(static_cast(key), {x, y}); + instance->keyPressEvent(e); +} + +void GlutApplication::staticMouseEvent(int button, int state, int x, int y) { + MouseEvent e(static_cast(button), {x, y}); + if(state == GLUT_DOWN) + instance->mousePressEvent(e); + else + instance->mouseReleaseEvent(e); +} + +void GlutApplication::staticMouseMoveEvent(int x, int y) { + MouseMoveEvent e({x, y}); + instance->mouseMoveEvent(e); +} + }} diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 6b7fafee0..8345a4f13 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -53,6 +53,11 @@ MAGNUM_GLUTAPPLICATION_MAIN(MyApplication) */ class GlutApplication { public: + class InputEvent; + class KeyEvent; + class MouseEvent; + class MouseMoveEvent; + /** * @brief Constructor * @param argc Count of arguments of `main()` function @@ -79,9 +84,9 @@ class GlutApplication { /** * @brief Viewport event * - * Called when viewport size changes. You should pass the new size to - * Framebuffer::setViewport() (and SceneGraph::AbstractCamera::setViewport(), - * if using scene graph). + * Called when window size changes. You should pass the new size to + * DefaultFramebuffer::setViewport() and possibly elsewhere (cameras, + * other framebuffers...). */ virtual void viewportEvent(const Vector2i& size) = 0; @@ -119,63 +124,18 @@ class GlutApplication { /** @{ @name Keyboard handling */ - public: - /** - * @brief Key - * - * @see keyPressEvent() - */ - enum class Key: int { - Up = GLUT_KEY_UP, /**< Up arrow */ - Down = GLUT_KEY_DOWN, /**< Down arrow */ - Left = GLUT_KEY_LEFT, /**< Left arrow */ - Right = GLUT_KEY_RIGHT, /**< Right arrow */ - F1 = GLUT_KEY_F1, /**< F1 */ - F2 = GLUT_KEY_F2, /**< F2 */ - F3 = GLUT_KEY_F3, /**< F3 */ - F4 = GLUT_KEY_F4, /**< F4 */ - F5 = GLUT_KEY_F5, /**< F5 */ - F6 = GLUT_KEY_F6, /**< F6 */ - F7 = GLUT_KEY_F7, /**< F7 */ - F8 = GLUT_KEY_F8, /**< F8 */ - F9 = GLUT_KEY_F9, /**< F9 */ - F10 = GLUT_KEY_F10, /**< F10 */ - F11 = GLUT_KEY_F11, /**< F11 */ - F12 = GLUT_KEY_F12, /**< F12 */ - Home = GLUT_KEY_HOME, /**< Home */ - End = GLUT_KEY_END, /**< End */ - PageUp = GLUT_KEY_PAGE_UP, /**< Page up */ - PageDown = GLUT_KEY_PAGE_DOWN /**< Page down */ - }; - - protected: /** * @brief Key press event - * @param key Key pressed - * @param position Cursor position * * Called when an key is pressed. Default implementation does nothing. */ - virtual void keyPressEvent(Key key, const Vector2i& position); + virtual void keyPressEvent(KeyEvent& event); /*@}*/ /** @{ @name Mouse handling */ public: - /** - * @brief Mouse button - * - * @see mousePressEvent(), mouseReleaseEvent() - */ - enum class MouseButton: int { - Left = GLUT_LEFT_BUTTON, /**< Left button */ - Middle = GLUT_MIDDLE_BUTTON, /**< Middle button */ - Right = GLUT_RIGHT_BUTTON, /**< Right button */ - WheelUp = 3, /**< Wheel up */ - WheelDown = 4 /**< Wheel down */ - }; - /** * @brief Mouse cursor * @@ -193,7 +153,7 @@ class GlutApplication { * when no button is pressed. Mouse tracking is disabled by default. */ inline void setMouseTracking(bool enabled) { - glutPassiveMotionFunc(enabled ? staticMouseMotionEvent : nullptr); + glutPassiveMotionFunc(enabled ? staticMouseMoveEvent : nullptr); } /** @brief Set mouse cursor */ @@ -213,7 +173,7 @@ class GlutApplication { * Called when mouse button is pressed. Default implementation does * nothing. */ - virtual void mousePressEvent(MouseButton button, const Vector2i& position); + virtual void mousePressEvent(MouseEvent& event); /** * @brief Mouse release event @@ -221,16 +181,16 @@ class GlutApplication { * Called when mouse button is released. Default implementation does * nothing. */ - virtual void mouseReleaseEvent(MouseButton button, const Vector2i& position); + virtual void mouseReleaseEvent(MouseEvent& event); /** - * @brief Mouse motion event + * @brief Mouse move event * * Called when any mouse button is pressed and mouse is moved. Default * implementation does nothing. * @see setMouseTracking() */ - virtual void mouseMotionEvent(const Vector2i& position); + virtual void mouseMoveEvent(MouseMoveEvent& event); /*@}*/ @@ -239,20 +199,11 @@ class GlutApplication { instance->viewportEvent({x, y}); } - inline static void staticKeyEvent(int key, int x, int y) { - instance->keyPressEvent(static_cast(key), {x, y}); - } + static void staticKeyEvent(int key, int x, int y); - inline static void staticMouseEvent(int button, int state, int x, int y) { - if(state == GLUT_DOWN) - instance->mousePressEvent(static_cast(button), {x, y}); - else - instance->mouseReleaseEvent(static_cast(button), {x, y}); - } + static void staticMouseEvent(int button, int state, int x, int y); - inline static void staticMouseMotionEvent(int x, int y) { - instance->mouseMotionEvent({x, y}); - } + static void staticMouseMoveEvent(int x, int y); inline static void staticDrawEvent() { instance->drawEvent(); @@ -263,11 +214,151 @@ class GlutApplication { Context* c; }; +/** +@brief Base for input events + +@see KeyEvent, MouseEvent, MouseMoveEvent, keyPressEvent(), mousePressEvent(), + mouseReleaseEvent(), mouseMoveEvent() +*/ +class GlutApplication::InputEvent { + InputEvent(const InputEvent& other) = delete; + InputEvent(InputEvent&& other) = delete; + InputEvent& operator=(const InputEvent& other) = delete; + InputEvent& operator=(InputEvent&& other) = delete; + + public: + inline virtual ~InputEvent() {} + + /** + * @brief Set event as accepted + * + * If the event is ignored (i.e., not set as accepted), it might be + * propagated elsewhere. By default is each event ignored. + */ + inline void setAccepted(bool accepted = true) { _accepted = accepted; } + + /** @brief Whether the event is accepted */ + inline bool isAccepted() { return _accepted; } + + #ifndef DOXYGEN_GENERATING_OUTPUT + protected: + inline InputEvent(): _accepted(false) {} + #endif + + private: + bool _accepted; +}; + +/** +@brief Key event + +@see keyPressEvent() +*/ +class GlutApplication::KeyEvent: public GlutApplication::InputEvent { + friend class GlutApplication; + + public: + /** + * @brief Key + * + * @see key() + */ + enum class Key: int { + Up = GLUT_KEY_UP, /**< Up arrow */ + Down = GLUT_KEY_DOWN, /**< Down arrow */ + Left = GLUT_KEY_LEFT, /**< Left arrow */ + Right = GLUT_KEY_RIGHT, /**< Right arrow */ + F1 = GLUT_KEY_F1, /**< F1 */ + F2 = GLUT_KEY_F2, /**< F2 */ + F3 = GLUT_KEY_F3, /**< F3 */ + F4 = GLUT_KEY_F4, /**< F4 */ + F5 = GLUT_KEY_F5, /**< F5 */ + F6 = GLUT_KEY_F6, /**< F6 */ + F7 = GLUT_KEY_F7, /**< F7 */ + F8 = GLUT_KEY_F8, /**< F8 */ + F9 = GLUT_KEY_F9, /**< F9 */ + F10 = GLUT_KEY_F10, /**< F10 */ + F11 = GLUT_KEY_F11, /**< F11 */ + F12 = GLUT_KEY_F12, /**< F12 */ + Home = GLUT_KEY_HOME, /**< Home */ + End = GLUT_KEY_END, /**< End */ + PageUp = GLUT_KEY_PAGE_UP, /**< Page up */ + PageDown = GLUT_KEY_PAGE_DOWN /**< Page down */ + }; + + /** @brief Key */ + inline Key key() const { return _key; } + + /** @brief Position */ + inline Vector2i position() const { return _position; } + + private: + inline KeyEvent(Key key, const Vector2i& position): _key(key), _position(position) {} + + const Key _key; + const Vector2i _position; +}; + +/** +@brief Mouse event + +@see MouseMoveEvent, mousePressEvent(), mouseReleaseEvent() +*/ +class GlutApplication::MouseEvent: public GlutApplication::InputEvent { + friend class GlutApplication; + + public: + /** + * @brief Mouse button + * + * @see button() + */ + enum class Button: int { + Left = GLUT_LEFT_BUTTON, /**< Left button */ + Middle = GLUT_MIDDLE_BUTTON, /**< Middle button */ + Right = GLUT_RIGHT_BUTTON, /**< Right button */ + WheelUp = 3, /**< Wheel up */ + WheelDown = 4 /**< Wheel down */ + }; + + /** @brief Button */ + inline Button button() const { return _button; } + + /** @brief Position */ + inline Vector2i position() const { return _position; } + + private: + inline MouseEvent(Button button, const Vector2i& position): _button(button), _position(position) {} + + const Button _button; + const Vector2i _position; +}; + +/** +@brief Mouse move event + +@see MouseEvent, mouseMoveEvent() +*/ +class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent { + friend class GlutApplication; + + public: + /** @brief Position */ + inline Vector2i position() const { return _position; } + + private: + inline MouseMoveEvent(const Vector2i& position): _position(position) {} + + const Vector2i _position; +}; + /** @hideinitializer +@brief Entry point for GLUT-based applications @param className Class name -Can be used as equivalent to the following code to achieve better portability, -see @ref portability-applications for more information. +Can be with GlutApplication subclasses used as equivalent to the following +code to achieve better portability, see @ref portability-applications for more +information. @code int main(int argc, char** argv) { className app(argc, argv); @@ -292,10 +383,10 @@ When no other application header is included this macro is also aliased to #endif /* Implementations for inline functions with unused parameters */ -inline void GlutApplication::keyPressEvent(Key, const Vector2i&) {} -inline void GlutApplication::mousePressEvent(MouseButton, const Vector2i&) {} -inline void GlutApplication::mouseReleaseEvent(MouseButton, const Vector2i&) {} -inline void GlutApplication::mouseMotionEvent(const Vector2i&) {} +inline void GlutApplication::keyPressEvent(KeyEvent&) {} +inline void GlutApplication::mousePressEvent(MouseEvent&) {} +inline void GlutApplication::mouseReleaseEvent(MouseEvent&) {} +inline void GlutApplication::mouseMoveEvent(MouseMoveEvent&) {} }} diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h index 13ed6e09b..874499f56 100644 --- a/src/Platform/NaClApplication.h +++ b/src/Platform/NaClApplication.h @@ -261,7 +261,8 @@ class NaClApplication::InputEvent { * @brief Set event as accepted * * If the event is ignored (i.e., not set as accepted), it is - * propagated to the browser. By default is each event ignored. + * propagated elsewhere (e.g. to the browser). By default is each + * event ignored. */ inline void setAccepted(bool accepted = true) { _accepted = accepted; } diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 82f2b377e..14c375628 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -100,11 +100,7 @@ class Sdl2Application { /** @{ @name Keyboard handling */ - /** - * @brief Key press event - * - * Called when an key is pressed. Default implementation does nothing. - */ + /** @copydoc GlutApplication::keyPressEvent() */ virtual void keyPressEvent(KeyEvent& event); /** @@ -134,20 +130,10 @@ class Sdl2Application { void setMouseLocked(bool enabled); protected: - /** - * @brief Mouse press event - * - * Called when mouse button is pressed. Default implementation does - * nothing. - */ + /** @copydoc GlutApplication::mousePressEvent() */ virtual void mousePressEvent(MouseEvent& event); - /** - * @brief Mouse release event - * - * Called when mouse button is released. Default implementation does - * nothing. - */ + /** @copydoc GlutApplication::mouseReleaseEvent() */ virtual void mouseReleaseEvent(MouseEvent& event); /** @@ -205,15 +191,10 @@ class Sdl2Application::InputEvent { inline virtual ~InputEvent() {} - /** - * @brief Set event as accepted - * - * If the event is ignored (i.e., not set as accepted), it might be - * propagated elsewhere. By default is each event ignored. - */ + /** @copydoc GlutApplication::InputEvent::setAccepted() */ inline void setAccepted(bool accepted = true) { _accepted = accepted; } - /** @brief Whether the event is accepted */ + /** @copydoc GlutApplication::InputEvent::isAccepted() */ inline bool isAccepted() { return _accepted; } #ifndef DOXYGEN_GENERATING_OUTPUT @@ -404,10 +385,12 @@ class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent { }; /** @hideinitializer +@brief Entry point for SDL2-based applications @param className Class name -Can be used as equivalent to the following code to achieve better portability, -see @ref portability-applications for more information. +Can be used with Sdl2Application subclasses as equivalent to the following +code to achieve better portability, see @ref portability-applications for more +information. @code int main(int argc, char** argv) { className app(argc, argv);