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.cpp949
1 files changed, 949 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..6d3bc0a
--- /dev/null
+++ b/tests/auto/gestures/tst_gestures.cpp
@@ -0,0 +1,949 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (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 http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtGui>
+
+#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; }
+};
+
+struct GestureState
+{
+ 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;
+ struct PanGesture
+ {
+ bool delivered;
+ TouchPoint startPoints[2];
+ TouchPoint lastPoints[2];
+ TouchPoint points[2];
+ QPoint offset;
+ } pan;
+ QSet<QString> cancelled;
+ } last;
+
+ GestureState() { reset(); }
+ 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();
+ }
+};
+
+struct TouchState
+{
+ int seenTouchBeginEvent;
+ int seenTouchUpdateEvent;
+ int seenTouchEndEvent;
+
+ TouchState() { reset(); }
+ void reset()
+ {
+ seenTouchBeginEvent = seenTouchUpdateEvent = seenTouchEndEvent = 0;
+ }
+};
+
+class GestureWidget : public QWidget
+{
+ Q_OBJECT
+ static QVector<QColor> colors;
+ static int numberOfWidgets;
+
+public:
+ enum Type { DoNotGrabGestures, GrabAllGestures, GrabSingleshot,
+ GrabPinch, GrabSecondFinger, GrabPan };
+
+ 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;
+ panGestureId = -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);
+ }
+ if (type == GrabAllGestures || type == GrabPan) {
+ panGestureId = grabGesture(PanGestureRecognizer::Name);
+ }
+ reset();
+ }
+ ~GestureWidget()
+ {
+ --numberOfWidgets;
+ ungrabGestures();
+ }
+
+ void grabSingleshotGesture()
+ {
+ singleshotGestureId = grabGesture(SingleshotGestureRecognizer::Name);
+ }
+ void grabPinchGesture()
+ {
+ pinchGestureId = grabGesture(PinchGestureRecognizer::Name);
+ }
+ void grabSecondFingerGesture()
+ {
+ secondFingerGestureId = grabGesture(SecondFingerGestureRecognizer::Name);
+ }
+ void grabPanGesture()
+ {
+ panGestureId = grabGesture(PanGestureRecognizer::Name);
+ }
+ void ungrabGestures()
+ {
+ releaseGesture(singleshotGestureId);
+ singleshotGestureId = -1;
+ releaseGesture(pinchGestureId);
+ pinchGestureId = -1;
+ releaseGesture(secondFingerGestureId);
+ secondFingerGestureId = -1;
+ releaseGesture(panGestureId);
+ panGestureId = -1;
+ }
+
+ int singleshotGestureId;
+ int pinchGestureId;
+ int secondFingerGestureId;
+ int panGestureId;
+
+ bool shouldAcceptSingleshotGesture;
+ bool shouldAcceptPinchGesture;
+ bool shouldAcceptSecondFingerGesture;
+ bool shouldAcceptPanGesture;
+
+ GestureState gesture;
+ TouchState touch;
+
+ void reset()
+ {
+ shouldAcceptSingleshotGesture = true;
+ shouldAcceptPinchGesture = true;
+ shouldAcceptSecondFingerGesture = true;
+ shouldAcceptPanGesture = true;
+ gesture.reset();
+ touch.reset();
+ }
+protected:
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::TouchBegin) {
+ event->accept();
+ ++touch.seenTouchBeginEvent;
+ return true;
+ } else if (event->type() == QEvent::TouchUpdate) {
+ ++touch.seenTouchUpdateEvent;
+ } else if (event->type() == QEvent::TouchEnd) {
+ ++touch.seenTouchEndEvent;
+ } else if (event->type() == QEvent::Gesture) {
+ QGestureEvent *e = static_cast<QGestureEvent*>(event);
+ ++gesture.seenGestureEvent;
+ if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) {
+ gesture.last.singleshot.delivered = true;
+ gesture.last.singleshot.offset = g->offset;
+ if (shouldAcceptSingleshotGesture)
+ g->accept();
+ }
+ if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) {
+ gesture.last.pinch.delivered = true;
+ gesture.last.pinch.startPoints[0] = g->startPoints[0];
+ gesture.last.pinch.startPoints[1] = g->startPoints[1];
+ gesture.last.pinch.lastPoints[0] = g->lastPoints[0];
+ gesture.last.pinch.lastPoints[1] = g->lastPoints[1];
+ gesture.last.pinch.points[0] = g->points[0];
+ gesture.last.pinch.points[1] = g->points[1];
+ gesture.last.pinch.offset = g->offset;
+ if (shouldAcceptPinchGesture)
+ g->accept();
+ }
+ if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) {
+ gesture.last.secondfinger.delivered = true;
+ gesture.last.secondfinger.startPoint = g->startPoint;
+ gesture.last.secondfinger.lastPoint = g->lastPoint;
+ gesture.last.secondfinger.point = g->point;
+ gesture.last.secondfinger.offset = g->offset;
+ if (shouldAcceptSecondFingerGesture)
+ g->accept();
+ }
+ if (PanGesture *g = (PanGesture*)e->gesture(PanGestureRecognizer::Name)) {
+ gesture.last.pan.delivered = true;
+ gesture.last.pan.startPoints[0] = g->startPoints[0];
+ gesture.last.pan.startPoints[1] = g->startPoints[1];
+ gesture.last.pan.lastPoints[0] = g->lastPoints[0];
+ gesture.last.pan.lastPoints[1] = g->lastPoints[1];
+ gesture.last.pan.points[0] = g->points[0];
+ gesture.last.pan.points[1] = g->points[1];
+ gesture.last.pan.offset = g->offset;
+ if (shouldAcceptPanGesture)
+ g->accept();
+ }
+ gesture.last.cancelled = e->cancelledGestures();
+ return true;
+ }
+ return QWidget::event(event);
+ }
+};
+QVector<QColor> GestureWidget::colors;
+int GestureWidget::numberOfWidgets = 0;
+
+class GraphicsScene : public QGraphicsScene
+{
+public:
+ GraphicsScene()
+ {
+ reset();
+ }
+ bool shouldAcceptSingleshotGesture;
+ bool shouldAcceptPinchGesture;
+ bool shouldAcceptSecondFingerGesture;
+ GestureState gesture;
+
+ void reset()
+ {
+ shouldAcceptSingleshotGesture = false;
+ shouldAcceptPinchGesture = false;
+ shouldAcceptSecondFingerGesture = false;
+ gesture.reset();
+ }
+protected:
+ bool event(QEvent *event)
+ {
+ if (event->type() == QEvent::GraphicsSceneGesture) {
+ QGraphicsSceneGestureEvent *e = static_cast<QGraphicsSceneGestureEvent*>(event);
+ ++gesture.seenGestureEvent;
+ QGraphicsScene::event(event);
+ if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) {
+ gesture.last.singleshot.delivered = true;
+ gesture.last.singleshot.offset = g->offset;
+ if (shouldAcceptSingleshotGesture)
+ g->accept();
+ }
+ if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) {
+ gesture.last.pinch.delivered = true;
+ gesture.last.pinch.startPoints[0] = g->startPoints[0];
+ gesture.last.pinch.startPoints[1] = g->startPoints[1];
+ gesture.last.pinch.lastPoints[0] = g->lastPoints[0];
+ gesture.last.pinch.lastPoints[1] = g->lastPoints[1];
+ gesture.last.pinch.points[0] = g->points[0];
+ gesture.last.pinch.points[1] = g->points[1];
+ gesture.last.pinch.offset = g->offset;
+ if (shouldAcceptPinchGesture)
+ g->accept();
+ }
+ if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) {
+ gesture.last.secondfinger.delivered = true;
+ gesture.last.secondfinger.startPoint = g->startPoint;
+ gesture.last.secondfinger.lastPoint = g->lastPoint;
+ gesture.last.secondfinger.point = g->point;
+ gesture.last.secondfinger.offset = g->offset;
+ if (shouldAcceptSecondFingerGesture)
+ g->accept();
+ }
+ gesture.last.cancelled = e->cancelledGestures();
+ return true;
+ }
+ return QGraphicsScene::event(event);
+ }
+};
+
+class GraphicsItem : public QGraphicsItem
+{
+public:
+ GraphicsItem(int w = 100, int h = 100)
+ : width(w), height(h)
+ {
+ reset();
+ }
+
+ QRectF boundingRect() const
+ {
+ return QRectF(0, 0, width, height);
+ }
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*)
+ {
+ painter->setBrush(Qt::green);
+ painter->drawRect(0, 0, width, height);
+ }
+
+ 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 width;
+ int height;
+
+ int singleshotGestureId;
+ int pinchGestureId;
+ int secondFingerGestureId;
+
+ bool shouldAcceptSingleshotGesture;
+ bool shouldAcceptPinchGesture;
+ bool shouldAcceptSecondFingerGesture;
+ GestureState gesture;
+
+ TouchState touch;
+
+ void reset()
+ {
+ shouldAcceptSingleshotGesture = true;
+ shouldAcceptPinchGesture = true;
+ shouldAcceptSecondFingerGesture = true;
+ gesture.reset();
+ }
+protected:
+ bool sceneEvent(QEvent *event)
+ {
+ if (event->type() == QEvent::TouchBegin) {
+ event->accept();
+ ++touch.seenTouchBeginEvent;
+ return true;
+ } else if (event->type() == QEvent::TouchUpdate) {
+ ++touch.seenTouchUpdateEvent;
+ } else if (event->type() == QEvent::TouchEnd) {
+ ++touch.seenTouchEndEvent;
+ } else if (event->type() == QEvent::GraphicsSceneGesture) {
+ QGraphicsSceneGestureEvent *e = static_cast<QGraphicsSceneGestureEvent*>(event);
+ ++gesture.seenGestureEvent;
+ if (SingleshotGesture *g = (SingleshotGesture*)e->gesture(SingleshotGestureRecognizer::Name)) {
+ gesture.last.singleshot.delivered = true;
+ gesture.last.singleshot.offset = g->offset;
+ if (shouldAcceptSingleshotGesture)
+ g->accept();
+ }
+ if (PinchGesture *g = (PinchGesture*)e->gesture(PinchGestureRecognizer::Name)) {
+ gesture.last.pinch.delivered = true;
+ gesture.last.pinch.startPoints[0] = g->startPoints[0];
+ gesture.last.pinch.startPoints[1] = g->startPoints[1];
+ gesture.last.pinch.lastPoints[0] = g->lastPoints[0];
+ gesture.last.pinch.lastPoints[1] = g->lastPoints[1];
+ gesture.last.pinch.points[0] = g->points[0];
+ gesture.last.pinch.points[1] = g->points[1];
+ gesture.last.pinch.offset = g->offset;
+ if (shouldAcceptPinchGesture)
+ g->accept();
+ }
+ if (SecondFingerGesture *g = (SecondFingerGesture*)e->gesture(SecondFingerGestureRecognizer::Name)) {
+ gesture.last.secondfinger.delivered = true;
+ gesture.last.secondfinger.startPoint = g->startPoint;
+ gesture.last.secondfinger.lastPoint = g->lastPoint;
+ gesture.last.secondfinger.point = g->point;
+ gesture.last.secondfinger.offset = g->offset;
+ if (shouldAcceptSecondFingerGesture)
+ g->accept();
+ }
+ gesture.last.cancelled = e->cancelledGestures();
+ return true;
+ }
+ return QGraphicsItem::sceneEvent(event);
+ }
+};
+
+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();
+
+ void simpleGraphicsView();
+ void simpleGraphicsItem();
+ void overlappingGraphicsItems();
+
+ void touch_widget();
+ void touch_graphicsView();
+
+ void panOnWidgets();
+
+private:
+ SingleshotGestureRecognizer *singleshotRecognizer;
+ PinchGestureRecognizer *pinchRecognizer;
+ SecondFingerGestureRecognizer *secondFingerRecognizer;
+ PanGestureRecognizer *panGestureRecognizer;
+ GestureWidget *mainWidget;
+
+ void sendPinchEvents(QWidget *receiver, const QPoint &fromFinger1, const QPoint &fromFinger2);
+};
+
+tst_Gestures::tst_Gestures()
+{
+ singleshotRecognizer = new SingleshotGestureRecognizer;
+ pinchRecognizer = new PinchGestureRecognizer;
+ secondFingerRecognizer = new SecondFingerGestureRecognizer;
+ panGestureRecognizer = new PanGestureRecognizer;
+ qApp->addGestureRecognizer(singleshotRecognizer);
+ qApp->addGestureRecognizer(pinchRecognizer);
+ qApp->addGestureRecognizer(secondFingerRecognizer);
+ qApp->addGestureRecognizer(panGestureRecognizer);
+}
+
+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 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->gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(mainWidget->gesture.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->gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(mainWidget->gesture.last.cancelled.isEmpty());
+ QVERIFY(mainWidget->gesture.last.pinch.delivered);
+ QCOMPARE(mainWidget->gesture.last.pinch.startPoints[0].pt, QPoint(10,10));
+ QCOMPARE(mainWidget->gesture.last.pinch.startPoints[1].pt, QPoint(20,20));
+ QCOMPARE(mainWidget->gesture.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.gesture.seenGestureEvent);
+ QVERIFY(!nonGestureWidget.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.last.cancelled.isEmpty());
+ QVERIFY(mainWidget->gesture.last.singleshot.delivered);
+ QCOMPARE(mainWidget->gesture.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.gesture.seenGestureEvent);
+ QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(mainWidget->gesture.last.cancelled.isEmpty());
+ QCOMPARE(mainWidget->gesture.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.gesture.seenGestureEvent);
+ QVERIFY(!secondGestureWidget.gesture.last.singleshot.delivered);
+ QVERIFY(secondGestureWidget.gesture.last.pinch.delivered);
+ QCOMPARE(secondGestureWidget.gesture.last.pinch.startPoints[0].pt, QPoint(10,10));
+ QCOMPARE(secondGestureWidget.gesture.last.pinch.startPoints[1].pt, QPoint(20,20));
+ QCOMPARE(secondGestureWidget.gesture.last.pinch.offset, QPoint(0,0));
+ QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.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.gesture.seenGestureEvent);
+ QVERIFY(!secondGestureWidget.gesture.last.singleshot.delivered);
+ QVERIFY(!secondGestureWidget.gesture.last.pinch.delivered);
+ QVERIFY(secondGestureWidget.gesture.last.secondfinger.delivered);
+ QCOMPARE(secondGestureWidget.gesture.last.secondfinger.startPoint.pt, QPoint(40,40));
+ QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(!mainWidget->gesture.last.secondfinger.delivered);
+ QVERIFY(mainWidget->gesture.last.pinch.delivered);
+ QCOMPARE(mainWidget->gesture.last.pinch.startPoints[0].pt, QPoint(10,10));
+ QCOMPARE(mainWidget->gesture.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.gesture.seenGestureEvent);
+ QVERIFY(secondGestureWidget.gesture.last.secondfinger.delivered);
+ QVERIFY(!nonGestureMiddleWidget.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.last.singleshot.delivered);
+ QVERIFY(mainWidget->gesture.last.secondfinger.delivered);
+ QVERIFY(mainWidget->gesture.last.pinch.delivered);
+}
+
+void tst_Gestures::simpleGraphicsView()
+{
+ mainWidget->grabSingleshotGesture();
+ GraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.grabGesture(SingleshotGestureRecognizer::Name);
+ mainWidget->layout()->addWidget(&view);
+ QApplication::processEvents();
+
+ scene.shouldAcceptSingleshotGesture = true;
+
+ SingleshotEvent event;
+ sendSpontaneousEvent(&view, &event);
+ QVERIFY(!mainWidget->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.last.singleshot.delivered);
+ QVERIFY(scene.gesture.last.cancelled.isEmpty());
+}
+
+void tst_Gestures::simpleGraphicsItem()
+{
+ mainWidget->grabSingleshotGesture();
+ GraphicsScene scene;
+ QGraphicsView view(&scene);
+ mainWidget->layout()->addWidget(&view);
+ GraphicsItem *item = new GraphicsItem;
+ item->grabSingleshotGesture();
+ item->setPos(30, 50);
+ scene.addItem(item);
+ QApplication::processEvents();
+
+ SingleshotEvent event(50, 80);
+ sendSpontaneousEvent(&view, &event);
+ QVERIFY(item->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.seenGestureEvent);
+
+ item->reset();
+ scene.reset();
+ mainWidget->reset();
+
+ item->shouldAcceptSingleshotGesture = false;
+ SingleshotEvent event2(20, 40);
+ sendSpontaneousEvent(&view, &event2);
+ QVERIFY(!item->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(mainWidget->gesture.seenGestureEvent);
+}
+
+void tst_Gestures::overlappingGraphicsItems()
+{
+ mainWidget->grabSingleshotGesture();
+ GraphicsScene scene;
+ QGraphicsView view(&scene);
+ mainWidget->layout()->addWidget(&view);
+
+ GraphicsItem *item = new GraphicsItem(300, 100);
+ item->setPos(30, 50);
+ scene.addItem(item);
+ GraphicsItem *subitem1 = new GraphicsItem(50, 70);
+ subitem1->setPos(70, 70);
+ scene.addItem(subitem1);
+ GraphicsItem *subitem2 = new GraphicsItem(50, 70);
+ subitem2->setPos(250, 70);
+ scene.addItem(subitem2);
+ QApplication::processEvents();
+
+ item->grabSingleshotGesture();
+ item->grabPinchGesture();
+ item->grabSecondFingerGesture();
+ subitem1->grabSingleshotGesture();
+ subitem2->grabSecondFingerGesture();
+
+ SingleshotEvent event(100, 100);
+ sendSpontaneousEvent(&view, &event);
+ QVERIFY(subitem1->gesture.seenGestureEvent);
+ QVERIFY(!subitem2->gesture.seenGestureEvent);
+ QVERIFY(!item->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.seenGestureEvent);
+ QVERIFY(subitem1->gesture.last.singleshot.delivered);
+
+ item->reset();
+ subitem1->reset();
+ subitem2->reset();
+ scene.reset();
+ mainWidget->reset();
+
+ subitem1->shouldAcceptSingleshotGesture = false;
+ SingleshotEvent event2(100, 100);
+ sendSpontaneousEvent(&view, &event2);
+ QVERIFY(subitem1->gesture.seenGestureEvent);
+ QVERIFY(!subitem2->gesture.seenGestureEvent);
+ QVERIFY(item->gesture.seenGestureEvent);
+ QVERIFY(scene.gesture.seenGestureEvent);
+ QVERIFY(!mainWidget->gesture.seenGestureEvent);
+ QVERIFY(subitem1->gesture.last.singleshot.delivered);
+ QVERIFY(item->gesture.last.singleshot.delivered);
+}
+
+void tst_Gestures::touch_widget()
+{
+ GestureWidget leftWidget(GestureWidget::DoNotGrabGestures);
+ leftWidget.setObjectName("leftWidget");
+ leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ GestureWidget rightWidget(GestureWidget::DoNotGrabGestures);
+ rightWidget.setObjectName("rightWidget");
+ rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ delete mainWidget->layout();
+ (void)new QHBoxLayout(mainWidget);
+ mainWidget->layout()->addWidget(&leftWidget);
+ mainWidget->layout()->addWidget(&rightWidget);
+ QApplication::processEvents();
+
+ QTest::touchEvent()
+ .press(0, QPoint(10, 10), &leftWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(12, 30), &leftWidget);
+ QTest::touchEvent()
+ .stationary(0)
+ .press(1, QPoint(15, 15), &rightWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(10, 35), &leftWidget)
+ .press(1, QPoint(15, 15), &rightWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(10, 40), &leftWidget)
+ .move(1, QPoint(20, 50), &rightWidget);
+ QTest::touchEvent()
+ .release(0, QPoint(10, 40), &leftWidget)
+ .release(1, QPoint(20, 50), &rightWidget);
+ QVERIFY(!mainWidget->touch.seenTouchBeginEvent);
+ QVERIFY(leftWidget.touch.seenTouchBeginEvent);
+ QVERIFY(leftWidget.touch.seenTouchUpdateEvent);
+ QVERIFY(leftWidget.touch.seenTouchEndEvent);
+ QVERIFY(rightWidget.touch.seenTouchBeginEvent);
+ QVERIFY(rightWidget.touch.seenTouchUpdateEvent);
+ QVERIFY(rightWidget.touch.seenTouchEndEvent);
+}
+
+void tst_Gestures::touch_graphicsView()
+{
+ mainWidget->setAttribute(Qt::WA_AcceptTouchEvents);
+ GraphicsScene scene;
+ QGraphicsView view(&scene);
+ view.viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
+ mainWidget->layout()->addWidget(&view);
+
+ GraphicsItem *item = new GraphicsItem(300, 100);
+ item->setAcceptTouchEvents(true);
+ item->setPos(30, 50);
+ scene.addItem(item);
+ GraphicsItem *subitem1 = new GraphicsItem(50, 70);
+ subitem1->setAcceptTouchEvents(true);
+ subitem1->setPos(70, 70);
+ scene.addItem(subitem1);
+ GraphicsItem *subitem2 = new GraphicsItem(50, 70);
+ subitem2->setAcceptTouchEvents(true);
+ subitem2->setPos(250, 70);
+ scene.addItem(subitem2);
+ QApplication::processEvents();
+
+ QRect itemRect = view.mapFromScene(item->mapRectToScene(item->boundingRect())).boundingRect();
+ QPoint pt = itemRect.center();
+ QTest::touchEvent(view.viewport())
+ .press(0, pt)
+ .press(1, pt);
+ QTest::touchEvent(view.viewport())
+ .move(0, pt + QPoint(20, 30))
+ .move(1, QPoint(300, 300));
+ QTest::touchEvent(view.viewport())
+ .stationary(0)
+ .move(1, QPoint(330, 330));
+ QTest::touchEvent(view.viewport())
+ .release(0, QPoint(120, 120))
+ .release(1, QPoint(300, 300));
+
+ QVERIFY(item->touch.seenTouchBeginEvent);
+ QVERIFY(item->touch.seenTouchUpdateEvent);
+ QVERIFY(item->touch.seenTouchEndEvent);
+}
+
+void tst_Gestures::panOnWidgets()
+{
+ GestureWidget leftWidget(GestureWidget::GrabPan);
+ leftWidget.setObjectName("leftWidget");
+ leftWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ GestureWidget rightWidget(GestureWidget::GrabPan);
+ rightWidget.setObjectName("rightWidget");
+ rightWidget.setAttribute(Qt::WA_AcceptTouchEvents);
+ delete mainWidget->layout();
+ (void)new QHBoxLayout(mainWidget);
+ mainWidget->layout()->addWidget(&leftWidget);
+ mainWidget->layout()->addWidget(&rightWidget);
+ QApplication::processEvents();
+
+ QTest::touchEvent()
+ .press(0, QPoint(10, 10), &leftWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(12, 30), &leftWidget);
+ QTest::touchEvent()
+ .stationary(0)
+ .press(1, QPoint(15, 15), &rightWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(10, 35), &leftWidget)
+ .press(1, QPoint(15, 15), &rightWidget);
+ QTest::touchEvent()
+ .move(0, QPoint(10, 40), &leftWidget)
+ .move(1, QPoint(20, 50), &rightWidget);
+ QTest::touchEvent()
+ .release(0, QPoint(10, 40), &leftWidget)
+ .release(1, QPoint(20, 50), &rightWidget);
+
+ QVERIFY(leftWidget.gesture.last.pan.delivered);
+ QVERIFY(rightWidget.gesture.last.pan.delivered);
+}
+
+QTEST_MAIN(tst_Gestures)
+#include "tst_gestures.moc"