1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite of the Qt Toolkit.
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.
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.
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.
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.
40 ****************************************************************************/
44 #include "qquickitem.h"
45 #include "qquickcanvas.h"
46 #include <QtWidgets/QGraphicsSceneMouseEvent>
47 #include "private/qquickfocusscope_p.h"
51 class TestItem : public QQuickItem
55 TestItem(QQuickItem *parent = 0) : QQuickItem(parent), focused(false), pressCount(0), releaseCount(0), wheelCount(0) {}
62 virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; }
63 virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; }
64 virtual void mousePressEvent(QMouseEvent *event) { event->accept(); ++pressCount; }
65 virtual void mouseReleaseEvent(QMouseEvent *event) { event->accept(); ++releaseCount; }
66 virtual void wheelEvent(QWheelEvent *event) { event->accept(); ++wheelCount; }
69 class TestPolishItem : public QQuickItem
73 TestPolishItem(QQuickItem *parent)
74 : QQuickItem(parent), wasPolished(false) {
75 QTimer::singleShot(10, this, SLOT(doPolish()));
81 virtual void updatePolish() {
91 class TestFocusScope : public QQuickFocusScope
95 TestFocusScope(QQuickItem *parent = 0) : QQuickFocusScope(parent), focused(false) {}
99 virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; }
100 virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; }
103 class tst_qquickitem : public QObject
111 void cleanupTestCase();
116 void addedToCanvas();
120 void setParentItem();
126 void polishOutsideAnimation();
128 void wheelEvent_data();
130 void hoverEvent_data();
132 void hoverEventInParent();
136 void ensureFocus(QWindow *w) {
138 w->requestActivateWindow();
139 qApp->processEvents();
142 // to be safe and avoid failing setFocus with window managers
143 qt_x11_wait_for_window_manager(w);
148 tst_qquickitem::tst_qquickitem()
152 void tst_qquickitem::initTestCase()
156 void tst_qquickitem::cleanupTestCase()
160 // Focus has no effect when outside a canvas
161 void tst_qquickitem::noCanvas()
163 QQuickItem *root = new TestItem;
164 QQuickItem *child = new TestItem(root);
165 QQuickItem *scope = new TestItem(root);
166 QQuickFocusScope *scopedChild = new TestFocusScope(scope);
167 QQuickFocusScope *scopedChild2 = new TestFocusScope(scope);
169 QCOMPARE(root->hasFocus(), false);
170 QCOMPARE(child->hasFocus(), false);
171 QCOMPARE(scope->hasFocus(), false);
172 QCOMPARE(scopedChild->hasFocus(), false);
173 QCOMPARE(scopedChild2->hasFocus(), false);
175 root->setFocus(true);
176 scope->setFocus(true);
177 scopedChild2->setFocus(true);
178 QCOMPARE(root->hasFocus(), true);
179 QCOMPARE(child->hasFocus(), false);
180 QCOMPARE(scope->hasFocus(), true);
181 QCOMPARE(scopedChild->hasFocus(), false);
182 QCOMPARE(scopedChild2->hasFocus(), true);
184 root->setFocus(false);
185 child->setFocus(true);
186 scopedChild->setFocus(true);
187 scope->setFocus(false);
188 QCOMPARE(root->hasFocus(), false);
189 QCOMPARE(child->hasFocus(), true);
190 QCOMPARE(scope->hasFocus(), false);
191 QCOMPARE(scopedChild->hasFocus(), true);
192 QCOMPARE(scopedChild2->hasFocus(), true);
198 FocusData() : focus(false), activeFocus(false) {}
200 void set(bool f, bool af) { focus = f; activeFocus = af; }
204 struct FocusState : public QHash<QQuickItem *, FocusData>
206 FocusState() : activeFocusItem(0) {}
207 FocusState &operator<<(QQuickItem *item) {
208 insert(item, FocusData());
212 void active(QQuickItem *i) {
215 QQuickItem *activeFocusItem;
220 if (focusState.activeFocusItem) { \
221 QCOMPARE(canvas.activeFocusItem(), focusState.activeFocusItem); \
222 if (qobject_cast<TestItem *>(canvas.activeFocusItem())) \
223 QCOMPARE(qobject_cast<TestItem *>(canvas.activeFocusItem())->focused, true); \
224 else if (qobject_cast<TestFocusScope *>(canvas.activeFocusItem())) \
225 QCOMPARE(qobject_cast<TestFocusScope *>(canvas.activeFocusItem())->focused, true); \
227 QCOMPARE(canvas.activeFocusItem(), canvas.rootItem()); \
229 for (QHash<QQuickItem *, FocusData>::Iterator iter = focusState.begin(); \
230 iter != focusState.end(); \
232 QCOMPARE(iter.key()->hasFocus(), iter.value().focus); \
233 QCOMPARE(iter.key()->hasActiveFocus(), iter.value().activeFocus); \
237 // Tests a simple set of top-level scoped items
238 void tst_qquickitem::simpleFocus()
241 ensureFocus(&canvas);
242 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
244 QQuickItem *l1c1 = new TestItem(canvas.rootItem());
245 QQuickItem *l1c2 = new TestItem(canvas.rootItem());
246 QQuickItem *l1c3 = new TestItem(canvas.rootItem());
248 QQuickItem *l2c1 = new TestItem(l1c1);
249 QQuickItem *l2c2 = new TestItem(l1c1);
250 QQuickItem *l2c3 = new TestItem(l1c3);
252 FocusState focusState;
253 focusState << l1c1 << l1c2 << l1c3
254 << l2c1 << l2c2 << l2c3;
257 l1c1->setFocus(true);
258 focusState[l1c1].set(true, true);
259 focusState.active(l1c1);
262 l2c3->setFocus(true);
263 focusState[l1c1].set(false, false);
264 focusState[l2c3].set(true, true);
265 focusState.active(l2c3);
268 l1c3->setFocus(true);
269 focusState[l2c3].set(false, false);
270 focusState[l1c3].set(true, true);
271 focusState.active(l1c3);
274 l1c2->setFocus(false);
277 l1c3->setFocus(false);
278 focusState[l1c3].set(false, false);
279 focusState.active(0);
282 l2c1->setFocus(true);
283 focusState[l2c1].set(true, true);
284 focusState.active(l2c1);
288 // Items with a focus scope
289 void tst_qquickitem::scopedFocus()
292 ensureFocus(&canvas);
293 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
295 QQuickItem *l1c1 = new TestItem(canvas.rootItem());
296 QQuickItem *l1c2 = new TestItem(canvas.rootItem());
297 QQuickItem *l1c3 = new TestItem(canvas.rootItem());
299 QQuickItem *l2c1 = new TestItem(l1c1);
300 QQuickItem *l2c2 = new TestItem(l1c1);
301 QQuickItem *l2c3 = new TestFocusScope(l1c3);
303 QQuickItem *l3c1 = new TestItem(l2c3);
304 QQuickItem *l3c2 = new TestFocusScope(l2c3);
306 QQuickItem *l4c1 = new TestItem(l3c2);
307 QQuickItem *l4c2 = new TestItem(l3c2);
309 FocusState focusState;
310 focusState << l1c1 << l1c2 << l1c3
311 << l2c1 << l2c2 << l2c3
316 l4c2->setFocus(true);
317 focusState[l4c2].set(true, false);
320 l4c1->setFocus(true);
321 focusState[l4c2].set(false, false);
322 focusState[l4c1].set(true, false);
325 l1c1->setFocus(true);
326 focusState[l1c1].set(true, true);
327 focusState.active(l1c1);
330 l3c2->setFocus(true);
331 focusState[l3c2].set(true, false);
334 l2c3->setFocus(true);
335 focusState[l1c1].set(false, false);
336 focusState[l2c3].set(true, true);
337 focusState[l3c2].set(true, true);
338 focusState[l4c1].set(true, true);
339 focusState.active(l4c1);
342 l3c2->setFocus(false);
343 focusState[l3c2].set(false, false);
344 focusState[l4c1].set(true, false);
345 focusState.active(l2c3);
348 l3c2->setFocus(true);
349 focusState[l3c2].set(true, true);
350 focusState[l4c1].set(true, true);
351 focusState.active(l4c1);
354 l4c1->setFocus(false);
355 focusState[l4c1].set(false, false);
356 focusState.active(l3c2);
359 l1c3->setFocus(true);
360 focusState[l1c3].set(true, true);
361 focusState[l2c3].set(false, false);
362 focusState[l3c2].set(true, false);
363 focusState.active(l1c3);
367 // Tests focus corrects itself when a tree is added to a canvas for the first time
368 void tst_qquickitem::addedToCanvas()
372 ensureFocus(&canvas);
373 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
375 QQuickItem *item = new TestItem;
377 FocusState focusState;
380 item->setFocus(true);
381 focusState[item].set(true, false);
384 item->setParentItem(canvas.rootItem());
385 focusState[item].set(true, true);
386 focusState.active(item);
392 ensureFocus(&canvas);
393 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
395 QQuickItem *item = new TestItem(canvas.rootItem());
397 QQuickItem *tree = new TestItem;
398 QQuickItem *c1 = new TestItem(tree);
399 QQuickItem *c2 = new TestItem(tree);
401 FocusState focusState;
402 focusState << item << tree << c1 << c2;
404 item->setFocus(true);
407 focusState[item].set(true, true);
408 focusState[c1].set(true, false);
409 focusState[c2].set(true, false);
410 focusState.active(item);
413 tree->setParentItem(item);
414 focusState[c1].set(false, false);
415 focusState[c2].set(false, false);
421 ensureFocus(&canvas);
422 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
424 QQuickItem *tree = new TestItem;
425 QQuickItem *c1 = new TestItem(tree);
426 QQuickItem *c2 = new TestItem(tree);
428 FocusState focusState;
429 focusState << tree << c1 << c2;
432 focusState[c1].set(true, false);
433 focusState[c2].set(true, false);
436 tree->setParentItem(canvas.rootItem());
437 focusState[c1].set(true, true);
438 focusState[c2].set(false, false);
439 focusState.active(c1);
445 ensureFocus(&canvas);
446 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
447 QQuickItem *tree = new TestFocusScope;
448 QQuickItem *c1 = new TestItem(tree);
449 QQuickItem *c2 = new TestItem(tree);
451 FocusState focusState;
452 focusState << tree << c1 << c2;
455 focusState[c1].set(true, false);
456 focusState[c2].set(true, false);
459 tree->setParentItem(canvas.rootItem());
460 focusState[c1].set(true, false);
461 focusState[c2].set(false, false);
464 tree->setFocus(true);
465 focusState[tree].set(true, true);
466 focusState[c1].set(true, true);
467 focusState.active(c1);
473 ensureFocus(&canvas);
474 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
475 QQuickItem *tree = new TestFocusScope;
476 QQuickItem *c1 = new TestItem(tree);
477 QQuickItem *c2 = new TestItem(tree);
479 FocusState focusState;
480 focusState << tree << c1 << c2;
481 tree->setFocus(true);
484 focusState[tree].set(true, false);
485 focusState[c1].set(true, false);
486 focusState[c2].set(true, false);
489 tree->setParentItem(canvas.rootItem());
490 focusState[tree].set(true, true);
491 focusState[c1].set(true, true);
492 focusState[c2].set(false, false);
493 focusState.active(c1);
499 ensureFocus(&canvas);
500 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
501 QQuickItem *child = new TestItem(canvas.rootItem());
502 QQuickItem *tree = new TestFocusScope;
503 QQuickItem *c1 = new TestItem(tree);
504 QQuickItem *c2 = new TestItem(tree);
506 FocusState focusState;
507 focusState << child << tree << c1 << c2;
508 child->setFocus(true);
509 tree->setFocus(true);
512 focusState[child].set(true, true);
513 focusState[tree].set(true, false);
514 focusState[c1].set(true, false);
515 focusState[c2].set(true, false);
516 focusState.active(child);
519 tree->setParentItem(canvas.rootItem());
520 focusState[tree].set(false, false);
521 focusState[c1].set(true, false);
522 focusState[c2].set(false, false);
525 tree->setFocus(true);
526 focusState[child].set(false, false);
527 focusState[tree].set(true, true);
528 focusState[c1].set(true, true);
529 focusState.active(c1);
534 void tst_qquickitem::changeParent()
536 // Parent to no parent
539 ensureFocus(&canvas);
540 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
541 QQuickItem *child = new TestItem(canvas.rootItem());
543 FocusState focusState;
547 child->setFocus(true);
548 focusState[child].set(true, true);
549 focusState.active(child);
552 child->setParentItem(0);
553 focusState[child].set(true, false);
554 focusState.active(0);
558 // Different parent, same focus scope
561 ensureFocus(&canvas);
562 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
563 QQuickItem *child = new TestItem(canvas.rootItem());
564 QQuickItem *child2 = new TestItem(canvas.rootItem());
566 FocusState focusState;
567 focusState << child << child2;
570 child->setFocus(true);
571 focusState[child].set(true, true);
572 focusState.active(child);
575 child->setParentItem(child2);
579 // Different parent, different focus scope
582 ensureFocus(&canvas);
583 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
584 QQuickItem *child = new TestItem(canvas.rootItem());
585 QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
586 QQuickItem *item = new TestItem(child);
588 FocusState focusState;
589 focusState << child << child2 << item;
592 item->setFocus(true);
593 focusState[item].set(true, true);
594 focusState.active(item);
597 item->setParentItem(child2);
598 focusState[item].set(true, false);
599 focusState.active(0);
604 ensureFocus(&canvas);
605 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
606 QQuickItem *child = new TestItem(canvas.rootItem());
607 QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
608 QQuickItem *item = new TestItem(child2);
610 FocusState focusState;
611 focusState << child << child2 << item;
614 item->setFocus(true);
615 focusState[item].set(true, false);
616 focusState.active(0);
619 item->setParentItem(child);
620 focusState[item].set(true, true);
621 focusState.active(item);
626 ensureFocus(&canvas);
627 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
628 QQuickItem *child = new TestItem(canvas.rootItem());
629 QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
630 QQuickItem *item = new TestItem(child2);
632 FocusState focusState;
633 focusState << child << child2 << item;
636 child->setFocus(true);
637 item->setFocus(true);
638 focusState[child].set(true, true);
639 focusState[item].set(true, false);
640 focusState.active(child);
643 item->setParentItem(child);
644 focusState[item].set(false, false);
650 void tst_qquickitem::constructor()
652 QQuickItem *root = new QQuickItem;
653 QVERIFY(root->parent() == 0);
654 QVERIFY(root->parentItem() == 0);
656 QQuickItem *child1 = new QQuickItem(root);
657 QVERIFY(child1->parent() == root);
658 QVERIFY(child1->parentItem() == root);
659 QCOMPARE(root->childItems().count(), 1);
660 QCOMPARE(root->childItems().at(0), child1);
662 QQuickItem *child2 = new QQuickItem(root);
663 QVERIFY(child2->parent() == root);
664 QVERIFY(child2->parentItem() == root);
665 QCOMPARE(root->childItems().count(), 2);
666 QCOMPARE(root->childItems().at(0), child1);
667 QCOMPARE(root->childItems().at(1), child2);
672 void tst_qquickitem::setParentItem()
674 QQuickItem *root = new QQuickItem;
675 QVERIFY(root->parent() == 0);
676 QVERIFY(root->parentItem() == 0);
678 QQuickItem *child1 = new QQuickItem;
679 QVERIFY(child1->parent() == 0);
680 QVERIFY(child1->parentItem() == 0);
682 child1->setParentItem(root);
683 QVERIFY(child1->parent() == 0);
684 QVERIFY(child1->parentItem() == root);
685 QCOMPARE(root->childItems().count(), 1);
686 QCOMPARE(root->childItems().at(0), child1);
688 QQuickItem *child2 = new QQuickItem;
689 QVERIFY(child2->parent() == 0);
690 QVERIFY(child2->parentItem() == 0);
691 child2->setParentItem(root);
692 QVERIFY(child2->parent() == 0);
693 QVERIFY(child2->parentItem() == root);
694 QCOMPARE(root->childItems().count(), 2);
695 QCOMPARE(root->childItems().at(0), child1);
696 QCOMPARE(root->childItems().at(1), child2);
698 child1->setParentItem(0);
699 QVERIFY(child1->parent() == 0);
700 QVERIFY(child1->parentItem() == 0);
701 QCOMPARE(root->childItems().count(), 1);
702 QCOMPARE(root->childItems().at(0), child2);
706 QVERIFY(child1->parent() == 0);
707 QVERIFY(child1->parentItem() == 0);
708 QVERIFY(child2->parent() == 0);
709 QVERIFY(child2->parentItem() == 0);
715 void tst_qquickitem::visible()
717 QQuickItem *root = new QQuickItem;
719 QQuickItem *child1 = new QQuickItem;
720 child1->setParentItem(root);
722 QQuickItem *child2 = new QQuickItem;
723 child2->setParentItem(root);
725 QVERIFY(child1->isVisible());
726 QVERIFY(child2->isVisible());
728 root->setVisible(false);
729 QVERIFY(!child1->isVisible());
730 QVERIFY(!child2->isVisible());
732 root->setVisible(true);
733 QVERIFY(child1->isVisible());
734 QVERIFY(child2->isVisible());
736 child1->setVisible(false);
737 QVERIFY(!child1->isVisible());
738 QVERIFY(child2->isVisible());
740 child2->setParentItem(child1);
741 QVERIFY(!child1->isVisible());
742 QVERIFY(!child2->isVisible());
744 child2->setParentItem(root);
745 QVERIFY(!child1->isVisible());
746 QVERIFY(child2->isVisible());
753 void tst_qquickitem::enabled()
755 QQuickItem *root = new QQuickItem;
757 QQuickItem *child1 = new QQuickItem;
758 child1->setParentItem(root);
760 QQuickItem *child2 = new QQuickItem;
761 child2->setParentItem(root);
763 QVERIFY(child1->isEnabled());
764 QVERIFY(child2->isEnabled());
766 root->setEnabled(false);
767 QVERIFY(!child1->isEnabled());
768 QVERIFY(!child2->isEnabled());
770 root->setEnabled(true);
771 QVERIFY(child1->isEnabled());
772 QVERIFY(child2->isEnabled());
774 child1->setEnabled(false);
775 QVERIFY(!child1->isEnabled());
776 QVERIFY(child2->isEnabled());
778 child2->setParentItem(child1);
779 QVERIFY(!child1->isEnabled());
780 QVERIFY(!child2->isEnabled());
782 child2->setParentItem(root);
783 QVERIFY(!child1->isEnabled());
784 QVERIFY(child2->isEnabled());
791 void tst_qquickitem::mouseGrab()
793 QQuickCanvas *canvas = new QQuickCanvas;
794 canvas->resize(200, 200);
797 TestItem *child1 = new TestItem;
798 child1->setAcceptedMouseButtons(Qt::LeftButton);
799 child1->setSize(QSizeF(200, 100));
800 child1->setParentItem(canvas->rootItem());
802 TestItem *child2 = new TestItem;
803 child2->setAcceptedMouseButtons(Qt::LeftButton);
805 child2->setSize(QSizeF(200, 100));
806 child2->setParentItem(canvas->rootItem());
808 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
810 qDebug() << canvas->mouseGrabberItem();
811 QVERIFY(canvas->mouseGrabberItem() == child1);
814 QCOMPARE(child1->pressCount, 1);
815 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
817 QVERIFY(canvas->mouseGrabberItem() == 0);
818 QCOMPARE(child1->releaseCount, 1);
820 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
822 QVERIFY(canvas->mouseGrabberItem() == child1);
823 QCOMPARE(child1->pressCount, 2);
824 child1->setEnabled(false);
825 QVERIFY(canvas->mouseGrabberItem() == 0);
826 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
828 QCOMPARE(child1->releaseCount, 1);
829 child1->setEnabled(true);
831 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
833 QVERIFY(canvas->mouseGrabberItem() == child1);
834 QCOMPARE(child1->pressCount, 3);
835 child1->setVisible(false);
836 QVERIFY(canvas->mouseGrabberItem() == 0);
837 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
838 QCOMPARE(child1->releaseCount, 1);
839 child1->setVisible(true);
841 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
843 QVERIFY(canvas->mouseGrabberItem() == child1);
844 QCOMPARE(child1->pressCount, 4);
846 QVERIFY(canvas->mouseGrabberItem() == child2);
847 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
849 QCOMPARE(child1->releaseCount, 1);
850 QCOMPARE(child2->releaseCount, 1);
853 QVERIFY(canvas->mouseGrabberItem() == child2);
854 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
856 QCOMPARE(child1->pressCount, 4);
857 QCOMPARE(child2->pressCount, 1);
858 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
860 QCOMPARE(child1->releaseCount, 1);
861 QCOMPARE(child2->releaseCount, 2);
868 void tst_qquickitem::polishOutsideAnimation()
870 QQuickCanvas *canvas = new QQuickCanvas;
871 canvas->resize(200, 200);
874 TestPolishItem *item = new TestPolishItem(canvas->rootItem());
875 item->setSize(QSizeF(200, 100));
877 QTRY_VERIFY(item->wasPolished);
883 void tst_qquickitem::wheelEvent_data()
885 QTest::addColumn<bool>("visible");
886 QTest::addColumn<bool>("enabled");
888 QTest::newRow("visible and enabled") << true << true;
889 QTest::newRow("visible and disabled") << true << false;
890 QTest::newRow("invisible and enabled") << false << true;
891 QTest::newRow("invisible and disabled") << false << false;
894 void tst_qquickitem::wheelEvent()
896 QFETCH(bool, visible);
897 QFETCH(bool, enabled);
899 const bool shouldReceiveWheelEvents = visible && enabled;
901 QQuickCanvas *canvas = new QQuickCanvas;
902 canvas->resize(200, 200);
905 TestItem *item = new TestItem;
906 item->setSize(QSizeF(200, 100));
907 item->setParentItem(canvas->rootItem());
909 item->setEnabled(enabled);
910 item->setVisible(visible);
912 QWheelEvent event(QPoint(100, 50), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
913 event.setAccepted(false);
914 QApplication::sendEvent(canvas, &event);
916 if (shouldReceiveWheelEvents) {
917 QVERIFY(event.isAccepted());
918 QCOMPARE(item->wheelCount, 1);
920 QVERIFY(!event.isAccepted());
921 QCOMPARE(item->wheelCount, 0);
927 class HoverItem : public QQuickItem
931 HoverItem(QQuickItem *parent = 0)
932 : QQuickItem(parent), hoverEnterCount(0), hoverMoveCount(0), hoverLeaveCount(0)
934 void resetCounters() {
943 virtual void hoverEnterEvent(QHoverEvent *event) {
947 virtual void hoverMoveEvent(QHoverEvent *event) {
951 virtual void hoverLeaveEvent(QHoverEvent *event) {
957 void tst_qquickitem::hoverEvent_data()
959 QTest::addColumn<bool>("visible");
960 QTest::addColumn<bool>("enabled");
961 QTest::addColumn<bool>("acceptHoverEvents");
963 QTest::newRow("visible, enabled, accept hover") << true << true << true;
964 QTest::newRow("visible, disabled, accept hover") << true << false << true;
965 QTest::newRow("invisible, enabled, accept hover") << false << true << true;
966 QTest::newRow("invisible, disabled, accept hover") << false << false << true;
968 QTest::newRow("visible, enabled, not accept hover") << true << true << false;
969 QTest::newRow("visible, disabled, not accept hover") << true << false << false;
970 QTest::newRow("invisible, enabled, not accept hover") << false << true << false;
971 QTest::newRow("invisible, disabled, not accept hover") << false << false << false;
974 // ### For some unknown reason QTest::mouseMove() isn't working correctly.
975 static void sendMouseMove(QObject *object, const QPoint &position)
977 QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, 0);
978 QApplication::sendEvent(object, &moveEvent);
981 void tst_qquickitem::hoverEvent()
983 QFETCH(bool, visible);
984 QFETCH(bool, enabled);
985 QFETCH(bool, acceptHoverEvents);
987 QQuickCanvas *canvas = new QQuickCanvas();
988 canvas->resize(200, 200);
991 HoverItem *item = new HoverItem;
992 item->setSize(QSizeF(100, 100));
993 item->setParentItem(canvas->rootItem());
995 item->setEnabled(enabled);
996 item->setVisible(visible);
997 item->setAcceptHoverEvents(acceptHoverEvents);
999 const QPoint outside(150, 150);
1000 const QPoint inside(50, 50);
1001 const QPoint anotherInside(51, 51);
1003 sendMouseMove(canvas, outside);
1004 item->resetCounters();
1006 // Enter, then move twice inside, then leave.
1007 sendMouseMove(canvas, inside);
1008 sendMouseMove(canvas, anotherInside);
1009 sendMouseMove(canvas, inside);
1010 sendMouseMove(canvas, outside);
1012 const bool shouldReceiveHoverEvents = visible && enabled && acceptHoverEvents;
1013 if (shouldReceiveHoverEvents) {
1014 QCOMPARE(item->hoverEnterCount, 1);
1015 QCOMPARE(item->hoverMoveCount, 2);
1016 QCOMPARE(item->hoverLeaveCount, 1);
1018 QCOMPARE(item->hoverEnterCount, 0);
1019 QCOMPARE(item->hoverMoveCount, 0);
1020 QCOMPARE(item->hoverLeaveCount, 0);
1026 void tst_qquickitem::hoverEventInParent()
1028 QQuickCanvas *canvas = new QQuickCanvas();
1029 canvas->resize(200, 200);
1032 HoverItem *parentItem = new HoverItem(canvas->rootItem());
1033 parentItem->setSize(QSizeF(200, 200));
1034 parentItem->setAcceptHoverEvents(true);
1036 HoverItem *leftItem = new HoverItem(parentItem);
1037 leftItem->setSize(QSizeF(100, 200));
1038 leftItem->setAcceptHoverEvents(true);
1040 HoverItem *rightItem = new HoverItem(parentItem);
1041 rightItem->setSize(QSizeF(100, 200));
1042 rightItem->setPos(QPointF(100, 0));
1043 rightItem->setAcceptHoverEvents(true);
1045 const QPoint insideLeft(50, 100);
1046 const QPoint insideRight(150, 100);
1048 sendMouseMove(canvas, insideLeft);
1049 parentItem->resetCounters();
1050 leftItem->resetCounters();
1051 rightItem->resetCounters();
1053 sendMouseMove(canvas, insideRight);
1054 QCOMPARE(parentItem->hoverEnterCount, 0);
1055 QCOMPARE(parentItem->hoverLeaveCount, 0);
1056 QCOMPARE(leftItem->hoverEnterCount, 0);
1057 QCOMPARE(leftItem->hoverLeaveCount, 1);
1058 QCOMPARE(rightItem->hoverEnterCount, 1);
1059 QCOMPARE(rightItem->hoverLeaveCount, 0);
1061 sendMouseMove(canvas, insideLeft);
1062 QCOMPARE(parentItem->hoverEnterCount, 0);
1063 QCOMPARE(parentItem->hoverLeaveCount, 0);
1064 QCOMPARE(leftItem->hoverEnterCount, 1);
1065 QCOMPARE(leftItem->hoverLeaveCount, 1);
1066 QCOMPARE(rightItem->hoverEnterCount, 1);
1067 QCOMPARE(rightItem->hoverLeaveCount, 1);
1072 QTEST_MAIN(tst_qquickitem)
1074 #include "tst_qquickitem.moc"