forked from organicmaps/organicmaps
refactored location::State to make it gui::Element.
This commit is contained in:
parent
47b22d3964
commit
e00411fd42
6 changed files with 323 additions and 86 deletions
|
@ -65,12 +65,12 @@ void Framework::RemoveMap(string const & datFile)
|
|||
|
||||
void Framework::SkipLocationCentering()
|
||||
{
|
||||
m_locationState.SkipLocationCentering();
|
||||
m_informationDisplay.locationState()->SkipLocationCentering();
|
||||
}
|
||||
|
||||
void Framework::OnLocationStatusChanged(location::TLocationStatus newStatus)
|
||||
{
|
||||
m_locationState.OnLocationStatusChanged(newStatus);
|
||||
m_informationDisplay.locationState()->OnLocationStatusChanged(newStatus);
|
||||
}
|
||||
|
||||
void Framework::OnGpsUpdate(location::GpsInfo const & info)
|
||||
|
@ -83,7 +83,7 @@ void Framework::OnGpsUpdate(location::GpsInfo const & info)
|
|||
location::GpsInfo const & rInfo = info;
|
||||
#endif
|
||||
|
||||
m_locationState.OnGpsUpdate(rInfo);
|
||||
m_informationDisplay.locationState()->OnGpsUpdate(rInfo);
|
||||
}
|
||||
|
||||
void Framework::OnCompassUpdate(location::CompassInfo const & info)
|
||||
|
@ -95,7 +95,7 @@ void Framework::OnCompassUpdate(location::CompassInfo const & info)
|
|||
location::CompassInfo const & rInfo = info;
|
||||
#endif
|
||||
|
||||
m_locationState.OnCompassUpdate(rInfo);
|
||||
m_informationDisplay.locationState()->OnCompassUpdate(rInfo);
|
||||
}
|
||||
|
||||
InformationDisplay & Framework::GetInformationDisplay()
|
||||
|
@ -130,8 +130,7 @@ Framework::Framework()
|
|||
#endif
|
||||
m_width(0),
|
||||
m_height(0),
|
||||
m_locationState(this),
|
||||
m_informationDisplay(&m_storage),
|
||||
m_informationDisplay(this),
|
||||
m_lowestMapVersion(-1),
|
||||
m_benchmarkEngine(0)
|
||||
{
|
||||
|
@ -585,8 +584,6 @@ void Framework::DrawAdditionalInfo(shared_ptr<PaintEvent> const & e)
|
|||
|
||||
m_informationDisplay.doDraw(pDrawer);
|
||||
|
||||
m_locationState.Draw(*pDrawer);
|
||||
|
||||
if (m_drawPlacemark)
|
||||
m_informationDisplay.drawPlacemark(pDrawer, "placemark", m_navigator.GtoP(m_placemark));
|
||||
|
||||
|
@ -785,7 +782,7 @@ void Framework::StartDrag(DragEvent const & e)
|
|||
if (m_renderPolicy)
|
||||
m_renderPolicy->StartDrag();
|
||||
|
||||
m_dragCompassProcessMode = m_locationState.CompassProcessMode();
|
||||
m_dragCompassProcessMode = m_informationDisplay.locationState()->CompassProcessMode();
|
||||
}
|
||||
|
||||
void Framework::DoDrag(DragEvent const & e)
|
||||
|
@ -798,7 +795,7 @@ void Framework::DoDrag(DragEvent const & e)
|
|||
|
||||
m_navigator.DoDrag(pt, ElapsedSeconds());
|
||||
|
||||
m_locationState.SetCompassProcessMode(location::ECompassDoNothing);
|
||||
m_informationDisplay.locationState()->SetCompassProcessMode(location::ECompassDoNothing);
|
||||
|
||||
if (m_renderPolicy)
|
||||
m_renderPolicy->DoDrag();
|
||||
|
@ -814,17 +811,19 @@ void Framework::StopDrag(DragEvent const & e)
|
|||
m_informationDisplay.setDebugPoint(0, pt);
|
||||
#endif
|
||||
|
||||
if (m_locationState.LocationProcessMode() != location::ELocationDoNothing)
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
|
||||
if (locationState->LocationProcessMode() != 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(m_locationState.Position())) >= s.GetMinPixelRectSize() / 2.0)
|
||||
if (GetPixelCenter().Length(s.GtoP(locationState->Position())) >= s.GetMinPixelRectSize() / 2.0)
|
||||
{
|
||||
m_locationState.SetLocationProcessMode(location::ELocationDoNothing);
|
||||
m_locationState.SetCompassProcessMode(location::ECompassDoNothing);
|
||||
locationState->SetLocationProcessMode(location::ELocationDoNothing);
|
||||
locationState->SetCompassProcessMode(location::ECompassDoNothing);
|
||||
}
|
||||
else
|
||||
m_locationState.SetCompassProcessMode(m_dragCompassProcessMode);
|
||||
locationState->SetCompassProcessMode(m_dragCompassProcessMode);
|
||||
}
|
||||
|
||||
if (m_renderPolicy)
|
||||
|
@ -870,7 +869,7 @@ void Framework::Move(double azDir, double factor)
|
|||
//@{
|
||||
void Framework::ScaleToPoint(ScaleToPointEvent const & e)
|
||||
{
|
||||
m2::PointD const pt = (m_locationState.LocationProcessMode() == location::ELocationDoNothing) ?
|
||||
m2::PointD const pt = (m_informationDisplay.locationState()->LocationProcessMode() == location::ELocationDoNothing) ?
|
||||
m_navigator.ShiftPoint(e.Pt()) : GetPixelCenter();
|
||||
|
||||
m_navigator.ScaleToPoint(pt, e.ScaleFactor(), ElapsedSeconds());
|
||||
|
@ -895,7 +894,10 @@ void Framework::CalcScalePoints(ScaleEvent const & e, m2::PointD & pt1, m2::Poin
|
|||
pt1 = m_navigator.ShiftPoint(e.Pt1());
|
||||
pt2 = m_navigator.ShiftPoint(e.Pt2());
|
||||
|
||||
if (m_locationState.HasPosition() && (m_locationState.LocationProcessMode() == location::ELocationCenterOnly))
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
|
||||
if (locationState->HasPosition()
|
||||
&& (locationState->LocationProcessMode() == location::ELocationCenterOnly))
|
||||
{
|
||||
m2::PointD const ptC = (pt1 + pt2) / 2;
|
||||
m2::PointD const ptDiff = GetPixelCenter() - ptC;
|
||||
|
@ -928,10 +930,13 @@ void Framework::DoScale(ScaleEvent const & e)
|
|||
if (m_renderPolicy)
|
||||
m_renderPolicy->DoScale();
|
||||
|
||||
if (m_navigator.IsRotatingDuringScale() && (m_locationState.CompassProcessMode() == location::ECompassFollow))
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
|
||||
if (m_navigator.IsRotatingDuringScale()
|
||||
&& (locationState->CompassProcessMode() == location::ECompassFollow))
|
||||
{
|
||||
m_locationState.StopAnimation();
|
||||
m_locationState.SetCompassProcessMode(location::ECompassDoNothing);
|
||||
locationState->StopAnimation();
|
||||
locationState->SetCompassProcessMode(location::ECompassDoNothing);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -991,9 +996,11 @@ bool Framework::Search(search::SearchParams const & params)
|
|||
|
||||
bool Framework::GetCurrentPosition(double & lat, double & lon) const
|
||||
{
|
||||
if (m_locationState.HasPosition())
|
||||
shared_ptr<location::State> locationState = m_informationDisplay.locationState();
|
||||
|
||||
if (locationState->HasPosition())
|
||||
{
|
||||
m2::PointD const pos = m_locationState.Position();
|
||||
m2::PointD const pos = locationState->Position();
|
||||
lat = MercatorBounds::YToLat(pos.y);
|
||||
lon = MercatorBounds::XToLon(pos.x);
|
||||
return true;
|
||||
|
@ -1060,8 +1067,8 @@ void Framework::SetRenderPolicy(RenderPolicy * renderPolicy)
|
|||
yg::gl::RenderContext::initParams();
|
||||
}
|
||||
|
||||
m_renderPolicy.reset();
|
||||
m_guiController->ResetRenderParams();
|
||||
m_renderPolicy.reset();
|
||||
m_renderPolicy.reset(renderPolicy);
|
||||
|
||||
if (m_renderPolicy)
|
||||
|
|
|
@ -96,7 +96,6 @@ protected:
|
|||
int m_width;
|
||||
int m_height;
|
||||
|
||||
location::State m_locationState;
|
||||
location::ECompassProcessMode m_dragCompassProcessMode;
|
||||
|
||||
//mutable threads::Mutex m_modelSyn;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "information_display.hpp"
|
||||
#include "drawer_yg.hpp"
|
||||
#include "country_status_display.hpp"
|
||||
#include "framework.hpp"
|
||||
|
||||
#include "../indexer/mercator.hpp"
|
||||
|
||||
|
@ -23,7 +24,7 @@
|
|||
#include "../std/iomanip.hpp"
|
||||
#include "../std/target_os.hpp"
|
||||
|
||||
InformationDisplay::InformationDisplay(storage::Storage * storage)
|
||||
InformationDisplay::InformationDisplay(Framework * framework)
|
||||
: m_ruler(Ruler::Params()),
|
||||
m_bottomShift(0)
|
||||
{
|
||||
|
@ -32,10 +33,23 @@ InformationDisplay::InformationDisplay(storage::Storage * storage)
|
|||
p.m_pivot = m2::PointD(0, 0);
|
||||
p.m_position = yg::EPosCenter;
|
||||
p.m_depth = yg::maxDepth;
|
||||
p.m_storage = storage;
|
||||
p.m_storage = &framework->Storage();
|
||||
|
||||
m_countryStatusDisplay.reset(new CountryStatusDisplay(p));
|
||||
|
||||
location::State::Params lsp;
|
||||
|
||||
lsp.m_position = yg::EPosCenter;
|
||||
lsp.m_depth = yg::maxDepth;
|
||||
lsp.m_pivot = m2::PointD(0, 0);
|
||||
lsp.m_compassAreaColor = yg::Color(255, 255, 255, 192);
|
||||
lsp.m_compassBorderColor = yg::Color(255, 255, 255, 96);
|
||||
lsp.m_locationAreaColor = yg::Color(0, 0, 255, 32);
|
||||
lsp.m_locationBorderColor = yg::Color(0, 0, 255, 32);
|
||||
lsp.m_framework = framework;
|
||||
|
||||
m_locationState.reset(new location::State(lsp));
|
||||
|
||||
enableDebugPoints(false);
|
||||
enableRuler(false);
|
||||
enableCenter(false);
|
||||
|
@ -54,6 +68,7 @@ void InformationDisplay::setController(gui::Controller *controller)
|
|||
{
|
||||
m_controller = controller;
|
||||
m_controller->AddElement(m_countryStatusDisplay);
|
||||
m_controller->AddElement(m_locationState);
|
||||
}
|
||||
|
||||
void InformationDisplay::setScreen(ScreenBase const & screen)
|
||||
|
@ -459,3 +474,8 @@ shared_ptr<CountryStatusDisplay> const & InformationDisplay::countryStatusDispla
|
|||
{
|
||||
return m_countryStatusDisplay;
|
||||
}
|
||||
|
||||
shared_ptr<location::State> const & InformationDisplay::locationState() const
|
||||
{
|
||||
return m_locationState;
|
||||
}
|
||||
|
|
|
@ -22,11 +22,7 @@ namespace gui
|
|||
class Controller;
|
||||
}
|
||||
|
||||
namespace storage
|
||||
{
|
||||
class Storage;
|
||||
}
|
||||
|
||||
class Framework;
|
||||
class CountryStatusDisplay;
|
||||
|
||||
/// Class, which displays additional information on the primary layer.
|
||||
|
@ -84,10 +80,11 @@ private:
|
|||
static WindowHandle * s_windowHandle;
|
||||
*/
|
||||
shared_ptr<CountryStatusDisplay> m_countryStatusDisplay;
|
||||
shared_ptr<location::State> m_locationState;
|
||||
|
||||
public:
|
||||
|
||||
InformationDisplay(storage::Storage * storage);
|
||||
InformationDisplay(Framework * framework);
|
||||
|
||||
void setController(gui::Controller * controller);
|
||||
|
||||
|
@ -129,6 +126,8 @@ public:
|
|||
void setLogSize(size_t logSize);
|
||||
void drawLog(DrawerYG * pDrawer);
|
||||
|
||||
shared_ptr<location::State> const & locationState() const;
|
||||
|
||||
void enableCountryStatusDisplay(bool doEnable);
|
||||
void setDownloadListener(gui::Button::TOnClickListener l);
|
||||
void setEmptyCountryName(string const & country);
|
||||
|
|
|
@ -1,27 +1,37 @@
|
|||
#include "location_state.hpp"
|
||||
#include "drawer_yg.hpp"
|
||||
#include "navigator.hpp"
|
||||
#include "framework.hpp"
|
||||
#include "rotate_screen_task.hpp"
|
||||
|
||||
#include "../yg/display_list.hpp"
|
||||
|
||||
#include "../anim/controller.hpp"
|
||||
|
||||
#include "../gui/controller.hpp"
|
||||
|
||||
#include "../platform/location.hpp"
|
||||
#include "../platform/platform.hpp"
|
||||
|
||||
#include "../geometry/rect2d.hpp"
|
||||
#include "../geometry/transformations.hpp"
|
||||
|
||||
#include "../indexer/mercator.hpp"
|
||||
|
||||
namespace location
|
||||
{
|
||||
State::State(Framework * fw)
|
||||
: m_hasPosition(false),
|
||||
State::State(Params const & p)
|
||||
: base_t(p),
|
||||
m_hasPosition(false),
|
||||
m_hasCompass(false),
|
||||
m_locationProcessMode(ELocationDoNothing),
|
||||
m_compassProcessMode(ECompassDoNothing),
|
||||
m_fw(fw)
|
||||
m_compassProcessMode(ECompassDoNothing)
|
||||
{
|
||||
m_locationAreaColor = p.m_locationAreaColor;
|
||||
m_locationBorderColor = p.m_locationBorderColor;
|
||||
m_compassAreaColor = p.m_compassAreaColor;
|
||||
m_compassBorderColor = p.m_compassBorderColor;
|
||||
m_framework = p.m_framework;
|
||||
m_boundRects.resize(1);
|
||||
}
|
||||
|
||||
bool State::HasPosition() const
|
||||
|
@ -38,6 +48,7 @@ namespace location
|
|||
{
|
||||
m_hasPosition = false;
|
||||
m_hasCompass = false;
|
||||
setIsVisible(false);
|
||||
}
|
||||
|
||||
void State::SkipLocationCentering()
|
||||
|
@ -90,7 +101,7 @@ namespace location
|
|||
TurnOff();
|
||||
}
|
||||
|
||||
m_fw->Invalidate();
|
||||
m_framework->Invalidate();
|
||||
}
|
||||
|
||||
void State::OnGpsUpdate(location::GpsInfo const & info)
|
||||
|
@ -102,6 +113,7 @@ namespace location
|
|||
m2::PointD const center = rect.Center();
|
||||
|
||||
m_hasPosition = true;
|
||||
setIsVisible(true);
|
||||
m_position = center;
|
||||
m_errorRadius = rect.SizeX() / 2;
|
||||
|
||||
|
@ -114,7 +126,7 @@ namespace location
|
|||
|
||||
// correct rect scale if country isn't downloaded
|
||||
int const upperScale = scales::GetUpperWorldScale();
|
||||
if (rectScale > upperScale && !m_fw->IsCountryLoaded(center))
|
||||
if (rectScale > upperScale && !m_framework->IsCountryLoaded(center))
|
||||
setScale = upperScale;
|
||||
else
|
||||
{
|
||||
|
@ -127,18 +139,18 @@ namespace location
|
|||
if (setScale != -1)
|
||||
rect = scales::GetRectForLevel(setScale, center, 1.0);
|
||||
|
||||
double a = m_fw->GetNavigator().Screen().GetAngle();
|
||||
double a = m_framework->GetNavigator().Screen().GetAngle();
|
||||
double dx = rect.SizeX();
|
||||
double dy = rect.SizeY();
|
||||
|
||||
m_fw->ShowRectFixed(m2::AnyRectD(rect.Center(), a, m2::RectD(-dx/2, -dy/2, dx/2, dy/2)));
|
||||
m_framework->ShowRectFixed(m2::AnyRectD(rect.Center(), a, m2::RectD(-dx/2, -dy/2, dx/2, dy/2)));
|
||||
|
||||
m_locationProcessMode = ELocationCenterOnly;
|
||||
break;
|
||||
}
|
||||
|
||||
case ELocationCenterOnly:
|
||||
m_fw->SetViewportCenter(center);
|
||||
m_framework->SetViewportCenter(center);
|
||||
break;
|
||||
|
||||
case ELocationSkipCentering:
|
||||
|
@ -149,7 +161,7 @@ namespace location
|
|||
break;
|
||||
}
|
||||
|
||||
m_fw->Invalidate();
|
||||
m_framework->Invalidate();
|
||||
}
|
||||
|
||||
void State::OnCompassUpdate(location::CompassInfo const & info)
|
||||
|
@ -160,66 +172,217 @@ namespace location
|
|||
|
||||
// Avoid situations when offset between magnetic north and true north is too small
|
||||
static double const MIN_SECTOR_RAD = math::pi / 18.0;
|
||||
|
||||
double oldHeadingHaldErrorRad = m_headingHalfErrorRad;
|
||||
|
||||
m_headingHalfErrorRad = (info.m_accuracy < MIN_SECTOR_RAD ? MIN_SECTOR_RAD : info.m_accuracy);
|
||||
|
||||
if (fabs(oldHeadingHaldErrorRad - m_headingHalfErrorRad) > 0.01)
|
||||
setIsDirtyDrawing(true);
|
||||
|
||||
if (m_compassProcessMode == ECompassFollow)
|
||||
FollowCompass();
|
||||
|
||||
m_fw->Invalidate();
|
||||
m_framework->Invalidate();
|
||||
}
|
||||
|
||||
void State::Draw(DrawerYG & drawer)
|
||||
|
||||
vector<m2::AnyRectD> const & State::boundRects() const
|
||||
{
|
||||
if (m_hasPosition)
|
||||
if (isDirtyRect())
|
||||
{
|
||||
m2::PointD const pxPosition = m_fw->GetNavigator().GtoP(Position());
|
||||
double const pxErrorRadius = pxPosition.Length(m_fw->GetNavigator().GtoP(Position() + m2::PointD(m_errorRadius, 0.0)));
|
||||
m_boundRects[0] = m2::AnyRectD(m_boundRect);
|
||||
setIsDirtyRect(false);
|
||||
}
|
||||
|
||||
// my position symbol
|
||||
drawer.drawSymbol(pxPosition, "current-position", yg::EPosCenter, yg::maxDepth);
|
||||
return m_boundRects;
|
||||
}
|
||||
|
||||
// my position circle
|
||||
drawer.screen()->fillSector(pxPosition, 0, 2.0 * math::pi, pxErrorRadius,
|
||||
yg::Color(0, 0, 255, 32),
|
||||
yg::maxDepth - 3);
|
||||
/*
|
||||
void State::cache()
|
||||
{
|
||||
m_cacheRadius = 500 * visualScale();
|
||||
|
||||
// display compass only if position is available
|
||||
double orientationRadius = max(pxErrorRadius, 30.0 * drawer.VisualScale());
|
||||
yg::gl::Screen * cacheScreen = m_controller->GetCacheScreen();
|
||||
|
||||
double screenAngle = m_fw->GetNavigator().Screen().GetAngle();
|
||||
m_locationDisplayList.reset();
|
||||
m_locationDisplayList.reset(cacheScreen->createDisplayList());
|
||||
|
||||
// 0 angle is for North ("up"), but in our coordinates it's to the right.
|
||||
double headingRad = m_headingRad - math::pi / 2.0;
|
||||
m_compassDisplayList.reset();
|
||||
m_compassDisplayList.reset(cacheScreen->createDisplayList());
|
||||
|
||||
if (m_hasCompass)
|
||||
cacheScreen->beginFrame();
|
||||
cacheScreen->setDisplayList(m_locationDisplayList.get());
|
||||
|
||||
m2::PointD zero(0, 0);
|
||||
|
||||
cacheScreen->drawSymbol(zero,
|
||||
"current_position",
|
||||
yg::EPosCenter,
|
||||
depth());
|
||||
|
||||
cacheScreen->fillSector(zero,
|
||||
0, 2.0 * math::pi,
|
||||
m_cacheRadius,
|
||||
m_locationAreaColor,
|
||||
depth() - 3);
|
||||
|
||||
cacheScreen->drawArc(zero,
|
||||
0, 2.0 * math::pi,
|
||||
m_cacheRadius,
|
||||
m_locationBorderColor,
|
||||
depth() - 2);
|
||||
|
||||
cacheScreen->setDisplayList(m_compassDisplayList.get());
|
||||
|
||||
cacheScreen->drawSector(zero,
|
||||
-m_headingHalfErrorRad,
|
||||
m_headingHalfErrorRad,
|
||||
m_cacheRadius,
|
||||
m_compassAreaColor,
|
||||
depth());
|
||||
|
||||
cacheScreen->fillSector(zero,
|
||||
-m_headingHalfErrorRad,
|
||||
m_headingHalfErrorRad,
|
||||
m_cacheRadius,
|
||||
m_compassBorderColor,
|
||||
depth() - 1);
|
||||
|
||||
cacheScreen->setDisplayList(0);
|
||||
cacheScreen->endFrame();
|
||||
}
|
||||
|
||||
void State::purge()
|
||||
{
|
||||
m_locationDisplayList.reset();
|
||||
m_compassDisplayList.reset();
|
||||
}
|
||||
|
||||
void State::update()
|
||||
{
|
||||
m2::PointD const pxPosition = m_framework->GetNavigator().GtoP(Position());
|
||||
|
||||
setPivot(pxPosition);
|
||||
|
||||
double const pxErrorRadius = pxPosition.Length(m_framework->GetNavigator().GtoP(Position() + m2::PointD(m_errorRadius, 0.0)));
|
||||
|
||||
m2::RectD newRect(pxPosition - m2::PointD(pxErrorRadius, pxErrorRadius),
|
||||
pxPosition + m2::PointD(pxErrorRadius, pxErrorRadius));
|
||||
|
||||
if (newRect != m_boundRect)
|
||||
{
|
||||
m_boundRect = newRect;
|
||||
setIsDirtyRect(true);
|
||||
}
|
||||
}
|
||||
|
||||
void State::draw(yg::gl::OverlayRenderer * r,
|
||||
math::Matrix<double, 3, 3> const & m) const
|
||||
{
|
||||
if (isVisible())
|
||||
{
|
||||
checkDirtyDrawing();
|
||||
|
||||
if (m_hasPosition)
|
||||
{
|
||||
drawer.screen()->drawSector(pxPosition,
|
||||
screenAngle + headingRad - m_headingHalfErrorRad,
|
||||
screenAngle + headingRad + m_headingHalfErrorRad,
|
||||
orientationRadius,
|
||||
yg::Color(255, 255, 255, 192),
|
||||
yg::maxDepth);
|
||||
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 orientationRadius = max(pxErrorRadius, 30.0 * visualScale());
|
||||
|
||||
drawer.screen()->fillSector(pxPosition,
|
||||
screenAngle + headingRad - m_headingHalfErrorRad,
|
||||
screenAngle + headingRad + m_headingHalfErrorRad,
|
||||
orientationRadius,
|
||||
yg::Color(255, 255, 255, 96),
|
||||
yg::maxDepth - 1);
|
||||
double screenAngle = m_framework->GetNavigator().Screen().GetAngle();
|
||||
|
||||
double k = pxErrorRadius / m_cacheRadius;
|
||||
|
||||
math::Matrix<double, 3, 3> locationDrawM =
|
||||
math::Shift(
|
||||
math::Scale(math::Identity<double, 3>(), k, k),
|
||||
pivot()
|
||||
);
|
||||
|
||||
m_locationDisplayList->draw(locationDrawM * m);
|
||||
|
||||
// 0 angle is for North ("up"), but in our coordinates it's to the right.
|
||||
double headingRad = m_headingRad - math::pi / 2.0;
|
||||
|
||||
if (m_hasCompass)
|
||||
{
|
||||
k = orientationRadius / m_cacheRadius;
|
||||
|
||||
math::Matrix<double, 3, 3> compassDrawM =
|
||||
math::Shift(
|
||||
math::Rotate(
|
||||
math::Scale(math::Identity<double, 3>(), k, k),
|
||||
screenAngle + headingRad),
|
||||
pivot());
|
||||
|
||||
m_compassDisplayList->draw(compassDrawM * m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void State::draw(yg::gl::OverlayRenderer * r,
|
||||
math::Matrix<double, 3, 3> const & m) const
|
||||
{
|
||||
if (isVisible())
|
||||
{
|
||||
checkDirtyDrawing();
|
||||
|
||||
if (m_hasPosition)
|
||||
{
|
||||
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 orientationRadius = max(pxErrorRadius, 30.0 * visualScale());
|
||||
|
||||
double screenAngle = m_framework->GetNavigator().Screen().GetAngle();
|
||||
|
||||
r->drawSymbol(pxPosition,
|
||||
"current-position",
|
||||
yg::EPosCenter,
|
||||
depth());
|
||||
|
||||
r->fillSector(pxPosition,
|
||||
0, 2.0 * math::pi,
|
||||
pxErrorRadius,
|
||||
m_locationAreaColor,
|
||||
depth() - 3);
|
||||
|
||||
// 0 angle is for North ("up"), but in our coordinates it's to the right.
|
||||
double headingRad = m_headingRad - math::pi / 2.0;
|
||||
|
||||
if (m_hasCompass)
|
||||
{
|
||||
r->drawSector(pxPosition,
|
||||
screenAngle + headingRad - m_headingHalfErrorRad,
|
||||
screenAngle + headingRad + m_headingHalfErrorRad,
|
||||
orientationRadius,
|
||||
m_compassAreaColor,
|
||||
depth());
|
||||
|
||||
r->fillSector(pxPosition,
|
||||
screenAngle + headingRad - m_headingHalfErrorRad,
|
||||
screenAngle + headingRad + m_headingHalfErrorRad,
|
||||
orientationRadius,
|
||||
m_compassBorderColor,
|
||||
depth() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void State::FollowCompass()
|
||||
{
|
||||
if (!m_fw->GetNavigator().DoSupportRotation())
|
||||
if (!m_framework->GetNavigator().DoSupportRotation())
|
||||
return;
|
||||
|
||||
m_fw->GetRenderPolicy()->GetAnimController()->Lock();
|
||||
m_framework->GetRenderPolicy()->GetAnimController()->Lock();
|
||||
|
||||
StopAnimation();
|
||||
|
||||
double startAngle = m_fw->GetNavigator().Screen().GetAngle();
|
||||
double startAngle = m_framework->GetNavigator().Screen().GetAngle();
|
||||
double endAngle = -m_headingRad;
|
||||
|
||||
double period = 2 * math::pi;
|
||||
|
@ -232,21 +395,23 @@ namespace location
|
|||
if (fabs(startAngle - endAngle) > math::pi)
|
||||
startAngle -= 2 * math::pi;
|
||||
|
||||
m_rotateScreenTask.reset(new RotateScreenTask(m_fw,
|
||||
m_rotateScreenTask.reset(new RotateScreenTask(m_framework,
|
||||
startAngle,
|
||||
endAngle,
|
||||
1));
|
||||
|
||||
m_fw->GetRenderPolicy()->GetAnimController()->AddTask(m_rotateScreenTask);
|
||||
m_framework->GetRenderPolicy()->GetAnimController()->AddTask(m_rotateScreenTask);
|
||||
}
|
||||
|
||||
m_fw->GetRenderPolicy()->GetAnimController()->Unlock();
|
||||
m_framework->GetRenderPolicy()->GetAnimController()->Unlock();
|
||||
}
|
||||
|
||||
void State::StopAnimation()
|
||||
{
|
||||
if (m_rotateScreenTask && !m_rotateScreenTask->IsFinished())
|
||||
m_rotateScreenTask->Finish();
|
||||
if (m_rotateScreenTask
|
||||
&& !m_rotateScreenTask->IsEnded()
|
||||
&& !m_rotateScreenTask->IsCancelled())
|
||||
m_rotateScreenTask->Cancel();
|
||||
m_rotateScreenTask.reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,19 @@
|
|||
|
||||
#include "../std/shared_ptr.hpp"
|
||||
|
||||
class DrawerYG;
|
||||
#include "../gui/element.hpp"
|
||||
|
||||
class Framework;
|
||||
class RotateScreenTask;
|
||||
|
||||
namespace yg
|
||||
{
|
||||
namespace gl
|
||||
{
|
||||
class DisplayList;
|
||||
}
|
||||
}
|
||||
|
||||
namespace location
|
||||
{
|
||||
class GpsInfo;
|
||||
|
@ -32,9 +41,10 @@ namespace location
|
|||
// Class, that handles position and compass updates,
|
||||
// centers, scales and rotates map according to this updates
|
||||
// and draws location and compass marks.
|
||||
class State
|
||||
class State : public gui::Element
|
||||
{
|
||||
private:
|
||||
|
||||
double m_errorRadius; //< error radius in mercator
|
||||
m2::PointD m_position; //< position in mercator
|
||||
|
||||
|
@ -49,13 +59,48 @@ namespace location
|
|||
|
||||
shared_ptr<RotateScreenTask> m_rotateScreenTask;
|
||||
|
||||
Framework * m_fw;
|
||||
|
||||
void FollowCompass();
|
||||
|
||||
/// GUI element related fields.
|
||||
|
||||
typedef gui::Element base_t;
|
||||
|
||||
yg::Color m_locationAreaColor;
|
||||
yg::Color m_locationBorderColor;
|
||||
|
||||
math::Matrix<double, 3, 3> m_locationDrawM;
|
||||
|
||||
yg::Color m_compassAreaColor;
|
||||
yg::Color m_compassBorderColor;
|
||||
|
||||
math::Matrix<double, 3, 3> m_compassDrawM;
|
||||
|
||||
Framework * m_framework;
|
||||
|
||||
double m_cacheRadius;
|
||||
|
||||
shared_ptr<yg::gl::DisplayList> m_locationDisplayList;
|
||||
shared_ptr<yg::gl::DisplayList> m_compassDisplayList;
|
||||
|
||||
/* void cache();
|
||||
void purge();
|
||||
void update();*/
|
||||
|
||||
mutable vector<m2::AnyRectD> m_boundRects;
|
||||
m2::RectD m_boundRect;
|
||||
|
||||
public:
|
||||
|
||||
State(Framework * framework);
|
||||
struct Params : base_t::Params
|
||||
{
|
||||
yg::Color m_locationAreaColor;
|
||||
yg::Color m_locationBorderColor;
|
||||
yg::Color m_compassAreaColor;
|
||||
yg::Color m_compassBorderColor;
|
||||
Framework * m_framework;
|
||||
};
|
||||
|
||||
State(Params const & p);
|
||||
|
||||
/// @return GPS center point in mercator
|
||||
m2::PointD const & Position() const { return m_position; }
|
||||
|
@ -71,7 +116,6 @@ namespace location
|
|||
|
||||
void TurnOff();
|
||||
|
||||
void Draw(DrawerYG & drawer);
|
||||
void StopAnimation();
|
||||
|
||||
/// @name GPS location updates routine.
|
||||
|
@ -81,5 +125,8 @@ namespace location
|
|||
void OnGpsUpdate(location::GpsInfo const & info);
|
||||
void OnCompassUpdate(location::CompassInfo const & info);
|
||||
//@}
|
||||
|
||||
vector<m2::AnyRectD> const & boundRects() const;
|
||||
void draw(yg::gl::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const;
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue