Browse Source

Platform: add MouseMoveEvent::relativePosition() to Glfw and Emscripten.

These toolkits don't support it, but I got really annoyed and so the
apps are emulating it.
pull/364/head
Vladimír Vondruš 7 years ago
parent
commit
89d4a754d5
  1. 5
      doc/changelog.dox
  2. 9
      src/Magnum/Platform/EmscriptenApplication.cpp
  3. 15
      src/Magnum/Platform/EmscriptenApplication.h
  4. 11
      src/Magnum/Platform/GlfwApplication.cpp
  5. 18
      src/Magnum/Platform/GlfwApplication.h
  6. 2
      src/Magnum/Platform/Sdl2Application.h
  7. 2
      src/Magnum/Platform/Test/EmscriptenApplicationTest.cpp
  8. 4
      src/Magnum/Platform/Test/GlfwApplicationTest.cpp
  9. 2
      src/Magnum/Platform/Test/Sdl2ApplicationTest.cpp

5
doc/changelog.dox

@ -375,6 +375,11 @@ See also:
@ref Platform::GlfwApplication::exit() now have an optional parameter to @ref Platform::GlfwApplication::exit() now have an optional parameter to
specify the actual application return code (see specify the actual application return code (see
[mosra/magnum#332](https://github.com/mosra/magnum/pull/332)) [mosra/magnum#332](https://github.com/mosra/magnum/pull/332))
- @ref Platform::GlfwApplication and @ref Platform::EmscriptenApplication now
implement @ref Platform::GlfwApplication::MouseMoveEvent::relativePosition()
as well for better compatibility with @ref Platform::Sdl2Application. The
relative position is not supplied by the underlying toolkits, so it's
emulated on the application side.
- Extended @ref Platform::BasicScreen with - Extended @ref Platform::BasicScreen with
@ref Platform::BasicScreen::mouseScrollEvent() "mouseScrollEvent()", @ref Platform::BasicScreen::mouseScrollEvent() "mouseScrollEvent()",
@ref Platform::BasicScreen::textInputEvent() "textInputEvent()" and @ref Platform::BasicScreen::textInputEvent() "textInputEvent()" and

9
src/Magnum/Platform/EmscriptenApplication.cpp

@ -470,7 +470,14 @@ void EmscriptenApplication::setupCallbacks(bool resizable) {
emscripten_set_mousemove_callback("#canvas", this, false, emscripten_set_mousemove_callback("#canvas", this, false,
([](int, const EmscriptenMouseEvent* event, void* userData) -> Int { ([](int, const EmscriptenMouseEvent* event, void* userData) -> Int {
MouseMoveEvent e{*event}; auto& app = *static_cast<EmscriptenApplication*>(userData);
/* Avoid bogus offset at first -- report 0 when the event is called
for the first time */
Vector2i position{Int(event->canvasX), Int(event->canvasY)};
MouseMoveEvent e{*event,
app._previousMouseMovePosition == Vector2i{-1} ? Vector2i{} :
position - app._previousMouseMovePosition};
app._previousMouseMovePosition = position;
static_cast<EmscriptenApplication*>(userData)->mouseMoveEvent(e); static_cast<EmscriptenApplication*>(userData)->mouseMoveEvent(e);
return e.isAccepted(); return e.isAccepted();
})); }));

15
src/Magnum/Platform/EmscriptenApplication.h

@ -639,7 +639,7 @@ class EmscriptenApplication {
void setupAnimationFrame(bool ForceAnimationFrame); void setupAnimationFrame(bool ForceAnimationFrame);
Vector2 _devicePixelRatio, _dpiScaling; Vector2 _devicePixelRatio, _dpiScaling;
Vector2i _lastKnownCanvasSize; Vector2i _lastKnownCanvasSize, _previousMouseMovePosition{-1};
Flags _flags; Flags _flags;
@ -1251,6 +1251,16 @@ class EmscriptenApplication::MouseMoveEvent: public EmscriptenApplication::Input
/** @brief Position */ /** @brief Position */
Vector2i position() const; Vector2i position() const;
/**
* @brief Relative position
*
* Position relative to previous move event. Unlike
* @ref Sdl2Application, HTML APIs don't provide relative position
* directly, so this is calculated explicitly as a delta from previous
* move event position.
*/
Vector2i relativePosition() const { return _relativePosition; }
/** @brief Mouse buttons */ /** @brief Mouse buttons */
Buttons buttons() const; Buttons buttons() const;
@ -1263,9 +1273,10 @@ class EmscriptenApplication::MouseMoveEvent: public EmscriptenApplication::Input
private: private:
friend EmscriptenApplication; friend EmscriptenApplication;
explicit MouseMoveEvent(const EmscriptenMouseEvent& event): _event(event) {} explicit MouseMoveEvent(const EmscriptenMouseEvent& event, const Vector2i& relativePosition): _event(event), _relativePosition{relativePosition} {}
const EmscriptenMouseEvent& _event; const EmscriptenMouseEvent& _event;
const Vector2i _relativePosition;
}; };
CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::MouseMoveEvent::Buttons) CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::MouseMoveEvent::Buttons)

11
src/Magnum/Platform/GlfwApplication.cpp

@ -517,8 +517,15 @@ void GlfwApplication::setupCallbacks() {
app.mouseReleaseEvent(e); app.mouseReleaseEvent(e);
}); });
glfwSetCursorPosCallback(_window, [](GLFWwindow* const window, const double x, const double y) { glfwSetCursorPosCallback(_window, [](GLFWwindow* const window, const double x, const double y) {
MouseMoveEvent e{window, Vector2i{Int(x), Int(y)}}; auto& app = *static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window));
static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window))->mouseMoveEvent(e); /* Avoid bogus offset at first -- report 0 when the event is called for
the first time */
Vector2i position{Int(x), Int(y)};
MouseMoveEvent e{window, position,
app._previousMouseMovePosition == Vector2i{-1} ? Vector2i{} :
position - app._previousMouseMovePosition};
app._previousMouseMovePosition = position;
app.mouseMoveEvent(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)}); MouseScrollEvent e(window, Vector2{Float(xoffset), Float(yoffset)});

18
src/Magnum/Platform/GlfwApplication.h

@ -590,8 +590,8 @@ class GlfwApplication {
#endif #endif
int _exitCode = 0; int _exitCode = 0;
Vector2i _minWindowSize; Vector2i _minWindowSize, _maxWindowSize;
Vector2i _maxWindowSize; Vector2i _previousMouseMovePosition{-1};
}; };
#ifdef MAGNUM_TARGET_GL #ifdef MAGNUM_TARGET_GL
@ -1590,6 +1590,16 @@ class GlfwApplication::MouseMoveEvent: public GlfwApplication::InputEvent {
/** @brief Position */ /** @brief Position */
Vector2i position() const { return _position; } Vector2i position() const { return _position; }
/**
* @brief Relative position
*
* Position relative to previous move event. Unlike
* @ref Sdl2Application, GLFW doesn't provide relative position
* directly, so this is calculated explicitly as a delta from previous
* move event position.
*/
Vector2i relativePosition() const { return _relativePosition; }
/** /**
* @brief Modifiers * @brief Modifiers
* *
@ -1600,10 +1610,10 @@ class GlfwApplication::MouseMoveEvent: public GlfwApplication::InputEvent {
private: private:
friend GlfwApplication; friend GlfwApplication;
explicit MouseMoveEvent(GLFWwindow* window, const Vector2i& position): _window{window}, _position{position} {} explicit MouseMoveEvent(GLFWwindow* window, const Vector2i& position, const Vector2i& relativePosition): _window{window}, _position{position}, _relativePosition{relativePosition} {}
GLFWwindow* const _window; GLFWwindow* const _window;
const Vector2i _position; const Vector2i _position, _relativePosition;
Containers::Optional<Buttons> _buttons; Containers::Optional<Buttons> _buttons;
Containers::Optional<Modifiers> _modifiers; Containers::Optional<Modifiers> _modifiers;
}; };

2
src/Magnum/Platform/Sdl2Application.h

@ -2191,7 +2191,7 @@ class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent {
/** /**
* @brief Relative position * @brief Relative position
* *
* Position relative to previous event. * Position relative to previous move event.
*/ */
Vector2i relativePosition() const { return _relativePosition; } Vector2i relativePosition() const { return _relativePosition; }

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

@ -80,7 +80,7 @@ struct EmscriptenApplicationTest: Platform::Application {
} }
void mouseMoveEvent(MouseMoveEvent& event) override { void mouseMoveEvent(MouseMoveEvent& event) override {
Debug{} << "mouse move event:" << event.position() << Int(event.buttons()); Debug{} << "mouse move event:" << event.position() << event.relativePosition() << Int(event.buttons());
} }
void mouseScrollEvent(MouseScrollEvent& event) override { void mouseScrollEvent(MouseScrollEvent& event) override {

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

@ -60,6 +60,10 @@ struct GlfwApplicationTest: Platform::Application {
} }
} }
void mouseMoveEvent(MouseMoveEvent& event) override {
Debug{} << "mouse move event:" << event.position() << event.relativePosition() << UnsignedInt(event.buttons());
}
void textInputEvent(TextInputEvent& event) override { void textInputEvent(TextInputEvent& event) override {
Debug{} << "text input event:" << std::string{event.text(), event.text().size()}; Debug{} << "text input event:" << std::string{event.text(), event.text().size()};
} }

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

@ -63,7 +63,7 @@ struct Sdl2ApplicationTest: Platform::Application {
} }
void mouseMoveEvent(MouseMoveEvent& event) override { void mouseMoveEvent(MouseMoveEvent& event) override {
Debug{} << "mouse move event:" << event.position() << Uint32(event.buttons()); Debug{} << "mouse move event:" << event.position() << event.relativePosition() << Uint32(event.buttons());
} }
void mouseScrollEvent(MouseScrollEvent& event) override { void mouseScrollEvent(MouseScrollEvent& event) override {

Loading…
Cancel
Save