From b0d448d75b4834a6a84838502dbf7017bfc68941 Mon Sep 17 00:00:00 2001 From: ExMix Date: Tue, 7 Oct 2014 10:52:19 +0300 Subject: [PATCH] [core] improved animation on compass tap --- map/compass_arrow.cpp | 3 +- map/location_state.cpp | 64 ++++++++++++++++++++++++++++++++++++------ map/location_state.hpp | 2 ++ map/navigator.cpp | 2 +- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/map/compass_arrow.cpp b/map/compass_arrow.cpp index d27c881b4f..b14dd14726 100644 --- a/map/compass_arrow.cpp +++ b/map/compass_arrow.cpp @@ -200,8 +200,7 @@ bool CompassArrow::onTapEnded(m2::PointD const & pt) anim::Controller::Guard guard(animController); // switching off compass follow mode - m_framework->GetInformationDisplay().locationState()->StopCompassFollowing(); - m_framework->GetAnimator().RotateScreen(m_framework->GetNavigator().Screen().GetAngle(), 0.0); + m_framework->GetLocationState()->OnCompassTaped(); m_framework->Invalidate(); return true; diff --git a/map/location_state.cpp b/map/location_state.cpp index d84715d77d..8c7cdd8c2b 100644 --- a/map/location_state.cpp +++ b/map/location_state.cpp @@ -67,11 +67,14 @@ public: m2::PointD const & srcPixelBinding, m2::PointD const & dstPixelbinding) : m_fw(fw) + , m_hasPendingAnimation(false) { m_angleAnim.reset(new anim::SafeAngleInterpolation(srcAngle, srcAngle, 1.0)); m_posAnim.reset(new anim::SafeSegmentInterpolation(srcPos, srcPos, 1.0)); - m_pxBindingAnim.reset(new anim::SafeSegmentInterpolation(InvertPxBinding(srcPixelBinding), - InvertPxBinding(dstPixelbinding), 1.0)); + m2::PointD srcInverted = InvertPxBinding(srcPixelBinding); + m2::PointD dstInverted = InvertPxBinding(dstPixelbinding); + m_pxBindingAnim.reset(new anim::SafeSegmentInterpolation(srcInverted, dstInverted, + m_fw->GetNavigator().ComputeMoveSpeed(srcInverted, dstInverted))); } void SetDestinationParams(m2::PointD const & dstPos, double dstAngle) @@ -79,15 +82,28 @@ public: ASSERT(m_angleAnim != nullptr, ()); ASSERT(m_posAnim != nullptr, ()); - if (dstPos.EqualDxDy(m_posAnim->GetCurrentValue(), POSITION_TOLERANCE) && - fabs(ang::GetShortestDistance(m_angleAnim->GetCurrentValue(), dstAngle)) < ANGLE_TOLERANCE) + double shortDist = fabs(ang::GetShortestDistance(m_angleAnim->GetCurrentValue(), dstAngle)); + if (dstPos.EqualDxDy(m_posAnim->GetCurrentValue(), POSITION_TOLERANCE) && shortDist < ANGLE_TOLERANCE) return; - double const posSpeed = m_fw->GetNavigator().ComputeMoveSpeed(m_posAnim->GetCurrentValue(), dstPos); - double const angleSpeed = 1.5;//m_fw->GetAnimator().GetRotationSpeed(); - m_angleAnim->ResetDestParams(dstAngle, angleSpeed); - m_posAnim->ResetDestParams(dstPos, posSpeed); + if (IsVisual()) + { + m_hasPendingAnimation = true; + m_pendingDstPos = dstPos; + m_pendingAngle = dstAngle; + } + else + SetParams(dstPos, dstAngle, shortDist); + } + + void Update() + { + if (m_hasPendingAnimation) + { + m_hasPendingAnimation = false; + SetParams(m_pendingDstPos, m_pendingAngle, ang::GetShortestDistance(m_angleAnim->GetCurrentValue(), m_pendingAngle)); + } } virtual void OnStep(double ts) @@ -152,6 +168,14 @@ private: m_fw->Invalidate(); } + void SetParams(m2::PointD const & dstPos, double dstAngle, double angleDist) + { + double const posSpeed = m_fw->GetNavigator().ComputeMoveSpeed(m_posAnim->GetCurrentValue(), dstPos); + double const angleSpeed = angleDist < 1.0 ? 1.5 : m_fw->GetAnimator().GetRotationSpeed(); + m_angleAnim->ResetDestParams(dstAngle, angleSpeed); + m_posAnim->ResetDestParams(dstPos, posSpeed); + } + bool OnStep(anim::Task * task, double ts) { if (task->IsReady()) @@ -186,6 +210,10 @@ private: unique_ptr m_angleAnim; unique_ptr m_posAnim; unique_ptr m_pxBindingAnim; + + bool m_hasPendingAnimation; + m2::PointD m_pendingDstPos; + double m_pendingAngle; }; } @@ -416,6 +444,9 @@ void State::update() { m2::PointD const pxPosition = m_framework->GetNavigator().GtoP(Position()); setPivot(pxPosition); + + if (m_animTask) + static_cast(m_animTask.get())->Update(); } } @@ -716,6 +747,13 @@ void State::Rotated() SetModeInfo(ChangeMode(m_modeInfo, NotFollow)); } +void State::OnCompassTaped() +{ + StopCompassFollowing(); + RotateOnNorth(); + AnimateFollow(); +} + void State::OnSize(m2::RectD const & /*oldPixelRect*/) { if (GetMode() == RotateAndFollow) @@ -787,6 +825,14 @@ void State::AnimateStateTransition(Mode oldMode, Mode newMode) { RotateOnNorth(); } + else if (oldMode == NotFollow && newMode == Follow) + { + m2::AnyRectD screenRect = GetModelView().GlobalRect(); + m2::RectD const & clipRect = GetModelView().ClipRect(); + screenRect.Inflate(clipRect.SizeX() / 2.0, clipRect.SizeY() / 2.0); + if (!screenRect.IsPointInside(m_position)) + m_framework->SetViewportCenter(m_position); + } AnimateFollow(); } @@ -799,7 +845,9 @@ void State::AnimateFollow() if (!FollowCompass()) { if (!m_position.EqualDxDy(m_framework->GetViewportCenter(), POSITION_TOLERANCE)) + { m_framework->SetViewportCenterAnimated(m_position); + } } } diff --git a/map/location_state.hpp b/map/location_state.hpp index 3d2ec853f2..48ab0ac6e4 100644 --- a/map/location_state.hpp +++ b/map/location_state.hpp @@ -91,6 +91,8 @@ namespace location void Rotated(); //@} + void OnCompassTaped(); + void OnSize(m2::RectD const & oldPixelRect); /// @name GPS location updates routine. diff --git a/map/navigator.cpp b/map/navigator.cpp index cb3b1fbad8..d9567a0829 100644 --- a/map/navigator.cpp +++ b/map/navigator.cpp @@ -76,7 +76,7 @@ void Navigator::CenterViewport(m2::PointD const & p) double Navigator::ComputeMoveSpeed(m2::PointD const & p0, m2::PointD const & p1) const { - return max(0.1, min(0.5, 0.5 * GtoP(p0).Length(GtoP(p1)) / 50.0)); + return 0.2;//max(0.5, min(0.5, 0.5 * GtoP(p0).Length(GtoP(p1)) / 50.0)); } void Navigator::SaveState()