diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index fe9f2bc18d..824db49765 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -23,6 +23,7 @@ BookmarkManager::BookmarkManager(Framework & f) , m_bmScreen(0) , m_lastScale(1.0) , m_cache(NULL) + , m_selection(f) { m_userMarkLayers.reserve(2); m_userMarkLayers.push_back(new SearchUserMarkContainer(graphics::activePinDepth, m_framework)); @@ -276,7 +277,9 @@ void BookmarkManager::DrawItems(shared_ptr const & e) const graphics::Screen * pScreen = e->drawer()->screen(); pScreen->beginFrame(); + PaintOverlayEvent event(e->drawer(), screen); + m_selection.Draw(event, m_cache); for_each(m_userMarkLayers.begin(), m_userMarkLayers.end(), bind(&UserMarkContainer::Draw, _1, event, m_cache)); for_each(m_categories.begin(), m_categories.end(), bind(&BookmarkManager::DrawCategory, this, _1, event)); @@ -307,10 +310,7 @@ bool BookmarkManager::DeleteBmCategory(size_t index) void BookmarkManager::ActivateMark(UserMark const * mark) { - for_each(m_categories.begin(), m_categories.end(), bind(&UserMarkContainer::DiactivateMark, _1)); - for_each(m_userMarkLayers.begin(), m_userMarkLayers.end(), bind(&UserMarkContainer::DiactivateMark, _1)); - if (mark != NULL) - mark->Activate(); + m_selection.ActivateMark(mark); } UserMark const * BookmarkManager::FindNearestUserMark(const m2::AnyRectD & rect) diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index 6a6ff0e3d7..ab312f0cb6 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -78,4 +78,6 @@ private: UserMarkContainer * FindUserMarksContainer(UserMarkContainer::Type type); UserMarkDLCache * m_cache; + + SelectionContainer m_selection; }; diff --git a/map/user_mark.cpp b/map/user_mark.cpp index ac46f5848a..f8b128456c 100644 --- a/map/user_mark.cpp +++ b/map/user_mark.cpp @@ -26,8 +26,3 @@ void UserMark::GetLatLon(double & lat, double & lon) const lon = MercatorBounds::XToLon(m_ptOrg.x); lat = MercatorBounds::YToLat(m_ptOrg.y); } - -void UserMark::Activate() const -{ - m_container->ActivateMark(this); -} diff --git a/map/user_mark.hpp b/map/user_mark.hpp index 84099e4f46..eb8614eae7 100644 --- a/map/user_mark.hpp +++ b/map/user_mark.hpp @@ -36,10 +36,6 @@ public: virtual bool IsCustomDrawable() const { return false;} virtual Type GetMarkType() const = 0; -protected: - friend class BookmarkManager; - void Activate() const; - protected: m2::PointD m_ptOrg; mutable UserMarkContainer * m_container; diff --git a/map/user_mark_container.cpp b/map/user_mark_container.cpp index b978fb8c29..59b80e33da 100644 --- a/map/user_mark_container.cpp +++ b/map/user_mark_container.cpp @@ -71,14 +71,66 @@ namespace m2::AnyRectD const & m_rect; m2::PointD m_globalCenter; }; + + void DrawUserMarkByPoint(double scale, + double visualScale, + m2::PointD const & pixelOfsset, + PaintOverlayEvent const & event, + graphics::DisplayList * dl, + m2::PointD const & ptOrg) + { + ScreenBase modelView = event.GetModelView(); + graphics::Screen * screen = event.GetDrawer()->screen(); + m2::PointD pxPoint = modelView.GtoP(ptOrg); + pxPoint += (pixelOfsset * visualScale); + math::Matrix m = math::Shift(math::Scale(math::Identity(), + scale, scale), + pxPoint.x, pxPoint.y); + dl->draw(screen, m); + } + + void DrawUserMarkImpl(double scale, + double visualScale, + m2::PointD const & pixelOfsset, + PaintOverlayEvent const & event, + graphics::DisplayList * dl, + UserMark const * mark) + { + DrawUserMarkByPoint(scale, visualScale, pixelOfsset, event, dl, mark->GetOrg()); + } + + void DrawUserMark(double scale, + double visualScale, + PaintOverlayEvent const & event, + UserMarkDLCache * cache, + UserMarkDLCache::Key const & defaultKey, + UserMark const * mark) + { + if (mark->IsCustomDrawable()) + { + ICustomDrawable const * drawable = static_cast(mark); + DrawUserMarkImpl(drawable->GetAnimScaleFactor(), visualScale, drawable->GetPixelOffset(), event, drawable->GetDisplayList(cache), mark); + } + else + DrawUserMarkImpl(scale, visualScale, m2::PointD(0.0, 0.0), event, cache->FindUserMark(defaultKey), mark); + } + + void DefaultDrawUserMark(double scale, + double visualScale, + PaintOverlayEvent const & event, + UserMarkDLCache * cache, + UserMarkDLCache::Key const & defaultKey, + UserMark const * mark) + { + DrawUserMarkImpl(scale, visualScale, m2::PointD(0.0, 0.0), event, cache->FindUserMark(defaultKey), mark); + } } -UserMarkContainer::UserMarkContainer(double layerDepth, Framework & framework) - : m_controller(this) +UserMarkContainer::UserMarkContainer(double layerDepth, Framework & fm) + : m_framework(fm) + , m_controller(this) , m_isVisible(true) , m_layerDepth(layerDepth) - , m_activeMark(NULL) - , m_framework(framework) { } @@ -101,37 +153,14 @@ void UserMarkContainer::Draw(PaintOverlayEvent const & e, UserMarkDLCache * cach if (m_isVisible == false) return; - if (m_activeMark != NULL) - { - UserMarkDLCache::Key defaultKey(GetActiveTypeName(), graphics::EPosCenter, m_layerDepth); - DefaultDrawUserMark(GetActiveMarkScale(), e, cache, defaultKey, m_activeMark); - } - UserMarkDLCache::Key defaultKey(GetTypeName(), graphics::EPosCenter, m_layerDepth); - for_each(m_userMarks.begin(), m_userMarks.end(), bind(&UserMarkContainer::DrawUserMark, this, - 1.0, e, cache, defaultKey, _1)); -} - -void UserMarkContainer::ActivateMark(UserMark const * mark) -{ - ASSERT(mark->GetContainer() == this, ()); - m_activeMark = mark; - StartActivationAnim(); -} - -void UserMarkContainer::DiactivateMark() -{ - if (m_activeMark != NULL) - { - KillActivationAnim(); - m_activeMark = NULL; - } + for_each(m_userMarks.begin(), m_userMarks.end(), bind(&DrawUserMark, 1.0, m_framework.GetVisualScale(), + e, cache, defaultKey, _1)); } void UserMarkContainer::Clear() { DeleteRange(m_userMarks, DeleteFunctor()); - m_activeMark = NULL; } namespace @@ -196,9 +225,6 @@ template void DeleteItem(vector & v, size_t i) void UserMarkContainer::DeleteUserMark(size_t index) { ASSERT_LESS(index, m_userMarks.size(), ()); - if (m_activeMark == m_userMarks[index]) - m_activeMark = NULL; - DeleteItem(m_userMarks, index); } @@ -209,68 +235,6 @@ void UserMarkContainer::DeleteUserMark(UserMark const * mark) DeleteUserMark(distance(m_userMarks.begin(), it)); } -void UserMarkContainer::DrawUserMarkImpl(double scale, - m2::PointD const & pixelOfsset, - PaintOverlayEvent const & event, - graphics::DisplayList * dl, - UserMark const * mark) const -{ - ScreenBase modelView = event.GetModelView(); - graphics::Screen * screen = event.GetDrawer()->screen(); - m2::PointD pxPoint = modelView.GtoP(mark->GetOrg()); - pxPoint += (pixelOfsset * m_framework.GetVisualScale()); - math::Matrix m = math::Shift(math::Scale(math::Identity(), - scale, scale), - pxPoint.x, pxPoint.y); - dl->draw(screen, m); -} - -void UserMarkContainer::DrawUserMark(double scale, - PaintOverlayEvent const & event, - UserMarkDLCache * cache, - UserMarkDLCache::Key const & defaultKey, - UserMark const * mark) const -{ - if (mark->IsCustomDrawable()) - { - ICustomDrawable const * drawable = static_cast(mark); - DrawUserMarkImpl(drawable->GetAnimScaleFactor(), drawable->GetPixelOffset(), event, drawable->GetDisplayList(cache), mark); - } - else - DefaultDrawUserMark(scale, event, cache, defaultKey, mark); -} - -void UserMarkContainer::DefaultDrawUserMark(double scale, - PaintOverlayEvent const & event, - UserMarkDLCache * cache, - UserMarkDLCache::Key const & defaultKey, - const UserMark * mark) const -{ - DrawUserMarkImpl(scale, m2::PointD(0.0, 0.0), event, cache->FindUserMark(defaultKey), mark); -} - -void UserMarkContainer::StartActivationAnim() -{ - m_animTask.reset(new PinAnimation(m_framework)); - m_framework.GetAnimController()->AddTask(m_animTask); -} - -void UserMarkContainer::KillActivationAnim() -{ - m_animTask.reset(); -} - -double UserMarkContainer::GetActiveMarkScale() const -{ - if (m_animTask != NULL) - { - PinAnimation * a = static_cast(m_animTask.get()); - return a->GetScale(); - } - - return 1.0; -} - SearchUserMarkContainer::SearchUserMarkContainer(double layerDepth, Framework & framework) : UserMarkContainer(layerDepth, framework) { @@ -310,3 +274,67 @@ UserMark * ApiUserMarkContainer::AllocateUserMark(const m2::PointD & ptOrg) { return new ApiMarkPoint(ptOrg, this); } + + +SelectionContainer::SelectionContainer(Framework & fm) + : m_hasActiveMark(false) + , m_depth(graphics::minDepth - 100) + , m_fm(fm) +{ +} + +void SelectionContainer::ActivateMark(UserMark const * userMark) +{ + KillActivationAnim(); + if (userMark != NULL) + { + m_hasActiveMark = true; + m_ptOrg = userMark->GetOrg(); + UserMarkContainer const * container = userMark->GetContainer(); + m_pinImageName = container->GetActiveTypeName(); + m_depth = container->GetDepth(); + StartActivationAnim(); + } + else + { + m_hasActiveMark = false; + m_depth = graphics::minDepth - 100; + } +} + +void SelectionContainer::Draw(const PaintOverlayEvent & e, UserMarkDLCache * cache) const +{ + if (m_hasActiveMark) + { + UserMarkDLCache::Key defaultKey(m_pinImageName, graphics::EPosCenter, m_depth); + DrawUserMarkByPoint(GetActiveMarkScale(), + m_fm.GetVisualScale(), + m2::PointD(0, 0), + e, cache->FindUserMark(defaultKey), + m_ptOrg); + } +} + + +void SelectionContainer::StartActivationAnim() +{ + m_animTask.reset(new PinAnimation(m_fm)); + m_fm.GetAnimController()->AddTask(m_animTask); + m_fm.Invalidate(); +} + +void SelectionContainer::KillActivationAnim() +{ + m_animTask.reset(); +} + +double SelectionContainer::GetActiveMarkScale() const +{ + if (m_animTask != NULL) + { + PinAnimation * a = static_cast(m_animTask.get()); + return a->GetScale(); + } + + return 1.0; +} diff --git a/map/user_mark_container.hpp b/map/user_mark_container.hpp index 3294d1ebde..ae68749274 100644 --- a/map/user_mark_container.hpp +++ b/map/user_mark_container.hpp @@ -49,7 +49,7 @@ public: BOOKMARK_MARK }; - UserMarkContainer(double layerDepth, Framework & framework); + UserMarkContainer(double layerDepth, Framework & fm); virtual ~UserMarkContainer(); void SetScreen(graphics::Screen * cacheScreen); @@ -77,9 +77,10 @@ public: Controller const & GetController() const { return m_controller; } Controller & GetController() { return m_controller; } + virtual string GetActiveTypeName() const = 0; + protected: virtual string GetTypeName() const = 0; - virtual string GetActiveTypeName() const = 0; virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg) = 0; private: @@ -91,42 +92,14 @@ private: void DeleteUserMark(size_t index); void DeleteUserMark(UserMark const * mark); -private: - void DrawUserMark(double scale, - PaintOverlayEvent const & event, - UserMarkDLCache * cache, - UserMarkDLCache::Key const & defaultKey, - UserMark const * mark) const; - - void DefaultDrawUserMark(double scale, - PaintOverlayEvent const & event, - UserMarkDLCache * cache, - UserMarkDLCache::Key const & defaultKey, - UserMark const * mark) const; - - void DrawUserMarkImpl(double scale, - const m2::PointD & pixelOfsset, - PaintOverlayEvent const & event, - graphics::DisplayList * dl, - UserMark const * mark) const; +protected: + Framework & m_framework; private: Controller m_controller; bool m_isVisible; double m_layerDepth; vector m_userMarks; - UserMark const * m_activeMark; - -protected: - Framework & m_framework; - -private: - /// animation support - void StartActivationAnim(); - void KillActivationAnim(); - double GetActiveMarkScale() const; - - shared_ptr m_animTask; }; class SearchUserMarkContainer : public UserMarkContainer @@ -136,9 +109,9 @@ public: virtual Type GetType() const { return SEARCH_MARK; } + virtual string GetActiveTypeName() const; protected: virtual string GetTypeName() const; - virtual string GetActiveTypeName() const; virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg); }; @@ -149,8 +122,32 @@ public: virtual Type GetType() const { return API_MARK; } + virtual string GetActiveTypeName() const; protected: virtual string GetTypeName() const; - virtual string GetActiveTypeName() const; virtual UserMark * AllocateUserMark(m2::PointD const & ptOrg); }; + +class SelectionContainer +{ +public: + SelectionContainer(Framework & fm); + + void ActivateMark(UserMark const * userMark); + void Draw(PaintOverlayEvent const & e, UserMarkDLCache * cache) const; + +private: + /// animation support + void StartActivationAnim(); + void KillActivationAnim(); + double GetActiveMarkScale() const; + + shared_ptr m_animTask; + +private: + bool m_hasActiveMark; + double m_depth; + string m_pinImageName; + m2::PointD m_ptOrg; + Framework & m_fm; +};