Allow binding the size of a Loader to its item.
authorMartin Jones <martin.jones@nokia.com>
Thu, 16 Feb 2012 03:45:02 +0000 (13:45 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 16 Feb 2012 05:36:38 +0000 (06:36 +0100)
If the size of the Loader is bound to the item, the item was resized
before the binding was evaluated, resulting in an item height of 0.
This change allows bindings to the item to be evaluated before we
apply the resize logic.

Task-number: QTBUG-22628
Change-Id: I30acdb54214b422a9d4aa4e7e02a0af3674322db
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
src/quick/items/qquickloader.cpp
tests/auto/qtquick2/qquickloader/data/sizebound.qml [new file with mode: 0644]
tests/auto/qtquick2/qquickloader/tst_qquickloader.cpp

index 50347f9..92724f4 100644 (file)
@@ -569,12 +569,14 @@ void QQuickLoaderPrivate::incubatorStateChanged(QDeclarativeIncubator::Status st
         QObject *obj = incubator->object();
         item = qobject_cast<QQuickItem*>(obj);
         if (item) {
+            emit q->itemChanged();
             initResize();
         } else {
             qmlInfo(q) << QQuickLoader::tr("Loader does not support loading non-visual elements.");
             delete itemContext;
             itemContext = 0;
             delete obj;
+            emit q->itemChanged();
         }
         incubator->clear();
     } else if (status == QDeclarativeIncubator::Error) {
@@ -584,6 +586,7 @@ void QQuickLoaderPrivate::incubatorStateChanged(QDeclarativeIncubator::Status st
         itemContext = 0;
         delete incubator->object();
         source = QUrl();
+        emit q->itemChanged();
     }
     if (loadingFromSource)
         emit q->sourceChanged();
@@ -591,7 +594,6 @@ void QQuickLoaderPrivate::incubatorStateChanged(QDeclarativeIncubator::Status st
         emit q->sourceComponentChanged();
     emit q->statusChanged();
     emit q->progressChanged();
-    emit q->itemChanged();
     emit q->loaded();
     disposeInitialPropertyValues(); // cleanup
 }
diff --git a/tests/auto/qtquick2/qquickloader/data/sizebound.qml b/tests/auto/qtquick2/qquickloader/data/sizebound.qml
new file mode 100644 (file)
index 0000000..09cf324
--- /dev/null
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+
+Item {
+    width: 200; height: 200
+
+    function switchComponent() {
+        load.sourceComponent = comp2
+    }
+
+    Component {
+        id: comp
+        Rectangle {
+            width: 50; height: 60; color: "red"
+        }
+    }
+
+    Component {
+        id: comp2
+        Rectangle {
+            width: 80; height: 90; color: "green"
+        }
+    }
+
+    Loader {
+        id: load
+        objectName: "loader"
+        sourceComponent: comp
+        height: item ? item.height : 0
+    }
+}
index 4001f70..33148db 100644 (file)
@@ -104,6 +104,7 @@ private slots:
     void asynchronous_clear();
 
     void parented();
+    void sizeBound();
 
 private:
     QDeclarativeEngine engine;
@@ -959,6 +960,27 @@ void tst_QQuickLoader::parented()
     delete root;
 }
 
+void tst_QQuickLoader::sizeBound()
+{
+    QDeclarativeComponent component(&engine, testFileUrl("sizebound.qml"));
+    QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+    QVERIFY(root);
+    QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
+    QVERIFY(loader != 0);
+
+    QVERIFY(loader->item());
+
+    QCOMPARE(loader->width(), 50.0);
+    QCOMPARE(loader->height(), 60.0);
+
+    QMetaObject::invokeMethod(root, "switchComponent");
+
+    QCOMPARE(loader->width(), 80.0);
+    QCOMPARE(loader->height(), 90.0);
+
+    delete root;
+}
+
 
 QTEST_MAIN(tst_QQuickLoader)