[core] create new bookmark animation

This commit is contained in:
ExMix 2014-05-16 16:31:39 +03:00 committed by Alex Zolotarev
parent e9f7e1d796
commit 751657cf72
8 changed files with 192 additions and 79 deletions

69
map/anim_phase_chain.cpp Normal file
View file

@ -0,0 +1,69 @@
#include "anim_phase_chain.hpp"
#include "framework.hpp"
AnimPhase::AnimPhase(double endScale, double timeInterval)
: m_endScale(endScale)
, m_timeInterval(timeInterval)
{
}
AnimPhaseChain::AnimPhaseChain(Framework & f, double & scale)
: m_f(f)
, m_scale(scale)
{
}
void AnimPhaseChain::AddAnimPhase(AnimPhase const & phase)
{
m_animPhases.push_back(phase);
}
void AnimPhaseChain::OnStart(double ts)
{
m_startTime = ts;
m_startScale = m_scale;
m_phaseIndex = 0;
}
void AnimPhaseChain::OnStep(double ts)
{
ASSERT(m_phaseIndex < m_animPhases.size(), ());
AnimPhase const * phase = &m_animPhases[m_phaseIndex];
double elapsedTime = ts - m_startTime;
if (elapsedTime > phase->m_timeInterval)
{
m_startTime = ts;
m_scale = phase->m_endScale;
m_startScale = m_scale;
m_phaseIndex++;
if (m_phaseIndex >= m_animPhases.size())
{
End();
return;
}
}
elapsedTime = ts - m_startTime;
double t = elapsedTime / phase->m_timeInterval;
m_scale = m_startScale + t * (phase->m_endScale - m_startScale);
m_f.Invalidate();
}
void InitDefaultPinAnim(AnimPhaseChain * chain)
{
chain->AddAnimPhase(AnimPhase(1.2, 0.15));
chain->AddAnimPhase(AnimPhase(0.8, 0.08));
chain->AddAnimPhase(AnimPhase(1, 0.05));
}
shared_ptr<anim::Task> CreateDefaultPinAnim(Framework & f, double & scale)
{
AnimPhaseChain * anim = new AnimPhaseChain(f, scale);
InitDefaultPinAnim(anim);
return make_shared_ptr<anim::Task>(anim);
}

37
map/anim_phase_chain.hpp Normal file
View file

@ -0,0 +1,37 @@
#pragma once
#include "../anim/task.hpp"
#include "../std/shared_ptr.hpp"
class Framework;
struct AnimPhase
{
AnimPhase(double endScale, double timeInterval);
double m_endScale;
double m_timeInterval;
};
class AnimPhaseChain : public anim::Task
{
public:
AnimPhaseChain(Framework & f, double & scale);
void AddAnimPhase(AnimPhase const & phase);
virtual void OnStart(double ts);
virtual void OnStep(double ts);
private:
Framework & m_f;
vector<AnimPhase> m_animPhases;
size_t m_phaseIndex;
double & m_scale;
double m_startTime;
double m_startScale;
};
void InitDefaultPinAnim(AnimPhaseChain * chain);
shared_ptr<anim::Task> CreateDefaultPinAnim(Framework & f, double & scale);

View file

@ -1,5 +1,12 @@
#include "bookmark.hpp"
#include "track.hpp"
#include "anim_phase_chain.hpp"
#include "framework.hpp"
#include "../anim/controller.hpp"
#include "../base/scope_guard.hpp"
#include "../graphics/depth_constants.hpp"
@ -19,6 +26,22 @@
#include "../std/algorithm.hpp"
#include "../std/auto_ptr.hpp"
graphics::DisplayList * Bookmark::GetDisplayList(UserMarkDLCache * cache) const
{
return cache->FindUserMark(UserMarkDLCache::Key(GetType(), graphics::EPosAbove, GetContainer()->GetDepth()));
}
double Bookmark::GetAnimScaleFactor() const
{
return m_animScaleFactor;
}
shared_ptr<anim::Task> Bookmark::CreateAnimTask(Framework & fm)
{
m_animScaleFactor = 0.0;
return CreateDefaultPinAnim(fm, m_animScaleFactor);
}
void BookmarkCategory::AddTrack(Track & track)
{
m_tracks.push_back(track.CreatePersistent());
@ -49,6 +72,7 @@ void BookmarkCategory::ReplaceBookmark(size_t index, BookmarkData const & bm)
BookmarkCategory::BookmarkCategory(const string & name, Framework & framework)
: base_t(graphics::bookmarkDepth, framework)
, m_name(name)
, m_blockAnimation(false)
{
}
@ -493,8 +517,31 @@ string BookmarkCategory::GetDefaultType()
return s_arrSupportedColors[0];
}
namespace
{
struct AnimBlockGuard
{
public:
AnimBlockGuard(bool & block)
: m_block(block)
{
m_block = true;
}
~AnimBlockGuard()
{
m_block = false;
}
private:
bool & m_block;
};
}
bool BookmarkCategory::LoadFromKML(ReaderPtr<Reader> const & reader)
{
AnimBlockGuard g(m_blockAnimation);
ReaderSource<ReaderPtr<Reader> > src(reader);
KMLParser parser(*this);
if (ParseXML(src, parser, true))
@ -746,7 +793,10 @@ string BookmarkCategory::GenerateUniqueFileName(const string & path, string name
UserMark * BookmarkCategory::AllocateUserMark(m2::PointD const & ptOrg)
{
return new Bookmark(ptOrg, this);
Bookmark * b = new Bookmark(ptOrg, this);
if (!m_blockAnimation)
m_framework.GetAnimController()->AddTask(b->CreateAnimTask(m_framework));
return b;
}
bool BookmarkCategory::SaveToKMLFile()

View file

@ -13,7 +13,12 @@
#include "../std/string.hpp"
#include "../std/noncopyable.hpp"
#include "../std/iostream.hpp"
#include "../std/shared_ptr.hpp"
namespace anim
{
class Task;
}
class Track;
@ -27,8 +32,8 @@ public:
}
BookmarkData(string const & name, string const & type,
string const & description = "", double scale = -1.0,
time_t timeStamp = my::INVALID_TIME_STAMP)
string const & description = "", double scale = -1.0,
time_t timeStamp = my::INVALID_TIME_STAMP)
: m_name(name)
, m_description(description)
, m_type(type)
@ -63,10 +68,12 @@ private:
class Bookmark : public ICustomDrawable
{
BookmarkData m_data;
double m_animScaleFactor;
public:
Bookmark(m2::PointD const & ptOrg, UserMarkContainer * container)
: ICustomDrawable(ptOrg, container)
, m_animScaleFactor(1.0)
{
}
@ -75,6 +82,7 @@ public:
UserMarkContainer * container)
: ICustomDrawable(ptOrg, container)
, m_data(data)
, m_animScaleFactor(1.0)
{
}
@ -100,10 +108,9 @@ public:
double GetScale() const { return m_data.GetScale(); }
void SetScale(double scale) { m_data.SetScale(scale); }
virtual graphics::DisplayList * GetDisplayList(UserMarkDLCache * cache) const
{
return cache->FindUserMark(UserMarkDLCache::Key(GetType(), graphics::EPosAbove, GetContainer()->GetDepth()));
}
virtual graphics::DisplayList * GetDisplayList(UserMarkDLCache * cache) const;
virtual double GetAnimScaleFactor() const;
shared_ptr<anim::Task> CreateAnimTask(Framework & fm);
};
class BookmarkCategory : public UserMarkContainer
@ -178,6 +185,9 @@ protected:
virtual string GetTypeName() const { return "search-result"; }
virtual string GetActiveTypeName() const { return "search-result-active"; }
virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg);
private:
bool m_blockAnimation;
};
/// <category index, bookmark index>

View file

@ -67,7 +67,8 @@ HEADERS += \
alfa_animation_task.hpp \
user_mark_container.hpp \
user_mark.hpp \
user_mark_dl_cache.hpp
user_mark_dl_cache.hpp \
anim_phase_chain.hpp
SOURCES += \
feature_vec_model.cpp \
@ -121,7 +122,8 @@ SOURCES += \
alfa_animation_task.cpp \
user_mark_container.cpp \
user_mark.cpp \
user_mark_dl_cache.cpp
user_mark_dl_cache.cpp \
anim_phase_chain.cpp
!iphone*:!tizen*:!android* {
HEADERS += qgl_render_context.hpp

View file

@ -119,4 +119,5 @@ public:
ICustomDrawable(m2::PointD const & ptOrg, UserMarkContainer * container) : UserMark(ptOrg, container) {}
bool IsCustomDrawable() const { return true; }
virtual graphics::DisplayList * GetDisplayList(UserMarkDLCache * cache) const = 0;
virtual double GetAnimScaleFactor() const = 0;
};

View file

@ -2,6 +2,7 @@
#include "drawer.hpp"
#include "framework.hpp"
#include "anim_phase_chain.hpp"
#include "../graphics/display_list.hpp"
#include "../graphics/screen.hpp"
@ -17,65 +18,17 @@
#include "../std/scoped_ptr.hpp"
#include "../std/algorithm.hpp"
////////////////////////////////////////////////////////////////////////
namespace
{
struct AnimPhase
{
AnimPhase(double endScale, double timeInterval)
: m_endScale(endScale)
, m_timeInterval(timeInterval)
{
}
double m_endScale;
double m_timeInterval;
};
class PinAnimation : public anim::Task
class PinAnimation : public AnimPhaseChain
{
public:
PinAnimation(Framework & f)
: m_f(f)
, m_scale(0.0)
: AnimPhaseChain(f, m_scale)
{
}
void AddAnimPhase(AnimPhase const & phase)
{
m_animPhases.push_back(phase);
}
virtual void OnStart(double ts)
{
m_startTime = ts;
m_startScale = m_scale;
m_phaseIndex = 0;
}
virtual void OnStep(double ts)
{
ASSERT(m_phaseIndex < m_animPhases.size(), ());
AnimPhase const * phase = &m_animPhases[m_phaseIndex];
double elapsedTime = ts - m_startTime;
if (elapsedTime > phase->m_timeInterval)
{
m_startTime = ts;
m_scale = phase->m_endScale;
m_startScale = m_scale;
m_phaseIndex++;
if (m_phaseIndex >= m_animPhases.size())
{
End();
return;
}
}
elapsedTime = ts - m_startTime;
double t = elapsedTime / phase->m_timeInterval;
m_scale = m_startScale + t * (phase->m_endScale - m_startScale);
m_f.Invalidate();
InitDefaultPinAnim(this);
}
double GetScale() const
@ -84,19 +37,9 @@ namespace
}
private:
Framework & m_f;
vector<AnimPhase> m_animPhases;
size_t m_phaseIndex;
double m_scale;
double m_startTime;
double m_startScale;
};
}
////////////////////////////////////////////////////////////////////////
namespace
{
class FindMarkFunctor
{
public:
@ -158,7 +101,10 @@ namespace
UserMark const * mark)
{
if (mark->IsCustomDrawable())
DrawUserMarkImpl(scale, event, static_cast<ICustomDrawable const *>(mark)->GetDisplayList(cache), mark);
{
ICustomDrawable const * drawable = static_cast<ICustomDrawable const *>(mark);
DrawUserMarkImpl(drawable->GetAnimScaleFactor(), event, drawable->GetDisplayList(cache), mark);
}
else
DefaultDrawUserMark(scale, event, cache, defaultKey, mark);
}
@ -298,11 +244,7 @@ void UserMarkContainer::DeleteUserMark(UserMark const * mark)
void UserMarkContainer::StartActivationAnim()
{
PinAnimation * anim = new PinAnimation(m_framework);
anim->AddAnimPhase(AnimPhase(1.2, 0.15));
anim->AddAnimPhase(AnimPhase(0.8, 0.08));
anim->AddAnimPhase(AnimPhase(1, 0.05));
m_animTask.reset(anim);
m_animTask.reset(new PinAnimation(m_framework));
m_framework.GetAnimController()->AddTask(m_animTask);
}

View file

@ -98,13 +98,15 @@ private:
vector<UserMark *> m_userMarks;
UserMark const * m_activeMark;
protected:
Framework & m_framework;
private:
/// animation support
void StartActivationAnim();
void KillActivationAnim();
double GetActiveMarkScale() const;
Framework & m_framework;
shared_ptr<anim::Task> m_animTask;
};