summaryrefslogtreecommitdiffstats
path: root/tests/auto/gestures/tst_gestures.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/gestures/tst_gestures.cpp')
-rw-r--r--tests/auto/gestures/tst_gestures.cpp487
1 files changed, 487 insertions, 0 deletions
diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp
new file mode 100644
index 0000000..eb692e9
--- /dev/null
+++ b/tests/auto/gestures/tst_gestures.cpp
@@ -0,0 +1,487 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <qapplication.h>
+#include <qlayout.h>
+
+#include <QtTest/QtTest>
+
+#include "customgesturerecognizer.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+// color generator for syntax highlighting from QQ-26 by Helder Correia
+QVector<QColor> highlight(const QColor &bg, const
+ QColor &fg, int noColors)
+{
+ QVector<QColor> colors;
+ const int HUE_BASE = (bg.hue() == -1) ? 90 : bg.hue();
+ int h, s, v;
+ for (int i = 0; i < noColors; i++) {
+ h = int(HUE_BASE + (360.0 / noColors * i)) % 360;
+ s = 240;
+ v = int(qMax(bg.value(), fg.value()) * 0.85);
+
+ const int M = 35;
+ if ((h < bg.hue() + M && h > bg.hue() - M)
+ || (h < fg.hue() + M && h > fg.hue() - M))
+ {
+ h = ((bg.hue() + fg.hue()) / (i+1)) % 360;
+ s = ((bg.saturation() + fg.saturation() + 2*i)
+ / 2) % 256;
+ v = ((bg.value() + fg.value() + 2*i) / 2)
+ % 256;
+ }
+ colors.append(QColor::fromHsv(h, s, v));
+ }
+ return colors;
+}
+
+
+// a hack to mark an event as spontaneous.
+class QETWidget
+{
+public:
+ static void setSpont(QEvent *event, bool spont) { event->spont = spont; }
+};
+
+class GestureWidget : public QWidget
+{
+ Q_OBJECT
+ static QVector<QColor> colors;
+ static int numberOfWidgets;
+
+public:
+ enum Type { DoNotGrabGestures, GrabAllGestures, GrabSingleshot, GrabPinch, GrabSecondFinger };
+
+ static const int LeftMargin = 10;
+ static const int TopMargin = 20;
+
+ GestureWidget(Type type = GrabAllGestures)
+ {
+ if (colors.isEmpty()) {
+ colors = highlight(palette().color(QPalette::Window), palette().color(QPalette::Text), 5);
+ }
+ QPalette p = palette();
+ p.setColor(QPalette::Window, colors[numberOfWidgets % colors.size()]);
+ setPalette(p);
+ setAutoFillBackground(true);
+ ++numberOfWidgets;
+
+ QVBoxLayout *l = new QVBoxLayout(this);
+ l->setSpacing(0);
+ l->setContentsMargins(LeftMargin, TopMargin, LeftMargin, TopMargin);
+
+ singleshotGestureId = -1;
+ pinchGestureId = -1;
+ secondFingerGestureId = -1;
+ if (type == GrabAllGestures || type == GrabSingleshot) {
+ singleshotGestureId = grabGesture(SingleshotGestureRecognizer::Name);
+ }
+ if (type == GrabAllGestures || type == GrabPinch) {
+ pinchGestureId = grabGesture(PinchGestureRecognizer::Name);
+ }
+ if (type == GrabAllGestures || type == GrabSecondFinger) {
+ secondFingerGestureId = grabGesture(SecondFingerGestureRecognizer::Name);
+ }
+
+ reset();
+ }
+ ~GestureWidget()
+ {
+ --numberOfWidgets;
+ ungrabGestures();
+ }
+
+ void grabSingleshotGesture()
+ {
+ singleshotGestureId = grabGesture(SingleshotGestureRecognizer::Name);
+ }
+ void grabPinchGesture()
+ {
+ pinchGestureId = grabGesture(PinchGestureRecognizer::Name);
+ }
+ void grabSecondFingerGesture()
+ {
+ secondFingerGestureId = grabGesture(SecondFingerGestureRecognizer::Name);
+ }
+ void ungrabGestures()
+ {
+ releaseGesture(singleshotGestureId);
+ singleshotGestureId = -1;
+ releaseGesture(pinchGestureId);
+ pinchGestureId = -1;
+ releaseGesture(secondFingerGestureId);
+ secondFingerGestureId = -1;
+ }
+
+ int singleshotGestureId;
+ int pinchGestureId;
+ int secondFingerGestureId;
+
+ bool shouldAcceptSingleshotGesture;
+ bool shouldAcceptPinchGesture;
+ bool shouldAcceptSecondFingerGesture;
+
+ int seenGestureEvent;
+ struct LastGestureEvent
+ {
+ struct SingleshotGesture
+ {
+ bool delivered;
+ QPoint offset;
+ } singleshot;
+ struct PinchGesture
+ {
+ bool delivered;
+ TouchPoint startPoints[2];
+ TouchPoint lastPoints[2];
+ TouchPoint points[2];
+ QPoint offset;
+ } pinch;
+ struct SecondFingerGesture
+ {
+ bool delivered;
+ TouchPoint startPoint;
+ TouchPoint lastPoint;
+ TouchPoint point;
+ QPoint offset;
+ } secondfinger;
+ QSet<QString> cancelled;
+ } last;
+ void reset()
+ {
+ seenGestureEvent = 0;
+ last.singleshot.delivered = false;
+ last.singleshot.offset = QPoint();
+ last.pinch.delivered = false;
+ last.pinch.startPoints[0] = TouchPoint();
+ last.pinch.startPoints[1] = TouchPoint();
+ last.pinch.lastPoints[0] = TouchPoint();
+ last.pinch.lastPoints[1] = TouchPoint();
+ last.pinch.points[0] = TouchPoint();
+ last.pinch.points[1] = TouchPoint();
+ last.pinch.offset = QPoint();
+ last.secondfinger.delivered = false;
+ last.secondfinger.startPoint = TouchPoint();
+ last.secondfinger.lastPoint = TouchPoint();
+ last.secondfinger.point = TouchPoint();
+ last.secondfinger.offset = QPoint();
+ last.cancelled.clear();
+
+ shouldAcceptSingleshotGesture = true;
+ shouldAcceptPinchGesture = true;
+ shouldAcceptSecondFingerGesture = true;
+ }
+
+protected:
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::Gesture) {
+ QGestureEvent *e = static_cast<QGestureEvent*>(event);
+ ++seenGestureEvent;
+ if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) {
+ last.singleshot.delivered = true;
+ last.singleshot.offset = g->offset;
+ if (shouldAcceptSingleshotGesture)
+ g->accept();
+ }
+ if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) {
+ last.pinch.delivered = true;
+ last.pinch.startPoints[0] = g->startPoints[0];
+ last.pinch.startPoints[1] = g->startPoints[1];
+ last.pinch.lastPoints[0] = g->lastPoints[0];
+ last.pinch.lastPoints[1] = g->lastPoints[1];
+ last.pinch.points[0] = g->points[0];
+ last.pinch.points[1] = g->points[1];
+ last.pinch.offset = g->offset;
+ if (shouldAcceptPinchGesture)
+ g->accept();
+ }
+ if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) {
+ last.secondfinger.delivered = true;
+ last.secondfinger.startPoint = g->startPoint;
+ last.secondfinger.lastPoint = g->lastPoint;
+ last.secondfinger.point = g->point;
+ last.secondfinger.offset = g->offset;
+ if (shouldAcceptSecondFingerGesture)
+ g->accept();
+ }
+ last.cancelled = e->cancelledGestures();
+ return true;
+ }
+ return QWidget::event(event);
+ }
+};
+QVector<QColor> GestureWidget::colors;
+int GestureWidget::numberOfWidgets = 0;
+
+class tst_Gestures : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_Gestures();
+ virtual ~tst_Gestures();
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void singleshotGesture();
+ void pinchGesture();
+
+ void simplePropagation();
+ void simplePropagation2();
+ void acceptedGesturePropagation();
+
+private:
+ SingleshotGestureRecognizer *singleshotRecognizer;
+ PinchGestureRecognizer *pinchRecognizer;
+ SecondFingerGestureRecognizer *secondFingerRecognizer;
+ GestureWidget *mainWidget;
+
+ bool sendSpontaneousEvent(QWidget *receiver, QEvent *event);
+ void sendPinchEvents(QWidget *receiver, const QPoint &fromFinger1, const QPoint &fromFinger2);
+};
+
+tst_Gestures::tst_Gestures()
+{
+ singleshotRecognizer = new SingleshotGestureRecognizer;
+ pinchRecognizer = new PinchGestureRecognizer;
+ secondFingerRecognizer = new SecondFingerGestureRecognizer;
+ qApp->addGestureRecognizer(singleshotRecognizer);
+ qApp->addGestureRecognizer(pinchRecognizer);
+ qApp->addGestureRecognizer(secondFingerRecognizer);
+}
+
+tst_Gestures::~tst_Gestures()
+{
+}
+
+
+void tst_Gestures::initTestCase()
+{
+ mainWidget = new GestureWidget(GestureWidget::DoNotGrabGestures);
+ mainWidget->setObjectName("MainGestureWidget");
+ mainWidget->resize(500, 600);
+ mainWidget->show();
+}
+
+void tst_Gestures::cleanupTestCase()
+{
+ delete mainWidget; mainWidget = 0;
+}
+
+void tst_Gestures::init()
+{
+ // TODO: Add initialization code here.
+ // This will be executed immediately before each test is run.
+ mainWidget->reset();
+}
+
+void tst_Gestures::cleanup()
+{
+}
+
+bool tst_Gestures::sendSpontaneousEvent(QWidget *receiver, QEvent *event)
+{
+ QETWidget::setSpont(event, true);
+ return qApp->notify(receiver, event);
+}
+
+void tst_Gestures::singleshotGesture()
+{
+ mainWidget->grabSingleshotGesture();
+ SingleshotEvent event;
+ sendSpontaneousEvent(mainWidget, &event);
+ QVERIFY(mainWidget->seenGestureEvent);
+ QVERIFY(mainWidget->last.singleshot.delivered);
+ QVERIFY(mainWidget->last.cancelled.isEmpty());
+}
+
+void tst_Gestures::sendPinchEvents(QWidget *receiver, const QPoint &fromFinger1, const QPoint &fromFinger2)
+{
+ int x1 = fromFinger1.x();
+ int y1 = fromFinger1.x();
+ int x2 = fromFinger2.x();
+ int y2 = fromFinger2.x();
+
+ TouchEvent event;
+ event.points[0] = TouchPoint(0,x1,y1, TouchPoint::Begin);
+ event.points[1] = TouchPoint();
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint(0, x1+=2,y1+=2, TouchPoint::Update);
+ event.points[1] = TouchPoint();
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint(0, x1,y1, TouchPoint::Update);
+ event.points[1] = TouchPoint(1, x2,y2, TouchPoint::Begin);
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint(0, x1+=5,y1+=10, TouchPoint::End);
+ event.points[1] = TouchPoint(1, x2+=3,y2+=6, TouchPoint::Update);
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint();
+ event.points[1] = TouchPoint(1, x2+=10,y2+=15, TouchPoint::Update);
+ sendSpontaneousEvent(receiver, &event);
+ event.points[0] = TouchPoint();
+ event.points[1] = TouchPoint(1, x2,y2, TouchPoint::End);
+ sendSpontaneousEvent(receiver, &event);
+}
+
+void tst_Gestures::pinchGesture()
+{
+ mainWidget->grabPinchGesture();
+ sendPinchEvents(mainWidget, QPoint(10,10), QPoint(20,20));
+
+ QVERIFY(mainWidget->seenGestureEvent);
+ QVERIFY(!mainWidget->last.singleshot.delivered);
+ QVERIFY(mainWidget->last.cancelled.isEmpty());
+ QVERIFY(mainWidget->last.pinch.delivered);
+ QCOMPARE(mainWidget->last.pinch.startPoints[0].pt, QPoint(10,10));
+ QCOMPARE(mainWidget->last.pinch.startPoints[1].pt, QPoint(20,20));
+ QCOMPARE(mainWidget->last.pinch.offset, QPoint(0,0));
+}
+
+void tst_Gestures::simplePropagation()
+{
+ mainWidget->grabSingleshotGesture();
+ GestureWidget offsetWidget(GestureWidget::DoNotGrabGestures);
+ offsetWidget.setFixedSize(30, 30);
+ mainWidget->layout()->addWidget(&offsetWidget);
+ GestureWidget nonGestureWidget(GestureWidget::DoNotGrabGestures);
+ mainWidget->layout()->addWidget(&nonGestureWidget);
+ QApplication::processEvents();
+
+ SingleshotEvent event;
+ sendSpontaneousEvent(&nonGestureWidget, &event);
+ QVERIFY(!offsetWidget.seenGestureEvent);
+ QVERIFY(!nonGestureWidget.seenGestureEvent);
+ QVERIFY(mainWidget->seenGestureEvent);
+ QVERIFY(mainWidget->last.cancelled.isEmpty());
+ QVERIFY(mainWidget->last.singleshot.delivered);
+ QCOMPARE(mainWidget->last.singleshot.offset, QPoint(GestureWidget::LeftMargin, 30 + GestureWidget::TopMargin));
+}
+
+void tst_Gestures::simplePropagation2()
+{
+ mainWidget->grabSingleshotGesture();
+ mainWidget->grabPinchGesture();
+ GestureWidget nonGestureMiddleWidget(GestureWidget::DoNotGrabGestures);
+ GestureWidget secondGestureWidget(GestureWidget::GrabPinch);
+ nonGestureMiddleWidget.layout()->addWidget(&secondGestureWidget);
+ mainWidget->layout()->addWidget(&nonGestureMiddleWidget);
+ QApplication::processEvents();
+
+ SingleshotEvent event;
+ sendSpontaneousEvent(&secondGestureWidget, &event);
+ QVERIFY(!secondGestureWidget.seenGestureEvent);
+ QVERIFY(!nonGestureMiddleWidget.seenGestureEvent);
+ QVERIFY(mainWidget->seenGestureEvent);
+ QVERIFY(mainWidget->last.singleshot.delivered);
+ QVERIFY(mainWidget->last.cancelled.isEmpty());
+ QCOMPARE(mainWidget->last.singleshot.offset, QPoint(GestureWidget::LeftMargin*2,GestureWidget::TopMargin*2));
+
+ mainWidget->reset();
+ nonGestureMiddleWidget.reset();
+ secondGestureWidget.reset();
+
+ sendPinchEvents(&secondGestureWidget, QPoint(10,10), QPoint(20,20));
+ QVERIFY(secondGestureWidget.seenGestureEvent);
+ QVERIFY(!secondGestureWidget.last.singleshot.delivered);
+ QVERIFY(secondGestureWidget.last.pinch.delivered);
+ QCOMPARE(secondGestureWidget.last.pinch.startPoints[0].pt, QPoint(10,10));
+ QCOMPARE(secondGestureWidget.last.pinch.startPoints[1].pt, QPoint(20,20));
+ QCOMPARE(secondGestureWidget.last.pinch.offset, QPoint(0,0));
+ QVERIFY(!nonGestureMiddleWidget.seenGestureEvent);
+ QVERIFY(!mainWidget->seenGestureEvent);
+}
+
+void tst_Gestures::acceptedGesturePropagation()
+{
+ mainWidget->grabSingleshotGesture();
+ mainWidget->grabPinchGesture();
+ mainWidget->grabSecondFingerGesture();
+ GestureWidget nonGestureMiddleWidget(GestureWidget::DoNotGrabGestures);
+ nonGestureMiddleWidget.setObjectName("nonGestureMiddleWidget");
+ GestureWidget secondGestureWidget(GestureWidget::GrabSecondFinger);
+ secondGestureWidget.setObjectName("secondGestureWidget");
+ nonGestureMiddleWidget.layout()->addWidget(&secondGestureWidget);
+ mainWidget->layout()->addWidget(&nonGestureMiddleWidget);
+ QApplication::processEvents();
+
+ sendPinchEvents(&secondGestureWidget, QPoint(10, 10), QPoint(40, 40));
+ QVERIFY(secondGestureWidget.seenGestureEvent);
+ QVERIFY(!secondGestureWidget.last.singleshot.delivered);
+ QVERIFY(!secondGestureWidget.last.pinch.delivered);
+ QVERIFY(secondGestureWidget.last.secondfinger.delivered);
+ QCOMPARE(secondGestureWidget.last.secondfinger.startPoint.pt, QPoint(40,40));
+ QVERIFY(!nonGestureMiddleWidget.seenGestureEvent);
+ QVERIFY(mainWidget->seenGestureEvent);
+ QVERIFY(!mainWidget->last.singleshot.delivered);
+ QVERIFY(!mainWidget->last.secondfinger.delivered);
+ QVERIFY(mainWidget->last.pinch.delivered);
+ QCOMPARE(mainWidget->last.pinch.startPoints[0].pt, QPoint(10,10));
+ QCOMPARE(mainWidget->last.pinch.startPoints[1].pt, QPoint(40,40));
+
+ mainWidget->reset();
+ nonGestureMiddleWidget.reset();
+ secondGestureWidget.reset();
+
+ // don't accept it and make sure it propagates to parent
+ secondGestureWidget.shouldAcceptSecondFingerGesture = false;
+ sendPinchEvents(&secondGestureWidget, QPoint(10, 10), QPoint(40, 40));
+ QVERIFY(secondGestureWidget.seenGestureEvent);
+ QVERIFY(secondGestureWidget.last.secondfinger.delivered);
+ QVERIFY(!nonGestureMiddleWidget.seenGestureEvent);
+ QVERIFY(mainWidget->seenGestureEvent);
+ QVERIFY(!mainWidget->last.singleshot.delivered);
+ QVERIFY(mainWidget->last.secondfinger.delivered);
+ QVERIFY(mainWidget->last.pinch.delivered);
+}
+
+
+QTEST_MAIN(tst_Gestures)
+#include "tst_gestures.moc"