Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorr.kuznetsov <r.kuznetsov@corp.mail.ru>2017-09-28 13:39:28 +0300
committerArsentiy Milchakov <milcars@mapswithme.com>2017-09-29 11:53:54 +0300
commitcccd8608896f1c95758aaae3f33badaca5772ae1 (patch)
treeb48dc752d1cfebd71751155a9c151237dcdf0364
parent46deebc993555d639dbfa412df89d3084959b319 (diff)
Improved kinetic scroll
-rw-r--r--drape_frontend/kinetic_scroller.cpp32
-rw-r--r--drape_frontend/kinetic_scroller.hpp6
-rw-r--r--drape_frontend/user_event_stream.cpp3
3 files changed, 37 insertions, 4 deletions
diff --git a/drape_frontend/kinetic_scroller.cpp b/drape_frontend/kinetic_scroller.cpp
index c4c67bda76..cb46a97283 100644
--- a/drape_frontend/kinetic_scroller.cpp
+++ b/drape_frontend/kinetic_scroller.cpp
@@ -15,6 +15,7 @@ double const kKineticThreshold = 50.0;
double const kKineticAcceleration = 0.4;
double const kKineticMaxSpeedStart = 1000.0; // pixels per second
double const kKineticMaxSpeedEnd = 10000.0; // pixels per second
+double const kInstantVelocityThresholdUnscaled = 200.0; // pixels per second
double CalculateKineticMaxSpeed(ScreenBase const & modelView)
{
@@ -117,12 +118,29 @@ private:
TObjectProperties m_properties;
};
-void KineticScroller::Init(ScreenBase const &modelView)
+void KineticScroller::Init(ScreenBase const & modelView)
{
ASSERT(!m_isActive, ());
m_isActive = true;
m_lastRect = modelView.GlobalRect();
m_lastTimestamp = std::chrono::steady_clock::now();
+ m_updatePosition = modelView.GlobalRect().GlobalCenter();
+ m_updateTimestamp = m_lastTimestamp;
+}
+
+void KineticScroller::Update(ScreenBase const & modelView)
+{
+ ASSERT(m_isActive, ());
+ using namespace std::chrono;
+ auto const nowTimestamp = std::chrono::steady_clock::now();
+ auto const curPos = modelView.GlobalRect().GlobalCenter();
+
+ double const instantPixelLen = (modelView.GtoP(curPos) - modelView.GtoP(m_updatePosition)).Length();
+ auto const updateElapsed = duration_cast<duration<double>>(nowTimestamp - m_updateTimestamp).count();
+ m_instantVelocity = (updateElapsed >= 1e-5) ? instantPixelLen / updateElapsed : 0.0;
+
+ m_updateTimestamp = nowTimestamp;
+ m_updatePosition = curPos;
}
bool KineticScroller::IsActive() const
@@ -139,9 +157,9 @@ m2::PointD KineticScroller::GetDirection(ScreenBase const & modelView) const
using namespace std::chrono;
auto const nowTimestamp = steady_clock::now();
auto const elapsed = duration_cast<duration<double>>(nowTimestamp - m_lastTimestamp).count();
+ m2::PointD const currentCenter = modelView.GlobalRect().GlobalCenter();
m2::PointD const lastCenter = m_lastRect.GlobalCenter();
- m2::PointD const currentCenter = modelView.GlobalRect().GlobalCenter();
double const pxDeltaLength = (modelView.GtoP(currentCenter) - modelView.GtoP(lastCenter)).Length();
m2::PointD delta = currentCenter - lastCenter;
if (!delta.IsAlmostZero())
@@ -164,7 +182,15 @@ void KineticScroller::Cancel()
drape_ptr<Animation> KineticScroller::CreateKineticAnimation(ScreenBase const & modelView)
{
- static double kVelocityThreshold = kKineticThreshold * VisualParams::Instance().GetVisualScale();
+ static double vs = VisualParams::Instance().GetVisualScale();
+ static double kVelocityThreshold = kKineticThreshold * vs;
+ static double kInstantVelocityThreshold = kInstantVelocityThresholdUnscaled * vs;
+
+ if (m_instantVelocity < kInstantVelocityThreshold)
+ {
+ Cancel();
+ return drape_ptr<Animation>();
+ }
auto const direction = GetDirection(modelView);
Cancel();
diff --git a/drape_frontend/kinetic_scroller.hpp b/drape_frontend/kinetic_scroller.hpp
index d62a101a61..d3950a7870 100644
--- a/drape_frontend/kinetic_scroller.hpp
+++ b/drape_frontend/kinetic_scroller.hpp
@@ -13,7 +13,8 @@ namespace df
class KineticScroller
{
public:
- void Init(ScreenBase const &modelView);
+ void Init(ScreenBase const & modelView);
+ void Update(ScreenBase const & modelView);
bool IsActive() const;
void Cancel();
drape_ptr<Animation> CreateKineticAnimation(ScreenBase const & modelView);
@@ -22,7 +23,10 @@ private:
m2::PointD GetDirection(ScreenBase const & modelView) const;
std::chrono::steady_clock::time_point m_lastTimestamp;
+ std::chrono::steady_clock::time_point m_updateTimestamp;
bool m_isActive = false;
m2::AnyRectD m_lastRect;
+ m2::PointD m_updatePosition;
+ double m_instantVelocity = 0.0;
};
} // namespace df
diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp
index 6967917ae3..ac3f176edb 100644
--- a/drape_frontend/user_event_stream.cpp
+++ b/drape_frontend/user_event_stream.cpp
@@ -987,6 +987,9 @@ void UserEventStream::Drag(Touch const & t)
TEST_CALL(DRAG);
ASSERT_EQUAL(m_state, STATE_DRAG, ());
m_navigator.DoDrag(t.m_location);
+
+ if (m_kineticScrollEnabled && m_scroller.IsActive())
+ m_scroller.Update(m_navigator.Screen());
}
bool UserEventStream::EndDrag(Touch const & t, bool cancelled)