diff --git a/map/animator.cpp b/map/animator.cpp index 2568fe0b8c..ad38102765 100644 --- a/map/animator.cpp +++ b/map/animator.cpp @@ -1,6 +1,7 @@ #include "animator.hpp" #include "rotate_screen_task.hpp" #include "change_viewport_task.hpp" +#include "move_screen_task.hpp" #include "framework.hpp" #include "../anim/controller.hpp" @@ -67,6 +68,43 @@ void Animator::StopRotation() m_rotateScreenTask.reset(); } +shared_ptr const & Animator::MoveScreen(m2::PointD const & startPt, + m2::PointD const & endPt, + double speed) +{ + StopMoveScreen(); + + m_moveScreenTask.reset(new MoveScreenTask(m_framework, + startPt, + endPt, + speed)); + + m_framework->GetAnimController()->AddTask(m_moveScreenTask); + + return m_moveScreenTask; +} + +void Animator::StopMoveScreen() +{ + if (m_moveScreenTask) + m_moveScreenTask->Lock(); + + if (m_moveScreenTask + && !m_moveScreenTask->IsEnded() + && !m_moveScreenTask->IsCancelled()) + { + m_moveScreenTask->Cancel(); + m_moveScreenTask->Unlock(); + m_moveScreenTask.reset(); + return; + } + + if (m_moveScreenTask) + m_moveScreenTask->Unlock(); + + m_moveScreenTask.reset(); +} + shared_ptr const & Animator::ChangeViewport(m2::AnyRectD const & start, m2::AnyRectD const & end, double rotationSpeed) diff --git a/map/animator.hpp b/map/animator.hpp index 6f308af36b..451cf8f2c6 100644 --- a/map/animator.hpp +++ b/map/animator.hpp @@ -8,6 +8,7 @@ class Framework; class RotateScreenTask; class ChangeViewportTask; +class MoveScreenTask; /// Class, which is responsible for /// tracking all map animations. class Animator @@ -18,6 +19,7 @@ private: shared_ptr m_rotateScreenTask; shared_ptr m_changeViewportTask; + shared_ptr m_moveScreenTask; public: @@ -36,4 +38,10 @@ public: void StopChangeViewport(); /// get screen rotation speed double GetRotationSpeed() const; + /// move screen from one point to another + shared_ptr const & MoveScreen(m2::PointD const & startPt, + m2::PointD const & endPt, + double speed); + /// stopping screen movement + void StopMoveScreen(); }; diff --git a/map/location_state.cpp b/map/location_state.cpp index 3302d806cb..62f5f54508 100644 --- a/map/location_state.cpp +++ b/map/location_state.cpp @@ -3,6 +3,7 @@ #include "framework.hpp" #include "compass_filter.hpp" #include "change_viewport_task.hpp" +#include "move_screen_task.hpp" #include "../yg/display_list.hpp" #include "../yg/skin.hpp" @@ -502,12 +503,13 @@ namespace location controller->Lock(); - m2::AnyRectD startRect = m_framework->GetNavigator().Screen().GlobalRect(); - m2::AnyRectD endRect = m2::AnyRectD(Position(), - startRect.Angle().val(), - m2::RectD(startRect.GetLocalRect())); + m2::PointD startPt = m_framework->GetNavigator().Screen().GetOrg(); + m2::PointD endPt = Position(); - m_framework->GetAnimator().ChangeViewport(startRect, endRect, 2); + ScreenBase const & s = m_framework->GetNavigator().Screen(); + double speed = min(0.5, 0.5 * s.GtoP(startPt).Length(s.GtoP(endPt)) / 50.0); + + m_framework->GetAnimator().MoveScreen(startPt, endPt, speed); controller->Unlock(); } @@ -518,12 +520,12 @@ namespace location controller->Lock(); - m2::AnyRectD startRect = m_framework->GetNavigator().Screen().GlobalRect(); - m2::AnyRectD endRect = m2::AnyRectD(Position(), - -m_compassFilter.GetHeadingRad(), - m2::RectD(startRect.GetLocalRect())); + m2::PointD startPt = m_framework->GetNavigator().Screen().GetOrg(); + m2::PointD endPt = Position(); + ScreenBase const & s = m_framework->GetNavigator().Screen(); + double speed = min(0.5,0.5 * s.GtoP(startPt).Length(s.GtoP(endPt)) / 50.0); - shared_ptr const & t = m_framework->GetAnimator().ChangeViewport(startRect, endRect, 2); + shared_ptr const & t = m_framework->GetAnimator().MoveScreen(startPt, endPt, speed); t->Lock(); t->AddCallback(anim::Task::EEnded, bind(&State::SetIsCentered, this, true)); @@ -547,6 +549,7 @@ namespace location SetCompassProcessMode(ECompassDoNothing); m_framework->GetAnimator().StopRotation(); m_framework->GetAnimator().StopChangeViewport(); + m_framework->GetAnimator().StopMoveScreen(); setState(EActive); } diff --git a/map/move_screen_task.cpp b/map/move_screen_task.cpp index bbe41a35b0..2f4c00e646 100644 --- a/map/move_screen_task.cpp +++ b/map/move_screen_task.cpp @@ -15,14 +15,17 @@ MoveScreenTask::MoveScreenTask(Framework * framework, void MoveScreenTask::OnStep(double ts) { + m2::PointD oldPt = m_outPt; anim::SegmentInterpolation::OnStep(ts); - m_framework->GetNavigator().SetOrg(m_outPt); + Navigator & nav = m_framework->GetNavigator(); + nav.SetOrg(nav.Screen().GetOrg() + m_outPt - oldPt); } void MoveScreenTask::OnEnd(double ts) { anim::SegmentInterpolation::OnEnd(ts); - m_framework->GetNavigator().SetOrg(m_outPt); + Navigator & nav = m_framework->GetNavigator(); + nav.SetOrg(m_outPt); } bool MoveScreenTask::IsVisual() const diff --git a/map/navigator.cpp b/map/navigator.cpp index 3883f04ddd..71943ff332 100644 --- a/map/navigator.cpp +++ b/map/navigator.cpp @@ -398,8 +398,8 @@ void Navigator::StartScale(m2::PointD const & pt1, m2::PointD const & pt2, doubl { //LOG(LDEBUG, (pt1.x, pt1.y, pt2.x, pt2.y)); m_StartScreen = m_Screen; - m_StartPt1 = pt1; - m_StartPt2 = pt2; + m_StartPt1 = m_LastPt1 = pt1; + m_StartPt2 = m_LastPt2 = pt2; m_DoCheckRotationThreshold = m_DoSupportRotation; m_IsRotatingDuringScale = false; @@ -518,9 +518,9 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double / m_Screen = m_StartScreen; + /// Checking for rotation threshold. if (m_DoCheckRotationThreshold) { - //LOG(LINFO, ("checking the rotation threshold")); double s = pt1.Length(pt2) / m_StartPt1.Length(m_StartPt2); double a = ang::AngleTo(pt1, pt2) - ang::AngleTo(m_StartPt1, m_StartPt2); @@ -534,22 +534,22 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double / { if (isRotationOutBounds) { - //LOG(LINFO, ("rotating during scale")); m_IsRotatingDuringScale = true; m_DoCheckRotationThreshold = false; } } else { - //LOG(LINFO, ("not rotating during scale")); m_IsRotatingDuringScale = false; m_DoCheckRotationThreshold = false; } } + m_Screen = PrevScreen; + if (!ScaleImpl(pt1, pt2, - m_StartPt1, m_StartPt2, - pt1.Length(pt2) / m_StartPt1.Length(m_StartPt2) > 1, + m_LastPt1, m_LastPt2, + pt1.Length(pt2) / m_LastPt1.Length(m_LastPt2) > 1, m_IsRotatingDuringScale)) m_Screen = PrevScreen; @@ -559,7 +559,6 @@ void Navigator::DoScale(m2::PointD const & pt1, m2::PointD const & pt2, double / void Navigator::StopScale(m2::PointD const & pt1, m2::PointD const & pt2, double timeInSec) { - // Ensure that final pos is reached. DoScale(pt1, pt2, timeInSec); ASSERT(m_LastPt1 == pt1, (m_LastPt1.x, m_LastPt1.y, pt1.x, pt1.y)); ASSERT(m_LastPt2 == pt2, (m_LastPt2.x, m_LastPt2.y, pt2.x, pt2.y)); diff --git a/map/rotate_screen_task.cpp b/map/rotate_screen_task.cpp index e8518114e1..3beecb95e3 100644 --- a/map/rotate_screen_task.cpp +++ b/map/rotate_screen_task.cpp @@ -15,14 +15,17 @@ RotateScreenTask::RotateScreenTask(Framework * framework, void RotateScreenTask::OnStep(double ts) { + double prevAngle = m_outAngle; anim::AngleInterpolation::OnStep(ts); - m_framework->GetNavigator().SetAngle(m_outAngle); + Navigator & nav = m_framework->GetNavigator(); + nav.SetAngle(nav.Screen().GetAngle() + m_outAngle - prevAngle); } void RotateScreenTask::OnEnd(double ts) { anim::AngleInterpolation::OnEnd(ts); - m_framework->GetNavigator().SetAngle(m_outAngle); + Navigator & nav = m_framework->GetNavigator(); + nav.SetAngle(m_outAngle); } bool RotateScreenTask::IsVisual() const