From 43e6ed5c8914b42d4d4666ecf2ddc78490a5b1ee Mon Sep 17 00:00:00 2001 From: rachytski Date: Mon, 24 Sep 2012 18:05:46 +0300 Subject: [PATCH] added Animator class as a central manager of all map-related animations. --- map/animator.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++ map/animator.hpp | 31 +++++++++++++++++++++++++ map/framework.cpp | 6 +++++ map/framework.hpp | 4 ++++ map/location_state.cpp | 44 ++++------------------------------- map/location_state.hpp | 3 --- map/map.pro | 6 +++-- 7 files changed, 102 insertions(+), 44 deletions(-) create mode 100644 map/animator.cpp create mode 100644 map/animator.hpp diff --git a/map/animator.cpp b/map/animator.cpp new file mode 100644 index 0000000000..370f27a2c7 --- /dev/null +++ b/map/animator.cpp @@ -0,0 +1,52 @@ +#include "animator.hpp" +#include "rotate_screen_task.hpp" +#include "framework.hpp" + +#include "../anim/controller.hpp" + +#include "../geometry/angles.hpp" + +Animator::Animator(Framework * framework) + : m_framework(framework) +{ + m_rotationThreshold = ang::DegreeToRad(10); +} + +void Animator::RotateScreen(double startAngle, double endAngle, double duration) +{ + bool shouldRotate = false; + + if (m_rotateScreenTask && m_rotateScreenTask->IsRunning()) + { + // if the end angle seriously changed we should re-create rotation task. + if (fabs(ang::GetShortestDistance(m_rotateScreenTask->EndAngle(), endAngle)) > m_rotationThreshold) + shouldRotate = true; + } + else + { + // if there are no current rotate screen task or the task is finished already + // we check for the distance between current screen angle and headingAngle + if (fabs(ang::GetShortestDistance(startAngle, endAngle)) > m_rotationThreshold) + shouldRotate = true; + } + + if (shouldRotate) + { + StopRotation(); + m_rotateScreenTask.reset(new RotateScreenTask(m_framework, + startAngle, + endAngle, + duration)); + + m_framework->GetAnimController()->AddTask(m_rotateScreenTask); + } +} + +void Animator::StopRotation() +{ + if (m_rotateScreenTask + && m_rotateScreenTask->IsRunning()) + m_rotateScreenTask->Cancel(); + + m_rotateScreenTask.reset(); +} diff --git a/map/animator.hpp b/map/animator.hpp new file mode 100644 index 0000000000..d8ef6ef5f7 --- /dev/null +++ b/map/animator.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "../std/shared_ptr.hpp" + +class Framework; +class RotateScreenTask; + +/// Class, which is responsible for +/// tracking all map animations. +class Animator +{ +private: + + Framework * m_framework; + + shared_ptr m_rotateScreenTask; + + bool m_rotationThreshold; + +public: + + /// constructor by Framework + Animator(Framework * framework); + /// rotate screen by shortest path. + void RotateScreen(double startAngle, + double endAngle, + double duration); + /// stopping screen rotation + void StopRotation(); + +}; diff --git a/map/framework.cpp b/map/framework.cpp index f1ded5360f..48d8deaccd 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -117,6 +117,7 @@ static void GetResourcesMaps(vector & outMaps) Framework::Framework() : //m_hasPendingInvalidate(false), //m_doForceUpdate(false), + m_animator(this), m_etalonSize(GetPlatform().ScaleEtalonSize()), m_queryMaxScaleMode(false), m_drawPlacemark(false), @@ -1317,6 +1318,11 @@ bool Framework::GetVisiblePOI(m2::PointD const & pxPoint, m2::PointD & pxPivot, return false; } +Animator & Framework::GetAnimator() +{ + return m_animator; +} + Navigator & Framework::GetNavigator() { return m_navigator; diff --git a/map/framework.hpp b/map/framework.hpp index 55470af39f..0ef391a074 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -6,6 +6,7 @@ #include "window_handle.hpp" #include "location_state.hpp" #include "navigator.hpp" +#include "animator.hpp" #include "feature_vec_model.hpp" #include "bookmark.hpp" @@ -71,6 +72,7 @@ protected: mutable scoped_ptr m_pSearchEngine; model::FeaturesFetcher m_model; Navigator m_navigator; + Animator m_animator; vector m_bookmarks; @@ -356,6 +358,8 @@ public: gui::Controller * GetGuiController() const; anim::Controller * GetAnimController() const; + + Animator & GetAnimator(); Navigator & GetNavigator(); /// Set the localized strings bundle diff --git a/map/location_state.cpp b/map/location_state.cpp index 23c6be4516..dcce01ccc2 100644 --- a/map/location_state.cpp +++ b/map/location_state.cpp @@ -376,7 +376,9 @@ namespace location void State::CheckFollowCompass() { - if (m_hasCompass && (CompassProcessMode() == ECompassFollow) && IsCentered()) + if (m_hasCompass + && (CompassProcessMode() == ECompassFollow) + && IsCentered()) FollowCompass(); } @@ -392,51 +394,15 @@ namespace location double startAngle = m_framework->GetNavigator().Screen().GetAngle(); double endAngle = -m_compassFilter.GetHeadingRad(); - bool shouldRotate = false; - - if (m_rotateScreenTask && m_rotateScreenTask->IsRunning()) - { - // if the end angle seriously changed we should re-create rotation task. - if (fabs(ang::GetShortestDistance(m_rotateScreenTask->EndAngle(), endAngle)) > ang::DegreeToRad(10)) - shouldRotate = true; - } - else - { - // if there are no current rotate screen task or the task is finished already - // we check for the distance between current screen angle and headingAngle - if (fabs(ang::GetShortestDistance(startAngle, endAngle)) > ang::DegreeToRad(10)) - shouldRotate = true; - } - - if (shouldRotate) - { - m_framework->GetInformationDisplay().locationState()->StopAnimation(); - StopAnimation(); - - m_rotateScreenTask.reset(new RotateScreenTask(m_framework, - startAngle, - endAngle, - 2)); - - controller->AddTask(m_rotateScreenTask); - } + m_framework->GetAnimator().RotateScreen(startAngle, endAngle, 2); controller->Unlock(); } - void State::StopAnimation() - { - if (m_rotateScreenTask - && !m_rotateScreenTask->IsEnded() - && !m_rotateScreenTask->IsCancelled()) - m_rotateScreenTask->Cancel(); - m_rotateScreenTask.reset(); - } - void State::StopCompassFollowing() { SetCompassProcessMode(ECompassDoNothing); - StopAnimation(); + m_framework->GetAnimator().StopRotation(); } bool State::IsCentered() const diff --git a/map/location_state.hpp b/map/location_state.hpp index d894c00179..f5482ca5dc 100644 --- a/map/location_state.hpp +++ b/map/location_state.hpp @@ -60,8 +60,6 @@ namespace location ELocationProcessMode m_locationProcessMode; ECompassProcessMode m_compassProcessMode; - shared_ptr m_rotateScreenTask; - void FollowCompass(); /// GUI element related fields. @@ -119,7 +117,6 @@ namespace location void TurnOff(); - void StopAnimation(); void StopCompassFollowing(); void SetIsCentered(bool flag); bool IsCentered() const; diff --git a/map/map.pro b/map/map.pro index 7397cccc48..27047603e8 100644 --- a/map/map.pro +++ b/map/map.pro @@ -50,7 +50,8 @@ HEADERS += \ country_status_display.hpp \ rotate_screen_task.hpp \ compass_arrow.hpp \ - compass_filter.hpp + compass_filter.hpp \ + animator.hpp SOURCES += \ feature_vec_model.cpp \ @@ -92,7 +93,8 @@ SOURCES += \ country_status_display.cpp \ rotate_screen_task.cpp \ compass_arrow.cpp \ - compass_filter.cpp + compass_filter.cpp \ + animator.cpp !iphone*:!bada*:!android* { HEADERS += qgl_render_context.hpp