Adjust MouseArea autotest to check mouse events with transformations
[profile/ivi/qtdeclarative.git] / tests / auto / quick / qquickmousearea / tst_qquickmousearea.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 <QtQuick/private/qquickmousearea_p.h>
45 #include <QtQuick/private/qquickrectangle_p.h>
46 #include <private/qquickflickable_p.h>
47 #include <QtQuick/qquickview.h>
48 #include <QtQml/qqmlcontext.h>
49 #include <QtQml/qqmlengine.h>
50 #include "../../shared/util.h"
51 #include <QtGui/qstylehints.h>
52
53 class tst_QQuickMouseArea: public QQmlDataTest
54 {
55     Q_OBJECT
56 private slots:
57     void dragProperties();
58     void resetDrag();
59     void dragging_data() { acceptedButton_data(); }
60     void dragging();
61     void invalidDrag_data() { rejectedButton_data(); }
62     void invalidDrag();
63     void setDragOnPressed();
64     void updateMouseAreaPosOnClick();
65     void updateMouseAreaPosOnResize();
66     void noOnClickedWithPressAndHold();
67     void onMousePressRejected();
68     void pressedCanceledOnWindowDeactivate();
69     void doubleClick_data() { acceptedButton_data(); }
70     void doubleClick();
71     void clickTwice_data() { acceptedButton_data(); }
72     void clickTwice();
73     void invalidClick_data() { rejectedButton_data(); }
74     void invalidClick();
75     void pressedOrdering();
76     void preventStealing();
77     void clickThrough();
78     void hoverPosition();
79     void hoverPropagation();
80     void hoverVisible();
81     void disableAfterPress();
82     void onWheel();
83     void transformedMouseArea_data();
84     void transformedMouseArea();
85
86 private:
87     void acceptedButton_data();
88     void rejectedButton_data();
89
90     QQuickView *createView();
91 };
92
93 Q_DECLARE_METATYPE(Qt::MouseButton)
94 Q_DECLARE_METATYPE(Qt::MouseButtons)
95
96 void tst_QQuickMouseArea::acceptedButton_data()
97 {
98     QTest::addColumn<Qt::MouseButtons>("acceptedButtons");
99     QTest::addColumn<Qt::MouseButton>("button");
100
101     QTest::newRow("left") << Qt::MouseButtons(Qt::LeftButton) << Qt::LeftButton;
102     QTest::newRow("right") << Qt::MouseButtons(Qt::RightButton) << Qt::RightButton;
103     QTest::newRow("middle") << Qt::MouseButtons(Qt::MiddleButton) << Qt::MiddleButton;
104
105     QTest::newRow("left (left|right)") << Qt::MouseButtons(Qt::LeftButton | Qt::RightButton) << Qt::LeftButton;
106     QTest::newRow("right (right|middle)") << Qt::MouseButtons(Qt::RightButton | Qt::MiddleButton) << Qt::RightButton;
107     QTest::newRow("middle (left|middle)") << Qt::MouseButtons(Qt::LeftButton | Qt::MiddleButton) << Qt::MiddleButton;
108 }
109
110 void tst_QQuickMouseArea::rejectedButton_data()
111 {
112     QTest::addColumn<Qt::MouseButtons>("acceptedButtons");
113     QTest::addColumn<Qt::MouseButton>("button");
114
115     QTest::newRow("middle (left|right)") << Qt::MouseButtons(Qt::LeftButton | Qt::RightButton) << Qt::MiddleButton;
116     QTest::newRow("left (right|middle)") << Qt::MouseButtons(Qt::RightButton | Qt::MiddleButton) << Qt::LeftButton;
117     QTest::newRow("right (left|middle)") << Qt::MouseButtons(Qt::LeftButton | Qt::MiddleButton) << Qt::RightButton;
118 }
119
120 void tst_QQuickMouseArea::dragProperties()
121 {
122     QQuickView *canvas = createView();
123
124     canvas->setSource(testFileUrl("dragproperties.qml"));
125     canvas->show();
126     canvas->requestActivateWindow();
127     QVERIFY(canvas->rootObject() != 0);
128
129     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
130     QQuickDrag *drag = mouseRegion->drag();
131     QVERIFY(mouseRegion != 0);
132     QVERIFY(drag != 0);
133
134     // target
135     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
136     QVERIFY(blackRect != 0);
137     QVERIFY(blackRect == drag->target());
138     QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
139     QVERIFY(rootItem != 0);
140     QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
141     drag->setTarget(rootItem);
142     QCOMPARE(targetSpy.count(),1);
143     drag->setTarget(rootItem);
144     QCOMPARE(targetSpy.count(),1);
145
146     // axis
147     QCOMPARE(drag->axis(), QQuickDrag::XandYAxis);
148     QSignalSpy axisSpy(drag, SIGNAL(axisChanged()));
149     drag->setAxis(QQuickDrag::XAxis);
150     QCOMPARE(drag->axis(), QQuickDrag::XAxis);
151     QCOMPARE(axisSpy.count(),1);
152     drag->setAxis(QQuickDrag::XAxis);
153     QCOMPARE(axisSpy.count(),1);
154
155     // minimum and maximum properties
156     QSignalSpy xminSpy(drag, SIGNAL(minimumXChanged()));
157     QSignalSpy xmaxSpy(drag, SIGNAL(maximumXChanged()));
158     QSignalSpy yminSpy(drag, SIGNAL(minimumYChanged()));
159     QSignalSpy ymaxSpy(drag, SIGNAL(maximumYChanged()));
160
161     QCOMPARE(drag->xmin(), 0.0);
162     QCOMPARE(drag->xmax(), rootItem->width()-blackRect->width());
163     QCOMPARE(drag->ymin(), 0.0);
164     QCOMPARE(drag->ymax(), rootItem->height()-blackRect->height());
165
166     drag->setXmin(10);
167     drag->setXmax(10);
168     drag->setYmin(10);
169     drag->setYmax(10);
170
171     QCOMPARE(drag->xmin(), 10.0);
172     QCOMPARE(drag->xmax(), 10.0);
173     QCOMPARE(drag->ymin(), 10.0);
174     QCOMPARE(drag->ymax(), 10.0);
175
176     QCOMPARE(xminSpy.count(),1);
177     QCOMPARE(xmaxSpy.count(),1);
178     QCOMPARE(yminSpy.count(),1);
179     QCOMPARE(ymaxSpy.count(),1);
180
181     drag->setXmin(10);
182     drag->setXmax(10);
183     drag->setYmin(10);
184     drag->setYmax(10);
185
186     QCOMPARE(xminSpy.count(),1);
187     QCOMPARE(xmaxSpy.count(),1);
188     QCOMPARE(yminSpy.count(),1);
189     QCOMPARE(ymaxSpy.count(),1);
190
191     // filterChildren
192     QSignalSpy filterChildrenSpy(drag, SIGNAL(filterChildrenChanged()));
193
194     drag->setFilterChildren(true);
195
196     QVERIFY(drag->filterChildren());
197     QCOMPARE(filterChildrenSpy.count(), 1);
198
199     drag->setFilterChildren(true);
200     QCOMPARE(filterChildrenSpy.count(), 1);
201
202     delete canvas;
203 }
204
205 void tst_QQuickMouseArea::resetDrag()
206 {
207     QQuickView *canvas = createView();
208
209     canvas->rootContext()->setContextProperty("haveTarget", QVariant(true));
210     canvas->setSource(testFileUrl("dragreset.qml"));
211     canvas->show();
212     canvas->requestActivateWindow();
213     QVERIFY(canvas->rootObject() != 0);
214
215     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
216     QQuickDrag *drag = mouseRegion->drag();
217     QVERIFY(mouseRegion != 0);
218     QVERIFY(drag != 0);
219
220     // target
221     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
222     QVERIFY(blackRect != 0);
223     QVERIFY(blackRect == drag->target());
224     QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
225     QVERIFY(rootItem != 0);
226     QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
227     QVERIFY(drag->target() != 0);
228     canvas->rootContext()->setContextProperty("haveTarget", QVariant(false));
229     QCOMPARE(targetSpy.count(),1);
230     QVERIFY(drag->target() == 0);
231
232     delete canvas;
233 }
234
235 void tst_QQuickMouseArea::dragging()
236 {
237     QFETCH(Qt::MouseButtons, acceptedButtons);
238     QFETCH(Qt::MouseButton, button);
239
240     QQuickView *canvas = createView();
241
242     canvas->setSource(testFileUrl("dragging.qml"));
243     canvas->show();
244     canvas->requestActivateWindow();
245     QTest::qWait(20);
246     QVERIFY(canvas->rootObject() != 0);
247
248     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
249     QQuickDrag *drag = mouseRegion->drag();
250     QVERIFY(mouseRegion != 0);
251     QVERIFY(drag != 0);
252
253     mouseRegion->setAcceptedButtons(acceptedButtons);
254
255     // target
256     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
257     QVERIFY(blackRect != 0);
258     QVERIFY(blackRect == drag->target());
259
260     QVERIFY(!drag->active());
261
262     QTest::mousePress(canvas, button, 0, QPoint(100,100));
263
264     QVERIFY(!drag->active());
265     QCOMPARE(blackRect->x(), 50.0);
266     QCOMPARE(blackRect->y(), 50.0);
267
268     // First move event triggers drag, second is acted upon.
269     // This is due to possibility of higher stacked area taking precedence.
270
271     QTest::mouseMove(canvas, QPoint(111,111));
272     QTest::qWait(50);
273     QTest::mouseMove(canvas, QPoint(122,122));
274     QTest::qWait(50);
275
276     QVERIFY(drag->active());
277     QCOMPARE(blackRect->x(), 72.0);
278     QCOMPARE(blackRect->y(), 72.0);
279
280     QTest::mouseRelease(canvas, button, 0, QPoint(122,122));
281     QTest::qWait(50);
282
283     QVERIFY(!drag->active());
284     QCOMPARE(blackRect->x(), 72.0);
285     QCOMPARE(blackRect->y(), 72.0);
286
287     delete canvas;
288 }
289
290 void tst_QQuickMouseArea::invalidDrag()
291 {
292     QFETCH(Qt::MouseButtons, acceptedButtons);
293     QFETCH(Qt::MouseButton, button);
294
295     QQuickView *canvas = createView();
296
297     canvas->setSource(testFileUrl("dragging.qml"));
298     canvas->show();
299     canvas->requestActivateWindow();
300     QTest::qWait(20);
301     QVERIFY(canvas->rootObject() != 0);
302
303     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
304     QQuickDrag *drag = mouseRegion->drag();
305     QVERIFY(mouseRegion != 0);
306     QVERIFY(drag != 0);
307
308     mouseRegion->setAcceptedButtons(acceptedButtons);
309
310     // target
311     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
312     QVERIFY(blackRect != 0);
313     QVERIFY(blackRect == drag->target());
314
315     QVERIFY(!drag->active());
316
317     QTest::mousePress(canvas, button, 0, QPoint(100,100));
318
319     QVERIFY(!drag->active());
320     QCOMPARE(blackRect->x(), 50.0);
321     QCOMPARE(blackRect->y(), 50.0);
322
323     // First move event triggers drag, second is acted upon.
324     // This is due to possibility of higher stacked area taking precedence.
325
326     QTest::mouseMove(canvas, QPoint(111,111));
327     QTest::qWait(50);
328     QTest::mouseMove(canvas, QPoint(122,122));
329     QTest::qWait(50);
330
331     QVERIFY(!drag->active());
332     QCOMPARE(blackRect->x(), 50.0);
333     QCOMPARE(blackRect->y(), 50.0);
334
335     QTest::mouseRelease(canvas, button, 0, QPoint(122,122));
336     QTest::qWait(50);
337
338     QVERIFY(!drag->active());
339     QCOMPARE(blackRect->x(), 50.0);
340     QCOMPARE(blackRect->y(), 50.0);
341
342     delete canvas;
343 }
344
345 void tst_QQuickMouseArea::setDragOnPressed()
346 {
347     QQuickView *canvas = createView();
348
349     canvas->setSource(testFileUrl("setDragOnPressed.qml"));
350     canvas->show();
351     canvas->requestActivateWindow();
352     QTest::qWait(20);
353     QVERIFY(canvas->rootObject() != 0);
354
355     QQuickMouseArea *mouseArea = qobject_cast<QQuickMouseArea *>(canvas->rootObject());
356     QVERIFY(mouseArea);
357
358     // target
359     QQuickItem *target = mouseArea->findChild<QQuickItem*>("target");
360     QVERIFY(target);
361
362     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
363
364     QQuickDrag *drag = mouseArea->drag();
365     QVERIFY(drag);
366     QVERIFY(!drag->active());
367
368     QCOMPARE(target->x(), 50.0);
369     QCOMPARE(target->y(), 50.0);
370
371     // First move event triggers drag, second is acted upon.
372     // This is due to possibility of higher stacked area taking precedence.
373
374     QTest::mouseMove(canvas, QPoint(111,102));
375     QTest::qWait(50);
376     QTest::mouseMove(canvas, QPoint(122,122));
377     QTest::qWait(50);
378
379     QVERIFY(drag->active());
380     QCOMPARE(target->x(), 72.0);
381     QCOMPARE(target->y(), 50.0);
382
383     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(122,122));
384     QTest::qWait(50);
385
386     QVERIFY(!drag->active());
387     QCOMPARE(target->x(), 72.0);
388     QCOMPARE(target->y(), 50.0);
389
390     delete canvas;
391 }
392
393 QQuickView *tst_QQuickMouseArea::createView()
394 {
395     QQuickView *canvas = new QQuickView(0);
396     canvas->setBaseSize(QSize(240,320));
397
398     return canvas;
399 }
400
401 void tst_QQuickMouseArea::updateMouseAreaPosOnClick()
402 {
403     QQuickView *canvas = createView();
404     canvas->setSource(testFileUrl("updateMousePosOnClick.qml"));
405     canvas->show();
406     canvas->requestActivateWindow();
407     QVERIFY(canvas->rootObject() != 0);
408
409     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
410     QVERIFY(mouseRegion != 0);
411
412     QQuickRectangle *rect = canvas->rootObject()->findChild<QQuickRectangle*>("ball");
413     QVERIFY(rect != 0);
414
415     QCOMPARE(mouseRegion->mouseX(), rect->x());
416     QCOMPARE(mouseRegion->mouseY(), rect->y());
417
418     QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
419     QGuiApplication::sendEvent(canvas, &event);
420
421     QCOMPARE(mouseRegion->mouseX(), 100.0);
422     QCOMPARE(mouseRegion->mouseY(), 100.0);
423
424     QCOMPARE(mouseRegion->mouseX(), rect->x());
425     QCOMPARE(mouseRegion->mouseY(), rect->y());
426
427     delete canvas;
428 }
429
430 void tst_QQuickMouseArea::updateMouseAreaPosOnResize()
431 {
432     QQuickView *canvas = createView();
433     canvas->setSource(testFileUrl("updateMousePosOnResize.qml"));
434     canvas->show();
435     canvas->requestActivateWindow();
436     QVERIFY(canvas->rootObject() != 0);
437
438     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
439     QVERIFY(mouseRegion != 0);
440
441     QQuickRectangle *rect = canvas->rootObject()->findChild<QQuickRectangle*>("brother");
442     QVERIFY(rect != 0);
443
444     QCOMPARE(mouseRegion->mouseX(), 0.0);
445     QCOMPARE(mouseRegion->mouseY(), 0.0);
446
447     QMouseEvent event(QEvent::MouseButtonPress, rect->pos().toPoint(), Qt::LeftButton, Qt::LeftButton, 0);
448     QGuiApplication::sendEvent(canvas, &event);
449
450     QVERIFY(!mouseRegion->property("emitPositionChanged").toBool());
451     QVERIFY(mouseRegion->property("mouseMatchesPos").toBool());
452
453     QCOMPARE(mouseRegion->property("x1").toReal(), 0.0);
454     QCOMPARE(mouseRegion->property("y1").toReal(), 0.0);
455
456     QCOMPARE(mouseRegion->property("x2").toReal(), rect->x());
457     QCOMPARE(mouseRegion->property("y2").toReal(), rect->y());
458
459     QCOMPARE(mouseRegion->mouseX(), rect->x());
460     QCOMPARE(mouseRegion->mouseY(), rect->y());
461
462     delete canvas;
463 }
464
465 void tst_QQuickMouseArea::noOnClickedWithPressAndHold()
466 {
467     {
468         // We handle onPressAndHold, therefore no onClicked
469         QQuickView *canvas = createView();
470         canvas->setSource(testFileUrl("clickandhold.qml"));
471         canvas->show();
472         canvas->requestActivateWindow();
473         QVERIFY(canvas->rootObject() != 0);
474
475         QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
476         QGuiApplication::sendEvent(canvas, &pressEvent);
477
478         QVERIFY(!canvas->rootObject()->property("clicked").toBool());
479         QVERIFY(!canvas->rootObject()->property("held").toBool());
480
481         QTest::qWait(1000);
482
483         QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
484         QGuiApplication::sendEvent(canvas, &releaseEvent);
485
486         QVERIFY(!canvas->rootObject()->property("clicked").toBool());
487         QVERIFY(canvas->rootObject()->property("held").toBool());
488
489         delete canvas;
490     }
491
492     {
493         // We do not handle onPressAndHold, therefore we get onClicked
494         QQuickView *canvas = createView();
495         canvas->setSource(testFileUrl("noclickandhold.qml"));
496         canvas->show();
497         canvas->requestActivateWindow();
498         QVERIFY(canvas->rootObject() != 0);
499
500         QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
501         QGuiApplication::sendEvent(canvas, &pressEvent);
502
503         QVERIFY(!canvas->rootObject()->property("clicked").toBool());
504
505         QTest::qWait(1000);
506
507         QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
508         QGuiApplication::sendEvent(canvas, &releaseEvent);
509
510         QVERIFY(canvas->rootObject()->property("clicked").toBool());
511
512         delete canvas;
513     }
514 }
515
516 void tst_QQuickMouseArea::onMousePressRejected()
517 {
518     QQuickView *canvas = createView();
519     canvas->setSource(testFileUrl("rejectEvent.qml"));
520     canvas->show();
521     canvas->requestActivateWindow();
522     QVERIFY(canvas->rootObject() != 0);
523     QVERIFY(canvas->rootObject()->property("enabled").toBool());
524
525     QVERIFY(!canvas->rootObject()->property("mr1_pressed").toBool());
526     QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
527     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
528     QVERIFY(!canvas->rootObject()->property("mr2_pressed").toBool());
529     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
530     QVERIFY(!canvas->rootObject()->property("mr2_canceled").toBool());
531
532     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
533     QGuiApplication::sendEvent(canvas, &pressEvent);
534
535     QVERIFY(canvas->rootObject()->property("mr1_pressed").toBool());
536     QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
537     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
538     QVERIFY(canvas->rootObject()->property("mr2_pressed").toBool());
539     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
540     QVERIFY(canvas->rootObject()->property("mr2_canceled").toBool());
541
542     QTest::qWait(200);
543
544     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
545     QGuiApplication::sendEvent(canvas, &releaseEvent);
546
547     QVERIFY(canvas->rootObject()->property("mr1_released").toBool());
548     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
549     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
550
551     delete canvas;
552 }
553 void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
554 {
555     QQuickView *canvas = createView();
556     canvas->setSource(testFileUrl("pressedCanceled.qml"));
557     canvas->show();
558     canvas->requestActivateWindow();
559     QVERIFY(canvas->rootObject() != 0);
560     QVERIFY(!canvas->rootObject()->property("pressed").toBool());
561     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
562     QVERIFY(!canvas->rootObject()->property("released").toBool());
563
564     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
565     QGuiApplication::sendEvent(canvas, &pressEvent);
566
567     QVERIFY(canvas->rootObject()->property("pressed").toBool());
568     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
569     QVERIFY(!canvas->rootObject()->property("released").toBool());
570
571     QTest::qWait(200);
572
573     QEvent windowDeactivateEvent(QEvent::WindowDeactivate);
574     QGuiApplication::sendEvent(canvas, &windowDeactivateEvent);
575     QVERIFY(!canvas->rootObject()->property("pressed").toBool());
576     QVERIFY(canvas->rootObject()->property("canceled").toBool());
577     QVERIFY(!canvas->rootObject()->property("released").toBool());
578
579     QTest::qWait(200);
580
581     //press again
582     QGuiApplication::sendEvent(canvas, &pressEvent);
583     QVERIFY(canvas->rootObject()->property("pressed").toBool());
584     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
585     QVERIFY(!canvas->rootObject()->property("released").toBool());
586
587     QTest::qWait(200);
588
589     //release
590     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
591     QGuiApplication::sendEvent(canvas, &releaseEvent);
592     QVERIFY(!canvas->rootObject()->property("pressed").toBool());
593     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
594     QVERIFY(canvas->rootObject()->property("released").toBool());
595
596     delete canvas;
597 }
598
599 void tst_QQuickMouseArea::doubleClick()
600 {
601     QFETCH(Qt::MouseButtons, acceptedButtons);
602     QFETCH(Qt::MouseButton, button);
603
604     QQuickView *canvas = createView();
605     canvas->setSource(testFileUrl("doubleclick.qml"));
606     canvas->show();
607     canvas->requestActivateWindow();
608     QVERIFY(canvas->rootObject() != 0);
609
610     QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea *>("mousearea");
611     QVERIFY(mouseArea);
612     mouseArea->setAcceptedButtons(acceptedButtons);
613
614     // The sequence for a double click is:
615     // press, release, (click), press, double click, release
616     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, 0);
617     QGuiApplication::sendEvent(canvas, &pressEvent);
618
619     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, 0);
620     QGuiApplication::sendEvent(canvas, &releaseEvent);
621
622     QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
623
624     QGuiApplication::sendEvent(canvas, &pressEvent);
625     pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, 0);
626     QGuiApplication::sendEvent(canvas, &pressEvent);
627     QGuiApplication::sendEvent(canvas, &releaseEvent);
628
629     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
630     QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1);
631     QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
632
633     delete canvas;
634 }
635
636 // QTBUG-14832
637 void tst_QQuickMouseArea::clickTwice()
638 {
639     QFETCH(Qt::MouseButtons, acceptedButtons);
640     QFETCH(Qt::MouseButton, button);
641
642     QQuickView *canvas = createView();
643     canvas->setSource(testFileUrl("clicktwice.qml"));
644     canvas->show();
645     canvas->requestActivateWindow();
646     QVERIFY(canvas->rootObject() != 0);
647
648     QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea *>("mousearea");
649     QVERIFY(mouseArea);
650     mouseArea->setAcceptedButtons(acceptedButtons);
651
652     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, 0);
653     QGuiApplication::sendEvent(canvas, &pressEvent);
654
655     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, 0);
656     QGuiApplication::sendEvent(canvas, &releaseEvent);
657
658     QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 1);
659     QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
660     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
661
662     QGuiApplication::sendEvent(canvas, &pressEvent);
663     pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, 0);
664     QGuiApplication::sendEvent(canvas, &pressEvent);
665     QGuiApplication::sendEvent(canvas, &releaseEvent);
666
667     QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 2);
668     QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
669     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2);
670
671     delete canvas;
672 }
673
674 void tst_QQuickMouseArea::invalidClick()
675 {
676     QFETCH(Qt::MouseButtons, acceptedButtons);
677     QFETCH(Qt::MouseButton, button);
678
679     QQuickView *canvas = createView();
680     canvas->setSource(testFileUrl("doubleclick.qml"));
681     canvas->show();
682     canvas->requestActivateWindow();
683     QVERIFY(canvas->rootObject() != 0);
684
685     QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea *>("mousearea");
686     QVERIFY(mouseArea);
687     mouseArea->setAcceptedButtons(acceptedButtons);
688
689     // The sequence for a double click is:
690     // press, release, (click), press, double click, release
691     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, 0);
692     QGuiApplication::sendEvent(canvas, &pressEvent);
693
694     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, 0);
695     QGuiApplication::sendEvent(canvas, &releaseEvent);
696
697     QCOMPARE(canvas->rootObject()->property("released").toInt(), 0);
698
699     QGuiApplication::sendEvent(canvas, &pressEvent);
700     pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, 0);
701     QGuiApplication::sendEvent(canvas, &pressEvent);
702     QGuiApplication::sendEvent(canvas, &releaseEvent);
703
704     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 0);
705     QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 0);
706     QCOMPARE(canvas->rootObject()->property("released").toInt(), 0);
707
708     delete canvas;
709 }
710
711 void tst_QQuickMouseArea::pressedOrdering()
712 {
713     QQuickView *canvas = createView();
714     canvas->setSource(testFileUrl("pressedOrdering.qml"));
715     canvas->show();
716     canvas->requestActivateWindow();
717     QVERIFY(canvas->rootObject() != 0);
718
719     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("base"));
720
721     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
722     QGuiApplication::sendEvent(canvas, &pressEvent);
723
724     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
725
726     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
727     QGuiApplication::sendEvent(canvas, &releaseEvent);
728
729     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("toggled"));
730
731     QGuiApplication::sendEvent(canvas, &pressEvent);
732
733     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
734
735     delete canvas;
736 }
737
738 void tst_QQuickMouseArea::preventStealing()
739 {
740     QQuickView *canvas = createView();
741
742     canvas->setSource(testFileUrl("preventstealing.qml"));
743     canvas->show();
744     canvas->requestActivateWindow();
745     QVERIFY(canvas->rootObject() != 0);
746
747     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(canvas->rootObject());
748     QVERIFY(flickable != 0);
749
750     QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea*>("mousearea");
751     QVERIFY(mouseArea != 0);
752
753     QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*)));
754
755     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
756
757     // Without preventStealing, mouse movement over MouseArea would
758     // cause the Flickable to steal mouse and trigger content movement.
759
760     QTest::mouseMove(canvas,QPoint(69,69));
761     QTest::mouseMove(canvas,QPoint(58,58));
762     QTest::mouseMove(canvas,QPoint(47,47));
763
764     // We should have received all three move events
765     QCOMPARE(mousePositionSpy.count(), 3);
766     QVERIFY(mouseArea->pressed());
767
768     // Flickable content should not have moved.
769     QCOMPARE(flickable->contentX(), 0.);
770     QCOMPARE(flickable->contentY(), 0.);
771
772     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(47, 47));
773
774     // Now allow stealing and confirm Flickable does its thing.
775     canvas->rootObject()->setProperty("stealing", false);
776
777     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
778
779     // Without preventStealing, mouse movement over MouseArea would
780     // cause the Flickable to steal mouse and trigger content movement.
781
782     QTest::mouseMove(canvas,QPoint(69,69));
783     QTest::mouseMove(canvas,QPoint(58,58));
784     QTest::mouseMove(canvas,QPoint(47,47));
785
786     // We should only have received the first move event
787     QCOMPARE(mousePositionSpy.count(), 4);
788     // Our press should be taken away
789     QVERIFY(!mouseArea->pressed());
790
791     // Flickable content should have moved.
792
793     QCOMPARE(flickable->contentX(), 11.);
794     QCOMPARE(flickable->contentY(), 11.);
795
796     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 50));
797
798     delete canvas;
799 }
800
801 void tst_QQuickMouseArea::clickThrough()
802 {
803     QSKIP("QTBUG-23976 Unstable");
804     //With no handlers defined click, doubleClick and PressAndHold should propagate to those with handlers
805     QQuickView *canvas = createView();
806     canvas->setSource(testFileUrl("clickThrough.qml"));
807     canvas->show();
808     canvas->requestActivateWindow();
809     QVERIFY(canvas->rootObject() != 0);
810
811     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
812     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
813
814     QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
815     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
816
817     // to avoid generating a double click.
818     int doubleClickInterval = qApp->styleHints()->mouseDoubleClickInterval() + 10;
819     QTest::qWait(doubleClickInterval);
820
821     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
822     QTest::qWait(1000);
823     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
824
825     QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
826     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
827     QTRY_COMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
828
829     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
830     QTest::qWait(100);
831
832     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
833     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
834     QTRY_COMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
835     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
836
837     delete canvas;
838
839     //With handlers defined click, doubleClick and PressAndHold should propagate only when explicitly ignored
840     canvas = createView();
841     canvas->setSource(testFileUrl("clickThrough2.qml"));
842     canvas->show();
843     canvas->requestActivateWindow();
844     QVERIFY(canvas->rootObject() != 0);
845
846     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
847     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
848
849     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
850     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
851
852     QTest::qWait(doubleClickInterval); // to avoid generating a double click.
853
854     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
855     QTest::qWait(1000);
856     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
857     QTest::qWait(100);
858
859     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
860     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
861     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0);
862
863     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
864     QTest::qWait(100);
865
866     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
867     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
868     QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 0);
869     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0);
870
871     canvas->rootObject()->setProperty("letThrough", QVariant(true));
872
873     QTest::qWait(doubleClickInterval); // to avoid generating a double click.
874     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
875     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
876
877     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
878     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
879
880     QTest::qWait(doubleClickInterval); // to avoid generating a double click.
881     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
882     QTest::qWait(1000);
883     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
884     QTest::qWait(100);
885
886     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
887     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
888     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
889
890     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
891     QTest::qWait(100);
892
893     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
894     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
895     QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
896     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
897
898     canvas->rootObject()->setProperty("noPropagation", QVariant(true));
899
900     QTest::qWait(doubleClickInterval); // to avoid generating a double click.
901     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
902     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
903
904     QTest::qWait(doubleClickInterval); // to avoid generating a double click.
905     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
906     QTest::qWait(1000);
907     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
908     QTest::qWait(100);
909
910     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
911     QTest::qWait(100);
912
913     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
914     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
915     QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
916     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
917
918     delete canvas;
919 }
920
921 void tst_QQuickMouseArea::hoverPosition()
922 {
923     QQuickView *canvas = createView();
924     canvas->setSource(testFileUrl("hoverPosition.qml"));
925
926     QQuickItem *root = canvas->rootObject();
927     QVERIFY(root != 0);
928
929     QCOMPARE(root->property("mouseX").toReal(), qreal(0));
930     QCOMPARE(root->property("mouseY").toReal(), qreal(0));
931
932     QTest::mouseMove(canvas,QPoint(10,32));
933
934
935     QCOMPARE(root->property("mouseX").toReal(), qreal(10));
936     QCOMPARE(root->property("mouseY").toReal(), qreal(32));
937
938     delete canvas;
939 }
940
941 void tst_QQuickMouseArea::hoverPropagation()
942 {
943     //QTBUG-18175, to behave like GV did.
944     QQuickView *canvas = createView();
945     canvas->setSource(testFileUrl("hoverPropagation.qml"));
946
947     QQuickItem *root = canvas->rootObject();
948     QVERIFY(root != 0);
949
950     QCOMPARE(root->property("point1").toBool(), false);
951     QCOMPARE(root->property("point2").toBool(), false);
952
953     QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, 0);
954     QGuiApplication::sendEvent(canvas, &moveEvent);
955
956     QCOMPARE(root->property("point1").toBool(), true);
957     QCOMPARE(root->property("point2").toBool(), false);
958
959     QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, 0);
960     QGuiApplication::sendEvent(canvas, &moveEvent2);
961     QCOMPARE(root->property("point1").toBool(), false);
962     QCOMPARE(root->property("point2").toBool(), true);
963
964     delete canvas;
965 }
966
967 void tst_QQuickMouseArea::hoverVisible()
968 {
969     QQuickView *canvas = createView();
970     canvas->setSource(testFileUrl("hoverVisible.qml"));
971
972     QQuickItem *root = canvas->rootObject();
973     QVERIFY(root != 0);
974
975     QQuickMouseArea *mouseTracker = canvas->rootObject()->findChild<QQuickMouseArea*>("mousetracker");
976     QVERIFY(mouseTracker != 0);
977
978     QSignalSpy enteredSpy(mouseTracker, SIGNAL(entered()));
979
980     // Note: We need to use a position that is different from the position in the last event
981     // generated in the previous test case. Otherwise it is not interpreted as a move.
982     QTest::mouseMove(canvas,QPoint(11,33));
983
984     QCOMPARE(mouseTracker->hovered(), false);
985     QCOMPARE(enteredSpy.count(), 0);
986
987     mouseTracker->setVisible(true);
988
989     QCOMPARE(mouseTracker->hovered(), true);
990     QCOMPARE(enteredSpy.count(), 1);
991
992     QEXPECT_FAIL("", "QTBUG-24282", Continue);
993     QCOMPARE(QPointF(mouseTracker->mouseX(), mouseTracker->mouseY()), QPointF(11,33));
994
995     delete canvas;
996 }
997
998 void tst_QQuickMouseArea::disableAfterPress()
999 {
1000     QQuickView *canvas = createView();
1001     canvas->setSource(testFileUrl("dragging.qml"));
1002     canvas->show();
1003     canvas->requestActivateWindow();
1004     QTest::qWait(20);
1005     QVERIFY(canvas->rootObject() != 0);
1006
1007     QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
1008     QQuickDrag *drag = mouseArea->drag();
1009     QVERIFY(mouseArea != 0);
1010     QVERIFY(drag != 0);
1011
1012     QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*)));
1013     QSignalSpy mousePressSpy(mouseArea, SIGNAL(pressed(QQuickMouseEvent*)));
1014     QSignalSpy mouseReleaseSpy(mouseArea, SIGNAL(released(QQuickMouseEvent*)));
1015
1016     // target
1017     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
1018     QVERIFY(blackRect != 0);
1019     QVERIFY(blackRect == drag->target());
1020
1021     QVERIFY(!drag->active());
1022
1023     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
1024
1025     QTRY_COMPARE(mousePressSpy.count(), 1);
1026
1027     QVERIFY(!drag->active());
1028     QCOMPARE(blackRect->x(), 50.0);
1029     QCOMPARE(blackRect->y(), 50.0);
1030
1031     // First move event triggers drag, second is acted upon.
1032     // This is due to possibility of higher stacked area taking precedence.
1033
1034     QTest::mouseMove(canvas, QPoint(111,111));
1035     QTest::qWait(50);
1036     QTest::mouseMove(canvas, QPoint(122,122));
1037
1038     QTRY_COMPARE(mousePositionSpy.count(), 2);
1039
1040     QVERIFY(drag->active());
1041     QCOMPARE(blackRect->x(), 72.0);
1042     QCOMPARE(blackRect->y(), 72.0);
1043
1044     mouseArea->setEnabled(false);
1045
1046     // move should still be acted upon
1047     QTest::mouseMove(canvas, QPoint(133,133));
1048     QTest::qWait(50);
1049     QTest::mouseMove(canvas, QPoint(144,144));
1050
1051     QTRY_COMPARE(mousePositionSpy.count(), 4);
1052
1053     QVERIFY(drag->active());
1054     QCOMPARE(blackRect->x(), 94.0);
1055     QCOMPARE(blackRect->y(), 94.0);
1056
1057     QVERIFY(mouseArea->pressed());
1058     QVERIFY(mouseArea->hovered());
1059
1060     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(144,144));
1061
1062     QTRY_COMPARE(mouseReleaseSpy.count(), 1);
1063
1064     QVERIFY(!drag->active());
1065     QCOMPARE(blackRect->x(), 94.0);
1066     QCOMPARE(blackRect->y(), 94.0);
1067
1068     QVERIFY(!mouseArea->pressed());
1069     QVERIFY(!mouseArea->hovered()); // since hover is not enabled
1070
1071     // Next press will be ignored
1072     blackRect->setX(50);
1073     blackRect->setY(50);
1074
1075     mousePressSpy.clear();
1076     mousePositionSpy.clear();
1077     mouseReleaseSpy.clear();
1078
1079     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
1080     QTest::qWait(50);
1081     QCOMPARE(mousePressSpy.count(), 0);
1082
1083     QTest::mouseMove(canvas, QPoint(111,111));
1084     QTest::qWait(50);
1085     QTest::mouseMove(canvas, QPoint(122,122));
1086     QTest::qWait(50);
1087
1088     QCOMPARE(mousePositionSpy.count(), 0);
1089
1090     QVERIFY(!drag->active());
1091     QCOMPARE(blackRect->x(), 50.0);
1092     QCOMPARE(blackRect->y(), 50.0);
1093
1094     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(122,122));
1095     QTest::qWait(50);
1096
1097     QCOMPARE(mouseReleaseSpy.count(), 0);
1098
1099     delete canvas;
1100 }
1101
1102 void tst_QQuickMouseArea::onWheel()
1103 {
1104     QQuickView *canvas = createView();
1105     canvas->setSource(testFileUrl("wheel.qml"));
1106
1107     QQuickItem *root = canvas->rootObject();
1108     QVERIFY(root != 0);
1109
1110     QWheelEvent wheelEvent(QPoint(10, 32), QPoint(10, 32), QPoint(60, 20), QPoint(0, 120),
1111                            0, Qt::Vertical,Qt::NoButton, Qt::ControlModifier);
1112     QGuiApplication::sendEvent(canvas, &wheelEvent);
1113
1114     QCOMPARE(root->property("angleDeltaY").toInt(), 120);
1115     QCOMPARE(root->property("mouseX").toReal(), qreal(10));
1116     QCOMPARE(root->property("mouseY").toReal(), qreal(32));
1117     QCOMPARE(root->property("controlPressed").toBool(), true);
1118
1119     delete canvas;
1120 }
1121
1122 void tst_QQuickMouseArea::transformedMouseArea_data()
1123 {
1124     QTest::addColumn<bool>("insideTarget");
1125     QTest::addColumn<QList<QPoint> >("points");
1126
1127     QList<QPoint> pointsInside;
1128     pointsInside << QPoint(200, 140)
1129                  << QPoint(140, 200)
1130                  << QPoint(200, 200)
1131                  << QPoint(260, 200)
1132                  << QPoint(200, 260);
1133     QTest::newRow("checking points inside") << true << pointsInside;
1134
1135     QList<QPoint> pointsOutside;
1136     pointsOutside << QPoint(140, 140)
1137                   << QPoint(260, 140)
1138                   << QPoint(120, 200)
1139                   << QPoint(280, 200)
1140                   << QPoint(140, 260)
1141                   << QPoint(260, 260);
1142     QTest::newRow("checking points outside") << false << pointsOutside;
1143 }
1144
1145 void tst_QQuickMouseArea::transformedMouseArea()
1146 {
1147     QFETCH(bool, insideTarget);
1148     QFETCH(QList<QPoint>, points);
1149
1150     QQuickView *canvas = createView();
1151     canvas->setSource(testFileUrl("transformedMouseArea.qml"));
1152     canvas->show();
1153     canvas->requestActivateWindow();
1154     QVERIFY(canvas->rootObject() != 0);
1155
1156     QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea *>("mouseArea");
1157     QVERIFY(mouseArea != 0);
1158
1159     foreach (const QPoint &point, points) {
1160         // check hover
1161         QTest::mouseMove(canvas, point);
1162         QTest::qWait(10);
1163         QCOMPARE(mouseArea->property("containsMouse").toBool(), insideTarget);
1164
1165         // check mouse press
1166         QTest::mousePress(canvas, Qt::LeftButton, 0, point);
1167         QTest::qWait(10);
1168         QCOMPARE(mouseArea->property("pressed").toBool(), insideTarget);
1169
1170         // check mouse release
1171         QTest::mouseRelease(canvas, Qt::LeftButton, 0, point);
1172         QTest::qWait(10);
1173         QCOMPARE(mouseArea->property("pressed").toBool(), false);
1174     }
1175
1176     delete canvas;
1177 }
1178
1179 QTEST_MAIN(tst_QQuickMouseArea)
1180
1181 #include "tst_qquickmousearea.moc"