[core] move selection drawing into separate container, because when re-search on viewport changed search container cleared, and it's clear selection

This commit is contained in:
ExMix 2014-05-30 17:31:46 +03:00 committed by Alex Zolotarev
parent 9f9d9e1269
commit 16429903fc
6 changed files with 159 additions and 141 deletions

View file

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

View file

@ -78,4 +78,6 @@ private:
UserMarkContainer * FindUserMarksContainer(UserMarkContainer::Type type);
UserMarkDLCache * m_cache;
SelectionContainer m_selection;
};

View file

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

View file

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

View file

@ -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<double, 3, 3> m = math::Shift(math::Scale(math::Identity<double, 3>(),
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<ICustomDrawable const *>(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 <class T> void DeleteItem(vector<T> & 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<double, 3, 3> m = math::Shift(math::Scale(math::Identity<double, 3>(),
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<ICustomDrawable const *>(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<PinAnimation *>(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<PinAnimation *>(m_animTask.get());
return a->GetScale();
}
return 1.0;
}

View file

@ -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<UserMark *> m_userMarks;
UserMark const * m_activeMark;
protected:
Framework & m_framework;
private:
/// animation support
void StartActivationAnim();
void KillActivationAnim();
double GetActiveMarkScale() const;
shared_ptr<anim::Task> 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<anim::Task> m_animTask;
private:
bool m_hasActiveMark;
double m_depth;
string m_pinImageName;
m2::PointD m_ptOrg;
Framework & m_fm;
};