MultiPointTouchArea autotest checks touch events with transformations
[profile/ivi/qtdeclarative.git] / tests / auto / quick / qquickmultipointtoucharea / tst_qquickmultipointtoucharea.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QtTest/QtTest>
43 #include <QtTest/QSignalSpy>
44 #include <qpa/qwindowsysteminterface.h>
45 #include <private/qquickmultipointtoucharea_p.h>
46 #include <private/qquickflickable_p.h>
47 #include <QtQuick/qquickview.h>
48 #include "../../shared/util.h"
49
50 class tst_QQuickMultiPointTouchArea : public QQmlDataTest
51 {
52     Q_OBJECT
53 public:
54     tst_QQuickMultiPointTouchArea() : device(0) { }
55 private slots:
56     void initTestCase() {
57         QQmlDataTest::initTestCase();
58         if (!device) {
59             device = new QTouchDevice;
60             device->setType(QTouchDevice::TouchScreen);
61             QWindowSystemInterface::registerTouchDevice(device);
62         }
63     }
64     void cleanupTestCase() {}
65
66     void properties();
67     void signalTest();
68     void release();
69     void reuse();
70     void nonOverlapping();
71     void nested();
72     void inFlickable();
73     void inFlickable2();
74     void invisible();
75     void transformedTouchArea_data();
76     void transformedTouchArea();
77
78 private:
79     QQuickView *createAndShowView(const QString &file);
80     QTouchDevice *device;
81 };
82
83 void tst_QQuickMultiPointTouchArea::properties()
84 {
85     QQuickView *canvas = createAndShowView("properties.qml");
86     QVERIFY(canvas->rootObject() != 0);
87
88     QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(canvas->rootObject());
89     QVERIFY(area != 0);
90
91     QCOMPARE(area->minimumTouchPoints(), 2);
92     QCOMPARE(area->maximumTouchPoints(), 4);
93
94     QQmlListReference ref(area, "touchPoints");
95     QCOMPARE(ref.count(), 4);
96
97     delete canvas;
98 }
99
100 void tst_QQuickMultiPointTouchArea::signalTest()
101 {
102     QQuickView *canvas = createAndShowView("signalTest.qml");
103     QVERIFY(canvas->rootObject() != 0);
104
105     QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(canvas->rootObject());
106     QVERIFY(area != 0);
107
108     QPoint p1(20,100);
109     QPoint p2(40,100);
110     QPoint p3(60,100);
111     QPoint p4(80,100);
112     QPoint p5(100,100);
113
114     QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas, device);
115
116     sequence.press(0, p1).press(1, p2).commit();
117
118     QCOMPARE(area->property("touchPointPressCount").toInt(), 2);
119     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
120     QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
121     QCOMPARE(area->property("touchCount").toInt(), 2);
122     QMetaObject::invokeMethod(area, "clearCounts");
123
124     sequence.stationary(0).stationary(1).press(2, p3).commit();
125
126     QCOMPARE(area->property("touchPointPressCount").toInt(), 1);
127     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
128     QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
129     QCOMPARE(area->property("touchCount").toInt(), 3);
130     QMetaObject::invokeMethod(area, "clearCounts");
131
132     p1 -= QPoint(10,10);
133     p2 += QPoint(10,10);
134     sequence.move(0, p1).move(1, p2).stationary(2).commit();
135
136     QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
137     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 2);
138     QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
139     QCOMPARE(area->property("touchCount").toInt(), 3);
140     QMetaObject::invokeMethod(area, "clearCounts");
141
142     p3 += QPoint(10,10);
143     sequence.release(0, p1).release(1, p2)
144             .move(2, p3).press(3, p4).press(4, p5).commit();
145
146     QCOMPARE(area->property("touchPointPressCount").toInt(), 2);
147     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 1);
148     QCOMPARE(area->property("touchPointReleaseCount").toInt(), 2);
149     QCOMPARE(area->property("touchCount").toInt(), 3);
150     QMetaObject::invokeMethod(area, "clearCounts");
151
152     sequence.release(2, p3).release(3, p4).release(4, p5).commit();
153
154     QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
155     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
156     QCOMPARE(area->property("touchPointReleaseCount").toInt(), 3);
157     QCOMPARE(area->property("touchCount").toInt(), 0);
158     QCOMPARE(area->property("touchUpdatedHandled").toBool(), true);
159     QMetaObject::invokeMethod(area, "clearCounts");
160
161     delete canvas;
162 }
163
164 void tst_QQuickMultiPointTouchArea::release()
165 {
166     QQuickView *canvas = createAndShowView("basic.qml");
167     QVERIFY(canvas->rootObject() != 0);
168
169     QQuickTouchPoint *point1 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point1");
170
171     QCOMPARE(point1->pressed(), false);
172
173     QPoint p1(20,100);
174
175     QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas, device);
176
177     sequence.press(0, p1).commit();
178
179     QCOMPARE(point1->pressed(), true);
180
181     p1 += QPoint(0,10);
182
183     sequence.move(0, p1).commit();
184
185     QCOMPARE(point1->pressed(), true);
186     QCOMPARE(point1->x(), qreal(20)); QCOMPARE(point1->y(), qreal(110));
187
188     p1 += QPoint(4,10);
189
190     sequence.release(0, p1).commit();
191
192     //test that a release without a prior move to the release position successfully updates the point's position
193     QCOMPARE(point1->pressed(), false);
194     QCOMPARE(point1->x(), qreal(24)); QCOMPARE(point1->y(), qreal(120));
195
196     delete canvas;
197 }
198
199 void tst_QQuickMultiPointTouchArea::reuse()
200 {
201     QQuickView *canvas = createAndShowView("basic.qml");
202     QVERIFY(canvas->rootObject() != 0);
203
204     QQuickTouchPoint *point1 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point1");
205     QQuickTouchPoint *point2 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point2");
206     QQuickTouchPoint *point3 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point3");
207
208     QCOMPARE(point1->pressed(), false);
209     QCOMPARE(point2->pressed(), false);
210
211     QPoint p1(20,100);
212     QPoint p2(40,100);
213     QPoint p3(60,100);
214     QPoint p4(80,100);
215
216     QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas, device);
217
218     sequence.press(0, p1).press(1, p2).commit();
219
220     QCOMPARE(point1->pressed(), true);
221     QCOMPARE(point2->pressed(), true);
222     QCOMPARE(point3->pressed(), false);
223
224     sequence.release(0, p1).stationary(1).press(2, p3).commit();
225
226     //we shouldn't reuse point 1 yet
227     QCOMPARE(point1->pressed(), false);
228     QCOMPARE(point2->pressed(), true);
229     QCOMPARE(point3->pressed(), true);
230
231     //back to base state (no touches)
232     sequence.release(1, p2).release(2, p3).commit();
233
234     QCOMPARE(point1->pressed(), false);
235     QCOMPARE(point2->pressed(), false);
236     QCOMPARE(point3->pressed(), false);
237
238     sequence.press(0, p1).press(1, p2).commit();
239
240     QCOMPARE(point1->pressed(), true);
241     QCOMPARE(point2->pressed(), true);
242     QCOMPARE(point3->pressed(), false);
243
244     sequence.release(0, p1).stationary(1).commit();
245
246     QCOMPARE(point1->pressed(), false);
247     QCOMPARE(point2->pressed(), true);
248     QCOMPARE(point3->pressed(), false);
249
250     sequence.press(4, p4).stationary(1).commit();
251
252     //the new touch point should reuse point 1
253     QCOMPARE(point1->pressed(), true);
254     QCOMPARE(point2->pressed(), true);
255     QCOMPARE(point3->pressed(), false);
256
257     QCOMPARE(point1->x(), qreal(80)); QCOMPARE(point1->y(), qreal(100));
258
259     delete canvas;
260 }
261
262 void tst_QQuickMultiPointTouchArea::nonOverlapping()
263 {
264     QQuickView *canvas = createAndShowView("nonOverlapping.qml");
265     QVERIFY(canvas->rootObject() != 0);
266
267     QQuickTouchPoint *point11 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point11");
268     QQuickTouchPoint *point12 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point12");
269     QQuickTouchPoint *point21 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point21");
270     QQuickTouchPoint *point22 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point22");
271     QQuickTouchPoint *point23 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point23");
272
273     QCOMPARE(point11->pressed(), false);
274     QCOMPARE(point12->pressed(), false);
275     QCOMPARE(point21->pressed(), false);
276     QCOMPARE(point22->pressed(), false);
277     QCOMPARE(point23->pressed(), false);
278
279     QPoint p1(20,100);
280     QPoint p2(40,100);
281     QPoint p3(60,180);
282     QPoint p4(80,180);
283     QPoint p5(100,180);
284
285     QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas, device);
286
287     sequence.press(0, p1).commit();
288
289     QCOMPARE(point11->pressed(), false);
290     QCOMPARE(point12->pressed(), false);
291     QCOMPARE(point21->pressed(), false);
292     QCOMPARE(point22->pressed(), false);
293     QCOMPARE(point23->pressed(), false);
294
295     sequence.stationary(0).press(1, p2).commit();
296
297     QCOMPARE(point11->pressed(), true);
298     QCOMPARE(point12->pressed(), true);
299     QCOMPARE(point21->pressed(), false);
300     QCOMPARE(point22->pressed(), false);
301     QCOMPARE(point23->pressed(), false);
302
303     QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100));
304     QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100));
305
306     p1 += QPoint(0,10);
307     p2 += QPoint(5,0);
308     sequence.move(0, p1).move(1, p2).commit();
309
310     QCOMPARE(point11->pressed(), true);
311     QCOMPARE(point12->pressed(), true);
312     QCOMPARE(point21->pressed(), false);
313     QCOMPARE(point22->pressed(), false);
314     QCOMPARE(point23->pressed(), false);
315
316     QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
317     QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
318
319     sequence.stationary(0).stationary(1).press(2, p3).commit();
320
321     QCOMPARE(point11->pressed(), true);
322     QCOMPARE(point12->pressed(), true);
323     QCOMPARE(point21->pressed(), false);
324     QCOMPARE(point22->pressed(), false);
325     QCOMPARE(point23->pressed(), false);
326
327     sequence.stationary(0).stationary(1).stationary(2).press(3, p4).press(4, p5).commit();
328
329     QCOMPARE(point11->pressed(), true);
330     QCOMPARE(point12->pressed(), true);
331     QCOMPARE(point21->pressed(), true);
332     QCOMPARE(point22->pressed(), true);
333     QCOMPARE(point23->pressed(), true);
334
335     QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
336     QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
337     QCOMPARE(point21->x(), qreal(60)); QCOMPARE(point21->y(), qreal(20));
338     QCOMPARE(point22->x(), qreal(80)); QCOMPARE(point22->y(), qreal(20));
339     QCOMPARE(point23->x(), qreal(100)); QCOMPARE(point23->y(), qreal(20));
340
341     p1 += QPoint(4,10);
342     p2 += QPoint(17,17);
343     p3 += QPoint(3,0);
344     p4 += QPoint(1,-1);
345     p5 += QPoint(-7,10);
346     sequence.move(0, p1).move(1, p2).move(2, p3).move(3, p4).move(4, p5).commit();
347
348     QCOMPARE(point11->pressed(), true);
349     QCOMPARE(point12->pressed(), true);
350     QCOMPARE(point21->pressed(), true);
351     QCOMPARE(point22->pressed(), true);
352     QCOMPARE(point23->pressed(), true);
353
354     QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120));
355     QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117));
356     QCOMPARE(point21->x(), qreal(63)); QCOMPARE(point21->y(), qreal(20));
357     QCOMPARE(point22->x(), qreal(81)); QCOMPARE(point22->y(), qreal(19));
358     QCOMPARE(point23->x(), qreal(93)); QCOMPARE(point23->y(), qreal(30));
359
360     sequence.release(0, p1).release(1, p2).release(2, p3).release(3, p4).release(4, p5).commit();
361
362     QCOMPARE(point11->pressed(), false);
363     QCOMPARE(point12->pressed(), false);
364     QCOMPARE(point21->pressed(), false);
365     QCOMPARE(point22->pressed(), false);
366     QCOMPARE(point23->pressed(), false);
367
368     delete canvas;
369 }
370
371 void tst_QQuickMultiPointTouchArea::nested()
372 {
373     QQuickView *canvas = createAndShowView("nested.qml");
374     QVERIFY(canvas->rootObject() != 0);
375
376     QQuickTouchPoint *point11 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point11");
377     QQuickTouchPoint *point12 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point12");
378     QQuickTouchPoint *point21 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point21");
379     QQuickTouchPoint *point22 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point22");
380     QQuickTouchPoint *point23 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point23");
381
382     QCOMPARE(point11->pressed(), false);
383     QCOMPARE(point12->pressed(), false);
384     QCOMPARE(point21->pressed(), false);
385     QCOMPARE(point22->pressed(), false);
386     QCOMPARE(point23->pressed(), false);
387
388     QPoint p1(20,100);
389     QPoint p2(40,100);
390     QPoint p3(60,180);
391
392     QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas, device);
393
394     sequence.press(0, p1).commit();
395
396     QCOMPARE(point11->pressed(), false);
397     QCOMPARE(point12->pressed(), false);
398     QCOMPARE(point21->pressed(), false);
399     QCOMPARE(point22->pressed(), false);
400     QCOMPARE(point23->pressed(), false);
401
402     sequence.stationary(0).press(1, p2).commit();
403
404     QCOMPARE(point11->pressed(), true);
405     QCOMPARE(point12->pressed(), true);
406     QCOMPARE(point21->pressed(), false);
407     QCOMPARE(point22->pressed(), false);
408     QCOMPARE(point23->pressed(), false);
409
410     QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100));
411     QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100));
412
413     p1 += QPoint(0,10);
414     p2 += QPoint(5,0);
415     sequence.move(0, p1).move(1, p2).commit();
416
417     QCOMPARE(point11->pressed(), true);
418     QCOMPARE(point12->pressed(), true);
419     QCOMPARE(point21->pressed(), false);
420     QCOMPARE(point22->pressed(), false);
421     QCOMPARE(point23->pressed(), false);
422
423     QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
424     QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
425
426     sequence.stationary(0).stationary(1).press(2, p3).commit();
427
428     QCOMPARE(point11->pressed(), true);
429     QCOMPARE(point12->pressed(), true);
430     QCOMPARE(point21->pressed(), true);
431     QCOMPARE(point22->pressed(), true);
432     QCOMPARE(point23->pressed(), true);
433
434     //point11 should be same as point21, point12 same as point22
435     QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
436     QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
437     QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110));
438     QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100));
439     QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
440
441     sequence.stationary(0).stationary(1).stationary(2).press(3, QPoint(80,180)).press(4, QPoint(100,180)).commit();
442
443     QCOMPARE(point11->pressed(), true);
444     QCOMPARE(point12->pressed(), true);
445     QCOMPARE(point21->pressed(), true);
446     QCOMPARE(point22->pressed(), true);
447     QCOMPARE(point23->pressed(), true);
448
449     //new touch points should be ignored (have no impact on our existing touch points)
450     QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
451     QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
452     QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110));
453     QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100));
454     QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
455
456     sequence.stationary(0).stationary(1).stationary(2).release(3, QPoint(80,180)).release(4, QPoint(100,180)).commit();
457
458     p1 += QPoint(4,10);
459     p2 += QPoint(17,17);
460     p3 += QPoint(3,0);
461     sequence.move(0, p1).move(1, p2).move(2, p3).commit();
462
463     QCOMPARE(point11->pressed(), true);
464     QCOMPARE(point12->pressed(), true);
465     QCOMPARE(point21->pressed(), true);
466     QCOMPARE(point22->pressed(), true);
467     QCOMPARE(point23->pressed(), true);
468
469     QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120));
470     QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117));
471     QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120));
472     QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117));
473     QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180));
474
475     p1 += QPoint(4,10);
476     p2 += QPoint(17,17);
477     p3 += QPoint(3,0);
478     sequence.move(0, p1).move(1, p2).move(2, p3).commit();
479
480     QCOMPARE(point11->pressed(), false);
481     QCOMPARE(point12->pressed(), false);
482     QCOMPARE(point21->pressed(), true);
483     QCOMPARE(point22->pressed(), true);
484     QCOMPARE(point23->pressed(), true);
485
486     //first two remain the same (touches now grabbed by inner touch area)
487     QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120));
488     QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117));
489     QCOMPARE(point21->x(), qreal(28)); QCOMPARE(point21->y(), qreal(130));
490     QCOMPARE(point22->x(), qreal(79)); QCOMPARE(point22->y(), qreal(134));
491     QCOMPARE(point23->x(), qreal(66)); QCOMPARE(point23->y(), qreal(180));
492
493     sequence.release(0, p1).release(1, p2).release(2, p3).commit();
494
495     sequence.press(0, p1).commit();
496
497     QCOMPARE(point11->pressed(), false);
498     QCOMPARE(point12->pressed(), false);
499     QCOMPARE(point21->pressed(), false);
500     QCOMPARE(point22->pressed(), false);
501     QCOMPARE(point23->pressed(), false);
502
503     sequence.release(0, p1).commit();
504
505     //test with grabbing turned off
506     canvas->rootObject()->setProperty("grabInnerArea", false);
507
508     sequence.press(0, p1).press(1, p2).press(2, p3).commit();
509
510     QCOMPARE(point11->pressed(), true);
511     QCOMPARE(point12->pressed(), true);
512     QCOMPARE(point21->pressed(), true);
513     QCOMPARE(point22->pressed(), true);
514     QCOMPARE(point23->pressed(), true);
515
516     p1 -= QPoint(4,10);
517     p2 -= QPoint(17,17);
518     p3 -= QPoint(3,0);
519     sequence.move(0, p1).move(1, p2).move(2, p3).commit();
520
521     QCOMPARE(point11->pressed(), true);
522     QCOMPARE(point12->pressed(), true);
523     QCOMPARE(point21->pressed(), true);
524     QCOMPARE(point22->pressed(), true);
525     QCOMPARE(point23->pressed(), true);
526
527     QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120));
528     QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117));
529     QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120));
530     QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117));
531     QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180));
532
533     p1 -= QPoint(4,10);
534     p2 -= QPoint(17,17);
535     p3 -= QPoint(3,0);
536     sequence.move(0, p1).move(1, p2).move(2, p3).commit();
537
538     QCOMPARE(point11->pressed(), true);
539     QCOMPARE(point12->pressed(), true);
540     QCOMPARE(point21->pressed(), true);
541     QCOMPARE(point22->pressed(), true);
542     QCOMPARE(point23->pressed(), true);
543
544     //all change (touches not grabbed by inner touch area)
545     QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110));
546     QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100));
547     QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110));
548     QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100));
549     QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180));
550
551     sequence.release(0, p1).release(1, p2).release(2, p3).commit();
552
553     delete canvas;
554 }
555
556 void tst_QQuickMultiPointTouchArea::inFlickable()
557 {
558     QQuickView *canvas = createAndShowView("inFlickable.qml");
559     QVERIFY(canvas->rootObject() != 0);
560
561     QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(canvas->rootObject());
562     QVERIFY(flickable != 0);
563
564     QQuickTouchPoint *point11 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point1");
565     QQuickTouchPoint *point12 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point2");
566
567     QCOMPARE(point11->pressed(), false);
568     QCOMPARE(point12->pressed(), false);
569
570     QPoint p1(20,100);
571     QPoint p2(40,100);
572
573     //moving one point vertically
574     QTest::touchEvent(canvas, device).press(0, p1);
575
576     p1 += QPoint(0,15);
577     QTest::touchEvent(canvas, device).move(0, p1);
578
579     p1 += QPoint(0,15);
580     QTest::touchEvent(canvas, device).move(0, p1);
581
582     p1 += QPoint(0,15);
583     QTest::touchEvent(canvas, device).move(0, p1);
584
585     p1 += QPoint(0,15);
586     QTest::touchEvent(canvas, device).move(0, p1);
587
588     QVERIFY(flickable->contentY() < 0);
589     QCOMPARE(point11->pressed(), false);
590     QCOMPARE(point12->pressed(), false);
591
592     QTest::touchEvent(canvas, device).release(0, p1);
593     QTest::qWait(50);
594
595     QTRY_VERIFY(!flickable->isMoving());
596
597     //moving two points vertically
598     p1 = QPoint(20,100);
599     QTest::touchEvent(canvas, device).press(0, p1).press(1, p2);
600     QTest::mousePress(canvas, Qt::LeftButton, 0, p1);
601
602     QCOMPARE(point11->pressed(), true);
603     QCOMPARE(point12->pressed(), true);
604     QCOMPARE(flickable->property("cancelCount").toInt(), 0);
605     QCOMPARE(flickable->property("touchCount").toInt(), 2);
606
607     p1 += QPoint(0,15); p2 += QPoint(0,15);
608     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
609     QTest::mouseMove(canvas, p1);
610
611     p1 += QPoint(0,15); p2 += QPoint(0,15);
612     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
613     QTest::mouseMove(canvas, p1);
614
615     p1 += QPoint(0,15); p2 += QPoint(0,15);
616     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
617     QTest::mouseMove(canvas, p1);
618
619     p1 += QPoint(0,15); p2 += QPoint(0,15);
620     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
621     QTest::mouseMove(canvas, p1);
622
623     QVERIFY(flickable->contentY() < 0);
624     QCOMPARE(point11->pressed(), false);
625     QCOMPARE(point12->pressed(), false);
626     QCOMPARE(flickable->property("cancelCount").toInt(), 2);
627     QCOMPARE(flickable->property("touchCount").toInt(), 0);
628
629     QTest::touchEvent(canvas, device).release(0, p1).release(1, p2);
630     QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1);
631     QTest::qWait(50);
632
633     QTRY_VERIFY(!flickable->isMoving());
634
635     //moving two points horizontally, then one point vertically
636     p1 = QPoint(20,100);
637     p2 = QPoint(40,100);
638     QTest::touchEvent(canvas, device).press(0, p1).press(1, p2);
639     QTest::mousePress(canvas, Qt::LeftButton, 0, p1);
640
641     QCOMPARE(point11->pressed(), true);
642     QCOMPARE(point12->pressed(), true);
643
644     p1 += QPoint(15,0); p2 += QPoint(15,0);
645     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
646     QTest::mouseMove(canvas, p1);
647
648     p1 += QPoint(15,0); p2 += QPoint(15,0);
649     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
650     QTest::mouseMove(canvas, p1);
651
652     p1 += QPoint(15,0); p2 += QPoint(15,0);
653     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
654     QTest::mouseMove(canvas, p1);
655
656     p1 += QPoint(15,0); p2 += QPoint(15,0);
657     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
658     QTest::mouseMove(canvas, p1);
659
660     p1 += QPoint(0,15); p2 += QPoint(0,15);
661     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
662     QTest::mouseMove(canvas, p1);
663
664     p1 += QPoint(0,15); p2 += QPoint(0,15);
665     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
666     QTest::mouseMove(canvas, p1);
667
668     p1 += QPoint(0,15); p2 += QPoint(0,15);
669     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
670     QTest::mouseMove(canvas, p1);
671
672     p1 += QPoint(0,15); p2 += QPoint(0,15);
673     QTest::touchEvent(canvas, device).move(0, p1).move(1, p2);
674     QTest::mouseMove(canvas, p1);
675
676     QVERIFY(flickable->contentY() == 0);
677     QCOMPARE(point11->pressed(), true);
678     QCOMPARE(point12->pressed(), true);
679
680     QTest::touchEvent(canvas, device).release(0, p1).release(1, p2);
681     QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1);
682     QTest::qWait(50);
683
684     delete canvas;
685 }
686
687 // test that dragging out of a Flickable containing a MPTA doesn't harm Flickable's state.
688 void tst_QQuickMultiPointTouchArea::inFlickable2()
689 {
690     QQuickView *canvas = createAndShowView("inFlickable2.qml");
691     QVERIFY(canvas->rootObject() != 0);
692
693     QQuickFlickable *flickable = canvas->rootObject()->findChild<QQuickFlickable*>("flickable");
694     QVERIFY(flickable != 0);
695
696     QQuickTouchPoint *point11 = canvas->rootObject()->findChild<QQuickTouchPoint*>("point1");
697     QVERIFY(point11);
698
699     QCOMPARE(point11->pressed(), false);
700
701     QPoint p1(50,100);
702
703     // move point horizontally, out of Flickable area
704     QTest::touchEvent(canvas, device).press(0, p1);
705     QTest::mousePress(canvas, Qt::LeftButton, 0, p1);
706
707     p1 += QPoint(15,0);
708     QTest::touchEvent(canvas, device).move(0, p1);
709     QTest::mouseMove(canvas, p1);
710
711     p1 += QPoint(15,0);
712     QTest::touchEvent(canvas, device).move(0, p1);
713     QTest::mouseMove(canvas, p1);
714
715     p1 += QPoint(15,0);
716     QTest::touchEvent(canvas, device).move(0, p1);
717     QTest::mouseMove(canvas, p1);
718
719     p1 += QPoint(15,0);
720     QTest::touchEvent(canvas, device).move(0, p1);
721     QTest::mouseMove(canvas, p1);
722
723     QVERIFY(!flickable->isMoving());
724     QVERIFY(point11->pressed());
725
726     QTest::touchEvent(canvas, device).release(0, p1);
727     QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1);
728     QTest::qWait(50);
729
730     QTRY_VERIFY(!flickable->isMoving());
731
732     // Check that we can still move the Flickable
733     p1 = QPoint(50,100);
734     QTest::touchEvent(canvas, device).press(0, p1);
735
736     QCOMPARE(point11->pressed(), true);
737
738     p1 += QPoint(0,15);
739     QTest::touchEvent(canvas, device).move(0, p1);
740
741     p1 += QPoint(0,15);
742     QTest::touchEvent(canvas, device).move(0, p1);
743
744     p1 += QPoint(0,15);
745     QTest::touchEvent(canvas, device).move(0, p1);
746
747     p1 += QPoint(0,15);
748     QTest::touchEvent(canvas, device).move(0, p1);
749
750     QVERIFY(flickable->contentY() < 0);
751     QVERIFY(flickable->isMoving());
752     QCOMPARE(point11->pressed(), true);
753
754     QTest::touchEvent(canvas, device).release(0, p1);
755     QTest::qWait(50);
756
757     QTRY_VERIFY(!flickable->isMoving());
758
759
760     delete canvas;
761 }
762
763 // QTBUG-23327
764 void tst_QQuickMultiPointTouchArea::invisible()
765 {
766     QQuickView *canvas = createAndShowView("signalTest.qml");
767     QVERIFY(canvas->rootObject() != 0);
768
769     QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(canvas->rootObject());
770     QVERIFY(area != 0);
771
772     area->setVisible(false);
773
774     QPoint p1(20,100);
775     QPoint p2(40,100);
776
777     QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas, device);
778
779     sequence.press(0, p1).press(1, p2).commit();
780
781     QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
782     QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
783     QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
784     QCOMPARE(area->property("touchCount").toInt(), 0);
785
786     delete canvas;
787 }
788
789 void tst_QQuickMultiPointTouchArea::transformedTouchArea_data()
790 {
791     QTest::addColumn<QPoint>("p1");
792     QTest::addColumn<QPoint>("p2");
793     QTest::addColumn<QPoint>("p3");
794     QTest::addColumn<int>("total1");
795     QTest::addColumn<int>("total2");
796     QTest::addColumn<int>("total3");
797
798     QTest::newRow("1st point inside")
799         << QPoint(140, 200) << QPoint(260, 260) << QPoint(0, 140) << 1 << 1 << 1;
800
801     QTest::newRow("2nd point inside")
802         << QPoint(260, 260) << QPoint(200, 200) << QPoint(0, 0) << 0 << 1 << 1;
803
804     QTest::newRow("3rd point inside")
805         << QPoint(140, 260) << QPoint(260, 140) << QPoint(200, 140) << 0 << 0 << 1;
806
807     QTest::newRow("all points inside")
808         << QPoint(200, 140) << QPoint(200, 260) << QPoint(140, 200) << 1 << 2 << 3;
809
810     QTest::newRow("all points outside")
811         << QPoint(140, 140) << QPoint(260, 260) << QPoint(260, 140) << 0 << 0 << 0;
812
813     QTest::newRow("1st and 2nd points inside")
814         << QPoint(200, 260) << QPoint(200, 140) << QPoint(140, 140) << 1 << 2 << 2;
815
816     QTest::newRow("1st and 3rd points inside")
817         << QPoint(200, 200) << QPoint(0, 0) << QPoint(200, 260) << 1 << 1 << 2;
818 }
819
820 void tst_QQuickMultiPointTouchArea::transformedTouchArea()
821 {
822     QFETCH(QPoint, p1);
823     QFETCH(QPoint, p2);
824     QFETCH(QPoint, p3);
825     QFETCH(int, total1);
826     QFETCH(int, total2);
827     QFETCH(int, total3);
828
829     QQuickView *canvas = createAndShowView("transformedMultiPointTouchArea.qml");
830     QVERIFY(canvas->rootObject() != 0);
831
832     QQuickMultiPointTouchArea *area = canvas->rootObject()->findChild<QQuickMultiPointTouchArea *>("touchArea");
833     QVERIFY(area != 0);
834
835     QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas, device);
836
837     sequence.press(0, p1).commit();
838     QCOMPARE(area->property("pointCount").toInt(), total1);
839
840     sequence.stationary(0).press(1, p2).commit();
841     QCOMPARE(area->property("pointCount").toInt(), total2);
842
843     sequence.stationary(0).stationary(1).press(2, p3).commit();
844     QCOMPARE(area->property("pointCount").toInt(), total3);
845
846     delete canvas;
847 }
848
849 QQuickView *tst_QQuickMultiPointTouchArea::createAndShowView(const QString &file)
850 {
851     QQuickView *canvas = new QQuickView(0);
852     canvas->setSource(testFileUrl(file));
853     canvas->show();
854     canvas->requestActivateWindow();
855     QTest::qWaitForWindowShown(canvas);
856
857     return canvas;
858 }
859
860 QTEST_MAIN(tst_QQuickMultiPointTouchArea)
861
862 #include "tst_qquickmultipointtoucharea.moc"