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