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
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,

12
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);
}

49
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<Pointer> 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<class> friend class BasicScreenedApplication;
template<class, bool> 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;
};
}}

2
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<class> friend class BasicScreenedApplication;
/* Not ApplicationScrollEventMixin, as this class doesn't have the
deprecated mouseScrollEvent() */
#endif
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,
([](int, const EmscriptenWheelEvent* event, void* userData) -> EM_BOOL {
MouseScrollEvent e{*event};
static_cast<EmscriptenApplication*>(userData)->mouseScrollEvent(e);
ScrollEvent e{*event};
static_cast<EmscriptenApplication*>(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<void>(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);

82
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<class> friend class BasicScreenedApplication;
template<class, bool> 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<Modifier> 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

41
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<GlfwApplication*>(glfwGetWindowUserPointer(window))->mouseScrollEvent(e);
ScrollEvent e{window, {Float(xoffset), Float(yoffset)}};
static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window))->scrollEvent(e);
});
glfwSetCharCallback(_window, [](GLFWwindow* window, unsigned int codepoint) {
auto& app = *static_cast<GlfwApplication*>(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<void>(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

92
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<class> friend class BasicScreenedApplication;
template<class, bool> 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<Modifier> 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<Vector2> _position;
Containers::Optional<Modifiers> _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<Vector2i> _position;
Containers::Optional<Modifiers> _modifiers;
};
#endif
/**
@brief Text input event

7
src/Magnum/Platform/Platform.h

@ -37,6 +37,13 @@ namespace Magnum { namespace Platform {
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class> class BasicScreen;
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
class GLContext;

55
src/Magnum/Platform/Screen.h

@ -62,16 +62,33 @@ template<class Application> class ScreenKeyEventMixin<Application, true> {
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> class ScreenMouseScrollEventMixin<Application, true> {
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:
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> class ScreenTextInputEventMixin<Application, true> {
@ -123,7 +140,10 @@ The following specialization are explicitly compiled into each particular
template<class Application> class BasicScreen:
private Containers::LinkedListItem<BasicScreen<Application>, BasicScreenedApplication<Application>>,
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>,
#endif
public Implementation::ScreenTextInputEventMixin<Application, Implementation::HasTextInputEvent<Application>::value>,
public Implementation::ScreenTextEditingEventMixin<Application, Implementation::HasTextEditingEvent<Application>::value>
{
@ -229,14 +249,27 @@ template<class Application> 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<Application>::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<Application>::MouseScrollEvent MouseScrollEvent;
#endif
/**
* @brief Text input event
@ -522,9 +555,22 @@ template<class Application> 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 Application> class BasicScreen:
*/
virtual void mouseScrollEvent(MouseScrollEvent& event);
#endif
#endif
/* Since 1.8.17, the original short-hand group closing doesn't work
anymore. FFS. */

33
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<class Application> struct ApplicationKeyEventMixin<Application, true> {
void callKeyReleaseEvent(typename Application::KeyEvent& event, Containers::LinkedList<BasicScreen<Application>>& 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<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 {
typedef int MouseScrollEvent;
virtual void mouseScrollEvent(MouseScrollEvent&) = 0;
@ -70,8 +86,11 @@ template<class Application, bool> struct ApplicationMouseScrollEventMixin {
void callMouseScrollEvent(MouseScrollEvent&, Containers::LinkedList<BasicScreen<Application>>&);
};
template<class Application> struct ApplicationMouseScrollEventMixin<Application, true> {
CORRADE_IGNORE_DEPRECATED_PUSH
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(),
otherwise provides a dummy virtual so the application can unconditionally
@ -175,7 +194,10 @@ template<class Application> class BasicScreenedApplication:
public Application,
private Containers::LinkedList<BasicScreen<Application>>,
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>,
#endif
private Implementation::ApplicationTextInputEventMixin<Application, Implementation::HasTextInputEvent<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 */
void keyPressEvent(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;
CORRADE_IGNORE_DEPRECATED_POP
#endif
void textInputEvent(typename BasicScreenedApplication<Application>::TextInputEvent& 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> 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 */
@ -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> 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,
true>::keyPressEvent(KeyEvent&) {}
template<class Application> void ScreenKeyEventMixin<Application,
true>::keyReleaseEvent(KeyEvent&) {}
template<class Application> void ScreenMouseScrollEventMixin<Application,
true>::mouseScrollEvent(MouseScrollEvent&) {}
template<class Application> void ScreenTextInputEventMixin<Application,
true>::textInputEvent(TextInputEvent&) {}
template<class Application> void ScreenTextEditingEventMixin<Application,
true>::textEditingEvent(TextEditingEvent&) {}
template<class Application> void ScreenKeyEventMixin<Application, true>::keyPressEvent(KeyEvent&) {}
template<class Application> void ScreenKeyEventMixin<Application, true>::keyReleaseEvent(KeyEvent&) {}
template<class Application> void ScreenScrollEventMixin<Application, true>::scrollEvent(ScrollEvent&) {}
#ifdef MAGNUM_BUILD_DEPRECATED
CORRADE_IGNORE_DEPRECATED_PUSH
template<class Application> void ScreenMouseScrollEventMixin<Application, true>::mouseScrollEvent(MouseScrollEvent&) {}
CORRADE_IGNORE_DEPRECATED_POP
#endif
template<class Application> void ScreenTextInputEventMixin<Application, true>::textInputEvent(TextInputEvent&) {}
template<class Application> void ScreenTextEditingEventMixin<Application, true>::textEditingEvent(TextEditingEvent&) {}
}
@ -324,9 +350,17 @@ template<class Application> void BasicScreenedApplication<Application>::mouseMov
CORRADE_IGNORE_DEPRECATED_POP
#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) {
this->callMouseScrollEvent(event, screens());
}
CORRADE_IGNORE_DEPRECATED_POP
#endif
template<class Application> void BasicScreenedApplication<Application>::textInputEvent(typename BasicScreenedApplication<Application>::TextInputEvent& event) {
this->callTextInputEvent(event, screens());

44
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<void>(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

84
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<class> friend class BasicScreenedApplication;
template<class, bool> 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<Modifier> 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<Vector2> _position;
Containers::Optional<Modifiers> _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<Vector2i> _position;
Containers::Optional<Modifiers> _modifiers;
};
#endif
/**
@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 */
#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

8
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 {

8
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();

8
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();

Loading…
Cancel
Save