summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2014-09-29 16:34:05 +0200
committerFriedemann Kleint <Friedemann.Kleint@digia.com>2014-10-23 21:11:28 +0200
commit68d83e82f80ba3af439f1eed74b2b4a0cefc4f2a (patch)
tree0ae755d171ea4da1432b49d01727a01d7d570e4c
parentab79e832e602b6366340151720b8c7c7b7ddb1a3 (diff)
Add autotest for QGestureRecognizer.
Task-number: QTBUG-12736 Task-number: QTBUG-15768 Task-number: QTBUG-40461 Change-Id: Ib6dfaa9336f615e17d41444f7aa686cb93d04fca Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com> Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
-rw-r--r--tests/auto/widgets/gestures/gestures.pro6
-rw-r--r--tests/auto/widgets/gestures/qgesturerecognizer/qgesturerecognizer.pro4
-rw-r--r--tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp330
-rw-r--r--tests/auto/widgets/widgets.pro1
4 files changed, 341 insertions, 0 deletions
diff --git a/tests/auto/widgets/gestures/gestures.pro b/tests/auto/widgets/gestures/gestures.pro
new file mode 100644
index 0000000000..5a87a01ee2
--- /dev/null
+++ b/tests/auto/widgets/gestures/gestures.pro
@@ -0,0 +1,6 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qgesturerecognizer \
+
+mac: SUBDIRS -= \ # Uses native recognizers
+ qgesturerecognizer \
diff --git a/tests/auto/widgets/gestures/qgesturerecognizer/qgesturerecognizer.pro b/tests/auto/widgets/gestures/qgesturerecognizer/qgesturerecognizer.pro
new file mode 100644
index 0000000000..7c9ddcfb03
--- /dev/null
+++ b/tests/auto/widgets/gestures/qgesturerecognizer/qgesturerecognizer.pro
@@ -0,0 +1,4 @@
+CONFIG += testcase
+TARGET = tst_qgesturerecognizer
+QT += widgets testlib gui-private core-private
+SOURCES += tst_qgesturerecognizer.cpp
diff --git a/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp b/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp
new file mode 100644
index 0000000000..867c6eb629
--- /dev/null
+++ b/tests/auto/widgets/gestures/qgesturerecognizer/tst_qgesturerecognizer.cpp
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QTest>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QGestureEvent>
+#include <QtGui/QScreen>
+#include <QtGui/QTouchDevice>
+#include <QtCore/QVector>
+#include <QtCore/QString>
+#include <QtCore/QHash>
+#include <QtCore/QDebug>
+
+#include <qpa/qwindowsysteminterface.h>
+
+class tst_QGestureRecognizer : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QGestureRecognizer();
+
+private Q_SLOTS:
+ void initTestCase();
+#ifndef QT_NO_GESTURES
+ void panGesture_data();
+ void panGesture();
+ void pinchGesture_data();
+ void pinchGesture();
+ void swipeGesture_data();
+ void swipeGesture();
+#endif // !QT_NO_GESTURES
+
+private:
+ const int m_fingerDistance;
+ QTouchDevice *m_touchDevice;
+};
+
+tst_QGestureRecognizer::tst_QGestureRecognizer()
+ : m_fingerDistance(qRound(QGuiApplication::primaryScreen()->physicalDotsPerInch() / 2.0))
+ , m_touchDevice(new QTouchDevice)
+{
+}
+
+void tst_QGestureRecognizer::initTestCase()
+{
+ m_touchDevice->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(m_touchDevice);
+}
+
+#ifndef QT_NO_GESTURES
+
+typedef QVector<Qt::GestureType> GestureTypeVector;
+
+class TestWidget : public QWidget
+{
+public:
+ explicit TestWidget(const GestureTypeVector &gestureTypes);
+
+ bool gestureReceived(Qt::GestureType gestureType) const
+ { return m_receivedGestures.value(gestureType); }
+
+protected:
+ bool event(QEvent * event) Q_DECL_OVERRIDE;
+
+private:
+ typedef QHash<Qt::GestureType, bool> GestureTypeHash;
+ GestureTypeHash m_receivedGestures;
+};
+
+TestWidget::TestWidget(const GestureTypeVector &gestureTypes)
+{
+ setAttribute(Qt::WA_AcceptTouchEvents);
+
+ foreach (Qt::GestureType gestureType, gestureTypes) {
+ grabGesture(gestureType);
+ m_receivedGestures.insert(gestureType, false);
+ }
+
+ const QRect geometry = QGuiApplication::primaryScreen()->availableGeometry();
+ const QSize size = geometry.size() / 2;
+ resize(size);
+ move(geometry.center() - QPoint(size.width() / 2, size.height() / 2));
+}
+
+bool TestWidget::event(QEvent * event)
+{
+ switch (event->type()) {
+ case QEvent::Gesture: {
+ const QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(event);
+ const GestureTypeHash::iterator hend = m_receivedGestures.end();
+ for (GestureTypeHash::iterator it = m_receivedGestures.begin(); it != hend; ++it) {
+ if (const QGesture *gesture = gestureEvent->gesture(it.key())) {
+ if (gesture->state() == Qt::GestureFinished)
+ it.value() = true;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return QWidget::event(event);
+}
+
+static void pressSequence(QTest::QTouchEventSequence &sequence,
+ QVector<QPoint> &points,
+ QWidget *widget)
+{
+ const int pointCount = points.size();
+ for (int p = 0; p < pointCount; ++p)
+ sequence.press(p, points.at(p), widget);
+ sequence.commit();
+}
+
+static void linearSequence(int n, const QPoint &delta,
+ QTest::QTouchEventSequence &sequence,
+ QVector<QPoint> &points,
+ QWidget *widget)
+{
+ const int pointCount = points.size();
+ for (int s = 0; s < n; ++s) {
+ for (int p = 0; p < pointCount; ++p) {
+ points[p] += delta;
+ sequence.move(p, points[p], widget);
+ }
+ sequence.commit();
+ }
+}
+
+static void releaseSequence(QTest::QTouchEventSequence &sequence,
+ QVector<QPoint> &points,
+ QWidget *widget)
+{
+ const int pointCount = points.size();
+ for (int p = 0; p < pointCount; ++p)
+ sequence.release(p, points[p], widget);
+ sequence.commit();
+}
+
+// --- Pan
+
+enum PanSubTest {
+ TwoFingerPanSubTest
+};
+
+void tst_QGestureRecognizer::panGesture_data()
+{
+ QTest::addColumn<int>("panSubTest");
+ QTest::addColumn<bool>("gestureExpected");
+ QTest::newRow("Two finger") << int(TwoFingerPanSubTest) << true;
+}
+
+void tst_QGestureRecognizer::panGesture()
+{
+ QFETCH(int, panSubTest);
+ QFETCH(bool, gestureExpected);
+
+ Q_UNUSED(panSubTest) // Single finger pan will be added later.
+
+ const int panPoints = 2;
+ const Qt::GestureType gestureType = Qt::PanGesture;
+ TestWidget widget(GestureTypeVector(1, gestureType));
+ widget.setWindowTitle(QTest::currentTestFunction());
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ QVector<QPoint> points;
+ for (int i = 0; i < panPoints; ++i)
+ points.append(QPoint(10 + i *20, 10 + i *20));
+
+ QTest::QTouchEventSequence panSequence = QTest::touchEvent(&widget, m_touchDevice);
+ pressSequence(panSequence, points, &widget);
+ linearSequence(5, QPoint(20, 20), panSequence, points, &widget);
+ releaseSequence(panSequence, points, &widget);
+
+ if (gestureExpected) {
+ QTRY_VERIFY(widget.gestureReceived(gestureType));
+ } else {
+ QCoreApplication::processEvents();
+ QVERIFY(!widget.gestureReceived(gestureType));
+ }
+}
+
+// --- Pinch
+
+enum PinchSubTest {
+ StandardPinchSubTest
+};
+
+void tst_QGestureRecognizer::pinchGesture_data()
+{
+ QTest::addColumn<int>("pinchSubTest");
+ QTest::addColumn<bool>("gestureExpected");
+ QTest::newRow("Standard") << int(StandardPinchSubTest) << true;
+}
+
+void tst_QGestureRecognizer::pinchGesture()
+{
+ QFETCH(int, pinchSubTest);
+ QFETCH(bool, gestureExpected);
+
+ Q_UNUSED(pinchSubTest)
+
+ const Qt::GestureType gestureType = Qt::PinchGesture;
+ TestWidget widget(GestureTypeVector(1, gestureType));
+ widget.setWindowTitle(QTest::currentTestFunction());
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ QVector<QPoint> points;
+ points.append(widget.rect().center());
+ points.append(points.front() + QPoint(0, 20));
+
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(&widget, m_touchDevice);
+ pressSequence(pinchSequence, points, &widget);
+
+ for (int s = 0; s < 5; ++s) {
+ points[0] += QPoint(5, 30);
+ pinchSequence.move(0, points[0], &widget);
+ points[1] += QPoint(5, -30);
+ pinchSequence.move(1, points[1], &widget);
+ pinchSequence.commit();
+ }
+
+ releaseSequence(pinchSequence, points, &widget);
+
+ if (gestureExpected) {
+ QTRY_VERIFY(widget.gestureReceived(gestureType));
+ } else {
+ QCoreApplication::processEvents();
+ QVERIFY(!widget.gestureReceived(gestureType));
+ }
+}
+
+// --- Swipe
+
+enum SwipeSubTest {
+ SwipeLineSubTest,
+};
+
+void tst_QGestureRecognizer::swipeGesture_data()
+{
+ QTest::addColumn<int>("swipeSubTest");
+ QTest::addColumn<bool>("gestureExpected");
+ QTest::newRow("Line") << int(SwipeLineSubTest) << true;
+}
+
+void tst_QGestureRecognizer::swipeGesture()
+{
+ enum { swipePoints = 3 };
+
+ QFETCH(int, swipeSubTest);
+ QFETCH(bool, gestureExpected);
+
+ const Qt::GestureType gestureType = Qt::SwipeGesture;
+ TestWidget widget(GestureTypeVector(1, gestureType));
+ widget.setWindowTitle(QTest::currentTestFunction());
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+
+ // Start a swipe sequence with 2 points (QTBUG-15768)
+ const QPoint fingerDistance(m_fingerDistance, m_fingerDistance);
+ QVector<QPoint> points;
+ for (int i = 0; i < swipePoints - 1; ++i)
+ points.append(fingerDistance + i * fingerDistance);
+
+ QTest::QTouchEventSequence swipeSequence = QTest::touchEvent(&widget, m_touchDevice);
+ pressSequence(swipeSequence, points, &widget);
+
+ // Press point #3
+ points.append(points.last() + fingerDistance);
+ swipeSequence.press(points.size() - 1, points.last(), &widget);
+ swipeSequence.commit();
+ Q_ASSERT(points.size() == swipePoints);
+
+ // Move.
+ const QPoint moveDelta(60, 20);
+ switch (swipeSubTest) {
+ case SwipeLineSubTest:
+ linearSequence(5, moveDelta, swipeSequence, points, &widget);
+ break;
+ }
+
+ releaseSequence(swipeSequence, points, &widget);
+
+ if (gestureExpected) {
+ QTRY_VERIFY(widget.gestureReceived(gestureType));
+ } else {
+ QCoreApplication::processEvents();
+ QVERIFY(!widget.gestureReceived(gestureType));
+ }
+}
+
+#endif // !QT_NO_GESTURES
+
+QTEST_MAIN(tst_QGestureRecognizer)
+
+#include "tst_qgesturerecognizer.moc"
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index 8b6c4722be..efcc47171d 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -8,3 +8,4 @@ SUBDIRS=\
styles \
util \
widgets \
+ gestures \