Browse Source

Platform: replace MouseScrollEvent with a ScrollEvent with float position.

All the new pointer events have float positions, this one was the odd one
out. And I didn't like the name anymore, so I took that as an opportunity
to change the position() data type without introducing a breaking change
for everyone.

Another considered change was adding Z offset to it, since HTML5 APIs
have that. However, all my googling led to just a single SO question from
2015, where someone said it's for trackballs that can navigate in 3D
space. I'm not sure if *scroll* is actually the best way to report those,
and since SDL3 didn't bother adding that and neither Android nor WINAPI
have anything like that, I'm not bothering either.

Unlike the previous commits, this is done for all apps at once, because
it's a comparatively simpler change. The only odd one out is
AbstractXApplication, where I introduced MouseScrollEvent just a few
commits back, so I simply renamed it without leaving a deprecated copy.
Then, ScreenedApplication needed some extra logic to handle the case of
apps not implementing any scroll event at all.
pull/651/head
Vladimír Vondruš 2 years ago
parent
commit
3981bcf2f4
  1. 21
      doc/changelog.dox
  2. 12
      src/Magnum/Platform/AbstractXApplication.cpp
  3. 49
      src/Magnum/Platform/AbstractXApplication.h
  4. 2
      src/Magnum/Platform/AndroidApplication.h
  5. 41
      src/Magnum/Platform/EmscriptenApplication.cpp
  6. 82
      src/Magnum/Platform/EmscriptenApplication.h
  7. 41
      src/Magnum/Platform/GlfwApplication.cpp
  8. 92
      src/Magnum/Platform/GlfwApplication.h
  9. 7
      src/Magnum/Platform/Platform.h
  10. 55
      src/Magnum/Platform/Screen.h
  11. 33
      src/Magnum/Platform/ScreenedApplication.h
  12. 54
      src/Magnum/Platform/ScreenedApplication.hpp
  13. 44
      src/Magnum/Platform/Sdl2Application.cpp
  14. 84
      src/Magnum/Platform/Sdl2Application.h
  15. 4
      src/Magnum/Platform/Test/AbstractXApplicationTest.cpp
  16. 8
      src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp
  17. 8
      src/Magnum/Platform/Test/GlfwApplicationTest.cpp
  18. 8
      src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp

21
doc/changelog.dox

@ -810,8 +810,8 @@ See also:
events themselves, which happen for example when moving windows across events themselves, which happen for example when moving windows across
displays with different DPI. displays with different DPI.
- Added more keys to @ref Platform::AbstractXApplication::KeyEvent::Key and - Added more keys to @ref Platform::AbstractXApplication::KeyEvent::Key and
implemented @ref Platform::AbstractXApplication::mouseScrollEvent() for implemented @ref Platform::AbstractXApplication::scrollEvent() for better
better consistency with other application implementations consistency with other application implementations
@subsubsection changelog-latest-changes-scenegraph SceneGraph library @subsubsection changelog-latest-changes-scenegraph SceneGraph library
@ -1391,13 +1391,16 @@ See also:
@relativeref{Platform::Sdl2Application,setMinimalLoopPeriod(Nanoseconds)} @relativeref{Platform::Sdl2Application,setMinimalLoopPeriod(Nanoseconds)}
- @cpp Platform::Sdl2Application::mousePressEvent() @ce, - @cpp Platform::Sdl2Application::mousePressEvent() @ce,
@cpp mouseReleaseEvent() @ce, @cpp mouseMoveEvent() @ce, @cpp mouseReleaseEvent() @ce, @cpp mouseMoveEvent() @ce,
@cpp MouseEvent @ce and @cpp MouseMoveEvent @ce are deprecated in favor of @cpp mouseScrollEvent() @ce, @cpp MouseEvent @ce. @cpp MouseMoveEvent @ce
new @ref Platform::Sdl2Application::pointerPressEvent(), and @cpp MouseScrollEvent @ce are deprecated in favor of new
@ref Platform::Sdl2Application::pointerPressEvent(),
@relativeref{Platform::Sdl2Application,pointerReleaseEvent()}, @relativeref{Platform::Sdl2Application,pointerReleaseEvent()},
@relativeref{Platform::Sdl2Application,pointerMoveEvent()}, @relativeref{Platform::Sdl2Application,pointerMoveEvent()},
@relativeref{Platform::Sdl2Application,PointerEvent} and @relativeref{Platform::Sdl2Application,scrollEvent()},
@relativeref{Platform::Sdl2Application,PointerMoveEvent} APIs that provide @relativeref{Platform::Sdl2Application,PointerEvent},
a better abstraction over general pointer input, not just a mouse alone. @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, The same change is done in @ref Platform::AbstractXApplication,
@ref Platform::AndroidApplication, @ref Platform::EmscriptenApplication, @ref Platform::AndroidApplication, @ref Platform::EmscriptenApplication,
@ref Platform::GlfwApplication and the @ref Platform::GlfwApplication and the
@ -1405,8 +1408,8 @@ See also:
wrappers as well. wrappers as well.
- @cpp Platform::AbstractXApplication::MouseEvent::Button::WheelUp @ce and - @cpp Platform::AbstractXApplication::MouseEvent::Button::WheelUp @ce and
`WheelDown` members are deprecated in favor of a dedicated `WheelDown` members are deprecated in favor of a dedicated
@ref Platform::AbstractXApplication::mouseScrollEvent(). Similar change was @ref Platform::AbstractXApplication::scrollEvent(). Similar change was done
done for all other application classes in 2016 already. for all other application classes in 2016 already.
- @cpp Shaders::DistanceFieldVector @ce, @cpp Shaders::Flat @ce, - @cpp Shaders::DistanceFieldVector @ce, @cpp Shaders::Flat @ce,
@cpp Shaders::Generic @ce, @cpp Shaders::MeshVisualizer2D @ce, @cpp Shaders::Generic @ce, @cpp Shaders::MeshVisualizer2D @ce,
@cpp Shaders::MeshVisualizer3D @ce, @cpp Shaders::Phong @ce, @cpp Shaders::MeshVisualizer3D @ce, @cpp Shaders::Phong @ce,

12
src/Magnum/Platform/AbstractXApplication.cpp

@ -206,11 +206,11 @@ bool AbstractXApplication::mainLoopIteration() {
applications */ applications */
if(event.xbutton.button == 4 /*Button4*/ || if(event.xbutton.button == 4 /*Button4*/ ||
event.xbutton.button == 5 /*Button5*/) { 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 /* It reports both press and release. Fire the scroll event
just on press. */ just on press. */
if(event.type == ButtonPress) if(event.type == ButtonPress)
mouseScrollEvent(e); scrollEvent(e);
} else { } else {
const Pointer pointer = buttonToPointer(event.xbutton.button); const Pointer pointer = buttonToPointer(event.xbutton.button);
Pointers pointers = buttonsToPointers(event.xbutton.state); Pointers pointers = buttonsToPointers(event.xbutton.state);
@ -360,10 +360,12 @@ void AbstractXApplication::mouseMoveEvent(MouseMoveEvent&) {}
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #endif
void AbstractXApplication::mouseScrollEvent(MouseScrollEvent& event) { void AbstractXApplication::scrollEvent(ScrollEvent& event) {
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
CORRADE_IGNORE_DEPRECATED_PUSH 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); mousePressEvent(e);
mouseReleaseEvent(e); mouseReleaseEvent(e);
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
@ -384,7 +386,7 @@ AbstractXApplication::Pointers AbstractXApplication::KeyEvent::pointers() const
return buttonsToPointers(_modifiers); return buttonsToPointers(_modifiers);
} }
AbstractXApplication::Pointers AbstractXApplication::MouseScrollEvent::pointers() const { AbstractXApplication::Pointers AbstractXApplication::ScrollEvent::pointers() const {
return buttonsToPointers(_modifiers); return buttonsToPointers(_modifiers);
} }

49
src/Magnum/Platform/AbstractXApplication.h

@ -63,6 +63,7 @@ typedef int Bool;
#include "Magnum/Magnum.h" #include "Magnum/Magnum.h"
#include "Magnum/Tags.h" #include "Magnum/Tags.h"
#include "Magnum/Math/Vector2.h" #include "Magnum/Math/Vector2.h"
#include "Magnum/Platform/Platform.h"
#include "Magnum/Platform/GLContext.h" #include "Magnum/Platform/GLContext.h"
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
@ -110,7 +111,7 @@ class AbstractXApplication {
class MouseEvent; class MouseEvent;
class MouseMoveEvent; class MouseMoveEvent;
#endif #endif
class MouseScrollEvent; class ScrollEvent;
/* The damn thing cannot handle forward enum declarations */ /* The damn thing cannot handle forward enum declarations */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
@ -122,7 +123,7 @@ class AbstractXApplication {
* @m_since_latest * @m_since_latest
* *
* @see @ref KeyEvent::pointers(), @ref PointerMoveEvent::pointers(), * @see @ref KeyEvent::pointers(), @ref PointerMoveEvent::pointers(),
* @ref MouseScrollEvent::pointers() * @ref ScrollEvent::pointers()
*/ */
typedef Containers::EnumSet<Pointer> Pointers; typedef Containers::EnumSet<Pointer> Pointers;
@ -403,7 +404,7 @@ class AbstractXApplication {
* @ref mouseReleaseEvent() with @ref MouseEvent::Button::WheelDown and * @ref mouseReleaseEvent() with @ref MouseEvent::Button::WheelDown and
* @ref MouseEvent::Button::WheelUp. * @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 /* Since 1.8.17, the original short-hand group closing doesn't work
anymore. FFS. */ anymore. FFS. */
@ -425,6 +426,7 @@ class AbstractXApplication {
/* Calls the base pointer*Event() in order to delegate to deprecated /* Calls the base pointer*Event() in order to delegate to deprecated
mouse events */ mouse events */
template<class> friend class BasicScreenedApplication; template<class> friend class BasicScreenedApplication;
template<class, bool> friend struct Implementation::ApplicationScrollEventMixin;
#endif #endif
enum class Flag: unsigned int { enum class Flag: unsigned int {
@ -457,7 +459,7 @@ class AbstractXApplication {
@see @ref Pointers, @ref KeyEvent::pointers(), @ref PointerEvent::pointer(), @see @ref Pointers, @ref KeyEvent::pointers(), @ref PointerEvent::pointer(),
@ref PointerMoveEvent::pointer(), @ref PointerMoveEvent::pointers(), @ref PointerMoveEvent::pointer(), @ref PointerMoveEvent::pointers(),
@ref MouseScrollEvent::pointers() @ref ScrollEvent::pointers()
*/ */
enum class AbstractXApplication::Pointer: UnsignedByte { enum class AbstractXApplication::Pointer: UnsignedByte {
/** Left mouse button. Corresponds to `Button1` / `Button1Mask`. */ /** Left mouse button. Corresponds to `Button1` / `Button1Mask`. */
@ -688,10 +690,9 @@ class AbstractXApplication::ViewportEvent {
/** /**
@brief Base for input events @brief Base for input events
@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @ref ScrollEvent,
@ref MouseScrollEvent, @ref keyPressEvent(), @ref keyReleaseEvent(), @ref keyPressEvent(), @ref keyReleaseEvent(), @ref pointerPressEvent(),
@ref pointerPressEvent(), @ref pointerReleaseEvent(), @ref pointerReleaseEvent(), @ref pointerMoveEvent(), @ref scrollEvent()
@ref pointerMoveEvent(), @ref mouseScrollEvent()
*/ */
class AbstractXApplication::InputEvent { class AbstractXApplication::InputEvent {
public: public:
@ -1236,7 +1237,7 @@ class AbstractXApplication::PointerEvent: public InputEvent {
@ref pointerReleaseEvent() instead, which is a better abstraction for @ref pointerReleaseEvent() instead, which is a better abstraction for
covering both mouse and touch / pen input. covering both mouse and touch / pen input.
@see @ref MouseMoveEvent, @ref MouseScrollEvent, @ref mousePressEvent(), @see @ref MouseMoveEvent, @ref ScrollEvent, @ref mousePressEvent(),
@ref mouseReleaseEvent() @ref mouseReleaseEvent()
*/ */
class CORRADE_DEPRECATED("use PointerEvent, pointerPressEvent() and pointerReleaseEvent() instead") AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent { 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 #ifdef MAGNUM_BUILD_DEPRECATED
/** /**
* Wheel up * Wheel up
* @m_deprecated_since_latest Implement @ref mouseScrollEvent() * @m_deprecated_since_latest Implement @ref scrollEvent() instead.
* instead.
*/ */
WheelUp CORRADE_DEPRECATED_ENUM("implement mouseScrollEvent() instead") = 4, WheelUp CORRADE_DEPRECATED_ENUM("implement scrollEvent() instead") = 4,
/** /**
* Wheel down * Wheel down
* @m_deprecated_since_latest Implement @ref mouseScrollEvent() * @m_deprecated_since_latest Implement @ref scrollEvent() instead.
* instead.
*/ */
WheelDown CORRADE_DEPRECATED_ENUM("implement mouseScrollEvent() instead") = 5 WheelDown CORRADE_DEPRECATED_ENUM("implement scrollEvent() instead") = 5
#endif #endif
}; };
@ -1348,7 +1347,7 @@ class AbstractXApplication::PointerMoveEvent: public InputEvent {
@ref pointerMoveEvent() instead, which is a better abstraction for covering @ref pointerMoveEvent() instead, which is a better abstraction for covering
both mouse and touch / pen input. 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 { class CORRADE_DEPRECATED("use PointerMoveEvent and pointerMoveEvent() instead") AbstractXApplication::MouseMoveEvent: public AbstractXApplication::InputEvent {
public: public:
@ -1365,12 +1364,12 @@ class CORRADE_DEPRECATED("use PointerMoveEvent and pointerMoveEvent() instead")
#endif #endif
/** /**
@brief Mouse scroll event @brief Scroll event
@m_since_latest @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: public:
/** /**
* @brief Scroll offset * @brief Scroll offset
@ -1379,8 +1378,12 @@ class AbstractXApplication::MouseScrollEvent: public InputEvent {
*/ */
Vector2 offset() const { return _offset; } 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 * @brief Pointer types pressed in this event
@ -1393,10 +1396,10 @@ class AbstractXApplication::MouseScrollEvent: public InputEvent {
private: private:
friend AbstractXApplication; 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 Vector2 _offset;
const Vector2i _position; const Vector2 _position;
}; };
}} }}

2
src/Magnum/Platform/AndroidApplication.h

@ -499,6 +499,8 @@ class AndroidApplication {
/* Calls the base pointer*Event() in order to delegate to deprecated /* Calls the base pointer*Event() in order to delegate to deprecated
mouse events */ mouse events */
template<class> friend class BasicScreenedApplication; template<class> friend class BasicScreenedApplication;
/* Not ApplicationScrollEventMixin, as this class doesn't have the
deprecated mouseScrollEvent() */
#endif #endif
struct LogOutput; struct LogOutput;

41
src/Magnum/Platform/EmscriptenApplication.cpp

@ -614,8 +614,8 @@ void EmscriptenApplication::setupCallbacks(bool resizable) {
emscripten_set_wheel_callback(_canvasTarget.data(), this, false, emscripten_set_wheel_callback(_canvasTarget.data(), this, false,
([](int, const EmscriptenWheelEvent* event, void* userData) -> EM_BOOL { ([](int, const EmscriptenWheelEvent* event, void* userData) -> EM_BOOL {
MouseScrollEvent e{*event}; ScrollEvent e{*event};
static_cast<EmscriptenApplication*>(userData)->mouseScrollEvent(e); static_cast<EmscriptenApplication*>(userData)->scrollEvent(e);
return e.isAccepted(); return e.isAccepted();
})); }));
@ -854,7 +854,23 @@ void EmscriptenApplication::mouseMoveEvent(MouseMoveEvent&) {}
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #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<void>(event);
#endif
}
#ifdef MAGNUM_BUILD_DEPRECATED
CORRADE_IGNORE_DEPRECATED_PUSH
void EmscriptenApplication::mouseScrollEvent(MouseScrollEvent&) {} void EmscriptenApplication::mouseScrollEvent(MouseScrollEvent&) {}
CORRADE_IGNORE_DEPRECATED_POP
#endif
void EmscriptenApplication::textInputEvent(TextInputEvent&) {} void EmscriptenApplication::textInputEvent(TextInputEvent&) {}
#ifdef MAGNUM_TARGET_GL #ifdef MAGNUM_TARGET_GL
@ -967,7 +983,7 @@ EmscriptenApplication::MouseMoveEvent::Modifiers EmscriptenApplication::MouseMov
} }
#endif #endif
Vector2 EmscriptenApplication::MouseScrollEvent::offset() const { Vector2 EmscriptenApplication::ScrollEvent::offset() const {
/* From emscripten's Browser.getMouseWheelDelta() function in /* From emscripten's Browser.getMouseWheelDelta() function in
library_browser.js: library_browser.js:
@ -980,6 +996,24 @@ Vector2 EmscriptenApplication::MouseScrollEvent::offset() const {
return {f*Float(_event.deltaX), f*Float(_event.deltaY)}; 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 { Vector2i EmscriptenApplication::MouseScrollEvent::position() const {
/* Relies on the target being the canvas, which should be always true for /* 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` 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 { EmscriptenApplication::InputEvent::Modifiers EmscriptenApplication::MouseScrollEvent::modifiers() const {
return eventModifiers(_event.mouse); return eventModifiers(_event.mouse);
} }
#endif
Key EmscriptenApplication::KeyEvent::key() const { Key EmscriptenApplication::KeyEvent::key() const {
return toKey(_event.key, _event.code); return toKey(_event.key, _event.code);

82
src/Magnum/Platform/EmscriptenApplication.h

@ -298,11 +298,12 @@ class EmscriptenApplication {
class InputEvent; class InputEvent;
class PointerEvent; class PointerEvent;
class PointerMoveEvent; class PointerMoveEvent;
class ScrollEvent;
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
class MouseEvent; class MouseEvent;
class MouseMoveEvent; class MouseMoveEvent;
#endif
class MouseScrollEvent; class MouseScrollEvent;
#endif
class KeyEvent; class KeyEvent;
class TextInputEvent; class TextInputEvent;
@ -910,12 +911,29 @@ class EmscriptenApplication {
#endif #endif
/** /**
* @brief Mouse scroll event * @brief Scroll event
* @m_since_latest
* *
* Called when a scrolling device is used (mouse wheel or scrolling * 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 /* Since 1.8.17, the original short-hand group closing doesn't work
anymore. FFS. */ anymore. FFS. */
@ -984,6 +1002,7 @@ class EmscriptenApplication {
/* Calls the base pointer*Event() in order to delegate to deprecated /* Calls the base pointer*Event() in order to delegate to deprecated
mouse events */ mouse events */
template<class> friend class BasicScreenedApplication; template<class> friend class BasicScreenedApplication;
template<class, bool> friend struct Implementation::ApplicationScrollEventMixin;
#endif #endif
enum class Flag: UnsignedByte; enum class Flag: UnsignedByte;
@ -1572,10 +1591,9 @@ class EmscriptenApplication::ViewportEvent {
/** /**
@brief Base for input events @brief Base for input events
@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @ref ScrollEvent,
@ref MouseScrollEvent, @ref keyPressEvent(), @ref keyReleaseEvent(), @ref keyPressEvent(), @ref keyReleaseEvent(), @ref pointerPressEvent(),
@ref pointerPressEvent(), @ref pointerReleaseEvent(), @ref pointerReleaseEvent(), @ref pointerMoveEvent(), @ref scrollEvent()
@ref pointerMoveEvent(), @ref mouseScrollEvent()
*/ */
class EmscriptenApplication::InputEvent { class EmscriptenApplication::InputEvent {
public: public:
@ -1585,7 +1603,7 @@ class EmscriptenApplication::InputEvent {
* @see @ref Modifiers, @ref KeyEvent::modifiers(), * @see @ref Modifiers, @ref KeyEvent::modifiers(),
* @ref PointerEvent::modifiers(), * @ref PointerEvent::modifiers(),
* @ref PointerMoveEvent::modifiers(), * @ref PointerMoveEvent::modifiers(),
* @ref MouseScrollEvent::modifiers() * @ref ScrollEvent::modifiers()
*/ */
enum class Modifier: Int { enum class Modifier: Int {
/** /**
@ -1622,7 +1640,7 @@ class EmscriptenApplication::InputEvent {
* *
* @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(), * @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(),
* @ref PointerMoveEvent::modifiers(), * @ref PointerMoveEvent::modifiers(),
* @ref MouseScrollEvent::modifiers() * @ref ScrollEvent::modifiers()
*/ */
typedef Containers::EnumSet<Modifier> Modifiers; typedef Containers::EnumSet<Modifier> Modifiers;
@ -1665,7 +1683,7 @@ CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::InputEvent::Modifiers)
@brief Pointer event @brief Pointer event
@m_since_latest @m_since_latest
@see @ref PointerMoveEvent, @ref MouseScrollEvent, @ref pointerPressEvent(), @see @ref PointerMoveEvent, @ref ScrollEvent, @ref pointerPressEvent(),
@ref pointerReleaseEvent() @ref pointerReleaseEvent()
*/ */
class EmscriptenApplication::PointerEvent: public InputEvent { class EmscriptenApplication::PointerEvent: public InputEvent {
@ -1763,7 +1781,7 @@ class CORRADE_DEPRECATED("use PointerEvent, pointerPressEvent() and pointerRelea
@brief Pointer move event @brief Pointer move event
@m_since_latest @m_since_latest
@see @ref PointerEvent, @ref MouseScrollEvent, @ref pointerMoveEvent() @see @ref PointerEvent, @ref ScrollEvent, @ref pointerMoveEvent()
*/ */
class EmscriptenApplication::PointerMoveEvent: public InputEvent { class EmscriptenApplication::PointerMoveEvent: public InputEvent {
public: public:
@ -1902,12 +1920,47 @@ CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::MouseMoveEvent::Buttons)
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #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 @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: public:
/** @brief Scroll offset */ /** @brief Scroll offset */
Vector2 offset() const; Vector2 offset() const;
@ -1928,6 +1981,7 @@ class EmscriptenApplication::MouseScrollEvent: public EmscriptenApplication::Inp
const EmscriptenWheelEvent& _event; const EmscriptenWheelEvent& _event;
}; };
#endif
/** /**
@brief Key event @brief Key event

41
src/Magnum/Platform/GlfwApplication.cpp

@ -727,8 +727,8 @@ void GlfwApplication::setupCallbacks() {
app.pointerMoveEvent(e); app.pointerMoveEvent(e);
}); });
glfwSetScrollCallback(_window, [](GLFWwindow* window, double xoffset, double yoffset) { glfwSetScrollCallback(_window, [](GLFWwindow* window, double xoffset, double yoffset) {
MouseScrollEvent e(window, Vector2{Float(xoffset), Float(yoffset)}); ScrollEvent e{window, {Float(xoffset), Float(yoffset)}};
static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window))->mouseScrollEvent(e); static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window))->scrollEvent(e);
}); });
glfwSetCharCallback(_window, [](GLFWwindow* window, unsigned int codepoint) { glfwSetCharCallback(_window, [](GLFWwindow* window, unsigned int codepoint) {
auto& app = *static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window)); auto& app = *static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window));
@ -1072,7 +1072,23 @@ void GlfwApplication::mouseMoveEvent(MouseMoveEvent&) {}
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #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<void>(event);
#endif
}
#ifdef MAGNUM_BUILD_DEPRECATED
CORRADE_IGNORE_DEPRECATED_PUSH
void GlfwApplication::mouseScrollEvent(MouseScrollEvent&) {} void GlfwApplication::mouseScrollEvent(MouseScrollEvent&) {}
CORRADE_IGNORE_DEPRECATED_POP
#endif
void GlfwApplication::textInputEvent(TextInputEvent&) {} void GlfwApplication::textInputEvent(TextInputEvent&) {}
bool GlfwApplication::isTextInputActive() const { bool GlfwApplication::isTextInputActive() const {
@ -1153,6 +1169,21 @@ auto GlfwApplication::MouseMoveEvent::modifiers() -> Modifiers {
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #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() { Vector2i GlfwApplication::MouseScrollEvent::position() {
if(!_position) { if(!_position) {
Vector2d position; Vector2d position;
@ -1167,11 +1198,13 @@ auto GlfwApplication::MouseScrollEvent::modifiers() -> Modifiers {
if(!_modifiers) _modifiers = currentGlfwModifiers(_window); if(!_modifiers) _modifiers = currentGlfwModifiers(_window);
return *_modifiers; return *_modifiers;
} }
CORRADE_IGNORE_DEPRECATED_POP
#endif
/* On MSVC 2017, deprecation warning suppression doesn't work on virtual /* On MSVC 2017, deprecation warning suppression doesn't work on virtual
function overrides, so ScreenedApplication overriding mousePressEvent(), function overrides, so ScreenedApplication overriding mousePressEvent(),
mouseReleaseEvent(), and mouseMoveEvent() causes warnings. Disable them at a mouseReleaseEvent() mouseMoveEvent() and mouseScrollEvent() causes warnings.
higher level instead. */ Disable them at a higher level instead. */
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(CORRADE_TARGET_MSVC) && !defined(CORRADE_TARGET_CLANG) && _MSC_VER < 1920 #if defined(MAGNUM_BUILD_DEPRECATED) && defined(CORRADE_TARGET_MSVC) && !defined(CORRADE_TARGET_CLANG) && _MSC_VER < 1920
CORRADE_IGNORE_DEPRECATED_PUSH CORRADE_IGNORE_DEPRECATED_PUSH
#endif #endif

92
src/Magnum/Platform/GlfwApplication.h

@ -180,11 +180,12 @@ class GlfwApplication {
class KeyEvent; class KeyEvent;
class PointerEvent; class PointerEvent;
class PointerMoveEvent; class PointerMoveEvent;
class ScrollEvent;
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
class MouseEvent; class MouseEvent;
class MouseMoveEvent; class MouseMoveEvent;
#endif
class MouseScrollEvent; class MouseScrollEvent;
#endif
class TextInputEvent; class TextInputEvent;
/* The damn thing cannot handle forward enum declarations */ /* The damn thing cannot handle forward enum declarations */
@ -776,8 +777,30 @@ class GlfwApplication {
virtual CORRADE_DEPRECATED("use pointerMoveEvent() instead") void mouseMoveEvent(MouseMoveEvent& event); virtual CORRADE_DEPRECATED("use pointerMoveEvent() instead") void mouseMoveEvent(MouseMoveEvent& event);
#endif #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 /* Since 1.8.17, the original short-hand group closing doesn't work
anymore. FFS. */ anymore. FFS. */
@ -870,6 +893,7 @@ class GlfwApplication {
/* Calls the base pointer*Event() in order to delegate to deprecated /* Calls the base pointer*Event() in order to delegate to deprecated
mouse events */ mouse events */
template<class> friend class BasicScreenedApplication; template<class> friend class BasicScreenedApplication;
template<class, bool> friend struct Implementation::ApplicationScrollEventMixin;
#endif #endif
enum class Flag: UnsignedByte; enum class Flag: UnsignedByte;
@ -1696,10 +1720,9 @@ class GlfwApplication::ViewportEvent {
/** /**
@brief Base for input events @brief Base for input events
@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @ref ScrollEvent,
@ref MouseScrollEvent, @ref keyPressEvent(), @ref keyReleaseEvent(), @ref keyPressEvent(), @ref keyReleaseEvent(), @ref pointerPressEvent(),
@ref pointerPressEvent(), @ref pointerReleaseEvent(), @ref pointerReleaseEvent(), @ref pointerMoveEvent(), @ref scrollEvent()
@ref pointerMoveEvent(), @ref mouseScrollEvent()
*/ */
class GlfwApplication::InputEvent { class GlfwApplication::InputEvent {
public: public:
@ -1709,7 +1732,7 @@ class GlfwApplication::InputEvent {
* @see @ref Modifiers, @ref KeyEvent::modifiers(), * @see @ref Modifiers, @ref KeyEvent::modifiers(),
* @ref PointerEvent::modifiers(), * @ref PointerEvent::modifiers(),
* @ref PointerMoveEvent::modifiers(), * @ref PointerMoveEvent::modifiers(),
* @ref MouseScrollEvent::modifiers() * @ref ScrollEvent::modifiers()
*/ */
enum class Modifier: Int { enum class Modifier: Int {
/** /**
@ -1746,7 +1769,7 @@ class GlfwApplication::InputEvent {
* *
* @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(), * @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(),
* @ref PointerMoveEvent::modifiers(), * @ref PointerMoveEvent::modifiers(),
* @ref MouseScrollEvent::modifiers() * @ref ScrollEvent::modifiers()
*/ */
typedef Containers::EnumSet<Modifier> Modifiers; typedef Containers::EnumSet<Modifier> Modifiers;
@ -2092,7 +2115,7 @@ class GlfwApplication::KeyEvent: public GlfwApplication::InputEvent {
@brief Pointer event @brief Pointer event
@m_since_latest @m_since_latest
@see @ref PointerMoveEvent, @ref MouseScrollEvent, @ref pointerPressEvent(), @see @ref PointerMoveEvent, @ref ScrollEvent, @ref pointerPressEvent(),
@ref pointerReleaseEvent() @ref pointerReleaseEvent()
*/ */
class GlfwApplication::PointerEvent: public InputEvent { class GlfwApplication::PointerEvent: public InputEvent {
@ -2189,7 +2212,7 @@ class CORRADE_DEPRECATED("use PointerEvent, pointerPressEvent() and pointerRelea
@brief Pointer move event @brief Pointer move event
@m_since_latest @m_since_latest
@see @ref PointerEvent, @ref MouseScrollEvent, @ref pointerMoveEvent() @see @ref PointerEvent, @ref ScrollEvent, @ref pointerMoveEvent()
*/ */
class GlfwApplication::PointerMoveEvent: public InputEvent { class GlfwApplication::PointerMoveEvent: public InputEvent {
public: public:
@ -2339,12 +2362,54 @@ CORRADE_ENUMSET_OPERATORS(GlfwApplication::MouseMoveEvent::Buttons)
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #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<Vector2> _position;
Containers::Optional<Modifiers> _modifiers;
};
#ifdef MAGNUM_BUILD_DEPRECATED
/** /**
@brief Mouse scroll event @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: public:
/** @brief Scroll offset */ /** @brief Scroll offset */
Vector2 offset() const { return _offset; } Vector2 offset() const { return _offset; }
@ -2373,6 +2438,7 @@ class GlfwApplication::MouseScrollEvent: public GlfwApplication::InputEvent {
Containers::Optional<Vector2i> _position; Containers::Optional<Vector2i> _position;
Containers::Optional<Modifiers> _modifiers; Containers::Optional<Modifiers> _modifiers;
}; };
#endif
/** /**
@brief Text input event @brief Text input event

7
src/Magnum/Platform/Platform.h

@ -37,6 +37,13 @@ namespace Magnum { namespace Platform {
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
template<class> class BasicScreen; template<class> class BasicScreen;
template<class> class BasicScreenedApplication; template<class> class BasicScreenedApplication;
/* For ScreenedApplication backwards compatibility with mouseScrollEvent()
delegated from scrollEvent(), remove once gone */
#ifdef MAGNUM_BUILD_DEPRECATED
namespace Implementation {
template<class, bool> struct ApplicationScrollEventMixin;
}
#endif
#ifdef MAGNUM_TARGET_GL #ifdef MAGNUM_TARGET_GL
class GLContext; class GLContext;

55
src/Magnum/Platform/Screen.h

@ -62,16 +62,33 @@ template<class Application> class ScreenKeyEventMixin<Application, true> {
virtual void keyReleaseEvent(KeyEvent& event); virtual void keyReleaseEvent(KeyEvent& event);
}; };
template<class Application, bool> class ScreenScrollEventMixin {};
template<class Application> class ScreenScrollEventMixin<Application, true> {
public:
typedef typename BasicScreenedApplication<Application>::ScrollEvent ScrollEvent;
private:
friend ApplicationScrollEventMixin<Application, true>;
virtual void scrollEvent(ScrollEvent& event);
};
#ifdef MAGNUM_BUILD_DEPRECATED
template<class Application, bool> class ScreenMouseScrollEventMixin {}; template<class Application, bool> class ScreenMouseScrollEventMixin {};
template<class Application> class ScreenMouseScrollEventMixin<Application, true> { template<class Application> class ScreenMouseScrollEventMixin<Application, true> {
public: public:
typedef typename BasicScreenedApplication<Application>::MouseScrollEvent MouseScrollEvent; CORRADE_IGNORE_DEPRECATED_PUSH
typedef CORRADE_DEPRECATED("use ScrollEvent and scrollEvent() instead") typename BasicScreenedApplication<Application>::MouseScrollEvent MouseScrollEvent;
CORRADE_IGNORE_DEPRECATED_POP
private: private:
friend ApplicationMouseScrollEventMixin<Application, true>; friend ApplicationMouseScrollEventMixin<Application, true>;
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 Application, bool> class ScreenTextInputEventMixin {}; template<class Application, bool> class ScreenTextInputEventMixin {};
template<class Application> class ScreenTextInputEventMixin<Application, true> { template<class Application> class ScreenTextInputEventMixin<Application, true> {
@ -123,7 +140,10 @@ The following specialization are explicitly compiled into each particular
template<class Application> class BasicScreen: template<class Application> class BasicScreen:
private Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>, private Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>,
public Implementation::ScreenKeyEventMixin<Application, Implementation::HasKeyEvent<Application>::value>, public Implementation::ScreenKeyEventMixin<Application, Implementation::HasKeyEvent<Application>::value>,
public Implementation::ScreenScrollEventMixin<Application, Implementation::HasScrollEvent<Application>::value>,
#ifdef MAGNUM_BUILD_DEPRECATED
public Implementation::ScreenMouseScrollEventMixin<Application, Implementation::HasMouseScrollEvent<Application>::value>, public Implementation::ScreenMouseScrollEventMixin<Application, Implementation::HasMouseScrollEvent<Application>::value>,
#endif
public Implementation::ScreenTextInputEventMixin<Application, Implementation::HasTextInputEvent<Application>::value>, public Implementation::ScreenTextInputEventMixin<Application, Implementation::HasTextInputEvent<Application>::value>,
public Implementation::ScreenTextEditingEventMixin<Application, Implementation::HasTextEditingEvent<Application>::value> public Implementation::ScreenTextEditingEventMixin<Application, Implementation::HasTextEditingEvent<Application>::value>
{ {
@ -229,14 +249,27 @@ template<class Application> class BasicScreen:
#endif #endif
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
/**
* @brief Scroll event
* @m_since_latest
*
* Defined only if the application has a
* @relativeref{Sdl2Application,ScrollEvent}.
*/
typedef typename BasicScreenedApplication<Application>::ScrollEvent ScrollEvent;
#ifdef MAGNUM_BUILD_DEPRECATED
/** /**
* @brief Mouse scroll event * @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 * Defined only if the application has a
* @ref Sdl2Application::MouseScrollEvent "MouseScrollEvent". * @ref Sdl2Application::MouseScrollEvent "MouseScrollEvent".
*/ */
typedef typename BasicScreenedApplication<Application>::MouseScrollEvent MouseScrollEvent; typedef typename BasicScreenedApplication<Application>::MouseScrollEvent MouseScrollEvent;
#endif
/** /**
* @brief Text input event * @brief Text input event
@ -522,9 +555,22 @@ template<class Application> class BasicScreen:
#endif #endif
#ifdef DOXYGEN_GENERATING_OUTPUT #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 * @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 * Called when @ref PropagatedEvent::Input is enabled and mouse wheel
* is rotated. See @ref Sdl2Application::mouseScrollEvent() "*Application::mouseScrollEvent()" * is rotated. See @ref Sdl2Application::mouseScrollEvent() "*Application::mouseScrollEvent()"
@ -533,6 +579,7 @@ template<class Application> class BasicScreen:
*/ */
virtual void mouseScrollEvent(MouseScrollEvent& event); virtual void mouseScrollEvent(MouseScrollEvent& event);
#endif #endif
#endif
/* Since 1.8.17, the original short-hand group closing doesn't work /* Since 1.8.17, the original short-hand group closing doesn't work
anymore. FFS. */ anymore. FFS. */

33
src/Magnum/Platform/ScreenedApplication.h

@ -41,7 +41,10 @@ namespace Magnum { namespace Platform {
namespace Implementation { namespace Implementation {
CORRADE_HAS_TYPE(HasKeyEvent, typename T::KeyEvent); 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); CORRADE_HAS_TYPE(HasMouseScrollEvent, typename T::MouseScrollEvent);
#endif
CORRADE_HAS_TYPE(HasTextInputEvent, typename T::TextInputEvent); CORRADE_HAS_TYPE(HasTextInputEvent, typename T::TextInputEvent);
CORRADE_HAS_TYPE(HasTextEditingEvent, typename T::TextEditingEvent); CORRADE_HAS_TYPE(HasTextEditingEvent, typename T::TextEditingEvent);
@ -60,9 +63,22 @@ template<class Application> struct ApplicationKeyEventMixin<Application, true> {
void callKeyReleaseEvent(typename Application::KeyEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens); void callKeyReleaseEvent(typename Application::KeyEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens);
}; };
/* Calls into the screen in case the application has a mouseScrollEvent(), /* Calls into the screen in case the application has a scrollEvent(), otherwise
otherwise provides a dummy virtual so the application can unconditionally provides a dummy virtual so the application can unconditionally override */
override */ template<class Application, bool implements> struct ApplicationScrollEventMixin {
typedef int ScrollEvent;
virtual void scrollEvent(ScrollEvent&) = 0;
void callScrollEvent(Application&, ScrollEvent&, Containers::LinkedList<BasicScreen<Application>>&);
};
template<class Application> struct ApplicationScrollEventMixin<Application, true> {
void callScrollEvent(Application& application, typename Application::ScrollEvent& event, Containers::LinkedList<BasicScreen<Application>>& 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<class Application, bool> struct ApplicationMouseScrollEventMixin { template<class Application, bool> struct ApplicationMouseScrollEventMixin {
typedef int MouseScrollEvent; typedef int MouseScrollEvent;
virtual void mouseScrollEvent(MouseScrollEvent&) = 0; virtual void mouseScrollEvent(MouseScrollEvent&) = 0;
@ -70,8 +86,11 @@ template<class Application, bool> struct ApplicationMouseScrollEventMixin {
void callMouseScrollEvent(MouseScrollEvent&, Containers::LinkedList<BasicScreen<Application>>&); void callMouseScrollEvent(MouseScrollEvent&, Containers::LinkedList<BasicScreen<Application>>&);
}; };
template<class Application> struct ApplicationMouseScrollEventMixin<Application, true> { template<class Application> struct ApplicationMouseScrollEventMixin<Application, true> {
CORRADE_IGNORE_DEPRECATED_PUSH
void callMouseScrollEvent(typename Application::MouseScrollEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens); void callMouseScrollEvent(typename Application::MouseScrollEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens);
CORRADE_IGNORE_DEPRECATED_POP
}; };
#endif
/* Calls into the screen in case the application has a textInputEvent(), /* Calls into the screen in case the application has a textInputEvent(),
otherwise provides a dummy virtual so the application can unconditionally otherwise provides a dummy virtual so the application can unconditionally
@ -175,7 +194,10 @@ template<class Application> class BasicScreenedApplication:
public Application, public Application,
private Containers::LinkedList<BasicScreen<Application>>, private Containers::LinkedList<BasicScreen<Application>>,
private Implementation::ApplicationKeyEventMixin<Application, Implementation::HasKeyEvent<Application>::value>, private Implementation::ApplicationKeyEventMixin<Application, Implementation::HasKeyEvent<Application>::value>,
private Implementation::ApplicationScrollEventMixin<Application, Implementation::HasScrollEvent<Application>::value>,
#ifdef MAGNUM_BUILD_DEPRECATED
private Implementation::ApplicationMouseScrollEventMixin<Application, Implementation::HasMouseScrollEvent<Application>::value>, private Implementation::ApplicationMouseScrollEventMixin<Application, Implementation::HasMouseScrollEvent<Application>::value>,
#endif
private Implementation::ApplicationTextInputEventMixin<Application, Implementation::HasTextInputEvent<Application>::value>, private Implementation::ApplicationTextInputEventMixin<Application, Implementation::HasTextInputEvent<Application>::value>,
private Implementation::ApplicationTextEditingEventMixin<Application, Implementation::HasTextEditingEvent<Application>::value> private Implementation::ApplicationTextEditingEventMixin<Application, Implementation::HasTextEditingEvent<Application>::value>
{ {
@ -339,7 +361,12 @@ template<class Application> class BasicScreenedApplication:
doesn't have them, they're overriding a mixin dummy */ doesn't have them, they're overriding a mixin dummy */
void keyPressEvent(typename BasicScreenedApplication<Application>::KeyEvent& event) override final; void keyPressEvent(typename BasicScreenedApplication<Application>::KeyEvent& event) override final;
void keyReleaseEvent(typename BasicScreenedApplication<Application>::KeyEvent& event) override final; void keyReleaseEvent(typename BasicScreenedApplication<Application>::KeyEvent& event) override final;
void scrollEvent(typename BasicScreenedApplication<Application>::ScrollEvent& event) override final;
#ifdef MAGNUM_BUILD_DEPRECATED
CORRADE_IGNORE_DEPRECATED_PUSH
void mouseScrollEvent(typename BasicScreenedApplication<Application>::MouseScrollEvent& event) override final; void mouseScrollEvent(typename BasicScreenedApplication<Application>::MouseScrollEvent& event) override final;
CORRADE_IGNORE_DEPRECATED_POP
#endif
void textInputEvent(typename BasicScreenedApplication<Application>::TextInputEvent& event) override final; void textInputEvent(typename BasicScreenedApplication<Application>::TextInputEvent& event) override final;
void textEditingEvent(typename BasicScreenedApplication<Application>::TextEditingEvent& event) override final; void textEditingEvent(typename BasicScreenedApplication<Application>::TextEditingEvent& event) override final;
}; };

54
src/Magnum/Platform/ScreenedApplication.hpp

@ -59,6 +59,30 @@ template<class Application> void ApplicationKeyEventMixin<Application, true>::ca
} }
} }
template<class Application, bool implements> void ApplicationScrollEventMixin<Application, implements>::callScrollEvent(Application&, ScrollEvent&, Containers::LinkedList<BasicScreen<Application>>&) {}
template<class Application> void ApplicationScrollEventMixin<Application, true>::callScrollEvent(Application& application, typename Application::ScrollEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens) {
/* Front-to-back event propagation, stop when the event gets accepted */
for(BasicScreen<Application>* 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<void>(application);
#endif
}
#ifdef MAGNUM_BUILD_DEPRECATED
CORRADE_IGNORE_DEPRECATED_PUSH
template<class Application, bool implements> void ApplicationMouseScrollEventMixin<Application, implements>::callMouseScrollEvent(MouseScrollEvent&, Containers::LinkedList<BasicScreen<Application>>&) {} template<class Application, bool implements> void ApplicationMouseScrollEventMixin<Application, implements>::callMouseScrollEvent(MouseScrollEvent&, Containers::LinkedList<BasicScreen<Application>>&) {}
template<class Application> void ApplicationMouseScrollEventMixin<Application, true>::callMouseScrollEvent(typename Application::MouseScrollEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens) { template<class Application> void ApplicationMouseScrollEventMixin<Application, true>::callMouseScrollEvent(typename Application::MouseScrollEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens) {
/* Front-to-back event propagation, stop when the event gets accepted */ /* Front-to-back event propagation, stop when the event gets accepted */
@ -69,6 +93,8 @@ template<class Application> void ApplicationMouseScrollEventMixin<Application, t
} }
} }
} }
CORRADE_IGNORE_DEPRECATED_POP
#endif
template<class Application, bool implements> void ApplicationTextInputEventMixin<Application, implements>::callTextInputEvent(TextInputEvent&, Containers::LinkedList<BasicScreen<Application>>&) {} template<class Application, bool implements> void ApplicationTextInputEventMixin<Application, implements>::callTextInputEvent(TextInputEvent&, Containers::LinkedList<BasicScreen<Application>>&) {}
template<class Application> void ApplicationTextInputEventMixin<Application, true>::callTextInputEvent(typename Application::TextInputEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens) { template<class Application> void ApplicationTextInputEventMixin<Application, true>::callTextInputEvent(typename Application::TextInputEvent& event, Containers::LinkedList<BasicScreen<Application>>& screens) {
@ -93,16 +119,16 @@ true>::callTextEditingEvent(typename Application::TextEditingEvent& event, Conta
} }
} }
template<class Application> void ScreenKeyEventMixin<Application, template<class Application> void ScreenKeyEventMixin<Application, true>::keyPressEvent(KeyEvent&) {}
true>::keyPressEvent(KeyEvent&) {} template<class Application> void ScreenKeyEventMixin<Application, true>::keyReleaseEvent(KeyEvent&) {}
template<class Application> void ScreenKeyEventMixin<Application, template<class Application> void ScreenScrollEventMixin<Application, true>::scrollEvent(ScrollEvent&) {}
true>::keyReleaseEvent(KeyEvent&) {} #ifdef MAGNUM_BUILD_DEPRECATED
template<class Application> void ScreenMouseScrollEventMixin<Application, CORRADE_IGNORE_DEPRECATED_PUSH
true>::mouseScrollEvent(MouseScrollEvent&) {} template<class Application> void ScreenMouseScrollEventMixin<Application, true>::mouseScrollEvent(MouseScrollEvent&) {}
template<class Application> void ScreenTextInputEventMixin<Application, CORRADE_IGNORE_DEPRECATED_POP
true>::textInputEvent(TextInputEvent&) {} #endif
template<class Application> void ScreenTextEditingEventMixin<Application, template<class Application> void ScreenTextInputEventMixin<Application, true>::textInputEvent(TextInputEvent&) {}
true>::textEditingEvent(TextEditingEvent&) {} template<class Application> void ScreenTextEditingEventMixin<Application, true>::textEditingEvent(TextEditingEvent&) {}
} }
@ -324,9 +350,17 @@ template<class Application> void BasicScreenedApplication<Application>::mouseMov
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #endif
template<class Application> void BasicScreenedApplication<Application>::scrollEvent(typename BasicScreenedApplication<Application>::ScrollEvent& event) {
this->callScrollEvent(*this, event, screens());
}
#ifdef MAGNUM_BUILD_DEPRECATED
CORRADE_IGNORE_DEPRECATED_PUSH
template<class Application> void BasicScreenedApplication<Application>::mouseScrollEvent(typename BasicScreenedApplication<Application>::MouseScrollEvent& event) { template<class Application> void BasicScreenedApplication<Application>::mouseScrollEvent(typename BasicScreenedApplication<Application>::MouseScrollEvent& event) {
this->callMouseScrollEvent(event, screens()); this->callMouseScrollEvent(event, screens());
} }
CORRADE_IGNORE_DEPRECATED_POP
#endif
template<class Application> void BasicScreenedApplication<Application>::textInputEvent(typename BasicScreenedApplication<Application>::TextInputEvent& event) { template<class Application> void BasicScreenedApplication<Application>::textInputEvent(typename BasicScreenedApplication<Application>::TextInputEvent& event) {
this->callTextInputEvent(event, screens()); this->callTextInputEvent(event, screens());

44
src/Magnum/Platform/Sdl2Application.cpp

@ -1042,8 +1042,8 @@ bool Sdl2Application::mainLoopIteration() {
} break; } break;
case SDL_MOUSEWHEEL: { case SDL_MOUSEWHEEL: {
MouseScrollEvent e{event, {Float(event.wheel.x), Float(event.wheel.y)}}; ScrollEvent e{event, {Float(event.wheel.x), Float(event.wheel.y)}};
mouseScrollEvent(e); scrollEvent(e);
} break; } break;
case SDL_MOUSEMOTION: { case SDL_MOUSEMOTION: {
@ -1401,7 +1401,23 @@ void Sdl2Application::mouseMoveEvent(MouseMoveEvent&) {}
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #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<void>(event);
#endif
}
#ifdef MAGNUM_BUILD_DEPRECATED
CORRADE_IGNORE_DEPRECATED_PUSH
void Sdl2Application::mouseScrollEvent(MouseScrollEvent&) {} void Sdl2Application::mouseScrollEvent(MouseScrollEvent&) {}
CORRADE_IGNORE_DEPRECATED_POP
#endif
void Sdl2Application::multiGestureEvent(MultiGestureEvent&) {} void Sdl2Application::multiGestureEvent(MultiGestureEvent&) {}
void Sdl2Application::textInputEvent(TextInputEvent&) {} void Sdl2Application::textInputEvent(TextInputEvent&) {}
void Sdl2Application::textEditingEvent(TextEditingEvent&) {} void Sdl2Application::textEditingEvent(TextEditingEvent&) {}
@ -1473,6 +1489,23 @@ Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseMoveEvent::modifier
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #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() { Vector2i Sdl2Application::MouseScrollEvent::position() {
if(_position) return *_position; if(_position) return *_position;
_position = Vector2i{}; _position = Vector2i{};
@ -1484,12 +1517,15 @@ Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseScrollEvent::modifi
if(_modifiers) return *_modifiers; if(_modifiers) return *_modifiers;
return *(_modifiers = fixedModifiers(Uint16(SDL_GetModState()))); return *(_modifiers = fixedModifiers(Uint16(SDL_GetModState())));
} }
CORRADE_IGNORE_DEPRECATED_POP
#endif
/* WinRT builds by default have deprecation warnings as errors. Combined with a /* WinRT builds by default have deprecation warnings as errors. Combined with a
MSVC 2017 bug where deprecation warning suppression doesn't work on virtual MSVC 2017 bug where deprecation warning suppression doesn't work on virtual
function overrides this make the build fail on deprecation warnings due to function overrides this make the build fail on deprecation warnings due to
ScreenedApplication overriding mousePressEvent(), mouseReleaseEvent() and ScreenedApplication overriding mousePressEvent(), mouseReleaseEvent(),
mouseMoveEvent(). Disable the warnings at a higher level instead. */ 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 #if defined(MAGNUM_BUILD_DEPRECATED) && defined(CORRADE_TARGET_MSVC) && !defined(CORRADE_TARGET_CLANG) && _MSC_VER < 1920
CORRADE_IGNORE_DEPRECATED_PUSH CORRADE_IGNORE_DEPRECATED_PUSH
#endif #endif

84
src/Magnum/Platform/Sdl2Application.h

@ -502,11 +502,12 @@ class Sdl2Application {
class KeyEvent; class KeyEvent;
class PointerEvent; class PointerEvent;
class PointerMoveEvent; class PointerMoveEvent;
class ScrollEvent;
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
class MouseEvent; class MouseEvent;
class MouseMoveEvent; class MouseMoveEvent;
#endif
class MouseScrollEvent; class MouseScrollEvent;
#endif
class MultiGestureEvent; class MultiGestureEvent;
class TextInputEvent; class TextInputEvent;
class TextEditingEvent; class TextEditingEvent;
@ -1184,12 +1185,29 @@ class Sdl2Application {
#endif #endif
/** /**
* @brief Mouse scroll event * @brief Scroll event
* @m_since_latest
* *
* Called when a scrolling device is used (mouse wheel or scrolling * 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 * @brief Multi gesture event
@ -1327,6 +1345,7 @@ class Sdl2Application {
/* Calls the base pointer*Event() in order to delegate to deprecated /* Calls the base pointer*Event() in order to delegate to deprecated
mouse events */ mouse events */
template<class> friend class BasicScreenedApplication; template<class> friend class BasicScreenedApplication;
template<class, bool> friend struct Implementation::ApplicationScrollEventMixin;
#endif #endif
enum class Flag: UnsignedByte; enum class Flag: UnsignedByte;
@ -2259,10 +2278,9 @@ class Sdl2Application::ViewportEvent {
/** /**
@brief Base for input events @brief Base for input events
@see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @see @ref KeyEvent, @ref PointerEvent, @ref PointerMoveEvent, @ref ScrollEvent,
@ref MouseScrollEvent, @ref keyPressEvent(), @ref keyReleaseEvent(), @ref keyPressEvent(), @ref keyReleaseEvent(), @ref pointerPressEvent(),
@ref pointerPressEvent(), @ref pointerReleaseEvent(), @ref pointerReleaseEvent(), @ref pointerMoveEvent(), @ref scrollEvent()
@ref pointerMoveEvent(), @ref mouseScrollEvent()
*/ */
class Sdl2Application::InputEvent { class Sdl2Application::InputEvent {
public: public:
@ -2272,7 +2290,7 @@ class Sdl2Application::InputEvent {
* @see @ref Modifiers, @ref KeyEvent::modifiers(), * @see @ref Modifiers, @ref KeyEvent::modifiers(),
* @ref PointerEvent::modifiers(), * @ref PointerEvent::modifiers(),
* @ref PointerMoveEvent::modifiers(), * @ref PointerMoveEvent::modifiers(),
* @ref MouseScrollEvent::modifiers() * @ref ScrollEvent::modifiers()
*/ */
enum class Modifier: Uint16 { enum class Modifier: Uint16 {
/** /**
@ -2331,7 +2349,7 @@ class Sdl2Application::InputEvent {
* *
* @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(), * @see @ref KeyEvent::modifiers(), @ref PointerEvent::modifiers(),
* @ref PointerMoveEvent::modifiers(), * @ref PointerMoveEvent::modifiers(),
* @ref MouseScrollEvent::modifiers() * @ref ScrollEvent::modifiers()
*/ */
typedef Containers::EnumSet<Modifier> Modifiers; typedef Containers::EnumSet<Modifier> Modifiers;
@ -2366,7 +2384,7 @@ class Sdl2Application::InputEvent {
* Of type `SDL_KEYDOWN` / `SDL_KEYUP` for @ref KeyEvent, * Of type `SDL_KEYDOWN` / `SDL_KEYUP` for @ref KeyEvent,
* `SDL_MOUSEBUTTONDOWN` / `SDL_MOUSEBUTTONUP` for @ref PointerEvent, * `SDL_MOUSEBUTTONDOWN` / `SDL_MOUSEBUTTONUP` for @ref PointerEvent,
* `SDL_MOUSEMOTION` for @ref PointerMoveEvent and `SDL_MOUSEWHEEL` for * `SDL_MOUSEMOTION` for @ref PointerMoveEvent and `SDL_MOUSEWHEEL` for
* @ref MouseScrollEvent. * @ref ScrollEvent.
* @see @ref Sdl2Application::anyEvent() * @see @ref Sdl2Application::anyEvent()
*/ */
const SDL_Event& event() const { return _event; } const SDL_Event& event() const { return _event; }
@ -2990,12 +3008,51 @@ CORRADE_ENUMSET_OPERATORS(Sdl2Application::MouseMoveEvent::Buttons)
CORRADE_IGNORE_DEPRECATED_POP CORRADE_IGNORE_DEPRECATED_POP
#endif #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<Vector2> _position;
Containers::Optional<Modifiers> _modifiers;
};
#ifdef MAGNUM_BUILD_DEPRECATED
/** /**
@brief Mouse scroll event @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: public:
/** @brief Scroll offset */ /** @brief Scroll offset */
Vector2 offset() const { return _offset; } Vector2 offset() const { return _offset; }
@ -3023,6 +3080,7 @@ class Sdl2Application::MouseScrollEvent: public Sdl2Application::InputEvent {
Containers::Optional<Vector2i> _position; Containers::Optional<Vector2i> _position;
Containers::Optional<Modifiers> _modifiers; Containers::Optional<Modifiers> _modifiers;
}; };
#endif
/** /**
@brief Multi gesture event @brief Multi gesture event

4
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 */ /* Comment out to test the deprecated scroll as press/release reporting */
#if 1 #if 1
void mouseScrollEvent(MouseScrollEvent& event) override { void scrollEvent(ScrollEvent& event) override {
Debug{} << "mouse scroll:" << event.pointers() << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); Debug{} << "scroll:" << event.pointers() << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position();
} }
#endif #endif

8
src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp

@ -299,6 +299,9 @@ struct EmscriptenApplicationTest: Platform::Application {
void pointerMoveEvent(PointerMoveEvent& event) override { void pointerMoveEvent(PointerMoveEvent& event) override {
Debug{} << "pointer move:" << event.pointer() << event.pointers() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); 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 #else
CORRADE_IGNORE_DEPRECATED_PUSH CORRADE_IGNORE_DEPRECATED_PUSH
void mousePressEvent(MouseEvent& event) override { void mousePressEvent(MouseEvent& event) override {
@ -310,12 +313,11 @@ struct EmscriptenApplicationTest: Platform::Application {
void mouseMoveEvent(MouseMoveEvent& event) override { void mouseMoveEvent(MouseMoveEvent& event) override {
Debug{} << "mouse move:" << event.buttons() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); 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 { void mouseScrollEvent(MouseScrollEvent& event) override {
Debug{} << "mouse scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); Debug{} << "mouse scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position();
} }
CORRADE_IGNORE_DEPRECATED_POP
#endif
/* For testing keyboard capture */ /* For testing keyboard capture */
void keyPressEvent(KeyEvent& event) override { void keyPressEvent(KeyEvent& event) override {

8
src/Magnum/Platform/Test/GlfwApplicationTest.cpp

@ -363,6 +363,9 @@ struct GlfwApplicationTest: Platform::Application {
void pointerMoveEvent(PointerMoveEvent& event) override { void pointerMoveEvent(PointerMoveEvent& event) override {
Debug{} << "pointer move:" << event.pointer() << event.pointers() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); 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 #else
CORRADE_IGNORE_DEPRECATED_PUSH CORRADE_IGNORE_DEPRECATED_PUSH
void mousePressEvent(MouseEvent& event) override { void mousePressEvent(MouseEvent& event) override {
@ -374,12 +377,11 @@ struct GlfwApplicationTest: Platform::Application {
void mouseMoveEvent(MouseMoveEvent& event) override { void mouseMoveEvent(MouseMoveEvent& event) override {
Debug{} << "mouse move:" << event.buttons() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); 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 { void mouseScrollEvent(MouseScrollEvent& event) override {
Debug{} << "mouse scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); Debug{} << "mouse scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position();
} }
CORRADE_IGNORE_DEPRECATED_POP
#endif
void textInputEvent(TextInputEvent& event) override { void textInputEvent(TextInputEvent& event) override {
Debug{} << "text input:" << event.text(); Debug{} << "text input:" << event.text();

8
src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp

@ -334,6 +334,9 @@ struct Sdl2ApplicationTest: Platform::Application {
void pointerMoveEvent(PointerMoveEvent& event) override { void pointerMoveEvent(PointerMoveEvent& event) override {
Debug{} << "pointer move:" << event.pointer() << event.pointers() << event.modifiers() << Debug::packed << event.position() << Debug::packed << event.relativePosition(); 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 #else
CORRADE_IGNORE_DEPRECATED_PUSH CORRADE_IGNORE_DEPRECATED_PUSH
void mousePressEvent(MouseEvent& event) override { void mousePressEvent(MouseEvent& event) override {
@ -349,12 +352,11 @@ struct Sdl2ApplicationTest: Platform::Application {
void mouseMoveEvent(MouseMoveEvent& event) override { void mouseMoveEvent(MouseMoveEvent& event) override {
Debug{} << "mouse move:" << event.buttons() << Debug::packed << event.position() << Debug::packed << event.relativePosition() << event.modifiers(); 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 { void mouseScrollEvent(MouseScrollEvent& event) override {
Debug{} << "mouse scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position(); Debug{} << "mouse scroll:" << event.modifiers() << Debug::packed << event.offset() << Debug::packed << event.position();
} }
CORRADE_IGNORE_DEPRECATED_POP
#endif
void multiGestureEvent(MultiGestureEvent& event) override { 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(); 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();

Loading…
Cancel
Save