From e86c011e05d78f8e74d0bba62742054923ccb27c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 14 Oct 2024 17:11:44 +0200 Subject: [PATCH] Platform: replace mouse events with pointer events in EmscriptenApp. Nothing special here, except for the extremely stupid difference where the middle mouse button is 1 in one event and 1 << 2 in another. --- doc/changelog.dox | 4 +- src/Magnum/Platform/EmscriptenApplication.cpp | 174 ++++++++++- src/Magnum/Platform/EmscriptenApplication.h | 281 ++++++++++++++++-- .../Test/EmscriptenApplicationTest.cpp | 53 +++- 4 files changed, 475 insertions(+), 37 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index c0b4c2508..3e9b453f3 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -1396,8 +1396,8 @@ See also: @relativeref{Platform::Sdl2Application,PointerEvent} and @relativeref{Platform::Sdl2Application,PointerMoveEvent} APIs that provide a better abstraction over general pointer input, not just a mouse alone. - The same change is done in @ref Platform::AbstractXApplication and - @ref Platform::GlfwApplication. + The same change is done in @ref Platform::AbstractXApplication, + @ref Platform::EmscriptenApplication and @ref Platform::GlfwApplication. - @cpp Platform::AbstractXApplication::MouseEvent::Button::WheelUp @ce and `WheelDown` members are deprecated in favor of a dedicated @ref Platform::AbstractXApplication::mouseScrollEvent(). Similar change was diff --git a/src/Magnum/Platform/EmscriptenApplication.cpp b/src/Magnum/Platform/EmscriptenApplication.cpp index 8d917d78d..206f1a609 100644 --- a/src/Magnum/Platform/EmscriptenApplication.cpp +++ b/src/Magnum/Platform/EmscriptenApplication.cpp @@ -501,6 +501,42 @@ void EmscriptenApplication::handleCanvasResize(const EmscriptenUiEvent* event) { } } +namespace { + +EmscriptenApplication::Pointer buttonToPointer(const std::int32_t button) { + /* https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button */ + switch(button) { + case 0: + return EmscriptenApplication::Pointer::MouseLeft; + case 1: + return EmscriptenApplication::Pointer::MouseMiddle; + case 2: + return EmscriptenApplication::Pointer::MouseRight; + } + + /* W3C spec allows other, platform-specific buttons: + https://www.w3.org/TR/uievents/#dom-mouseevent-button + Return an invalid value in that case, don't treat this as an unreachable + scenario. */ + return {}; +} + +EmscriptenApplication::Pointers buttonsToPointers(const std::uint32_t buttons) { + /* https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons, + note that Middle and Right has order swapped compared to button, for + some unexplainable reason */ + EmscriptenApplication::Pointers pointers; + if(buttons & (1 << 0)) + pointers |= EmscriptenApplication::Pointer::MouseLeft; + if(buttons & (1 << 2)) + pointers |= EmscriptenApplication::Pointer::MouseMiddle; + if(buttons & (1 << 1)) + pointers |= EmscriptenApplication::Pointer::MouseRight; + return pointers; +} + +} + void EmscriptenApplication::setupCallbacks(bool resizable) { /* Since 1.38.17 all emscripten_set_*_callback() are macros. Play it safe and wrap all lambdas in () to avoid the preprocessor getting upset when @@ -524,32 +560,55 @@ void EmscriptenApplication::setupCallbacks(bool resizable) { emscripten_set_mousedown_callback(_canvasTarget.data(), this, false, ([](int, const EmscriptenMouseEvent* event, void* userData) -> EM_BOOL { - MouseEvent e{*event}; - static_cast(userData)->mousePressEvent(e); - return e.isAccepted(); + auto& app = *static_cast(userData); + const Pointer pointer = buttonToPointer(event->button); + const Pointers pointers = buttonsToPointers(event->buttons); + + /* If an additional mouse button was pressed, call a move event + instead */ + if(pointers & ~pointer) { + PointerMoveEvent e{*event, pointer, pointers, {}}; + app.pointerMoveEvent(e); + return e.isAccepted(); + } else { + PointerEvent e{*event, pointer}; + app.pointerPressEvent(e); + return e.isAccepted(); + } })); emscripten_set_mouseup_callback(_canvasTarget.data(), this, false, ([](int, const EmscriptenMouseEvent* event, void* userData) -> EM_BOOL { - MouseEvent e{*event}; - static_cast(userData)->mouseReleaseEvent(e); - return e.isAccepted(); + auto& app = *static_cast(userData); + const Pointer pointer = buttonToPointer(event->button); + const Pointers pointers = buttonsToPointers(event->buttons); + + /* If some buttons are still left pressed after a release, call a + move event instead */ + if(pointers) { + PointerMoveEvent e{*event, pointer, pointers, {}}; + app.pointerMoveEvent(e); + return e.isAccepted(); + } else { + PointerEvent e{*event, pointer}; + app.pointerReleaseEvent(e); + return e.isAccepted(); + } })); emscripten_set_mousemove_callback(_canvasTarget.data(), this, false, ([](int, const EmscriptenMouseEvent* event, void* userData) -> EM_BOOL { auto& app = *static_cast(userData); /* Relies on the target being the canvas, which should be always - true for mouse events. The targetX and targetY variables used - to be a `long` before 3.1.47, which is why the cast. */ - Vector2i position{Int(event->targetX), Int(event->targetY)}; - MouseMoveEvent e{*event, + true for mouse events */ + Vector2 position{Float(event->targetX), Float(event->targetY)}; + PointerMoveEvent e{*event, {}, buttonsToPointers(event->buttons), /* Avoid bogus offset at first -- report 0 when the event is calledĀ for the first time. */ - app._previousMouseMovePosition == Vector2i{-1} ? Vector2i{} : + Math::isNan(app._previousMouseMovePosition).all() ? Vector2{} : position - app._previousMouseMovePosition}; app._previousMouseMovePosition = position; - static_cast(userData)->mouseMoveEvent(e); + app.pointerMoveEvent(e); return e.isAccepted(); })); @@ -729,9 +788,72 @@ void EmscriptenApplication::setTextInputRect(const Range2Di&) { void EmscriptenApplication::viewportEvent(ViewportEvent&) {} void EmscriptenApplication::keyPressEvent(KeyEvent&) {} void EmscriptenApplication::keyReleaseEvent(KeyEvent&) {} + +void EmscriptenApplication::pointerPressEvent(PointerEvent& event) { + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_IGNORE_DEPRECATED_PUSH + MouseEvent mouseEvent{event.event()}; + mousePressEvent(mouseEvent); + CORRADE_IGNORE_DEPRECATED_POP + #else + static_cast(event); + #endif +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH void EmscriptenApplication::mousePressEvent(MouseEvent&) {} +CORRADE_IGNORE_DEPRECATED_POP +#endif + +void EmscriptenApplication::pointerReleaseEvent(PointerEvent& event) { + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_IGNORE_DEPRECATED_PUSH + MouseEvent mouseEvent{event.event()}; + mouseReleaseEvent(mouseEvent); + CORRADE_IGNORE_DEPRECATED_POP + #else + static_cast(event); + #endif +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH void EmscriptenApplication::mouseReleaseEvent(MouseEvent&) {} +CORRADE_IGNORE_DEPRECATED_POP +#endif + +void EmscriptenApplication::pointerMoveEvent(PointerMoveEvent& event) { + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_IGNORE_DEPRECATED_PUSH + /* If the event is due to some button being additionally pressed or one + button from a larger set being released, delegate to a press/release + event instead */ + if(event.pointer()) { + /* Emscripten reports either a move or a press/release, so there + shouldn't be any move in this case */ + CORRADE_INTERNAL_ASSERT(event.relativePosition() == Vector2{}); + MouseEvent mouseEvent{event.event()}; + event.pointers() >= *event.pointer() ? + mousePressEvent(mouseEvent) : mouseReleaseEvent(mouseEvent); + } else { + /* The positions are reported in integers in the first place, no need + to round anything */ + MouseMoveEvent mouseEvent{event.event(), Vector2i{event.relativePosition()}}; + mouseMoveEvent(mouseEvent); + } + CORRADE_IGNORE_DEPRECATED_POP + #else + static_cast(event); + #endif +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH void EmscriptenApplication::mouseMoveEvent(MouseMoveEvent&) {} +CORRADE_IGNORE_DEPRECATED_POP +#endif + void EmscriptenApplication::mouseScrollEvent(MouseScrollEvent&) {} void EmscriptenApplication::textInputEvent(TextInputEvent&) {} @@ -787,6 +909,18 @@ template EmscriptenApplication::InputEvent::Modifiers eventModifiers(co } +Vector2 EmscriptenApplication::PointerEvent::position() const { + /* Relies on the target being the canvas, which should be always true for + mouse events */ + return {Float(_event.targetX), Float(_event.targetY)}; +} + +EmscriptenApplication::PointerEvent::Modifiers EmscriptenApplication::PointerEvent::modifiers() const { + return eventModifiers(_event); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH EmscriptenApplication::MouseEvent::Button EmscriptenApplication::MouseEvent::button() const { return Button(_event.button); } @@ -801,10 +935,25 @@ Vector2i EmscriptenApplication::MouseEvent::position() const { EmscriptenApplication::MouseEvent::Modifiers EmscriptenApplication::MouseEvent::modifiers() const { return eventModifiers(_event); } +CORRADE_IGNORE_DEPRECATED_POP +#endif + +Vector2 EmscriptenApplication::PointerMoveEvent::position() const { + /* Relies on the target being the canvas, which should be always true for + mouse events */ + return {Float(_event.targetX), Float(_event.targetY)}; +} + +EmscriptenApplication::PointerMoveEvent::Modifiers EmscriptenApplication::PointerMoveEvent::modifiers() const { + return eventModifiers(_event); +} +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH EmscriptenApplication::MouseMoveEvent::Buttons EmscriptenApplication::MouseMoveEvent::buttons() const { return EmscriptenApplication::MouseMoveEvent::Button(_event.buttons); } +CORRADE_IGNORE_DEPRECATED_POP Vector2i EmscriptenApplication::MouseMoveEvent::position() const { /* Relies on the target being the canvas, which should be always true for @@ -816,6 +965,7 @@ Vector2i EmscriptenApplication::MouseMoveEvent::position() const { EmscriptenApplication::MouseMoveEvent::Modifiers EmscriptenApplication::MouseMoveEvent::modifiers() const { return eventModifiers(_event); } +#endif Vector2 EmscriptenApplication::MouseScrollEvent::offset() const { /* From emscripten's Browser.getMouseWheelDelta() function in diff --git a/src/Magnum/Platform/EmscriptenApplication.h b/src/Magnum/Platform/EmscriptenApplication.h index a470ad30c..8cca7518b 100644 --- a/src/Magnum/Platform/EmscriptenApplication.h +++ b/src/Magnum/Platform/EmscriptenApplication.h @@ -296,12 +296,29 @@ class EmscriptenApplication { class GLConfiguration; class ViewportEvent; class InputEvent; + class PointerEvent; + class PointerMoveEvent; + #ifdef MAGNUM_BUILD_DEPRECATED class MouseEvent; class MouseMoveEvent; + #endif class MouseScrollEvent; class KeyEvent; class TextInputEvent; + /* The damn thing cannot handle forward enum declarations */ + #ifndef DOXYGEN_GENERATING_OUTPUT + enum class Pointer: UnsignedByte; + #endif + + /** + * @brief Set of pointer types + * @m_since_latest + * + * @see @ref PointerMoveEvent::pointers() + */ + typedef Containers::EnumSet Pointers; + #ifdef MAGNUM_TARGET_GL /** * @brief Construct with a WebGL context @@ -600,7 +617,7 @@ class EmscriptenApplication { * @} */ - /** @{ @name Mouse handling */ + /** @{ @name Pointer handling */ public: /** @@ -807,28 +824,90 @@ class EmscriptenApplication { Cursor cursor(); private: + /** + * @brief Pointer press event + * @m_since_latest + * + * Called when a mouse is pressed. Note that if at least one mouse + * button is already pressed and another button gets pressed in + * addition, @ref pointerMoveEvent() with the new combination is + * called, not this function. + * + * On builds with @ref MAGNUM_BUILD_DEPRECATED enabled, default + * implementation delegates to @ref mousePressEvent(). On builds with + * deprecated functionality disabled, default implementation does + * nothing. + */ + virtual void pointerPressEvent(PointerEvent& event); + + #ifdef MAGNUM_BUILD_DEPRECATED /** * @brief Mouse press event + * @m_deprecated_since_latest Use @ref pointerPressEvent() instead, + * which is a better abstraction for covering both mouse and touch + * / pen input. + * + * Default implementation does nothing. + */ + virtual CORRADE_DEPRECATED("use pointerPressEvent() instead") void mousePressEvent(MouseEvent& event); + #endif + + /** + * @brief Pointer release event + * @m_since_latest + * + * Called when a mouse is released. Note that if multiple mouse buttons + * are pressed and one of these is released, @ref pointerMoveEvent() + * with the new combination is called, not this function. * - * Called when mouse button is pressed. Default implementation does + * On builds with @ref MAGNUM_BUILD_DEPRECATED enabled, default + * implementation delegates to @ref mouseReleaseEvent(). On builds with + * deprecated functionality disabled, default implementation does * nothing. */ - virtual void mousePressEvent(MouseEvent& event); + virtual void pointerReleaseEvent(PointerEvent& event); + #ifdef MAGNUM_BUILD_DEPRECATED /** * @brief Mouse release event + * @m_deprecated_since_latest Use @ref pointerReleaseEvent() instead, + * which is a better abstraction for covering both mouse and touch + * / pen input. + * + * Default implementation does nothing. + */ + virtual CORRADE_DEPRECATED("use pointerReleaseEvent() instead") void mouseReleaseEvent(MouseEvent& event); + #endif + + /** + * @brief Pointer move event + * @m_since_latest + * + * Called when any of the currently pressed pointers is moved or + * changes its properties. Gets called also if the set of pressed mouse + * buttons changes. * - * Called when mouse button is released. Default implementation does + * On builds with @ref MAGNUM_BUILD_DEPRECATED enabled, default + * implementation delegates to @ref mouseMoveEvent(), or if + * @ref PointerMoveEvent::pointer() is not + * @relativeref{Corrade,Containers::NullOpt}, to either + * @ref mousePressEvent() or @ref mouseReleaseEvent(). On builds with + * deprecated functionality disabled, default implementation does * nothing. */ - virtual void mouseReleaseEvent(MouseEvent& event); + virtual void pointerMoveEvent(PointerMoveEvent& event); + #ifdef MAGNUM_BUILD_DEPRECATED /** * @brief Mouse move event + * @m_deprecated_since_latest Use @ref pointerMoveEvent() instead, + * which is a better abstraction for covering both mouse and touch + * / pen input. * - * Called when mouse is moved. Default implementation does nothing. + * Default implementation does nothing. */ - virtual void mouseMoveEvent(MouseMoveEvent& event); + virtual CORRADE_DEPRECATED("use pointerMoveEvent() instead") void mouseMoveEvent(MouseMoveEvent& event); + #endif /** * @brief Mouse scroll event @@ -912,7 +991,8 @@ class EmscriptenApplication { void setupCallbacks(bool resizable); void setupAnimationFrame(bool ForceAnimationFrame); - Vector2i _lastKnownCanvasSize, _previousMouseMovePosition{-1}; + Vector2i _lastKnownCanvasSize; + Vector2 _previousMouseMovePosition{Constants::nan()}; Vector2 _lastKnownDevicePixelRatio; Flags _flags; @@ -937,6 +1017,26 @@ class EmscriptenApplication { int (*_callback)(void*); }; +/** +@brief Pointer type +@m_since_latest + +@see @ref Pointers, @ref PointerEvent::pointer(), + @ref PointerMoveEvent::pointer(), @ref PointerMoveEvent::pointers() +*/ +enum class EmscriptenApplication::Pointer: UnsignedByte { + /** Left mouse button */ + MouseLeft = 1 << 0, + + /** Middle mouse button */ + MouseMiddle = 1 << 1, + + /** Right mouse button */ + MouseRight = 1 << 2 +}; + +CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::Pointers) + #ifdef MAGNUM_TARGET_GL /** @brief WebGL context configuration @@ -1466,8 +1566,10 @@ class EmscriptenApplication::ViewportEvent { /** @brief Base for input events -@see @ref KeyEvent, @ref MouseEvent, @ref MouseMoveEvent, @ref keyPressEvent(), - @ref mousePressEvent(), @ref mouseReleaseEvent(), @ref mouseMoveEvent() +@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, + @ref MouseScrollEvent, @ref keyPressEvent(), @ref keyReleaseEvent(), + @ref pointerPressEvent(), @ref pointerReleaseEvent(), + @ref pointerMoveEvent(), @ref mouseScrollEvent() */ class EmscriptenApplication::InputEvent { public: @@ -1475,7 +1577,9 @@ class EmscriptenApplication::InputEvent { * @brief Modifier * * @see @ref Modifiers, @ref KeyEvent::modifiers(), - * @ref MouseEvent::modifiers() + * @ref PointerEvent::modifiers(), + * @ref PointerMoveEvent::modifiers(), + * @ref MouseScrollEvent::modifiers() */ enum class Modifier: Int { /** @@ -1510,8 +1614,9 @@ class EmscriptenApplication::InputEvent { /** * @brief Set of modifiers * - * @see @ref KeyEvent::modifiers(), @ref MouseEvent::modifiers(), - * @ref MouseMoveEvent::modifiers() + * @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(), + * @ref PointerMoveEvent::modifiers(), + * @ref MouseScrollEvent::modifiers() */ typedef Containers::EnumSet Modifiers; @@ -1550,12 +1655,70 @@ class EmscriptenApplication::InputEvent { CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::InputEvent::Modifiers) +/** +@brief Pointer event +@m_since_latest + +@see @ref PointerMoveEvent, @ref MouseScrollEvent, @ref pointerPressEvent(), + @ref pointerReleaseEvent() +*/ +class EmscriptenApplication::PointerEvent: public InputEvent { + public: + /** @brief Copying is not allowed */ + PointerEvent(const PointerEvent&) = delete; + + /** @brief Moving is not allowed */ + PointerEvent(PointerEvent&&) = delete; + + /** @brief Copying is not allowed */ + PointerEvent& operator=(const PointerEvent&) = delete; + + /** @brief Moving is not allowed */ + PointerEvent& operator=(PointerEvent&&) = delete; + + /** + * @brief Pointer type that was pressed or released + * + * The browser is free to report any extra mouse buttons in addition to + * the ones listed in @ref Pointer. In that case a zero value is + * returned and you can get the actual button index through + * @ref event(). + */ + Pointer pointer() const { return _pointer; } + + /** + * @brief Position + * + * The position is always reported in whole pixels. + */ + Vector2 position() const; + + /** @brief Modifiers */ + Modifiers modifiers() const; + + /** @brief Underlying Emscripten event */ + const EmscriptenMouseEvent& event() const { return _event; } + + private: + friend EmscriptenApplication; + + explicit PointerEvent(const EmscriptenMouseEvent& event, Pointer pointer): _event(event), _pointer{pointer} {} + + const EmscriptenMouseEvent& _event; + const Pointer _pointer; +}; + +#ifdef MAGNUM_BUILD_DEPRECATED /** @brief Mouse event +@m_deprecated_since_latest Use @ref PointerEvent, @ref pointerPressEvent() and + @ref pointerReleaseEvent() instead, which is a better abstraction for + covering both mouse and touch / pen input. -@see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() +@see @ref MouseMoveEvent, @ref MouseScrollEvent, @ref mousePressEvent(), + @ref mouseReleaseEvent() */ -class EmscriptenApplication::MouseEvent: public EmscriptenApplication::InputEvent { +class CORRADE_DEPRECATED("use PointerEvent, pointerPressEvent() and pointerReleaseEvent() instead") EmscriptenApplication::MouseEvent: public InputEvent { public: /** * @brief Mouse button @@ -1588,13 +1751,92 @@ class EmscriptenApplication::MouseEvent: public EmscriptenApplication::InputEven const EmscriptenMouseEvent& _event; }; +#endif + +/** +@brief Pointer move event +@m_since_latest + +@see @ref PointerEvent, @ref MouseScrollEvent, @ref pointerMoveEvent() +*/ +class EmscriptenApplication::PointerMoveEvent: public InputEvent { + public: + /** @brief Copying is not allowed */ + PointerMoveEvent(const PointerMoveEvent&) = delete; + + /** @brief Moving is not allowed */ + PointerMoveEvent(PointerMoveEvent&&) = delete; + + /** @brief Copying is not allowed */ + PointerMoveEvent& operator=(const PointerMoveEvent&) = delete; + + /** @brief Moving is not allowed */ + PointerMoveEvent& operator=(PointerMoveEvent&&) = delete; + + /** + * @brief Pointer type that was added or removed from the set of pressed pointers + * + * Is non-empty only in case a mouse button was pressed in addition to + * an already pressed button, or if one mouse button from multiple + * pressed buttons was released. If non-empty and @ref pointers() don't + * contain given @ref Pointer value, the button was released, if they + * contain given value, the button was pressed. + */ + Containers::Optional pointer() const { return _pointer; } + + /** + * @brief Pointer types pressed in this event + * + * Returns an empty set if no pointers are pressed, which happens for + * example when a mouse is just moved around. + * @see @ref pointer() + */ + Pointers pointers() const { return _pointers; } + + /** + * @brief Position + * + * The position is always reported in whole pixels. + */ + Vector2 position() const; + + /** + * @brief Position relative to the previous touch event + * + * The position is always reported in whole pixels. Unlike + * @ref Sdl2Application, HTML APIs don't provide relative position + * directly, so this is calculated explicitly as a delta from previous + * move event position. + */ + Vector2 relativePosition() const { return _relativePosition; } + + /** @brief Modifiers */ + Modifiers modifiers() const; + + /** @brief Underlying Emscripten event */ + const EmscriptenMouseEvent& event() const { return _event; } + + private: + friend EmscriptenApplication; + + explicit PointerMoveEvent(const EmscriptenMouseEvent& event, Containers::Optional pointer, Pointers pointers, const Vector2& relativePosition): _event(event), _pointer{pointer}, _pointers{pointers}, _relativePosition{relativePosition} {} + + const EmscriptenMouseEvent& _event; + const Containers::Optional _pointer; + const Pointers _pointers; + const Vector2 _relativePosition; +}; +#ifdef MAGNUM_BUILD_DEPRECATED /** @brief Mouse move event +@m_deprecated_since_latest Use @ref PointerMoveEvent and + @ref pointerMoveEvent() instead, which is a better abstraction for covering + both mouse and touch / pen input. -@see @ref MouseEvent, @ref mouseMoveEvent() +@see @ref MouseEvent, @ref MouseScrollEvent, @ref mouseMoveEvent() */ -class EmscriptenApplication::MouseMoveEvent: public EmscriptenApplication::InputEvent { +class CORRADE_DEPRECATED("use PointerMoveEvent and pointerMoveEvent() instead") EmscriptenApplication::MouseMoveEvent: public InputEvent { public: /** * @brief Mouse button @@ -1649,12 +1891,15 @@ class EmscriptenApplication::MouseMoveEvent: public EmscriptenApplication::Input const Vector2i _relativePosition; }; +CORRADE_IGNORE_DEPRECATED_PUSH CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::MouseMoveEvent::Buttons) +CORRADE_IGNORE_DEPRECATED_POP +#endif /** @brief Mouse scroll event -@see @ref MouseEvent, @ref MouseMoveEvent, @ref mouseScrollEvent() +@see @ref PointerEvent, @ref PointerMoveEvent, @ref mouseScrollEvent() */ class EmscriptenApplication::MouseScrollEvent: public EmscriptenApplication::InputEvent { public: diff --git a/src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp b/src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp index 869ac082d..b0bfb9ce2 100644 --- a/src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp +++ b/src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp @@ -65,7 +65,23 @@ static Debug& operator<<(Debug& debug, Application::InputEvent::Modifier value) return debug << "(" << Debug::nospace << UnsignedInt(value) << Debug::nospace << ")"; } -static Debug& operator<<(Debug& debug, Application::MouseMoveEvent::Button value) { +static Debug& operator<<(Debug& debug, Application::Pointer value) { + debug << "Pointer" << Debug::nospace; + + switch(value) { + #define _c(value) case Application::Pointer::value: return debug << "::" #value; + _c(MouseLeft) + _c(MouseMiddle) + _c(MouseRight) + #undef _c + } + + return debug << "(" << Debug::nospace << UnsignedInt(value) << Debug::nospace << ")"; +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH +CORRADE_UNUSED static Debug& operator<<(Debug& debug, Application::MouseMoveEvent::Button value) { debug << "Button" << Debug::nospace; switch(value) { @@ -78,6 +94,8 @@ static Debug& operator<<(Debug& debug, Application::MouseMoveEvent::Button value return debug << "(" << Debug::nospace << UnsignedInt(value) << Debug::nospace << ")"; } +CORRADE_IGNORE_DEPRECATED_POP +#endif namespace Test { namespace { @@ -90,7 +108,17 @@ Debug& operator<<(Debug& debug, Application::InputEvent::Modifiers value) { }); } -Debug& operator<<(Debug& debug, Application::MouseEvent::Button value) { +Debug& operator<<(Debug& debug, Application::Pointers value) { + return Containers::enumSetDebugOutput(debug, value, "Pointers{}", { + Application::Pointer::MouseLeft, + Application::Pointer::MouseMiddle, + Application::Pointer::MouseRight, + }); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH +CORRADE_UNUSED Debug& operator<<(Debug& debug, Application::MouseEvent::Button value) { debug << "Button" << Debug::nospace; switch(value) { @@ -104,13 +132,15 @@ Debug& operator<<(Debug& debug, Application::MouseEvent::Button value) { return debug << "(" << Debug::nospace << UnsignedInt(value) << Debug::nospace << ")"; } -Debug& operator<<(Debug& debug, Application::MouseMoveEvent::Buttons value) { +CORRADE_UNUSED Debug& operator<<(Debug& debug, Application::MouseMoveEvent::Buttons value) { return Containers::enumSetDebugOutput(debug, value, "Buttons{}", { Application::MouseMoveEvent::Button::Left, Application::MouseMoveEvent::Button::Middle, Application::MouseMoveEvent::Button::Right, }); } +CORRADE_IGNORE_DEPRECATED_POP +#endif Debug& operator<<(Debug& debug, const Application::KeyEvent::Key value) { debug << "Key" << Debug::nospace; @@ -258,17 +288,30 @@ struct EmscriptenApplicationTest: Platform::Application { } #endif + /* Set to 0 to test the deprecated mouse events instead */ + #if 1 + void pointerPressEvent(PointerEvent& event) override { + Debug{} << "pointer press:" << event.pointer() << event.modifiers() << Debug::packed << event.position(); + } + void pointerReleaseEvent(PointerEvent& event) override { + Debug{} << "pointer release:" << event.pointer() << event.modifiers() << Debug::packed << event.position(); + } + void pointerMoveEvent(PointerMoveEvent& event) override { + Debug{} << "pointer move:" << event.pointer() << event.pointers() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); + } + #else + CORRADE_IGNORE_DEPRECATED_PUSH void mousePressEvent(MouseEvent& event) override { Debug{} << "mouse press:" << event.button() << event.modifiers() << Debug::packed << event.position(); } - void mouseReleaseEvent(MouseEvent& event) override { Debug{} << "mouse release:" << event.button() << event.modifiers() << Debug::packed << event.position(); } - void mouseMoveEvent(MouseMoveEvent& event) override { Debug{} << "mouse move:" << event.buttons() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); } + CORRADE_IGNORE_DEPRECATED_POP + #endif void mouseScrollEvent(MouseScrollEvent& event) override { Debug{} << "mouse scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position();