mirror of
https://codeberg.org/comaps/comaps
synced 2026-01-20 10:13:51 +00:00
[drape] Remember navigation mode between sessions
Signed-off-by: Leonardo Bishop <me@leonardobishop.net>
This commit is contained in:
committed by
Konstantin Pastbin
parent
2b6cd0db54
commit
f9485d44f5
@@ -19,6 +19,7 @@ using namespace std::placeholders;
|
||||
namespace
|
||||
{
|
||||
std::string_view constexpr kLocationStateMode = "LastLocationStateMode";
|
||||
std::string_view constexpr kPreferredRoutingMode = "PreferredRoutingMode";
|
||||
std::string_view constexpr kLastEnterBackground = "LastEnterBackground";
|
||||
} // namespace
|
||||
|
||||
@@ -39,16 +40,20 @@ DrapeEngine::DrapeEngine(Params && params)
|
||||
m_requestedTiles = make_unique_dp<RequestedTiles>();
|
||||
|
||||
using namespace location;
|
||||
EMyPositionMode mode = PendingPosition;
|
||||
if (settings::Get(kLocationStateMode, mode) && mode == FollowAndRotate)
|
||||
EMyPositionMode lastMode = PendingPosition;
|
||||
if (settings::Get(kLocationStateMode, lastMode) && lastMode == FollowAndRotate)
|
||||
{
|
||||
// If the screen rect setting in follow and rotate mode is missing or invalid, it could cause
|
||||
// invalid animations, so the follow and rotate mode should be discarded.
|
||||
m2::AnyRectD rect;
|
||||
if (!(settings::Get("ScreenClipRect", rect) && df::GetWorldRect().IsRectInside(rect.GetGlobalRect())))
|
||||
mode = Follow;
|
||||
lastMode = Follow;
|
||||
}
|
||||
|
||||
EMyPositionMode preferredRoutingMode;
|
||||
if (!settings::Get(kPreferredRoutingMode, preferredRoutingMode))
|
||||
preferredRoutingMode = FollowAndRotate;
|
||||
|
||||
if (!settings::Get(kLastEnterBackground, m_startBackgroundTime))
|
||||
m_startBackgroundTime = base::Timer::LocalTime();
|
||||
|
||||
@@ -65,9 +70,10 @@ DrapeEngine::DrapeEngine(Params && params)
|
||||
// effects.push_back(PostprocessRenderer::Antialiasing);
|
||||
//}
|
||||
|
||||
MyPositionController::Params mpParams(mode, base::Timer::LocalTime() - m_startBackgroundTime, params.m_hints,
|
||||
MyPositionController::Params mpParams(lastMode, preferredRoutingMode,
|
||||
base::Timer::LocalTime() - m_startBackgroundTime, params.m_hints,
|
||||
params.m_isRoutingActive, params.m_isAutozoomEnabled,
|
||||
std::bind(&DrapeEngine::MyPositionModeChanged, this, _1, _2));
|
||||
std::bind(&DrapeEngine::MyPositionModeChanged, this, _1, _2, _3));
|
||||
|
||||
FrontendRenderer::Params frParams(
|
||||
params.m_apiVersion, make_ref(m_threadCommutator), params.m_factory, make_ref(m_textureManager),
|
||||
@@ -404,9 +410,11 @@ void DrapeEngine::ModelViewChanged(ScreenBase const & screen)
|
||||
m_modelViewChangedHandler(screen);
|
||||
}
|
||||
|
||||
void DrapeEngine::MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive)
|
||||
void DrapeEngine::MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive, bool shouldPersistMode)
|
||||
{
|
||||
settings::Set(kLocationStateMode, mode);
|
||||
if (shouldPersistMode && routingActive)
|
||||
settings::Set(kPreferredRoutingMode, mode);
|
||||
if (m_myPositionModeChanged)
|
||||
m_myPositionModeChanged(mode, routingActive);
|
||||
}
|
||||
@@ -458,6 +466,12 @@ void DrapeEngine::SwitchMyPositionNextMode()
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
void DrapeEngine::StartPendingPositionMode()
|
||||
{
|
||||
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp<StartPendingPositionModeMessage>(),
|
||||
MessagePriority::Normal);
|
||||
}
|
||||
|
||||
void DrapeEngine::LoseLocation()
|
||||
{
|
||||
using Mode = ChangeMyPositionModeMessage::EChangeType;
|
||||
|
||||
@@ -157,6 +157,7 @@ public:
|
||||
void SetGpsInfo(location::GpsInfo const & info, bool isNavigable, double distToNextTurn, double speedLimit,
|
||||
location::RouteMatchingInfo const & routeInfo);
|
||||
void SwitchMyPositionNextMode();
|
||||
void StartPendingPositionMode();
|
||||
void LoseLocation();
|
||||
void StopLocationFollow();
|
||||
|
||||
@@ -250,7 +251,7 @@ private:
|
||||
void AddUserEvent(drape_ptr<UserEvent> && e);
|
||||
void PostUserEvent(drape_ptr<UserEvent> && e);
|
||||
void ModelViewChanged(ScreenBase const & screen);
|
||||
void MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive);
|
||||
void MyPositionModeChanged(location::EMyPositionMode mode, bool routingActive, bool shouldPersistMode);
|
||||
void TapEvent(TapInfo const & tapInfo);
|
||||
void UserPositionChanged(m2::PointD const & position, bool hasPosition);
|
||||
|
||||
|
||||
@@ -425,6 +425,12 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
|
||||
break;
|
||||
}
|
||||
|
||||
case Message::Type::StartPendingPositionMode:
|
||||
{
|
||||
m_myPositionController->StartPendingPositionMode();
|
||||
break;
|
||||
}
|
||||
|
||||
case Message::Type::CompassInfo:
|
||||
{
|
||||
ref_ptr<CompassInfoMessage> msg = message;
|
||||
|
||||
@@ -33,6 +33,7 @@ std::string DebugPrint(Message::Type msgType)
|
||||
case Message::Type::MapShapesRecache: return "MapShapesRecache";
|
||||
case Message::Type::MapShapes: return "MapShapes";
|
||||
case Message::Type::ChangeMyPositionMode: return "ChangeMyPositionMode";
|
||||
case Message::Type::StartPendingPositionMode: return "StartPendingPositionMode";
|
||||
case Message::Type::CompassInfo: return "CompassInfo";
|
||||
case Message::Type::GpsInfo: return "GpsInfo";
|
||||
case Message::Type::SelectObject: return "SelectObject";
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
MapShapesRecache,
|
||||
MapShapes,
|
||||
ChangeMyPositionMode,
|
||||
StartPendingPositionMode,
|
||||
CompassInfo,
|
||||
GpsInfo,
|
||||
SelectObject,
|
||||
|
||||
@@ -459,6 +459,12 @@ private:
|
||||
EChangeType const m_changeType;
|
||||
};
|
||||
|
||||
class StartPendingPositionModeMessage : public Message
|
||||
{
|
||||
public:
|
||||
Type GetType() const override { return Type::StartPendingPositionMode; }
|
||||
};
|
||||
|
||||
class CompassInfoMessage : public Message
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "platform/location.hpp"
|
||||
#include "platform/measurement_utils.hpp"
|
||||
|
||||
#include "base/math.hpp"
|
||||
@@ -203,8 +204,10 @@ MyPositionController::MyPositionController(Params && params, ref_ptr<DrapeNotifi
|
||||
m_mode = NotFollowNoPosition;
|
||||
}
|
||||
|
||||
m_preferredRoutingMode = params.m_preferredRoutingMode;
|
||||
|
||||
if (m_modeChangeCallback)
|
||||
m_modeChangeCallback(m_mode, m_isInRouting);
|
||||
m_modeChangeCallback(m_mode, m_isInRouting, false);
|
||||
}
|
||||
|
||||
void MyPositionController::UpdatePosition()
|
||||
@@ -398,7 +401,11 @@ void MyPositionController::NextMode(ScreenBase const & screen)
|
||||
// In routing not-follow -> follow-and-rotate, otherwise not-follow -> follow.
|
||||
if (m_mode == location::NotFollow)
|
||||
{
|
||||
ChangeMode(m_isInRouting ? location::FollowAndRotate : location::Follow);
|
||||
if ((IsRotationAvailable() || m_isInRouting) && m_preferredRoutingMode == location::FollowAndRotate)
|
||||
ChangeMode(location::FollowAndRotate, true);
|
||||
else
|
||||
ChangeMode(location::Follow, true);
|
||||
|
||||
UpdateViewport(preferredZoomLevel);
|
||||
return;
|
||||
}
|
||||
@@ -409,7 +416,7 @@ void MyPositionController::NextMode(ScreenBase const & screen)
|
||||
{
|
||||
if (IsRotationAvailable() || m_isInRouting)
|
||||
{
|
||||
ChangeMode(location::FollowAndRotate);
|
||||
ChangeMode(location::FollowAndRotate, true);
|
||||
UpdateViewport(preferredZoomLevel);
|
||||
}
|
||||
return;
|
||||
@@ -420,11 +427,20 @@ void MyPositionController::NextMode(ScreenBase const & screen)
|
||||
{
|
||||
if (m_isInRouting && screen.isPerspective())
|
||||
preferredZoomLevel = static_cast<int>(GetZoomLevel(ScreenBase::GetStartPerspectiveScale() * 1.1));
|
||||
ChangeMode(location::Follow);
|
||||
ChangeMode(location::Follow, true);
|
||||
ChangeModelView(m_position, 0.0, m_visiblePixelRect.Center(), preferredZoomLevel);
|
||||
}
|
||||
}
|
||||
|
||||
void MyPositionController::StartPendingPositionMode()
|
||||
{
|
||||
if (m_mode == location::NotFollowNoPosition)
|
||||
{
|
||||
ChangeMode(location::PendingPosition);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool isNavigable, double distanceToNextTurn,
|
||||
double speedLimit, ScreenBase const & screen)
|
||||
{
|
||||
@@ -478,8 +494,7 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool
|
||||
|
||||
if (!m_isPositionAssigned)
|
||||
{
|
||||
location::EMyPositionMode newMode = m_desiredInitMode;
|
||||
ChangeMode(newMode);
|
||||
ChangeMode(m_isInRouting ? m_preferredRoutingMode : m_desiredInitMode, true);
|
||||
|
||||
if (!m_hints.m_isFirstLaunch || !AnimationSystem::Instance().AnimationExists(Animation::Object::MapPlane))
|
||||
{
|
||||
@@ -497,14 +512,14 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool
|
||||
}
|
||||
else if (m_mode == location::PendingPosition)
|
||||
{
|
||||
if (m_isInRouting)
|
||||
if (m_isInRouting && m_preferredRoutingMode == location::FollowAndRotate)
|
||||
{
|
||||
ChangeMode(location::FollowAndRotate);
|
||||
ChangeMode(location::FollowAndRotate, true);
|
||||
UpdateViewport(kMaxScaleZoomLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeMode(location::Follow);
|
||||
ChangeMode(location::Follow, true);
|
||||
if (m_hints.m_isFirstLaunch)
|
||||
{
|
||||
if (!AnimationSystem::Instance().AnimationExists(Animation::Object::MapPlane))
|
||||
@@ -523,15 +538,15 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool
|
||||
}
|
||||
else if (m_mode == location::NotFollowNoPosition)
|
||||
{
|
||||
if (m_isInRouting)
|
||||
if (m_isInRouting && m_preferredRoutingMode == location::FollowAndRotate)
|
||||
{
|
||||
ChangeMode(location::FollowAndRotate);
|
||||
ChangeMode(location::FollowAndRotate, true);
|
||||
UpdateViewport(kMaxScaleZoomLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Here we silently get the position and go to NotFollow mode.
|
||||
ChangeMode(location::NotFollow);
|
||||
ChangeMode(location::NotFollow, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,13 +668,24 @@ void MyPositionController::SetDirection(double bearing)
|
||||
}
|
||||
|
||||
void MyPositionController::ChangeMode(location::EMyPositionMode newMode)
|
||||
{
|
||||
ChangeMode(newMode, false);
|
||||
}
|
||||
|
||||
void MyPositionController::ChangeMode(location::EMyPositionMode newMode, bool shouldPersist)
|
||||
{
|
||||
if (m_isInRouting && (m_mode != newMode) && (newMode == location::FollowAndRotate))
|
||||
ResetBlockAutoZoomTimer();
|
||||
|
||||
m_mode = newMode;
|
||||
|
||||
// We should remember this mode if the user intentionally caused the mode change
|
||||
// (e.g. tapping the mode button)
|
||||
if (m_isInRouting && shouldPersist)
|
||||
m_preferredRoutingMode = newMode;
|
||||
|
||||
if (m_modeChangeCallback)
|
||||
m_modeChangeCallback(m_mode, m_isInRouting);
|
||||
m_modeChangeCallback(m_mode, m_isInRouting, shouldPersist);
|
||||
}
|
||||
|
||||
bool MyPositionController::IsWaitingForLocation() const
|
||||
@@ -690,7 +716,8 @@ void MyPositionController::OnEnterForeground(double backgroundTime)
|
||||
// When location was active during previous session the app will try to follow the user.
|
||||
if (m_mode == location::NotFollow)
|
||||
{
|
||||
ChangeMode(m_isInRouting ? location::FollowAndRotate : location::Follow);
|
||||
ChangeMode((m_isInRouting && m_preferredRoutingMode == location::FollowAndRotate) ? location::FollowAndRotate
|
||||
: location::Follow);
|
||||
UpdateViewport(kDoNotChangeZoom);
|
||||
}
|
||||
|
||||
@@ -876,9 +903,17 @@ void MyPositionController::ActivateRouting(int zoomLevel, bool enableAutoZoom, b
|
||||
m_isArrowGluedInRouting = isArrowGlued;
|
||||
m_enableAutoZoomInRouting = enableAutoZoom;
|
||||
|
||||
ChangeMode(location::FollowAndRotate);
|
||||
ChangeModelView(m_position, m_isDirectionAssigned ? m_drawDirection : 0.0, GetRoutingRotationPixelCenter(),
|
||||
zoomLevel, [this](ref_ptr<Animation> anim) { UpdateViewport(kDoNotChangeZoom); });
|
||||
if (m_preferredRoutingMode == location::Follow)
|
||||
{
|
||||
ChangeMode(location::Follow);
|
||||
ChangeModelView(m_position, kDoNotChangeZoom);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeMode(location::FollowAndRotate);
|
||||
ChangeModelView(m_position, m_isDirectionAssigned ? m_drawDirection : 0.0, GetRoutingRotationPixelCenter(),
|
||||
zoomLevel, [this](ref_ptr<Animation> anim) { UpdateViewport(kDoNotChangeZoom); });
|
||||
}
|
||||
ResetRoutingNotFollowTimer();
|
||||
}
|
||||
}
|
||||
@@ -919,7 +954,7 @@ void MyPositionController::CheckNotFollowRouting()
|
||||
CHECK_ON_TIMEOUT(m_routingNotFollowNotifyId, kMaxNotFollowRoutingTimeSec, CheckNotFollowRouting);
|
||||
if (m_routingNotFollowTimer.ElapsedSeconds() >= kMaxNotFollowRoutingTimeSec)
|
||||
{
|
||||
ChangeMode(location::FollowAndRotate);
|
||||
ChangeMode(m_preferredRoutingMode);
|
||||
UpdateViewport(kDoNotChangeZoom);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace df
|
||||
{
|
||||
using TAnimationCreator = std::function<drape_ptr<Animation>(ref_ptr<Animation>)>;
|
||||
|
||||
using TMyPositionModeChanged = std::function<void(location::EMyPositionMode, bool, bool)>;
|
||||
|
||||
class DrapeNotifier;
|
||||
|
||||
class MyPositionController
|
||||
@@ -49,9 +51,10 @@ public:
|
||||
|
||||
struct Params
|
||||
{
|
||||
Params(location::EMyPositionMode initMode, double timeInBackground, Hints const & hints, bool isRoutingActive,
|
||||
bool isAutozoomEnabled, location::TMyPositionModeChanged && fn)
|
||||
Params(location::EMyPositionMode initMode, location::EMyPositionMode preferredRoutingMode, double timeInBackground,
|
||||
Hints const & hints, bool isRoutingActive, bool isAutozoomEnabled, TMyPositionModeChanged && fn)
|
||||
: m_initMode(initMode)
|
||||
, m_preferredRoutingMode(preferredRoutingMode)
|
||||
, m_timeInBackground(timeInBackground)
|
||||
, m_hints(hints)
|
||||
, m_isRoutingActive(isRoutingActive)
|
||||
@@ -60,11 +63,12 @@ public:
|
||||
{}
|
||||
|
||||
location::EMyPositionMode m_initMode;
|
||||
location::EMyPositionMode m_preferredRoutingMode;
|
||||
double m_timeInBackground;
|
||||
Hints m_hints;
|
||||
bool m_isRoutingActive;
|
||||
bool m_isAutozoomEnabled;
|
||||
location::TMyPositionModeChanged m_myPositionModeCallback;
|
||||
TMyPositionModeChanged m_myPositionModeCallback;
|
||||
};
|
||||
|
||||
MyPositionController(Params && params, ref_ptr<DrapeNotifier> notifier);
|
||||
@@ -112,6 +116,7 @@ public:
|
||||
void NextMode(ScreenBase const & screen);
|
||||
void LoseLocation();
|
||||
location::EMyPositionMode GetCurrentMode() const { return m_mode; }
|
||||
void StartPendingPositionMode();
|
||||
|
||||
void OnEnterForeground(double backgroundTime);
|
||||
void OnEnterBackground();
|
||||
@@ -134,6 +139,7 @@ public:
|
||||
void UpdateRoutingOffsetY(bool useDefault, int offsetY);
|
||||
|
||||
private:
|
||||
void ChangeMode(location::EMyPositionMode newMode, bool persist);
|
||||
void ChangeMode(location::EMyPositionMode newMode);
|
||||
void SetDirection(double bearing);
|
||||
|
||||
@@ -163,7 +169,8 @@ private:
|
||||
|
||||
location::EMyPositionMode m_mode;
|
||||
location::EMyPositionMode m_desiredInitMode;
|
||||
location::TMyPositionModeChanged m_modeChangeCallback;
|
||||
location::EMyPositionMode m_preferredRoutingMode;
|
||||
TMyPositionModeChanged m_modeChangeCallback;
|
||||
Hints m_hints;
|
||||
|
||||
bool m_isInRouting = false;
|
||||
|
||||
@@ -206,6 +206,12 @@ void Framework::SwitchMyPositionNextMode()
|
||||
m_drapeEngine->SwitchMyPositionNextMode();
|
||||
}
|
||||
|
||||
void Framework::StartPendingPositionMode()
|
||||
{
|
||||
if (m_drapeEngine != nullptr)
|
||||
m_drapeEngine->StartPendingPositionMode();
|
||||
}
|
||||
|
||||
void Framework::SetMyPositionModeListener(TMyPositionModeChanged && fn)
|
||||
{
|
||||
m_myPositionListener = std::move(fn);
|
||||
|
||||
@@ -390,6 +390,7 @@ public:
|
||||
void OnLocationUpdate(location::GpsInfo const & info);
|
||||
void OnCompassUpdate(location::CompassInfo const & info);
|
||||
void SwitchMyPositionNextMode();
|
||||
void StartPendingPositionMode();
|
||||
/// Should be set before Drape initialization. Guarantees that fn is called in main thread context.
|
||||
void SetMyPositionModeListener(location::TMyPositionModeChanged && fn);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user