added Animator class as a central manager of all map-related animations.

This commit is contained in:
rachytski 2012-09-24 18:05:46 +03:00 committed by Alex Zolotarev
parent c928d967c8
commit 43e6ed5c89
7 changed files with 102 additions and 44 deletions

52
map/animator.cpp Normal file
View file

@ -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();
}

31
map/animator.hpp Normal file
View file

@ -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<RotateScreenTask> 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();
};

View file

@ -117,6 +117,7 @@ static void GetResourcesMaps(vector<string> & 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;

View file

@ -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<search::Engine> m_pSearchEngine;
model::FeaturesFetcher m_model;
Navigator m_navigator;
Animator m_animator;
vector<BookmarkCategory *> m_bookmarks;
@ -356,6 +358,8 @@ public:
gui::Controller * GetGuiController() const;
anim::Controller * GetAnimController() const;
Animator & GetAnimator();
Navigator & GetNavigator();
/// Set the localized strings bundle

View file

@ -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

View file

@ -60,8 +60,6 @@ namespace location
ELocationProcessMode m_locationProcessMode;
ECompassProcessMode m_compassProcessMode;
shared_ptr<RotateScreenTask> 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;

View file

@ -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