1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
42 #include <QtTest/QtTest>
43 #include <QtTest/QSignalSpy>
44 #include <QtQuick/private/qquickmousearea_p.h>
45 #include <QtQuick/private/qquickrectangle_p.h>
46 #include <private/qquickflickable_p.h>
47 #include <QtQuick/qquickview.h>
48 #include <QtQml/qqmlcontext.h>
49 #include <QtQml/qqmlengine.h>
50 #include "../../shared/util.h"
51 #include <QtGui/qstylehints.h>
53 class tst_QQuickMouseArea: public QQmlDataTest
57 void dragProperties();
59 void dragging_data() { acceptedButton_data(); }
61 void invalidDrag_data() { rejectedButton_data(); }
63 void setDragOnPressed();
64 void updateMouseAreaPosOnClick();
65 void updateMouseAreaPosOnResize();
66 void noOnClickedWithPressAndHold();
67 void onMousePressRejected();
68 void pressedCanceledOnWindowDeactivate();
69 void doubleClick_data() { acceptedButton_data(); }
71 void clickTwice_data() { acceptedButton_data(); }
73 void invalidClick_data() { rejectedButton_data(); }
75 void pressedOrdering();
76 void preventStealing();
79 void hoverPropagation();
81 void disableAfterPress();
83 void transformedMouseArea_data();
84 void transformedMouseArea();
85 void pressedMultipleButtons_data();
86 void pressedMultipleButtons();
93 void acceptedButton_data();
94 void rejectedButton_data();
96 QQuickView *createView();
99 Q_DECLARE_METATYPE(Qt::MouseButton)
100 Q_DECLARE_METATYPE(Qt::MouseButtons)
102 void tst_QQuickMouseArea::acceptedButton_data()
104 QTest::addColumn<Qt::MouseButtons>("acceptedButtons");
105 QTest::addColumn<Qt::MouseButton>("button");
107 QTest::newRow("left") << Qt::MouseButtons(Qt::LeftButton) << Qt::LeftButton;
108 QTest::newRow("right") << Qt::MouseButtons(Qt::RightButton) << Qt::RightButton;
109 QTest::newRow("middle") << Qt::MouseButtons(Qt::MiddleButton) << Qt::MiddleButton;
111 QTest::newRow("left (left|right)") << Qt::MouseButtons(Qt::LeftButton | Qt::RightButton) << Qt::LeftButton;
112 QTest::newRow("right (right|middle)") << Qt::MouseButtons(Qt::RightButton | Qt::MiddleButton) << Qt::RightButton;
113 QTest::newRow("middle (left|middle)") << Qt::MouseButtons(Qt::LeftButton | Qt::MiddleButton) << Qt::MiddleButton;
116 void tst_QQuickMouseArea::rejectedButton_data()
118 QTest::addColumn<Qt::MouseButtons>("acceptedButtons");
119 QTest::addColumn<Qt::MouseButton>("button");
121 QTest::newRow("middle (left|right)") << Qt::MouseButtons(Qt::LeftButton | Qt::RightButton) << Qt::MiddleButton;
122 QTest::newRow("left (right|middle)") << Qt::MouseButtons(Qt::RightButton | Qt::MiddleButton) << Qt::LeftButton;
123 QTest::newRow("right (left|middle)") << Qt::MouseButtons(Qt::LeftButton | Qt::MiddleButton) << Qt::RightButton;
126 void tst_QQuickMouseArea::dragProperties()
128 QQuickView *window = createView();
130 window->setSource(testFileUrl("dragproperties.qml"));
132 window->requestActivate();
133 QVERIFY(window->rootObject() != 0);
135 QQuickMouseArea *mouseRegion = window->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
136 QQuickDrag *drag = mouseRegion->drag();
137 QVERIFY(mouseRegion != 0);
141 QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
142 QVERIFY(blackRect != 0);
143 QVERIFY(blackRect == drag->target());
144 QQuickItem *rootItem = qobject_cast<QQuickItem*>(window->rootObject());
145 QVERIFY(rootItem != 0);
146 QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
147 drag->setTarget(rootItem);
148 QCOMPARE(targetSpy.count(),1);
149 drag->setTarget(rootItem);
150 QCOMPARE(targetSpy.count(),1);
153 QCOMPARE(drag->axis(), QQuickDrag::XandYAxis);
154 QSignalSpy axisSpy(drag, SIGNAL(axisChanged()));
155 drag->setAxis(QQuickDrag::XAxis);
156 QCOMPARE(drag->axis(), QQuickDrag::XAxis);
157 QCOMPARE(axisSpy.count(),1);
158 drag->setAxis(QQuickDrag::XAxis);
159 QCOMPARE(axisSpy.count(),1);
161 // minimum and maximum properties
162 QSignalSpy xminSpy(drag, SIGNAL(minimumXChanged()));
163 QSignalSpy xmaxSpy(drag, SIGNAL(maximumXChanged()));
164 QSignalSpy yminSpy(drag, SIGNAL(minimumYChanged()));
165 QSignalSpy ymaxSpy(drag, SIGNAL(maximumYChanged()));
167 QCOMPARE(drag->xmin(), 0.0);
168 QCOMPARE(drag->xmax(), rootItem->width()-blackRect->width());
169 QCOMPARE(drag->ymin(), 0.0);
170 QCOMPARE(drag->ymax(), rootItem->height()-blackRect->height());
177 QCOMPARE(drag->xmin(), 10.0);
178 QCOMPARE(drag->xmax(), 10.0);
179 QCOMPARE(drag->ymin(), 10.0);
180 QCOMPARE(drag->ymax(), 10.0);
182 QCOMPARE(xminSpy.count(),1);
183 QCOMPARE(xmaxSpy.count(),1);
184 QCOMPARE(yminSpy.count(),1);
185 QCOMPARE(ymaxSpy.count(),1);
192 QCOMPARE(xminSpy.count(),1);
193 QCOMPARE(xmaxSpy.count(),1);
194 QCOMPARE(yminSpy.count(),1);
195 QCOMPARE(ymaxSpy.count(),1);
198 QSignalSpy filterChildrenSpy(drag, SIGNAL(filterChildrenChanged()));
200 drag->setFilterChildren(true);
202 QVERIFY(drag->filterChildren());
203 QCOMPARE(filterChildrenSpy.count(), 1);
205 drag->setFilterChildren(true);
206 QCOMPARE(filterChildrenSpy.count(), 1);
211 void tst_QQuickMouseArea::resetDrag()
213 QQuickView *window = createView();
215 window->rootContext()->setContextProperty("haveTarget", QVariant(true));
216 window->setSource(testFileUrl("dragreset.qml"));
218 window->requestActivate();
219 QVERIFY(window->rootObject() != 0);
221 QQuickMouseArea *mouseRegion = window->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
222 QQuickDrag *drag = mouseRegion->drag();
223 QVERIFY(mouseRegion != 0);
227 QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
228 QVERIFY(blackRect != 0);
229 QVERIFY(blackRect == drag->target());
230 QQuickItem *rootItem = qobject_cast<QQuickItem*>(window->rootObject());
231 QVERIFY(rootItem != 0);
232 QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
233 QVERIFY(drag->target() != 0);
234 window->rootContext()->setContextProperty("haveTarget", QVariant(false));
235 QCOMPARE(targetSpy.count(),1);
236 QVERIFY(drag->target() == 0);
241 void tst_QQuickMouseArea::dragging()
243 QFETCH(Qt::MouseButtons, acceptedButtons);
244 QFETCH(Qt::MouseButton, button);
246 QQuickView *window = createView();
248 window->setSource(testFileUrl("dragging.qml"));
250 window->requestActivate();
252 QVERIFY(window->rootObject() != 0);
254 QQuickMouseArea *mouseRegion = window->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
255 QQuickDrag *drag = mouseRegion->drag();
256 QVERIFY(mouseRegion != 0);
259 mouseRegion->setAcceptedButtons(acceptedButtons);
262 QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
263 QVERIFY(blackRect != 0);
264 QVERIFY(blackRect == drag->target());
266 QVERIFY(!drag->active());
268 QTest::mousePress(window, button, 0, QPoint(100,100));
270 QVERIFY(!drag->active());
271 QCOMPARE(blackRect->x(), 50.0);
272 QCOMPARE(blackRect->y(), 50.0);
274 // First move event triggers drag, second is acted upon.
275 // This is due to possibility of higher stacked area taking precedence.
277 QTest::mouseMove(window, QPoint(111,111));
279 QTest::mouseMove(window, QPoint(122,122));
282 QVERIFY(drag->active());
283 QCOMPARE(blackRect->x(), 72.0);
284 QCOMPARE(blackRect->y(), 72.0);
286 QTest::mouseRelease(window, button, 0, QPoint(122,122));
289 QVERIFY(!drag->active());
290 QCOMPARE(blackRect->x(), 72.0);
291 QCOMPARE(blackRect->y(), 72.0);
296 void tst_QQuickMouseArea::invalidDrag()
298 QFETCH(Qt::MouseButtons, acceptedButtons);
299 QFETCH(Qt::MouseButton, button);
301 QQuickView *window = createView();
303 window->setSource(testFileUrl("dragging.qml"));
305 window->requestActivate();
307 QVERIFY(window->rootObject() != 0);
309 QQuickMouseArea *mouseRegion = window->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
310 QQuickDrag *drag = mouseRegion->drag();
311 QVERIFY(mouseRegion != 0);
314 mouseRegion->setAcceptedButtons(acceptedButtons);
317 QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
318 QVERIFY(blackRect != 0);
319 QVERIFY(blackRect == drag->target());
321 QVERIFY(!drag->active());
323 QTest::mousePress(window, button, 0, QPoint(100,100));
325 QVERIFY(!drag->active());
326 QCOMPARE(blackRect->x(), 50.0);
327 QCOMPARE(blackRect->y(), 50.0);
329 // First move event triggers drag, second is acted upon.
330 // This is due to possibility of higher stacked area taking precedence.
332 QTest::mouseMove(window, QPoint(111,111));
334 QTest::mouseMove(window, QPoint(122,122));
337 QVERIFY(!drag->active());
338 QCOMPARE(blackRect->x(), 50.0);
339 QCOMPARE(blackRect->y(), 50.0);
341 QTest::mouseRelease(window, button, 0, QPoint(122,122));
344 QVERIFY(!drag->active());
345 QCOMPARE(blackRect->x(), 50.0);
346 QCOMPARE(blackRect->y(), 50.0);
351 void tst_QQuickMouseArea::setDragOnPressed()
353 QQuickView *window = createView();
355 window->setSource(testFileUrl("setDragOnPressed.qml"));
357 window->requestActivate();
359 QVERIFY(window->rootObject() != 0);
361 QQuickMouseArea *mouseArea = qobject_cast<QQuickMouseArea *>(window->rootObject());
365 QQuickItem *target = mouseArea->findChild<QQuickItem*>("target");
368 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
370 QQuickDrag *drag = mouseArea->drag();
372 QVERIFY(!drag->active());
374 QCOMPARE(target->x(), 50.0);
375 QCOMPARE(target->y(), 50.0);
377 // First move event triggers drag, second is acted upon.
378 // This is due to possibility of higher stacked area taking precedence.
380 QTest::mouseMove(window, QPoint(111,102));
382 QTest::mouseMove(window, QPoint(122,122));
385 QVERIFY(drag->active());
386 QCOMPARE(target->x(), 72.0);
387 QCOMPARE(target->y(), 50.0);
389 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(122,122));
392 QVERIFY(!drag->active());
393 QCOMPARE(target->x(), 72.0);
394 QCOMPARE(target->y(), 50.0);
399 QQuickView *tst_QQuickMouseArea::createView()
401 QQuickView *window = new QQuickView(0);
402 window->setBaseSize(QSize(240,320));
407 void tst_QQuickMouseArea::updateMouseAreaPosOnClick()
409 QQuickView *window = createView();
410 window->setSource(testFileUrl("updateMousePosOnClick.qml"));
412 window->requestActivate();
413 QVERIFY(window->rootObject() != 0);
415 QQuickMouseArea *mouseRegion = window->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
416 QVERIFY(mouseRegion != 0);
418 QQuickRectangle *rect = window->rootObject()->findChild<QQuickRectangle*>("ball");
421 QCOMPARE(mouseRegion->mouseX(), rect->x());
422 QCOMPARE(mouseRegion->mouseY(), rect->y());
424 QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
425 QGuiApplication::sendEvent(window, &event);
427 QCOMPARE(mouseRegion->mouseX(), 100.0);
428 QCOMPARE(mouseRegion->mouseY(), 100.0);
430 QCOMPARE(mouseRegion->mouseX(), rect->x());
431 QCOMPARE(mouseRegion->mouseY(), rect->y());
436 void tst_QQuickMouseArea::updateMouseAreaPosOnResize()
438 QQuickView *window = createView();
439 window->setSource(testFileUrl("updateMousePosOnResize.qml"));
441 window->requestActivate();
442 QVERIFY(window->rootObject() != 0);
444 QQuickMouseArea *mouseRegion = window->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
445 QVERIFY(mouseRegion != 0);
447 QQuickRectangle *rect = window->rootObject()->findChild<QQuickRectangle*>("brother");
450 QCOMPARE(mouseRegion->mouseX(), 0.0);
451 QCOMPARE(mouseRegion->mouseY(), 0.0);
453 QMouseEvent event(QEvent::MouseButtonPress, rect->position().toPoint(), Qt::LeftButton, Qt::LeftButton, 0);
454 QGuiApplication::sendEvent(window, &event);
456 QVERIFY(!mouseRegion->property("emitPositionChanged").toBool());
457 QVERIFY(mouseRegion->property("mouseMatchesPos").toBool());
459 QCOMPARE(mouseRegion->property("x1").toReal(), 0.0);
460 QCOMPARE(mouseRegion->property("y1").toReal(), 0.0);
462 QCOMPARE(mouseRegion->property("x2").toReal(), rect->x());
463 QCOMPARE(mouseRegion->property("y2").toReal(), rect->y());
465 QCOMPARE(mouseRegion->mouseX(), rect->x());
466 QCOMPARE(mouseRegion->mouseY(), rect->y());
471 void tst_QQuickMouseArea::noOnClickedWithPressAndHold()
474 // We handle onPressAndHold, therefore no onClicked
475 QQuickView *window = createView();
476 window->setSource(testFileUrl("clickandhold.qml"));
478 window->requestActivate();
479 QVERIFY(window->rootObject() != 0);
481 QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
482 QGuiApplication::sendEvent(window, &pressEvent);
484 QVERIFY(!window->rootObject()->property("clicked").toBool());
485 QVERIFY(!window->rootObject()->property("held").toBool());
489 QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
490 QGuiApplication::sendEvent(window, &releaseEvent);
492 QVERIFY(!window->rootObject()->property("clicked").toBool());
493 QVERIFY(window->rootObject()->property("held").toBool());
499 // We do not handle onPressAndHold, therefore we get onClicked
500 QQuickView *window = createView();
501 window->setSource(testFileUrl("noclickandhold.qml"));
503 window->requestActivate();
504 QVERIFY(window->rootObject() != 0);
506 QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
507 QGuiApplication::sendEvent(window, &pressEvent);
509 QVERIFY(!window->rootObject()->property("clicked").toBool());
513 QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
514 QGuiApplication::sendEvent(window, &releaseEvent);
516 QVERIFY(window->rootObject()->property("clicked").toBool());
522 void tst_QQuickMouseArea::onMousePressRejected()
524 QQuickView *window = createView();
525 window->setSource(testFileUrl("rejectEvent.qml"));
527 window->requestActivate();
528 QVERIFY(window->rootObject() != 0);
529 QVERIFY(window->rootObject()->property("enabled").toBool());
531 QVERIFY(!window->rootObject()->property("mr1_pressed").toBool());
532 QVERIFY(!window->rootObject()->property("mr1_released").toBool());
533 QVERIFY(!window->rootObject()->property("mr1_canceled").toBool());
534 QVERIFY(!window->rootObject()->property("mr2_pressed").toBool());
535 QVERIFY(!window->rootObject()->property("mr2_released").toBool());
536 QVERIFY(!window->rootObject()->property("mr2_canceled").toBool());
538 QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
539 QGuiApplication::sendEvent(window, &pressEvent);
541 QVERIFY(window->rootObject()->property("mr1_pressed").toBool());
542 QVERIFY(!window->rootObject()->property("mr1_released").toBool());
543 QVERIFY(!window->rootObject()->property("mr1_canceled").toBool());
544 QVERIFY(window->rootObject()->property("mr2_pressed").toBool());
545 QVERIFY(!window->rootObject()->property("mr2_released").toBool());
546 QVERIFY(window->rootObject()->property("mr2_canceled").toBool());
550 QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
551 QGuiApplication::sendEvent(window, &releaseEvent);
553 QVERIFY(window->rootObject()->property("mr1_released").toBool());
554 QVERIFY(!window->rootObject()->property("mr1_canceled").toBool());
555 QVERIFY(!window->rootObject()->property("mr2_released").toBool());
559 void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
561 QQuickView *window = createView();
562 window->setSource(testFileUrl("pressedCanceled.qml"));
564 window->requestActivate();
565 QVERIFY(window->rootObject() != 0);
566 QVERIFY(!window->rootObject()->property("pressed").toBool());
567 QVERIFY(!window->rootObject()->property("canceled").toBool());
568 QVERIFY(!window->rootObject()->property("released").toBool());
570 QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
571 QGuiApplication::sendEvent(window, &pressEvent);
573 QVERIFY(window->rootObject()->property("pressed").toBool());
574 QVERIFY(!window->rootObject()->property("canceled").toBool());
575 QVERIFY(!window->rootObject()->property("released").toBool());
579 QEvent windowDeactivateEvent(QEvent::WindowDeactivate);
580 QGuiApplication::sendEvent(window, &windowDeactivateEvent);
581 QVERIFY(!window->rootObject()->property("pressed").toBool());
582 QVERIFY(window->rootObject()->property("canceled").toBool());
583 QVERIFY(!window->rootObject()->property("released").toBool());
588 QGuiApplication::sendEvent(window, &pressEvent);
589 QVERIFY(window->rootObject()->property("pressed").toBool());
590 QVERIFY(!window->rootObject()->property("canceled").toBool());
591 QVERIFY(!window->rootObject()->property("released").toBool());
596 QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
597 QGuiApplication::sendEvent(window, &releaseEvent);
598 QVERIFY(!window->rootObject()->property("pressed").toBool());
599 QVERIFY(!window->rootObject()->property("canceled").toBool());
600 QVERIFY(window->rootObject()->property("released").toBool());
605 void tst_QQuickMouseArea::doubleClick()
607 QFETCH(Qt::MouseButtons, acceptedButtons);
608 QFETCH(Qt::MouseButton, button);
610 QQuickView *window = createView();
611 window->setSource(testFileUrl("doubleclick.qml"));
613 window->requestActivate();
614 QVERIFY(window->rootObject() != 0);
616 QQuickMouseArea *mouseArea = window->rootObject()->findChild<QQuickMouseArea *>("mousearea");
618 mouseArea->setAcceptedButtons(acceptedButtons);
620 // The sequence for a double click is:
621 // press, release, (click), press, double click, release
622 QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, 0);
623 QGuiApplication::sendEvent(window, &pressEvent);
625 QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, 0);
626 QGuiApplication::sendEvent(window, &releaseEvent);
628 QCOMPARE(window->rootObject()->property("released").toInt(), 1);
630 QGuiApplication::sendEvent(window, &pressEvent);
631 pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, 0);
632 QGuiApplication::sendEvent(window, &pressEvent);
633 QGuiApplication::sendEvent(window, &releaseEvent);
635 QCOMPARE(window->rootObject()->property("clicked").toInt(), 1);
636 QCOMPARE(window->rootObject()->property("doubleClicked").toInt(), 1);
637 QCOMPARE(window->rootObject()->property("released").toInt(), 2);
643 void tst_QQuickMouseArea::clickTwice()
645 QFETCH(Qt::MouseButtons, acceptedButtons);
646 QFETCH(Qt::MouseButton, button);
648 QQuickView *window = createView();
649 window->setSource(testFileUrl("clicktwice.qml"));
651 window->requestActivate();
652 QVERIFY(window->rootObject() != 0);
654 QQuickMouseArea *mouseArea = window->rootObject()->findChild<QQuickMouseArea *>("mousearea");
656 mouseArea->setAcceptedButtons(acceptedButtons);
658 QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, 0);
659 QGuiApplication::sendEvent(window, &pressEvent);
661 QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, 0);
662 QGuiApplication::sendEvent(window, &releaseEvent);
664 QCOMPARE(window->rootObject()->property("pressed").toInt(), 1);
665 QCOMPARE(window->rootObject()->property("released").toInt(), 1);
666 QCOMPARE(window->rootObject()->property("clicked").toInt(), 1);
668 QGuiApplication::sendEvent(window, &pressEvent);
669 pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, 0);
670 QGuiApplication::sendEvent(window, &pressEvent);
671 QGuiApplication::sendEvent(window, &releaseEvent);
673 QCOMPARE(window->rootObject()->property("pressed").toInt(), 2);
674 QCOMPARE(window->rootObject()->property("released").toInt(), 2);
675 QCOMPARE(window->rootObject()->property("clicked").toInt(), 2);
680 void tst_QQuickMouseArea::invalidClick()
682 QFETCH(Qt::MouseButtons, acceptedButtons);
683 QFETCH(Qt::MouseButton, button);
685 QQuickView *window = createView();
686 window->setSource(testFileUrl("doubleclick.qml"));
688 window->requestActivate();
689 QVERIFY(window->rootObject() != 0);
691 QQuickMouseArea *mouseArea = window->rootObject()->findChild<QQuickMouseArea *>("mousearea");
693 mouseArea->setAcceptedButtons(acceptedButtons);
695 // The sequence for a double click is:
696 // press, release, (click), press, double click, release
697 QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, 0);
698 QGuiApplication::sendEvent(window, &pressEvent);
700 QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, 0);
701 QGuiApplication::sendEvent(window, &releaseEvent);
703 QCOMPARE(window->rootObject()->property("released").toInt(), 0);
705 QGuiApplication::sendEvent(window, &pressEvent);
706 pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, 0);
707 QGuiApplication::sendEvent(window, &pressEvent);
708 QGuiApplication::sendEvent(window, &releaseEvent);
710 QCOMPARE(window->rootObject()->property("clicked").toInt(), 0);
711 QCOMPARE(window->rootObject()->property("doubleClicked").toInt(), 0);
712 QCOMPARE(window->rootObject()->property("released").toInt(), 0);
717 void tst_QQuickMouseArea::pressedOrdering()
719 QQuickView *window = createView();
720 window->setSource(testFileUrl("pressedOrdering.qml"));
722 window->requestActivate();
723 QVERIFY(window->rootObject() != 0);
725 QCOMPARE(window->rootObject()->property("value").toString(), QLatin1String("base"));
727 QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
728 QGuiApplication::sendEvent(window, &pressEvent);
730 QCOMPARE(window->rootObject()->property("value").toString(), QLatin1String("pressed"));
732 QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0);
733 QGuiApplication::sendEvent(window, &releaseEvent);
735 QCOMPARE(window->rootObject()->property("value").toString(), QLatin1String("toggled"));
737 QGuiApplication::sendEvent(window, &pressEvent);
739 QCOMPARE(window->rootObject()->property("value").toString(), QLatin1String("pressed"));
744 void tst_QQuickMouseArea::preventStealing()
746 QQuickView *window = createView();
748 window->setSource(testFileUrl("preventstealing.qml"));
750 window->requestActivate();
751 QVERIFY(window->rootObject() != 0);
753 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
754 QVERIFY(flickable != 0);
756 QQuickMouseArea *mouseArea = window->rootObject()->findChild<QQuickMouseArea*>("mousearea");
757 QVERIFY(mouseArea != 0);
759 QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*)));
761 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(80, 80));
763 // Without preventStealing, mouse movement over MouseArea would
764 // cause the Flickable to steal mouse and trigger content movement.
766 QTest::mouseMove(window,QPoint(69,69));
767 QTest::mouseMove(window,QPoint(58,58));
768 QTest::mouseMove(window,QPoint(47,47));
770 // We should have received all three move events
771 QCOMPARE(mousePositionSpy.count(), 3);
772 QVERIFY(mouseArea->pressed());
774 // Flickable content should not have moved.
775 QCOMPARE(flickable->contentX(), 0.);
776 QCOMPARE(flickable->contentY(), 0.);
778 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(47, 47));
780 // Now allow stealing and confirm Flickable does its thing.
781 window->rootObject()->setProperty("stealing", false);
783 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(80, 80));
785 // Without preventStealing, mouse movement over MouseArea would
786 // cause the Flickable to steal mouse and trigger content movement.
788 QTest::mouseMove(window,QPoint(69,69));
789 QTest::mouseMove(window,QPoint(58,58));
790 QTest::mouseMove(window,QPoint(47,47));
792 // We should only have received the first move event
793 QCOMPARE(mousePositionSpy.count(), 4);
794 // Our press should be taken away
795 QVERIFY(!mouseArea->pressed());
797 // Flickable content should have moved.
799 QCOMPARE(flickable->contentX(), 11.);
800 QCOMPARE(flickable->contentY(), 11.);
802 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(50, 50));
807 void tst_QQuickMouseArea::clickThrough()
809 QSKIP("QTBUG-23976 Unstable");
810 //With no handlers defined click, doubleClick and PressAndHold should propagate to those with handlers
811 QQuickView *window = createView();
812 window->setSource(testFileUrl("clickThrough.qml"));
814 window->requestActivate();
815 QVERIFY(window->rootObject() != 0);
817 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
818 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(100,100));
820 QTRY_COMPARE(window->rootObject()->property("presses").toInt(), 0);
821 QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 1);
823 // to avoid generating a double click.
824 int doubleClickInterval = qApp->styleHints()->mouseDoubleClickInterval() + 10;
825 QTest::qWait(doubleClickInterval);
827 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
829 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(100,100));
831 QTRY_COMPARE(window->rootObject()->property("presses").toInt(), 0);
832 QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 1);
833 QTRY_COMPARE(window->rootObject()->property("pressAndHolds").toInt(), 1);
835 QTest::mouseDClick(window, Qt::LeftButton, 0, QPoint(100,100));
838 QCOMPARE(window->rootObject()->property("presses").toInt(), 0);
839 QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 2);
840 QTRY_COMPARE(window->rootObject()->property("doubleClicks").toInt(), 1);
841 QCOMPARE(window->rootObject()->property("pressAndHolds").toInt(), 1);
845 //With handlers defined click, doubleClick and PressAndHold should propagate only when explicitly ignored
846 window = createView();
847 window->setSource(testFileUrl("clickThrough2.qml"));
849 window->requestActivate();
850 QVERIFY(window->rootObject() != 0);
852 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
853 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(100,100));
855 QCOMPARE(window->rootObject()->property("presses").toInt(), 0);
856 QCOMPARE(window->rootObject()->property("clicks").toInt(), 0);
858 QTest::qWait(doubleClickInterval); // to avoid generating a double click.
860 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
862 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(100,100));
865 QCOMPARE(window->rootObject()->property("presses").toInt(), 0);
866 QCOMPARE(window->rootObject()->property("clicks").toInt(), 0);
867 QCOMPARE(window->rootObject()->property("pressAndHolds").toInt(), 0);
869 QTest::mouseDClick(window, Qt::LeftButton, 0, QPoint(100,100));
872 QCOMPARE(window->rootObject()->property("presses").toInt(), 0);
873 QCOMPARE(window->rootObject()->property("clicks").toInt(), 0);
874 QCOMPARE(window->rootObject()->property("doubleClicks").toInt(), 0);
875 QCOMPARE(window->rootObject()->property("pressAndHolds").toInt(), 0);
877 window->rootObject()->setProperty("letThrough", QVariant(true));
879 QTest::qWait(doubleClickInterval); // to avoid generating a double click.
880 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
881 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(100,100));
883 QCOMPARE(window->rootObject()->property("presses").toInt(), 0);
884 QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 1);
886 QTest::qWait(doubleClickInterval); // to avoid generating a double click.
887 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
889 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(100,100));
892 QCOMPARE(window->rootObject()->property("presses").toInt(), 0);
893 QCOMPARE(window->rootObject()->property("clicks").toInt(), 1);
894 QCOMPARE(window->rootObject()->property("pressAndHolds").toInt(), 1);
896 QTest::mouseDClick(window, Qt::LeftButton, 0, QPoint(100,100));
899 QCOMPARE(window->rootObject()->property("presses").toInt(), 0);
900 QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 2);
901 QCOMPARE(window->rootObject()->property("doubleClicks").toInt(), 1);
902 QCOMPARE(window->rootObject()->property("pressAndHolds").toInt(), 1);
904 window->rootObject()->setProperty("noPropagation", QVariant(true));
906 QTest::qWait(doubleClickInterval); // to avoid generating a double click.
907 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
908 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(100,100));
910 QTest::qWait(doubleClickInterval); // to avoid generating a double click.
911 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
913 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(100,100));
916 QTest::mouseDClick(window, Qt::LeftButton, 0, QPoint(100,100));
919 QCOMPARE(window->rootObject()->property("presses").toInt(), 0);
920 QTRY_COMPARE(window->rootObject()->property("clicks").toInt(), 2);
921 QCOMPARE(window->rootObject()->property("doubleClicks").toInt(), 1);
922 QCOMPARE(window->rootObject()->property("pressAndHolds").toInt(), 1);
927 void tst_QQuickMouseArea::hoverPosition()
929 QQuickView *window = createView();
930 window->setSource(testFileUrl("hoverPosition.qml"));
932 QQuickItem *root = window->rootObject();
935 QCOMPARE(root->property("mouseX").toReal(), qreal(0));
936 QCOMPARE(root->property("mouseY").toReal(), qreal(0));
938 QTest::mouseMove(window,QPoint(10,32));
941 QCOMPARE(root->property("mouseX").toReal(), qreal(10));
942 QCOMPARE(root->property("mouseY").toReal(), qreal(32));
947 void tst_QQuickMouseArea::hoverPropagation()
949 //QTBUG-18175, to behave like GV did.
950 QQuickView *window = createView();
951 window->setSource(testFileUrl("hoverPropagation.qml"));
953 QQuickItem *root = window->rootObject();
956 QCOMPARE(root->property("point1").toBool(), false);
957 QCOMPARE(root->property("point2").toBool(), false);
959 QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, 0);
960 QGuiApplication::sendEvent(window, &moveEvent);
962 QCOMPARE(root->property("point1").toBool(), true);
963 QCOMPARE(root->property("point2").toBool(), false);
965 QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, 0);
966 QGuiApplication::sendEvent(window, &moveEvent2);
967 QCOMPARE(root->property("point1").toBool(), false);
968 QCOMPARE(root->property("point2").toBool(), true);
973 void tst_QQuickMouseArea::hoverVisible()
975 QQuickView *window = createView();
976 window->setSource(testFileUrl("hoverVisible.qml"));
978 QQuickItem *root = window->rootObject();
981 QQuickMouseArea *mouseTracker = window->rootObject()->findChild<QQuickMouseArea*>("mousetracker");
982 QVERIFY(mouseTracker != 0);
984 QSignalSpy enteredSpy(mouseTracker, SIGNAL(entered()));
986 // Note: We need to use a position that is different from the position in the last event
987 // generated in the previous test case. Otherwise it is not interpreted as a move.
988 QTest::mouseMove(window,QPoint(11,33));
990 QCOMPARE(mouseTracker->hovered(), false);
991 QCOMPARE(enteredSpy.count(), 0);
993 mouseTracker->setVisible(true);
995 QCOMPARE(mouseTracker->hovered(), true);
996 QCOMPARE(enteredSpy.count(), 1);
998 QCOMPARE(QPointF(mouseTracker->mouseX(), mouseTracker->mouseY()), QPointF(11,33));
1003 void tst_QQuickMouseArea::disableAfterPress()
1005 QQuickView *window = createView();
1006 window->setSource(testFileUrl("dragging.qml"));
1008 window->requestActivate();
1010 QVERIFY(window->rootObject() != 0);
1012 QQuickMouseArea *mouseArea = window->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
1013 QQuickDrag *drag = mouseArea->drag();
1014 QVERIFY(mouseArea != 0);
1017 QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*)));
1018 QSignalSpy mousePressSpy(mouseArea, SIGNAL(pressed(QQuickMouseEvent*)));
1019 QSignalSpy mouseReleaseSpy(mouseArea, SIGNAL(released(QQuickMouseEvent*)));
1022 QQuickItem *blackRect = window->rootObject()->findChild<QQuickItem*>("blackrect");
1023 QVERIFY(blackRect != 0);
1024 QVERIFY(blackRect == drag->target());
1026 QVERIFY(!drag->active());
1028 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
1030 QTRY_COMPARE(mousePressSpy.count(), 1);
1032 QVERIFY(!drag->active());
1033 QCOMPARE(blackRect->x(), 50.0);
1034 QCOMPARE(blackRect->y(), 50.0);
1036 // First move event triggers drag, second is acted upon.
1037 // This is due to possibility of higher stacked area taking precedence.
1039 QTest::mouseMove(window, QPoint(111,111));
1041 QTest::mouseMove(window, QPoint(122,122));
1043 QTRY_COMPARE(mousePositionSpy.count(), 2);
1045 QVERIFY(drag->active());
1046 QCOMPARE(blackRect->x(), 72.0);
1047 QCOMPARE(blackRect->y(), 72.0);
1049 mouseArea->setEnabled(false);
1051 // move should still be acted upon
1052 QTest::mouseMove(window, QPoint(133,133));
1054 QTest::mouseMove(window, QPoint(144,144));
1056 QTRY_COMPARE(mousePositionSpy.count(), 4);
1058 QVERIFY(drag->active());
1059 QCOMPARE(blackRect->x(), 94.0);
1060 QCOMPARE(blackRect->y(), 94.0);
1062 QVERIFY(mouseArea->pressed());
1063 QVERIFY(mouseArea->hovered());
1065 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(144,144));
1067 QTRY_COMPARE(mouseReleaseSpy.count(), 1);
1069 QVERIFY(!drag->active());
1070 QCOMPARE(blackRect->x(), 94.0);
1071 QCOMPARE(blackRect->y(), 94.0);
1073 QVERIFY(!mouseArea->pressed());
1074 QVERIFY(!mouseArea->hovered()); // since hover is not enabled
1076 // Next press will be ignored
1077 blackRect->setX(50);
1078 blackRect->setY(50);
1080 mousePressSpy.clear();
1081 mousePositionSpy.clear();
1082 mouseReleaseSpy.clear();
1084 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(100,100));
1086 QCOMPARE(mousePressSpy.count(), 0);
1088 QTest::mouseMove(window, QPoint(111,111));
1090 QTest::mouseMove(window, QPoint(122,122));
1093 QCOMPARE(mousePositionSpy.count(), 0);
1095 QVERIFY(!drag->active());
1096 QCOMPARE(blackRect->x(), 50.0);
1097 QCOMPARE(blackRect->y(), 50.0);
1099 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(122,122));
1102 QCOMPARE(mouseReleaseSpy.count(), 0);
1107 void tst_QQuickMouseArea::onWheel()
1109 QQuickView *window = createView();
1110 window->setSource(testFileUrl("wheel.qml"));
1112 QQuickItem *root = window->rootObject();
1115 QWheelEvent wheelEvent(QPoint(10, 32), QPoint(10, 32), QPoint(60, 20), QPoint(0, 120),
1116 0, Qt::Vertical,Qt::NoButton, Qt::ControlModifier);
1117 QGuiApplication::sendEvent(window, &wheelEvent);
1119 QCOMPARE(root->property("angleDeltaY").toInt(), 120);
1120 QCOMPARE(root->property("mouseX").toReal(), qreal(10));
1121 QCOMPARE(root->property("mouseY").toReal(), qreal(32));
1122 QCOMPARE(root->property("controlPressed").toBool(), true);
1127 void tst_QQuickMouseArea::transformedMouseArea_data()
1129 QTest::addColumn<bool>("insideTarget");
1130 QTest::addColumn<QList<QPoint> >("points");
1132 QList<QPoint> pointsInside;
1133 pointsInside << QPoint(200, 140)
1137 << QPoint(200, 260);
1138 QTest::newRow("checking points inside") << true << pointsInside;
1140 QList<QPoint> pointsOutside;
1141 pointsOutside << QPoint(140, 140)
1146 << QPoint(260, 260);
1147 QTest::newRow("checking points outside") << false << pointsOutside;
1150 void tst_QQuickMouseArea::transformedMouseArea()
1152 QFETCH(bool, insideTarget);
1153 QFETCH(QList<QPoint>, points);
1155 QQuickView *window = createView();
1156 window->setSource(testFileUrl("transformedMouseArea.qml"));
1158 window->requestActivate();
1159 QVERIFY(window->rootObject() != 0);
1161 QQuickMouseArea *mouseArea = window->rootObject()->findChild<QQuickMouseArea *>("mouseArea");
1162 QVERIFY(mouseArea != 0);
1164 foreach (const QPoint &point, points) {
1166 QTest::mouseMove(window, point);
1168 QCOMPARE(mouseArea->property("containsMouse").toBool(), insideTarget);
1170 // check mouse press
1171 QTest::mousePress(window, Qt::LeftButton, 0, point);
1173 QCOMPARE(mouseArea->property("pressed").toBool(), insideTarget);
1175 // check mouse release
1176 QTest::mouseRelease(window, Qt::LeftButton, 0, point);
1178 QCOMPARE(mouseArea->property("pressed").toBool(), false);
1184 void tst_QQuickMouseArea::pressedMultipleButtons_data()
1186 QTest::addColumn<Qt::MouseButtons>("accepted");
1187 QTest::addColumn<QList<Qt::MouseButtons> >("buttons");
1188 QTest::addColumn<QList<bool> >("pressed");
1189 QTest::addColumn<QList<Qt::MouseButtons> >("pressedButtons");
1190 QTest::addColumn<int>("changeCount");
1192 QList<Qt::MouseButtons> buttons;
1193 QList<bool> pressed;
1194 QList<Qt::MouseButtons> pressedButtons;
1195 buttons << Qt::LeftButton
1196 << (Qt::LeftButton | Qt::RightButton)
1203 pressedButtons << Qt::LeftButton
1207 QTest::newRow("Accept Left - Press left, Press Right, Release Right")
1208 << Qt::MouseButtons(Qt::LeftButton) << buttons << pressed << pressedButtons << 2;
1212 pressedButtons.clear();
1213 buttons << Qt::LeftButton
1214 << (Qt::LeftButton | Qt::RightButton)
1221 pressedButtons << Qt::LeftButton
1225 QTest::newRow("Accept Left - Press left, Press Right, Release Left")
1226 << Qt::MouseButtons(Qt::LeftButton) << buttons << pressed << pressedButtons << 2;
1230 pressedButtons.clear();
1231 buttons << Qt::LeftButton
1232 << (Qt::LeftButton | Qt::RightButton)
1239 pressedButtons << Qt::LeftButton
1240 << (Qt::LeftButton | Qt::RightButton)
1243 QTest::newRow("Accept Left|Right - Press left, Press Right, Release Right")
1244 << (Qt::LeftButton | Qt::RightButton) << buttons << pressed << pressedButtons << 4;
1248 pressedButtons.clear();
1249 buttons << Qt::RightButton
1250 << (Qt::LeftButton | Qt::RightButton)
1257 pressedButtons << Qt::RightButton
1261 QTest::newRow("Accept Right - Press Right, Press Left, Release Right")
1262 << Qt::MouseButtons(Qt::RightButton) << buttons << pressed << pressedButtons << 2;
1265 void tst_QQuickMouseArea::pressedMultipleButtons()
1267 QFETCH(Qt::MouseButtons, accepted);
1268 QFETCH(QList<Qt::MouseButtons>, buttons);
1269 QFETCH(QList<bool>, pressed);
1270 QFETCH(QList<Qt::MouseButtons>, pressedButtons);
1271 QFETCH(int, changeCount);
1273 QQuickView *view = createView();
1274 view->setSource(testFileUrl("simple.qml"));
1276 view->requestActivate();
1277 QVERIFY(view->rootObject() != 0);
1279 QQuickMouseArea *mouseArea = view->rootObject()->findChild<QQuickMouseArea *>("mousearea");
1280 QVERIFY(mouseArea != 0);
1282 QSignalSpy pressedSpy(mouseArea, SIGNAL(pressedChanged()));
1283 QSignalSpy pressedButtonsSpy(mouseArea, SIGNAL(pressedButtonsChanged()));
1284 mouseArea->setAcceptedMouseButtons(accepted);
1286 QPoint point(10,10);
1288 int prevButtons = 0;
1289 for (int i = 0; i < buttons.count(); ++i) {
1290 int btns = buttons.at(i);
1292 // The windowsysteminterface takes care of sending releases
1293 QTest::mousePress(view, (Qt::MouseButton)btns, 0, point);
1295 QCOMPARE(mouseArea->pressed(), pressed.at(i));
1296 QCOMPARE(mouseArea->pressedButtons(), pressedButtons.at(i));
1298 prevButtons = buttons.at(i);
1301 QTest::mousePress(view, Qt::NoButton, 0, point);
1302 QCOMPARE(mouseArea->pressed(), false);
1304 QCOMPARE(pressedSpy.count(), 2);
1305 QCOMPARE(pressedButtonsSpy.count(), changeCount);
1310 void tst_QQuickMouseArea::changeAxis()
1312 QQuickView *view = createView();
1314 view->setSource(testFileUrl("changeAxis.qml"));
1316 view->requestActivate();
1317 QTRY_VERIFY(view->rootObject() != 0);
1319 QQuickMouseArea *mouseRegion = view->rootObject()->findChild<QQuickMouseArea*>("mouseregion");
1320 QQuickDrag *drag = mouseRegion->drag();
1321 QVERIFY(mouseRegion != 0);
1324 mouseRegion->setAcceptedButtons(Qt::LeftButton);
1327 QQuickItem *blackRect = view->rootObject()->findChild<QQuickItem*>("blackrect");
1328 QVERIFY(blackRect != 0);
1329 QVERIFY(blackRect == drag->target());
1331 QVERIFY(!drag->active());
1333 // Start a diagonal drag
1334 QTest::mousePress(view, Qt::LeftButton, 0, QPoint(100, 100));
1336 QVERIFY(!drag->active());
1337 QCOMPARE(blackRect->x(), 50.0);
1338 QCOMPARE(blackRect->y(), 50.0);
1340 QTest::mouseMove(view, QPoint(111, 111));
1342 QTest::mouseMove(view, QPoint(122, 122));
1344 QTRY_VERIFY(drag->active());
1345 QCOMPARE(blackRect->x(), 72.0);
1346 QCOMPARE(blackRect->y(), 72.0);
1347 QCOMPARE(drag->axis(), QQuickDrag::XandYAxis);
1349 /* When blackRect.x becomes bigger than 75, the drag axis is changed to
1350 * Drag.YAxis by the QML code. Verify that this happens, and that the drag
1351 * movement is effectively constrained to the Y axis. */
1352 QTest::mouseMove(view, QPoint(133, 133));
1354 QTRY_COMPARE(blackRect->x(), 83.0);
1355 QTRY_COMPARE(blackRect->y(), 83.0);
1356 QTRY_COMPARE(drag->axis(), QQuickDrag::YAxis);
1358 QTest::mouseMove(view, QPoint(144, 144));
1360 QTRY_COMPARE(blackRect->y(), 94.0);
1361 QCOMPARE(blackRect->x(), 83.0);
1363 QTest::mouseRelease(view, Qt::LeftButton, 0, QPoint(144, 144));
1365 QTRY_VERIFY(!drag->active());
1366 QCOMPARE(blackRect->x(), 83.0);
1367 QCOMPARE(blackRect->y(), 94.0);
1372 #ifndef QT_NO_CURSOR
1373 void tst_QQuickMouseArea::cursorShape()
1376 QQmlComponent component(&engine);
1377 component.setData("import QtQuick 2.0\n MouseArea {}", QUrl());
1378 QScopedPointer<QObject> object(component.create());
1379 QQuickMouseArea *mouseArea = qobject_cast<QQuickMouseArea *>(object.data());
1382 QSignalSpy spy(mouseArea, SIGNAL(cursorShapeChanged()));
1384 QCOMPARE(mouseArea->cursorShape(), Qt::ArrowCursor);
1385 QCOMPARE(mouseArea->cursor().shape(), Qt::ArrowCursor);
1387 mouseArea->setCursorShape(Qt::IBeamCursor);
1388 QCOMPARE(mouseArea->cursorShape(), Qt::IBeamCursor);
1389 QCOMPARE(mouseArea->cursor().shape(), Qt::IBeamCursor);
1390 QCOMPARE(spy.count(), 1);
1392 mouseArea->setCursorShape(Qt::IBeamCursor);
1393 QCOMPARE(spy.count(), 1);
1395 mouseArea->setCursorShape(Qt::WaitCursor);
1396 QCOMPARE(mouseArea->cursorShape(), Qt::WaitCursor);
1397 QCOMPARE(mouseArea->cursor().shape(), Qt::WaitCursor);
1398 QCOMPARE(spy.count(), 2);
1402 QTEST_MAIN(tst_QQuickMouseArea)
1404 #include "tst_qquickmousearea.moc"