[core] my position click

Framework::GetUserMark find user mark with priority. Bookmark > Api point > Search result
This commit is contained in:
ExMix 2014-06-16 16:03:04 +03:00 committed by Alex Zolotarev
parent 2678376422
commit 4cfe3ed541
9 changed files with 142 additions and 275 deletions

View file

@ -35,7 +35,7 @@ void PinClickManager::OnShowMark(UserMark const * mark)
void PinClickManager::OnBookmarkClick(BookmarkAndCategory const & bnc)
{
Bookmark * mark = m_f.GetBmCategory(bnc.first)->GetBookmark(bnc.second);
m_f.GetBookmarkManager().ActivateMark(mark);
m_f.ActivateUserMark(mark);
SetBalloonVisible(true);
}
@ -49,7 +49,7 @@ void PinClickManager::SetBalloonVisible(bool isVisible)
void PinClickManager::RemovePin()
{
m_f.GetBookmarkManager().ActivateMark(NULL);
m_f.ActivateUserMark(NULL);
m_f.Invalidate();
}

View file

@ -308,42 +308,45 @@ bool BookmarkManager::DeleteBmCategory(size_t index)
return false;
}
void BookmarkManager::ActivateMark(UserMark const * mark)
void BookmarkManager::ActivateMark(UserMark const * mark, bool needAnim)
{
m_selection.ActivateMark(mark);
m_selection.ActivateMark(mark, needAnim);
}
UserMark const * BookmarkManager::FindNearestUserMark(const m2::AnyRectD & rect) const
namespace
{
double d = numeric_limits<double>::max();
UserMark const * mark = FindUserMarksContainer(UserMarkContainer::API_MARK)->FindMarkInRect(rect, d);
if (mark != NULL)
return mark;
mark = FindUserMarksContainer(UserMarkContainer::SEARCH_MARK)->FindMarkInRect(rect, d);
for (size_t i = 0; i < GetBmCategoriesCount(); ++i)
class BestUserMarkFinder
{
BookmarkCategory * category = GetBmCategory(i);
if (!category->IsVisible())
continue;
public:
BestUserMarkFinder(m2::AnyRectD const & rect)
: m_rect(rect)
, m_d(numeric_limits<double>::max())
, m_mark(NULL) {}
for (size_t j = 0; j < category->GetBookmarksCount(); ++ j)
void operator()(UserMarkContainer const * container)
{
Bookmark const * bookmark = category->GetBookmark(j);
m2::PointD bmOrg = bookmark->GetOrg();
if (rect.IsPointInside(bmOrg))
{
double currentD = rect.GetGlobalRect().Center().SquareLength(bmOrg);
if (currentD < d)
{
mark = bookmark;
d = currentD;
}
}
UserMark const * findedMark = container->FindMarkInRect(m_rect, m_d);
if (findedMark != NULL)
m_mark = findedMark;
}
}
return mark;
UserMark const * GetFindedMark() const { return m_mark; }
private:
m2::AnyRectD const & m_rect;
double m_d;
UserMark const * m_mark;
};
}
UserMark const * BookmarkManager::FindNearestUserMark(m2::AnyRectD const & rect) const
{
BestUserMarkFinder finder(rect);
for_each(m_categories.begin(), m_categories.end(), bind(&BestUserMarkFinder::operator(), &finder, _1));
finder(FindUserMarksContainer(UserMarkContainer::API_MARK));
finder(FindUserMarksContainer(UserMarkContainer::SEARCH_MARK));
return finder.GetFindedMark();
}
void BookmarkManager::UserMarksSetVisible(UserMarkContainer::Type type, bool isVisible)

View file

@ -60,7 +60,7 @@ public:
void DeleteBmCategory(CategoryIter i);
bool DeleteBmCategory(size_t index);
void ActivateMark(UserMark const * mark);
void ActivateMark(UserMark const * mark, bool needAnim);
UserMark const * FindNearestUserMark(m2::AnyRectD const & rect) const;
/// Additional layer methods

View file

@ -189,7 +189,8 @@ Framework::Framework()
m_lowestMapVersion(numeric_limits<int>::max()),
m_benchmarkEngine(0),
m_bmManager(*this),
m_balloonManager(*this)
m_balloonManager(*this),
m_locationChangedSlotID(-1)
{
// Checking whether we should enable benchmark.
bool isBenchmarkingEnabled = false;
@ -1479,6 +1480,13 @@ void Framework::SetViewPortASync(m2::RectD const & r)
m_animator.ChangeViewport(aRect, aRect, 0.0);
}
void Framework::UpdateSelectedMyPosition(m2::PointD const & pt)
{
PoiMarkPoint * poiMark = UserMarkContainer::UserMarkForPoi();
poiMark->SetPtOrg(pt);
ActivateUserMark(poiMark, false);
}
m2::RectD Framework::GetCurrentViewport() const
{
return m_navigator.Screen().ClipRect();
@ -1579,15 +1587,34 @@ shared_ptr<location::State> const & Framework::GetLocationState() const
return m_informationDisplay.locationState();
}
void Framework::ActivateUserMark(UserMark const * mark)
void Framework::ActivateUserMark(UserMark const * mark, bool needAnim)
{
m_bmManager.ActivateMark(mark);
if (mark != UserMarkContainer::UserMarkForPoi() && m_locationChangedSlotID != -1)
GetLocationState()->RemovePositionChangedListener(m_locationChangedSlotID);
m_bmManager.ActivateMark(mark, needAnim);
}
UserMark const * Framework::GetUserMark(m2::PointD const & pxPoint, bool isLongPress) const
UserMark const * Framework::GetUserMark(m2::PointD const & pxPoint, bool isLongPress)
{
m2::AnyRectD rect;
m_navigator.GetTouchRect(pxPoint, TOUCH_PIXEL_RADIUS * GetVisualScale(), rect);
shared_ptr<location::State> const & locationState = GetLocationState();
if (locationState->HasPosition())
{
m2::PointD const & glPivot = locationState->Position();
if (rect.IsPointInside(glPivot))
{
search::AddressInfo info;
info.m_name = m_stringsBundle.GetString("my_position");
PoiMarkPoint * poiMark = UserMarkContainer::UserMarkForPoi();
m_locationChangedSlotID = locationState->AddPositionChangedListener(bind(&Framework::UpdateSelectedMyPosition, this, _1));
poiMark->SetPtOrg(glPivot);
poiMark->SetInfo(info);
return poiMark;
}
}
UserMark const * mark = m_bmManager.FindNearestUserMark(rect);
if (mark == NULL)
@ -1606,7 +1633,8 @@ UserMark const * Framework::GetUserMark(m2::PointD const & pxPoint, bool isLongP
if (needMark)
{
PoiMarkPoint * poiMark = UserMarkContainer::UserMarkForPoi(m_navigator.PtoG(pxPivot));
PoiMarkPoint * poiMark = UserMarkContainer::UserMarkForPoi();
poiMark->SetPtOrg(m_navigator.PtoG(pxPivot));
poiMark->SetInfo(info);
mark = poiMark;
}
@ -1619,7 +1647,8 @@ PoiMarkPoint * Framework::GetAddressMark(m2::PointD const & globalPoint) const
{
search::AddressInfo info;
GetAddressInfoForGlobalPoint(globalPoint, info);
PoiMarkPoint * mark = UserMarkContainer::UserMarkForPoi(globalPoint);
PoiMarkPoint * mark = UserMarkContainer::UserMarkForPoi();
mark->SetPtOrg(globalPoint);
mark->SetInfo(info);
return mark;
}

View file

@ -437,8 +437,8 @@ public:
bool IsCountryLoaded(m2::PointD const & pt) const;
shared_ptr<location::State> const & GetLocationState() const;
void ActivateUserMark(UserMark const * mark);
UserMark const * GetUserMark(m2::PointD const & pxPoint, bool isLongPress) const;
void ActivateUserMark(UserMark const * mark, bool needAnim = true);
UserMark const * GetUserMark(m2::PointD const & pxPoint, bool isLongPress);
PoiMarkPoint * GetAddressMark(m2::PointD const & globalPoint) const;
BookmarkAndCategory FindBookmark(UserMark const * mark) const;
@ -455,6 +455,9 @@ private:
url_scheme::ParsedMapApi m_ParsedMapApi;
void SetViewPortASync(m2::RectD const & rect);
void UpdateSelectedMyPosition(m2::PointD const & pt);
int m_locationChangedSlotID;
public:
//@}

View file

@ -26,87 +26,6 @@ namespace location
{
const float MaxPositionFault = 25.0;
const float MaxHeadingFaultDeg = 3.0;
// class ErrorSectorAnimator : public anim::Task
// {
// typedef anim::Task base_t;
// public:
// ErrorSectorAnimator(double maxRadius, ::location::State * state)
// : m_maxRadius(maxRadius)
// , m_currentRadius(0.0)
// , m_pause(0.0)
// , m_state(state)
// {
// }
// void Update(Framework * f)
// {
// ScreenBase s = f->GetNavigator().Screen();
// m2::PointD pxPosition = m_state->pivot();
// double pxRadius = pxPosition.Length(s.GtoP(m_state->Position() + m2::PointD(m_maxRadius, 0)));
// m2::RectD r = s.PixelRect();
// double minSize = min(r.SizeX(), r.SizeY());
// double factor = pxRadius / minSize;
// double percent = 1E-2;
// if (factor > 1.0)
// percent = 5E-3;
// else if (factor > 0.1)
// percent = 9E-3;
// m_baseVelocity = percent * m_maxRadius;
// }
// void SetMaxRadius(double maxRadius)
// {
// m_maxRadius = maxRadius;
// }
// double GetCurrentRadius() const
// {
// return m_currentRadius;
// }
// float GetTransparency() const
// {
// return 0.3 * (1 - m_currentRadius / m_maxRadius);
// }
// virtual void OnStart(double ts)
// {
// m_startTime = ts;
// }
// virtual void OnStep(double ts)
// {
// base_t::OnStep(ts);
// double time = ts - (m_startTime + m_pause);
// if (time > 0.0)
// {
// double e = exp(-time) + 0.5;
// m_currentRadius += (max(e, 0.3) * m_baseVelocity);
// if (m_currentRadius > m_maxRadius)
// {
// m_currentRadius = 0.0;
// m_startTime = ts;
// m_pause = 0.5;
// }
// }
// m_state->invalidate();
// }
// private:
// double m_maxRadius;
// double m_currentRadius;
// double m_startTime;
// double m_pause;
// double m_baseVelocity;
// location::State * m_state;
// };
}
double const State::s_cacheRadius = 500;
@ -127,9 +46,9 @@ namespace location
m_compassFault(0.0),
m_isCentered(false),
m_isFirstPosition(false),
m_currentSlotID(0),
m_locationProcessMode(ELocationDoNothing),
m_compassProcessMode(ECompassDoNothing),
m_currentSlotID(0)
m_compassProcessMode(ECompassDoNothing)
{
m_locationAreaColor = p.m_locationAreaColor;
m_framework = p.m_framework;
@ -195,27 +114,6 @@ namespace location
CallCompassStatusListeners(mode);
}
void State::setIsVisible(bool isVisible)
{
gui::Element::setIsVisible(isVisible);
// if (isVisible)
// {
// if (m_radiusAnimation == NULL)
// {
// m_radiusAnimation.reset(new ErrorSectorAnimator(m_errorRadius, this));
// m_framework->GetAnimController()->AddTask(m_radiusAnimation);
// }
// }
// else
// {
// if (m_radiusAnimation)
// {
// m_radiusAnimation->End();
// m_radiusAnimation.reset();
// }
// }
}
void State::OnLocationUpdate(location::GpsInfo const & info)
{
m_isFirstPosition = false;
@ -230,7 +128,6 @@ namespace location
setIsVisible(true);
m_position = center;
m_errorRadius = rect.SizeX() / 2;
//SetErrorRadius(m_errorRadius);
switch (m_locationProcessMode)
{
@ -254,6 +151,7 @@ namespace location
break;
}
CallPositionChangedListeners(m_position);
invalidate();
}
@ -285,46 +183,6 @@ namespace location
return m_boundRects;
}
// void State::UpdateAnimation()
// {
// if (m_radiusAnimation)
// {
// ErrorSectorAnimator * a = static_cast<ErrorSectorAnimator *>(m_radiusAnimation.get());
// a->Update(m_framework);
// }
// }
// void State::SetErrorRadius(double errorRadius)
// {
// if (m_radiusAnimation)
// {
// ErrorSectorAnimator * a = static_cast<ErrorSectorAnimator *>(m_radiusAnimation.get());
// a->SetMaxRadius(errorRadius);
// }
// }
double State::GetErrorRadius() const
{
// if (m_radiusAnimation)
// {
// ErrorSectorAnimator * a = static_cast<ErrorSectorAnimator *>(m_radiusAnimation.get());
// return a->GetCurrentRadius();
// }
return m_errorRadius;
}
float State::GetTransparency() const
{
// if (m_radiusAnimation && !IsPositionFaultCritical())
// {
// ErrorSectorAnimator * a = static_cast<ErrorSectorAnimator *>(m_radiusAnimation.get());
// return a->GetTransparency();
// }
return m_locationAreaColor.a;
}
bool State::IsPositionFaultCritical() const
{
return m_positionFault > MaxPositionFault;
@ -336,6 +194,45 @@ namespace location
return m_compassFault > s_maxOffset;
}
void State::CallCompassStatusListeners(ECompassProcessMode mode)
{
for (TCompassStatusListeners::const_iterator it = m_compassStatusListeners.begin();
it != m_compassStatusListeners.end();
++it)
it->second(mode);
}
int State::AddCompassStatusListener(TCompassStatusListener const & l)
{
int slotID = m_currentSlotID++;
m_compassStatusListeners[slotID] = l;
return slotID;
}
void State::RemoveCompassStatusListener(int slotID)
{
m_compassStatusListeners.erase(slotID);
}
void State::CallPositionChangedListeners(m2::PointD const & pt)
{
typedef TPositionChangedListeners::const_iterator iter_t;
for (iter_t it = m_callbacks.begin(); it != m_callbacks.end(); ++it)
it->second(pt);
}
int State::AddPositionChangedListener(State::TPositionChangedCallback const & func)
{
int result = m_currentSlotID++;
m_callbacks[result] = func;
return result;
}
void State::RemovePositionChangedListener(int slotID)
{
m_callbacks.erase(slotID);
}
void State::cachePositionArrow()
{
graphics::Screen * cacheScreen = m_controller->GetCacheScreen();
@ -391,7 +288,6 @@ namespace location
cacheScreen->beginFrame();
cacheScreen->setDisplayList(m_locationMarkDL.get());
cacheScreen->applyVarAlfaStates();
cacheScreen->fillSector(m2::PointD(0, 0),
0, 2.0 * math::pi,
@ -399,9 +295,7 @@ namespace location
m_locationAreaColor,
depth() - 3);
cacheScreen->applyStates();
cacheScreen->setDisplayList(m_positionMarkDL.get());
cacheScreen->drawSymbol(m2::PointD(0, 0),
"current-position",
graphics::EPosCenter,
@ -450,8 +344,6 @@ namespace location
m_boundRect = newRect;
setIsDirtyRect(true);
}
//UpdateAnimation();
}
}
@ -469,7 +361,7 @@ namespace location
/// then position
m2::PointD const pxPosition = m_framework->GetNavigator().GtoP(Position());
double const pxErrorRadius = pxPosition.Length(
m_framework->GetNavigator().GtoP(Position() + m2::PointD(GetErrorRadius(), 0.0)));
m_framework->GetNavigator().GtoP(Position() + m2::PointD(m_errorRadius, 0.0)));
double const drawScale = pxErrorRadius / s_cacheRadius;
@ -482,10 +374,7 @@ namespace location
pivot());
math::Matrix<double, 3, 3> const drawM = locationDrawM * m;
graphics::UniformsHolder holder;
holder.insertValue(graphics::ETransparency, GetTransparency());
r->drawDisplayList(m_locationMarkDL.get(), drawM, &holder);
r->drawDisplayList(m_locationMarkDL.get(), drawM);
if (HasCompass())
{
@ -517,8 +406,7 @@ namespace location
bool State::hitTest(m2::PointD const & pt) const
{
double radius = m_halfArrowSize.x;
return (pt.SquareLength(pivot()) <= my::sq(radius));
return false;
}
void State::CheckCompassFollowing()
@ -594,21 +482,6 @@ namespace location
m_isCentered = flag;
}
void State::CallCompassStatusListeners(ECompassProcessMode mode)
{
for (TCompassStatusListeners::const_iterator it = m_compassStatusListeners.begin();
it != m_compassStatusListeners.end();
++it)
it->second(mode);
}
int State::AddCompassStatusListener(TCompassStatusListener const & l)
{
int slotID = m_currentSlotID++;
m_compassStatusListeners[slotID] = l;
return slotID;
}
void State::OnStartLocation()
{
SetCompassProcessMode(location::ECompassDoNothing);
@ -623,35 +496,4 @@ namespace location
m_isFirstPosition = false;
TurnOff();
}
void State::RemoveCompassStatusListener(int slotID)
{
m_compassStatusListeners.erase(slotID);
}
bool State::onTapEnded(m2::PointD const & pt)
{
CallOnPositionClickListeners(pt);
return false;
}
void State::CallOnPositionClickListeners(m2::PointD const & point)
{
for (TOnPositionClickListeners::const_iterator it = m_onPositionClickListeners.begin();
it != m_onPositionClickListeners.end();
++it)
it->second(Position());
}
int State::AddOnPositionClickListener(TOnPositionClickListener const & listner)
{
int slotID = m_currentSlotID++;
m_onPositionClickListeners[slotID] = listner;
return slotID;
}
void State::RemoveOnPositionClickListener(int listnerID)
{
m_onPositionClickListeners.erase(listnerID);
}
}

View file

@ -41,18 +41,12 @@ namespace location
class State : public gui::Element
{
public:
typedef function<void(int)> TCompassStatusListener;
typedef function<void(m2::PointD const &)> TOnPositionClickListener;
typedef function<void (m2::PointD const &)> TPositionChangedCallback;
private:
static const double s_cacheRadius;
//shared_ptr<anim::Task> m_radiusAnimation;
//void UpdateAnimation();
//void SetErrorRadius(double errorRadius);
double GetErrorRadius() const;
float GetTransparency() const;
double m_errorRadius; //< error radius in mercator
m2::PointD m_position; //< position in mercator
@ -70,6 +64,16 @@ namespace location
bool IsPositionFaultCritical() const;
bool IsCompassFaultCritical() const;
typedef map<int, TCompassStatusListener> TCompassStatusListeners;
TCompassStatusListeners m_compassStatusListeners;
typedef map<int, TPositionChangedCallback> TPositionChangedListeners;
TPositionChangedListeners m_callbacks;
int m_currentSlotID;
void CallPositionChangedListeners(m2::PointD const & pt);
void CallCompassStatusListeners(ECompassProcessMode mode);
ELocationProcessMode m_locationProcessMode;
ECompassProcessMode m_compassProcessMode;
@ -98,17 +102,6 @@ namespace location
mutable vector<m2::AnyRectD> m_boundRects;
m2::RectD m_boundRect;
typedef map<int, TCompassStatusListener> TCompassStatusListeners;
TCompassStatusListeners m_compassStatusListeners;
int m_currentSlotID;
typedef map<int, TOnPositionClickListener> TOnPositionClickListeners;
TOnPositionClickListeners m_onPositionClickListeners;
void CallOnPositionClickListeners(m2::PointD const & point);
void CallCompassStatusListeners(ECompassProcessMode mode);
void CheckCompassFollowing();
void FollowCompass();
@ -135,7 +128,11 @@ namespace location
ECompassProcessMode GetCompassProcessMode() const;
void SetCompassProcessMode(ECompassProcessMode mode);
void setIsVisible(bool isVisible);
int AddCompassStatusListener(TCompassStatusListener const & l);
void RemoveCompassStatusListener(int slotID);
int AddPositionChangedListener(TPositionChangedCallback const & func);
void RemovePositionChangedListener(int slotID);
void TurnOff();
@ -145,12 +142,6 @@ namespace location
void OnStartLocation();
void OnStopLocation();
int AddCompassStatusListener(TCompassStatusListener const & l);
void RemoveCompassStatusListener(int slotID);
int AddOnPositionClickListener(TOnPositionClickListener const & listner);
void RemoveOnPositionClickListener(int listnerID);
void SetIsCentered(bool flag);
bool IsCentered() const;
@ -170,7 +161,6 @@ namespace location
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
bool roughHitTest(m2::PointD const & pt) const;
bool hitTest(m2::PointD const & pt) const;
bool onTapEnded(m2::PointD const & p);
/// @}
};
}

View file

@ -132,7 +132,6 @@ UserMarkContainer::~UserMarkContainer()
UserMark const * UserMarkContainer::FindMarkInRect(m2::AnyRectD const & rect, double & d) const
{
UserMark * mark = NULL;
d = numeric_limits<double>::max();
FindMarkFunctor f(&mark, d, rect);
for_each(m_userMarks.begin(), m_userMarks.end(), f);
return mark;
@ -164,10 +163,9 @@ void UserMarkContainer::InitPoiSelectionMark(UserMarkContainer * container)
s_selectionUserMark.reset(new PoiMarkPoint(container));
}
PoiMarkPoint * UserMarkContainer::UserMarkForPoi(m2::PointD const & ptOrg)
PoiMarkPoint * UserMarkContainer::UserMarkForPoi()
{
ASSERT(s_selectionUserMark != NULL, ());
s_selectionUserMark->SetPtOrg(ptOrg);
return s_selectionUserMark.get();
}
@ -272,14 +270,16 @@ SelectionContainer::SelectionContainer(Framework & fm)
{
}
void SelectionContainer::ActivateMark(UserMark const * userMark)
void SelectionContainer::ActivateMark(UserMark const * userMark, bool needAnim)
{
KillActivationAnim();
if (needAnim)
KillActivationAnim();
if (userMark != NULL)
{
m_ptOrg = userMark->GetOrg();
m_container = userMark->GetContainer();
StartActivationAnim();
if (needAnim)
StartActivationAnim();
}
else
m_container = NULL;

View file

@ -72,7 +72,7 @@ public:
double GetDepth() const { return m_layerDepth; }
static void InitPoiSelectionMark(UserMarkContainer * container);
static PoiMarkPoint * UserMarkForPoi(m2::PointD const & ptOrg);
static PoiMarkPoint * UserMarkForPoi();
Controller const & GetController() const { return m_controller; }
Controller & GetController() { return m_controller; }
@ -133,7 +133,7 @@ class SelectionContainer
public:
SelectionContainer(Framework & fm);
void ActivateMark(UserMark const * userMark);
void ActivateMark(UserMark const * userMark, bool needAnim);
void Draw(PaintOverlayEvent const & e, UserMarkDLCache * cache) const;
private: