Merge pull request #811 from rokuz/fixed-force-touch

Fixed force touch
This commit is contained in:
igrechuhin 2015-12-02 14:22:19 +03:00
commit 23631132c7
6 changed files with 39 additions and 2 deletions

View file

@ -24,6 +24,7 @@ public:
}
void OnTap(m2::PointD const & pt, bool isLong) override {}
void OnForceTap(m2::PointD const & pt) override {}
void OnDoubleTap(m2::PointD const & pt) override {}
void OnTwoFingersTap() override {}
bool OnSingleTouchFiltrate(m2::PointD const & pt, df::TouchEvent::ETouchType type) override { return m_filtrate; }

View file

@ -757,6 +757,12 @@ void FrontendRenderer::OnTap(m2::PointD const & pt, bool isLongTap)
m_tapEventInfoFn(pt, isLongTap, isMyPosition, GetVisiblePOI(selectRect));
}
void FrontendRenderer::OnForceTap(m2::PointD const & pt)
{
// Emulate long tap on force tap.
OnTap(pt, true /* isLongTap */);
}
void FrontendRenderer::OnDoubleTap(m2::PointD const & pt)
{
m_userEventStream.AddEvent(ScaleEvent(2.0 /* scale factor */, pt, true /* animated */));

View file

@ -150,6 +150,7 @@ private:
void ResolveZoomLevel(ScreenBase const & screen);
void OnTap(m2::PointD const & pt, bool isLong) override;
void OnForceTap(m2::PointD const & pt) override;
void OnDoubleTap(m2::PointD const & pt) override;
void OnTwoFingersTap() override;
bool OnSingleTouchFiltrate(m2::PointD const & pt, TouchEvent::ETouchType type) override;

View file

@ -22,6 +22,8 @@ uint64_t const kKineticDelayMs = 500;
double const kMaxAnimationTimeSec = 1.5; // in seconds
float const kForceTapThreshold = 0.75;
size_t GetValidTouchesCount(array<Touch, 2> const & touches)
{
size_t result = 0;
@ -742,25 +744,32 @@ void UserEventStream::BeginTapDetector()
void UserEventStream::DetectShortTap(Touch const & touch)
{
if (DetectForceTap(touch))
return;
uint64_t const ms = m_touchTimer.TimeElapsedAs<milliseconds>().count();
if (ms > kDoubleTapPauseMs)
{
m_state = STATE_EMPTY;
if (m_listener)
m_listener->OnTap(touch.m_location, false);
m_listener->OnTap(touch.m_location, false /* isLongTap */);
}
}
void UserEventStream::DetectLongTap(Touch const & touch)
{
ASSERT_EQUAL(m_state, STATE_TAP_DETECTION, ());
if (DetectForceTap(touch))
return;
uint64_t const ms = m_touchTimer.TimeElapsedAs<milliseconds>().count();
if (ms > kLongTouchMs)
{
TEST_CALL(LONG_TAP_DETECTED);
m_state = STATE_EMPTY;
if (m_listener)
m_listener->OnTap(touch.m_location, true);
m_listener->OnTap(touch.m_location, true /* isLongTap */);
}
}
@ -777,6 +786,19 @@ bool UserEventStream::DetectDoubleTap(Touch const & touch)
return true;
}
bool UserEventStream::DetectForceTap(Touch const & touch)
{
if (touch.m_force >= kForceTapThreshold)
{
m_state = STATE_EMPTY;
if (m_listener)
m_listener->OnForceTap(touch.m_location);
return true;
}
return false;
}
void UserEventStream::EndTapDetector(Touch const & touch)
{
TEST_CALL(SHORT_TAP_DETECTED);

View file

@ -25,6 +25,7 @@ struct Touch
{
m2::PointF m_location = m2::PointF::Zero();
int64_t m_id = -1; // if id == -1 then touch is invalid
float m_force = 0.0; // relative force of touch [0.0 - 1.0]
};
struct TouchEvent
@ -204,6 +205,7 @@ public:
virtual ~Listener() {}
virtual void OnTap(m2::PointD const & pt, bool isLong) = 0;
virtual void OnForceTap(m2::PointD const & pt) = 0;
virtual void OnDoubleTap(m2::PointD const & pt) = 0;
virtual void OnTwoFingersTap() = 0;
virtual bool OnSingleTouchFiltrate(m2::PointD const & pt, TouchEvent::ETouchType type) = 0;
@ -283,6 +285,7 @@ private:
void DetectShortTap(Touch const & touch);
void DetectLongTap(Touch const & touch);
bool DetectDoubleTap(Touch const & touch);
bool DetectForceTap(Touch const & touch);
void EndTapDetector(Touch const & touch);
void CancelTapDetector();

View file

@ -270,12 +270,16 @@ typedef NS_ENUM(NSUInteger, UserTouchesAction)
e.m_type = type;
e.m_touches[0].m_id = reinterpret_cast<int64_t>(touch);
e.m_touches[0].m_location = m2::PointD(pt.x * scaleFactor, pt.y * scaleFactor);
if ([self hasForceTouch])
e.m_touches[0].m_force = touch.force / touch.maximumPossibleForce;
if (allTouches.count > 1)
{
UITouch * touch = [allTouches objectAtIndex:1];
CGPoint const pt = [touch locationInView:v];
e.m_touches[1].m_id = reinterpret_cast<int64_t>(touch);
e.m_touches[1].m_location = m2::PointD(pt.x * scaleFactor, pt.y * scaleFactor);
if ([self hasForceTouch])
e.m_touches[1].m_force = touch.force / touch.maximumPossibleForce;
}
NSArray * toggledTouches = [touches allObjects];