From 11bf69d1b92c426b57fddcd8db1c6ccdeaa60229 Mon Sep 17 00:00:00 2001 From: ExMix Date: Thu, 18 Jun 2015 10:34:14 +0300 Subject: [PATCH] [drape] added: - double tap detection - drag threshold - warning fixes --- .../user_event_stream_tests.cpp | 3 +- drape_frontend/frontend_renderer.cpp | 9 ++- drape_frontend/frontend_renderer.hpp | 1 + drape_frontend/message_subclasses.hpp | 2 +- drape_frontend/route_shape.cpp | 4 +- drape_frontend/user_event_stream.cpp | 69 +++++++++++++++---- drape_frontend/user_event_stream.hpp | 4 ++ drape_frontend/visual_params.cpp | 5 ++ drape_frontend/visual_params.hpp | 1 + map/bookmark_manager.cpp | 1 - map/bookmark_manager.hpp | 3 - 11 files changed, 78 insertions(+), 24 deletions(-) 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 4242907fe8..c95b68efc6 100644 --- a/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp +++ b/drape_frontend/drape_frontend_tests/user_event_stream_tests.cpp @@ -22,7 +22,8 @@ public: m_stream.SetTestBridge(bind(&UserEventStreamTest::TestBridge, this, _1)); } - void OnTap(const m2::PointD & pt, bool isLong) override {} + void OnTap(m2::PointD const & pt, bool isLong) override {} + void OnDoubleTap(m2::PointD const & pt) override {} bool OnSingleTouchFiltrate(m2::PointD const & pt, df::TouchEvent::ETouchType type) override { return m_filtrate; } void OnDragStarted() override {} void OnDragEnded(m2::PointD const & /*distance*/) override {} diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 27716410b2..87ae70e092 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -41,6 +41,7 @@ const double VSyncInterval = 0.014; FrontendRenderer::FrontendRenderer(Params const & params) : BaseRenderer(ThreadsCommutator::RenderThread, params) , m_gpuProgramManager(new dp::GpuProgramManager()) + , m_routeRenderer(new RouteRenderer()) , m_overlayTree(new dp::OverlayTree()) , m_viewport(params.m_viewport) , m_userEventStream(params.m_isCountryLoadedFn) @@ -48,7 +49,6 @@ FrontendRenderer::FrontendRenderer(Params const & params) , m_tapEventInfoFn(params.m_tapEventFn) , m_userPositionChangedFn(params.m_positionChangedFn) , m_tileTree(new TileTree()) - , m_routeRenderer(new RouteRenderer()) { #ifdef DRAW_INFO m_tpf = 0,0; @@ -606,9 +606,14 @@ void FrontendRenderer::OnTap(m2::PointD const & pt, bool isLongTap) m_tapEventInfoFn(pt, isLongTap, isMyPosition, GetVisiblePOI(selectRect)); } +void FrontendRenderer::OnDoubleTap(m2::PointD const & pt) +{ + m_userEventStream.AddEvent(ScaleEvent(2.0 /*scale factor*/, pt, true /*animated*/)); +} + bool FrontendRenderer::OnSingleTouchFiltrate(m2::PointD const & pt, TouchEvent::ETouchType type) { - float const rectHalfSize = 5 * df::VisualParams::Instance().GetVisualScale(); + float const rectHalfSize = df::VisualParams::Instance().GetTouchRectRadius(); m2::RectD r(-rectHalfSize, -rectHalfSize, rectHalfSize, rectHalfSize); r.SetCenter(pt); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index f287aeb97e..72d93dfa5f 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -140,6 +140,7 @@ private: void ResolveZoomLevel(ScreenBase const & screen); void OnTap(m2::PointD const & pt, bool isLong) override; + void OnDoubleTap(m2::PointD const & pt) override; bool OnSingleTouchFiltrate(m2::PointD const & pt, TouchEvent::ETouchType type) override; void OnDragStarted() override; void OnDragEnded(m2::PointD const & distance) override; diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index a4a1fc3079..946bfc8bac 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -499,8 +499,8 @@ class AddRouteMessage : public Message public: AddRouteMessage(m2::PolylineD const & routePolyline, vector const & turns, dp::Color const & color) : m_routePolyline(routePolyline) - , m_turns(turns) , m_color(color) + , m_turns(turns) {} Type GetType() const override { return Message::AddRoute; } diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index ca9d865833..65217a8d3c 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -27,9 +27,9 @@ namespace } RouteShape::RouteShape(m2::PolylineD const & polyline, CommonViewParams const & params) - : m_params(params) + : m_length(0) + , m_params(params) , m_polyline(polyline) - , m_length(0) , m_endOfRouteState(0, dp::GLState::OverlayLayer) {} diff --git a/drape_frontend/user_event_stream.cpp b/drape_frontend/user_event_stream.cpp index 875cb1b098..17823d0a0f 100644 --- a/drape_frontend/user_event_stream.cpp +++ b/drape_frontend/user_event_stream.cpp @@ -16,6 +16,7 @@ namespace df namespace { +uint64_t const DOUBLE_TAP_PAUSE = 250; uint64_t const LONG_TOUCH_MS = 1000; } // namespace @@ -120,8 +121,13 @@ ScreenBase const & UserEventStream::ProcessEvents(bool & modelViewChange, bool & m_animation.reset(); } - if (m_state == STATE_TAP_DETECTION && m_validTouchesCount == 1) - DetectLongTap(m_touches[0]); + if (m_validTouchesCount == 1) + { + if (m_state == STATE_WAIT_DOUBLE_TAP) + DetectShortTap(m_touches[0]); + else if (m_state == STATE_TAP_DETECTION) + DetectLongTap(m_touches[0]); + } return m_navigator.Screen(); } @@ -237,11 +243,19 @@ bool UserEventStream::TouchDown(array const & touches) if (touchCount == 1) { - ASSERT(m_state == STATE_EMPTY, ()); - if (!TryBeginFilter(touches[0])) - BeginTapDetector(); - else - isMapTouch = false; + if (!DetectDoubleTap(touches[0])) + { + if (m_state == STATE_EMPTY) + { + if (!TryBeginFilter(touches[0])) + { + BeginTapDetector(); + m_startDragOrg = touches[0].m_location; + } + else + isMapTouch = false; + } + } } else if (touchCount == 2) { @@ -253,13 +267,13 @@ bool UserEventStream::TouchDown(array const & touches) CancelFilter(touches[0]); break; case STATE_TAP_DETECTION: + case STATE_WAIT_DOUBLE_TAP: CancelTapDetector(); break; case STATE_DRAG: EndDrag(touches[0]); break; default: - ASSERT(false, ()); break; } @@ -289,7 +303,8 @@ bool UserEventStream::TouchMove(array const & touches) break; case STATE_TAP_DETECTION: ASSERT(touchCount == 1, ()); - CancelTapDetector(); + if (m_startDragOrg.SquareLength(touches[0].m_location) > VisualParams::Instance().GetDragThreshold()) + CancelTapDetector(); break; case STATE_DRAG: ASSERT(touchCount == 1, ()); @@ -300,6 +315,7 @@ bool UserEventStream::TouchMove(array const & touches) Scale(touches[0], touches[1]); break; default: + ASSERT(false, ()); break; } @@ -314,6 +330,8 @@ bool UserEventStream::TouchCancel(array const & touches) switch (m_state) { case STATE_EMPTY: + case STATE_WAIT_DOUBLE_TAP: + isMapTouch = false; break; case STATE_FILTER: ASSERT(touchCount == 1, ()); @@ -333,6 +351,7 @@ bool UserEventStream::TouchCancel(array const & touches) EndScale(touches[0], touches[1]); break; default: + ASSERT(false, ()); break; } UpdateTouches(touches, touchCount); @@ -346,7 +365,8 @@ bool UserEventStream::TouchUp(array const & touches) switch (m_state) { case STATE_EMPTY: - // Can be if long tap detected + isMapTouch = false; + // Can be if long tap or double tap detected break; case STATE_FILTER: ASSERT(touchCount == 1, ()); @@ -366,6 +386,7 @@ bool UserEventStream::TouchUp(array const & touches) EndScale(touches[0], touches[1]); break; default: + ASSERT(false, ()); break; } @@ -488,6 +509,16 @@ void UserEventStream::BeginTapDetector() m_touchTimer.Reset(); } +void UserEventStream::DetectShortTap(Touch const & touch) +{ + if (m_touchTimer.ElapsedMillis() > DOUBLE_TAP_PAUSE) + { + m_state = STATE_EMPTY; + if (m_listener) + m_listener->OnTap(touch.m_location, false); + } +} + void UserEventStream::DetectLongTap(Touch const & touch) { ASSERT(m_state == STATE_TAP_DETECTION, ()); @@ -500,19 +531,29 @@ void UserEventStream::DetectLongTap(Touch const & touch) } } +bool UserEventStream::DetectDoubleTap(Touch const & touch) +{ + if (m_state != STATE_WAIT_DOUBLE_TAP || m_touchTimer.ElapsedMillis() > DOUBLE_TAP_PAUSE) + return false; + + m_state = STATE_EMPTY; + if (m_listener) + m_listener->OnDoubleTap(touch.m_location); + + return true; +} + void UserEventStream::EndTapDetector(Touch const & touch) { TEST_CALL(SHORT_TAP_DETECTED); ASSERT(m_state == STATE_TAP_DETECTION, ()); - m_state = STATE_EMPTY; - if (m_listener) - m_listener->OnTap(touch.m_location, false); + m_state = STATE_WAIT_DOUBLE_TAP; } void UserEventStream::CancelTapDetector() { TEST_CALL(CANCEL_TAP_DETECTOR); - ASSERT(m_state == STATE_TAP_DETECTION, ()); + ASSERT(m_state == STATE_TAP_DETECTION || m_state == STATE_WAIT_DOUBLE_TAP, ()); m_state = STATE_EMPTY; } diff --git a/drape_frontend/user_event_stream.hpp b/drape_frontend/user_event_stream.hpp index c0aacfa282..1d4cac9dc7 100644 --- a/drape_frontend/user_event_stream.hpp +++ b/drape_frontend/user_event_stream.hpp @@ -158,6 +158,7 @@ public: virtual ~Listener() {} virtual void OnTap(m2::PointD const & pt, bool isLong) = 0; + virtual void OnDoubleTap(m2::PointD const & pt) = 0; virtual bool OnSingleTouchFiltrate(m2::PointD const & pt, TouchEvent::ETouchType type) = 0; virtual void OnDragStarted() = 0; virtual void OnDragEnded(m2::PointD const & distance) = 0; @@ -224,7 +225,9 @@ private: void EndScale(Touch const & t1, Touch const & t2); void BeginTapDetector(); + void DetectShortTap(Touch const & touch); void DetectLongTap(Touch const & touch); + bool DetectDoubleTap(Touch const & touch); void EndTapDetector(Touch const & touch); void CancelTapDetector(); @@ -245,6 +248,7 @@ private: STATE_EMPTY, STATE_FILTER, STATE_TAP_DETECTION, + STATE_WAIT_DOUBLE_TAP, STATE_DRAG, STATE_SCALE } m_state; diff --git a/drape_frontend/visual_params.cpp b/drape_frontend/visual_params.cpp index 5ca17a4c57..6954baf183 100644 --- a/drape_frontend/visual_params.cpp +++ b/drape_frontend/visual_params.cpp @@ -103,6 +103,11 @@ uint32_t VisualParams::GetTouchRectRadius() const return 20 * GetVisualScale(); } +double VisualParams::GetDragThreshold() const +{ + return 10.0 * GetVisualScale(); +} + VisualParams::VisualParams() : m_tileSize(0) , m_visualScale(0.0) diff --git a/drape_frontend/visual_params.hpp b/drape_frontend/visual_params.hpp index 5cb38bf5ae..a987acc45d 100644 --- a/drape_frontend/visual_params.hpp +++ b/drape_frontend/visual_params.hpp @@ -26,6 +26,7 @@ public: /// How many pixels around touch point are used to get bookmark or POI in consideration of visual scale uint32_t GetTouchRectRadius() const; + double GetDragThreshold() const; private: int m_tileSize; diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index b2b9afc0d6..c66bf0358d 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -17,7 +17,6 @@ BookmarkManager::BookmarkManager(Framework & f) : m_framework(f) - , m_lastScale(1.0) { m_userMarkLayers.reserve(3); ///@TODO UVR diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index ef297bdad8..b4f83890ee 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -20,9 +20,6 @@ class BookmarkManager : private noncopyable Framework & m_framework; vector m_userMarkLayers; - - mutable double m_lastScale; - typedef vector::iterator CategoryIter; void SaveState() const;