diff --git a/drape_frontend/animation/parallel_animation.cpp b/drape_frontend/animation/parallel_animation.cpp index c6a724c6e7..3445933a66 100644 --- a/drape_frontend/animation/parallel_animation.cpp +++ b/drape_frontend/animation/parallel_animation.cpp @@ -97,6 +97,10 @@ bool ParallelAnimation::GetTargetProperty(TObject object, TProperty property, Pr void ParallelAnimation::AddAnimation(drape_ptr && animation) { + SetCouldBeInterrupted(CouldBeInterrupted() && animation->CouldBeInterrupted()); + SetCouldBeBlended(CouldBeBlended() && animation->CouldBeBlended()); + SetCouldBeRewinded(CouldBeRewinded() && animation->CouldBeRewinded()); + m_animations.emplace_back(move(animation)); ObtainObjectProperties(); } diff --git a/drape_frontend/animation/parallel_animation.hpp b/drape_frontend/animation/parallel_animation.hpp index 45d762ef1f..c405188a9f 100644 --- a/drape_frontend/animation/parallel_animation.hpp +++ b/drape_frontend/animation/parallel_animation.hpp @@ -39,6 +39,20 @@ public: bool GetProperty(TObject object, TProperty property, PropertyValue & value) const override; bool GetTargetProperty(TObject object, TProperty property, PropertyValue & value) const override; + template T const * FindAnimation(Animation::Type type, char const * customType = nullptr) const + { + for (auto const & anim : m_animations) + { + if ((anim->GetType() == type) && + (customType == nullptr || strcmp(anim->GetCustomType().c_str(), customType) == 0)) + { + ASSERT(dynamic_cast(anim.get()) != nullptr, ()); + return static_cast(anim.get()); + } + } + return nullptr; + } + private: void ObtainObjectProperties(); diff --git a/drape_frontend/animation_system.cpp b/drape_frontend/animation_system.cpp index 7e4469b075..2e06a55b0f 100644 --- a/drape_frontend/animation_system.cpp +++ b/drape_frontend/animation_system.cpp @@ -293,7 +293,7 @@ void AnimationSystem::FinishAnimations(function const { #ifdef DEBUG_ANIMATIONS LOG(LINFO, ("Finish animation", (*it)->GetType(), ", rewind:", rewind, - ", couldBeRewinded:", anim->CouldBeRewinded())); + ", couldBeRewinded:", (*it)->CouldBeRewinded())); changed = true; #endif it = lst.erase(it); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index a11d6ac551..3e4e25d0be 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1403,7 +1403,6 @@ void FrontendRenderer::OnAnimatedScaleEnded() void FrontendRenderer::OnAnimationStarted(ref_ptr anim) { - m_myPositionController->AnimationStarted(anim); } void FrontendRenderer::OnTouchMapAction() diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 0f39443c7f..3d868a8efd 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -641,18 +641,21 @@ void MyPositionController::ChangeModelView(m2::PointD const & center, int zoomLe { if (m_listener) m_listener->ChangeModelView(center, zoomLevel, m_animCreator); + m_animCreator = nullptr; } void MyPositionController::ChangeModelView(double azimuth) { if (m_listener) m_listener->ChangeModelView(azimuth, m_animCreator); + m_animCreator = nullptr; } void MyPositionController::ChangeModelView(m2::RectD const & rect) { if (m_listener) m_listener->ChangeModelView(rect, m_animCreator); + m_animCreator = nullptr; } void MyPositionController::ChangeModelView(m2::PointD const & userPos, double azimuth, @@ -660,12 +663,14 @@ void MyPositionController::ChangeModelView(m2::PointD const & userPos, double az { if (m_listener) m_listener->ChangeModelView(userPos, azimuth, pxZero, zoomLevel, m_animCreator); + m_animCreator = nullptr; } void MyPositionController::ChangeModelView(double autoScale, m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero) { if (m_listener) m_listener->ChangeModelView(autoScale, userPos, azimuth, pxZero, m_animCreator); + m_animCreator = nullptr; } void MyPositionController::UpdateViewport(int zoomLevel) @@ -697,11 +702,14 @@ m2::PointD MyPositionController::GetRoutingRotationPixelCenter() const m_pixelRect.maxY() - m_positionYOffset * VisualParams::Instance().GetVisualScale()); } -m2::PointD MyPositionController::GetDrawablePosition() const +m2::PointD MyPositionController::GetDrawablePosition() { m2::PointD position; if (AnimationSystem::Instance().GetArrowPosition(position)) + { + m_isPendingAnimation = false; return position; + } if (m_isPendingAnimation) return m_oldPosition; @@ -709,11 +717,14 @@ m2::PointD MyPositionController::GetDrawablePosition() const return m_position; } -double MyPositionController::GetDrawableAzimut() const +double MyPositionController::GetDrawableAzimut() { double angle; if (AnimationSystem::Instance().GetArrowAngle(angle)) + { + m_isPendingAnimation = false; return angle; + } if (m_isPendingAnimation) return m_oldDrawDirection; @@ -721,18 +732,6 @@ double MyPositionController::GetDrawableAzimut() const return m_drawDirection; } -void MyPositionController::AnimationStarted(ref_ptr anim) -{ - if (m_isPendingAnimation && m_animCreator != nullptr && anim != nullptr && - (anim->GetType() == Animation::MapFollow || - anim->GetType() == Animation::MapLinear)) - { - m_isPendingAnimation = false; - double const kDoNotChangeDuration = -1.0; - m_animCreator(anim->GetType() == Animation::MapFollow ? anim->GetDuration() : kDoNotChangeDuration); - } -} - void MyPositionController::CreateAnim(m2::PointD const & oldPos, double oldAzimut, ScreenBase const & screen) { double const moveDuration = PositionInterpolator::GetMoveDuration(oldPos, m_position, screen); @@ -741,11 +740,11 @@ void MyPositionController::CreateAnim(m2::PointD const & oldPos, double oldAzimu { if (IsModeChangeViewport()) { - m_animCreator = [this, oldPos, oldAzimut, moveDuration](double correctedDuration) -> drape_ptr + m_animCreator = [this, moveDuration](double correctedDuration) -> drape_ptr { - return make_unique_dp(oldPos, m_position, + return make_unique_dp(GetDrawablePosition(), m_position, correctedDuration > 0.0 ? correctedDuration : moveDuration, - oldAzimut, m_drawDirection); + GetDrawableAzimut(), m_drawDirection); }; m_oldPosition = oldPos; m_oldDrawDirection = oldAzimut; diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp index 29956224be..516a5898df 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -59,8 +59,6 @@ public: void ScaleStarted(); void ScaleEnded(); - void AnimationStarted(ref_ptr anim); - void Rotated(); void ResetRoutingNotFollowTimer(); @@ -100,7 +98,7 @@ public: bool IsWaitingForTimers() const; bool IsWaitingForLocation() const; - m2::PointD GetDrawablePosition() const; + m2::PointD GetDrawablePosition(); private: bool IsModeChangeViewport() const; @@ -123,7 +121,7 @@ private: m2::PointD GetRotationPixelCenter() const; m2::PointD GetRoutingRotationPixelCenter() const; - double GetDrawableAzimut() const; + double GetDrawableAzimut(); void CreateAnim(m2::PointD const & oldPos, double oldAzimut, ScreenBase const & screen); bool AlmostCurrentPosition(m2::PointD const & pos) const; diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 907b44f250..1d2b44de24 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -36,6 +36,8 @@ uint64_t const kKineticDelayMs = 500; float const kForceTapThreshold = 0.75; +double const kDoNotChangeDuration = -1.0; + size_t GetValidTouchesCount(array const & touches) { size_t result = 0; @@ -303,7 +305,13 @@ bool UserEventStream::SetScale(m2::PointD const & pxScaleCenter, double factor, if (isAnim) { - auto const & followAnim = m_animationSystem.FindAnimation(Animation::MapFollow); + auto followAnim = m_animationSystem.FindAnimation(Animation::MapFollow); + if (followAnim == nullptr) + { + auto const parallelAnim = m_animationSystem.FindAnimation(Animation::Parallel, kParallelFollowAnim.c_str()); + if (parallelAnim != nullptr) + followAnim = parallelAnim->FindAnimation(Animation::MapFollow); + } if (followAnim != nullptr && followAnim->HasScale()) { // Scaling is not possible if current follow animation does pixel offset. @@ -312,6 +320,7 @@ bool UserEventStream::SetScale(m2::PointD const & pxScaleCenter, double factor, // Reset follow animation with scaling if we apply scale explicitly. ResetAnimations(Animation::MapFollow); + ResetAnimations(Animation::Parallel, kParallelFollowAnim); } m2::PointD glbScaleCenter = m_navigator.PtoG(m_navigator.P3dtoP(scaleCenter)); @@ -389,7 +398,7 @@ bool UserEventStream::SetScreen(ScreenBase const & endScreen, bool isAnim, TAnim { drape_ptr parallelAnim = make_unique_dp(); parallelAnim->SetCustomType(kParallelLinearAnim); - parallelAnim->AddAnimation(parallelAnimCreator(anim->GetDuration())); + parallelAnim->AddAnimation(parallelAnimCreator(kDoNotChangeDuration)); parallelAnim->AddAnimation(move(anim)); m_animationSystem.CombineAnimation(move(parallelAnim)); } @@ -423,19 +432,17 @@ bool UserEventStream::InterruptFollowAnimations(bool force) followAnim = m_animationSystem.FindAnimation(Animation::Sequence, kPrettyFollowAnim.c_str()); if (followAnim == nullptr) - followAnim = m_animationSystem.FindAnimation(Animation::Parallel, kParallelFollowAnim.c_str()); + followAnim = m_animationSystem.FindAnimation(Animation::Parallel, kParallelFollowAnim.c_str()); if (followAnim == nullptr) - followAnim = m_animationSystem.FindAnimation(Animation::Parallel, kParallelLinearAnim.c_str()); + followAnim = m_animationSystem.FindAnimation(Animation::Parallel, kParallelLinearAnim.c_str()); if (followAnim != nullptr) { if (force || followAnim->CouldBeInterrupted()) ResetAnimations(followAnim->GetType(), followAnim->GetCustomType()); else - { return false; - } } return true; } @@ -491,7 +498,7 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD { drape_ptr parallelAnim = make_unique_dp(); parallelAnim->SetCustomType(kParallelFollowAnim); - parallelAnim->AddAnimation(parallelAnimCreator(anim->GetDuration())); + parallelAnim->AddAnimation(parallelAnimCreator(anim->GetType() == Animation::MapFollow ? anim->GetDuration() : kDoNotChangeDuration)); parallelAnim->AddAnimation(move(anim)); m_animationSystem.CombineAnimation(move(parallelAnim)); }