diff --git a/map/anim_phase_chain.cpp b/map/anim_phase_chain.cpp new file mode 100644 index 0000000000..e37cc54ab2 --- /dev/null +++ b/map/anim_phase_chain.cpp @@ -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 CreateDefaultPinAnim(Framework & f, double & scale) +{ + AnimPhaseChain * anim = new AnimPhaseChain(f, scale); + InitDefaultPinAnim(anim); + + return make_shared_ptr(anim); +} + diff --git a/map/anim_phase_chain.hpp b/map/anim_phase_chain.hpp new file mode 100644 index 0000000000..5530fb78c0 --- /dev/null +++ b/map/anim_phase_chain.hpp @@ -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 m_animPhases; + size_t m_phaseIndex; + double & m_scale; + double m_startTime; + double m_startScale; +}; + +void InitDefaultPinAnim(AnimPhaseChain * chain); +shared_ptr CreateDefaultPinAnim(Framework & f, double & scale); diff --git a/map/bookmark.cpp b/map/bookmark.cpp index d9e08b81a7..ece60bade1 100644 --- a/map/bookmark.cpp +++ b/map/bookmark.cpp @@ -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 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 const & reader) { + AnimBlockGuard g(m_blockAnimation); + ReaderSource > 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() diff --git a/map/bookmark.hpp b/map/bookmark.hpp index f181951d85..f3716d0f17 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -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 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; }; /// diff --git a/map/map.pro b/map/map.pro index dfdd657933..20fba9733b 100644 --- a/map/map.pro +++ b/map/map.pro @@ -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 diff --git a/map/user_mark.hpp b/map/user_mark.hpp index d148f4b2d6..2f7ed6aa53 100644 --- a/map/user_mark.hpp +++ b/map/user_mark.hpp @@ -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; }; diff --git a/map/user_mark_container.cpp b/map/user_mark_container.cpp index 3b8c847a0f..cf4fec6976 100644 --- a/map/user_mark_container.cpp +++ b/map/user_mark_container.cpp @@ -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 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(mark)->GetDisplayList(cache), mark); + { + ICustomDrawable const * drawable = static_cast(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); } diff --git a/map/user_mark_container.hpp b/map/user_mark_container.hpp index dc5bde367a..366abc8ca9 100644 --- a/map/user_mark_container.hpp +++ b/map/user_mark_container.hpp @@ -98,13 +98,15 @@ private: vector 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 m_animTask; };