Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaria Volvenkova <d.volvenkova@corp.mail.ru>2016-09-05 13:17:07 +0300
committerDaria Volvenkova <d.volvenkova@corp.mail.ru>2016-09-26 17:26:00 +0300
commit24834ce40c571ef6021991350bc0863279f71497 (patch)
tree96d0d4c8f9b8f36aa50f76442eef29a2cae4813c
parent12be223279b3e84da9d58e0143793f854d5761e3 (diff)
Positioning in visible viewport.
-rw-r--r--android/jni/com/mapswithme/maps/Framework.cpp2
-rw-r--r--drape/overlay_tree.cpp17
-rw-r--r--drape/overlay_tree.hpp1
-rw-r--r--drape_frontend/drape_engine.cpp7
-rw-r--r--drape_frontend/drape_engine.hpp2
-rw-r--r--drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp5
-rwxr-xr-xdrape_frontend/frontend_renderer.cpp60
-rwxr-xr-xdrape_frontend/frontend_renderer.hpp1
-rw-r--r--drape_frontend/message.hpp3
-rw-r--r--drape_frontend/message_subclasses.hpp14
-rw-r--r--drape_frontend/my_position_controller.cpp29
-rw-r--r--drape_frontend/my_position_controller.hpp9
-rw-r--r--drape_frontend/selection_shape.cpp22
-rw-r--r--drape_frontend/selection_shape.hpp4
-rw-r--r--drape_frontend/user_event_stream.cpp33
-rw-r--r--drape_frontend/user_event_stream.hpp23
-rw-r--r--map/framework.cpp15
-rw-r--r--map/framework.hpp3
18 files changed, 221 insertions, 29 deletions
diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp
index 573059dd63..83cd8e6bc8 100644
--- a/android/jni/com/mapswithme/maps/Framework.cpp
+++ b/android/jni/com/mapswithme/maps/Framework.cpp
@@ -1171,7 +1171,7 @@ Java_com_mapswithme_maps_Framework_nativeGetActiveObjectFormattedCuisine(JNIEnv
JNIEXPORT void JNICALL
Java_com_mapswithme_maps_Framework_nativeSetVisibleRect(JNIEnv * env, jclass, jint left, jint top, jint right, jint bottom)
{
- //TODO: call framework method
+ frm()->SetVisibleViewport(m2::RectD(left, top, right, bottom));
}
} // extern "C"
diff --git a/drape/overlay_tree.cpp b/drape/overlay_tree.cpp
index 9daf1e229a..275df08525 100644
--- a/drape/overlay_tree.cpp
+++ b/drape/overlay_tree.cpp
@@ -367,6 +367,23 @@ void OverlayTree::DeleteHandle(ref_ptr<OverlayHandle> const & handle)
Erase(handle);
}
+bool OverlayTree::GetSelectedFeatureRect(ScreenBase const & screen, m2::RectD & featureRect)
+{
+ if (!m_selectedFeatureID.IsValid())
+ return false;
+
+ featureRect.MakeEmpty();
+ for (auto const & handle : m_handlesCache)
+ {
+ if (handle->IsVisible() && handle->GetFeatureID() == m_selectedFeatureID)
+ {
+ m2::RectD rect = handle->GetPixelRect(screen, screen.isPerspective());
+ featureRect.Add(rect);
+ }
+ }
+ return true;
+}
+
void OverlayTree::Select(m2::PointD const & glbPoint, TOverlayContainer & result) const
{
ScreenBase const & screen = m_traits.m_modelView;
diff --git a/drape/overlay_tree.hpp b/drape/overlay_tree.hpp
index 8a65e18afb..ef669d1a7b 100644
--- a/drape/overlay_tree.hpp
+++ b/drape/overlay_tree.hpp
@@ -66,6 +66,7 @@ public:
void SetDisplacementMode(int displacementMode);
void SetSelectedFeature(FeatureID const & featureID);
+ bool GetSelectedFeatureRect(ScreenBase const & screen, m2::RectD & featureRect);
#ifdef COLLECT_DISPLACEMENT_INFO
struct DisplacementData
diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp
index 42b4b554a2..402a9d732a 100644
--- a/drape_frontend/drape_engine.cpp
+++ b/drape_frontend/drape_engine.cpp
@@ -111,6 +111,13 @@ void DrapeEngine::Resize(int w, int h)
ResizeImpl(w, h);
}
+void DrapeEngine::SetVisibleViewport(m2::RectD const & rect) const
+{
+ m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
+ make_unique_dp<SetVisibleViewportMessage>(rect),
+ MessagePriority::Normal);
+}
+
void DrapeEngine::Invalidate()
{
m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread,
diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp
index 8eacbbde71..c908b64dec 100644
--- a/drape_frontend/drape_engine.hpp
+++ b/drape_frontend/drape_engine.hpp
@@ -89,6 +89,8 @@ public:
void Resize(int w, int h);
void Invalidate();
+ void SetVisibleViewport(m2::RectD const & rect) const;
+
void AddTouchEvent(TouchEvent const & event);
void Scale(double factor, m2::PointD const & pxPoint, bool isAnim);
diff --git a/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp b/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp
index 036019ea90..e79148ff47 100644
--- a/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp
+++ b/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp
@@ -38,6 +38,11 @@ public:
void OnScaleEnded() override {}
void OnTouchMapAction() override {}
void OnAnimatedScaleEnded() override {}
+ bool OnNewVisibleViewport(m2::RectD const & oldViewport, m2::RectD const & newViewport,
+ m2::PointD & gOffset) override
+ {
+ return false;
+ }
void AddUserEvent(df::TouchEvent const & event)
{
diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp
index 61182eee24..e9bf267a5e 100755
--- a/drape_frontend/frontend_renderer.cpp
+++ b/drape_frontend/frontend_renderer.cpp
@@ -387,6 +387,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
{
ProcessSelection(make_ref(m_selectObjectMessage));
m_selectObjectMessage.reset();
+ AddUserEvent(make_unique_dp<SetVisibleViewportEvent>(m_userEventStream.GetVisibleViewport()));
}
}
break;
@@ -452,6 +453,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
break;
}
ProcessSelection(msg);
+ AddUserEvent(make_unique_dp<SetVisibleViewportEvent>(m_userEventStream.GetVisibleViewport()));
+
break;
}
@@ -718,6 +721,15 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
break;
}
+ case Message::SetVisibleViewport:
+ {
+ ref_ptr<SetVisibleViewportMessage> msg = message;
+ AddUserEvent(make_unique_dp<SetVisibleViewportEvent>(msg->GetRect()));
+ m_myPositionController->SetVisibleViewport(msg->GetRect());
+ m_myPositionController->UpdatePosition();
+ break;
+ }
+
case Message::Invalidate:
{
m_myPositionController->ResetRoutingNotFollowTimer();
@@ -843,11 +855,11 @@ void FrontendRenderer::OnResize(ScreenBase const & screen)
double const kEps = 1e-5;
bool const viewportChanged = !m2::IsEqualSize(m_lastReadedModelView.PixelRectIn3d(), viewportRect, kEps, kEps);
- m_myPositionController->UpdatePixelPosition(screen);
+ m_myPositionController->OnUpdateScreen(screen);
if (viewportChanged)
{
- m_myPositionController->OnNewViewportRect();
+ m_myPositionController->UpdatePosition();
m_viewport.SetViewport(0, 0, viewportRect.SizeX(), viewportRect.SizeY());
}
@@ -1438,6 +1450,48 @@ void FrontendRenderer::OnTouchMapAction()
m_myPositionController->ResetRoutingNotFollowTimer();
}
+bool FrontendRenderer::OnNewVisibleViewport(m2::RectD const & oldViewport, m2::RectD const & newViewport, m2::PointD & gOffset)
+{
+ gOffset = m2::PointD(0, 0);
+ if (m_myPositionController->IsModeChangeViewport() || m_selectionShape == nullptr)
+ return false;
+
+ ScreenBase const & screen = m_userEventStream.GetCurrentScreen();
+ m2::PointD pos;
+
+ double const vs = VisualParams::Instance().GetVisualScale();
+ if (m_selectionShape->IsVisible(screen, pos))
+ {
+ m2::RectD rect(pos, pos);
+ if (!(m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_POI &&
+ m_overlayTree->GetSelectedFeatureRect(screen, rect)))
+ {
+ double const r = m_selectionShape->GetRadius();
+ rect.Inflate(r, r);
+ }
+
+ if (oldViewport.IsIntersect(rect) && !newViewport.IsRectInside(rect))
+ {
+ double const kOffset = 50 * vs;
+ m2::PointD pOffset(0.0, 0.0);
+ if (rect.minX() < newViewport.minX())
+ pOffset.x = newViewport.minX() - rect.minX() + kOffset;
+ else if (rect.maxX() > newViewport.maxX())
+ pOffset.x = newViewport.maxX() - rect.maxX() - kOffset;
+
+ if (rect.minY() < newViewport.minY())
+ pOffset.y = newViewport.minY() - rect.minY() + kOffset;
+ else if (rect.maxY() > newViewport.maxY())
+ pOffset.y = newViewport.maxY() - rect.maxY() - kOffset;
+
+ gOffset = screen.PtoG(screen.P3dtoP(pos + pOffset)) - screen.PtoG(screen.P3dtoP(pos));
+
+ }
+ return true;
+ }
+ return false;
+}
+
TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen)
{
m2::RectD const & rect = screen.ClipRect();
@@ -1726,7 +1780,7 @@ void FrontendRenderer::PrepareScene(ScreenBase const & modelView)
RefreshZScale(modelView);
RefreshPivotTransform(modelView);
- m_myPositionController->UpdatePixelPosition(modelView);
+ m_myPositionController->OnUpdateScreen(modelView);
m_routeRenderer->UpdateRoute(modelView, bind(&FrontendRenderer::OnCacheRouteArrows, this, _1, _2));
}
diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp
index 47c443e668..cccc8e4578 100755
--- a/drape_frontend/frontend_renderer.hpp
+++ b/drape_frontend/frontend_renderer.hpp
@@ -203,6 +203,7 @@ private:
void OnScaleEnded() override;
void OnAnimatedScaleEnded() override;
void OnTouchMapAction() override;
+ bool OnNewVisibleViewport(m2::RectD const & oldViewport, m2::RectD const & newViewport, m2::PointD & gOffset) override;
class Routine : public threads::IRoutine
{
diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp
index e237b93c6c..851608e968 100644
--- a/drape_frontend/message.hpp
+++ b/drape_frontend/message.hpp
@@ -63,7 +63,8 @@ public:
SetDisplacementMode,
AllowAutoZoom,
RequestSymbolsSize,
- RecoverGLResources
+ RecoverGLResources,
+ SetVisibleViewport
};
virtual ~Message() {}
diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp
index 67ad21e1f1..03c418a634 100644
--- a/drape_frontend/message_subclasses.hpp
+++ b/drape_frontend/message_subclasses.hpp
@@ -794,6 +794,20 @@ public:
bool IsGLContextDependent() const override { return true; }
};
+class SetVisibleViewportMessage : public Message
+{
+public:
+ SetVisibleViewportMessage(m2::RectD const & rect)
+ : m_rect(rect)
+ {}
+
+ Type GetType() const override { return Message::SetVisibleViewport; }
+ m2::RectD const & GetRect() const { return m_rect; }
+
+private:
+ m2::RectD m_rect;
+};
+
class DeactivateRouteFollowingMessage : public Message
{
public:
diff --git a/drape_frontend/my_position_controller.cpp b/drape_frontend/my_position_controller.cpp
index 592ea95390..ea2fc4befe 100644
--- a/drape_frontend/my_position_controller.cpp
+++ b/drape_frontend/my_position_controller.cpp
@@ -167,15 +167,22 @@ MyPositionController::~MyPositionController()
{
}
-void MyPositionController::OnNewViewportRect()
+void MyPositionController::UpdatePosition()
{
UpdateViewport(kDoNotChangeZoom);
}
-void MyPositionController::UpdatePixelPosition(ScreenBase const & screen)
+void MyPositionController::OnUpdateScreen(ScreenBase const & screen)
{
m_pixelRect = screen.isPerspective() ? screen.PixelRectIn3d() : screen.PixelRect();
m_positionYOffset = screen.isPerspective() ? kPositionOffsetYIn3D : kPositionOffsetY;
+ if (m_visiblePixelRect.IsEmptyInterior())
+ m_visiblePixelRect = m_pixelRect;
+}
+
+void MyPositionController::SetVisibleViewport(const m2::RectD &rect)
+{
+ m_visiblePixelRect = rect;
}
void MyPositionController::SetListener(ref_ptr<MyPositionController::Listener> listener)
@@ -344,7 +351,7 @@ void MyPositionController::NextMode(ScreenBase const & screen)
if (!m_isInRouting)
{
ChangeMode(location::Follow);
- ChangeModelView(m_position, 0.0, m_pixelRect.Center(), preferredZoomLevel);
+ ChangeModelView(m_position, 0.0, m_visiblePixelRect.Center(), preferredZoomLevel);
}
}
}
@@ -399,7 +406,7 @@ void MyPositionController::OnLocationUpdate(location::GpsInfo const & info, bool
ChangeModelView(m_position, kDoNotChangeZoom);
else if (m_mode == location::FollowAndRotate)
ChangeModelView(m_position, m_drawDirection,
- m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(), kDoNotChangeZoom);
+ m_isInRouting ? GetRoutingRotationPixelCenter() : m_visiblePixelRect.Center(), kDoNotChangeZoom);
}
}
else if (m_mode == location::PendingPosition || m_mode == location::NotFollowNoPosition)
@@ -635,7 +642,7 @@ void MyPositionController::OnCompassTapped()
if (m_mode == location::FollowAndRotate)
{
ChangeMode(location::Follow);
- ChangeModelView(m_position, 0.0, m_pixelRect.Center(), kDoNotChangeZoom);
+ ChangeModelView(m_position, 0.0, m_visiblePixelRect.Center(), kDoNotChangeZoom);
}
else
{
@@ -688,24 +695,24 @@ void MyPositionController::UpdateViewport(int zoomLevel)
ChangeModelView(m_position, zoomLevel);
else if (m_mode == location::FollowAndRotate)
ChangeModelView(m_position, m_drawDirection,
- m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center(), zoomLevel);
+ m_isInRouting ? GetRoutingRotationPixelCenter() : m_visiblePixelRect.Center(), zoomLevel);
}
m2::PointD MyPositionController::GetRotationPixelCenter() const
{
if (m_mode == location::Follow)
- return m_pixelRect.Center();
+ return m_visiblePixelRect.Center();
if (m_mode == location::FollowAndRotate)
- return m_isInRouting ? GetRoutingRotationPixelCenter() : m_pixelRect.Center();
+ return m_isInRouting ? GetRoutingRotationPixelCenter() : m_visiblePixelRect.Center();
return m2::PointD::Zero();
}
m2::PointD MyPositionController::GetRoutingRotationPixelCenter() const
{
- return m2::PointD(m_pixelRect.Center().x,
- m_pixelRect.maxY() - m_positionYOffset * VisualParams::Instance().GetVisualScale());
+ return m2::PointD(m_visiblePixelRect.Center().x,
+ m_visiblePixelRect.maxY() - m_positionYOffset * VisualParams::Instance().GetVisualScale());
}
m2::PointD MyPositionController::GetDrawablePosition()
@@ -806,7 +813,7 @@ void MyPositionController::DeactivateRouting()
m_isInRouting = false;
ChangeMode(location::Follow);
- ChangeModelView(m_position, 0.0, m_pixelRect.Center(), kDoNotChangeZoom);
+ ChangeModelView(m_position, 0.0, m_visiblePixelRect.Center(), kDoNotChangeZoom);
}
}
diff --git a/drape_frontend/my_position_controller.hpp b/drape_frontend/my_position_controller.hpp
index 51d9ff75ef..1f11c1e7b7 100644
--- a/drape_frontend/my_position_controller.hpp
+++ b/drape_frontend/my_position_controller.hpp
@@ -44,8 +44,10 @@ public:
bool isFirstLaunch, bool isRoutingActive, bool isAutozoomEnabled);
~MyPositionController();
- void OnNewViewportRect();
- void UpdatePixelPosition(ScreenBase const & screen);
+ void UpdatePosition();
+ void OnUpdateScreen(ScreenBase const & screen);
+ void SetVisibleViewport(m2::RectD const & rect);
+
void SetListener(ref_ptr<Listener> listener);
m2::PointD const & Position() const;
@@ -97,12 +99,12 @@ public:
bool IsInRouting() const { return m_isInRouting; }
bool IsRouteFollowingActive() const;
bool IsWaitingForTimers() const;
+ bool IsModeChangeViewport() const;
bool IsWaitingForLocation() const;
m2::PointD GetDrawablePosition();
private:
- bool IsModeChangeViewport() const;
void ChangeMode(location::EMyPositionMode newMode);
void SetDirection(double bearing);
@@ -161,6 +163,7 @@ private:
double m_lastLocationTimestamp;
m2::RectD m_pixelRect;
+ m2::RectD m_visiblePixelRect;
double m_positionYOffset;
bool m_isVisible;
diff --git a/drape_frontend/selection_shape.cpp b/drape_frontend/selection_shape.cpp
index caafa84566..715cb73460 100644
--- a/drape_frontend/selection_shape.cpp
+++ b/drape_frontend/selection_shape.cpp
@@ -104,10 +104,10 @@ SelectionShape::SelectionShape(ref_ptr<dp::TextureManager> mng)
batcher.InsertTriangleList(state, make_ref(&provider), nullptr);
}
- double r = 15.0f * VisualParams::Instance().GetVisualScale();
- m_mapping.AddRangePoint(0.6, 1.3 * r);
- m_mapping.AddRangePoint(0.85, 0.8 * r);
- m_mapping.AddRangePoint(1.0, r);
+ m_radius = 15.0f * VisualParams::Instance().GetVisualScale();
+ m_mapping.AddRangePoint(0.6, 1.3 * m_radius);
+ m_mapping.AddRangePoint(0.85, 0.8 * m_radius);
+ m_mapping.AddRangePoint(1.0, m_radius);
}
void SelectionShape::Show(ESelectedObject obj, m2::PointD const & position, double positionZ, bool isAnimate)
@@ -128,6 +128,20 @@ void SelectionShape::Hide()
m_selectedObject = OBJECT_EMPTY;
}
+bool SelectionShape::IsVisible(ScreenBase const & screen, m2::PointD & pxPos) const
+{
+ m2::PointD const pt = screen.GtoP(m_position);
+ ShowHideAnimation::EState state = m_animation.GetState();
+
+ if ((state == ShowHideAnimation::STATE_VISIBLE || state == ShowHideAnimation::STATE_SHOW_DIRECTION) &&
+ !screen.IsReverseProjection3d(pt))
+ {
+ pxPos = screen.PtoP3d(pt, -m_positionZ);
+ return true;
+ }
+ return false;
+}
+
void SelectionShape::Render(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms)
{
diff --git a/drape_frontend/selection_shape.hpp b/drape_frontend/selection_shape.hpp
index 3f47a10c3a..5655033ae1 100644
--- a/drape_frontend/selection_shape.hpp
+++ b/drape_frontend/selection_shape.hpp
@@ -38,6 +38,9 @@ public:
void Render(ScreenBase const & screen, int zoomLevel, ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms);
+ bool IsVisible(ScreenBase const & screen, m2::PointD & pxPos) const;
+ double GetRadius() const { return m_radius; }
+
ESelectedObject GetSelectedObject() const;
private:
@@ -46,6 +49,7 @@ private:
private:
m2::PointD m_position;
double m_positionZ;
+ double m_radius;
ShowHideAnimation m_animation;
ESelectedObject m_selectedObject;
diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp
index 4108da46e1..0d3ed4c5b5 100644
--- a/drape_frontend/user_event_stream.cpp
+++ b/drape_frontend/user_event_stream.cpp
@@ -180,6 +180,8 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool
{
ref_ptr<ResizeEvent> resizeEvent = make_ref(e);
m_navigator.OnSize(resizeEvent->GetWidth(), resizeEvent->GetHeight());
+ if (m_visibleViewport.IsEmptyInterior())
+ m_visibleViewport = m2::RectD(0, 0, resizeEvent->GetWidth(), resizeEvent->GetHeight());
viewportChanged = true;
breakAnim = true;
TouchCancel(m_touches);
@@ -236,6 +238,21 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChanged, bool
SetAutoPerspective(perspectiveEvent->IsAutoPerspective());
}
break;
+ case UserEvent::EventType::VisibleViewport:
+ {
+ ref_ptr<SetVisibleViewportEvent> viewportEvent = make_ref(e);
+ m2::RectD prevVisibleViewport = m_visibleViewport;
+ m_visibleViewport = viewportEvent->GetRect();
+ m2::PointD gOffset;
+ if (m_listener->OnNewVisibleViewport(prevVisibleViewport, m_visibleViewport, gOffset))
+ {
+ ScreenBase screen = GetCurrentScreen();
+ screen.MoveG(gOffset);
+ SetScreen(screen, true /* isAnim */);
+ }
+ }
+ break;
+
default:
ASSERT(false, ());
break;
@@ -284,6 +301,11 @@ ScreenBase const & UserEventStream::GetCurrentScreen() const
return m_navigator.Screen();
}
+m2::RectD const & UserEventStream::GetVisibleViewport() const
+{
+ return m_visibleViewport;
+}
+
bool UserEventStream::OnSetScale(ref_ptr<ScaleEvent> scaleEvent)
{
double factor = scaleEvent->GetFactor();
@@ -359,12 +381,12 @@ bool UserEventStream::OnSetCenter(ref_ptr<SetCenterEvent> centerEvent)
if (zoom == kDoNotChangeZoom)
{
GetTargetScreen(screen);
- screen.MatchGandP3d(center, screen.PixelRectIn3d().Center());
+ screen.MatchGandP3d(center, m_visibleViewport.Center());
}
else
{
screen.SetFromParams(center, screen.GetAngle(), GetScale(zoom));
- screen.MatchGandP3d(center, screen.PixelRectIn3d().Center());
+ screen.MatchGandP3d(center, m_visibleViewport.Center());
}
ShrinkAndScaleInto(screen, df::GetWorldRect());
@@ -381,16 +403,19 @@ bool UserEventStream::SetAngle(double azimuth, TAnimationCreator const & paralle
{
ScreenBase screen;
GetTargetScreen(screen);
+ m2::PointD pt = m_visibleViewport.Center();
+ m2::PointD gPt = screen.PtoG(screen.P3dtoP(pt));
+
if (screen.isPerspective())
{
- m2::PointD pt = screen.PixelRectIn3d().Center();
- return SetFollowAndRotate(screen.PtoG(screen.P3dtoP(pt)), pt,
+ return SetFollowAndRotate(gPt, pt,
azimuth, kDoNotChangeZoom, kDoNotAutoZoom,
true /* isAnim */, false /* isAutoScale */,
parallelAnimCreator);
}
screen.SetAngle(azimuth);
+ screen.MatchGandP3d(gPt, pt);
return SetScreen(screen, true /* isAnim */, parallelAnimCreator);
}
diff --git a/drape_frontend/user_event_stream.hpp b/drape_frontend/user_event_stream.hpp
index cdf2e04382..98d2fc482c 100644
--- a/drape_frontend/user_event_stream.hpp
+++ b/drape_frontend/user_event_stream.hpp
@@ -38,7 +38,8 @@ public:
Resize,
Rotate,
FollowAndRotate,
- AutoPerspective
+ AutoPerspective,
+ VisibleViewport
};
virtual ~UserEvent() {}
@@ -306,6 +307,21 @@ private:
uint32_t m_height;
};
+class SetVisibleViewportEvent : public UserEvent
+{
+public:
+ SetVisibleViewportEvent(m2::RectD const & rect)
+ : m_rect(rect)
+ {}
+
+ EventType GetType() const override { return UserEvent::EventType::VisibleViewport; }
+
+ m2::RectD const & GetRect() const { return m_rect; }
+
+private:
+ m2::RectD m_rect;
+};
+
class UserEventStream
{
public:
@@ -331,12 +347,15 @@ public:
virtual void OnAnimatedScaleEnded() = 0;
virtual void OnTouchMapAction() = 0;
+
+ virtual bool OnNewVisibleViewport(m2::RectD const & oldViewport, m2::RectD const & newViewport, m2::PointD & gOffset) = 0;
};
UserEventStream();
void AddEvent(drape_ptr<UserEvent> && event);
ScreenBase const & ProcessEvents(bool & modelViewChanged, bool & viewportChanged);
ScreenBase const & GetCurrentScreen() const;
+ m2::RectD const & GetVisibleViewport() const;
void GetTargetScreen(ScreenBase & screen);
m2::AnyRectD GetTargetRect();
@@ -444,6 +463,8 @@ private:
TEventsList m_events;
mutable mutex m_lock;
+ m2::RectD m_visibleViewport;
+
Navigator m_navigator;
my::Timer m_touchTimer;
enum ERecognitionState
diff --git a/map/framework.cpp b/map/framework.cpp
index 665f39ac8f..e4686e70af 100644
--- a/map/framework.cpp
+++ b/map/framework.cpp
@@ -948,6 +948,11 @@ m2::PointD Framework::GetPixelCenter() const
: m_currentModelView.PixelRect().Center();
}
+m2::PointD Framework::GetVisiblePixelCenter() const
+{
+ return m_visibleViewport.Center();
+}
+
m2::PointD const & Framework::GetViewportCenter() const
{
return m_currentModelView.GetOrg();
@@ -968,6 +973,14 @@ m2::RectD Framework::GetCurrentViewport() const
return m_currentModelView.ClipRect();
}
+void Framework::SetVisibleViewport(m2::RectD const & rect)
+{
+ if (m_drapeEngine == nullptr)
+ return;
+ m_visibleViewport = rect;
+ m_drapeEngine->SetVisibleViewport(rect);
+}
+
void Framework::ShowRect(m2::RectD const & rect, int maxScale)
{
CallDrapeFunction(bind(&df::DrapeEngine::SetModelViewRect, _1, rect, true, maxScale, true));
@@ -1016,7 +1029,7 @@ void Framework::Scale(Framework::EScaleMode mode, m2::PointD const & pxPoint, bo
void Framework::Scale(double factor, bool isAnim)
{
- Scale(factor, GetPixelCenter(), isAnim);
+ Scale(factor, GetVisiblePixelCenter(), isAnim);
}
void Framework::Scale(double factor, m2::PointD const & pxPoint, bool isAnim)
diff --git a/map/framework.hpp b/map/framework.hpp
index 7d0e78fc19..7c5e46a9c6 100644
--- a/map/framework.hpp
+++ b/map/framework.hpp
@@ -134,6 +134,7 @@ protected:
search::QuerySaver m_searchQuerySaver;
ScreenBase m_currentModelView;
+ m2::RectD m_visibleViewport;
using TViewportChanged = df::DrapeEngine::TModelViewListenerFn;
TViewportChanged m_viewportChanged;
@@ -531,12 +532,14 @@ public:
void ShowAll();
m2::PointD GetPixelCenter() const;
+ m2::PointD GetVisiblePixelCenter() const;
m2::PointD const & GetViewportCenter() const;
void SetViewportCenter(m2::PointD const & pt);
void SetViewportCenter(m2::PointD const & pt, int zoomLevel);
m2::RectD GetCurrentViewport() const;
+ void SetVisibleViewport(m2::RectD const & rect);
/// - Check minimal visible scale according to downloaded countries.
void ShowRect(m2::RectD const & rect, int maxScale = -1);