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
specify the actual application return code (see
[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
@ref Platform::BasicScreen::mouseScrollEvent() "mouseScrollEvent()",
@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,
([](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);
return e.isAccepted();
}));

15
src/Magnum/Platform/EmscriptenApplication.h

@ -639,7 +639,7 @@ class EmscriptenApplication {
void setupAnimationFrame(bool ForceAnimationFrame);
Vector2 _devicePixelRatio, _dpiScaling;
Vector2i _lastKnownCanvasSize;
Vector2i _lastKnownCanvasSize, _previousMouseMovePosition{-1};
Flags _flags;
@ -1251,6 +1251,16 @@ class EmscriptenApplication::MouseMoveEvent: public EmscriptenApplication::Input
/** @brief Position */
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 */
Buttons buttons() const;
@ -1263,9 +1273,10 @@ class EmscriptenApplication::MouseMoveEvent: public EmscriptenApplication::Input
private:
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 Vector2i _relativePosition;
};
CORRADE_ENUMSET_OPERATORS(EmscriptenApplication::MouseMoveEvent::Buttons)

11
src/Magnum/Platform/GlfwApplication.cpp

@ -517,8 +517,15 @@ void GlfwApplication::setupCallbacks() {
app.mouseReleaseEvent(e);
});
glfwSetCursorPosCallback(_window, [](GLFWwindow* const window, const double x, const double y) {
MouseMoveEvent e{window, Vector2i{Int(x), Int(y)}};
static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window))->mouseMoveEvent(e);
auto& app = *static_cast<GlfwApplication*>(glfwGetWindowUserPointer(window));
/* 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) {
MouseScrollEvent e(window, Vector2{Float(xoffset), Float(yoffset)});

18
src/Magnum/Platform/GlfwApplication.h

@ -590,8 +590,8 @@ class GlfwApplication {
#endif
int _exitCode = 0;
Vector2i _minWindowSize;
Vector2i _maxWindowSize;
Vector2i _minWindowSize, _maxWindowSize;
Vector2i _previousMouseMovePosition{-1};
};
#ifdef MAGNUM_TARGET_GL
@ -1590,6 +1590,16 @@ class GlfwApplication::MouseMoveEvent: public GlfwApplication::InputEvent {
/** @brief 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
*
@ -1600,10 +1610,10 @@ class GlfwApplication::MouseMoveEvent: public GlfwApplication::InputEvent {
private:
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;
const Vector2i _position;
const Vector2i _position, _relativePosition;
Containers::Optional<Buttons> _buttons;
Containers::Optional<Modifiers> _modifiers;
};

2
src/Magnum/Platform/Sdl2Application.h

@ -2191,7 +2191,7 @@ class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent {
/**
* @brief Relative position
*
* Position relative to previous event.
* Position relative to previous move event.
*/
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 {
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 {

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

Loading…
Cancel
Save