diff --git a/doc/changelog.dox b/doc/changelog.dox index 910b84a85..2ba29a20c 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -810,8 +810,8 @@ See also: events themselves, which happen for example when moving windows across displays with different DPI. - Added more keys to @ref Platform::AbstractXApplication::KeyEvent::Key and - implemented @ref Platform::AbstractXApplication::mouseScrollEvent() for - better consistency with other application implementations + implemented @ref Platform::AbstractXApplication::scrollEvent() for better + consistency with other application implementations @subsubsection changelog-latest-changes-scenegraph SceneGraph library @@ -1391,13 +1391,16 @@ See also: @relativeref{Platform::Sdl2Application,setMinimalLoopPeriod(Nanoseconds)} - @cpp Platform::Sdl2Application::mousePressEvent() @ce, @cpp mouseReleaseEvent() @ce, @cpp mouseMoveEvent() @ce, - @cpp MouseEvent @ce and @cpp MouseMoveEvent @ce are deprecated in favor of - new @ref Platform::Sdl2Application::pointerPressEvent(), + @cpp mouseScrollEvent() @ce, @cpp MouseEvent @ce. @cpp MouseMoveEvent @ce + and @cpp MouseScrollEvent @ce are deprecated in favor of new + @ref Platform::Sdl2Application::pointerPressEvent(), @relativeref{Platform::Sdl2Application,pointerReleaseEvent()}, @relativeref{Platform::Sdl2Application,pointerMoveEvent()}, - @relativeref{Platform::Sdl2Application,PointerEvent} and - @relativeref{Platform::Sdl2Application,PointerMoveEvent} APIs that provide - a better abstraction over general pointer input, not just a mouse alone. + @relativeref{Platform::Sdl2Application,scrollEvent()}, + @relativeref{Platform::Sdl2Application,PointerEvent}, + @relativeref{Platform::Sdl2Application,PointerMoveEvent} and + @relativeref{Platform::Sdl2Application,ScrollEvent} APIs that provide a + better abstraction over general pointer input, not just a mouse alone. The same change is done in @ref Platform::AbstractXApplication, @ref Platform::AndroidApplication, @ref Platform::EmscriptenApplication, @ref Platform::GlfwApplication and the @@ -1405,8 +1408,8 @@ See also: wrappers as well. - @cpp Platform::AbstractXApplication::MouseEvent::Button::WheelUp @ce and `WheelDown` members are deprecated in favor of a dedicated - @ref Platform::AbstractXApplication::mouseScrollEvent(). Similar change was - done for all other application classes in 2016 already. + @ref Platform::AbstractXApplication::scrollEvent(). Similar change was done + for all other application classes in 2016 already. - @cpp Shaders::DistanceFieldVector @ce, @cpp Shaders::Flat @ce, @cpp Shaders::Generic @ce, @cpp Shaders::MeshVisualizer2D @ce, @cpp Shaders::MeshVisualizer3D @ce, @cpp Shaders::Phong @ce, diff --git a/src/Magnum/Platform/AbstractXApplication.cpp b/src/Magnum/Platform/AbstractXApplication.cpp index 1eed0d9bf..21ff9b22e 100644 --- a/src/Magnum/Platform/AbstractXApplication.cpp +++ b/src/Magnum/Platform/AbstractXApplication.cpp @@ -206,11 +206,11 @@ bool AbstractXApplication::mainLoopIteration() { applications */ if(event.xbutton.button == 4 /*Button4*/ || event.xbutton.button == 5 /*Button5*/) { - MouseScrollEvent e{Vector2::yAxis(event.xbutton.button == 4 ? 1.0f : -1.0f), {event.xbutton.x, event.xbutton.y}, event.xbutton.state}; + ScrollEvent e{Vector2::yAxis(event.xbutton.button == 4 ? 1.0f : -1.0f), {Float(event.xbutton.x), Float(event.xbutton.y)}, event.xbutton.state}; /* It reports both press and release. Fire the scroll event just on press. */ if(event.type == ButtonPress) - mouseScrollEvent(e); + scrollEvent(e); } else { const Pointer pointer = buttonToPointer(event.xbutton.button); Pointers pointers = buttonsToPointers(event.xbutton.state); @@ -360,10 +360,12 @@ void AbstractXApplication::mouseMoveEvent(MouseMoveEvent&) {} CORRADE_IGNORE_DEPRECATED_POP #endif -void AbstractXApplication::mouseScrollEvent(MouseScrollEvent& event) { +void AbstractXApplication::scrollEvent(ScrollEvent& event) { #ifdef MAGNUM_BUILD_DEPRECATED CORRADE_IGNORE_DEPRECATED_PUSH - MouseEvent e{event.offset().y() > 0.0f ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, event._modifiers, event.position()}; + /* The positions are reported in integers in the first place, no need to + round anything */ + MouseEvent e{event.offset().y() > 0.0f ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, event._modifiers, Vector2i{event.position()}}; mousePressEvent(e); mouseReleaseEvent(e); CORRADE_IGNORE_DEPRECATED_POP @@ -384,7 +386,7 @@ AbstractXApplication::Pointers AbstractXApplication::KeyEvent::pointers() const return buttonsToPointers(_modifiers); } -AbstractXApplication::Pointers AbstractXApplication::MouseScrollEvent::pointers() const { +AbstractXApplication::Pointers AbstractXApplication::ScrollEvent::pointers() const { return buttonsToPointers(_modifiers); } diff --git a/src/Magnum/Platform/AbstractXApplication.h b/src/Magnum/Platform/AbstractXApplication.h index 22f1a42c3..ac149cb0d 100644 --- a/src/Magnum/Platform/AbstractXApplication.h +++ b/src/Magnum/Platform/AbstractXApplication.h @@ -63,6 +63,7 @@ typedef int Bool; #include "Magnum/Magnum.h" #include "Magnum/Tags.h" #include "Magnum/Math/Vector2.h" +#include "Magnum/Platform/Platform.h" #include "Magnum/Platform/GLContext.h" #ifdef MAGNUM_BUILD_DEPRECATED @@ -110,7 +111,7 @@ class AbstractXApplication { class MouseEvent; class MouseMoveEvent; #endif - class MouseScrollEvent; + class ScrollEvent; /* The damn thing cannot handle forward enum declarations */ #ifndef DOXYGEN_GENERATING_OUTPUT @@ -122,7 +123,7 @@ class AbstractXApplication { * @m_since_latest * * @see @ref KeyEvent::pointers(), @ref PointerMoveEvent::pointers(), - * @ref MouseScrollEvent::pointers() + * @ref ScrollEvent::pointers() */ typedef Containers::EnumSet Pointers; @@ -403,7 +404,7 @@ class AbstractXApplication { * @ref mouseReleaseEvent() with @ref MouseEvent::Button::WheelDown and * @ref MouseEvent::Button::WheelUp. */ - virtual void mouseScrollEvent(MouseScrollEvent& event); + virtual void scrollEvent(ScrollEvent& event); /* Since 1.8.17, the original short-hand group closing doesn't work anymore. FFS. */ @@ -425,6 +426,7 @@ class AbstractXApplication { /* Calls the base pointer*Event() in order to delegate to deprecated mouse events */ template friend class BasicScreenedApplication; + template friend struct Implementation::ApplicationScrollEventMixin; #endif enum class Flag: unsigned int { @@ -457,7 +459,7 @@ class AbstractXApplication { @see @ref Pointers, @ref KeyEvent::pointers(), @ref PointerEvent::pointer(), @ref PointerMoveEvent::pointer(), @ref PointerMoveEvent::pointers(), - @ref MouseScrollEvent::pointers() + @ref ScrollEvent::pointers() */ enum class AbstractXApplication::Pointer: UnsignedByte { /** Left mouse button. Corresponds to `Button1` / `Button1Mask`. */ @@ -688,10 +690,9 @@ class AbstractXApplication::ViewportEvent { /** @brief Base for input events -@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, - @ref MouseScrollEvent, @ref keyPressEvent(), @ref keyReleaseEvent(), - @ref pointerPressEvent(), @ref pointerReleaseEvent(), - @ref pointerMoveEvent(), @ref mouseScrollEvent() +@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @ref ScrollEvent, + @ref keyPressEvent(), @ref keyReleaseEvent(), @ref pointerPressEvent(), + @ref pointerReleaseEvent(), @ref pointerMoveEvent(), @ref scrollEvent() */ class AbstractXApplication::InputEvent { public: @@ -1236,7 +1237,7 @@ class AbstractXApplication::PointerEvent: public InputEvent { @ref pointerReleaseEvent() instead, which is a better abstraction for covering both mouse and touch / pen input. -@see @ref MouseMoveEvent, @ref MouseScrollEvent, @ref mousePressEvent(), +@see @ref MouseMoveEvent, @ref ScrollEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class CORRADE_DEPRECATED("use PointerEvent, pointerPressEvent() and pointerReleaseEvent() instead") AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent { @@ -1254,17 +1255,15 @@ class CORRADE_DEPRECATED("use PointerEvent, pointerPressEvent() and pointerRelea #ifdef MAGNUM_BUILD_DEPRECATED /** * Wheel up - * @m_deprecated_since_latest Implement @ref mouseScrollEvent() - * instead. + * @m_deprecated_since_latest Implement @ref scrollEvent() instead. */ - WheelUp CORRADE_DEPRECATED_ENUM("implement mouseScrollEvent() instead") = 4, + WheelUp CORRADE_DEPRECATED_ENUM("implement scrollEvent() instead") = 4, /** * Wheel down - * @m_deprecated_since_latest Implement @ref mouseScrollEvent() - * instead. + * @m_deprecated_since_latest Implement @ref scrollEvent() instead. */ - WheelDown CORRADE_DEPRECATED_ENUM("implement mouseScrollEvent() instead") = 5 + WheelDown CORRADE_DEPRECATED_ENUM("implement scrollEvent() instead") = 5 #endif }; @@ -1348,7 +1347,7 @@ class AbstractXApplication::PointerMoveEvent: public InputEvent { @ref pointerMoveEvent() instead, which is a better abstraction for covering both mouse and touch / pen input. -@see @ref MouseEvent, @ref MouseScrollEvent, @ref mouseMoveEvent() +@see @ref MouseEvent, @ref ScrollEvent, @ref mouseMoveEvent() */ class CORRADE_DEPRECATED("use PointerMoveEvent and pointerMoveEvent() instead") AbstractXApplication::MouseMoveEvent: public AbstractXApplication::InputEvent { public: @@ -1365,12 +1364,12 @@ class CORRADE_DEPRECATED("use PointerMoveEvent and pointerMoveEvent() instead") #endif /** -@brief Mouse scroll event +@brief Scroll event @m_since_latest -@see @ref PointerEvent, @ref PointerMoveEvent, @ref mouseScrollEvent() +@see @ref PointerEvent, @ref PointerMoveEvent, @ref scrollEvent() */ -class AbstractXApplication::MouseScrollEvent: public InputEvent { +class AbstractXApplication::ScrollEvent: public InputEvent { public: /** * @brief Scroll offset @@ -1379,8 +1378,12 @@ class AbstractXApplication::MouseScrollEvent: public InputEvent { */ Vector2 offset() const { return _offset; } - /** @brief Position */ - Vector2i position() const { return _position; } + /** + * @brief Position + * + * For mouse input the position is always reported in whole pixels. + */ + Vector2 position() const { return _position; } /** * @brief Pointer types pressed in this event @@ -1393,10 +1396,10 @@ class AbstractXApplication::MouseScrollEvent: public InputEvent { private: friend AbstractXApplication; - explicit MouseScrollEvent(const Vector2& offset, const Vector2i& position, unsigned int modifiers): InputEvent{modifiers}, _offset{offset}, _position{position} {} + explicit ScrollEvent(const Vector2& offset, const Vector2& position, unsigned int modifiers): InputEvent{modifiers}, _offset{offset}, _position{position} {} const Vector2 _offset; - const Vector2i _position; + const Vector2 _position; }; }} diff --git a/src/Magnum/Platform/AndroidApplication.h b/src/Magnum/Platform/AndroidApplication.h index 9e5534809..f8663d00d 100644 --- a/src/Magnum/Platform/AndroidApplication.h +++ b/src/Magnum/Platform/AndroidApplication.h @@ -499,6 +499,8 @@ class AndroidApplication { /* Calls the base pointer*Event() in order to delegate to deprecated mouse events */ template friend class BasicScreenedApplication; + /* Not ApplicationScrollEventMixin, as this class doesn't have the + deprecated mouseScrollEvent() */ #endif struct LogOutput; diff --git a/src/Magnum/Platform/EmscriptenApplication.cpp b/src/Magnum/Platform/EmscriptenApplication.cpp index 206f1a609..4ea6a96ab 100644 --- a/src/Magnum/Platform/EmscriptenApplication.cpp +++ b/src/Magnum/Platform/EmscriptenApplication.cpp @@ -614,8 +614,8 @@ void EmscriptenApplication::setupCallbacks(bool resizable) { emscripten_set_wheel_callback(_canvasTarget.data(), this, false, ([](int, const EmscriptenWheelEvent* event, void* userData) -> EM_BOOL { - MouseScrollEvent e{*event}; - static_cast(userData)->mouseScrollEvent(e); + ScrollEvent e{*event}; + static_cast(userData)->scrollEvent(e); return e.isAccepted(); })); @@ -854,7 +854,23 @@ void EmscriptenApplication::mouseMoveEvent(MouseMoveEvent&) {} CORRADE_IGNORE_DEPRECATED_POP #endif +void EmscriptenApplication::scrollEvent(ScrollEvent& event) { + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_IGNORE_DEPRECATED_PUSH + MouseScrollEvent mouseEvent{event.event()}; + mouseScrollEvent(mouseEvent); + CORRADE_IGNORE_DEPRECATED_POP + #else + static_cast(event); + #endif +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH void EmscriptenApplication::mouseScrollEvent(MouseScrollEvent&) {} +CORRADE_IGNORE_DEPRECATED_POP +#endif + void EmscriptenApplication::textInputEvent(TextInputEvent&) {} #ifdef MAGNUM_TARGET_GL @@ -967,7 +983,7 @@ EmscriptenApplication::MouseMoveEvent::Modifiers EmscriptenApplication::MouseMov } #endif -Vector2 EmscriptenApplication::MouseScrollEvent::offset() const { +Vector2 EmscriptenApplication::ScrollEvent::offset() const { /* From emscripten's Browser.getMouseWheelDelta() function in library_browser.js: @@ -980,6 +996,24 @@ Vector2 EmscriptenApplication::MouseScrollEvent::offset() const { return {f*Float(_event.deltaX), f*Float(_event.deltaY)}; } +Vector2 EmscriptenApplication::ScrollEvent::position() const { + /* Relies on the target being the canvas, which should be always true for + mouse events */ + return {Float(_event.mouse.targetX), Float(_event.mouse.targetY)}; +} + +EmscriptenApplication::InputEvent::Modifiers EmscriptenApplication::ScrollEvent::modifiers() const { + return eventModifiers(_event.mouse); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +Vector2 EmscriptenApplication::MouseScrollEvent::offset() const { + const Float f = (_event.deltaMode == DOM_DELTA_PIXEL) ? -0.01f : + ((_event.deltaMode == DOM_DELTA_LINE) ? -1.0f/3.0f : -80.0f); + + return {f*Float(_event.deltaX), f*Float(_event.deltaY)}; +} + Vector2i EmscriptenApplication::MouseScrollEvent::position() const { /* 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` @@ -990,6 +1024,7 @@ Vector2i EmscriptenApplication::MouseScrollEvent::position() const { EmscriptenApplication::InputEvent::Modifiers EmscriptenApplication::MouseScrollEvent::modifiers() const { return eventModifiers(_event.mouse); } +#endif Key EmscriptenApplication::KeyEvent::key() const { return toKey(_event.key, _event.code); diff --git a/src/Magnum/Platform/EmscriptenApplication.h b/src/Magnum/Platform/EmscriptenApplication.h index 70b08ca34..222030ef8 100644 --- a/src/Magnum/Platform/EmscriptenApplication.h +++ b/src/Magnum/Platform/EmscriptenApplication.h @@ -298,11 +298,12 @@ class EmscriptenApplication { class InputEvent; class PointerEvent; class PointerMoveEvent; + class ScrollEvent; #ifdef MAGNUM_BUILD_DEPRECATED class MouseEvent; class MouseMoveEvent; - #endif class MouseScrollEvent; + #endif class KeyEvent; class TextInputEvent; @@ -910,12 +911,29 @@ class EmscriptenApplication { #endif /** - * @brief Mouse scroll event + * @brief Scroll event + * @m_since_latest * * Called when a scrolling device is used (mouse wheel or scrolling - * area on a touchpad). Default implementation does nothing. + * area on a touchpad). + * + * On builds with @ref MAGNUM_BUILD_DEPRECATED enabled, default + * implementation delegates to @ref mouseScrollEvent(). On builds with + * deprecated functionality disabled, default implementation does + * nothing. */ - virtual void mouseScrollEvent(MouseScrollEvent& event); + virtual void scrollEvent(ScrollEvent& event); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Mouse move event + * @m_deprecated_since_latest Use @ref scrollEvent() instead, which + * isn't semantically tied to just a mouse. + * + * Default implementation does nothing. + */ + virtual CORRADE_DEPRECATED("use scrollEvent() instead") void mouseScrollEvent(MouseScrollEvent& event); + #endif /* Since 1.8.17, the original short-hand group closing doesn't work anymore. FFS. */ @@ -984,6 +1002,7 @@ class EmscriptenApplication { /* Calls the base pointer*Event() in order to delegate to deprecated mouse events */ template friend class BasicScreenedApplication; + template friend struct Implementation::ApplicationScrollEventMixin; #endif enum class Flag: UnsignedByte; @@ -1572,10 +1591,9 @@ class EmscriptenApplication::ViewportEvent { /** @brief Base for input events -@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, - @ref MouseScrollEvent, @ref keyPressEvent(), @ref keyReleaseEvent(), - @ref pointerPressEvent(), @ref pointerReleaseEvent(), - @ref pointerMoveEvent(), @ref mouseScrollEvent() +@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @ref ScrollEvent, + @ref keyPressEvent(), @ref keyReleaseEvent(), @ref pointerPressEvent(), + @ref pointerReleaseEvent(), @ref pointerMoveEvent(), @ref scrollEvent() */ class EmscriptenApplication::InputEvent { public: @@ -1585,7 +1603,7 @@ class EmscriptenApplication::InputEvent { * @see @ref Modifiers, @ref KeyEvent::modifiers(), * @ref PointerEvent::modifiers(), * @ref PointerMoveEvent::modifiers(), - * @ref MouseScrollEvent::modifiers() + * @ref ScrollEvent::modifiers() */ enum class Modifier: Int { /** @@ -1622,7 +1640,7 @@ class EmscriptenApplication::InputEvent { * * @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(), * @ref PointerMoveEvent::modifiers(), - * @ref MouseScrollEvent::modifiers() + * @ref ScrollEvent::modifiers() */ typedef Containers::EnumSet Modifiers; @@ -1665,7 +1683,7 @@ CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::InputEvent::Modifiers) @brief Pointer event @m_since_latest -@see @ref PointerMoveEvent, @ref MouseScrollEvent, @ref pointerPressEvent(), +@see @ref PointerMoveEvent, @ref ScrollEvent, @ref pointerPressEvent(), @ref pointerReleaseEvent() */ class EmscriptenApplication::PointerEvent: public InputEvent { @@ -1763,7 +1781,7 @@ class CORRADE_DEPRECATED("use PointerEvent, pointerPressEvent() and pointerRelea @brief Pointer move event @m_since_latest -@see @ref PointerEvent, @ref MouseScrollEvent, @ref pointerMoveEvent() +@see @ref PointerEvent, @ref ScrollEvent, @ref pointerMoveEvent() */ class EmscriptenApplication::PointerMoveEvent: public InputEvent { public: @@ -1902,12 +1920,47 @@ CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::MouseMoveEvent::Buttons) CORRADE_IGNORE_DEPRECATED_POP #endif +/** +@brief Scroll event +@m_since_latest + +@see @ref PointerEvent, @ref PointerMoveEvent, @ref scrollEvent() +*/ +class EmscriptenApplication::ScrollEvent: public EmscriptenApplication::InputEvent { + public: + /** @brief Scroll offset */ + Vector2 offset() const; + + /** + * @brief Position + * + * The position is always reported in whole pixels. + */ + Vector2 position() const; + + /** @brief Modifiers */ + Modifiers modifiers() const; + + /** @brief Underlying Emscripten event */ + const EmscriptenWheelEvent& event() const { return _event; } + + private: + friend EmscriptenApplication; + + explicit ScrollEvent(const EmscriptenWheelEvent& event): _event(event) {} + + const EmscriptenWheelEvent& _event; +}; + +#ifdef MAGNUM_BUILD_DEPRECATED /** @brief Mouse scroll event +@m_deprecated_since_latest Use @ref ScrollEvent and @ref scrollEvent() instead, + which isn't semantically tied to just a mouse. -@see @ref PointerEvent, @ref PointerMoveEvent, @ref mouseScrollEvent() +@see @ref MouseEvent, @ref MouseMoveEvent, @ref mouseScrollEvent() */ -class EmscriptenApplication::MouseScrollEvent: public EmscriptenApplication::InputEvent { +class CORRADE_DEPRECATED("use ScrollEvent and scrollEvent() instead") EmscriptenApplication::MouseScrollEvent: public InputEvent { public: /** @brief Scroll offset */ Vector2 offset() const; @@ -1928,6 +1981,7 @@ class EmscriptenApplication::MouseScrollEvent: public EmscriptenApplication::Inp const EmscriptenWheelEvent& _event; }; +#endif /** @brief Key event diff --git a/src/Magnum/Platform/GlfwApplication.cpp b/src/Magnum/Platform/GlfwApplication.cpp index 1865e412a..441a7ac59 100644 --- a/src/Magnum/Platform/GlfwApplication.cpp +++ b/src/Magnum/Platform/GlfwApplication.cpp @@ -727,8 +727,8 @@ void GlfwApplication::setupCallbacks() { app.pointerMoveEvent(e); }); glfwSetScrollCallback(_window, [](GLFWwindow* window, double xoffset, double yoffset) { - MouseScrollEvent e(window, Vector2{Float(xoffset), Float(yoffset)}); - static_cast(glfwGetWindowUserPointer(window))->mouseScrollEvent(e); + ScrollEvent e{window, {Float(xoffset), Float(yoffset)}}; + static_cast(glfwGetWindowUserPointer(window))->scrollEvent(e); }); glfwSetCharCallback(_window, [](GLFWwindow* window, unsigned int codepoint) { auto& app = *static_cast(glfwGetWindowUserPointer(window)); @@ -1072,7 +1072,23 @@ void GlfwApplication::mouseMoveEvent(MouseMoveEvent&) {} CORRADE_IGNORE_DEPRECATED_POP #endif +void GlfwApplication::scrollEvent(ScrollEvent& event) { + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_IGNORE_DEPRECATED_PUSH + MouseScrollEvent mouseEvent{_window, event.offset()}; + mouseScrollEvent(mouseEvent); + CORRADE_IGNORE_DEPRECATED_POP + #else + static_cast(event); + #endif +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH void GlfwApplication::mouseScrollEvent(MouseScrollEvent&) {} +CORRADE_IGNORE_DEPRECATED_POP +#endif + void GlfwApplication::textInputEvent(TextInputEvent&) {} bool GlfwApplication::isTextInputActive() const { @@ -1153,6 +1169,21 @@ auto GlfwApplication::MouseMoveEvent::modifiers() -> Modifiers { CORRADE_IGNORE_DEPRECATED_POP #endif +auto GlfwApplication::ScrollEvent::modifiers() -> Modifiers { + if(!_modifiers) _modifiers = currentGlfwModifiers(_window); + return *_modifiers; +} +Vector2 GlfwApplication::ScrollEvent::position() { + if(!_position) { + Vector2d position; + glfwGetCursorPos(_window, &position.x(), &position.y()); + _position = Vector2{position}; + } + return *_position; +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH Vector2i GlfwApplication::MouseScrollEvent::position() { if(!_position) { Vector2d position; @@ -1167,11 +1198,13 @@ auto GlfwApplication::MouseScrollEvent::modifiers() -> Modifiers { if(!_modifiers) _modifiers = currentGlfwModifiers(_window); return *_modifiers; } +CORRADE_IGNORE_DEPRECATED_POP +#endif /* On MSVC 2017, deprecation warning suppression doesn't work on virtual function overrides, so ScreenedApplication overriding mousePressEvent(), - mouseReleaseEvent(), and mouseMoveEvent() causes warnings. Disable them at a - higher level instead. */ + mouseReleaseEvent() mouseMoveEvent() and mouseScrollEvent() causes warnings. + Disable them at a higher level instead. */ #if defined(MAGNUM_BUILD_DEPRECATED) && defined(CORRADE_TARGET_MSVC) && !defined(CORRADE_TARGET_CLANG) && _MSC_VER < 1920 CORRADE_IGNORE_DEPRECATED_PUSH #endif diff --git a/src/Magnum/Platform/GlfwApplication.h b/src/Magnum/Platform/GlfwApplication.h index d025b4359..f909c2c22 100644 --- a/src/Magnum/Platform/GlfwApplication.h +++ b/src/Magnum/Platform/GlfwApplication.h @@ -180,11 +180,12 @@ class GlfwApplication { class KeyEvent; class PointerEvent; class PointerMoveEvent; + class ScrollEvent; #ifdef MAGNUM_BUILD_DEPRECATED class MouseEvent; class MouseMoveEvent; - #endif class MouseScrollEvent; + #endif class TextInputEvent; /* The damn thing cannot handle forward enum declarations */ @@ -776,8 +777,30 @@ class GlfwApplication { virtual CORRADE_DEPRECATED("use pointerMoveEvent() instead") void mouseMoveEvent(MouseMoveEvent& event); #endif - /** @copydoc Sdl2Application::mouseScrollEvent() */ - virtual void mouseScrollEvent(MouseScrollEvent& event); + /** + * @brief Scroll event + * @m_since_latest + * + * Called when a scrolling device is used (mouse wheel or scrolling + * area on a touchpad). + * + * On builds with @ref MAGNUM_BUILD_DEPRECATED enabled, default + * implementation delegates to @ref mouseScrollEvent(). On builds with + * deprecated functionality disabled, default implementation does + * nothing. + */ + virtual void scrollEvent(ScrollEvent& event); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Mouse move event + * @m_deprecated_since_latest Use @ref scrollEvent() instead, which + * isn't semantically tied to just a mouse. + * + * Default implementation does nothing. + */ + virtual CORRADE_DEPRECATED("use scrollEvent() instead") void mouseScrollEvent(MouseScrollEvent& event); + #endif /* Since 1.8.17, the original short-hand group closing doesn't work anymore. FFS. */ @@ -870,6 +893,7 @@ class GlfwApplication { /* Calls the base pointer*Event() in order to delegate to deprecated mouse events */ template friend class BasicScreenedApplication; + template friend struct Implementation::ApplicationScrollEventMixin; #endif enum class Flag: UnsignedByte; @@ -1696,10 +1720,9 @@ class GlfwApplication::ViewportEvent { /** @brief Base for input events -@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, - @ref MouseScrollEvent, @ref keyPressEvent(), @ref keyReleaseEvent(), - @ref pointerPressEvent(), @ref pointerReleaseEvent(), - @ref pointerMoveEvent(), @ref mouseScrollEvent() +@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @ref ScrollEvent, + @ref keyPressEvent(), @ref keyReleaseEvent(), @ref pointerPressEvent(), + @ref pointerReleaseEvent(), @ref pointerMoveEvent(), @ref scrollEvent() */ class GlfwApplication::InputEvent { public: @@ -1709,7 +1732,7 @@ class GlfwApplication::InputEvent { * @see @ref Modifiers, @ref KeyEvent::modifiers(), * @ref PointerEvent::modifiers(), * @ref PointerMoveEvent::modifiers(), - * @ref MouseScrollEvent::modifiers() + * @ref ScrollEvent::modifiers() */ enum class Modifier: Int { /** @@ -1746,7 +1769,7 @@ class GlfwApplication::InputEvent { * * @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(), * @ref PointerMoveEvent::modifiers(), - * @ref MouseScrollEvent::modifiers() + * @ref ScrollEvent::modifiers() */ typedef Containers::EnumSet Modifiers; @@ -2092,7 +2115,7 @@ class GlfwApplication::KeyEvent: public GlfwApplication::InputEvent { @brief Pointer event @m_since_latest -@see @ref PointerMoveEvent, @ref MouseScrollEvent, @ref pointerPressEvent(), +@see @ref PointerMoveEvent, @ref ScrollEvent, @ref pointerPressEvent(), @ref pointerReleaseEvent() */ class GlfwApplication::PointerEvent: public InputEvent { @@ -2189,7 +2212,7 @@ class CORRADE_DEPRECATED("use PointerEvent, pointerPressEvent() and pointerRelea @brief Pointer move event @m_since_latest -@see @ref PointerEvent, @ref MouseScrollEvent, @ref pointerMoveEvent() +@see @ref PointerEvent, @ref ScrollEvent, @ref pointerMoveEvent() */ class GlfwApplication::PointerMoveEvent: public InputEvent { public: @@ -2339,12 +2362,54 @@ CORRADE_ENUMSET_OPERATORS(GlfwApplication::MouseMoveEvent::Buttons) CORRADE_IGNORE_DEPRECATED_POP #endif +/** +@brief Scroll event +@m_since_latest + +@see @ref PointerEvent, @ref PointerMoveEvent, @ref scrollEvent() +*/ +class GlfwApplication::ScrollEvent: public InputEvent { + public: + /** @brief Scroll offset */ + Vector2 offset() const { return _offset; } + + /** + * @brief Position + * + * May return fractional values for example on HiDPI systems where + * window size is smaller than actual framebuffer size. Use + * @ref Math::round() to snap them to the nearest window pixel. Lazily + * populated on first request. + */ + Vector2 position(); + + /** + * @brief Modifiers + * + * Lazily populated on first request. + */ + Modifiers modifiers(); + + private: + friend GlfwApplication; + + explicit ScrollEvent(GLFWwindow* window, const Vector2& offset): _window{window}, _offset{offset} {} + + GLFWwindow* const _window; + const Vector2 _offset; + Containers::Optional _position; + Containers::Optional _modifiers; +}; + +#ifdef MAGNUM_BUILD_DEPRECATED /** @brief Mouse scroll event +@m_deprecated_since_latest Use @ref ScrollEvent and @ref scrollEvent() instead, + which isn't semantically tied to just a mouse. -@see @ref PointerEvent, @ref PointerMoveEvent, @ref mouseScrollEvent() +@see @ref MouseEvent, @ref MouseMoveEvent, @ref mouseScrollEvent() */ -class GlfwApplication::MouseScrollEvent: public GlfwApplication::InputEvent { +class CORRADE_DEPRECATED("use ScrollEvent and scrollEvent() instead") GlfwApplication::MouseScrollEvent: public GlfwApplication::InputEvent { public: /** @brief Scroll offset */ Vector2 offset() const { return _offset; } @@ -2373,6 +2438,7 @@ class GlfwApplication::MouseScrollEvent: public GlfwApplication::InputEvent { Containers::Optional _position; Containers::Optional _modifiers; }; +#endif /** @brief Text input event diff --git a/src/Magnum/Platform/Platform.h b/src/Magnum/Platform/Platform.h index 92850798c..87342e4a9 100644 --- a/src/Magnum/Platform/Platform.h +++ b/src/Magnum/Platform/Platform.h @@ -37,6 +37,13 @@ namespace Magnum { namespace Platform { #ifndef DOXYGEN_GENERATING_OUTPUT template class BasicScreen; template class BasicScreenedApplication; +/* For ScreenedApplication backwards compatibility with mouseScrollEvent() + delegated from scrollEvent(), remove once gone */ +#ifdef MAGNUM_BUILD_DEPRECATED +namespace Implementation { + template struct ApplicationScrollEventMixin; +} +#endif #ifdef MAGNUM_TARGET_GL class GLContext; diff --git a/src/Magnum/Platform/Screen.h b/src/Magnum/Platform/Screen.h index 8e4b40490..b9289df5c 100644 --- a/src/Magnum/Platform/Screen.h +++ b/src/Magnum/Platform/Screen.h @@ -62,16 +62,33 @@ template class ScreenKeyEventMixin { virtual void keyReleaseEvent(KeyEvent& event); }; +template class ScreenScrollEventMixin {}; +template class ScreenScrollEventMixin { + public: + typedef typename BasicScreenedApplication::ScrollEvent ScrollEvent; + + private: + friend ApplicationScrollEventMixin; + + virtual void scrollEvent(ScrollEvent& event); +}; + +#ifdef MAGNUM_BUILD_DEPRECATED template class ScreenMouseScrollEventMixin {}; template class ScreenMouseScrollEventMixin { public: - typedef typename BasicScreenedApplication::MouseScrollEvent MouseScrollEvent; + CORRADE_IGNORE_DEPRECATED_PUSH + typedef CORRADE_DEPRECATED("use ScrollEvent and scrollEvent() instead") typename BasicScreenedApplication::MouseScrollEvent MouseScrollEvent; + CORRADE_IGNORE_DEPRECATED_POP private: friend ApplicationMouseScrollEventMixin; - virtual void mouseScrollEvent(MouseScrollEvent& event); + CORRADE_IGNORE_DEPRECATED_PUSH + virtual CORRADE_DEPRECATED("use scrollEvent() instead") void mouseScrollEvent(MouseScrollEvent& event); + CORRADE_IGNORE_DEPRECATED_POP }; +#endif template class ScreenTextInputEventMixin {}; template class ScreenTextInputEventMixin { @@ -123,7 +140,10 @@ The following specialization are explicitly compiled into each particular template class BasicScreen: private Containers::LinkedListItem, BasicScreenedApplication>, public Implementation::ScreenKeyEventMixin::value>, + public Implementation::ScreenScrollEventMixin::value>, + #ifdef MAGNUM_BUILD_DEPRECATED public Implementation::ScreenMouseScrollEventMixin::value>, + #endif public Implementation::ScreenTextInputEventMixin::value>, public Implementation::ScreenTextEditingEventMixin::value> { @@ -229,14 +249,27 @@ template class BasicScreen: #endif #ifdef DOXYGEN_GENERATING_OUTPUT + /** + * @brief Scroll event + * @m_since_latest + * + * Defined only if the application has a + * @relativeref{Sdl2Application,ScrollEvent}. + */ + typedef typename BasicScreenedApplication::ScrollEvent ScrollEvent; + + #ifdef MAGNUM_BUILD_DEPRECATED /** * @brief Mouse scroll event - * @m_since{2019,10} + * @m_deprecated_since_latest Use @ref ScrollEvent and + * @ref scrollEvent() instead, which isn't semantically tied to + * just a mouse. * * Defined only if the application has a * @ref Sdl2Application::MouseScrollEvent "MouseScrollEvent". */ typedef typename BasicScreenedApplication::MouseScrollEvent MouseScrollEvent; + #endif /** * @brief Text input event @@ -522,9 +555,22 @@ template class BasicScreen: #endif #ifdef DOXYGEN_GENERATING_OUTPUT + /** + * @brief Scroll event + * @m_since_latest + * + * Called when @ref PropagatedEvent::Input is enabled and mouse wheel + * is rotated. See @ref Sdl2Application::scrollEvent() "*Application::scrollEvent()" + * for more information. Defined only if the application has a + * @ref Sdl2Application::ScrollEvent "ScrollEvent". + */ + virtual void scrollEvent(ScrollEvent& event); + + #ifdef MAGNUM_BUILD_DEPRECATED /** * @brief Mouse scroll event - * @m_since{2019,10} + * @m_deprecated_since_latest Use @ref scrollEvent() instead, which + * isn't semantically tied to just a mouse. * * Called when @ref PropagatedEvent::Input is enabled and mouse wheel * is rotated. See @ref Sdl2Application::mouseScrollEvent() "*Application::mouseScrollEvent()" @@ -533,6 +579,7 @@ template class BasicScreen: */ virtual void mouseScrollEvent(MouseScrollEvent& event); #endif + #endif /* Since 1.8.17, the original short-hand group closing doesn't work anymore. FFS. */ diff --git a/src/Magnum/Platform/ScreenedApplication.h b/src/Magnum/Platform/ScreenedApplication.h index 3487164f9..1b0cb6a4b 100644 --- a/src/Magnum/Platform/ScreenedApplication.h +++ b/src/Magnum/Platform/ScreenedApplication.h @@ -41,7 +41,10 @@ namespace Magnum { namespace Platform { namespace Implementation { CORRADE_HAS_TYPE(HasKeyEvent, typename T::KeyEvent); +CORRADE_HAS_TYPE(HasScrollEvent, typename T::ScrollEvent); +#ifdef MAGNUM_BUILD_DEPRECATED CORRADE_HAS_TYPE(HasMouseScrollEvent, typename T::MouseScrollEvent); +#endif CORRADE_HAS_TYPE(HasTextInputEvent, typename T::TextInputEvent); CORRADE_HAS_TYPE(HasTextEditingEvent, typename T::TextEditingEvent); @@ -60,9 +63,22 @@ template struct ApplicationKeyEventMixin { void callKeyReleaseEvent(typename Application::KeyEvent& event, Containers::LinkedList>& screens); }; -/* Calls into the screen in case the application has a mouseScrollEvent(), - otherwise provides a dummy virtual so the application can unconditionally - override */ +/* Calls into the screen in case the application has a scrollEvent(), otherwise + provides a dummy virtual so the application can unconditionally override */ +template struct ApplicationScrollEventMixin { + typedef int ScrollEvent; + virtual void scrollEvent(ScrollEvent&) = 0; + + void callScrollEvent(Application&, ScrollEvent&, Containers::LinkedList>&); +}; +template struct ApplicationScrollEventMixin { + void callScrollEvent(Application& application, typename Application::ScrollEvent& event, Containers::LinkedList>& screens); +}; + +#ifdef MAGNUM_BUILD_DEPRECATED +/* Calls into the screen in case the application has a (deprecated) + mouseScrollEvent(), otherwise provides a dummy virtual so the application + can unconditionally override */ template struct ApplicationMouseScrollEventMixin { typedef int MouseScrollEvent; virtual void mouseScrollEvent(MouseScrollEvent&) = 0; @@ -70,8 +86,11 @@ template struct ApplicationMouseScrollEventMixin { void callMouseScrollEvent(MouseScrollEvent&, Containers::LinkedList>&); }; template struct ApplicationMouseScrollEventMixin { + CORRADE_IGNORE_DEPRECATED_PUSH void callMouseScrollEvent(typename Application::MouseScrollEvent& event, Containers::LinkedList>& screens); + CORRADE_IGNORE_DEPRECATED_POP }; +#endif /* Calls into the screen in case the application has a textInputEvent(), otherwise provides a dummy virtual so the application can unconditionally @@ -175,7 +194,10 @@ template class BasicScreenedApplication: public Application, private Containers::LinkedList>, private Implementation::ApplicationKeyEventMixin::value>, + private Implementation::ApplicationScrollEventMixin::value>, + #ifdef MAGNUM_BUILD_DEPRECATED private Implementation::ApplicationMouseScrollEventMixin::value>, + #endif private Implementation::ApplicationTextInputEventMixin::value>, private Implementation::ApplicationTextEditingEventMixin::value> { @@ -339,7 +361,12 @@ template class BasicScreenedApplication: doesn't have them, they're overriding a mixin dummy */ void keyPressEvent(typename BasicScreenedApplication::KeyEvent& event) override final; void keyReleaseEvent(typename BasicScreenedApplication::KeyEvent& event) override final; + void scrollEvent(typename BasicScreenedApplication::ScrollEvent& event) override final; + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_IGNORE_DEPRECATED_PUSH void mouseScrollEvent(typename BasicScreenedApplication::MouseScrollEvent& event) override final; + CORRADE_IGNORE_DEPRECATED_POP + #endif void textInputEvent(typename BasicScreenedApplication::TextInputEvent& event) override final; void textEditingEvent(typename BasicScreenedApplication::TextEditingEvent& event) override final; }; diff --git a/src/Magnum/Platform/ScreenedApplication.hpp b/src/Magnum/Platform/ScreenedApplication.hpp index b5688234d..ef23837c7 100644 --- a/src/Magnum/Platform/ScreenedApplication.hpp +++ b/src/Magnum/Platform/ScreenedApplication.hpp @@ -59,6 +59,30 @@ template void ApplicationKeyEventMixin::ca } } +template void ApplicationScrollEventMixin::callScrollEvent(Application&, ScrollEvent&, Containers::LinkedList>&) {} +template void ApplicationScrollEventMixin::callScrollEvent(Application& application, typename Application::ScrollEvent& event, Containers::LinkedList>& screens) { + /* Front-to-back event propagation, stop when the event gets accepted */ + for(BasicScreen* s = screens.first(); s; s = s->nextFartherScreen()) { + if(s->propagatedEvents() & Implementation::PropagatedScreenEvent::Input) { + s->scrollEvent(event); + if(event.isAccepted()) break; + } + } + + #ifdef MAGNUM_BUILD_DEPRECATED + /* If the event wasn't accepted, it's possible that the screens still only + implement the deprecated mouse events. Call into the base + implementation and assume it appropriately delegates to + mouseScrollEvent(). */ + if(!event.isAccepted()) + application.scrollEvent(event); + #else + static_cast(application); + #endif +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH template void ApplicationMouseScrollEventMixin::callMouseScrollEvent(MouseScrollEvent&, Containers::LinkedList>&) {} template void ApplicationMouseScrollEventMixin::callMouseScrollEvent(typename Application::MouseScrollEvent& event, Containers::LinkedList>& screens) { /* Front-to-back event propagation, stop when the event gets accepted */ @@ -69,6 +93,8 @@ template void ApplicationMouseScrollEventMixin void ApplicationTextInputEventMixin::callTextInputEvent(TextInputEvent&, Containers::LinkedList>&) {} template void ApplicationTextInputEventMixin::callTextInputEvent(typename Application::TextInputEvent& event, Containers::LinkedList>& screens) { @@ -93,16 +119,16 @@ true>::callTextEditingEvent(typename Application::TextEditingEvent& event, Conta } } -template void ScreenKeyEventMixin::keyPressEvent(KeyEvent&) {} -template void ScreenKeyEventMixin::keyReleaseEvent(KeyEvent&) {} -template void ScreenMouseScrollEventMixin::mouseScrollEvent(MouseScrollEvent&) {} -template void ScreenTextInputEventMixin::textInputEvent(TextInputEvent&) {} -template void ScreenTextEditingEventMixin::textEditingEvent(TextEditingEvent&) {} +template void ScreenKeyEventMixin::keyPressEvent(KeyEvent&) {} +template void ScreenKeyEventMixin::keyReleaseEvent(KeyEvent&) {} +template void ScreenScrollEventMixin::scrollEvent(ScrollEvent&) {} +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH +template void ScreenMouseScrollEventMixin::mouseScrollEvent(MouseScrollEvent&) {} +CORRADE_IGNORE_DEPRECATED_POP +#endif +template void ScreenTextInputEventMixin::textInputEvent(TextInputEvent&) {} +template void ScreenTextEditingEventMixin::textEditingEvent(TextEditingEvent&) {} } @@ -324,9 +350,17 @@ template void BasicScreenedApplication::mouseMov CORRADE_IGNORE_DEPRECATED_POP #endif +template void BasicScreenedApplication::scrollEvent(typename BasicScreenedApplication::ScrollEvent& event) { + this->callScrollEvent(*this, event, screens()); +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH template void BasicScreenedApplication::mouseScrollEvent(typename BasicScreenedApplication::MouseScrollEvent& event) { this->callMouseScrollEvent(event, screens()); } +CORRADE_IGNORE_DEPRECATED_POP +#endif template void BasicScreenedApplication::textInputEvent(typename BasicScreenedApplication::TextInputEvent& event) { this->callTextInputEvent(event, screens()); diff --git a/src/Magnum/Platform/Sdl2Application.cpp b/src/Magnum/Platform/Sdl2Application.cpp index 76479fa0c..761a98f74 100644 --- a/src/Magnum/Platform/Sdl2Application.cpp +++ b/src/Magnum/Platform/Sdl2Application.cpp @@ -1042,8 +1042,8 @@ bool Sdl2Application::mainLoopIteration() { } break; case SDL_MOUSEWHEEL: { - MouseScrollEvent e{event, {Float(event.wheel.x), Float(event.wheel.y)}}; - mouseScrollEvent(e); + ScrollEvent e{event, {Float(event.wheel.x), Float(event.wheel.y)}}; + scrollEvent(e); } break; case SDL_MOUSEMOTION: { @@ -1401,7 +1401,23 @@ void Sdl2Application::mouseMoveEvent(MouseMoveEvent&) {} CORRADE_IGNORE_DEPRECATED_POP #endif +void Sdl2Application::scrollEvent(ScrollEvent& event) { + #ifdef MAGNUM_BUILD_DEPRECATED + CORRADE_IGNORE_DEPRECATED_PUSH + MouseScrollEvent mouseEvent{event.event(), event.offset()}; + mouseScrollEvent(mouseEvent); + CORRADE_IGNORE_DEPRECATED_POP + #else + static_cast(event); + #endif +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH void Sdl2Application::mouseScrollEvent(MouseScrollEvent&) {} +CORRADE_IGNORE_DEPRECATED_POP +#endif + void Sdl2Application::multiGestureEvent(MultiGestureEvent&) {} void Sdl2Application::textInputEvent(TextInputEvent&) {} void Sdl2Application::textEditingEvent(TextEditingEvent&) {} @@ -1473,6 +1489,23 @@ Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseMoveEvent::modifier CORRADE_IGNORE_DEPRECATED_POP #endif +Vector2 Sdl2Application::ScrollEvent::position() { + if(!_position) { + Vector2i position; + SDL_GetMouseState(&position.x(), &position.y()); + _position = Vector2{position}; + } + return *_position; +} + +Sdl2Application::InputEvent::Modifiers Sdl2Application::ScrollEvent::modifiers() { + if(!_modifiers) + _modifiers = fixedModifiers(Uint16(SDL_GetModState())); + return *_modifiers; +} + +#ifdef MAGNUM_BUILD_DEPRECATED +CORRADE_IGNORE_DEPRECATED_PUSH Vector2i Sdl2Application::MouseScrollEvent::position() { if(_position) return *_position; _position = Vector2i{}; @@ -1484,12 +1517,15 @@ Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseScrollEvent::modifi if(_modifiers) return *_modifiers; return *(_modifiers = fixedModifiers(Uint16(SDL_GetModState()))); } +CORRADE_IGNORE_DEPRECATED_POP +#endif /* WinRT builds by default have deprecation warnings as errors. Combined with a MSVC 2017 bug where deprecation warning suppression doesn't work on virtual function overrides this make the build fail on deprecation warnings due to - ScreenedApplication overriding mousePressEvent(), mouseReleaseEvent() and - mouseMoveEvent(). Disable the warnings at a higher level instead. */ + ScreenedApplication overriding mousePressEvent(), mouseReleaseEvent(), + mouseMoveEvent() and mouseScrollEvent(). Disable the warnings at a higher + level instead. */ #if defined(MAGNUM_BUILD_DEPRECATED) && defined(CORRADE_TARGET_MSVC) && !defined(CORRADE_TARGET_CLANG) && _MSC_VER < 1920 CORRADE_IGNORE_DEPRECATED_PUSH #endif diff --git a/src/Magnum/Platform/Sdl2Application.h b/src/Magnum/Platform/Sdl2Application.h index 47be1a338..c89e89ac6 100644 --- a/src/Magnum/Platform/Sdl2Application.h +++ b/src/Magnum/Platform/Sdl2Application.h @@ -502,11 +502,12 @@ class Sdl2Application { class KeyEvent; class PointerEvent; class PointerMoveEvent; + class ScrollEvent; #ifdef MAGNUM_BUILD_DEPRECATED class MouseEvent; class MouseMoveEvent; - #endif class MouseScrollEvent; + #endif class MultiGestureEvent; class TextInputEvent; class TextEditingEvent; @@ -1184,12 +1185,29 @@ class Sdl2Application { #endif /** - * @brief Mouse scroll event + * @brief Scroll event + * @m_since_latest * * Called when a scrolling device is used (mouse wheel or scrolling - * area on a touchpad). Default implementation does nothing. + * area on a touchpad). + * + * On builds with @ref MAGNUM_BUILD_DEPRECATED enabled, default + * implementation delegates to @ref mouseScrollEvent(). On builds with + * deprecated functionality disabled, default implementation does + * nothing. + */ + virtual void scrollEvent(ScrollEvent& event); + + #ifdef MAGNUM_BUILD_DEPRECATED + /** + * @brief Mouse move event + * @m_deprecated_since_latest Use @ref scrollEvent() instead, which + * isn't semantically tied to just a mouse. + * + * Default implementation does nothing. */ - virtual void mouseScrollEvent(MouseScrollEvent& event); + virtual CORRADE_DEPRECATED("use scrollEvent() instead") void mouseScrollEvent(MouseScrollEvent& event); + #endif /** * @brief Multi gesture event @@ -1327,6 +1345,7 @@ class Sdl2Application { /* Calls the base pointer*Event() in order to delegate to deprecated mouse events */ template friend class BasicScreenedApplication; + template friend struct Implementation::ApplicationScrollEventMixin; #endif enum class Flag: UnsignedByte; @@ -2259,10 +2278,9 @@ class Sdl2Application::ViewportEvent { /** @brief Base for input events -@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, - @ref MouseScrollEvent, @ref keyPressEvent(), @ref keyReleaseEvent(), - @ref pointerPressEvent(), @ref pointerReleaseEvent(), - @ref pointerMoveEvent(), @ref mouseScrollEvent() +@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @ref ScrollEvent, + @ref keyPressEvent(), @ref keyReleaseEvent(), @ref pointerPressEvent(), + @ref pointerReleaseEvent(), @ref pointerMoveEvent(), @ref scrollEvent() */ class Sdl2Application::InputEvent { public: @@ -2272,7 +2290,7 @@ class Sdl2Application::InputEvent { * @see @ref Modifiers, @ref KeyEvent::modifiers(), * @ref PointerEvent::modifiers(), * @ref PointerMoveEvent::modifiers(), - * @ref MouseScrollEvent::modifiers() + * @ref ScrollEvent::modifiers() */ enum class Modifier: Uint16 { /** @@ -2331,7 +2349,7 @@ class Sdl2Application::InputEvent { * * @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(), * @ref PointerMoveEvent::modifiers(), - * @ref MouseScrollEvent::modifiers() + * @ref ScrollEvent::modifiers() */ typedef Containers::EnumSet Modifiers; @@ -2366,7 +2384,7 @@ class Sdl2Application::InputEvent { * Of type `SDL_KEYDOWN` / `SDL_KEYUP` for @ref KeyEvent, * `SDL_MOUSEBUTTONDOWN` / `SDL_MOUSEBUTTONUP` for @ref PointerEvent, * `SDL_MOUSEMOTION` for @ref PointerMoveEvent and `SDL_MOUSEWHEEL` for - * @ref MouseScrollEvent. + * @ref ScrollEvent. * @see @ref Sdl2Application::anyEvent() */ const SDL_Event& event() const { return _event; } @@ -2990,12 +3008,51 @@ CORRADE_ENUMSET_OPERATORS(Sdl2Application::MouseMoveEvent::Buttons) CORRADE_IGNORE_DEPRECATED_POP #endif +/** +@brief Scroll event +@m_since_latest + +@see @ref PointerEvent, @ref PointerMoveEvent, @ref scrollEvent() +*/ +class Sdl2Application::ScrollEvent: public Sdl2Application::InputEvent { + public: + /** @brief Scroll offset */ + Vector2 offset() const { return _offset; } + + /** + * @brief Position + * + * For mouse input the position is always reported in whole pixels. + * Lazily populated on first request. + */ + Vector2 position(); + + /** + * @brief Modifiers + * + * Lazily populated on first request. + */ + Modifiers modifiers(); + + private: + friend Sdl2Application; + + explicit ScrollEvent(const SDL_Event& event, const Vector2& offset): InputEvent{event}, _offset{offset} {} + + const Vector2 _offset; + Containers::Optional _position; + Containers::Optional _modifiers; +}; + +#ifdef MAGNUM_BUILD_DEPRECATED /** @brief Mouse scroll event +@m_deprecated_since_latest Use @ref ScrollEvent and @ref scrollEvent() instead, + which isn't semantically tied to just a mouse. -@see @ref PointerEvent, @ref PointerMoveEvent, @ref mouseScrollEvent() +@see @ref MouseEvent, @ref MouseMoveEvent, @ref mouseScrollEvent() */ -class Sdl2Application::MouseScrollEvent: public Sdl2Application::InputEvent { +class CORRADE_DEPRECATED("use ScrollEvent and scrollEvent() instead") Sdl2Application::MouseScrollEvent: public InputEvent { public: /** @brief Scroll offset */ Vector2 offset() const { return _offset; } @@ -3023,6 +3080,7 @@ class Sdl2Application::MouseScrollEvent: public Sdl2Application::InputEvent { Containers::Optional _position; Containers::Optional _modifiers; }; +#endif /** @brief Multi gesture event diff --git a/src/Magnum/Platform/Test/AbstractXApplicationTest.cpp b/src/Magnum/Platform/Test/AbstractXApplicationTest.cpp index 00eefcd3f..de6d777d1 100644 --- a/src/Magnum/Platform/Test/AbstractXApplicationTest.cpp +++ b/src/Magnum/Platform/Test/AbstractXApplicationTest.cpp @@ -299,8 +299,8 @@ struct AbstractXApplicationTest: Platform::Application { /* Comment out to test the deprecated scroll as press/release reporting */ #if 1 - void mouseScrollEvent(MouseScrollEvent& event) override { - Debug{} << "mouse scroll:" << event.pointers() << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); + void scrollEvent(ScrollEvent& event) override { + Debug{} << "scroll:" << event.pointers() << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); } #endif diff --git a/src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp b/src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp index b0bfb9ce2..8b8f12ad9 100644 --- a/src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp +++ b/src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp @@ -299,6 +299,9 @@ struct EmscriptenApplicationTest: Platform::Application { void pointerMoveEvent(PointerMoveEvent& event) override { Debug{} << "pointer move:" << event.pointer() << event.pointers() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); } + void scrollEvent(ScrollEvent& event) override { + Debug{} << "scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); + } #else CORRADE_IGNORE_DEPRECATED_PUSH void mousePressEvent(MouseEvent& event) override { @@ -310,12 +313,11 @@ struct EmscriptenApplicationTest: Platform::Application { 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(); } + CORRADE_IGNORE_DEPRECATED_POP + #endif /* For testing keyboard capture */ void keyPressEvent(KeyEvent& event) override { diff --git a/src/Magnum/Platform/Test/GlfwApplicationTest.cpp b/src/Magnum/Platform/Test/GlfwApplicationTest.cpp index 5b2f4c52f..7ba653a9f 100644 --- a/src/Magnum/Platform/Test/GlfwApplicationTest.cpp +++ b/src/Magnum/Platform/Test/GlfwApplicationTest.cpp @@ -363,6 +363,9 @@ struct GlfwApplicationTest: Platform::Application { void pointerMoveEvent(PointerMoveEvent& event) override { Debug{} << "pointer move:" << event.pointer() << event.pointers() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); } + void scrollEvent(ScrollEvent& event) override { + Debug{} << "scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); + } #else CORRADE_IGNORE_DEPRECATED_PUSH void mousePressEvent(MouseEvent& event) override { @@ -374,12 +377,11 @@ struct GlfwApplicationTest: Platform::Application { 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(); } + CORRADE_IGNORE_DEPRECATED_POP + #endif void textInputEvent(TextInputEvent& event) override { Debug{} << "text input:" << event.text(); diff --git a/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp b/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp index ee5627b28..1dccaf7ae 100644 --- a/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp +++ b/src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp @@ -334,6 +334,9 @@ struct Sdl2ApplicationTest: Platform::Application { void pointerMoveEvent(PointerMoveEvent& event) override { Debug{} << "pointer move:" << event.pointer() << event.pointers() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); } + void scrollEvent(ScrollEvent& event) override { + Debug{} << "scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); + } #else CORRADE_IGNORE_DEPRECATED_PUSH void mousePressEvent(MouseEvent& event) override { @@ -349,12 +352,11 @@ struct Sdl2ApplicationTest: Platform::Application { void mouseMoveEvent(MouseMoveEvent& event) override { Debug{} << "mouse move:" << event.buttons() << Debug::packed << event.position() << Debug::packed << event.relativePosition() << event.modifiers(); } - CORRADE_IGNORE_DEPRECATED_POP - #endif - void mouseScrollEvent(MouseScrollEvent& event) override { Debug{} << "mouse scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); } + CORRADE_IGNORE_DEPRECATED_POP + #endif void multiGestureEvent(MultiGestureEvent& event) override { Debug{} << "multi gesture:" << event.center() << "rotation:" << Deg{_gestureRotation} << Debug::nospace << ", relative" << Deg{event.relativeRotation()} << Debug::nospace << ", distance" << _gestureDistance << Debug::nospace << ", relative" << event.relativeDistance() << Debug::nospace << ", fingers" << event.fingerCount();