aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/touchmouse
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@nokia.com>2012-06-26 18:00:59 +0200
committerQt by Nokia <qt-info@nokia.com>2012-06-28 16:47:42 +0200
commit468626e99a90d6ac21cb311cde05c658ccb3b781 (patch)
tree7ac0039994e4489ea19e27cb0840dfa000486cbb /tests/auto/quick/touchmouse
parent4c1addd2c3b019d66b5c19fcd8ba9e0918e92978 (diff)
Propagate synthesized mouse events in parallel with touch.
The old way of event propagation inside QQuickCanvas was to send the touch event through all elements, and if it was accepted along the way, stop. Otherwise generate a mouse event and propagate it through the items in the same way. With this patch the behavior is changed instead to do the propagation in parallel. The idea is to first send a touch, then a mouse event to each QML item (in paint order) that can potentially handle the events. When items filter their child elements, the same logic applies. Other changes/clarifications: - mouse events no longer get synthesized for more than one touch point - TouchPoints can be distributed to multiple Items - if an item accepts a touch point, it always gets updates, even if the point is stationary - events containing only stationary TouchPoints are discarded - PinchArea must accept any initial single TouchPoint in order to receive subsequent updates, even though it's not pinching yet. This means if PA is on top, items underneath don't get touches. New unit tests showing this behavior were added. This patch was written by Frederik Gladhorn, Laszlo Agocs and Shawn Rutledge. Due to the complexity of the logic some refactoring was done. QQuickMouseEventEx has been removed because it inherently relied on using the QEvent d pointer. Change-Id: If19ef687d7602e83cc11b18d2fecfbbdb4e44f5c Reviewed-by: Frederik Gladhorn <frederik.gladhorn@nokia.com>
Diffstat (limited to 'tests/auto/quick/touchmouse')
-rw-r--r--tests/auto/quick/touchmouse/data/buttononflickable.qml42
-rw-r--r--tests/auto/quick/touchmouse/data/buttonontouch.qml100
-rw-r--r--tests/auto/quick/touchmouse/data/flickableonpinch.qml37
-rw-r--r--tests/auto/quick/touchmouse/data/mouseonflickableonpinch.qml47
-rw-r--r--tests/auto/quick/touchmouse/data/pinchonflickable.qml35
-rw-r--r--tests/auto/quick/touchmouse/data/singleitem.qml18
-rw-r--r--tests/auto/quick/touchmouse/data/twoitems.qml22
-rw-r--r--tests/auto/quick/touchmouse/touchmouse.pro17
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp923
9 files changed, 1241 insertions, 0 deletions
diff --git a/tests/auto/quick/touchmouse/data/buttononflickable.qml b/tests/auto/quick/touchmouse/data/buttononflickable.qml
new file mode 100644
index 0000000000..95a993f806
--- /dev/null
+++ b/tests/auto/quick/touchmouse/data/buttononflickable.qml
@@ -0,0 +1,42 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Rectangle {
+ id: root
+ width: 300
+ height: 500
+ color: "green"
+
+ Flickable {
+ objectName: "flickable"
+ anchors.fill: parent
+ contentHeight: 1000
+
+ Rectangle {
+ objectName: "button"
+ y: 100
+ height: 100
+ width: parent.width
+
+ EventItem {
+ objectName: "eventItem1"
+ height: 100
+ width: 300
+ }
+ }
+
+ Rectangle {
+ objectName: "button2"
+ y: 300
+ height: 100
+ width: parent.width
+
+ EventItem {
+ objectName: "eventItem2"
+ height: 100
+ width: 300
+ }
+ }
+ }
+}
+
diff --git a/tests/auto/quick/touchmouse/data/buttonontouch.qml b/tests/auto/quick/touchmouse/data/buttonontouch.qml
new file mode 100644
index 0000000000..dcd2573f2e
--- /dev/null
+++ b/tests/auto/quick/touchmouse/data/buttonontouch.qml
@@ -0,0 +1,100 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Rectangle {
+ id: root
+ width: 300
+ height: 800
+ color: "green"
+
+ Rectangle {
+ color: "blue"
+ height: 400
+ width: parent.width
+
+
+ PinchArea {
+ pinch.target: button1
+ objectName: "pincharea"
+ anchors.fill: parent
+
+ pinch.minimumScale: 0.1
+ pinch.maximumScale: 10.0
+ }
+
+ Rectangle {
+
+ id: button1
+ objectName: "button1"
+ y: 100
+ height: 100
+ width: parent.width
+ Text { text: "Button 1" }
+
+ EventItem {
+ objectName: "eventItem1"
+ height: 100
+ width: 300
+ }
+ }
+
+ Rectangle {
+ objectName: "button2"
+ y: 300
+ height: 100
+ width: parent.width
+ Text { text: "Button 2" }
+
+ EventItem {
+ objectName: "eventItem2"
+ height: 100
+ width: 300
+ }
+ }
+ }
+
+ Rectangle {
+ y: 400
+ width: parent.width
+ height: parent.height
+ color: "red"
+
+ MultiPointTouchArea {
+ objectName: "toucharea"
+ anchors.fill: parent
+
+ y: 400
+ height: 400
+
+ Rectangle {
+ objectName: "button3"
+ y: 100
+ height: 100
+ width: parent.width
+ Text { text: "Button 3" }
+
+ EventItem {
+ objectName: "eventItem3"
+ height: 100
+ width: 300
+ }
+ }
+
+ Rectangle {
+ objectName: "button4"
+ y: 300
+ height: 100
+ width: parent.width
+ Text { text: "Button 4" }
+
+ EventItem {
+ objectName: "eventItem4"
+ height: 100
+ width: 300
+ }
+ }
+
+ }
+ }
+}
+
diff --git a/tests/auto/quick/touchmouse/data/flickableonpinch.qml b/tests/auto/quick/touchmouse/data/flickableonpinch.qml
new file mode 100644
index 0000000000..9c9a197d66
--- /dev/null
+++ b/tests/auto/quick/touchmouse/data/flickableonpinch.qml
@@ -0,0 +1,37 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Rectangle {
+ id: root
+ width: 600
+ height: 600
+ color: "green"
+
+ PinchArea {
+ objectName: "pincharea"
+ pinch.target: rect
+ anchors.fill: parent
+
+ pinch.minimumScale: 1.0
+ pinch.maximumScale: 10.0
+
+ Flickable {
+ objectName: "flickable"
+ anchors.fill: parent
+ contentHeight: 1000
+ contentWidth: 1000
+
+ Rectangle {
+ objectName: "rect"
+ id: rect
+ color: "blue"
+ x: 200
+ y: 200
+ width: 400
+ height: 400
+ }
+ }
+ }
+
+}
+
diff --git a/tests/auto/quick/touchmouse/data/mouseonflickableonpinch.qml b/tests/auto/quick/touchmouse/data/mouseonflickableonpinch.qml
new file mode 100644
index 0000000000..015391f291
--- /dev/null
+++ b/tests/auto/quick/touchmouse/data/mouseonflickableonpinch.qml
@@ -0,0 +1,47 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Rectangle {
+ id: root
+ width: 600
+ height: 600
+ color: "green"
+
+ PinchArea {
+ objectName: "pincharea"
+ pinch.target: rect
+ anchors.fill: parent
+
+ pinch.minimumScale: 1.0
+ pinch.maximumScale: 10.0
+
+ Flickable {
+ objectName: "flickable"
+ anchors.fill: parent
+ contentHeight: 1000
+ contentWidth: 1000
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (rect.color == "#000000")
+ rect.color = "#00ff00"
+ else
+ rect.color = "#000000"
+ }
+ }
+
+ Rectangle {
+ objectName: "rect"
+ id: rect
+ color: "blue"
+ x: 200
+ y: 200
+ width: 400
+ height: 400
+ }
+ }
+ }
+
+}
+
diff --git a/tests/auto/quick/touchmouse/data/pinchonflickable.qml b/tests/auto/quick/touchmouse/data/pinchonflickable.qml
new file mode 100644
index 0000000000..2a7a91006e
--- /dev/null
+++ b/tests/auto/quick/touchmouse/data/pinchonflickable.qml
@@ -0,0 +1,35 @@
+import QtQuick 2.0
+//import Qt.test 1.0
+
+Rectangle {
+ id: root
+ width: 600
+ height: 600
+ color: "green"
+
+ Flickable {
+ objectName: "flickable"
+ anchors.fill: parent
+ contentHeight: 1000
+ contentWidth: 1000
+
+ Rectangle {
+ objectName: "rect"
+ id: rect
+ color: "blue"
+ x: 200
+ y: 200
+ width: 400
+ height: 400
+ }
+ PinchArea {
+ objectName: "pincharea"
+ pinch.target: rect
+ anchors.fill: parent
+
+ pinch.minimumScale: 1.0
+ pinch.maximumScale: 10.0
+ }
+ }
+}
+
diff --git a/tests/auto/quick/touchmouse/data/singleitem.qml b/tests/auto/quick/touchmouse/data/singleitem.qml
new file mode 100644
index 0000000000..76d3a51da9
--- /dev/null
+++ b/tests/auto/quick/touchmouse/data/singleitem.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Rectangle {
+ id: root
+ width: 320
+ height: 480
+ color: "green"
+
+ EventItem {
+ objectName: "eventItem1"
+ x: 5
+ y: 5
+ height: 30
+ width: 30
+ }
+}
+
diff --git a/tests/auto/quick/touchmouse/data/twoitems.qml b/tests/auto/quick/touchmouse/data/twoitems.qml
new file mode 100644
index 0000000000..afbf35fe1a
--- /dev/null
+++ b/tests/auto/quick/touchmouse/data/twoitems.qml
@@ -0,0 +1,22 @@
+import QtQuick 2.0
+import Qt.test 1.0
+
+Rectangle {
+ id: root
+ width: 320
+ height: 480
+ color: "green"
+
+ EventItem {
+ objectName: "eventItem1"
+ height: 200
+ width: 100
+
+ EventItem {
+ objectName: "eventItem2"
+ height: 100
+ width: 100
+ }
+ }
+}
+
diff --git a/tests/auto/quick/touchmouse/touchmouse.pro b/tests/auto/quick/touchmouse/touchmouse.pro
new file mode 100644
index 0000000000..d0b0fa79f2
--- /dev/null
+++ b/tests/auto/quick/touchmouse/touchmouse.pro
@@ -0,0 +1,17 @@
+CONFIG += testcase
+
+TARGET = tst_touchmouse
+QT += core-private gui-private qml-private quick-private v8-private testlib
+
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_touchmouse.cpp
+
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+# OTHER_FILES += data/foo.qml
+
+CONFIG += parallel_test
+
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
new file mode 100644
index 0000000000..7ab9387ea7
--- /dev/null
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -0,0 +1,923 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.1, 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <QtGui/qstylehints.h>
+
+#include <QtQuick/qquickview.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/private/qquickmousearea_p.h>
+#include <QtQuick/private/qquickmultipointtoucharea_p.h>
+#include <QtQuick/private/qquickpincharea_p.h>
+#include <QtQuick/private/qquickflickable_p.h>
+
+#include <private/qquickcanvas_p.h>
+
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlproperty.h>
+
+#include "../../shared/util.h"
+
+struct Event
+{
+ Event(QEvent::Type t, QPoint mouse, QPoint global)
+ :type(t), mousePos(mouse), mousePosGlobal(global)
+ {}
+
+ Event(QEvent::Type t, QList<QTouchEvent::TouchPoint> touch)
+ :type(t), points(touch)
+ {}
+
+ QEvent::Type type;
+ QPoint mousePos;
+ QPoint mousePosGlobal;
+ QList<QTouchEvent::TouchPoint> points;
+};
+
+class EventItem : public QQuickItem
+{
+ Q_OBJECT
+public:
+ EventItem(QQuickItem *parent = 0)
+ : QQuickItem(parent), acceptMouse(false), acceptTouch(false), filterTouch(false)
+ {}
+
+ void touchEvent(QTouchEvent *event)
+ {
+ eventList.append(Event(event->type(), event->touchPoints()));
+ event->setAccepted(acceptTouch);
+ }
+ void mousePressEvent(QMouseEvent *event)
+ {
+ eventList.append(Event(event->type(), event->pos(), event->globalPos()));
+ event->setAccepted(acceptMouse);
+ }
+ void mouseMoveEvent(QMouseEvent *event)
+ {
+ eventList.append(Event(event->type(), event->pos(), event->globalPos()));
+ event->setAccepted(acceptMouse);
+ }
+ void mouseReleaseEvent(QMouseEvent *event)
+ {
+ eventList.append(Event(event->type(), event->pos(), event->globalPos()));
+ event->setAccepted(acceptMouse);
+ }
+ void mouseDoubleClickEvent(QMouseEvent *event)
+ {
+ eventList.append(Event(event->type(), event->pos(), event->globalPos()));
+ event->setAccepted(acceptMouse);
+ }
+ bool event(QEvent *event) {
+ if (event->type() == QEvent::UngrabMouse) {
+ eventList.append(Event(event->type(), QPoint(0,0), QPoint(0,0)));
+ }
+ return QQuickItem::event(event);
+ }
+
+ QList<Event> eventList;
+ bool acceptMouse;
+ bool acceptTouch;
+ bool filterTouch; // when used as event filter
+
+ bool eventFilter(QObject *, QEvent *event)
+ {
+ if (event->type() == QEvent::TouchBegin ||
+ event->type() == QEvent::TouchUpdate ||
+ event->type() == QEvent::TouchCancel ||
+ event->type() == QEvent::TouchEnd) {
+ QTouchEvent *touch = static_cast<QTouchEvent*>(event);
+ eventList.append(Event(event->type(), touch->touchPoints()));
+ if (filterTouch)
+ event->accept();
+ return true;
+ }
+ return false;
+ }
+};
+
+class tst_TouchMouse : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_TouchMouse()
+ :device(0)
+ {}
+
+private slots:
+ void initTestCase();
+
+ void simpleTouchEvent();
+ void eventFilter();
+ void mouse();
+ void touchOverMouse();
+ void mouseOverTouch();
+
+ void buttonOnFlickable();
+ void buttonOnTouch();
+
+ void pinchOnFlickable();
+ void flickableOnPinch();
+ void mouseOnFlickableOnPinch();
+
+private:
+ QQuickView *createView();
+ QTouchDevice *device;
+};
+
+QQuickView *tst_TouchMouse::createView()
+{
+ QQuickView *canvas = new QQuickView(0);
+ canvas->setGeometry(0,0,240,320);
+
+ return canvas;
+}
+
+void tst_TouchMouse::initTestCase()
+{
+ // This test assumes that we don't get synthesized mouse events from QGuiApplication
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
+
+ QQmlDataTest::initTestCase();
+ qmlRegisterType<EventItem>("Qt.test", 1, 0, "EventItem");
+ if (!device) {
+ device = new QTouchDevice;
+ device->setType(QTouchDevice::TouchScreen);
+ QWindowSystemInterface::registerTouchDevice(device);
+ }
+}
+
+void tst_TouchMouse::simpleTouchEvent()
+{
+ QQuickView *canvas = createView();
+
+ canvas->setSource(testFileUrl("singleitem.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QTest::qWaitForWindowShown(canvas);
+ QVERIFY(canvas->rootObject() != 0);
+
+ EventItem *eventItem1 = canvas->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+
+ // Do not accept touch or mouse
+ QPoint p1;
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 1);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 1);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 1);
+ eventItem1->eventList.clear();
+
+ // Accept touch
+ eventItem1->acceptTouch = true;
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 1);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 3);
+ eventItem1->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Accept mouse
+ eventItem1->acceptTouch = false;
+ eventItem1->acceptMouse = true;
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
+ QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
+ QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
+ QCOMPARE(canvasPriv->mouseGrabberItem, eventItem1);
+
+ QPoint localPos = eventItem1->mapFromScene(p1).toPoint();
+ QPoint globalPos = canvas->mapToGlobal(p1);
+ QPoint scenePos = p1; // item is at 0,0
+ QCOMPARE(eventItem1->eventList.at(0).points.at(0).pos().toPoint(), localPos);
+ QCOMPARE(eventItem1->eventList.at(0).points.at(0).scenePos().toPoint(), scenePos);
+ QCOMPARE(eventItem1->eventList.at(0).points.at(0).screenPos().toPoint(), globalPos);
+ QCOMPARE(eventItem1->eventList.at(1).mousePos, localPos);
+ QCOMPARE(eventItem1->eventList.at(1).mousePosGlobal, globalPos);
+
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 4);
+ QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchUpdate);
+ QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseMove);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 6);
+ QCOMPARE(eventItem1->eventList.at(4).type, QEvent::TouchEnd);
+ QCOMPARE(eventItem1->eventList.at(5).type, QEvent::MouseButtonRelease);
+ eventItem1->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Accept mouse buttons but not the event
+ eventItem1->acceptTouch = false;
+ eventItem1->acceptMouse = false;
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
+ QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ eventItem1->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Accept touch and mouse
+ eventItem1->acceptTouch = true;
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 1);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE(eventItem1->eventList.at(1).type, QEvent::TouchUpdate);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchEnd);
+ eventItem1->eventList.clear();
+
+ delete canvas;
+}
+
+void tst_TouchMouse::eventFilter()
+{
+// // install event filter on item and see that it can grab events
+// QQuickView *canvas = createView();
+
+// canvas->setSource(testFileUrl("singleitem.qml"));
+// canvas->show();
+// canvas->requestActivateWindow();
+// QVERIFY(canvas->rootObject() != 0);
+
+// EventItem *eventItem1 = canvas->rootObject()->findChild<EventItem*>("eventItem1");
+// QVERIFY(eventItem1);
+// eventItem1->acceptTouch = true;
+
+// EventItem *filter = new EventItem;
+// filter->filterTouch = true;
+// eventItem1->installEventFilter(filter);
+
+// QPoint p1 = QPoint(20, 20);
+// QTest::touchEvent(canvas, device).press(0, p1, canvas);
+// // QEXPECT_FAIL("", "We do not implement event filters correctly", Abort);
+// QCOMPARE(eventItem1->eventList.size(), 0);
+// QCOMPARE(filter->eventList.size(), 1);
+// QTest::touchEvent(canvas, device).release(0, p1, canvas);
+// QCOMPARE(eventItem1->eventList.size(), 0);
+// QCOMPARE(filter->eventList.size(), 2);
+
+// delete filter;
+// delete canvas;
+}
+
+void tst_TouchMouse::mouse()
+{
+ // eventItem1
+ // - eventItem2
+
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+ QQuickView *canvas = createView();
+
+ canvas->setSource(testFileUrl("twoitems.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QVERIFY(canvas->rootObject() != 0);
+
+ EventItem *eventItem1 = canvas->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+ EventItem *eventItem2 = canvas->rootObject()->findChild<EventItem*>("eventItem2");
+ QVERIFY(eventItem2);
+ QTest::qWaitForWindowShown(canvas);
+
+ // bottom item likes mouse, top likes touch
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ eventItem1->acceptMouse = true;
+ // item 2 doesn't accept anything, thus it sees a touch pass by
+ QPoint p1 = QPoint(30, 30);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
+ QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
+
+ delete canvas;
+}
+
+void tst_TouchMouse::touchOverMouse()
+{
+ // eventItem1
+ // - eventItem2
+
+ QQuickView *canvas = createView();
+
+ canvas->setSource(testFileUrl("twoitems.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QVERIFY(canvas->rootObject() != 0);
+
+ EventItem *eventItem1 = canvas->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+ EventItem *eventItem2 = canvas->rootObject()->findChild<EventItem*>("eventItem2");
+ QVERIFY(eventItem2);
+
+ // bottom item likes mouse, top likes touch
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ eventItem2->acceptTouch = true;
+
+ QTest::qWaitForWindowShown(canvas);
+
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ QPoint p1 = QPoint(20, 20);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ QCOMPARE(eventItem2->eventList.size(), 1);
+ QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas);
+ QCOMPARE(eventItem2->eventList.size(), 2);
+ QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchUpdate);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem2->eventList.size(), 3);
+ QCOMPARE(eventItem2->eventList.at(2).type, QEvent::TouchEnd);
+ eventItem2->eventList.clear();
+
+ delete canvas;
+}
+
+void tst_TouchMouse::mouseOverTouch()
+{
+ // eventItem1
+ // - eventItem2
+
+ QQuickView *canvas = createView();
+
+ canvas->setSource(testFileUrl("twoitems.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QVERIFY(canvas->rootObject() != 0);
+
+ EventItem *eventItem1 = canvas->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+ EventItem *eventItem2 = canvas->rootObject()->findChild<EventItem*>("eventItem2");
+ QVERIFY(eventItem2);
+
+ // bottom item likes mouse, top likes touch
+ eventItem1->acceptTouch = true;
+ eventItem2->setAcceptedMouseButtons(Qt::LeftButton);
+ eventItem2->acceptMouse = true;
+
+ QTest::qWaitForWindowShown(canvas);
+
+ QPoint p1 = QPoint(20, 20);
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ QCOMPARE(eventItem2->eventList.size(), 2);
+ QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
+ QCOMPARE(eventItem2->eventList.at(1).type, QEvent::MouseButtonPress);
+
+
+// p1 += QPoint(10, 0);
+// QTest::touchEvent(canvas, device).move(0, p1, canvas);
+// QCOMPARE(eventItem2->eventList.size(), 1);
+// QTest::touchEvent(canvas, device).release(0, p1, canvas);
+// QCOMPARE(eventItem2->eventList.size(), 1);
+// eventItem2->eventList.clear();
+
+ delete canvas;
+}
+
+void tst_TouchMouse::buttonOnFlickable()
+{
+ // flickable - height 500 / 1000
+ // - eventItem1 y: 100, height 100
+ // - eventItem2 y: 300, height 100
+
+ QQuickView *canvas = createView();
+
+ canvas->setSource(testFileUrl("buttononflickable.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickFlickable *flickable = canvas->rootObject()->findChild<QQuickFlickable*>("flickable");
+ QVERIFY(flickable);
+
+ // should a mouse area button be clickable on top of flickable? yes :)
+ EventItem *eventItem1 = canvas->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ eventItem1->acceptMouse = true;
+
+ // should a touch button be touchable on top of flickable? yes :)
+ EventItem *eventItem2 = canvas->rootObject()->findChild<EventItem*>("eventItem2");
+ QVERIFY(eventItem2);
+ QCOMPARE(eventItem2->eventList.size(), 0);
+ eventItem2->acceptTouch = true;
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // check that buttons are clickable
+ // mouse button
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ QPoint p1 = QPoint(20, 130);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
+ QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 4);
+ QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchEnd);
+ QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseButtonRelease);
+ eventItem1->eventList.clear();
+
+ // touch button
+ p1 = QPoint(10, 310);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem2->eventList.size(), 1);
+ QCOMPARE(eventItem2->eventList.at(0).type, QEvent::TouchBegin);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem2->eventList.size(), 2);
+ QCOMPARE(eventItem2->eventList.at(1).type, QEvent::TouchEnd);
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ eventItem2->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // click above button, no events please
+ p1 = QPoint(10, 90);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ eventItem1->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // check that flickable moves - mouse button
+ QCOMPARE(eventItem1->eventList.size(), 0);
+ p1 = QPoint(10, 110);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
+ QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
+
+ QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
+ QCOMPARE(canvasPriv->touchMouseId, 0);
+ QCOMPARE(canvasPriv->itemForTouchPointId[0], eventItem1);
+ QCOMPARE(canvasPriv->mouseGrabberItem, eventItem1);
+
+ p1 += QPoint(0, -10);
+ QPoint p2 = p1 + QPoint(0, -10);
+ QPoint p3 = p2 + QPoint(0, -10);
+ QTest::qWait(10);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas);
+ QTest::qWait(10);
+ QTest::touchEvent(canvas, device).move(0, p2, canvas);
+ QTest::qWait(10);
+ QTest::touchEvent(canvas, device).move(0, p3, canvas);
+
+ // we cannot really know when the events get grabbed away
+ QVERIFY(eventItem1->eventList.size() >= 4);
+ QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchUpdate);
+ QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseMove);
+
+ QCOMPARE(canvasPriv->mouseGrabberItem, flickable);
+ QVERIFY(flickable->isMovingVertically());
+
+ QTest::touchEvent(canvas, device).release(0, p3, canvas);
+ delete canvas;
+}
+
+void tst_TouchMouse::buttonOnTouch()
+{
+ // 400x800
+ // PinchArea - height 400
+ // - eventItem1 y: 100, height 100
+ // - eventItem2 y: 300, height 100
+ // MultiPointTouchArea - height 400
+ // - eventItem1 y: 100, height 100
+ // - eventItem2 y: 300, height 100
+
+ QQuickView *canvas = createView();
+ canvas->setSource(testFileUrl("buttonontouch.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickPinchArea *pinchArea = canvas->rootObject()->findChild<QQuickPinchArea*>("pincharea");
+ QVERIFY(pinchArea);
+ QQuickItem *button1 = canvas->rootObject()->findChild<QQuickItem*>("button1");
+ QVERIFY(button1);
+ EventItem *eventItem1 = canvas->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+ EventItem *eventItem2 = canvas->rootObject()->findChild<EventItem*>("eventItem2");
+ QVERIFY(eventItem2);
+
+ QQuickMultiPointTouchArea *touchArea = canvas->rootObject()->findChild<QQuickMultiPointTouchArea*>("toucharea");
+ QVERIFY(touchArea);
+ EventItem *eventItem3 = canvas->rootObject()->findChild<EventItem*>("eventItem3");
+ QVERIFY(eventItem3);
+ EventItem *eventItem4 = canvas->rootObject()->findChild<EventItem*>("eventItem4");
+ QVERIFY(eventItem4);
+
+
+ // Test the common case of a mouse area on top of pinch
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ eventItem1->acceptMouse = true;
+
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Normal touch click
+ QPoint p1 = QPoint(10, 110);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QTest::touchEvent(canvas, device).release(0, p1, canvas);
+ QCOMPARE(eventItem1->eventList.size(), 4);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
+ QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
+ QCOMPARE(eventItem1->eventList.at(2).type, QEvent::TouchEnd);
+ QCOMPARE(eventItem1->eventList.at(3).type, QEvent::MouseButtonRelease);
+ eventItem1->eventList.clear();
+
+ // Normal mouse click
+ QTest::mouseClick(canvas, Qt::LeftButton, 0, p1);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::MouseButtonPress);
+ QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonRelease);
+ eventItem1->eventList.clear();
+
+ // Pinch starting on the PinchArea should work
+ p1 = QPoint(40, 10);
+ QPoint p2 = QPoint(60, 10);
+
+ // Start the events after each other
+ QTest::touchEvent(canvas, device).press(0, p1, canvas);
+ QTest::touchEvent(canvas, device).stationary(0).press(1, p2, canvas);
+
+ QCOMPARE(button1->scale(), 1.0);
+
+ // This event seems to be discarded, let's ignore it for now until someone digs into pincharea
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas).move(1, p2, canvas);
+
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas).move(1, p2, canvas);
+// QCOMPARE(button1->scale(), 1.5);
+ qDebug() << "Button scale: " << button1->scale();
+
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas).move(1, p2, canvas);
+// QCOMPARE(button1->scale(), 2.0);
+ qDebug() << "Button scale: " << button1->scale();
+
+ QTest::touchEvent(canvas, device).release(0, p1, canvas).release(1, p2, canvas);
+// QVERIFY(eventItem1->eventList.isEmpty());
+// QCOMPARE(button1->scale(), 2.0);
+ qDebug() << "Button scale: " << button1->scale();
+
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Start pinching while on the button
+ button1->setScale(1.0);
+ p1 = QPoint(40, 110);
+ p2 = QPoint(60, 110);
+ QTest::touchEvent(canvas, device).press(0, p1, canvas).press(1, p2, canvas);
+ QCOMPARE(button1->scale(), 1.0);
+ QCOMPARE(eventItem1->eventList.count(), 2);
+ QCOMPARE(eventItem1->eventList.at(0).type, QEvent::TouchBegin);
+ QCOMPARE(eventItem1->eventList.at(1).type, QEvent::MouseButtonPress);
+
+ // This event seems to be discarded, let's ignore it for now until someone digs into pincharea
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas).move(1, p2, canvas);
+
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas).move(1, p2, canvas);
+ //QCOMPARE(button1->scale(), 1.5);
+ qDebug() << button1->scale();
+
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p1, canvas).move(1, p2, canvas);
+ qDebug() << button1->scale();
+ //QCOMPARE(button1->scale(), 2.0);
+
+ QTest::touchEvent(canvas, device).release(0, p1, canvas).release(1, p2, canvas);
+// QCOMPARE(eventItem1->eventList.size(), 99);
+ qDebug() << button1->scale();
+ //QCOMPARE(button1->scale(), 2.0);
+
+ delete canvas;
+}
+
+void tst_TouchMouse::pinchOnFlickable()
+{
+ QQuickView *canvas = createView();
+ canvas->setSource(testFileUrl("pinchonflickable.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickPinchArea *pinchArea = canvas->rootObject()->findChild<QQuickPinchArea*>("pincharea");
+ QVERIFY(pinchArea);
+ QQuickFlickable *flickable = canvas->rootObject()->findChild<QQuickFlickable*>("flickable");
+ QVERIFY(flickable);
+ QQuickItem *rect = canvas->rootObject()->findChild<QQuickItem*>("rect");
+ QVERIFY(rect);
+
+ // flickable - single touch point
+ QVERIFY(flickable->contentX() == 0.0);
+ QPoint p = QPoint(100, 100);
+ QTest::touchEvent(canvas, device).press(0, p, canvas);
+ QCOMPARE(rect->pos(), QPointF(200.0, 200.0));
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+ QTest::qWait(10);
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+ QTest::qWait(10);
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+ QTest::touchEvent(canvas, device).release(0, p, canvas);
+
+ QGuiApplication::processEvents();
+ QTest::qWait(10);
+ QVERIFY(!flickable->isAtXBeginning());
+ // wait until flicking is done
+ QTRY_VERIFY(!flickable->isFlicking());
+
+ // pinch
+ QPoint p1 = QPoint(40, 20);
+ QPoint p2 = QPoint(60, 20);
+
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(canvas, device);
+ pinchSequence.press(0, p1, canvas).commit();
+ // In order for the stationary point to remember its previous position,
+ // we have to reuse the same pinchSequence object. Otherwise if we let it
+ // be destroyed and then start a new sequence, point 0 will default to being
+ // stationary at 0, 0, and PinchArea will filter out that touchpoint because
+ // it is outside its bounds.
+ pinchSequence.stationary(0).press(1, p2, canvas).commit();
+ p1 -= QPoint(10,10);
+ p2 += QPoint(10,10);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ QCOMPARE(rect->scale(), 1.0);
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ pinchSequence.release(0, p1, canvas).release(1, p2, canvas).commit();
+ QVERIFY(rect->scale() > 1.0);
+}
+
+void tst_TouchMouse::flickableOnPinch()
+{
+ QQuickView *canvas = createView();
+ canvas->setSource(testFileUrl("flickableonpinch.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickPinchArea *pinchArea = canvas->rootObject()->findChild<QQuickPinchArea*>("pincharea");
+ QVERIFY(pinchArea);
+ QQuickFlickable *flickable = canvas->rootObject()->findChild<QQuickFlickable*>("flickable");
+ QVERIFY(flickable);
+ QQuickItem *rect = canvas->rootObject()->findChild<QQuickItem*>("rect");
+ QVERIFY(rect);
+
+ // flickable - single touch point
+ QVERIFY(flickable->contentX() == 0.0);
+ QPoint p = QPoint(100, 100);
+ QTest::touchEvent(canvas, device).press(0, p, canvas);
+ QCOMPARE(rect->pos(), QPointF(200.0, 200.0));
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+
+ QTest::qWait(1000);
+
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+ QTest::touchEvent(canvas, device).release(0, p, canvas);
+
+ QTest::qWait(1000);
+
+ //QVERIFY(flickable->isMovingHorizontally());
+ qDebug() << "Pos: " << rect->pos();
+ // wait until flicking is done
+ QTRY_VERIFY(!flickable->isFlicking());
+
+ // pinch
+ QPoint p1 = QPoint(40, 20);
+ QPoint p2 = QPoint(60, 20);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(canvas, device);
+ pinchSequence.press(0, p1, canvas).commit();
+ // In order for the stationary point to remember its previous position,
+ // we have to reuse the same pinchSequence object. Otherwise if we let it
+ // be destroyed and then start a new sequence, point 0 will default to being
+ // stationary at 0, 0, and PinchArea will filter out that touchpoint because
+ // it is outside its bounds.
+ pinchSequence.stationary(0).press(1, p2, canvas).commit();
+ p1 -= QPoint(10,10);
+ p2 += QPoint(10,10);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ QCOMPARE(rect->scale(), 1.0);
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ pinchSequence.release(0, p1, canvas).release(1, p2, canvas).commit();
+ QVERIFY(rect->scale() > 1.0);
+}
+
+void tst_TouchMouse::mouseOnFlickableOnPinch()
+{
+ QQuickView *canvas = createView();
+ canvas->setSource(testFileUrl("mouseonflickableonpinch.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QVERIFY(canvas->rootObject() != 0);
+
+ QQuickPinchArea *pinchArea = canvas->rootObject()->findChild<QQuickPinchArea*>("pincharea");
+ QVERIFY(pinchArea);
+ QQuickFlickable *flickable = canvas->rootObject()->findChild<QQuickFlickable*>("flickable");
+ QVERIFY(flickable);
+ QQuickItem *rect = canvas->rootObject()->findChild<QQuickItem*>("rect");
+ QVERIFY(rect);
+
+ // flickable - single touch point
+ QVERIFY(flickable->contentX() == 0.0);
+ QPoint p = QPoint(100, 100);
+ QTest::touchEvent(canvas, device).press(0, p, canvas);
+ QCOMPARE(rect->pos(), QPointF(200.0, 200.0));
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+
+ QTest::qWait(1000);
+
+ p -= QPoint(10, 0);
+ QTest::touchEvent(canvas, device).move(0, p, canvas);
+ QTest::touchEvent(canvas, device).release(0, p, canvas);
+
+ QTest::qWait(1000);
+
+ //QVERIFY(flickable->isMovingHorizontally());
+ qDebug() << "Pos: " << rect->pos();
+
+ // pinch
+ QPoint p1 = QPoint(40, 20);
+ QPoint p2 = QPoint(60, 20);
+ QTest::QTouchEventSequence pinchSequence = QTest::touchEvent(canvas, device);
+ pinchSequence.press(0, p1, canvas).commit();
+ // In order for the stationary point to remember its previous position,
+ // we have to reuse the same pinchSequence object. Otherwise if we let it
+ // be destroyed and then start a new sequence, point 0 will default to being
+ // stationary at 0, 0, and PinchArea will filter out that touchpoint because
+ // it is outside its bounds.
+ pinchSequence.stationary(0).press(1, p2, canvas).commit();
+ p1 -= QPoint(10,10);
+ p2 += QPoint(10,10);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ QCOMPARE(rect->scale(), 1.0);
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ p1 -= QPoint(10, 0);
+ p2 += QPoint(10, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ pinchSequence.release(0, p1, canvas).release(1, p2, canvas).commit();
+ QVERIFY(rect->scale() > 1.0);
+
+ // PinchArea should steal the event after flicking started
+ rect->setScale(1.0);
+ flickable->setContentX(0.0);
+ p = QPoint(100, 100);
+ pinchSequence.press(0, p, canvas).commit();
+ QCOMPARE(rect->pos(), QPointF(200.0, 200.0));
+ p -= QPoint(10, 0);
+ pinchSequence.move(0, p, canvas).commit();
+ p -= QPoint(10, 0);
+ pinchSequence.move(0, p, canvas).commit();
+ QTest::qWait(1000);
+ p -= QPoint(10, 0);
+ pinchSequence.move(0, p, canvas).commit();
+
+ QQuickCanvasPrivate *canvasPriv = QQuickCanvasPrivate::get(canvas);
+ QCOMPARE(canvasPriv->mouseGrabberItem, flickable);
+ qDebug() << "Mouse Grabber: " << canvasPriv->mouseGrabberItem << " itemForTouchPointId: " << canvasPriv->itemForTouchPointId;
+
+ // Add a second finger, this should lead to stealing
+ p1 = QPoint(40, 100);
+ p2 = QPoint(60, 100);
+ pinchSequence.stationary(0).press(1, p2, canvas).commit();
+ QCOMPARE(rect->scale(), 1.0);
+
+ p1 -= QPoint(5, 0);
+ p2 += QPoint(5, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ p1 -= QPoint(5, 0);
+ p2 += QPoint(5, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ p1 -= QPoint(5, 0);
+ p2 += QPoint(5, 0);
+ pinchSequence.move(0, p1, canvas).move(1, p2, canvas).commit();
+ pinchSequence.release(0, p1, canvas).release(1, p2, canvas).commit();
+ QVERIFY(rect->scale() > 1.0);
+ pinchSequence.release(0, p, canvas).commit();
+}
+
+QTEST_MAIN(tst_TouchMouse)
+
+#include "tst_touchmouse.moc"
+