Merge remote branch 'gerrit/api_changes' into merge-master
[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 <QtOpenGL/QGLShaderProgram>
51 #include "../../shared/util.h"
52
53 //#define OLDWAY
54
55 class tst_QQuickMouseArea: public QQmlDataTest
56 {
57     Q_OBJECT
58 private slots:
59     void dragProperties();
60     void resetDrag();
61     void dragging();
62     void updateMouseAreaPosOnClick();
63     void updateMouseAreaPosOnResize();
64     void noOnClickedWithPressAndHold();
65     void onMousePressRejected();
66     void pressedCanceledOnWindowDeactivate();
67     void doubleClick();
68     void clickTwice();
69     void pressedOrdering();
70     void preventStealing();
71     void clickThrough();
72     void hoverPosition();
73     void hoverPropagation();
74     void hoverVisible();
75
76 private:
77     QQuickView *createView();
78 };
79
80 void tst_QQuickMouseArea::dragProperties()
81 {
82     QQuickView *canvas = createView();
83
84     canvas->setSource(testFileUrl("dragproperties.qml"));
85     canvas->show();
86     canvas->requestActivateWindow();
87     QVERIFY(canvas->rootObject() != 0);
88
89     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
90     QQuickDrag *drag = mouseRegion->drag();
91     QVERIFY(mouseRegion != 0);
92     QVERIFY(drag != 0);
93
94     // target
95     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
96     QVERIFY(blackRect != 0);
97     QVERIFY(blackRect == drag->target());
98     QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
99     QVERIFY(rootItem != 0);
100     QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
101     drag->setTarget(rootItem);
102     QCOMPARE(targetSpy.count(),1);
103     drag->setTarget(rootItem);
104     QCOMPARE(targetSpy.count(),1);
105
106     // axis
107     QCOMPARE(drag->axis(), QQuickDrag::XandYAxis);
108     QSignalSpy axisSpy(drag, SIGNAL(axisChanged()));
109     drag->setAxis(QQuickDrag::XAxis);
110     QCOMPARE(drag->axis(), QQuickDrag::XAxis);
111     QCOMPARE(axisSpy.count(),1);
112     drag->setAxis(QQuickDrag::XAxis);
113     QCOMPARE(axisSpy.count(),1);
114
115     // minimum and maximum properties
116     QSignalSpy xminSpy(drag, SIGNAL(minimumXChanged()));
117     QSignalSpy xmaxSpy(drag, SIGNAL(maximumXChanged()));
118     QSignalSpy yminSpy(drag, SIGNAL(minimumYChanged()));
119     QSignalSpy ymaxSpy(drag, SIGNAL(maximumYChanged()));
120
121     QCOMPARE(drag->xmin(), 0.0);
122     QCOMPARE(drag->xmax(), rootItem->width()-blackRect->width());
123     QCOMPARE(drag->ymin(), 0.0);
124     QCOMPARE(drag->ymax(), rootItem->height()-blackRect->height());
125
126     drag->setXmin(10);
127     drag->setXmax(10);
128     drag->setYmin(10);
129     drag->setYmax(10);
130
131     QCOMPARE(drag->xmin(), 10.0);
132     QCOMPARE(drag->xmax(), 10.0);
133     QCOMPARE(drag->ymin(), 10.0);
134     QCOMPARE(drag->ymax(), 10.0);
135
136     QCOMPARE(xminSpy.count(),1);
137     QCOMPARE(xmaxSpy.count(),1);
138     QCOMPARE(yminSpy.count(),1);
139     QCOMPARE(ymaxSpy.count(),1);
140
141     drag->setXmin(10);
142     drag->setXmax(10);
143     drag->setYmin(10);
144     drag->setYmax(10);
145
146     QCOMPARE(xminSpy.count(),1);
147     QCOMPARE(xmaxSpy.count(),1);
148     QCOMPARE(yminSpy.count(),1);
149     QCOMPARE(ymaxSpy.count(),1);
150
151     // filterChildren
152     QSignalSpy filterChildrenSpy(drag, SIGNAL(filterChildrenChanged()));
153
154     drag->setFilterChildren(true);
155
156     QVERIFY(drag->filterChildren());
157     QCOMPARE(filterChildrenSpy.count(), 1);
158
159     drag->setFilterChildren(true);
160     QCOMPARE(filterChildrenSpy.count(), 1);
161
162     delete canvas;
163 }
164
165 void tst_QQuickMouseArea::resetDrag()
166 {
167     QQuickView *canvas = createView();
168
169     canvas->rootContext()->setContextProperty("haveTarget", QVariant(true));
170     canvas->setSource(testFileUrl("dragreset.qml"));
171     canvas->show();
172     canvas->requestActivateWindow();
173     QVERIFY(canvas->rootObject() != 0);
174
175     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
176     QQuickDrag *drag = mouseRegion->drag();
177     QVERIFY(mouseRegion != 0);
178     QVERIFY(drag != 0);
179
180     // target
181     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
182     QVERIFY(blackRect != 0);
183     QVERIFY(blackRect == drag->target());
184     QQuickItem *rootItem = qobject_cast<QQuickItem*>(canvas->rootObject());
185     QVERIFY(rootItem != 0);
186     QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
187     QVERIFY(drag->target() != 0);
188     canvas->rootContext()->setContextProperty("haveTarget", QVariant(false));
189     QCOMPARE(targetSpy.count(),1);
190     QVERIFY(drag->target() == 0);
191
192     delete canvas;
193 }
194
195
196 void tst_QQuickMouseArea::dragging()
197 {
198     QQuickView *canvas = createView();
199
200     canvas->setSource(testFileUrl("dragging.qml"));
201     canvas->show();
202     canvas->requestActivateWindow();
203     QTest::qWait(20);
204     QVERIFY(canvas->rootObject() != 0);
205
206     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
207     QQuickDrag *drag = mouseRegion->drag();
208     QVERIFY(mouseRegion != 0);
209     QVERIFY(drag != 0);
210
211     // target
212     QQuickItem *blackRect = canvas->rootObject()->findChild<QQuickItem*>("blackrect");
213     QVERIFY(blackRect != 0);
214     QVERIFY(blackRect == drag->target());
215
216     QVERIFY(!drag->active());
217
218 #ifdef OLDWAY
219     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
220     QGuiApplication::sendEvent(canvas, &pressEvent);
221 #else
222     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
223 #endif
224
225     QVERIFY(!drag->active());
226     QCOMPARE(blackRect->x(), 50.0);
227     QCOMPARE(blackRect->y(), 50.0);
228
229     // First move event triggers drag, second is acted upon.
230     // This is due to possibility of higher stacked area taking precedence.
231
232     QTest::mouseMove(canvas, QPoint(111,111));
233     QTest::qWait(50);
234     QTest::mouseMove(canvas, QPoint(122,122));
235     QTest::qWait(50);
236
237     QVERIFY(drag->active());
238     QCOMPARE(blackRect->x(), 72.0);
239     QCOMPARE(blackRect->y(), 72.0);
240
241 #ifdef OLDWAY
242     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
243     QGuiApplication::sendEvent(canvas, &releaseEvent);
244 #else
245     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(122,122));
246     QTest::qWait(50);
247 #endif
248
249     QVERIFY(!drag->active());
250     QCOMPARE(blackRect->x(), 72.0);
251     QCOMPARE(blackRect->y(), 72.0);
252
253     delete canvas;
254 }
255
256 QQuickView *tst_QQuickMouseArea::createView()
257 {
258     QQuickView *canvas = new QQuickView(0);
259     canvas->setBaseSize(QSize(240,320));
260
261     return canvas;
262 }
263
264 void tst_QQuickMouseArea::updateMouseAreaPosOnClick()
265 {
266     QQuickView *canvas = createView();
267     canvas->setSource(testFileUrl("updateMousePosOnClick.qml"));
268     canvas->show();
269     canvas->requestActivateWindow();
270     QVERIFY(canvas->rootObject() != 0);
271
272     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
273     QVERIFY(mouseRegion != 0);
274
275     QQuickRectangle *rect = canvas->rootObject()->findChild<QQuickRectangle*>("ball");
276     QVERIFY(rect != 0);
277
278     QCOMPARE(mouseRegion->mouseX(), rect->x());
279     QCOMPARE(mouseRegion->mouseY(), rect->y());
280
281     QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
282     QGuiApplication::sendEvent(canvas, &event);
283
284     QCOMPARE(mouseRegion->mouseX(), 100.0);
285     QCOMPARE(mouseRegion->mouseY(), 100.0);
286
287     QCOMPARE(mouseRegion->mouseX(), rect->x());
288     QCOMPARE(mouseRegion->mouseY(), rect->y());
289
290     delete canvas;
291 }
292
293 void tst_QQuickMouseArea::updateMouseAreaPosOnResize()
294 {
295     QQuickView *canvas = createView();
296     canvas->setSource(testFileUrl("updateMousePosOnResize.qml"));
297     canvas->show();
298     canvas->requestActivateWindow();
299     QVERIFY(canvas->rootObject() != 0);
300
301     QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
302     QVERIFY(mouseRegion != 0);
303
304     QQuickRectangle *rect = canvas->rootObject()->findChild<QQuickRectangle*>("brother");
305     QVERIFY(rect != 0);
306
307     QCOMPARE(mouseRegion->mouseX(), 0.0);
308     QCOMPARE(mouseRegion->mouseY(), 0.0);
309
310     QMouseEvent event(QEvent::MouseButtonPress, rect->pos().toPoint(), Qt::LeftButton, Qt::LeftButton, 0);
311     QGuiApplication::sendEvent(canvas, &event);
312
313     QVERIFY(!mouseRegion->property("emitPositionChanged").toBool());
314     QVERIFY(mouseRegion->property("mouseMatchesPos").toBool());
315
316     QCOMPARE(mouseRegion->property("x1").toReal(), 0.0);
317     QCOMPARE(mouseRegion->property("y1").toReal(), 0.0);
318
319     QCOMPARE(mouseRegion->property("x2").toReal(), rect->x());
320     QCOMPARE(mouseRegion->property("y2").toReal(), rect->y());
321
322     QCOMPARE(mouseRegion->mouseX(), rect->x());
323     QCOMPARE(mouseRegion->mouseY(), rect->y());
324
325     delete canvas;
326 }
327
328 void tst_QQuickMouseArea::noOnClickedWithPressAndHold()
329 {
330     {
331         // We handle onPressAndHold, therefore no onClicked
332         QQuickView *canvas = createView();
333         canvas->setSource(testFileUrl("clickandhold.qml"));
334         canvas->show();
335         canvas->requestActivateWindow();
336         QVERIFY(canvas->rootObject() != 0);
337
338         QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
339         QGuiApplication::sendEvent(canvas, &pressEvent);
340
341         QVERIFY(!canvas->rootObject()->property("clicked").toBool());
342         QVERIFY(!canvas->rootObject()->property("held").toBool());
343
344         QTest::qWait(1000);
345
346         QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
347         QGuiApplication::sendEvent(canvas, &releaseEvent);
348
349         QVERIFY(!canvas->rootObject()->property("clicked").toBool());
350         QVERIFY(canvas->rootObject()->property("held").toBool());
351
352         delete canvas;
353     }
354
355     {
356         // We do not handle onPressAndHold, therefore we get onClicked
357         QQuickView *canvas = createView();
358         canvas->setSource(testFileUrl("noclickandhold.qml"));
359         canvas->show();
360         canvas->requestActivateWindow();
361         QVERIFY(canvas->rootObject() != 0);
362
363         QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
364         QGuiApplication::sendEvent(canvas, &pressEvent);
365
366         QVERIFY(!canvas->rootObject()->property("clicked").toBool());
367
368         QTest::qWait(1000);
369
370         QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
371         QGuiApplication::sendEvent(canvas, &releaseEvent);
372
373         QVERIFY(canvas->rootObject()->property("clicked").toBool());
374
375         delete canvas;
376     }
377 }
378
379 void tst_QQuickMouseArea::onMousePressRejected()
380 {
381     QQuickView *canvas = createView();
382     canvas->setSource(testFileUrl("rejectEvent.qml"));
383     canvas->show();
384     canvas->requestActivateWindow();
385     QVERIFY(canvas->rootObject() != 0);
386     QVERIFY(canvas->rootObject()->property("enabled").toBool());
387
388     QVERIFY(!canvas->rootObject()->property("mr1_pressed").toBool());
389     QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
390     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
391     QVERIFY(!canvas->rootObject()->property("mr2_pressed").toBool());
392     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
393     QVERIFY(!canvas->rootObject()->property("mr2_canceled").toBool());
394
395     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
396     QGuiApplication::sendEvent(canvas, &pressEvent);
397
398     QVERIFY(canvas->rootObject()->property("mr1_pressed").toBool());
399     QVERIFY(!canvas->rootObject()->property("mr1_released").toBool());
400     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
401     QVERIFY(canvas->rootObject()->property("mr2_pressed").toBool());
402     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
403     QVERIFY(canvas->rootObject()->property("mr2_canceled").toBool());
404
405     QTest::qWait(200);
406
407     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
408     QGuiApplication::sendEvent(canvas, &releaseEvent);
409
410     QVERIFY(canvas->rootObject()->property("mr1_released").toBool());
411     QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool());
412     QVERIFY(!canvas->rootObject()->property("mr2_released").toBool());
413
414     delete canvas;
415 }
416 void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
417 {
418     QQuickView *canvas = createView();
419     canvas->setSource(testFileUrl("pressedCanceled.qml"));
420     canvas->show();
421     canvas->requestActivateWindow();
422     QVERIFY(canvas->rootObject() != 0);
423     QVERIFY(!canvas->rootObject()->property("pressed").toBool());
424     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
425     QVERIFY(!canvas->rootObject()->property("released").toBool());
426
427     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
428     QGuiApplication::sendEvent(canvas, &pressEvent);
429
430     QVERIFY(canvas->rootObject()->property("pressed").toBool());
431     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
432     QVERIFY(!canvas->rootObject()->property("released").toBool());
433
434     QTest::qWait(200);
435
436     QEvent windowDeactivateEvent(QEvent::WindowDeactivate);
437     QGuiApplication::sendEvent(canvas, &windowDeactivateEvent);
438     QVERIFY(!canvas->rootObject()->property("pressed").toBool());
439     QVERIFY(canvas->rootObject()->property("canceled").toBool());
440     QVERIFY(!canvas->rootObject()->property("released").toBool());
441
442     QTest::qWait(200);
443
444     //press again
445     QGuiApplication::sendEvent(canvas, &pressEvent);
446     QVERIFY(canvas->rootObject()->property("pressed").toBool());
447     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
448     QVERIFY(!canvas->rootObject()->property("released").toBool());
449
450     QTest::qWait(200);
451
452     //release
453     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
454     QGuiApplication::sendEvent(canvas, &releaseEvent);
455     QVERIFY(!canvas->rootObject()->property("pressed").toBool());
456     QVERIFY(!canvas->rootObject()->property("canceled").toBool());
457     QVERIFY(canvas->rootObject()->property("released").toBool());
458
459     delete canvas;
460 }
461 void tst_QQuickMouseArea::doubleClick()
462 {
463     QQuickView *canvas = createView();
464     canvas->setSource(testFileUrl("doubleclick.qml"));
465     canvas->show();
466     canvas->requestActivateWindow();
467     QVERIFY(canvas->rootObject() != 0);
468
469     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
470     QGuiApplication::sendEvent(canvas, &pressEvent);
471
472     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
473     QGuiApplication::sendEvent(canvas, &releaseEvent);
474
475     QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
476
477     pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
478     QGuiApplication::sendEvent(canvas, &pressEvent);
479
480     QGuiApplication::sendEvent(canvas, &releaseEvent);
481
482     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
483     QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1);
484     QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
485
486     delete canvas;
487 }
488
489 // QTBUG-14832
490 void tst_QQuickMouseArea::clickTwice()
491 {
492     QQuickView *canvas = createView();
493     canvas->setSource(testFileUrl("clicktwice.qml"));
494     canvas->show();
495     canvas->requestActivateWindow();
496     QVERIFY(canvas->rootObject() != 0);
497
498     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
499     QGuiApplication::sendEvent(canvas, &pressEvent);
500
501     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
502     QGuiApplication::sendEvent(canvas, &releaseEvent);
503
504     QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 1);
505     QCOMPARE(canvas->rootObject()->property("released").toInt(), 1);
506     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1);
507
508     pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
509     QGuiApplication::sendEvent(canvas, &pressEvent);
510
511     QGuiApplication::sendEvent(canvas, &pressEvent);
512     QGuiApplication::sendEvent(canvas, &releaseEvent);
513
514     QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 2);
515     QCOMPARE(canvas->rootObject()->property("released").toInt(), 2);
516     QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2);
517
518     delete canvas;
519 }
520
521 void tst_QQuickMouseArea::pressedOrdering()
522 {
523     QQuickView *canvas = createView();
524     canvas->setSource(testFileUrl("pressedOrdering.qml"));
525     canvas->show();
526     canvas->requestActivateWindow();
527     QVERIFY(canvas->rootObject() != 0);
528
529     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("base"));
530
531     QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
532     QGuiApplication::sendEvent(canvas, &pressEvent);
533
534     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
535
536     QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
537     QGuiApplication::sendEvent(canvas, &releaseEvent);
538
539     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("toggled"));
540
541     QGuiApplication::sendEvent(canvas, &pressEvent);
542
543     QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed"));
544
545     delete canvas;
546 }
547
548 void tst_QQuickMouseArea::preventStealing()
549 {
550     QQuickView *canvas = createView();
551
552     canvas->setSource(testFileUrl("preventstealing.qml"));
553     canvas->show();
554     canvas->requestActivateWindow();
555     QVERIFY(canvas->rootObject() != 0);
556
557     QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(canvas->rootObject());
558     QVERIFY(flickable != 0);
559
560     QQuickMouseArea *mouseArea = canvas->rootObject()->findChild<QQuickMouseArea*>("mousearea");
561     QVERIFY(mouseArea != 0);
562
563     QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*)));
564
565     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
566
567     // Without preventStealing, mouse movement over MouseArea would
568     // cause the Flickable to steal mouse and trigger content movement.
569
570     QTest::mouseMove(canvas,QPoint(69,69));
571     QTest::mouseMove(canvas,QPoint(58,58));
572     QTest::mouseMove(canvas,QPoint(47,47));
573
574     // We should have received all three move events
575     QCOMPARE(mousePositionSpy.count(), 3);
576     QVERIFY(mouseArea->pressed());
577
578     // Flickable content should not have moved.
579     QCOMPARE(flickable->contentX(), 0.);
580     QCOMPARE(flickable->contentY(), 0.);
581
582     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(47, 47));
583
584     // Now allow stealing and confirm Flickable does its thing.
585     canvas->rootObject()->setProperty("stealing", false);
586
587     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80));
588
589     // Without preventStealing, mouse movement over MouseArea would
590     // cause the Flickable to steal mouse and trigger content movement.
591
592     QTest::mouseMove(canvas,QPoint(69,69));
593     QTest::mouseMove(canvas,QPoint(58,58));
594     QTest::mouseMove(canvas,QPoint(47,47));
595
596     // We should only have received the first move event
597     QCOMPARE(mousePositionSpy.count(), 4);
598     // Our press should be taken away
599     QVERIFY(!mouseArea->pressed());
600
601     // Flickable content should have moved.
602
603     QCOMPARE(flickable->contentX(), 11.);
604     QCOMPARE(flickable->contentY(), 11.);
605
606     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 50));
607
608     delete canvas;
609 }
610
611 void tst_QQuickMouseArea::clickThrough()
612 {
613     QSKIP("QTBUG-23976 Unstable");
614     //With no handlers defined click, doubleClick and PressAndHold should propagate to those with handlers
615     QQuickView *canvas = createView();
616     canvas->setSource(testFileUrl("clickThrough.qml"));
617     canvas->show();
618     canvas->requestActivateWindow();
619     QVERIFY(canvas->rootObject() != 0);
620
621     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
622     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
623
624     QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
625     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
626
627     QTest::qWait(800); // to avoid generating a double click.
628
629     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
630     QTest::qWait(1000);
631     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
632
633     QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0);
634     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
635     QTRY_COMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
636
637     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
638     QTest::qWait(100);
639
640     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
641     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
642     QTRY_COMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
643     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
644
645     delete canvas;
646
647     //With handlers defined click, doubleClick and PressAndHold should propagate only when explicitly ignored
648     canvas = createView();
649     canvas->setSource(testFileUrl("clickThrough2.qml"));
650     canvas->show();
651     canvas->requestActivateWindow();
652     QVERIFY(canvas->rootObject() != 0);
653
654     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
655     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
656
657     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
658     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
659
660     QTest::qWait(800); // to avoid generating a double click.
661
662     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
663     QTest::qWait(1000);
664     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
665     QTest::qWait(100);
666
667     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
668     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
669     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0);
670
671     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
672     QTest::qWait(100);
673
674     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
675     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0);
676     QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 0);
677     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0);
678
679     canvas->rootObject()->setProperty("letThrough", QVariant(true));
680
681     QTest::qWait(800); // to avoid generating a double click.
682     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
683     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
684
685     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
686     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
687
688     QTest::qWait(800); // to avoid generating a double click.
689     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
690     QTest::qWait(1000);
691     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
692     QTest::qWait(100);
693
694     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
695     QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 1);
696     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
697
698     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
699     QTest::qWait(100);
700
701     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
702     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
703     QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
704     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
705
706     canvas->rootObject()->setProperty("noPropagation", QVariant(true));
707
708     QTest::qWait(800); // to avoid generating a double click.
709     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
710     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
711
712     QTest::qWait(800); // to avoid generating a double click.
713     QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100));
714     QTest::qWait(1000);
715     QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100));
716     QTest::qWait(100);
717
718     QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100));
719     QTest::qWait(100);
720
721     QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0);
722     QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2);
723     QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1);
724     QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1);
725
726     delete canvas;
727 }
728
729 void tst_QQuickMouseArea::hoverPosition()
730 {
731     QQuickView *canvas = createView();
732     canvas->setSource(testFileUrl("hoverPosition.qml"));
733
734     QQuickItem *root = canvas->rootObject();
735     QVERIFY(root != 0);
736
737     QCOMPARE(root->property("mouseX").toReal(), qreal(0));
738     QCOMPARE(root->property("mouseY").toReal(), qreal(0));
739
740     QTest::mouseMove(canvas,QPoint(10,32));
741
742
743     QCOMPARE(root->property("mouseX").toReal(), qreal(10));
744     QCOMPARE(root->property("mouseY").toReal(), qreal(32));
745
746     delete canvas;
747 }
748
749 void tst_QQuickMouseArea::hoverPropagation()
750 {
751     //QTBUG-18175, to behave like GV did.
752     QQuickView *canvas = createView();
753     canvas->setSource(testFileUrl("hoverPropagation.qml"));
754
755     QQuickItem *root = canvas->rootObject();
756     QVERIFY(root != 0);
757
758     QCOMPARE(root->property("point1").toBool(), false);
759     QCOMPARE(root->property("point2").toBool(), false);
760
761     QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, 0);
762     QGuiApplication::sendEvent(canvas, &moveEvent);
763
764     QCOMPARE(root->property("point1").toBool(), true);
765     QCOMPARE(root->property("point2").toBool(), false);
766
767     QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, 0);
768     QGuiApplication::sendEvent(canvas, &moveEvent2);
769     QCOMPARE(root->property("point1").toBool(), false);
770     QCOMPARE(root->property("point2").toBool(), true);
771
772     delete canvas;
773 }
774
775 void tst_QQuickMouseArea::hoverVisible()
776 {
777     QQuickView *canvas = createView();
778     canvas->setSource(testFileUrl("hoverVisible.qml"));
779
780     QQuickItem *root = canvas->rootObject();
781     QVERIFY(root != 0);
782
783     QQuickMouseArea *mouseTracker = canvas->rootObject()->findChild<QQuickMouseArea*>("mousetracker");
784     QVERIFY(mouseTracker != 0);
785
786     QSignalSpy enteredSpy(mouseTracker, SIGNAL(entered()));
787
788     QTest::mouseMove(canvas,QPoint(10,32));
789
790     QCOMPARE(mouseTracker->hovered(), false);
791     QCOMPARE(enteredSpy.count(), 0);
792
793     mouseTracker->setVisible(true);
794
795     QCOMPARE(mouseTracker->hovered(), true);
796     QCOMPARE(enteredSpy.count(), 1);
797
798     QEXPECT_FAIL("", "QTBUG-24282", Continue);
799     QCOMPARE(QPointF(mouseTracker->mouseX(), mouseTracker->mouseY()), QPointF(10,32));
800
801     delete canvas;
802 }
803
804 QTEST_MAIN(tst_QQuickMouseArea)
805
806 #include "tst_qquickmousearea.moc"