From dcfa52b2ae137f307a2f87843b2be92127c533a8 Mon Sep 17 00:00:00 2001 From: Daria Volvenkova Date: Wed, 3 Aug 2016 17:51:00 +0300 Subject: Move arrow animation into parallel animation. --- drape_frontend/animation/parallel_animation.cpp | 111 ++++++++++++++++++++++-- drape_frontend/animation/parallel_animation.hpp | 28 +++--- drape_frontend/animation/sequence_animation.cpp | 6 +- drape_frontend/animation/sequence_animation.hpp | 2 +- drape_frontend/animation_system.cpp | 4 +- drape_frontend/animation_system.hpp | 4 +- drape_frontend/frontend_renderer.cpp | 22 ++--- drape_frontend/frontend_renderer.hpp | 11 +-- drape_frontend/my_position_controller.cpp | 17 ++-- drape_frontend/my_position_controller.hpp | 13 +-- drape_frontend/screen_animations.cpp | 2 + drape_frontend/screen_animations.hpp | 2 + drape_frontend/user_event_stream.cpp | 86 ++++++++++-------- drape_frontend/user_event_stream.hpp | 42 ++++++--- 14 files changed, 250 insertions(+), 100 deletions(-) (limited to 'drape_frontend') diff --git a/drape_frontend/animation/parallel_animation.cpp b/drape_frontend/animation/parallel_animation.cpp index bee969b738..c6a724c6e7 100644 --- a/drape_frontend/animation/parallel_animation.cpp +++ b/drape_frontend/animation/parallel_animation.cpp @@ -1,5 +1,7 @@ #include "parallel_animation.hpp" +#include "animation_system.hpp" + namespace df { @@ -7,6 +9,26 @@ ParallelAnimation::ParallelAnimation() : Animation(true /* couldBeInterrupted */, true /* couldBeBlended */) {} +string ParallelAnimation::GetCustomType() const +{ + return m_customType; +} + +void ParallelAnimation::SetCustomType(string const & type) +{ + m_customType = type; +} + +Animation::TAnimObjects const & ParallelAnimation::GetObjects() const +{ + return m_objects; +} + +bool ParallelAnimation::HasObject(TObject object) const +{ + return m_objects.find(object) != m_objects.end(); +} + Animation::TObjectProperties const & ParallelAnimation::GetProperties(TObject object) const { ASSERT(HasObject(object), ()); @@ -17,20 +39,66 @@ bool ParallelAnimation::HasProperty(TObject object, TProperty property) const { if (!HasObject(object)) return false; - TObjectProperties properties = GetProperties(object); + TObjectProperties const & properties = GetProperties(object); return properties.find(property) != properties.end(); } -void ParallelAnimation::AddAnimation(drape_ptr animation) +bool ParallelAnimation::HasTargetProperty(TObject object, TProperty property) const +{ + ASSERT(!m_animations.empty(), ()); + for (auto const & anim : m_animations) + { + if (anim->HasTargetProperty(object, property)) + return true; + } + return false; +} + +void ParallelAnimation::SetMaxDuration(double maxDuration) +{ + for (auto const & anim : m_animations) + anim->SetMaxDuration(maxDuration); +} + +double ParallelAnimation::GetDuration() const +{ + double duration = 0.0; + for (auto const & anim : m_animations) + duration = max(duration, anim->GetDuration()); + return duration; +} + +bool ParallelAnimation::IsFinished() const +{ + return m_animations.empty(); +} + +bool ParallelAnimation::GetProperty(TObject object, TProperty property, PropertyValue & value) const +{ + ASSERT(!m_animations.empty(), ()); + for (auto const & anim : m_animations) + { + if (anim->HasProperty(object, property)) + return anim->GetProperty(object, property, value); + } + return false; +} + +bool ParallelAnimation::GetTargetProperty(TObject object, TProperty property, PropertyValue & value) const { - TAnimObjects const & objects = animation->GetObjects(); - m_objects.insert(objects.begin(), objects.end()); - for (auto const & object : objects) + ASSERT(!m_animations.empty(), ()); + for (auto const & anim : m_animations) { - TObjectProperties const & properties = animation->GetProperties(object); - m_properties[object].insert(properties.begin(), properties.end()); + if (anim->HasProperty(object, property)) + return anim->GetTargetProperty(object, property, value); } - m_animations.push_back(move(animation)); + return false; +} + +void ParallelAnimation::AddAnimation(drape_ptr && animation) +{ + m_animations.emplace_back(move(animation)); + ObtainObjectProperties(); } void ParallelAnimation::OnStart() @@ -54,7 +122,9 @@ void ParallelAnimation::Advance(double elapsedSeconds) if ((*iter)->IsFinished()) { (*iter)->OnFinish(); + AnimationSystem::Instance().SaveAnimationResult(*(*iter)); iter = m_animations.erase(iter); + ObtainObjectProperties(); } else { @@ -66,8 +136,33 @@ void ParallelAnimation::Advance(double elapsedSeconds) void ParallelAnimation::Finish() { for (auto & anim : m_animations) + { anim->Finish(); + AnimationSystem::Instance().SaveAnimationResult(*anim); + } + m_animations.clear(); + ObtainObjectProperties(); Animation::Finish(); } +void ParallelAnimation::ObtainObjectProperties() +{ + m_objects.clear(); + m_properties.clear(); + + if (m_animations.empty()) + return; + + for (auto const & anim : m_animations) + { + TAnimObjects const & objects = anim->GetObjects(); + m_objects.insert(objects.begin(), objects.end()); + for (auto const & object : objects) + { + TObjectProperties const & properties = anim->GetProperties(object); + m_properties[object].insert(properties.begin(), properties.end()); + } + } +} + } // namespace df diff --git a/drape_frontend/animation/parallel_animation.hpp b/drape_frontend/animation/parallel_animation.hpp index 524ceaf2b7..45d762ef1f 100644 --- a/drape_frontend/animation/parallel_animation.hpp +++ b/drape_frontend/animation/parallel_animation.hpp @@ -14,31 +14,39 @@ public: Animation::Type GetType() const override { return Animation::Parallel; } - TAnimObjects const & GetObjects() const override - { - return m_objects; - } - - bool HasObject(TObject object) const override - { - return m_objects.find(object) != m_objects.end(); - } + TAnimObjects const & GetObjects() const override; + bool HasObject(TObject object) const override; TObjectProperties const & GetProperties(TObject object) const override; bool HasProperty(TObject object, TProperty property) const override; + bool HasTargetProperty(TObject object, TProperty property) const override; + + string GetCustomType() const override; + void SetCustomType(string const & type); - void AddAnimation(drape_ptr animation); + void AddAnimation(drape_ptr && animation); void OnStart() override; void OnFinish() override; + void SetMaxDuration(double maxDuration) override; + double GetDuration() const override; + bool IsFinished() const override; + void Advance(double elapsedSeconds) override; void Finish() override; + bool GetProperty(TObject object, TProperty property, PropertyValue & value) const override; + bool GetTargetProperty(TObject object, TProperty property, PropertyValue & value) const override; + private: + void ObtainObjectProperties(); + list> m_animations; TAnimObjects m_objects; map m_properties; + + string m_customType; }; } // namespace df diff --git a/drape_frontend/animation/sequence_animation.cpp b/drape_frontend/animation/sequence_animation.cpp index 13ed1ad7a1..4a2a121fa1 100644 --- a/drape_frontend/animation/sequence_animation.cpp +++ b/drape_frontend/animation/sequence_animation.cpp @@ -41,6 +41,8 @@ Animation::TObjectProperties const & SequenceAnimation::GetProperties(TObject ob bool SequenceAnimation::HasProperty(TObject object, TProperty property) const { + if (!HasObject(object)) + return false; ASSERT(!m_animations.empty(), ()); return m_animations.front()->HasProperty(object, property); } @@ -94,9 +96,9 @@ bool SequenceAnimation::GetTargetProperty(TObject object, TProperty property, Pr return false; } -void SequenceAnimation::AddAnimation(drape_ptr animation) +void SequenceAnimation::AddAnimation(drape_ptr && animation) { - m_animations.push_back(move(animation)); + m_animations.emplace_back(move(animation)); if (m_animations.size() == 1) ObtainObjectProperties(); } diff --git a/drape_frontend/animation/sequence_animation.hpp b/drape_frontend/animation/sequence_animation.hpp index 0cffac5c15..6fbd16c31a 100644 --- a/drape_frontend/animation/sequence_animation.hpp +++ b/drape_frontend/animation/sequence_animation.hpp @@ -30,7 +30,7 @@ public: bool GetProperty(TObject object, TProperty property, PropertyValue &value) const override; bool GetTargetProperty(TObject object, TProperty property, PropertyValue &value) const override; - void AddAnimation(drape_ptr animation); + void AddAnimation(drape_ptr && animation); void OnStart() override; void OnFinish() override; diff --git a/drape_frontend/animation_system.cpp b/drape_frontend/animation_system.cpp index b1acd5c1ff..7e4469b075 100644 --- a/drape_frontend/animation_system.cpp +++ b/drape_frontend/animation_system.cpp @@ -159,7 +159,7 @@ AnimationSystem & AnimationSystem::Instance() return animSystem; } -void AnimationSystem::CombineAnimation(drape_ptr animation) +void AnimationSystem::CombineAnimation(drape_ptr && animation) { #ifdef DEBUG_ANIMATIONS LOG(LINFO, ("Combine animation", animation->GetType())); @@ -233,7 +233,7 @@ void AnimationSystem::CombineAnimation(drape_ptr animation) PushAnimation(move(animation)); } -void AnimationSystem::PushAnimation(drape_ptr animation) +void AnimationSystem::PushAnimation(drape_ptr && animation) { #ifdef DEBUG_ANIMATIONS LOG(LINFO, ("Push animation", animation->GetType())); diff --git a/drape_frontend/animation_system.hpp b/drape_frontend/animation_system.hpp index 72bd6c7f03..f163f09695 100644 --- a/drape_frontend/animation_system.hpp +++ b/drape_frontend/animation_system.hpp @@ -30,8 +30,8 @@ public: bool AnimationExists(Animation::TObject object) const; bool HasAnimations() const; - void CombineAnimation(drape_ptr animation); - void PushAnimation(drape_ptr animation); + void CombineAnimation(drape_ptr && animation); + void PushAnimation(drape_ptr && animation); void FinishAnimations(Animation::Type type, bool rewind, bool finishAll); void FinishAnimations(Animation::Type type, string const & customType, bool rewind, bool finishAll); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 161fdb9026..a11d6ac551 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1609,30 +1609,32 @@ void FrontendRenderer::PositionChanged(m2::PointD const & position) m_userPositionChangedFn(position); } -void FrontendRenderer::ChangeModelView(m2::PointD const & center, int zoomLevel) +void FrontendRenderer::ChangeModelView(m2::PointD const & center, int zoomLevel, TAnimationCreator parallelAnimCreator) { - AddUserEvent(make_unique_dp(center, zoomLevel, true)); + AddUserEvent(make_unique_dp(center, zoomLevel, true, parallelAnimCreator)); } -void FrontendRenderer::ChangeModelView(double azimuth) +void FrontendRenderer::ChangeModelView(double azimuth, TAnimationCreator parallelAnimCreator) { - AddUserEvent(make_unique_dp(azimuth)); + AddUserEvent(make_unique_dp(azimuth, parallelAnimCreator)); } -void FrontendRenderer::ChangeModelView(m2::RectD const & rect) +void FrontendRenderer::ChangeModelView(m2::RectD const & rect, TAnimationCreator parallelAnimCreator) { - AddUserEvent(make_unique_dp(rect, true, kDoNotChangeZoom, true)); + AddUserEvent(make_unique_dp(rect, true, kDoNotChangeZoom, true, parallelAnimCreator)); } void FrontendRenderer::ChangeModelView(m2::PointD const & userPos, double azimuth, - m2::PointD const & pxZero, int preferredZoomLevel) + m2::PointD const & pxZero, int preferredZoomLevel, + TAnimationCreator parallelAnimCreator) { - AddUserEvent(make_unique_dp(userPos, pxZero, azimuth, preferredZoomLevel, true)); + AddUserEvent(make_unique_dp(userPos, pxZero, azimuth, preferredZoomLevel, true, parallelAnimCreator)); } -void FrontendRenderer::ChangeModelView(double autoScale, m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero) +void FrontendRenderer::ChangeModelView(double autoScale, m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero, + TAnimationCreator parallelAnimCreator) { - AddUserEvent(make_unique_dp(userPos, pxZero, azimuth, autoScale)); + AddUserEvent(make_unique_dp(userPos, pxZero, azimuth, autoScale, parallelAnimCreator)); } ScreenBase const & FrontendRenderer::ProcessEvents(bool & modelViewChanged, bool & viewportChanged) diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 9ae629e523..270109baa2 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -140,12 +140,13 @@ public: /// MyPositionController::Listener void PositionChanged(m2::PointD const & position) override; - void ChangeModelView(m2::PointD const & center, int zoomLevel) override; - void ChangeModelView(double azimuth) override; - void ChangeModelView(m2::RectD const & rect) override; + void ChangeModelView(m2::PointD const & center, int zoomLevel, TAnimationCreator parallelAnimCreator) override; + void ChangeModelView(double azimuth, TAnimationCreator parallelAnimCreator) override; + void ChangeModelView(m2::RectD const & rect, TAnimationCreator parallelAnimCreator) override; void ChangeModelView(m2::PointD const & userPos, double azimuth, - m2::PointD const & pxZero, int preferredZoomLevel) override; - void ChangeModelView(double autoScale, m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero) override; + m2::PointD const & pxZero, int preferredZoomLevel, TAnimationCreator parallelAnimCreator) override; + void ChangeModelView(double autoScale, m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero, + TAnimationCreator parallelAnimCreator) override; protected: void AcceptMessage(ref_ptr message) override; diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp index 5130a4a043..0f39443c7f 100644 --- a/drape_frontend/my_position_controller.cpp +++ b/drape_frontend/my_position_controller.cpp @@ -640,32 +640,32 @@ void MyPositionController::OnCompassTapped() void MyPositionController::ChangeModelView(m2::PointD const & center, int zoomLevel) { if (m_listener) - m_listener->ChangeModelView(center, zoomLevel); + m_listener->ChangeModelView(center, zoomLevel, m_animCreator); } void MyPositionController::ChangeModelView(double azimuth) { if (m_listener) - m_listener->ChangeModelView(azimuth); + m_listener->ChangeModelView(azimuth, m_animCreator); } void MyPositionController::ChangeModelView(m2::RectD const & rect) { if (m_listener) - m_listener->ChangeModelView(rect); + m_listener->ChangeModelView(rect, m_animCreator); } void MyPositionController::ChangeModelView(m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero, int zoomLevel) { if (m_listener) - m_listener->ChangeModelView(userPos, azimuth, pxZero, zoomLevel); + m_listener->ChangeModelView(userPos, azimuth, pxZero, zoomLevel, m_animCreator); } 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_listener->ChangeModelView(autoScale, userPos, azimuth, pxZero, m_animCreator); } void MyPositionController::UpdateViewport(int zoomLevel) @@ -741,10 +741,11 @@ void MyPositionController::CreateAnim(m2::PointD const & oldPos, double oldAzimu { if (IsModeChangeViewport()) { - m_animCreator = [this, oldPos, oldAzimut, moveDuration](double correctedDuration) + m_animCreator = [this, oldPos, oldAzimut, moveDuration](double correctedDuration) -> drape_ptr { - AnimationSystem::Instance().CombineAnimation(make_unique_dp(oldPos, m_position, - correctedDuration > 0.0 ? correctedDuration : moveDuration, oldAzimut, m_drawDirection)); + return make_unique_dp(oldPos, m_position, + correctedDuration > 0.0 ? correctedDuration : moveDuration, + oldAzimut, 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 64350ae3e3..29956224be 100644 --- a/drape_frontend/my_position_controller.hpp +++ b/drape_frontend/my_position_controller.hpp @@ -15,7 +15,9 @@ namespace df { + class Animation; +using TAnimationCreator = function(double)>; class MyPositionController { @@ -26,16 +28,16 @@ public: virtual ~Listener() {} virtual void PositionChanged(m2::PointD const & position) = 0; /// Show map with center in "center" point and current zoom - virtual void ChangeModelView(m2::PointD const & center, int zoomLevel) = 0; + virtual void ChangeModelView(m2::PointD const & center, int zoomLevel, TAnimationCreator parallelAnimCreator) = 0; /// Change azimuth of current ModelView - virtual void ChangeModelView(double azimuth) = 0; + virtual void ChangeModelView(double azimuth, TAnimationCreator parallelAnimCreator) = 0; /// Somehow show map that "rect" will see - virtual void ChangeModelView(m2::RectD const & rect) = 0; + virtual void ChangeModelView(m2::RectD const & rect, TAnimationCreator parallelAnimCreator) = 0; /// Show map where "usePos" (mercator) placed in "pxZero" on screen and map rotated around "userPos" virtual void ChangeModelView(m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero, - int zoomLevel) = 0; + int zoomLevel, TAnimationCreator parallelAnimCreator) = 0; virtual void ChangeModelView(double autoScale, - m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero) = 0; + m2::PointD const & userPos, double azimuth, m2::PointD const & pxZero, TAnimationCreator parallelAnimCreator) = 0; }; MyPositionController(location::EMyPositionMode initMode, double timeInBackground, @@ -167,7 +169,6 @@ private: bool m_isDirtyAutoZoom; bool m_isPendingAnimation; - using TAnimationCreator = function; TAnimationCreator m_animCreator; bool m_isPositionAssigned; diff --git a/drape_frontend/screen_animations.cpp b/drape_frontend/screen_animations.cpp index b896fa2445..fa8941afac 100644 --- a/drape_frontend/screen_animations.cpp +++ b/drape_frontend/screen_animations.cpp @@ -12,6 +12,8 @@ namespace df string const kPrettyMoveAnim = "PrettyMove"; string const kPrettyFollowAnim = "PrettyFollow"; +string const kParallelFollowAnim = "ParallelFollow"; +string const kParallelLinearAnim = "ParallelLinear"; drape_ptr GetPrettyMoveAnimation(ScreenBase const & startScreen, ScreenBase const & endScreen) { diff --git a/drape_frontend/screen_animations.hpp b/drape_frontend/screen_animations.hpp index ed81f3bd6f..e862eeaf12 100644 --- a/drape_frontend/screen_animations.hpp +++ b/drape_frontend/screen_animations.hpp @@ -9,6 +9,8 @@ namespace df extern string const kPrettyMoveAnim; extern string const kPrettyFollowAnim; +extern string const kParallelFollowAnim; +extern string const kParallelLinearAnim; class SequenceAnimation; class MapLinearAnimation; diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 9f93b133e5..907b44f250 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -1,7 +1,8 @@ #include "drape_frontend/user_event_stream.hpp" +#include "drape_frontend/animation/follow_animation.hpp" #include "drape_frontend/animation/linear_animation.hpp" #include "drape_frontend/animation/scale_animation.hpp" -#include "drape_frontend/animation/follow_animation.hpp" +#include "drape_frontend/animation/parallel_animation.hpp" #include "drape_frontend/animation/sequence_animation.hpp" #include "drape_frontend/animation_constants.hpp" #include "drape_frontend/animation_system.hpp" @@ -192,14 +193,16 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool { ref_ptr rectEvent = make_ref(e); breakAnim = SetRect(rectEvent->GetRect(), rectEvent->GetZoom(), - rectEvent->GetApplyRotation(), rectEvent->IsAnim()); + rectEvent->GetApplyRotation(), rectEvent->IsAnim(), + rectEvent->GetParallelAnimCreator()); TouchCancel(m_touches); } break; case UserEvent::SetCenter: { ref_ptr centerEvent = make_ref(e); - breakAnim = SetCenter(centerEvent->GetCenter(), centerEvent->GetZoom(), centerEvent->IsAnim()); + breakAnim = SetCenter(centerEvent->GetCenter(), centerEvent->GetZoom(), centerEvent->IsAnim(), + centerEvent->GetParallelAnimCreator()); TouchCancel(m_touches); } break; @@ -218,13 +221,14 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool m2::PointD pt = screen.PixelRectIn3d().Center(); breakAnim = SetFollowAndRotate(screen.PtoG(screen.P3dtoP(pt)), pt, rotateEvent->GetTargetAzimuth(), kDoNotChangeZoom, kDoNotAutoZoom, - true /* isAnim */, false /* isAutoScale */); + true /* isAnim */, false /* isAutoScale */, + rotateEvent->GetParallelAnimCreator()); } else { m2::AnyRectD dstRect = GetTargetRect(); dstRect.SetAngle(rotateEvent->GetTargetAzimuth()); - breakAnim = SetRect(dstRect, true); + breakAnim = SetRect(dstRect, true, rotateEvent->GetParallelAnimCreator()); } } break; @@ -233,7 +237,8 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool ref_ptr followEvent = make_ref(e); breakAnim = SetFollowAndRotate(followEvent->GetUserPos(), followEvent->GetPixelZero(), followEvent->GetAzimuth(), followEvent->GetPreferredZoomLelel(), - followEvent->GetAutoScale(), followEvent->IsAnim(), followEvent->IsAutoScale()); + followEvent->GetAutoScale(), followEvent->IsAnim(), followEvent->IsAutoScale(), + followEvent->GetParallelAnimCreator()); } break; case UserEvent::AutoPerspective: @@ -335,7 +340,7 @@ bool UserEventStream::SetScale(m2::PointD const & pxScaleCenter, double factor, return true; } -bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim) +bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim, TAnimationCreator parallelAnimCreator) { ScreenBase screen = GetCurrentScreen(); if (zoom == kDoNotChangeZoom) @@ -351,27 +356,21 @@ bool UserEventStream::SetCenter(m2::PointD const & center, int zoom, bool isAnim ShrinkAndScaleInto(screen, df::GetWorldRect()); - return SetScreen(screen, isAnim); + return SetScreen(screen, isAnim, parallelAnimCreator); } -bool UserEventStream::SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim) +bool UserEventStream::SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim, TAnimationCreator parallelAnimCreator) { CheckMinGlobalRect(rect, kDefault3dScale); CheckMinMaxVisibleScale(rect, zoom, kDefault3dScale); m2::AnyRectD targetRect = applyRotation ? ToRotated(m_navigator, rect) : m2::AnyRectD(rect); - return SetRect(targetRect, isAnim); + return SetRect(targetRect, isAnim, parallelAnimCreator); } -bool UserEventStream::SetScreen(ScreenBase const & endScreen, bool isAnim) +bool UserEventStream::SetScreen(ScreenBase const & endScreen, bool isAnim, TAnimationCreator parallelAnimCreator) { if (isAnim) { - auto onStartHandler = [this](ref_ptr animation) - { - if (m_listener) - m_listener->OnAnimationStarted(animation); - }; - ScreenBase const & screen = GetCurrentScreen(); drape_ptr anim = GetRectAnimation(screen, endScreen); @@ -386,8 +385,18 @@ bool UserEventStream::SetScreen(ScreenBase const & endScreen, bool isAnim) if (anim != nullptr) { - anim->SetOnStartAction(onStartHandler); - m_animationSystem.CombineAnimation(move(anim)); + if (parallelAnimCreator != nullptr) + { + drape_ptr parallelAnim = make_unique_dp(); + parallelAnim->SetCustomType(kParallelLinearAnim); + parallelAnim->AddAnimation(parallelAnimCreator(anim->GetDuration())); + parallelAnim->AddAnimation(move(anim)); + m_animationSystem.CombineAnimation(move(parallelAnim)); + } + else + { + m_animationSystem.CombineAnimation(move(anim)); + } return false; } } @@ -397,13 +406,13 @@ bool UserEventStream::SetScreen(ScreenBase const & endScreen, bool isAnim) return true; } -bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim) +bool UserEventStream::SetRect(m2::AnyRectD const & rect, bool isAnim, TAnimationCreator parallelAnimCreator) { ScreenBase tmp = GetCurrentScreen(); tmp.SetFromRects(rect, tmp.PixelRectIn3d()); tmp.MatchGandP3d(rect.GlobalCenter(), tmp.PixelRectIn3d().Center()); - return SetScreen(tmp, isAnim); + return SetScreen(tmp, isAnim, parallelAnimCreator); } bool UserEventStream::InterruptFollowAnimations(bool force) @@ -413,15 +422,16 @@ bool UserEventStream::InterruptFollowAnimations(bool force) if (followAnim == nullptr) followAnim = m_animationSystem.FindAnimation(Animation::Sequence, kPrettyFollowAnim.c_str()); + if (followAnim == nullptr) + followAnim = m_animationSystem.FindAnimation(Animation::Parallel, kParallelFollowAnim.c_str()); + + if (followAnim == nullptr) + followAnim = m_animationSystem.FindAnimation(Animation::Parallel, kParallelLinearAnim.c_str()); + if (followAnim != nullptr) { if (force || followAnim->CouldBeInterrupted()) - { - bool const isFollowAnim = followAnim->GetType() == Animation::MapFollow; - ResetAnimations(followAnim->GetType()); - if (isFollowAnim) - ResetAnimations(Animation::Arrow); - } + ResetAnimations(followAnim->GetType(), followAnim->GetCustomType()); else { return false; @@ -432,7 +442,7 @@ bool UserEventStream::InterruptFollowAnimations(bool force) bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD const & pixelPos, double azimuth, int preferredZoomLevel, double autoScale, - bool isAnim, bool isAutoScale) + bool isAnim, bool isAutoScale, TAnimationCreator parallelAnimCreator) { // Reset current follow-and-rotate animation if possible. if (isAnim && !InterruptFollowAnimations(false /* force */)) @@ -456,12 +466,6 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD if (isAnim) { - auto onStartHandler = [this](ref_ptr animation) - { - if (m_listener) - m_listener->OnAnimationStarted(animation); - }; - drape_ptr anim; double const moveDuration = PositionInterpolator::GetMoveDuration(currentScreen.GetOrg(), screen.GetOrg(), currentScreen.PixelRectIn3d(), @@ -483,8 +487,18 @@ bool UserEventStream::SetFollowAndRotate(m2::PointD const & userPos, m2::PointD anim->SetCouldBeBlended(false); } - anim->SetOnStartAction(onStartHandler); - m_animationSystem.CombineAnimation(move(anim)); + if (parallelAnimCreator != nullptr) + { + drape_ptr parallelAnim = make_unique_dp(); + parallelAnim->SetCustomType(kParallelFollowAnim); + parallelAnim->AddAnimation(parallelAnimCreator(anim->GetDuration())); + parallelAnim->AddAnimation(move(anim)); + m_animationSystem.CombineAnimation(move(parallelAnim)); + } + else + { + m_animationSystem.CombineAnimation(move(anim)); + } return false; } diff --git a/drape_frontend/user_event_stream.hpp b/drape_frontend/user_event_stream.hpp index 73690c1a5f..d969e72147 100644 --- a/drape_frontend/user_event_stream.hpp +++ b/drape_frontend/user_event_stream.hpp @@ -23,6 +23,8 @@ namespace df int const kDoNotChangeZoom = -1; double const kDoNotAutoZoom = -1.0; +using TAnimationCreator = function(double)>; + class UserEvent { public: @@ -134,10 +136,12 @@ private: class SetCenterEvent : public UserEvent { public: - SetCenterEvent(m2::PointD const & center, int zoom, bool isAnim) + SetCenterEvent(m2::PointD const & center, int zoom, bool isAnim, + TAnimationCreator parallelAnimCreator = nullptr) : m_center(center) , m_zoom(zoom) , m_isAnim(isAnim) + , m_parallelAnimCreator(parallelAnimCreator) { } @@ -146,21 +150,25 @@ public: m2::PointD const & GetCenter() const { return m_center; } int GetZoom() const { return m_zoom; } bool IsAnim() const { return m_isAnim; } + TAnimationCreator const & GetParallelAnimCreator() const { return m_parallelAnimCreator; } private: m2::PointD m_center; // center point in mercator int m_zoom; // if zoom == -1, then zoom level will'n change bool m_isAnim; + TAnimationCreator m_parallelAnimCreator; }; class SetRectEvent : public UserEvent { public: - SetRectEvent(m2::RectD const & rect, bool rotate, int zoom, bool isAnim) + SetRectEvent(m2::RectD const & rect, bool rotate, int zoom, bool isAnim, + TAnimationCreator parallelAnimCreator = nullptr) : m_rect(rect) , m_applyRotation(rotate) , m_zoom(zoom) , m_isAnim(isAnim) + , m_parallelAnimCreator(parallelAnimCreator) { } @@ -170,12 +178,14 @@ public: bool GetApplyRotation() const { return m_applyRotation; } int GetZoom() const { return m_zoom; } bool IsAnim() const { return m_isAnim; } + TAnimationCreator const & GetParallelAnimCreator() const { return m_parallelAnimCreator; } private: m2::RectD m_rect; // destination mercator rect bool m_applyRotation; // if true, current rotation will be apply to m_rect int m_zoom; // if zoom == -1, then zoom level will'n change bool m_isAnim; + TAnimationCreator m_parallelAnimCreator; }; class SetAnyRectEvent : public UserEvent @@ -200,7 +210,7 @@ class FollowAndRotateEvent : public UserEvent { public: FollowAndRotateEvent(m2::PointD const & userPos, m2::PointD const & pixelZero, - double azimuth, double autoScale) + double azimuth, double autoScale, TAnimationCreator parallelAnimCreator = nullptr) : m_userPos(userPos) , m_pixelZero(pixelZero) , m_azimuth(azimuth) @@ -208,12 +218,13 @@ public: , m_autoScale(autoScale) , m_isAutoScale(true) , m_isAnim(true) + , m_parallelAnimCreator(parallelAnimCreator) { } FollowAndRotateEvent(m2::PointD const & userPos, m2::PointD const & pixelZero, double azimuth, int preferredZoomLevel, - bool isAnim) + bool isAnim, TAnimationCreator parallelAnimCreator = nullptr) : m_userPos(userPos) , m_pixelZero(pixelZero) , m_azimuth(azimuth) @@ -221,6 +232,7 @@ public: , m_autoScale(kDoNotAutoZoom) , m_isAutoScale(false) , m_isAnim(isAnim) + , m_parallelAnimCreator(parallelAnimCreator) {} EEventType GetType() const override { return UserEvent::FollowAndRotate; } @@ -232,6 +244,7 @@ public: double GetAutoScale() const { return m_autoScale; } bool IsAutoScale() const { return m_isAutoScale; } bool IsAnim() const { return m_isAnim; } + TAnimationCreator const & GetParallelAnimCreator() const { return m_parallelAnimCreator; } private: m2::PointD m_userPos; @@ -241,6 +254,7 @@ private: double m_autoScale; bool m_isAutoScale; bool m_isAnim; + TAnimationCreator m_parallelAnimCreator; }; class SetAutoPerspectiveEvent : public UserEvent @@ -261,16 +275,19 @@ private: class RotateEvent : public UserEvent { public: - RotateEvent(double targetAzimut) + RotateEvent(double targetAzimut, TAnimationCreator parallelAnimCreator = nullptr) : m_targetAzimut(targetAzimut) + , m_parallelAnimCreator(parallelAnimCreator) {} EEventType GetType() const override { return UserEvent::Rotate; } double GetTargetAzimuth() const { return m_targetAzimut; } + TAnimationCreator const & GetParallelAnimCreator() const { return m_parallelAnimCreator; } private: double m_targetAzimut; + TAnimationCreator m_parallelAnimCreator; }; class ResizeEvent : public UserEvent @@ -357,13 +374,18 @@ public: private: bool SetScale(m2::PointD const & pxScaleCenter, double factor, bool isAnim); - bool SetCenter(m2::PointD const & center, int zoom, bool isAnim); - bool SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim); - bool SetRect(m2::AnyRectD const & rect, bool isAnim); - bool SetScreen(ScreenBase const & screen, bool isAnim); + bool SetCenter(m2::PointD const & center, int zoom, bool isAnim, + TAnimationCreator parallelAnimCreator = nullptr); + bool SetRect(m2::RectD rect, int zoom, bool applyRotation, bool isAnim, + TAnimationCreator parallelAnimCreator = nullptr); + bool SetRect(m2::AnyRectD const & rect, bool isAnim, + TAnimationCreator parallelAnimCreator = nullptr); + bool SetScreen(ScreenBase const & screen, bool isAnim, + TAnimationCreator parallelAnimCreator = nullptr); bool SetFollowAndRotate(m2::PointD const & userPos, m2::PointD const & pixelPos, double azimuth, int preferredZoomLevel, double autoScale, - bool isAnim, bool isAutoScale); + bool isAnim, bool isAutoScale, + TAnimationCreator parallelAnimCreator = nullptr); void SetAutoPerspective(bool isAutoPerspective); m2::AnyRectD GetCurrentRect() const; -- cgit v1.2.3