diff --git a/doc/changelog.dox b/doc/changelog.dox index d1e2cbf2e..e5f3140df 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -518,11 +518,12 @@ See also: [mosra/magnum#332](https://github.com/mosra/magnum/pull/332)) - @ref Platform::Sdl2Application::mainLoopIteration() now returns a @cpp bool @ce to indicate if the application should exit -- @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. +- @ref Platform::GlfwApplication, @ref Platform::EmscriptenApplication and + @ref Platform::AndroidApplication 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 diff --git a/src/Magnum/Platform/AndroidApplication.cpp b/src/Magnum/Platform/AndroidApplication.cpp index ef7d17b31..35c38fcf7 100644 --- a/src/Magnum/Platform/AndroidApplication.cpp +++ b/src/Magnum/Platform/AndroidApplication.cpp @@ -250,13 +250,21 @@ std::int32_t AndroidApplication::inputEvent(android_app* state, AInputEvent* eve switch(action) { case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_UP: { + /* On a touch screen move events aren't reported when the + finger is moving above (of course), so remember the position + always */ + app._previousMouseMovePosition = {Int(AMotionEvent_getX(event, 0)), Int(AMotionEvent_getY(event, 0))}; MouseEvent e(event); action == AMOTION_EVENT_ACTION_DOWN ? app.mousePressEvent(e) : app.mouseReleaseEvent(e); return e.isAccepted() ? 1 : 0; } case AMOTION_EVENT_ACTION_MOVE: { - MouseMoveEvent e(event); + Vector2i position{Int(AMotionEvent_getX(event, 0)), Int(AMotionEvent_getY(event, 0))}; + MouseMoveEvent e{event, + app._previousMouseMovePosition == Vector2i{-1} ? Vector2i{} : + position - app._previousMouseMovePosition}; + app._previousMouseMovePosition = position; app.mouseMoveEvent(e); return e.isAccepted() ? 1 : 0; } diff --git a/src/Magnum/Platform/AndroidApplication.h b/src/Magnum/Platform/AndroidApplication.h index aa9dd63b7..584726e5a 100644 --- a/src/Magnum/Platform/AndroidApplication.h +++ b/src/Magnum/Platform/AndroidApplication.h @@ -418,6 +418,7 @@ class AndroidApplication { EGLDisplay _display; EGLSurface _surface; EGLContext _glContext; + Vector2i _previousMouseMovePosition{-1}; Containers::Pointer _context; Containers::Pointer _logOutput; @@ -765,6 +766,16 @@ class AndroidApplication::MouseMoveEvent: public InputEvent { Int(AMotionEvent_getY(_event, 0))}; } + /** + * @brief Relative position + * + * Position relative to previous move event. Unlike + * @ref Sdl2Application, Android 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 { #if __ANDROID_API__ >= 14 @@ -775,7 +786,9 @@ class AndroidApplication::MouseMoveEvent: public InputEvent { } private: - explicit MouseMoveEvent(AInputEvent* event): InputEvent(event) {} + explicit MouseMoveEvent(AInputEvent* event, Vector2i relativePosition): InputEvent{event}, _relativePosition{relativePosition} {} + + const Vector2i _relativePosition; }; CORRADE_ENUMSET_OPERATORS(AndroidApplication::MouseMoveEvent::Buttons)