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