summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp')
-rw-r--r--Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp119
1 files changed, 67 insertions, 52 deletions
diff --git a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp
index 007659b2f..eea6385bb 100644
--- a/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtTapGestureRecognizer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011, 2012 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,73 +27,92 @@
#include "QtWebPageEventHandler.h"
#include <QLineF>
-#include <QTouchEvent>
namespace WebKit {
+// FIXME: These constants should possibly depend on DPI.
+static const int panDistanceThreshold = 10;
+static const int maxDoubleTapDistance = 120;
+
+// FIXME: These constants should possibly be consistent across the platform.
+static const int tapAndHoldTime = 1000;
+static const int maxDoubleTapInterval = 500;
+static const int highlightDelay = 100;
+
+
QtTapGestureRecognizer::QtTapGestureRecognizer(QtWebPageEventHandler* eventHandler)
: QtGestureRecognizer(eventHandler)
- , m_candidate(Invalid)
+ , m_candidate(SingleTapCandidate)
{
}
bool QtTapGestureRecognizer::withinDistance(const QTouchEvent::TouchPoint& touchPoint, int distance)
{
+ ASSERT(m_lastTouchPoint.id() != -1);
return QLineF(touchPoint.screenPos(), m_lastTouchPoint.screenPos()).length() < distance;
}
-bool QtTapGestureRecognizer::update(QEvent::Type eventType, const QTouchEvent::TouchPoint& touchPoint)
+void QtTapGestureRecognizer::update(const QTouchEvent::TouchPoint& touchPoint)
{
- ASSERT(m_eventHandler);
-
- switch (eventType) {
- case QEvent::TouchBegin:
+ switch (m_state) {
+ case NoGesture:
m_doubleTapTimer.stop(); // Cancel other pending single tap event.
+ m_state = GestureRecognitionStarted;
ASSERT(!m_tapAndHoldTimer.isActive());
m_tapAndHoldTimer.start(tapAndHoldTime, this);
- if (m_lastTouchPoint.id() != -1 && withinDistance(touchPoint, maxDoubleTapDistance))
- m_candidate = DoubleTapCandidate;
- else {
- m_candidate = SingleTapCandidate;
- // The below in facts resets any previous single tap event.
- m_highlightTimer.start(highlightDelay, this);
- m_lastTouchPoint = touchPoint;
- m_doubleTapTimer.start(maxDoubleTapInterval, this);
- }
- break;
+ // Early return if this is the second touch point of a potential double tap gesture.
+ if (m_candidate == DoubleTapCandidate && withinDistance(touchPoint, maxDoubleTapDistance))
+ return;
- case QEvent::TouchUpdate:
+ // The below in fact resets any previous single tap event.
+ m_candidate = SingleTapCandidate;
+ m_lastTouchPoint = touchPoint;
+ m_highlightTimer.start(highlightDelay, this);
+ m_doubleTapTimer.start(maxDoubleTapInterval, this);
+ break;
+ case GestureRecognitionStarted:
// If the touch point moves further than the threshold, we cancel the tap gesture.
- if (m_candidate != Invalid && !withinDistance(touchPoint, maxPanDistance))
+ if (!withinDistance(touchPoint, panDistanceThreshold))
reset();
break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
- case QEvent::TouchEnd:
- m_tapAndHoldTimer.stop();
-
- if (m_candidate == Invalid)
- break;
+void QtTapGestureRecognizer::finish(const QTouchEvent::TouchPoint& touchPoint)
+{
+ ASSERT(m_eventHandler);
+ m_tapAndHoldTimer.stop();
- if (m_candidate == DoubleTapCandidate) {
- m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint());
- m_eventHandler->handleDoubleTapEvent(touchPoint);
- reset();
- }
+ // Gesture has been cancelled, ignore.
+ if (m_state == NoGesture)
+ return;
- break;
+ m_state = NoGesture;
- default:
- break;
- }
+ if (m_candidate == SingleTapCandidate) {
+ if (m_doubleTapTimer.isActive()) {
+ m_candidate = DoubleTapCandidate;
+ m_lastTouchPoint = touchPoint;
+ // Early return since this is a potential double tap gesture.
+ return;
+ }
+ // This happens when the finger is released (gesture finished) after the single
+ // tap timeout elapsed (500ms) but before the tap-and-hold timeout (1000ms) fired.
+ m_eventHandler->handleSingleTapEvent(touchPoint);
+ } else // DoubleTapCandidate
+ m_eventHandler->handleDoubleTapEvent(touchPoint);
- return false;
+ reset();
}
void QtTapGestureRecognizer::cancel()
{
- if (m_candidate == Invalid)
+ if (m_lastTouchPoint.id() == -1)
return;
reset();
@@ -103,27 +122,22 @@ void QtTapGestureRecognizer::highlightTimeout()
{
m_highlightTimer.stop();
- if (m_candidate != SingleTapCandidate)
+ // Gesture has been cancelled, ignore.
+ if (m_lastTouchPoint.id() == -1)
return;
- ASSERT(m_lastTouchPoint.id() != -1);
- m_eventHandler->handlePotentialSingleTapEvent(m_lastTouchPoint);
+ m_eventHandler->activateTapHighlight(m_lastTouchPoint);
}
void QtTapGestureRecognizer::singleTapTimeout()
{
m_doubleTapTimer.stop();
- // Finger is still pressed, ignore.
- if (m_tapAndHoldTimer.isActive())
+ // Finger is still pressed or gesture has been cancelled, ignore.
+ if (m_tapAndHoldTimer.isActive() || m_lastTouchPoint.id() == -1)
return;
- ASSERT(m_lastTouchPoint.id() != -1);
-
- if (m_candidate == SingleTapCandidate) {
- m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint());
- m_eventHandler->handleSingleTapEvent(m_lastTouchPoint);
- }
+ m_eventHandler->handleSingleTapEvent(m_lastTouchPoint);
reset();
}
@@ -131,9 +145,11 @@ void QtTapGestureRecognizer::tapAndHoldTimeout()
{
m_tapAndHoldTimer.stop();
- ASSERT(m_lastTouchPoint.id() != -1);
+ // Gesture has been cancelled, ignore.
+ if (m_lastTouchPoint.id() == -1)
+ return;
+
#if 0 // No support for synthetic context menus in WK2 yet.
- m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint());
m_eventHandler->handleTapAndHoldEvent(m_lastTouchPoint);
#endif
reset();
@@ -141,10 +157,9 @@ void QtTapGestureRecognizer::tapAndHoldTimeout()
void QtTapGestureRecognizer::reset()
{
- if (m_candidate != Invalid)
- m_eventHandler->handlePotentialSingleTapEvent(QTouchEvent::TouchPoint());
+ m_eventHandler->deactivateTapHighlight();
- m_candidate = Invalid;
+ m_candidate = SingleTapCandidate;
m_lastTouchPoint.setId(-1);
m_highlightTimer.stop();
m_doubleTapTimer.stop();