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();
143 tst_qquickitem::tst_qquickitem()
147 void tst_qquickitem::initTestCase()
151 void tst_qquickitem::cleanupTestCase()
155 // Focus has no effect when outside a canvas
156 void tst_qquickitem::noCanvas()
158 QQuickItem *root = new TestItem;
159 QQuickItem *child = new TestItem(root);
160 QQuickItem *scope = new TestItem(root);
161 QQuickFocusScope *scopedChild = new TestFocusScope(scope);
162 QQuickFocusScope *scopedChild2 = new TestFocusScope(scope);
164 QCOMPARE(root->hasFocus(), false);
165 QCOMPARE(child->hasFocus(), false);
166 QCOMPARE(scope->hasFocus(), false);
167 QCOMPARE(scopedChild->hasFocus(), false);
168 QCOMPARE(scopedChild2->hasFocus(), false);
170 root->setFocus(true);
171 scope->setFocus(true);
172 scopedChild2->setFocus(true);
173 QCOMPARE(root->hasFocus(), true);
174 QCOMPARE(child->hasFocus(), false);
175 QCOMPARE(scope->hasFocus(), true);
176 QCOMPARE(scopedChild->hasFocus(), false);
177 QCOMPARE(scopedChild2->hasFocus(), true);
179 root->setFocus(false);
180 child->setFocus(true);
181 scopedChild->setFocus(true);
182 scope->setFocus(false);
183 QCOMPARE(root->hasFocus(), false);
184 QCOMPARE(child->hasFocus(), true);
185 QCOMPARE(scope->hasFocus(), false);
186 QCOMPARE(scopedChild->hasFocus(), true);
187 QCOMPARE(scopedChild2->hasFocus(), true);
193 FocusData() : focus(false), activeFocus(false) {}
195 void set(bool f, bool af) { focus = f; activeFocus = af; }
199 struct FocusState : public QHash<QQuickItem *, FocusData>
201 FocusState() : activeFocusItem(0) {}
202 FocusState &operator<<(QQuickItem *item) {
203 insert(item, FocusData());
207 void active(QQuickItem *i) {
210 QQuickItem *activeFocusItem;
215 if (focusState.activeFocusItem) { \
216 QCOMPARE(canvas.activeFocusItem(), focusState.activeFocusItem); \
217 if (qobject_cast<TestItem *>(canvas.activeFocusItem())) \
218 QCOMPARE(qobject_cast<TestItem *>(canvas.activeFocusItem())->focused, true); \
219 else if (qobject_cast<TestFocusScope *>(canvas.activeFocusItem())) \
220 QCOMPARE(qobject_cast<TestFocusScope *>(canvas.activeFocusItem())->focused, true); \
222 QCOMPARE(canvas.activeFocusItem(), canvas.rootItem()); \
224 for (QHash<QQuickItem *, FocusData>::Iterator iter = focusState.begin(); \
225 iter != focusState.end(); \
227 QCOMPARE(iter.key()->hasFocus(), iter.value().focus); \
228 QCOMPARE(iter.key()->hasActiveFocus(), iter.value().activeFocus); \
232 // Tests a simple set of top-level scoped items
233 void tst_qquickitem::simpleFocus()
236 ensureFocus(&canvas);
237 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
239 QQuickItem *l1c1 = new TestItem(canvas.rootItem());
240 QQuickItem *l1c2 = new TestItem(canvas.rootItem());
241 QQuickItem *l1c3 = new TestItem(canvas.rootItem());
243 QQuickItem *l2c1 = new TestItem(l1c1);
244 QQuickItem *l2c2 = new TestItem(l1c1);
245 QQuickItem *l2c3 = new TestItem(l1c3);
247 FocusState focusState;
248 focusState << l1c1 << l1c2 << l1c3
249 << l2c1 << l2c2 << l2c3;
252 l1c1->setFocus(true);
253 focusState[l1c1].set(true, true);
254 focusState.active(l1c1);
257 l2c3->setFocus(true);
258 focusState[l1c1].set(false, false);
259 focusState[l2c3].set(true, true);
260 focusState.active(l2c3);
263 l1c3->setFocus(true);
264 focusState[l2c3].set(false, false);
265 focusState[l1c3].set(true, true);
266 focusState.active(l1c3);
269 l1c2->setFocus(false);
272 l1c3->setFocus(false);
273 focusState[l1c3].set(false, false);
274 focusState.active(0);
277 l2c1->setFocus(true);
278 focusState[l2c1].set(true, true);
279 focusState.active(l2c1);
283 // Items with a focus scope
284 void tst_qquickitem::scopedFocus()
287 ensureFocus(&canvas);
288 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
290 QQuickItem *l1c1 = new TestItem(canvas.rootItem());
291 QQuickItem *l1c2 = new TestItem(canvas.rootItem());
292 QQuickItem *l1c3 = new TestItem(canvas.rootItem());
294 QQuickItem *l2c1 = new TestItem(l1c1);
295 QQuickItem *l2c2 = new TestItem(l1c1);
296 QQuickItem *l2c3 = new TestFocusScope(l1c3);
298 QQuickItem *l3c1 = new TestItem(l2c3);
299 QQuickItem *l3c2 = new TestFocusScope(l2c3);
301 QQuickItem *l4c1 = new TestItem(l3c2);
302 QQuickItem *l4c2 = new TestItem(l3c2);
304 FocusState focusState;
305 focusState << l1c1 << l1c2 << l1c3
306 << l2c1 << l2c2 << l2c3
311 l4c2->setFocus(true);
312 focusState[l4c2].set(true, false);
315 l4c1->setFocus(true);
316 focusState[l4c2].set(false, false);
317 focusState[l4c1].set(true, false);
320 l1c1->setFocus(true);
321 focusState[l1c1].set(true, true);
322 focusState.active(l1c1);
325 l3c2->setFocus(true);
326 focusState[l3c2].set(true, false);
329 l2c3->setFocus(true);
330 focusState[l1c1].set(false, false);
331 focusState[l2c3].set(true, true);
332 focusState[l3c2].set(true, true);
333 focusState[l4c1].set(true, true);
334 focusState.active(l4c1);
337 l3c2->setFocus(false);
338 focusState[l3c2].set(false, false);
339 focusState[l4c1].set(true, false);
340 focusState.active(l2c3);
343 l3c2->setFocus(true);
344 focusState[l3c2].set(true, true);
345 focusState[l4c1].set(true, true);
346 focusState.active(l4c1);
349 l4c1->setFocus(false);
350 focusState[l4c1].set(false, false);
351 focusState.active(l3c2);
354 l1c3->setFocus(true);
355 focusState[l1c3].set(true, true);
356 focusState[l2c3].set(false, false);
357 focusState[l3c2].set(true, false);
358 focusState.active(l1c3);
362 // Tests focus corrects itself when a tree is added to a canvas for the first time
363 void tst_qquickitem::addedToCanvas()
367 ensureFocus(&canvas);
368 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
370 QQuickItem *item = new TestItem;
372 FocusState focusState;
375 item->setFocus(true);
376 focusState[item].set(true, false);
379 item->setParentItem(canvas.rootItem());
380 focusState[item].set(true, true);
381 focusState.active(item);
387 ensureFocus(&canvas);
388 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
390 QQuickItem *item = new TestItem(canvas.rootItem());
392 QQuickItem *tree = new TestItem;
393 QQuickItem *c1 = new TestItem(tree);
394 QQuickItem *c2 = new TestItem(tree);
396 FocusState focusState;
397 focusState << item << tree << c1 << c2;
399 item->setFocus(true);
402 focusState[item].set(true, true);
403 focusState[c1].set(true, false);
404 focusState[c2].set(true, false);
405 focusState.active(item);
408 tree->setParentItem(item);
409 focusState[c1].set(false, false);
410 focusState[c2].set(false, false);
416 ensureFocus(&canvas);
417 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
419 QQuickItem *tree = new TestItem;
420 QQuickItem *c1 = new TestItem(tree);
421 QQuickItem *c2 = new TestItem(tree);
423 FocusState focusState;
424 focusState << tree << c1 << c2;
427 focusState[c1].set(true, false);
428 focusState[c2].set(true, false);
431 tree->setParentItem(canvas.rootItem());
432 focusState[c1].set(true, true);
433 focusState[c2].set(false, false);
434 focusState.active(c1);
440 ensureFocus(&canvas);
441 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
442 QQuickItem *tree = new TestFocusScope;
443 QQuickItem *c1 = new TestItem(tree);
444 QQuickItem *c2 = new TestItem(tree);
446 FocusState focusState;
447 focusState << tree << c1 << c2;
450 focusState[c1].set(true, false);
451 focusState[c2].set(true, false);
454 tree->setParentItem(canvas.rootItem());
455 focusState[c1].set(true, false);
456 focusState[c2].set(false, false);
459 tree->setFocus(true);
460 focusState[tree].set(true, true);
461 focusState[c1].set(true, true);
462 focusState.active(c1);
468 ensureFocus(&canvas);
469 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
470 QQuickItem *tree = new TestFocusScope;
471 QQuickItem *c1 = new TestItem(tree);
472 QQuickItem *c2 = new TestItem(tree);
474 FocusState focusState;
475 focusState << tree << c1 << c2;
476 tree->setFocus(true);
479 focusState[tree].set(true, false);
480 focusState[c1].set(true, false);
481 focusState[c2].set(true, false);
484 tree->setParentItem(canvas.rootItem());
485 focusState[tree].set(true, true);
486 focusState[c1].set(true, true);
487 focusState[c2].set(false, false);
488 focusState.active(c1);
494 ensureFocus(&canvas);
495 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
496 QQuickItem *child = new TestItem(canvas.rootItem());
497 QQuickItem *tree = new TestFocusScope;
498 QQuickItem *c1 = new TestItem(tree);
499 QQuickItem *c2 = new TestItem(tree);
501 FocusState focusState;
502 focusState << child << tree << c1 << c2;
503 child->setFocus(true);
504 tree->setFocus(true);
507 focusState[child].set(true, true);
508 focusState[tree].set(true, false);
509 focusState[c1].set(true, false);
510 focusState[c2].set(true, false);
511 focusState.active(child);
514 tree->setParentItem(canvas.rootItem());
515 focusState[tree].set(false, false);
516 focusState[c1].set(true, false);
517 focusState[c2].set(false, false);
520 tree->setFocus(true);
521 focusState[child].set(false, false);
522 focusState[tree].set(true, true);
523 focusState[c1].set(true, true);
524 focusState.active(c1);
529 void tst_qquickitem::changeParent()
531 // Parent to no parent
534 ensureFocus(&canvas);
535 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
536 QQuickItem *child = new TestItem(canvas.rootItem());
538 FocusState focusState;
542 child->setFocus(true);
543 focusState[child].set(true, true);
544 focusState.active(child);
547 child->setParentItem(0);
548 focusState[child].set(true, false);
549 focusState.active(0);
553 // Different parent, same focus scope
556 ensureFocus(&canvas);
557 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
558 QQuickItem *child = new TestItem(canvas.rootItem());
559 QQuickItem *child2 = new TestItem(canvas.rootItem());
561 FocusState focusState;
562 focusState << child << child2;
565 child->setFocus(true);
566 focusState[child].set(true, true);
567 focusState.active(child);
570 child->setParentItem(child2);
574 // Different parent, different focus scope
577 ensureFocus(&canvas);
578 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
579 QQuickItem *child = new TestItem(canvas.rootItem());
580 QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
581 QQuickItem *item = new TestItem(child);
583 FocusState focusState;
584 focusState << child << child2 << item;
587 item->setFocus(true);
588 focusState[item].set(true, true);
589 focusState.active(item);
592 item->setParentItem(child2);
593 focusState[item].set(true, false);
594 focusState.active(0);
599 ensureFocus(&canvas);
600 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
601 QQuickItem *child = new TestItem(canvas.rootItem());
602 QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
603 QQuickItem *item = new TestItem(child2);
605 FocusState focusState;
606 focusState << child << child2 << item;
609 item->setFocus(true);
610 focusState[item].set(true, false);
611 focusState.active(0);
614 item->setParentItem(child);
615 focusState[item].set(true, true);
616 focusState.active(item);
621 ensureFocus(&canvas);
622 QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas);
623 QQuickItem *child = new TestItem(canvas.rootItem());
624 QQuickItem *child2 = new TestFocusScope(canvas.rootItem());
625 QQuickItem *item = new TestItem(child2);
627 FocusState focusState;
628 focusState << child << child2 << item;
631 child->setFocus(true);
632 item->setFocus(true);
633 focusState[child].set(true, true);
634 focusState[item].set(true, false);
635 focusState.active(child);
638 item->setParentItem(child);
639 focusState[item].set(false, false);
645 void tst_qquickitem::constructor()
647 QQuickItem *root = new QQuickItem;
648 QVERIFY(root->parent() == 0);
649 QVERIFY(root->parentItem() == 0);
651 QQuickItem *child1 = new QQuickItem(root);
652 QVERIFY(child1->parent() == root);
653 QVERIFY(child1->parentItem() == root);
654 QCOMPARE(root->childItems().count(), 1);
655 QCOMPARE(root->childItems().at(0), child1);
657 QQuickItem *child2 = new QQuickItem(root);
658 QVERIFY(child2->parent() == root);
659 QVERIFY(child2->parentItem() == root);
660 QCOMPARE(root->childItems().count(), 2);
661 QCOMPARE(root->childItems().at(0), child1);
662 QCOMPARE(root->childItems().at(1), child2);
667 void tst_qquickitem::setParentItem()
669 QQuickItem *root = new QQuickItem;
670 QVERIFY(root->parent() == 0);
671 QVERIFY(root->parentItem() == 0);
673 QQuickItem *child1 = new QQuickItem;
674 QVERIFY(child1->parent() == 0);
675 QVERIFY(child1->parentItem() == 0);
677 child1->setParentItem(root);
678 QVERIFY(child1->parent() == 0);
679 QVERIFY(child1->parentItem() == root);
680 QCOMPARE(root->childItems().count(), 1);
681 QCOMPARE(root->childItems().at(0), child1);
683 QQuickItem *child2 = new QQuickItem;
684 QVERIFY(child2->parent() == 0);
685 QVERIFY(child2->parentItem() == 0);
686 child2->setParentItem(root);
687 QVERIFY(child2->parent() == 0);
688 QVERIFY(child2->parentItem() == root);
689 QCOMPARE(root->childItems().count(), 2);
690 QCOMPARE(root->childItems().at(0), child1);
691 QCOMPARE(root->childItems().at(1), child2);
693 child1->setParentItem(0);
694 QVERIFY(child1->parent() == 0);
695 QVERIFY(child1->parentItem() == 0);
696 QCOMPARE(root->childItems().count(), 1);
697 QCOMPARE(root->childItems().at(0), child2);
701 QVERIFY(child1->parent() == 0);
702 QVERIFY(child1->parentItem() == 0);
703 QVERIFY(child2->parent() == 0);
704 QVERIFY(child2->parentItem() == 0);
710 void tst_qquickitem::visible()
712 QQuickItem *root = new QQuickItem;
714 QQuickItem *child1 = new QQuickItem;
715 child1->setParentItem(root);
717 QQuickItem *child2 = new QQuickItem;
718 child2->setParentItem(root);
720 QVERIFY(child1->isVisible());
721 QVERIFY(child2->isVisible());
723 root->setVisible(false);
724 QVERIFY(!child1->isVisible());
725 QVERIFY(!child2->isVisible());
727 root->setVisible(true);
728 QVERIFY(child1->isVisible());
729 QVERIFY(child2->isVisible());
731 child1->setVisible(false);
732 QVERIFY(!child1->isVisible());
733 QVERIFY(child2->isVisible());
735 child2->setParentItem(child1);
736 QVERIFY(!child1->isVisible());
737 QVERIFY(!child2->isVisible());
739 child2->setParentItem(root);
740 QVERIFY(!child1->isVisible());
741 QVERIFY(child2->isVisible());
748 void tst_qquickitem::enabled()
750 QQuickItem *root = new QQuickItem;
752 QQuickItem *child1 = new QQuickItem;
753 child1->setParentItem(root);
755 QQuickItem *child2 = new QQuickItem;
756 child2->setParentItem(root);
758 QVERIFY(child1->isEnabled());
759 QVERIFY(child2->isEnabled());
761 root->setEnabled(false);
762 QVERIFY(!child1->isEnabled());
763 QVERIFY(!child2->isEnabled());
765 root->setEnabled(true);
766 QVERIFY(child1->isEnabled());
767 QVERIFY(child2->isEnabled());
769 child1->setEnabled(false);
770 QVERIFY(!child1->isEnabled());
771 QVERIFY(child2->isEnabled());
773 child2->setParentItem(child1);
774 QVERIFY(!child1->isEnabled());
775 QVERIFY(!child2->isEnabled());
777 child2->setParentItem(root);
778 QVERIFY(!child1->isEnabled());
779 QVERIFY(child2->isEnabled());
786 void tst_qquickitem::mouseGrab()
788 QQuickCanvas *canvas = new QQuickCanvas;
789 canvas->resize(200, 200);
792 TestItem *child1 = new TestItem;
793 child1->setAcceptedMouseButtons(Qt::LeftButton);
794 child1->setSize(QSizeF(200, 100));
795 child1->setParentItem(canvas->rootItem());
797 TestItem *child2 = new TestItem;
798 child2->setAcceptedMouseButtons(Qt::LeftButton);
800 child2->setSize(QSizeF(200, 100));
801 child2->setParentItem(canvas->rootItem());
803 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
805 qDebug() << canvas->mouseGrabberItem();
806 QVERIFY(canvas->mouseGrabberItem() == child1);
809 QCOMPARE(child1->pressCount, 1);
810 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
812 QVERIFY(canvas->mouseGrabberItem() == 0);
813 QCOMPARE(child1->releaseCount, 1);
815 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
817 QVERIFY(canvas->mouseGrabberItem() == child1);
818 QCOMPARE(child1->pressCount, 2);
819 child1->setEnabled(false);
820 QVERIFY(canvas->mouseGrabberItem() == 0);
821 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
823 QCOMPARE(child1->releaseCount, 1);
824 child1->setEnabled(true);
826 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
828 QVERIFY(canvas->mouseGrabberItem() == child1);
829 QCOMPARE(child1->pressCount, 3);
830 child1->setVisible(false);
831 QVERIFY(canvas->mouseGrabberItem() == 0);
832 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
833 QCOMPARE(child1->releaseCount, 1);
834 child1->setVisible(true);
836 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
838 QVERIFY(canvas->mouseGrabberItem() == child1);
839 QCOMPARE(child1->pressCount, 4);
841 QVERIFY(canvas->mouseGrabberItem() == child2);
842 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
844 QCOMPARE(child1->releaseCount, 1);
845 QCOMPARE(child2->releaseCount, 1);
848 QVERIFY(canvas->mouseGrabberItem() == child2);
849 QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50));
851 QCOMPARE(child1->pressCount, 4);
852 QCOMPARE(child2->pressCount, 1);
853 QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50));
855 QCOMPARE(child1->releaseCount, 1);
856 QCOMPARE(child2->releaseCount, 2);
863 void tst_qquickitem::polishOutsideAnimation()
865 QQuickCanvas *canvas = new QQuickCanvas;
866 canvas->resize(200, 200);
869 TestPolishItem *item = new TestPolishItem(canvas->rootItem());
870 item->setSize(QSizeF(200, 100));
872 QTRY_VERIFY(item->wasPolished);
878 void tst_qquickitem::wheelEvent_data()
880 QTest::addColumn<bool>("visible");
881 QTest::addColumn<bool>("enabled");
883 QTest::newRow("visible and enabled") << true << true;
884 QTest::newRow("visible and disabled") << true << false;
885 QTest::newRow("invisible and enabled") << false << true;
886 QTest::newRow("invisible and disabled") << false << false;
889 void tst_qquickitem::wheelEvent()
891 QFETCH(bool, visible);
892 QFETCH(bool, enabled);
894 const bool shouldReceiveWheelEvents = visible && enabled;
896 QQuickCanvas *canvas = new QQuickCanvas;
897 canvas->resize(200, 200);
900 TestItem *item = new TestItem;
901 item->setSize(QSizeF(200, 100));
902 item->setParentItem(canvas->rootItem());
904 item->setEnabled(enabled);
905 item->setVisible(visible);
907 QWheelEvent event(QPoint(100, 50), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical);
908 event.setAccepted(false);
909 QApplication::sendEvent(canvas, &event);
911 if (shouldReceiveWheelEvents) {
912 QVERIFY(event.isAccepted());
913 QCOMPARE(item->wheelCount, 1);
915 QVERIFY(!event.isAccepted());
916 QCOMPARE(item->wheelCount, 0);
922 class HoverItem : public QQuickItem
926 HoverItem(QQuickItem *parent = 0)
927 : QQuickItem(parent), hoverEnterCount(0), hoverMoveCount(0), hoverLeaveCount(0)
929 void resetCounters() {
938 virtual void hoverEnterEvent(QHoverEvent *event) {
942 virtual void hoverMoveEvent(QHoverEvent *event) {
946 virtual void hoverLeaveEvent(QHoverEvent *event) {
952 void tst_qquickitem::hoverEvent_data()
954 QTest::addColumn<bool>("visible");
955 QTest::addColumn<bool>("enabled");
956 QTest::addColumn<bool>("acceptHoverEvents");
958 QTest::newRow("visible, enabled, accept hover") << true << true << true;
959 QTest::newRow("visible, disabled, accept hover") << true << false << true;
960 QTest::newRow("invisible, enabled, accept hover") << false << true << true;
961 QTest::newRow("invisible, disabled, accept hover") << false << false << true;
963 QTest::newRow("visible, enabled, not accept hover") << true << true << false;
964 QTest::newRow("visible, disabled, not accept hover") << true << false << false;
965 QTest::newRow("invisible, enabled, not accept hover") << false << true << false;
966 QTest::newRow("invisible, disabled, not accept hover") << false << false << false;
969 // ### For some unknown reason QTest::mouseMove() isn't working correctly.
970 static void sendMouseMove(QObject *object, const QPoint &position)
972 QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, 0);
973 QApplication::sendEvent(object, &moveEvent);
976 void tst_qquickitem::hoverEvent()
978 QFETCH(bool, visible);
979 QFETCH(bool, enabled);
980 QFETCH(bool, acceptHoverEvents);
982 QQuickCanvas *canvas = new QQuickCanvas();
983 canvas->resize(200, 200);
986 HoverItem *item = new HoverItem;
987 item->setSize(QSizeF(100, 100));
988 item->setParentItem(canvas->rootItem());
990 item->setEnabled(enabled);
991 item->setVisible(visible);
992 item->setAcceptHoverEvents(acceptHoverEvents);
994 const QPoint outside(150, 150);
995 const QPoint inside(50, 50);
996 const QPoint anotherInside(51, 51);
998 sendMouseMove(canvas, outside);
999 item->resetCounters();
1001 // Enter, then move twice inside, then leave.
1002 sendMouseMove(canvas, inside);
1003 sendMouseMove(canvas, anotherInside);
1004 sendMouseMove(canvas, inside);
1005 sendMouseMove(canvas, outside);
1007 const bool shouldReceiveHoverEvents = visible && enabled && acceptHoverEvents;
1008 if (shouldReceiveHoverEvents) {
1009 QCOMPARE(item->hoverEnterCount, 1);
1010 QCOMPARE(item->hoverMoveCount, 2);
1011 QCOMPARE(item->hoverLeaveCount, 1);
1013 QCOMPARE(item->hoverEnterCount, 0);
1014 QCOMPARE(item->hoverMoveCount, 0);
1015 QCOMPARE(item->hoverLeaveCount, 0);
1021 void tst_qquickitem::hoverEventInParent()
1023 QQuickCanvas *canvas = new QQuickCanvas();
1024 canvas->resize(200, 200);
1027 HoverItem *parentItem = new HoverItem(canvas->rootItem());
1028 parentItem->setSize(QSizeF(200, 200));
1029 parentItem->setAcceptHoverEvents(true);
1031 HoverItem *leftItem = new HoverItem(parentItem);
1032 leftItem->setSize(QSizeF(100, 200));
1033 leftItem->setAcceptHoverEvents(true);
1035 HoverItem *rightItem = new HoverItem(parentItem);
1036 rightItem->setSize(QSizeF(100, 200));
1037 rightItem->setPos(QPointF(100, 0));
1038 rightItem->setAcceptHoverEvents(true);
1040 const QPoint insideLeft(50, 100);
1041 const QPoint insideRight(150, 100);
1043 sendMouseMove(canvas, insideLeft);
1044 parentItem->resetCounters();
1045 leftItem->resetCounters();
1046 rightItem->resetCounters();
1048 sendMouseMove(canvas, insideRight);
1049 QCOMPARE(parentItem->hoverEnterCount, 0);
1050 QCOMPARE(parentItem->hoverLeaveCount, 0);
1051 QCOMPARE(leftItem->hoverEnterCount, 0);
1052 QCOMPARE(leftItem->hoverLeaveCount, 1);
1053 QCOMPARE(rightItem->hoverEnterCount, 1);
1054 QCOMPARE(rightItem->hoverLeaveCount, 0);
1056 sendMouseMove(canvas, insideLeft);
1057 QCOMPARE(parentItem->hoverEnterCount, 0);
1058 QCOMPARE(parentItem->hoverLeaveCount, 0);
1059 QCOMPARE(leftItem->hoverEnterCount, 1);
1060 QCOMPARE(leftItem->hoverLeaveCount, 1);
1061 QCOMPARE(rightItem->hoverEnterCount, 1);
1062 QCOMPARE(rightItem->hoverLeaveCount, 1);
1067 QTEST_MAIN(tst_qquickitem)
1069 #include "tst_qquickitem.moc"