forked from organicmaps/organicmaps
[core] location state refactoring
This commit is contained in:
parent
feaedef14c
commit
333a4967eb
4 changed files with 529 additions and 563 deletions
|
@ -104,16 +104,6 @@ void Framework::RemoveMap(string const & file)
|
|||
m_model.RemoveMap(file);
|
||||
}
|
||||
|
||||
void Framework::StartLocation()
|
||||
{
|
||||
m_informationDisplay.locationState()->OnStartLocation();
|
||||
}
|
||||
|
||||
void Framework::StopLocation()
|
||||
{
|
||||
m_informationDisplay.locationState()->OnStopLocation();
|
||||
}
|
||||
|
||||
void Framework::OnLocationError(location::TLocationError error)
|
||||
{}
|
||||
|
||||
|
@ -146,7 +136,7 @@ void Framework::OnLocationUpdate(location::GpsInfo const & info)
|
|||
state->OnLocationUpdate(rInfo);
|
||||
m_balloonManager.LocationChanged(rInfo);
|
||||
|
||||
if (state->GetLocationProcessMode() != location::ELocationDoNothing)
|
||||
if (state->IsModeChangeViewport())
|
||||
UpdateUserViewportChanged();
|
||||
}
|
||||
|
||||
|
@ -164,11 +154,7 @@ void Framework::OnCompassUpdate(location::CompassInfo const & info)
|
|||
|
||||
void Framework::StopLocationFollow()
|
||||
{
|
||||
shared_ptr<location::State> ls = m_informationDisplay.locationState();
|
||||
|
||||
ls->StopCompassFollowing();
|
||||
ls->SetLocationProcessMode(location::ELocationDoNothing);
|
||||
ls->SetIsCentered(false);
|
||||
m_informationDisplay.locationState()->StopLocationFollow();
|
||||
}
|
||||
|
||||
InformationDisplay & Framework::GetInformationDisplay()
|
||||
|
@ -908,13 +894,14 @@ void Framework::StartDrag(DragEvent const & e)
|
|||
#endif
|
||||
|
||||
m_navigator.StartDrag(pt, ElapsedSeconds());
|
||||
m_informationDisplay.locationState()->DragStarted();
|
||||
|
||||
if (m_renderPolicy)
|
||||
m_renderPolicy->StartDrag();
|
||||
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
m_dragCompassProcessMode = locationState->GetCompassProcessMode();
|
||||
m_dragLocationProcessMode = locationState->GetLocationProcessMode();
|
||||
// shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
// m_dragCompassProcessMode = locationState->GetCompassProcessMode();
|
||||
// m_dragLocationProcessMode = locationState->GetLocationProcessMode();
|
||||
}
|
||||
|
||||
void Framework::DoDrag(DragEvent const & e)
|
||||
|
@ -926,12 +913,7 @@ void Framework::DoDrag(DragEvent const & e)
|
|||
#endif
|
||||
|
||||
m_navigator.DoDrag(pt, ElapsedSeconds());
|
||||
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
|
||||
locationState->SetIsCentered(false);
|
||||
locationState->StopCompassFollowing();
|
||||
locationState->SetLocationProcessMode(location::ELocationDoNothing);
|
||||
m_informationDisplay.locationState()->Draged();
|
||||
|
||||
if (m_renderPolicy)
|
||||
m_renderPolicy->DoDrag();
|
||||
|
@ -946,24 +928,7 @@ void Framework::StopDrag(DragEvent const & e)
|
|||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pt);
|
||||
#endif
|
||||
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
|
||||
if (m_dragLocationProcessMode != location::ELocationDoNothing)
|
||||
{
|
||||
// reset GPS centering mode if we have dragged far from current location
|
||||
ScreenBase const & s = m_navigator.Screen();
|
||||
if (GetPixelCenter().Length(s.GtoP(locationState->Position())) >= s.GetMinPixelRectSize() / 5.0)
|
||||
locationState->SetLocationProcessMode(location::ELocationDoNothing);
|
||||
else
|
||||
{
|
||||
locationState->SetLocationProcessMode(m_dragLocationProcessMode);
|
||||
if (m_dragCompassProcessMode == location::ECompassFollow)
|
||||
locationState->AnimateToPositionAndEnqueueFollowing();
|
||||
else
|
||||
locationState->AnimateToPosition();
|
||||
}
|
||||
}
|
||||
m_informationDisplay.locationState()->DragEnded();
|
||||
|
||||
if (m_renderPolicy)
|
||||
{
|
||||
|
@ -995,6 +960,7 @@ void Framework::StopRotate(RotateEvent const & e)
|
|||
if (m_renderPolicy && m_renderPolicy->DoSupportRotation())
|
||||
{
|
||||
m_navigator.StopRotate(e.Angle(), ElapsedSeconds());
|
||||
m_informationDisplay.locationState()->Rotated();
|
||||
m_renderPolicy->StopRotate(e.Angle(), ElapsedSeconds());
|
||||
|
||||
UpdateUserViewportChanged();
|
||||
|
@ -1013,9 +979,8 @@ void Framework::Move(double azDir, double factor)
|
|||
//@{
|
||||
void Framework::ScaleToPoint(ScaleToPointEvent const & e)
|
||||
{
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
m2::PointD const pt = (locationState->GetLocationProcessMode() == location::ELocationDoNothing) ?
|
||||
m_navigator.ShiftPoint(e.Pt()) : GetPixelCenter();
|
||||
m2::PointD pt = m_navigator.ShiftPoint(e.Pt());
|
||||
m_informationDisplay.locationState()->ScaleCorrection(pt);
|
||||
|
||||
m_animController->AddTask(m_navigator.ScaleToPointAnim(pt, e.ScaleFactor(), 0.25));
|
||||
|
||||
|
@ -1041,16 +1006,7 @@ void Framework::CalcScalePoints(ScaleEvent const & e, m2::PointD & pt1, m2::Poin
|
|||
pt1 = m_navigator.ShiftPoint(e.Pt1());
|
||||
pt2 = m_navigator.ShiftPoint(e.Pt2());
|
||||
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
|
||||
if (locationState->HasPosition()
|
||||
&& (locationState->GetLocationProcessMode() == location::ELocationCenterOnly))
|
||||
{
|
||||
m2::PointD const ptC = (pt1 + pt2) / 2;
|
||||
m2::PointD const ptDiff = GetPixelCenter() - ptC;
|
||||
pt1 += ptDiff;
|
||||
pt2 += ptDiff;
|
||||
}
|
||||
m_informationDisplay.locationState()->ScaleCorrection(pt1, pt2);
|
||||
|
||||
#ifdef DRAW_TOUCH_POINTS
|
||||
m_informationDisplay.setDebugPoint(0, pt1);
|
||||
|
@ -1077,11 +1033,8 @@ void Framework::DoScale(ScaleEvent const & e)
|
|||
if (m_renderPolicy)
|
||||
m_renderPolicy->DoScale();
|
||||
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
|
||||
if (m_navigator.IsRotatingDuringScale()
|
||||
&& (locationState->GetCompassProcessMode() == location::ECompassFollow))
|
||||
locationState->StopCompassFollowing();
|
||||
if (m_navigator.IsRotatingDuringScale())
|
||||
m_informationDisplay.locationState()->Rotated();
|
||||
}
|
||||
|
||||
void Framework::StopScale(ScaleEvent const & e)
|
||||
|
@ -1349,7 +1302,7 @@ bool Framework::GetCurrentPosition(double & lat, double & lon) const
|
|||
{
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
|
||||
if (locationState->HasPosition())
|
||||
if (locationState->IsModeHasPosition())
|
||||
{
|
||||
m2::PointD const pos = locationState->Position();
|
||||
lat = MercatorBounds::YToLat(pos.y);
|
||||
|
@ -1891,7 +1844,7 @@ UserMark const * Framework::GetUserMark(m2::PointD const & pxPoint, bool isLongP
|
|||
m_navigator.GetTouchRect(pxPoint, TOUCH_PIXEL_RADIUS * GetVisualScale(), rect);
|
||||
|
||||
shared_ptr<location::State> const & locationState = GetLocationState();
|
||||
if (locationState->HasPosition())
|
||||
if (locationState->IsModeHasPosition())
|
||||
{
|
||||
m2::PointD const & glPivot = locationState->Position();
|
||||
if (rect.IsPointInside(glPivot))
|
||||
|
|
|
@ -110,9 +110,6 @@ protected:
|
|||
int m_width;
|
||||
int m_height;
|
||||
|
||||
location::ECompassProcessMode m_dragCompassProcessMode;
|
||||
location::ELocationProcessMode m_dragLocationProcessMode;
|
||||
|
||||
void StopLocationFollow();
|
||||
|
||||
storage::Storage m_storage;
|
||||
|
@ -215,10 +212,6 @@ public:
|
|||
|
||||
/// @name GPS location updates routine.
|
||||
//@{
|
||||
|
||||
void StartLocation();
|
||||
void StopLocation();
|
||||
|
||||
void OnLocationError(location::TLocationError error);
|
||||
void OnLocationUpdate(location::GpsInfo const & info);
|
||||
void OnCompassUpdate(location::CompassInfo const & info);
|
||||
|
@ -391,9 +384,9 @@ public:
|
|||
|
||||
/// @name Drag implementation.
|
||||
//@{
|
||||
private:
|
||||
m2::PointD GetPixelCenter() const;
|
||||
public:
|
||||
m2::PointD GetPixelCenter() const;
|
||||
|
||||
void StartDrag(DragEvent const & e);
|
||||
void DoDrag(DragEvent const & e);
|
||||
void StopDrag(DragEvent const & e);
|
||||
|
|
|
@ -22,428 +22,459 @@
|
|||
|
||||
namespace location
|
||||
{
|
||||
// namespace
|
||||
// {
|
||||
// const float MaxPositionFault = 25.0;
|
||||
// const float MaxHeadingFaultDeg = 3.0;
|
||||
// }
|
||||
|
||||
double const State::s_cacheRadius = 500;
|
||||
namespace
|
||||
{
|
||||
|
||||
State::Params::Params()
|
||||
: m_locationAreaColor(0, 0, 0, 0),
|
||||
m_framework(0)
|
||||
{}
|
||||
uint16_t IncludeModeBit(uint16_t mode, uint16_t bit)
|
||||
{
|
||||
return mode | bit;
|
||||
}
|
||||
|
||||
State::State(Params const & p)
|
||||
: BaseT(p),
|
||||
m_errorRadius(0),
|
||||
m_position(0, 0),
|
||||
m_drawHeading(0.0),
|
||||
m_hasPosition(false),
|
||||
m_hasCompass(false),
|
||||
m_isCentered(false),
|
||||
m_isFirstPosition(false),
|
||||
m_currentSlotID(0),
|
||||
m_locationProcessMode(ELocationDoNothing),
|
||||
m_compassProcessMode(ECompassDoNothing)
|
||||
uint16_t ExcludeModeBit(uint16_t mode, uint16_t bit)
|
||||
{
|
||||
return mode & (~bit);
|
||||
}
|
||||
|
||||
State::Mode ExcludeAllBits(uint16_t mode)
|
||||
{
|
||||
return (State::Mode)(mode & 0xF);
|
||||
}
|
||||
|
||||
uint16_t ChangeMode(uint16_t mode, State::Mode newMode)
|
||||
{
|
||||
return (mode & 0xF0) | newMode;
|
||||
}
|
||||
|
||||
bool TestModeBit(uint16_t mode, uint16_t bit)
|
||||
{
|
||||
return (mode & bit) != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
State::Params::Params()
|
||||
: m_locationAreaColor(0, 0, 0, 0),
|
||||
m_framework(0)
|
||||
{}
|
||||
|
||||
State::State(Params const & p)
|
||||
: TBase(p),
|
||||
m_modeInfo(UnknowPosition),
|
||||
m_errorRadius(0),
|
||||
m_position(0, 0),
|
||||
m_drawDirection(0.0),
|
||||
m_currentSlotID(0)
|
||||
{
|
||||
m_locationAreaColor = p.m_locationAreaColor;
|
||||
m_framework = p.m_framework;
|
||||
|
||||
setIsVisible(false);
|
||||
}
|
||||
|
||||
m2::PointD const & State::Position() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
State::Mode State::GetMode() const
|
||||
{
|
||||
return ExcludeAllBits(m_modeInfo);
|
||||
}
|
||||
|
||||
bool State::IsModeChangeViewport() const
|
||||
{
|
||||
return !(GetMode() < Follow);
|
||||
}
|
||||
|
||||
bool State::IsModeHasPosition() const
|
||||
{
|
||||
return !(GetMode() < NotFollow);
|
||||
}
|
||||
|
||||
void State::SwitchToNextMode()
|
||||
{
|
||||
Mode currentMode = GetMode();
|
||||
Mode newMode = currentMode;
|
||||
switch (currentMode)
|
||||
{
|
||||
m_locationAreaColor = p.m_locationAreaColor;
|
||||
m_framework = p.m_framework;
|
||||
|
||||
setState(EActive);
|
||||
setIsVisible(false);
|
||||
}
|
||||
|
||||
bool State::HasPosition() const
|
||||
{
|
||||
return m_hasPosition;
|
||||
}
|
||||
|
||||
m2::PointD const & State::Position() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
bool State::HasCompass() const
|
||||
{
|
||||
return m_hasCompass;
|
||||
}
|
||||
|
||||
bool State::IsFirstPosition() const
|
||||
{
|
||||
return m_isFirstPosition;
|
||||
}
|
||||
|
||||
void State::TurnOff()
|
||||
{
|
||||
m_hasPosition = false;
|
||||
m_hasCompass = false;
|
||||
m_isFirstPosition = false;
|
||||
|
||||
setIsVisible(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
ELocationProcessMode State::GetLocationProcessMode() const
|
||||
{
|
||||
return m_locationProcessMode;
|
||||
}
|
||||
|
||||
void State::SetLocationProcessMode(ELocationProcessMode mode)
|
||||
{
|
||||
m_locationProcessMode = mode;
|
||||
}
|
||||
|
||||
ECompassProcessMode State::GetCompassProcessMode() const
|
||||
{
|
||||
return m_compassProcessMode;
|
||||
}
|
||||
|
||||
void State::SetCompassProcessMode(ECompassProcessMode mode)
|
||||
{
|
||||
bool stateChanged = (m_compassProcessMode != mode);
|
||||
|
||||
m_compassProcessMode = mode;
|
||||
|
||||
if (stateChanged)
|
||||
CallCompassStatusListeners(mode);
|
||||
}
|
||||
|
||||
void State::OnLocationUpdate(location::GpsInfo const & info)
|
||||
{
|
||||
m_isFirstPosition = false;
|
||||
m2::RectD rect = MercatorBounds::MetresToXY(info.m_longitude,
|
||||
info.m_latitude,
|
||||
info.m_horizontalAccuracy);
|
||||
m2::PointD const center = rect.Center();
|
||||
|
||||
m_hasPosition = true;
|
||||
setIsVisible(true);
|
||||
m_position = center;
|
||||
m_errorRadius = rect.SizeX() / 2;
|
||||
|
||||
switch (m_locationProcessMode)
|
||||
{
|
||||
case ELocationCenterAndScale:
|
||||
m_framework->ShowRectExVisibleScale(rect, scales::GetUpperComfortScale());
|
||||
|
||||
SetIsCentered(true);
|
||||
CheckCompassFollowing();
|
||||
|
||||
m_locationProcessMode = ELocationCenterOnly;
|
||||
break;
|
||||
|
||||
case ELocationCenterOnly:
|
||||
m_framework->SetViewportCenter(center);
|
||||
|
||||
SetIsCentered(true);
|
||||
CheckCompassFollowing();
|
||||
break;
|
||||
|
||||
case ELocationDoNothing:
|
||||
break;
|
||||
}
|
||||
|
||||
CallPositionChangedListeners(m_position);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void State::OnCompassUpdate(location::CompassInfo const & info)
|
||||
{
|
||||
m_hasCompass = true;
|
||||
if (info.m_trueHeading >= 0.0)
|
||||
m_drawHeading = info.m_trueHeading;
|
||||
case UnknowPosition:
|
||||
newMode = PendingPosition;
|
||||
break;
|
||||
case PendingPosition:
|
||||
newMode = UnknowPosition;
|
||||
break;
|
||||
case NotFollow:
|
||||
newMode = Follow;
|
||||
break;
|
||||
case Follow:
|
||||
if (TestModeBit(m_modeInfo, KnownDirectionBit))
|
||||
newMode = RotateAndFollow;
|
||||
else
|
||||
m_drawHeading = info.m_magneticHeading;
|
||||
|
||||
CheckCompassFollowing();
|
||||
|
||||
invalidate();
|
||||
newMode = UnknowPosition;
|
||||
break;
|
||||
case RotateAndFollow:
|
||||
newMode = UnknowPosition;
|
||||
break;
|
||||
}
|
||||
|
||||
m2::RectD State::GetBoundRect() const
|
||||
SetModeInfo(ChangeMode(m_modeInfo, newMode));
|
||||
}
|
||||
|
||||
void State::RestoreMode()
|
||||
{
|
||||
SetModeInfo(IncludeModeBit(m_modeInfo, ModeNotProcessed));
|
||||
}
|
||||
|
||||
void State::TurnOff()
|
||||
{
|
||||
SetModeInfo(UnknowPosition);
|
||||
setIsVisible(false);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void State::OnLocationUpdate(location::GpsInfo const & info)
|
||||
{
|
||||
|
||||
m2::RectD rect = MercatorBounds::MetresToXY(info.m_longitude,
|
||||
info.m_latitude,
|
||||
info.m_horizontalAccuracy);
|
||||
m2::PointD const center = rect.Center();
|
||||
|
||||
m_position = center;
|
||||
m_errorRadius = rect.SizeX() / 2;
|
||||
|
||||
setIsVisible(true);
|
||||
|
||||
if (GetMode() == PendingPosition)
|
||||
SetModeInfo(IncludeModeBit(ChangeMode(m_modeInfo, Follow), ModeNotProcessed));
|
||||
|
||||
AnimateCurrentState();
|
||||
|
||||
CallPositionChangedListeners(m_position);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void State::OnCompassUpdate(location::CompassInfo const & info)
|
||||
{
|
||||
SetModeInfo(IncludeModeBit(m_modeInfo, KnownDirectionBit));
|
||||
|
||||
if (info.m_trueHeading >= 0.0)
|
||||
m_drawDirection = info.m_trueHeading;
|
||||
else
|
||||
m_drawDirection = info.m_magneticHeading;
|
||||
|
||||
FollowCompass();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void State::CallStateModeListeners()
|
||||
{
|
||||
Mode currentMode = GetMode();
|
||||
for (auto it : m_modeListeners)
|
||||
it.second(currentMode);
|
||||
}
|
||||
|
||||
int State::AddStateModeListener(TStateModeListener const & l)
|
||||
{
|
||||
int slotID = m_currentSlotID++;
|
||||
m_modeListeners[slotID] = l;
|
||||
return slotID;
|
||||
}
|
||||
|
||||
void State::RemoveStateModeListener(int slotID)
|
||||
{
|
||||
m_modeListeners.erase(slotID);
|
||||
}
|
||||
|
||||
void State::CallPositionChangedListeners(m2::PointD const & pt)
|
||||
{
|
||||
for (auto it : m_positionListeners)
|
||||
it.second(pt);
|
||||
}
|
||||
|
||||
int State::AddPositionChangedListener(State::TPositionListener const & func)
|
||||
{
|
||||
int result = m_currentSlotID++;
|
||||
m_positionListeners[result] = func;
|
||||
return result;
|
||||
}
|
||||
|
||||
void State::RemovePositionChangedListener(int slotID)
|
||||
{
|
||||
m_positionListeners.erase(slotID);
|
||||
}
|
||||
|
||||
void State::cache()
|
||||
{
|
||||
CachePositionArrow();
|
||||
CacheLocationMark();
|
||||
|
||||
m_controller->GetCacheScreen()->completeCommands();
|
||||
}
|
||||
|
||||
void State::purge()
|
||||
{
|
||||
m_positionArrow.reset();
|
||||
m_locationMarkDL.reset();
|
||||
m_positionMarkDL.reset();
|
||||
}
|
||||
|
||||
void State::update()
|
||||
{
|
||||
if (isVisible() && IsModeHasPosition())
|
||||
{
|
||||
return m2::RectD();
|
||||
m2::PointD const pxPosition = m_framework->GetNavigator().GtoP(Position());
|
||||
setPivot(pxPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void State::CallCompassStatusListeners(ECompassProcessMode mode)
|
||||
void State::draw(graphics::OverlayRenderer * r,
|
||||
math::Matrix<double, 3, 3> const & m) const
|
||||
{
|
||||
Mode currentMode = GetMode();
|
||||
if (currentMode < NotFollow || !isVisible())
|
||||
return;
|
||||
|
||||
checkDirtyLayout();
|
||||
|
||||
m2::PointD const pxPosition = m_framework->GetNavigator().GtoP(Position());
|
||||
double const pxErrorRadius = pxPosition.Length(
|
||||
m_framework->GetNavigator().GtoP(Position() + m2::PointD(m_errorRadius, 0.0)));
|
||||
|
||||
double const drawScale = pxErrorRadius / s_cacheRadius;
|
||||
|
||||
math::Matrix<double, 3, 3> locationDrawM = math::Shift(
|
||||
math::Scale(
|
||||
math::Identity<double, 3>(),
|
||||
drawScale,
|
||||
drawScale),
|
||||
pivot());
|
||||
|
||||
math::Matrix<double, 3, 3> const drawM = locationDrawM * m;
|
||||
// draw error sector
|
||||
r->drawDisplayList(m_locationMarkDL.get(), drawM);
|
||||
|
||||
// if we know look direction than we draw arrow
|
||||
if (TestModeBit(m_modeInfo, KnownDirectionBit))
|
||||
{
|
||||
for (TCompassStatusListeners::const_iterator it = m_compassStatusListeners.begin();
|
||||
it != m_compassStatusListeners.end();
|
||||
++it)
|
||||
it->second(mode);
|
||||
double rotateAngle = m_drawDirection + m_framework->GetNavigator().Screen().GetAngle();
|
||||
|
||||
math::Matrix<double, 3, 3> compassDrawM =math::Shift(
|
||||
math::Rotate(
|
||||
math::Identity<double, 3>(),
|
||||
rotateAngle),
|
||||
pivot());
|
||||
|
||||
r->drawDisplayList(m_positionArrow.get(), compassDrawM * m);
|
||||
}
|
||||
else
|
||||
r->drawDisplayList(m_positionMarkDL.get(), drawM);
|
||||
}
|
||||
|
||||
int State::AddCompassStatusListener(TCompassStatusListener const & l)
|
||||
void State::CachePositionArrow()
|
||||
{
|
||||
graphics::Screen * cacheScreen = m_controller->GetCacheScreen();
|
||||
graphics::Icon::Info info("current-position-compas");
|
||||
|
||||
graphics::Resource const * res = cacheScreen->fromID(cacheScreen->findInfo(info));
|
||||
m2::RectU rect = res->m_texRect;
|
||||
m2::PointD halfArrowSize(rect.SizeX() / 2.0, rect.SizeY() / 2.0);
|
||||
|
||||
m_positionArrow.reset();
|
||||
m_positionArrow.reset(cacheScreen->createDisplayList());
|
||||
|
||||
cacheScreen->beginFrame();
|
||||
cacheScreen->setDisplayList(m_positionArrow.get());
|
||||
|
||||
m2::PointD coords[4] =
|
||||
{
|
||||
int slotID = m_currentSlotID++;
|
||||
m_compassStatusListeners[slotID] = l;
|
||||
return slotID;
|
||||
}
|
||||
m2::PointD(-halfArrowSize.x, -halfArrowSize.y),
|
||||
m2::PointD(-halfArrowSize.x, halfArrowSize.y),
|
||||
m2::PointD( halfArrowSize.x, -halfArrowSize.y),
|
||||
m2::PointD( halfArrowSize.x, halfArrowSize.y)
|
||||
};
|
||||
|
||||
void State::RemoveCompassStatusListener(int slotID)
|
||||
m2::PointF normal(0.0, 0.0);
|
||||
shared_ptr<graphics::gl::BaseTexture> texture = cacheScreen->pipeline(res->m_pipelineID).texture();
|
||||
|
||||
m2::PointF texCoords[4] =
|
||||
{
|
||||
m_compassStatusListeners.erase(slotID);
|
||||
}
|
||||
texture->mapPixel(m2::PointF(rect.minX(), rect.minY())),
|
||||
texture->mapPixel(m2::PointF(rect.minX(), rect.maxY())),
|
||||
texture->mapPixel(m2::PointF(rect.maxX(), rect.minY())),
|
||||
texture->mapPixel(m2::PointF(rect.maxX(), rect.maxY()))
|
||||
};
|
||||
|
||||
void State::CallPositionChangedListeners(m2::PointD const & pt)
|
||||
cacheScreen->addTexturedStripStrided(coords, sizeof(m2::PointD),
|
||||
&normal, 0,
|
||||
texCoords, sizeof(m2::PointF),
|
||||
4, depth(), res->m_pipelineID);
|
||||
cacheScreen->setDisplayList(0);
|
||||
cacheScreen->endFrame();
|
||||
}
|
||||
|
||||
void State::CacheLocationMark()
|
||||
{
|
||||
graphics::Screen * cacheScreen = m_controller->GetCacheScreen();
|
||||
|
||||
m_locationMarkDL.reset();
|
||||
m_locationMarkDL.reset(cacheScreen->createDisplayList());
|
||||
|
||||
m_positionMarkDL.reset();
|
||||
m_positionMarkDL.reset(cacheScreen->createDisplayList());
|
||||
|
||||
cacheScreen->beginFrame();
|
||||
cacheScreen->setDisplayList(m_locationMarkDL.get());
|
||||
|
||||
cacheScreen->fillSector(m2::PointD(0, 0),
|
||||
0, 2.0 * math::pi,
|
||||
s_cacheRadius,
|
||||
m_locationAreaColor,
|
||||
depth() - 3);
|
||||
|
||||
cacheScreen->setDisplayList(m_positionMarkDL.get());
|
||||
cacheScreen->drawSymbol(m2::PointD(0, 0),
|
||||
"current-position",
|
||||
graphics::EPosCenter,
|
||||
depth() - 1);
|
||||
|
||||
cacheScreen->setDisplayList(0);
|
||||
|
||||
cacheScreen->endFrame();
|
||||
}
|
||||
|
||||
void State::FollowCompass()
|
||||
{
|
||||
if (!m_framework->GetNavigator().DoSupportRotation())
|
||||
return;
|
||||
|
||||
if (TestModeBit(m_modeInfo, KnownDirectionBit) && GetMode() == RotateAndFollow)
|
||||
{
|
||||
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();
|
||||
graphics::Icon::Info info("current-position-compas");
|
||||
|
||||
graphics::Resource const * res = cacheScreen->fromID(cacheScreen->findInfo(info));
|
||||
m2::RectU rect = res->m_texRect;
|
||||
m2::PointD halfArrowSize(rect.SizeX() / 2.0, rect.SizeY() / 2.0);
|
||||
|
||||
m_positionArrow.reset();
|
||||
m_positionArrow.reset(cacheScreen->createDisplayList());
|
||||
|
||||
cacheScreen->beginFrame();
|
||||
cacheScreen->setDisplayList(m_positionArrow.get());
|
||||
|
||||
m2::PointD coords[4] =
|
||||
{
|
||||
m2::PointD(-halfArrowSize.x, -halfArrowSize.y),
|
||||
m2::PointD(-halfArrowSize.x, halfArrowSize.y),
|
||||
m2::PointD( halfArrowSize.x, -halfArrowSize.y),
|
||||
m2::PointD( halfArrowSize.x, halfArrowSize.y)
|
||||
};
|
||||
|
||||
m2::PointF normal(0.0, 0.0);
|
||||
shared_ptr<graphics::gl::BaseTexture> texture = cacheScreen->pipeline(res->m_pipelineID).texture();
|
||||
|
||||
m2::PointF texCoords[4] =
|
||||
{
|
||||
texture->mapPixel(m2::PointF(rect.minX(), rect.minY())),
|
||||
texture->mapPixel(m2::PointF(rect.minX(), rect.maxY())),
|
||||
texture->mapPixel(m2::PointF(rect.maxX(), rect.minY())),
|
||||
texture->mapPixel(m2::PointF(rect.maxX(), rect.maxY()))
|
||||
};
|
||||
|
||||
cacheScreen->addTexturedStripStrided(coords, sizeof(m2::PointD),
|
||||
&normal, 0,
|
||||
texCoords, sizeof(m2::PointF),
|
||||
4, depth(), res->m_pipelineID);
|
||||
cacheScreen->setDisplayList(0);
|
||||
cacheScreen->endFrame();
|
||||
}
|
||||
|
||||
void State::cacheLocationMark()
|
||||
{
|
||||
graphics::Screen * cacheScreen = m_controller->GetCacheScreen();
|
||||
|
||||
m_locationMarkDL.reset();
|
||||
m_locationMarkDL.reset(cacheScreen->createDisplayList());
|
||||
|
||||
m_positionMarkDL.reset();
|
||||
m_positionMarkDL.reset(cacheScreen->createDisplayList());
|
||||
|
||||
cacheScreen->beginFrame();
|
||||
cacheScreen->setDisplayList(m_locationMarkDL.get());
|
||||
|
||||
cacheScreen->fillSector(m2::PointD(0, 0),
|
||||
0, 2.0 * math::pi,
|
||||
s_cacheRadius,
|
||||
m_locationAreaColor,
|
||||
depth() - 3);
|
||||
|
||||
cacheScreen->setDisplayList(m_positionMarkDL.get());
|
||||
cacheScreen->drawSymbol(m2::PointD(0, 0),
|
||||
"current-position",
|
||||
graphics::EPosCenter,
|
||||
depth() - 1);
|
||||
|
||||
cacheScreen->setDisplayList(0);
|
||||
|
||||
cacheScreen->endFrame();
|
||||
}
|
||||
|
||||
void State::cache()
|
||||
{
|
||||
cachePositionArrow();
|
||||
cacheLocationMark();
|
||||
|
||||
m_controller->GetCacheScreen()->completeCommands();
|
||||
}
|
||||
|
||||
void State::purge()
|
||||
{
|
||||
m_positionArrow.reset();
|
||||
m_locationMarkDL.reset();
|
||||
m_positionMarkDL.reset();
|
||||
}
|
||||
|
||||
void State::update()
|
||||
{
|
||||
if (isVisible() && m_hasPosition)
|
||||
{
|
||||
m2::PointD const pxPosition = m_framework->GetNavigator().GtoP(Position());
|
||||
setPivot(pxPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void State::draw(graphics::OverlayRenderer * r,
|
||||
math::Matrix<double, 3, 3> const & m) const
|
||||
{
|
||||
if (isVisible())
|
||||
{
|
||||
checkDirtyLayout();
|
||||
|
||||
if (m_hasPosition)
|
||||
{
|
||||
math::Matrix<double, 3, 3> locationDrawM;
|
||||
|
||||
/// then position
|
||||
m2::PointD const pxPosition = m_framework->GetNavigator().GtoP(Position());
|
||||
double const pxErrorRadius = pxPosition.Length(
|
||||
m_framework->GetNavigator().GtoP(Position() + m2::PointD(m_errorRadius, 0.0)));
|
||||
|
||||
double const drawScale = pxErrorRadius / s_cacheRadius;
|
||||
|
||||
locationDrawM =
|
||||
math::Shift(
|
||||
math::Scale(
|
||||
math::Identity<double, 3>(),
|
||||
drawScale,
|
||||
drawScale),
|
||||
pivot());
|
||||
|
||||
math::Matrix<double, 3, 3> const drawM = locationDrawM * m;
|
||||
r->drawDisplayList(m_locationMarkDL.get(), drawM);
|
||||
|
||||
if (HasCompass())
|
||||
{
|
||||
double screenAngle = m_framework->GetNavigator().Screen().GetAngle();
|
||||
|
||||
math::Matrix<double, 3, 3> compassDrawM;
|
||||
|
||||
double const headingRad = m_drawHeading;
|
||||
|
||||
compassDrawM =
|
||||
math::Shift(
|
||||
math::Rotate(
|
||||
math::Identity<double, 3>(),
|
||||
screenAngle + headingRad),
|
||||
pivot());
|
||||
|
||||
r->drawDisplayList(m_positionArrow.get(), compassDrawM * m);
|
||||
}
|
||||
else
|
||||
r->drawDisplayList(m_positionMarkDL.get(), drawM);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool State::hitTest(m2::PointD const & /*pt*/) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void State::CheckCompassFollowing()
|
||||
{
|
||||
if (HasCompass()
|
||||
&& (GetCompassProcessMode() == ECompassFollow)
|
||||
&& IsCentered())
|
||||
FollowCompass();
|
||||
}
|
||||
|
||||
void State::FollowCompass()
|
||||
{
|
||||
if (!m_framework->GetNavigator().DoSupportRotation())
|
||||
return;
|
||||
|
||||
anim::Controller::Guard guard(m_framework->GetAnimController());
|
||||
|
||||
m_framework->GetAnimator().RotateScreen(
|
||||
m_framework->GetNavigator().Screen().GetAngle(),
|
||||
-m_drawHeading);
|
||||
}
|
||||
|
||||
void State::AnimateToPosition()
|
||||
{
|
||||
m_framework->SetViewportCenterAnimated(Position());
|
||||
}
|
||||
|
||||
void State::AnimateToPositionAndEnqueueFollowing()
|
||||
{
|
||||
shared_ptr<MoveScreenTask> const & t = m_framework->SetViewportCenterAnimated(Position());
|
||||
|
||||
t->Lock();
|
||||
t->AddCallback(anim::Task::EEnded, bind(&State::SetIsCentered, this, true));
|
||||
t->AddCallback(anim::Task::EEnded, bind(&State::StartCompassFollowing, this));
|
||||
t->Unlock();
|
||||
}
|
||||
|
||||
void State::AnimateToPositionAndEnqueueLocationProcessMode(location::ELocationProcessMode mode)
|
||||
{
|
||||
shared_ptr<MoveScreenTask> const & t = m_framework->SetViewportCenterAnimated(Position());
|
||||
|
||||
t->Lock();
|
||||
t->AddCallback(anim::Task::EEnded, bind(&State::SetIsCentered, this, true));
|
||||
t->AddCallback(anim::Task::EEnded, bind(&State::SetLocationProcessMode, this, mode));
|
||||
t->Unlock();
|
||||
}
|
||||
|
||||
void State::StartCompassFollowing()
|
||||
{
|
||||
SetCompassProcessMode(ECompassFollow);
|
||||
SetLocationProcessMode(ELocationCenterOnly);
|
||||
|
||||
CheckCompassFollowing();
|
||||
setState(EPressed);
|
||||
}
|
||||
|
||||
void State::StopCompassFollowing()
|
||||
{
|
||||
SetCompassProcessMode(ECompassDoNothing);
|
||||
m_framework->GetAnimator().StopRotation();
|
||||
m_framework->GetAnimator().StopChangeViewport();
|
||||
m_framework->GetAnimator().StopMoveScreen();
|
||||
setState(EActive);
|
||||
}
|
||||
|
||||
bool State::IsCentered() const
|
||||
{
|
||||
return m_isCentered;
|
||||
}
|
||||
|
||||
void State::SetIsCentered(bool flag)
|
||||
{
|
||||
m_isCentered = flag;
|
||||
}
|
||||
|
||||
void State::OnStartLocation()
|
||||
{
|
||||
SetCompassProcessMode(location::ECompassDoNothing);
|
||||
SetLocationProcessMode(location::ELocationCenterAndScale);
|
||||
m_isFirstPosition = true;
|
||||
}
|
||||
|
||||
void State::OnStopLocation()
|
||||
{
|
||||
SetLocationProcessMode(location::ELocationDoNothing);
|
||||
SetCompassProcessMode(location::ECompassDoNothing);
|
||||
m_isFirstPosition = false;
|
||||
TurnOff();
|
||||
-m_drawDirection);
|
||||
}
|
||||
}
|
||||
|
||||
void State::SetModeInfo(uint16_t modeInfo)
|
||||
{
|
||||
bool callModeChanged = GetMode() != ExcludeAllBits(modeInfo);
|
||||
m_modeInfo = modeInfo;
|
||||
if (callModeChanged)
|
||||
{
|
||||
CallStateModeListeners();
|
||||
AnimateCurrentState();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void State::StopCompassFollowing()
|
||||
{
|
||||
if (GetMode() != RotateAndFollow)
|
||||
return;
|
||||
|
||||
SetModeInfo(ChangeMode(m_modeInfo, Follow));
|
||||
|
||||
m_framework->GetAnimator().StopRotation();
|
||||
m_framework->GetAnimator().StopChangeViewport();
|
||||
m_framework->GetAnimator().StopMoveScreen();
|
||||
}
|
||||
|
||||
void State::StopLocationFollow()
|
||||
{
|
||||
if (GetMode() > NotFollow)
|
||||
SetModeInfo(NotFollow);
|
||||
}
|
||||
|
||||
void State::DragStarted()
|
||||
{
|
||||
m_dragModeInfo = m_modeInfo;
|
||||
}
|
||||
|
||||
void State::Draged()
|
||||
{
|
||||
if (GetMode() < Follow)
|
||||
return;
|
||||
|
||||
StopCompassFollowing();
|
||||
SetModeInfo(ChangeMode(m_modeInfo, NotFollow));
|
||||
}
|
||||
|
||||
void State::DragEnded()
|
||||
{
|
||||
if (ExcludeAllBits(m_dragModeInfo) < Follow)
|
||||
return;
|
||||
|
||||
// reset GPS centering mode if we have dragged far from current location
|
||||
ScreenBase const & s = m_framework->GetNavigator().Screen();
|
||||
m2::PointD const pixelCenter = m_framework->GetPixelCenter();
|
||||
if (pixelCenter.Length(s.GtoP(Position())) < s.GetMinPixelRectSize() / 5.0)
|
||||
SetModeInfo(IncludeModeBit(m_dragModeInfo, ModeNotProcessed));
|
||||
}
|
||||
|
||||
void State::ScaleCorrection(m2::PointD & pt)
|
||||
{
|
||||
if (GetMode() > NotFollow)
|
||||
pt = m_framework->GetPixelCenter();
|
||||
}
|
||||
|
||||
void State::ScaleCorrection(m2::PointD & pt1, m2::PointD & pt2)
|
||||
{
|
||||
if (GetMode() > NotFollow)
|
||||
{
|
||||
m2::PointD const ptC = (pt1 + pt2) / 2;
|
||||
m2::PointD const ptDiff = m_framework->GetPixelCenter() - ptC;
|
||||
pt1 += ptDiff;
|
||||
pt2 += ptDiff;
|
||||
}
|
||||
}
|
||||
|
||||
void State::Rotated()
|
||||
{
|
||||
StopCompassFollowing();
|
||||
}
|
||||
|
||||
void State::AnimateCurrentState()
|
||||
{
|
||||
if (TestModeBit(m_modeInfo, ModeNotProcessed))
|
||||
{
|
||||
m2::PointD size(m_errorRadius, m_errorRadius);
|
||||
m2::RectD rect(m_position - size, m_position + size);
|
||||
m_framework->ShowRectExVisibleScale(rect, scales::GetUpperComfortScale());
|
||||
SetModeInfo(ExcludeModeBit(m_modeInfo, ModeNotProcessed));
|
||||
}
|
||||
else if (GetMode() > NotFollow)
|
||||
{
|
||||
m_framework->SetViewportCenter(m_position);
|
||||
FollowCompass();
|
||||
}
|
||||
}
|
||||
|
||||
//void State::AnimateToPosition()
|
||||
//{
|
||||
// m_framework->SetViewportCenterAnimated(Position());
|
||||
//}
|
||||
|
||||
//void State::AnimateToPositionAndEnqueueFollowing()
|
||||
//{
|
||||
// shared_ptr<MoveScreenTask> const & t = m_framework->SetViewportCenterAnimated(Position());
|
||||
|
||||
// t->Lock();
|
||||
// t->AddCallback(anim::Task::EEnded, bind(&State::StartCompassFollowing, this));
|
||||
// t->Unlock();
|
||||
//}
|
||||
|
||||
//void State::AnimateToPositionAndEnqueueLocationProcessMode(location::ELocationProcessMode mode)
|
||||
//{
|
||||
// shared_ptr<MoveScreenTask> const & t = m_framework->SetViewportCenterAnimated(Position());
|
||||
|
||||
// t->Lock();
|
||||
// t->AddCallback(anim::Task::EEnded, bind(&State::SetIsCentered, this, true));
|
||||
// t->AddCallback(anim::Task::EEnded, bind(&State::SetLocationProcessMode, this, mode));
|
||||
// t->Unlock();
|
||||
//}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,127 +13,73 @@
|
|||
class Framework;
|
||||
|
||||
namespace graphics { class DisplayList; }
|
||||
namespace anim { class Task; }
|
||||
|
||||
namespace location
|
||||
{
|
||||
class GpsInfo;
|
||||
class CompassInfo;
|
||||
|
||||
enum ELocationProcessMode
|
||||
{
|
||||
ELocationDoNothing = 0,
|
||||
ELocationCenterAndScale,
|
||||
ELocationCenterOnly
|
||||
};
|
||||
|
||||
enum ECompassProcessMode
|
||||
{
|
||||
ECompassDoNothing = 0,
|
||||
ECompassFollow
|
||||
};
|
||||
|
||||
// Class, that handles position and compass updates,
|
||||
// centers, scales and rotates map according to this updates
|
||||
// and draws location and compass marks.
|
||||
class State : public gui::Element
|
||||
{
|
||||
public:
|
||||
typedef function<void(int)> TCompassStatusListener;
|
||||
typedef function<void (m2::PointD const &)> TPositionChangedCallback;
|
||||
|
||||
private:
|
||||
|
||||
static const double s_cacheRadius;
|
||||
|
||||
double m_errorRadius; //< error radius in mercator
|
||||
m2::PointD m_position; //< position in mercator
|
||||
|
||||
double m_drawHeading;
|
||||
|
||||
bool m_hasPosition;
|
||||
bool m_hasCompass;
|
||||
bool m_isCentered;
|
||||
bool m_isFirstPosition;
|
||||
|
||||
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;
|
||||
|
||||
typedef gui::Element BaseT;
|
||||
|
||||
graphics::Color m_locationAreaColor;
|
||||
|
||||
Framework * m_framework;
|
||||
|
||||
/// @nameCompass Rendering Parameters
|
||||
//@{
|
||||
unique_ptr<graphics::DisplayList> m_positionArrow;
|
||||
unique_ptr<graphics::DisplayList> m_locationMarkDL;
|
||||
unique_ptr<graphics::DisplayList> m_positionMarkDL;
|
||||
//@}
|
||||
|
||||
void cachePositionArrow();
|
||||
void cacheLocationMark();
|
||||
|
||||
void CheckCompassFollowing();
|
||||
void FollowCompass();
|
||||
typedef gui::Element TBase;
|
||||
|
||||
public:
|
||||
struct Params : BaseT::Params
|
||||
struct Params : TBase::Params
|
||||
{
|
||||
graphics::Color m_locationAreaColor;
|
||||
Framework * m_framework;
|
||||
Params();
|
||||
};
|
||||
|
||||
public:
|
||||
// Do not change the order
|
||||
enum Mode
|
||||
{
|
||||
UnknowPosition = 0x0,
|
||||
PendingPosition = 0x1,
|
||||
NotFollow = 0x2,
|
||||
Follow = 0x4,
|
||||
RotateAndFollow = 0x8,
|
||||
};
|
||||
|
||||
typedef function<void(Mode)> TStateModeListener;
|
||||
typedef function<void (m2::PointD const &)> TPositionListener;
|
||||
|
||||
State(Params const & p);
|
||||
|
||||
/// @return GPS center point in mercator
|
||||
m2::PointD const & Position() const;
|
||||
|
||||
// Заменяем на GetMode()
|
||||
//{
|
||||
bool HasPosition() const;
|
||||
bool HasCompass() const;
|
||||
bool IsFirstPosition() const;
|
||||
Mode GetMode() const;
|
||||
bool IsModeChangeViewport() const;
|
||||
bool IsModeHasPosition() const;
|
||||
void SwitchToNextMode();
|
||||
void RestoreMode();
|
||||
|
||||
ELocationProcessMode GetLocationProcessMode() const;
|
||||
void SetLocationProcessMode(ELocationProcessMode mode);
|
||||
int AddStateModeListener(TStateModeListener const & l);
|
||||
void RemoveStateModeListener(int slotID);
|
||||
|
||||
ECompassProcessMode GetCompassProcessMode() const;
|
||||
void SetCompassProcessMode(ECompassProcessMode mode);
|
||||
//}
|
||||
|
||||
int AddCompassStatusListener(TCompassStatusListener const & l);
|
||||
void RemoveCompassStatusListener(int slotID);
|
||||
|
||||
int AddPositionChangedListener(TPositionChangedCallback const & func);
|
||||
int AddPositionChangedListener(TPositionListener const & func);
|
||||
void RemovePositionChangedListener(int slotID);
|
||||
|
||||
void TurnOff();
|
||||
|
||||
void StartCompassFollowing();
|
||||
void StopCompassFollowing();
|
||||
void StopLocationFollow();
|
||||
|
||||
void OnStartLocation();
|
||||
void OnStopLocation();
|
||||
/// @name User input notification block
|
||||
//@{
|
||||
void DragStarted();
|
||||
void Draged();
|
||||
void DragEnded();
|
||||
|
||||
void SetIsCentered(bool flag);
|
||||
bool IsCentered() const;
|
||||
void ScaleCorrection(m2::PointD & pt);
|
||||
void ScaleCorrection(m2::PointD & pt1, m2::PointD & pt2);
|
||||
|
||||
void AnimateToPosition();
|
||||
void AnimateToPositionAndEnqueueFollowing();
|
||||
void AnimateToPositionAndEnqueueLocationProcessMode(location::ELocationProcessMode mode);
|
||||
void Rotated();
|
||||
//@}
|
||||
|
||||
/// @name GPS location updates routine.
|
||||
//@{
|
||||
|
@ -143,14 +89,57 @@ namespace location
|
|||
|
||||
/// @name Override from graphics::OverlayElement and gui::Element.
|
||||
//@{
|
||||
virtual m2::RectD GetBoundRect() const;
|
||||
virtual m2::RectD GetBoundRect() const { return m2::RectD(); }
|
||||
|
||||
void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
bool hitTest(m2::PointD const & pt) const;
|
||||
bool hitTest(m2::PointD const & /*pt*/) const { return false; }
|
||||
|
||||
void cache();
|
||||
void purge();
|
||||
void update();
|
||||
//@}
|
||||
|
||||
private:
|
||||
void AnimateCurrentState();
|
||||
|
||||
void CallPositionChangedListeners(m2::PointD const & pt);
|
||||
void CallStateModeListeners();
|
||||
|
||||
void CachePositionArrow();
|
||||
void CacheLocationMark();
|
||||
|
||||
void FollowCompass();
|
||||
void SetModeInfo(uint16_t modeInfo);
|
||||
|
||||
private:
|
||||
// Mode bits
|
||||
// {
|
||||
constexpr static uint16_t const ModeNotProcessed = 0x40;
|
||||
constexpr static uint16_t const KnownDirectionBit = 0x80;
|
||||
// }
|
||||
constexpr static float const s_cacheRadius = 500.0f;
|
||||
|
||||
uint16_t m_modeInfo; // combination of Mode enum and "Mode bits"
|
||||
uint16_t m_dragModeInfo;
|
||||
Framework * m_framework;
|
||||
|
||||
double m_errorRadius; //< error radius in mercator
|
||||
m2::PointD m_position; //< position in mercator
|
||||
double m_drawDirection;
|
||||
|
||||
typedef map<int, TStateModeListener> TModeListeners;
|
||||
typedef map<int, TPositionListener> TPositionListeners;
|
||||
|
||||
TModeListeners m_modeListeners;
|
||||
TPositionListeners m_positionListeners;
|
||||
int m_currentSlotID;
|
||||
|
||||
/// @nameCompass Rendering Parameters
|
||||
//@{
|
||||
unique_ptr<graphics::DisplayList> m_positionArrow;
|
||||
unique_ptr<graphics::DisplayList> m_locationMarkDL;
|
||||
unique_ptr<graphics::DisplayList> m_positionMarkDL;
|
||||
graphics::Color m_locationAreaColor;
|
||||
//@}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue