1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QSignalSpy>
43 #include <QtQml/qqmlengine.h>
44 #include <QtQml/qqmlcomponent.h>
45 #include <QtQml/qqmlcontext.h>
46 #include <QtQuick/qquickview.h>
47 #include <QtGui/private/qinputmethod_p.h>
48 #include <QtQuick/private/qquickrectangle_p.h>
49 #include <QtQuick/private/qquicktextinput_p.h>
50 #include <private/qquickitem_p.h>
51 #include "../../shared/util.h"
52 #include "../shared/visualtestutil.h"
53 #include "../../shared/platforminputcontext.h"
55 using namespace QQuickVisualTestUtil;
57 class tst_QQuickItem : public QQmlDataTest
68 void keysProcessingOrder();
71 void keyNavigation_RightToLeft();
72 void keyNavigation_skipNotVisible();
73 void keyNavigation_implicitSetting();
74 void layoutMirroring();
75 void layoutMirroringIllegalParent();
78 void mapCoordinates();
79 void mapCoordinates_data();
80 void mapCoordinatesRect();
81 void mapCoordinatesRect_data();
82 void propertyChanges();
84 void transforms_data();
86 void childrenRectBug();
87 void childrenRectBug2();
88 void childrenRectBug3();
90 void childrenProperty();
91 void resourcesProperty();
93 void transformCrash();
96 void visibleChildren();
105 class KeysTestObject : public QObject
109 Q_PROPERTY(bool processLast READ processLast NOTIFY processLastChanged)
112 KeysTestObject() : mKey(0), mModifiers(0), mForwardedKey(0), mLast(false), mNativeScanCode(0) {}
122 bool processLast() const { return mLast; }
123 void setProcessLast(bool b) {
126 emit processLastChanged();
131 void keyPress(int key, QString text, int modifiers) {
134 mModifiers = modifiers;
136 void keyRelease(int key, QString text, int modifiers) {
139 mModifiers = modifiers;
141 void forwardedKey(int key) {
144 void specialKey(int key, QString text, quint32 nativeScanCode) {
147 mNativeScanCode = nativeScanCode;
151 void processLastChanged();
159 quint32 mNativeScanCode;
164 class KeyTestItem : public QQuickItem
168 KeyTestItem(QQuickItem *parent=0) : QQuickItem(parent), mKey(0) {}
171 void keyPressEvent(QKeyEvent *e) {
174 if (e->key() == Qt::Key_A)
180 void keyReleaseEvent(QKeyEvent *e) {
181 if (e->key() == Qt::Key_B)
191 QML_DECLARE_TYPE(KeyTestItem);
193 class HollowTestItem : public QQuickItem
196 Q_PROPERTY(bool circle READ isCircle WRITE setCircle)
197 Q_PROPERTY(qreal holeRadius READ holeRadius WRITE setHoleRadius)
200 HollowTestItem(QQuickItem *parent = 0)
201 : QQuickItem(parent),
207 setAcceptHoverEvents(true);
208 setAcceptedMouseButtons(Qt::LeftButton);
211 bool isPressed() const { return m_isPressed; }
212 bool isHovered() const { return m_isHovered; }
214 bool isCircle() const { return m_isCircle; }
215 void setCircle(bool circle) { m_isCircle = circle; }
217 qreal holeRadius() const { return m_holeRadius; }
218 void setHoleRadius(qreal radius) { m_holeRadius = radius; }
220 bool contains(const QPointF &point) const {
221 const qreal w = width();
222 const qreal h = height();
223 const qreal r = m_holeRadius;
226 if (!QRectF(0, 0, w, h).contains(point))
231 return !QRectF(w / 2 - r, h / 2 - r, r * 2, r * 2).contains(point);
234 const qreal dx = point.x() - (w / 2);
235 const qreal dy = point.y() - (h / 2);
236 const qreal dd = (dx * dx) + (dy * dy);
237 const qreal outerRadius = qMin<qreal>(w / 2, h / 2);
238 return dd > (r * r) && dd <= outerRadius * outerRadius;
242 void hoverEnterEvent(QHoverEvent *) { m_isHovered = true; }
243 void hoverLeaveEvent(QHoverEvent *) { m_isHovered = false; }
244 void mousePressEvent(QMouseEvent *) { m_isPressed = true; }
245 void mouseReleaseEvent(QMouseEvent *) { m_isPressed = false; }
254 QML_DECLARE_TYPE(HollowTestItem);
257 tst_QQuickItem::tst_QQuickItem()
261 void tst_QQuickItem::initTestCase()
263 QQmlDataTest::initTestCase();
264 qmlRegisterType<KeyTestItem>("Test",1,0,"KeyTestItem");
265 qmlRegisterType<HollowTestItem>("Test", 1, 0, "HollowTestItem");
268 void tst_QQuickItem::cleanup()
270 QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
271 inputMethodPrivate->testContext = 0;
274 void tst_QQuickItem::keys()
276 QQuickView *window = new QQuickView(0);
277 window->setBaseSize(QSize(240,320));
279 KeysTestObject *testObject = new KeysTestObject;
280 window->rootContext()->setContextProperty("keysTestObject", testObject);
282 window->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
283 window->rootContext()->setContextProperty("forwardeeVisible", QVariant(true));
285 window->setSource(testFileUrl("keystest.qml"));
287 window->requestActivateWindow();
288 QTest::qWaitForWindowShown(window);
289 QTRY_VERIFY(QGuiApplication::focusWindow() == window);
291 QVERIFY(window->rootObject());
292 QCOMPARE(window->rootObject()->property("isEnabled").toBool(), true);
294 QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
295 QGuiApplication::sendEvent(window, &key);
296 QCOMPARE(testObject->mKey, int(Qt::Key_A));
297 QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
298 QCOMPARE(testObject->mText, QLatin1String("A"));
299 QVERIFY(testObject->mModifiers == Qt::NoModifier);
300 QVERIFY(!key.isAccepted());
304 key = QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier, "A", false, 1);
305 QGuiApplication::sendEvent(window, &key);
306 QCOMPARE(testObject->mKey, int(Qt::Key_A));
307 QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A));
308 QCOMPARE(testObject->mText, QLatin1String("A"));
309 QVERIFY(testObject->mModifiers == Qt::ShiftModifier);
310 QVERIFY(key.isAccepted());
314 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
315 QGuiApplication::sendEvent(window, &key);
316 QCOMPARE(testObject->mKey, int(Qt::Key_Return));
317 QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Return));
318 QCOMPARE(testObject->mText, QLatin1String("Return"));
319 QVERIFY(testObject->mModifiers == Qt::NoModifier);
320 QVERIFY(key.isAccepted());
324 key = QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0", false, 1);
325 QGuiApplication::sendEvent(window, &key);
326 QCOMPARE(testObject->mKey, int(Qt::Key_0));
327 QCOMPARE(testObject->mForwardedKey, int(Qt::Key_0));
328 QCOMPARE(testObject->mText, QLatin1String("0"));
329 QVERIFY(testObject->mModifiers == Qt::NoModifier);
330 QVERIFY(key.isAccepted());
334 key = QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9", false, 1);
335 QGuiApplication::sendEvent(window, &key);
336 QCOMPARE(testObject->mKey, int(Qt::Key_9));
337 QCOMPARE(testObject->mForwardedKey, int(Qt::Key_9));
338 QCOMPARE(testObject->mText, QLatin1String("9"));
339 QVERIFY(testObject->mModifiers == Qt::NoModifier);
340 QVERIFY(!key.isAccepted());
344 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
345 QGuiApplication::sendEvent(window, &key);
346 QCOMPARE(testObject->mKey, int(Qt::Key_Tab));
347 QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Tab));
348 QCOMPARE(testObject->mText, QLatin1String("Tab"));
349 QVERIFY(testObject->mModifiers == Qt::NoModifier);
350 QVERIFY(key.isAccepted());
354 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
355 QGuiApplication::sendEvent(window, &key);
356 QCOMPARE(testObject->mKey, int(Qt::Key_Backtab));
357 QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Backtab));
358 QCOMPARE(testObject->mText, QLatin1String("Backtab"));
359 QVERIFY(testObject->mModifiers == Qt::NoModifier);
360 QVERIFY(key.isAccepted());
364 key = QKeyEvent(QEvent::KeyPress, Qt::Key_VolumeUp, Qt::NoModifier, 1234, 0, 0);
365 QGuiApplication::sendEvent(window, &key);
366 QCOMPARE(testObject->mKey, int(Qt::Key_VolumeUp));
367 QCOMPARE(testObject->mForwardedKey, int(Qt::Key_VolumeUp));
368 QVERIFY(testObject->mModifiers == Qt::NoModifier);
369 QVERIFY(testObject->mNativeScanCode == 1234);
370 QVERIFY(key.isAccepted());
374 window->rootContext()->setContextProperty("forwardeeVisible", QVariant(false));
375 key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
376 QGuiApplication::sendEvent(window, &key);
377 QCOMPARE(testObject->mKey, int(Qt::Key_A));
378 QCOMPARE(testObject->mForwardedKey, 0);
379 QCOMPARE(testObject->mText, QLatin1String("A"));
380 QVERIFY(testObject->mModifiers == Qt::NoModifier);
381 QVERIFY(!key.isAccepted());
385 window->rootContext()->setContextProperty("enableKeyHanding", QVariant(false));
386 QCOMPARE(window->rootObject()->property("isEnabled").toBool(), false);
388 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
389 QGuiApplication::sendEvent(window, &key);
390 QCOMPARE(testObject->mKey, 0);
391 QVERIFY(!key.isAccepted());
393 window->rootContext()->setContextProperty("enableKeyHanding", QVariant(true));
394 QCOMPARE(window->rootObject()->property("isEnabled").toBool(), true);
396 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1);
397 QGuiApplication::sendEvent(window, &key);
398 QCOMPARE(testObject->mKey, int(Qt::Key_Return));
399 QVERIFY(key.isAccepted());
405 void tst_QQuickItem::keysProcessingOrder()
407 QQuickView *window = new QQuickView(0);
408 window->setBaseSize(QSize(240,320));
410 KeysTestObject *testObject = new KeysTestObject;
411 window->rootContext()->setContextProperty("keysTestObject", testObject);
413 window->setSource(testFileUrl("keyspriority.qml"));
415 window->requestActivateWindow();
416 QTest::qWaitForWindowShown(window);
417 QTRY_VERIFY(QGuiApplication::focusWindow() == window);
419 KeyTestItem *testItem = qobject_cast<KeyTestItem*>(window->rootObject());
422 QCOMPARE(testItem->property("priorityTest").toInt(), 0);
424 QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
425 QGuiApplication::sendEvent(window, &key);
426 QCOMPARE(testObject->mKey, int(Qt::Key_A));
427 QCOMPARE(testObject->mText, QLatin1String("A"));
428 QVERIFY(testObject->mModifiers == Qt::NoModifier);
429 QVERIFY(key.isAccepted());
433 testObject->setProcessLast(true);
435 QCOMPARE(testItem->property("priorityTest").toInt(), 1);
437 key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1);
438 QGuiApplication::sendEvent(window, &key);
439 QCOMPARE(testObject->mKey, 0);
440 QVERIFY(key.isAccepted());
444 key = QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier, "B", false, 1);
445 QGuiApplication::sendEvent(window, &key);
446 QCOMPARE(testObject->mKey, int(Qt::Key_B));
447 QCOMPARE(testObject->mText, QLatin1String("B"));
448 QVERIFY(testObject->mModifiers == Qt::NoModifier);
449 QVERIFY(!key.isAccepted());
453 key = QKeyEvent(QEvent::KeyRelease, Qt::Key_B, Qt::NoModifier, "B", false, 1);
454 QGuiApplication::sendEvent(window, &key);
455 QCOMPARE(testObject->mKey, 0);
456 QVERIFY(key.isAccepted());
462 void tst_QQuickItem::keysim()
464 PlatformInputContext platformInputContext;
465 QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
466 inputMethodPrivate->testContext = &platformInputContext;
468 QQuickView *window = new QQuickView(0);
469 window->setBaseSize(QSize(240,320));
471 window->setSource(testFileUrl("keysim.qml"));
473 window->requestActivateWindow();
474 QTest::qWaitForWindowShown(window);
475 QTRY_VERIFY(QGuiApplication::focusWindow() == window);
477 QVERIFY(window->rootObject());
478 QVERIFY(window->rootObject()->hasFocus() && window->rootObject()->hasActiveFocus());
480 QQuickTextInput *input = window->rootObject()->findChild<QQuickTextInput*>();
483 QInputMethodEvent ev("Hello world!", QList<QInputMethodEvent::Attribute>());
484 QGuiApplication::sendEvent(qGuiApp->focusObject(), &ev);
486 QEXPECT_FAIL("", "QTBUG-24280", Continue);
487 QCOMPARE(input->text(), QLatin1String("Hello world!"));
492 QQuickItemPrivate *childPrivate(QQuickItem *rootItem, const char * itemString)
494 QQuickItem *item = findItem<QQuickItem>(rootItem, QString(QLatin1String(itemString)));
495 QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item);
499 QVariant childProperty(QQuickItem *rootItem, const char * itemString, const char * property)
501 QQuickItem *item = findItem<QQuickItem>(rootItem, QString(QLatin1String(itemString)));
502 return item->property(property);
505 bool anchorsMirrored(QQuickItem *rootItem, const char * itemString)
507 QQuickItem *item = findItem<QQuickItem>(rootItem, QString(QLatin1String(itemString)));
508 QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item);
509 return itemPrivate->anchors()->mirrored();
512 void tst_QQuickItem::layoutMirroring()
514 QQuickView *window = new QQuickView(0);
515 window->setSource(testFileUrl("layoutmirroring.qml"));
518 QQuickItem *rootItem = qobject_cast<QQuickItem*>(window->rootObject());
520 QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(rootItem);
521 QVERIFY(rootPrivate);
523 QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
524 QCOMPARE(childPrivate(rootItem, "mirrored2")->effectiveLayoutMirror, true);
525 QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
526 QCOMPARE(childPrivate(rootItem, "notMirrored2")->effectiveLayoutMirror, false);
527 QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
528 QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
530 QCOMPARE(anchorsMirrored(rootItem, "mirrored1"), true);
531 QCOMPARE(anchorsMirrored(rootItem, "mirrored2"), true);
532 QCOMPARE(anchorsMirrored(rootItem, "notMirrored1"), false);
533 QCOMPARE(anchorsMirrored(rootItem, "notMirrored2"), false);
534 QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror1"), true);
535 QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror2"), true);
537 QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
538 QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritedLayoutMirror, false);
539 QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
540 QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritedLayoutMirror, false);
541 QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
542 QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
544 QCOMPARE(childPrivate(rootItem, "mirrored1")->isMirrorImplicit, false);
545 QCOMPARE(childPrivate(rootItem, "mirrored2")->isMirrorImplicit, false);
546 QCOMPARE(childPrivate(rootItem, "notMirrored1")->isMirrorImplicit, false);
547 QCOMPARE(childPrivate(rootItem, "notMirrored2")->isMirrorImplicit, true);
548 QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->isMirrorImplicit, true);
549 QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->isMirrorImplicit, true);
551 QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromParent, true);
552 QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromParent, false);
553 QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromParent, true);
554 QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromParent, false);
555 QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromParent, true);
556 QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromParent, true);
558 QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromItem, true);
559 QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromItem, false);
560 QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromItem, false);
561 QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromItem, false);
562 QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromItem, false);
563 QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromItem, false);
565 // load dynamic content using Loader that needs to inherit mirroring
566 rootItem->setProperty("state", "newContent");
567 QCOMPARE(childPrivate(rootItem, "notMirrored3")->effectiveLayoutMirror, false);
568 QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->effectiveLayoutMirror, true);
570 QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritedLayoutMirror, true);
571 QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritedLayoutMirror, true);
573 QCOMPARE(childPrivate(rootItem, "notMirrored3")->isMirrorImplicit, false);
574 QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->isMirrorImplicit, true);
576 QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromParent, true);
577 QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritMirrorFromParent, true);
579 QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
580 QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false);
582 // disable inheritance
583 rootItem->setProperty("childrenInherit", false);
585 QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, false);
586 QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, false);
587 QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
588 QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
590 QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, false);
591 QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, false);
592 QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, false);
593 QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, false);
595 // re-enable inheritance
596 rootItem->setProperty("childrenInherit", true);
598 QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true);
599 QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true);
600 QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true);
601 QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false);
603 QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true);
604 QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true);
605 QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true);
606 QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true);
611 QQuickItem *parentItem1 = new QQuickItem();
612 QQuickItemPrivate::get(parentItem1)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
613 QQuickItemPrivate::get(parentItem1)->isMirrorImplicit = false;
614 QQuickItemPrivate::get(parentItem1)->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true
615 QQuickItemPrivate::get(parentItem1)->resolveLayoutMirror();
617 // inherit in constructor
618 QQuickItem *childItem1 = new QQuickItem(parentItem1);
619 QCOMPARE(QQuickItemPrivate::get(childItem1)->effectiveLayoutMirror, true);
620 QCOMPARE(QQuickItemPrivate::get(childItem1)->inheritMirrorFromParent, true);
622 // inherit through a parent change
623 QQuickItem *childItem2 = new QQuickItem();
624 QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
625 QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
626 childItem2->setParentItem(parentItem1);
627 QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, true);
628 QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, true);
630 // stop inherting through a parent change
631 QQuickItem *parentItem2 = new QQuickItem();
632 QQuickItemPrivate::get(parentItem2)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true
633 QQuickItemPrivate::get(parentItem2)->resolveLayoutMirror();
634 childItem2->setParentItem(parentItem2);
635 QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false);
636 QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false);
642 void tst_QQuickItem::layoutMirroringIllegalParent()
644 QQmlComponent component(&engine);
645 component.setData("import QtQuick 2.0; QtObject { LayoutMirroring.enabled: true; LayoutMirroring.childrenInherit: true }", QUrl::fromLocalFile(""));
646 QTest::ignoreMessage(QtWarningMsg, "file::1:21: QML QtObject: LayoutDirection attached property only works with Items");
647 QObject *object = component.create();
648 QVERIFY(object != 0);
651 void tst_QQuickItem::keyNavigation()
653 QQuickView *window = new QQuickView(0);
654 window->setBaseSize(QSize(240,320));
656 window->setSource(testFileUrl("keynavigationtest.qml"));
658 window->requestActivateWindow();
659 QTest::qWaitForWindowShown(window);
660 QTRY_VERIFY(QGuiApplication::focusWindow() == window);
662 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item1");
664 QVERIFY(item->hasActiveFocus());
667 QVERIFY(QMetaObject::invokeMethod(window->rootObject(), "verify",
668 Q_RETURN_ARG(QVariant, result)));
669 QVERIFY(result.toBool());
672 QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
673 QGuiApplication::sendEvent(window, &key);
674 QVERIFY(key.isAccepted());
676 item = findItem<QQuickItem>(window->rootObject(), "item2");
678 QVERIFY(item->hasActiveFocus());
681 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
682 QGuiApplication::sendEvent(window, &key);
683 QVERIFY(key.isAccepted());
685 item = findItem<QQuickItem>(window->rootObject(), "item4");
687 QVERIFY(item->hasActiveFocus());
690 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
691 QGuiApplication::sendEvent(window, &key);
692 QVERIFY(key.isAccepted());
694 item = findItem<QQuickItem>(window->rootObject(), "item3");
696 QVERIFY(item->hasActiveFocus());
699 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
700 QGuiApplication::sendEvent(window, &key);
701 QVERIFY(key.isAccepted());
703 item = findItem<QQuickItem>(window->rootObject(), "item1");
705 QVERIFY(item->hasActiveFocus());
708 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
709 QGuiApplication::sendEvent(window, &key);
710 QVERIFY(key.isAccepted());
712 item = findItem<QQuickItem>(window->rootObject(), "item2");
714 QVERIFY(item->hasActiveFocus());
717 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
718 QGuiApplication::sendEvent(window, &key);
719 QVERIFY(key.isAccepted());
721 item = findItem<QQuickItem>(window->rootObject(), "item1");
723 QVERIFY(item->hasActiveFocus());
728 void tst_QQuickItem::keyNavigation_RightToLeft()
730 QQuickView *window = new QQuickView(0);
731 window->setBaseSize(QSize(240,320));
733 window->setSource(testFileUrl("keynavigationtest.qml"));
735 window->requestActivateWindow();
736 QTest::qWaitForWindowShown(window);
737 QTRY_VERIFY(QGuiApplication::focusWindow() == window);
739 QQuickItem *rootItem = qobject_cast<QQuickItem*>(window->rootObject());
741 QQuickItemPrivate* rootItemPrivate = QQuickItemPrivate::get(rootItem);
743 rootItemPrivate->effectiveLayoutMirror = true; // LayoutMirroring.mirror: true
744 rootItemPrivate->isMirrorImplicit = false;
745 rootItemPrivate->inheritMirrorFromItem = true; // LayoutMirroring.inherit: true
746 rootItemPrivate->resolveLayoutMirror();
748 QEvent wa(QEvent::WindowActivate);
749 QGuiApplication::sendEvent(window, &wa);
750 QFocusEvent fe(QEvent::FocusIn);
751 QGuiApplication::sendEvent(window, &fe);
753 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item1");
755 QVERIFY(item->hasActiveFocus());
758 QVERIFY(QMetaObject::invokeMethod(window->rootObject(), "verify",
759 Q_RETURN_ARG(QVariant, result)));
760 QVERIFY(result.toBool());
763 QKeyEvent key(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
764 QGuiApplication::sendEvent(window, &key);
765 QVERIFY(key.isAccepted());
767 item = findItem<QQuickItem>(window->rootObject(), "item2");
769 QVERIFY(item->hasActiveFocus());
772 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
773 QGuiApplication::sendEvent(window, &key);
774 QVERIFY(key.isAccepted());
776 item = findItem<QQuickItem>(window->rootObject(), "item1");
778 QVERIFY(item->hasActiveFocus());
783 void tst_QQuickItem::keyNavigation_skipNotVisible()
785 QQuickView *window = new QQuickView(0);
786 window->setBaseSize(QSize(240,320));
788 window->setSource(testFileUrl("keynavigationtest.qml"));
790 window->requestActivateWindow();
791 QTest::qWaitForWindowShown(window);
792 QTRY_VERIFY(QGuiApplication::focusWindow() == window);
794 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item1");
796 QVERIFY(item->hasActiveFocus());
798 // Set item 2 to not visible
799 item = findItem<QQuickItem>(window->rootObject(), "item2");
801 item->setVisible(false);
802 QVERIFY(!item->isVisible());
805 QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
806 QGuiApplication::sendEvent(window, &key);
807 QVERIFY(key.isAccepted());
809 item = findItem<QQuickItem>(window->rootObject(), "item1");
811 QVERIFY(item->hasActiveFocus());
814 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
815 QGuiApplication::sendEvent(window, &key);
816 QVERIFY(key.isAccepted());
818 item = findItem<QQuickItem>(window->rootObject(), "item3");
820 QVERIFY(item->hasActiveFocus());
823 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
824 QGuiApplication::sendEvent(window, &key);
825 QVERIFY(key.isAccepted());
827 item = findItem<QQuickItem>(window->rootObject(), "item1");
829 QVERIFY(item->hasActiveFocus());
831 //Set item 3 to not visible
832 item = findItem<QQuickItem>(window->rootObject(), "item3");
834 item->setVisible(false);
835 QVERIFY(!item->isVisible());
838 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
839 QGuiApplication::sendEvent(window, &key);
840 QVERIFY(key.isAccepted());
842 item = findItem<QQuickItem>(window->rootObject(), "item4");
844 QVERIFY(item->hasActiveFocus());
847 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
848 QGuiApplication::sendEvent(window, &key);
849 QVERIFY(key.isAccepted());
851 item = findItem<QQuickItem>(window->rootObject(), "item1");
853 QVERIFY(item->hasActiveFocus());
858 void tst_QQuickItem::keyNavigation_implicitSetting()
860 QQuickView *window = new QQuickView(0);
861 window->setBaseSize(QSize(240,320));
863 window->setSource(testFileUrl("keynavigationtest_implicit.qml"));
865 window->requestActivateWindow();
866 QTest::qWaitForWindowShown(window);
867 QTRY_VERIFY(QGuiApplication::focusWindow() == window);
869 QEvent wa(QEvent::WindowActivate);
870 QGuiApplication::sendEvent(window, &wa);
871 QFocusEvent fe(QEvent::FocusIn);
872 QGuiApplication::sendEvent(window, &fe);
874 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item1");
876 QVERIFY(item->hasActiveFocus());
879 QVERIFY(QMetaObject::invokeMethod(window->rootObject(), "verify",
880 Q_RETURN_ARG(QVariant, result)));
881 QVERIFY(result.toBool());
884 QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
885 QGuiApplication::sendEvent(window, &key);
886 QVERIFY(key.isAccepted());
888 item = findItem<QQuickItem>(window->rootObject(), "item2");
890 QVERIFY(item->hasActiveFocus());
893 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
894 QGuiApplication::sendEvent(window, &key);
895 QVERIFY(key.isAccepted());
897 item = findItem<QQuickItem>(window->rootObject(), "item1");
899 QVERIFY(item->hasActiveFocus());
902 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
903 QGuiApplication::sendEvent(window, &key);
904 QVERIFY(key.isAccepted());
906 item = findItem<QQuickItem>(window->rootObject(), "item3");
908 QVERIFY(item->hasActiveFocus());
911 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
912 QGuiApplication::sendEvent(window, &key);
913 QVERIFY(key.isAccepted());
915 item = findItem<QQuickItem>(window->rootObject(), "item4");
917 QVERIFY(item->hasActiveFocus());
920 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1);
921 QGuiApplication::sendEvent(window, &key);
922 QVERIFY(key.isAccepted());
924 item = findItem<QQuickItem>(window->rootObject(), "item3");
926 QVERIFY(item->hasActiveFocus());
929 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
930 QGuiApplication::sendEvent(window, &key);
931 QVERIFY(key.isAccepted());
933 item = findItem<QQuickItem>(window->rootObject(), "item4");
935 QVERIFY(item->hasActiveFocus());
938 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1);
939 QGuiApplication::sendEvent(window, &key);
940 QVERIFY(key.isAccepted());
942 item = findItem<QQuickItem>(window->rootObject(), "item2");
944 QVERIFY(item->hasActiveFocus());
947 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1);
948 QGuiApplication::sendEvent(window, &key);
949 QVERIFY(key.isAccepted());
951 item = findItem<QQuickItem>(window->rootObject(), "item4");
953 QVERIFY(item->hasActiveFocus());
956 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
957 QGuiApplication::sendEvent(window, &key);
958 QVERIFY(key.isAccepted());
960 item = findItem<QQuickItem>(window->rootObject(), "item1");
962 QVERIFY(item->hasActiveFocus());
965 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
966 QGuiApplication::sendEvent(window, &key);
967 QVERIFY(key.isAccepted());
969 item = findItem<QQuickItem>(window->rootObject(), "item4");
971 QVERIFY(item->hasActiveFocus());
974 key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
975 QGuiApplication::sendEvent(window, &key);
976 QVERIFY(key.isAccepted());
978 item = findItem<QQuickItem>(window->rootObject(), "item3");
980 QVERIFY(item->hasActiveFocus());
985 void tst_QQuickItem::smooth()
987 QQmlComponent component(&engine);
988 component.setData("import QtQuick 2.0; Item { smooth: false; }", QUrl::fromLocalFile(""));
989 QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
990 QSignalSpy spy(item, SIGNAL(smoothChanged(bool)));
993 QVERIFY(!item->smooth());
995 item->setSmooth(true);
996 QVERIFY(item->smooth());
997 QCOMPARE(spy.count(),1);
998 QList<QVariant> arguments = spy.first();
999 QVERIFY(arguments.count() == 1);
1000 QVERIFY(arguments.at(0).toBool() == true);
1002 item->setSmooth(true);
1003 QCOMPARE(spy.count(),1);
1005 item->setSmooth(false);
1006 QVERIFY(!item->smooth());
1007 QCOMPARE(spy.count(),2);
1008 item->setSmooth(false);
1009 QCOMPARE(spy.count(),2);
1014 void tst_QQuickItem::clip()
1016 QQmlComponent component(&engine);
1017 component.setData("import QtQuick 2.0\nItem { clip: false\n }", QUrl::fromLocalFile(""));
1018 QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
1019 QSignalSpy spy(item, SIGNAL(clipChanged(bool)));
1022 QVERIFY(!item->clip());
1024 item->setClip(true);
1025 QVERIFY(item->clip());
1027 QList<QVariant> arguments = spy.first();
1028 QVERIFY(arguments.count() == 1);
1029 QVERIFY(arguments.at(0).toBool() == true);
1031 QCOMPARE(spy.count(),1);
1032 item->setClip(true);
1033 QCOMPARE(spy.count(),1);
1035 item->setClip(false);
1036 QVERIFY(!item->clip());
1037 QCOMPARE(spy.count(),2);
1038 item->setClip(false);
1039 QCOMPARE(spy.count(),2);
1044 void tst_QQuickItem::mapCoordinates()
1049 QQuickView *window = new QQuickView(0);
1050 window->setBaseSize(QSize(300, 300));
1051 window->setSource(testFileUrl("mapCoordinates.qml"));
1053 qApp->processEvents();
1055 QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
1057 QQuickItem *a = findItem<QQuickItem>(window->rootObject(), "itemA");
1059 QQuickItem *b = findItem<QQuickItem>(window->rootObject(), "itemB");
1064 QVERIFY(QMetaObject::invokeMethod(root, "mapAToB",
1065 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
1066 QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToItem(b, QPointF(x, y)));
1068 QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB",
1069 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
1070 QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromItem(b, QPointF(x, y)));
1072 QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull",
1073 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
1074 QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToScene(QPointF(x, y)));
1076 QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull",
1077 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
1078 QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromScene(QPointF(x, y)));
1080 QString warning1 = testFileUrl("mapCoordinates.qml").toString() + ":48:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item";
1081 QString warning2 = testFileUrl("mapCoordinates.qml").toString() + ":48:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item";
1083 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
1084 QVERIFY(QMetaObject::invokeMethod(root, "checkMapAToInvalid",
1085 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
1086 QVERIFY(result.toBool());
1088 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
1089 QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid",
1090 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
1091 QVERIFY(result.toBool());
1096 void tst_QQuickItem::mapCoordinates_data()
1098 QTest::addColumn<int>("x");
1099 QTest::addColumn<int>("y");
1101 for (int i=-20; i<=20; i+=10)
1102 QTest::newRow(QTest::toString(i)) << i << i;
1105 void tst_QQuickItem::mapCoordinatesRect()
1110 QFETCH(int, height);
1112 QQuickView *window = new QQuickView(0);
1113 window->setBaseSize(QSize(300, 300));
1114 window->setSource(testFileUrl("mapCoordinatesRect.qml"));
1116 qApp->processEvents();
1118 QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
1120 QQuickItem *a = findItem<QQuickItem>(window->rootObject(), "itemA");
1122 QQuickItem *b = findItem<QQuickItem>(window->rootObject(), "itemB");
1127 QVERIFY(QMetaObject::invokeMethod(root, "mapAToB",
1128 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
1129 QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectToItem(b, QRectF(x, y, width, height)));
1131 QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB",
1132 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
1133 QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectFromItem(b, QRectF(x, y, width, height)));
1135 QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull",
1136 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
1137 QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectToScene(QRectF(x, y, width, height)));
1139 QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull",
1140 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
1141 QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectFromScene(QRectF(x, y, width, height)));
1143 QString warning1 = testFileUrl("mapCoordinatesRect.qml").toString() + ":48:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item";
1144 QString warning2 = testFileUrl("mapCoordinatesRect.qml").toString() + ":48:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item";
1146 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
1147 QVERIFY(QMetaObject::invokeMethod(root, "checkMapAToInvalid",
1148 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
1149 QVERIFY(result.toBool());
1151 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
1152 QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid",
1153 Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
1154 QVERIFY(result.toBool());
1159 void tst_QQuickItem::mapCoordinatesRect_data()
1161 QTest::addColumn<int>("x");
1162 QTest::addColumn<int>("y");
1163 QTest::addColumn<int>("width");
1164 QTest::addColumn<int>("height");
1166 for (int i=-20; i<=20; i+=5)
1167 QTest::newRow(QTest::toString(i)) << i << i << i << i;
1170 void tst_QQuickItem::transforms_data()
1172 QTest::addColumn<QByteArray>("qml");
1173 QTest::addColumn<QTransform>("transform");
1174 QTest::newRow("translate") << QByteArray("Translate { x: 10; y: 20 }")
1175 << QTransform(1,0,0,0,1,0,10,20,1);
1176 QTest::newRow("rotation") << QByteArray("Rotation { angle: 90 }")
1177 << QTransform(0,1,0,-1,0,0,0,0,1);
1178 QTest::newRow("scale") << QByteArray("Scale { xScale: 1.5; yScale: -2 }")
1179 << QTransform(1.5,0,0,0,-2,0,0,0,1);
1180 QTest::newRow("sequence") << QByteArray("[ Translate { x: 10; y: 20 }, Scale { xScale: 1.5; yScale: -2 } ]")
1181 << QTransform(1,0,0,0,1,0,10,20,1) * QTransform(1.5,0,0,0,-2,0,0,0,1);
1184 void tst_QQuickItem::transforms()
1186 QFETCH(QByteArray, qml);
1187 QFETCH(QTransform, transform);
1188 QQmlComponent component(&engine);
1189 component.setData("import QtQuick 2.0\nItem { transform: "+qml+"}", QUrl::fromLocalFile(""));
1190 QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
1192 QCOMPARE(item->itemTransform(0,0), transform);
1195 void tst_QQuickItem::childrenProperty()
1197 QQmlComponent component(&engine, testFileUrl("childrenProperty.qml"));
1199 QObject *o = component.create();
1202 QCOMPARE(o->property("test1").toBool(), true);
1203 QCOMPARE(o->property("test2").toBool(), true);
1204 QCOMPARE(o->property("test3").toBool(), true);
1205 QCOMPARE(o->property("test4").toBool(), true);
1206 QCOMPARE(o->property("test5").toBool(), true);
1210 void tst_QQuickItem::resourcesProperty()
1212 QQmlComponent component(&engine, testFileUrl("resourcesProperty.qml"));
1214 QObject *o = component.create();
1217 QCOMPARE(o->property("test1").toBool(), true);
1218 QCOMPARE(o->property("test2").toBool(), true);
1219 QCOMPARE(o->property("test3").toBool(), true);
1220 QCOMPARE(o->property("test4").toBool(), true);
1221 QCOMPARE(o->property("test5").toBool(), true);
1225 void tst_QQuickItem::propertyChanges()
1227 QQuickView *window = new QQuickView(0);
1228 window->setBaseSize(QSize(300, 300));
1229 window->setSource(testFileUrl("propertychanges.qml"));
1231 window->requestActivateWindow();
1232 QTest::qWaitForWindowShown(window);
1233 QTRY_VERIFY(QGuiApplication::focusWindow() == window);
1235 QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "item");
1236 QQuickItem *parentItem = findItem<QQuickItem>(window->rootObject(), "parentItem");
1239 QVERIFY(parentItem);
1241 QSignalSpy parentSpy(item, SIGNAL(parentChanged(QQuickItem *)));
1242 QSignalSpy widthSpy(item, SIGNAL(widthChanged()));
1243 QSignalSpy heightSpy(item, SIGNAL(heightChanged()));
1244 QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal)));
1245 QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF)));
1246 QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool)));
1247 QSignalSpy wantsFocusSpy(parentItem, SIGNAL(activeFocusChanged(bool)));
1248 QSignalSpy childrenChangedSpy(parentItem, SIGNAL(childrenChanged()));
1249 QSignalSpy xSpy(item, SIGNAL(xChanged()));
1250 QSignalSpy ySpy(item, SIGNAL(yChanged()));
1252 item->setParentItem(parentItem);
1253 item->setWidth(100.0);
1254 item->setHeight(200.0);
1255 item->setFocus(true);
1256 item->setBaselineOffset(10.0);
1258 QCOMPARE(item->parentItem(), parentItem);
1259 QCOMPARE(parentSpy.count(),1);
1260 QList<QVariant> parentArguments = parentSpy.first();
1261 QVERIFY(parentArguments.count() == 1);
1262 QCOMPARE(item->parentItem(), qvariant_cast<QQuickItem *>(parentArguments.at(0)));
1263 QCOMPARE(childrenChangedSpy.count(),1);
1265 item->setParentItem(parentItem);
1266 QCOMPARE(childrenChangedSpy.count(),1);
1268 QCOMPARE(item->width(), 100.0);
1269 QCOMPARE(widthSpy.count(),1);
1271 QCOMPARE(item->height(), 200.0);
1272 QCOMPARE(heightSpy.count(),1);
1274 QCOMPARE(item->baselineOffset(), 10.0);
1275 QCOMPARE(baselineOffsetSpy.count(),1);
1276 QList<QVariant> baselineOffsetArguments = baselineOffsetSpy.first();
1277 QVERIFY(baselineOffsetArguments.count() == 1);
1278 QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal());
1280 QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0));
1281 QCOMPARE(childrenRectSpy.count(),1);
1282 QList<QVariant> childrenRectArguments = childrenRectSpy.at(0);
1283 QVERIFY(childrenRectArguments.count() == 1);
1284 QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF());
1286 QCOMPARE(item->hasActiveFocus(), true);
1287 QCOMPARE(focusSpy.count(),1);
1288 QList<QVariant> focusArguments = focusSpy.first();
1289 QVERIFY(focusArguments.count() == 1);
1290 QCOMPARE(focusArguments.at(0).toBool(), true);
1292 QCOMPARE(parentItem->hasActiveFocus(), false);
1293 QCOMPARE(parentItem->hasFocus(), false);
1294 QCOMPARE(wantsFocusSpy.count(),0);
1297 QCOMPARE(item->x(), 10.0);
1298 QCOMPARE(xSpy.count(), 1);
1301 QCOMPARE(item->y(), 10.0);
1302 QCOMPARE(ySpy.count(), 1);
1307 void tst_QQuickItem::childrenRect()
1309 QQuickView *window = new QQuickView(0);
1310 window->setSource(testFileUrl("childrenRect.qml"));
1311 window->setBaseSize(QSize(240,320));
1314 QQuickItem *o = window->rootObject();
1315 QQuickItem *item = o->findChild<QQuickItem*>("testItem");
1316 QCOMPARE(item->width(), qreal(0));
1317 QCOMPARE(item->height(), qreal(0));
1319 o->setProperty("childCount", 1);
1320 QCOMPARE(item->width(), qreal(10));
1321 QCOMPARE(item->height(), qreal(20));
1323 o->setProperty("childCount", 5);
1324 QCOMPARE(item->width(), qreal(50));
1325 QCOMPARE(item->height(), qreal(100));
1327 o->setProperty("childCount", 0);
1328 QCOMPARE(item->width(), qreal(0));
1329 QCOMPARE(item->height(), qreal(0));
1336 void tst_QQuickItem::childrenRectBug()
1338 QQuickView *window = new QQuickView(0);
1340 QString warning = testFileUrl("childrenRectBug.qml").toString() + ":7:5: QML Item: Binding loop detected for property \"height\"";
1341 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
1342 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
1344 window->setSource(testFileUrl("childrenRectBug.qml"));
1347 QQuickItem *o = window->rootObject();
1348 QQuickItem *item = o->findChild<QQuickItem*>("theItem");
1349 QCOMPARE(item->width(), qreal(200));
1350 QCOMPARE(item->height(), qreal(100));
1351 QCOMPARE(item->x(), qreal(100));
1357 void tst_QQuickItem::childrenRectBug2()
1359 QQuickView *window = new QQuickView(0);
1361 QString warning1 = testFileUrl("childrenRectBug2.qml").toString() + ":7:5: QML Item: Binding loop detected for property \"width\"";
1362 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
1363 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
1365 QString warning2 = testFileUrl("childrenRectBug2.qml").toString() + ":7:5: QML Item: Binding loop detected for property \"height\"";
1366 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
1367 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
1368 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
1369 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2));
1371 window->setSource(testFileUrl("childrenRectBug2.qml"));
1374 QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(window->rootObject());
1376 QQuickItem *item = rect->findChild<QQuickItem*>("theItem");
1377 QCOMPARE(item->width(), qreal(100));
1378 QCOMPARE(item->height(), qreal(110));
1379 QCOMPARE(item->x(), qreal(130));
1381 QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
1382 rectPrivate->setState("row");
1383 QCOMPARE(item->width(), qreal(210));
1384 QCOMPARE(item->height(), qreal(50));
1385 QCOMPARE(item->x(), qreal(75));
1391 void tst_QQuickItem::childrenRectBug3()
1393 QQuickView *window = new QQuickView(0);
1394 window->setSource(testFileUrl("childrenRectBug3.qml"));
1397 //don't crash on delete
1402 void tst_QQuickItem::transformCrash()
1404 QQuickView *window = new QQuickView(0);
1405 window->setSource(testFileUrl("transformCrash.qml"));
1411 void tst_QQuickItem::implicitSize()
1413 QQuickView *window = new QQuickView(0);
1414 window->setSource(testFileUrl("implicitsize.qml"));
1417 QQuickItem *item = qobject_cast<QQuickItem*>(window->rootObject());
1419 QCOMPARE(item->width(), qreal(80));
1420 QCOMPARE(item->height(), qreal(60));
1422 QCOMPARE(item->implicitWidth(), qreal(200));
1423 QCOMPARE(item->implicitHeight(), qreal(100));
1425 QMetaObject::invokeMethod(item, "resetSize");
1427 QCOMPARE(item->width(), qreal(200));
1428 QCOMPARE(item->height(), qreal(100));
1430 QMetaObject::invokeMethod(item, "changeImplicit");
1432 QCOMPARE(item->implicitWidth(), qreal(150));
1433 QCOMPARE(item->implicitHeight(), qreal(80));
1434 QCOMPARE(item->width(), qreal(150));
1435 QCOMPARE(item->height(), qreal(80));
1437 QMetaObject::invokeMethod(item, "assignImplicitBinding");
1439 QCOMPARE(item->implicitWidth(), qreal(150));
1440 QCOMPARE(item->implicitHeight(), qreal(80));
1441 QCOMPARE(item->width(), qreal(150));
1442 QCOMPARE(item->height(), qreal(80));
1444 QMetaObject::invokeMethod(item, "increaseImplicit");
1446 QCOMPARE(item->implicitWidth(), qreal(200));
1447 QCOMPARE(item->implicitHeight(), qreal(100));
1448 QCOMPARE(item->width(), qreal(175));
1449 QCOMPARE(item->height(), qreal(90));
1451 QMetaObject::invokeMethod(item, "changeImplicit");
1453 QCOMPARE(item->implicitWidth(), qreal(150));
1454 QCOMPARE(item->implicitHeight(), qreal(80));
1455 QCOMPARE(item->width(), qreal(150));
1456 QCOMPARE(item->height(), qreal(80));
1458 QMetaObject::invokeMethod(item, "assignUndefinedBinding");
1460 QCOMPARE(item->implicitWidth(), qreal(150));
1461 QCOMPARE(item->implicitHeight(), qreal(80));
1462 QCOMPARE(item->width(), qreal(150));
1463 QCOMPARE(item->height(), qreal(80));
1465 QMetaObject::invokeMethod(item, "increaseImplicit");
1467 QCOMPARE(item->implicitWidth(), qreal(200));
1468 QCOMPARE(item->implicitHeight(), qreal(100));
1469 QCOMPARE(item->width(), qreal(175));
1470 QCOMPARE(item->height(), qreal(90));
1472 QMetaObject::invokeMethod(item, "changeImplicit");
1474 QCOMPARE(item->implicitWidth(), qreal(150));
1475 QCOMPARE(item->implicitHeight(), qreal(80));
1476 QCOMPARE(item->width(), qreal(150));
1477 QCOMPARE(item->height(), qreal(80));
1482 void tst_QQuickItem::qtbug_16871()
1484 QQmlComponent component(&engine, testFileUrl("qtbug_16871.qml"));
1485 QObject *o = component.create();
1491 void tst_QQuickItem::visibleChildren()
1493 QQuickView *window = new QQuickView(0);
1494 window->setSource(testFileUrl("visiblechildren.qml"));
1497 QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
1500 QCOMPARE(root->property("test1_1").toBool(), true);
1501 QCOMPARE(root->property("test1_2").toBool(), true);
1502 QCOMPARE(root->property("test1_3").toBool(), true);
1503 QCOMPARE(root->property("test1_4").toBool(), true);
1505 QMetaObject::invokeMethod(root, "hideFirstAndLastRowChild");
1506 QCOMPARE(root->property("test2_1").toBool(), true);
1507 QCOMPARE(root->property("test2_2").toBool(), true);
1508 QCOMPARE(root->property("test2_3").toBool(), true);
1509 QCOMPARE(root->property("test2_4").toBool(), true);
1511 QMetaObject::invokeMethod(root, "showLastRowChildsLastChild");
1512 QCOMPARE(root->property("test3_1").toBool(), true);
1513 QCOMPARE(root->property("test3_2").toBool(), true);
1514 QCOMPARE(root->property("test3_3").toBool(), true);
1515 QCOMPARE(root->property("test3_4").toBool(), true);
1517 QMetaObject::invokeMethod(root, "showLastRowChild");
1518 QCOMPARE(root->property("test4_1").toBool(), true);
1519 QCOMPARE(root->property("test4_2").toBool(), true);
1520 QCOMPARE(root->property("test4_3").toBool(), true);
1521 QCOMPARE(root->property("test4_4").toBool(), true);
1523 QString warning1 = testFileUrl("visiblechildren.qml").toString() + ":96:32: QML Item: QQuickItem: visibleChildren property is readonly and cannot be assigned to.";
1524 QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1));
1525 QMetaObject::invokeMethod(root, "tryWriteToReadonlyVisibleChildren");
1526 QCOMPARE(root->property("test5_1").toBool(), true);
1528 QMetaObject::invokeMethod(root, "reparentVisibleItem3");
1529 QCOMPARE(root->property("test6_1").toBool(), true);
1530 QCOMPARE(root->property("test6_2").toBool(), true);
1531 QCOMPARE(root->property("test6_3").toBool(), true);
1532 QCOMPARE(root->property("test6_4").toBool(), true);
1534 QMetaObject::invokeMethod(root, "reparentImlicitlyInvisibleItem4_1");
1535 QCOMPARE(root->property("test7_1").toBool(), true);
1536 QCOMPARE(root->property("test7_2").toBool(), true);
1537 QCOMPARE(root->property("test7_3").toBool(), true);
1538 QCOMPARE(root->property("test7_4").toBool(), true);
1540 // FINALLY TEST THAT EVERYTHING IS AS EXPECTED
1541 QCOMPARE(root->property("test8_1").toBool(), true);
1542 QCOMPARE(root->property("test8_2").toBool(), true);
1543 QCOMPARE(root->property("test8_3").toBool(), true);
1544 QCOMPARE(root->property("test8_4").toBool(), true);
1545 QCOMPARE(root->property("test8_5").toBool(), true);
1550 void tst_QQuickItem::parentLoop()
1552 QQuickView *window = new QQuickView(0);
1554 QTest::ignoreMessage(QtWarningMsg, "QQuickItem::setParentItem: Parent is already part of this items subtree.");
1555 window->setSource(testFileUrl("parentLoop.qml"));
1557 QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
1560 QQuickItem *item1 = root->findChild<QQuickItem*>("item1");
1562 QCOMPARE(item1->parentItem(), root);
1564 QQuickItem *item2 = root->findChild<QQuickItem*>("item2");
1566 QCOMPARE(item2->parentItem(), item1);
1571 void tst_QQuickItem::contains_data()
1573 QTest::addColumn<bool>("circleTest");
1574 QTest::addColumn<bool>("insideTarget");
1575 QTest::addColumn<QList<QPoint> >("points");
1577 QList<QPoint> points;
1579 points << QPoint(176, 176)
1586 << QPoint(250, 200);
1587 QTest::newRow("hollow square: testing points inside") << false << true << points;
1590 points << QPoint(162, 162)
1602 << QPoint(280, 200);
1603 QTest::newRow("hollow square: testing points outside") << false << false << points;
1606 points << QPoint(174, 174)
1613 << QPoint(235, 200);
1614 QTest::newRow("hollow circle: testing points inside") << true << true << points;
1617 points << QPoint(160, 160)
1629 << QPoint(200, 255);
1630 QTest::newRow("hollow circle: testing points outside") << true << false << points;
1633 void tst_QQuickItem::contains()
1635 QFETCH(bool, circleTest);
1636 QFETCH(bool, insideTarget);
1637 QFETCH(QList<QPoint>, points);
1639 QQuickView *window = new QQuickView(0);
1640 window->rootContext()->setContextProperty("circleShapeTest", circleTest);
1641 window->setBaseSize(QSize(400, 400));
1642 window->setSource(testFileUrl("hollowTestItem.qml"));
1644 window->requestActivateWindow();
1645 QTest::qWaitForWindowShown(window);
1646 QTRY_VERIFY(QGuiApplication::focusWindow() == window);
1648 QQuickItem *root = qobject_cast<QQuickItem *>(window->rootObject());
1651 HollowTestItem *hollowItem = root->findChild<HollowTestItem *>("hollowItem");
1652 QVERIFY(hollowItem);
1654 foreach (const QPoint &point, points) {
1655 // check mouse hover
1656 QTest::mouseMove(window, point);
1658 QCOMPARE(hollowItem->isHovered(), insideTarget);
1660 // check mouse press
1661 QTest::mousePress(window, Qt::LeftButton, 0, point);
1663 QCOMPARE(hollowItem->isPressed(), insideTarget);
1665 // check mouse release
1666 QTest::mouseRelease(window, Qt::LeftButton, 0, point);
1668 QCOMPARE(hollowItem->isPressed(), false);
1675 QTEST_MAIN(tst_QQuickItem)
1677 #include "tst_qquickitem.moc"