From c7daa3e7d79788d2ac7d5ee8d03deb78a7baca9d Mon Sep 17 00:00:00 2001 From: peak3d Date: Mon, 23 Mar 2020 19:25:35 +0100 Subject: [PATCH] Adjust gesture timing constants / respect DPI for inertial scrolling --- xbmc/input/InertialScrollingHandler.cpp | 26 +++++++++++++------ xbmc/input/InertialScrollingHandler.h | 1 + xbmc/input/touch/ITouchInputHandler.h | 1 + .../generic/GenericTouchInputHandler.cpp | 2 +- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/xbmc/input/InertialScrollingHandler.cpp b/xbmc/input/InertialScrollingHandler.cpp index cb92b12514f4f..f6026f341c4ad 100644 --- a/xbmc/input/InertialScrollingHandler.cpp +++ b/xbmc/input/InertialScrollingHandler.cpp @@ -14,6 +14,7 @@ #include "guilib/GUIComponent.h" #include "guilib/GUIWindowManager.h" #include "input/Key.h" +#include "input/touch/generic/GenericTouchInputHandler.h" #include "utils/TimeUtils.h" #include "utils/log.h" #include "windowing/WinSystem.h" @@ -21,11 +22,13 @@ #include #include -//time for reaching velocity 0 in secs +// time for reaching velocity 0 in secs #define TIME_TO_ZERO_SPEED 1.0f -//minimum speed for doing inertial scroll is 100 pixels / s -#define MINIMUM_SPEED_FOR_INERTIA 100 -//maximum time between last movement and gesture end in ms to consider as moving +// minimum speed for doing inertial scroll is 100 pixels / s +#define MINIMUM_SPEED_FOR_INERTIA 200 +// maximum speed for reducing time to zero +#define MAXIMUM_SPEED_FOR_REDUCTION 750 +// maximum time between last movement and gesture end in ms to consider as moving #define MAXIMUM_DELAY_FOR_INERTIA 200 CInertialScrollingHandler::CInertialScrollingHandler() @@ -95,8 +98,15 @@ bool CInertialScrollingHandler::CheckForInertialScrolling(const CAction* action) auto velocityX = velocitySum.x / m_panPoints.size(); auto velocityY = velocitySum.y / m_panPoints.size(); - if (std::abs(velocityX) > MINIMUM_SPEED_FOR_INERTIA || std::abs(velocityY) > MINIMUM_SPEED_FOR_INERTIA) + m_timeToZero = TIME_TO_ZERO_SPEED; + auto velocityMax = std::max(std::abs(velocityX), std::abs(velocityY)); + float dpiScale = CGenericTouchInputHandler::GetInstance().GetScreenDPI() / 160.0f; + + if (velocityMax > MINIMUM_SPEED_FOR_INERTIA * dpiScale) { + if (velocityMax < MAXIMUM_SPEED_FOR_REDUCTION * dpiScale) + m_timeToZero = (m_timeToZero * velocityMax) / (MAXIMUM_SPEED_FOR_REDUCTION * dpiScale); + bool inertialRequested = false; CGUIMessage message(GUI_MSG_GESTURE_NOTIFY, 0, 0, static_cast (velocityX), static_cast (velocityY)); @@ -128,8 +138,8 @@ bool CInertialScrollingHandler::CheckForInertialScrolling(const CAction* action) //calc deacceleration for fullstop in TIME_TO_ZERO_SPEED secs //v = a*t + v0 -> set v = 0 because we want to stop scrolling //a = -v0 / t - m_inertialDeacceleration.x = -1*m_iFlickVelocity.x/TIME_TO_ZERO_SPEED; - m_inertialDeacceleration.y = -1*m_iFlickVelocity.y/TIME_TO_ZERO_SPEED; + m_inertialDeacceleration.x = -1 * m_iFlickVelocity.x / m_timeToZero; + m_inertialDeacceleration.y = -1 * m_iFlickVelocity.y / m_timeToZero; m_inertialStartTime = CTimeUtils::GetFrameTime();//start time of inertial scrolling ret = true; @@ -159,7 +169,7 @@ bool CInertialScrollingHandler::ProcessInertialScroll(float frameTime) float absoluteInertialTime = (CTimeUtils::GetFrameTime() - m_inertialStartTime)/(float)1000; //as long as we aren't over the overall inertial scroll time - do the deacceleration - if ( absoluteInertialTime < TIME_TO_ZERO_SPEED ) + if (absoluteInertialTime < m_timeToZero) { //v = s/t -> s = t * v xMovement = frameTime * m_iFlickVelocity.x; diff --git a/xbmc/input/InertialScrollingHandler.h b/xbmc/input/InertialScrollingHandler.h index a0469edd24c71..4d79b53a8089a 100644 --- a/xbmc/input/InertialScrollingHandler.h +++ b/xbmc/input/InertialScrollingHandler.h @@ -45,4 +45,5 @@ class CInertialScrollingHandler CPoint m_iLastGesturePoint; CVector m_inertialDeacceleration; unsigned int m_inertialStartTime = 0; + float m_timeToZero = 0.0f; }; diff --git a/xbmc/input/touch/ITouchInputHandler.h b/xbmc/input/touch/ITouchInputHandler.h index 5638bc9bff09d..9ff5179499dc5 100644 --- a/xbmc/input/touch/ITouchInputHandler.h +++ b/xbmc/input/touch/ITouchInputHandler.h @@ -86,6 +86,7 @@ class ITouchInputHandler : public ITouchInputHandling virtual bool UpdateTouchPointer(int32_t pointer, float x, float y, int64_t time, float size = 0.0f) { return false; } void SetScreenDPI(float dpi) { if (dpi > 0.0f) m_dpi = dpi; } + float GetScreenDPI() { return m_dpi; } protected: /*! diff --git a/xbmc/input/touch/generic/GenericTouchInputHandler.cpp b/xbmc/input/touch/generic/GenericTouchInputHandler.cpp index 13bb2da6ecd6e..93cca98aa177f 100644 --- a/xbmc/input/touch/generic/GenericTouchInputHandler.cpp +++ b/xbmc/input/touch/generic/GenericTouchInputHandler.cpp @@ -19,7 +19,7 @@ namespace { -constexpr int TOUCH_HOLD_TIMEOUT = 1000; +constexpr int TOUCH_HOLD_TIMEOUT = 500; } CGenericTouchInputHandler::CGenericTouchInputHandler()