diff options
-rw-r--r-- | src/quick/items/qquickimplicitsizeitem.cpp | 12 | ||||
-rw-r--r-- | src/quick/items/qquickitem.cpp | 12 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickitemchangelistener_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickloader.cpp | 71 | ||||
-rw-r--r-- | src/quick/items/qquickloader_p_p.h | 7 | ||||
-rw-r--r-- | tests/auto/quick/qquickloader/data/implicitSize.qml | 5 | ||||
-rw-r--r-- | tests/auto/quick/qquickloader/tst_qquickloader.cpp | 12 |
8 files changed, 102 insertions, 21 deletions
diff --git a/src/quick/items/qquickimplicitsizeitem.cpp b/src/quick/items/qquickimplicitsizeitem.cpp index 427be42312..1de8e0ab73 100644 --- a/src/quick/items/qquickimplicitsizeitem.cpp +++ b/src/quick/items/qquickimplicitsizeitem.cpp @@ -47,12 +47,24 @@ QT_BEGIN_NAMESPACE void QQuickImplicitSizeItemPrivate::implicitWidthChanged() { Q_Q(QQuickImplicitSizeItem); + for (int ii = 0; ii < changeListeners.count(); ++ii) { + const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii); + if (change.types & QQuickItemPrivate::ImplicitWidth) { + change.listener->itemImplicitWidthChanged(q); + } + } emit q->implicitWidthChanged(); } void QQuickImplicitSizeItemPrivate::implicitHeightChanged() { Q_Q(QQuickImplicitSizeItem); + for (int ii = 0; ii < changeListeners.count(); ++ii) { + const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii); + if (change.types & QQuickItemPrivate::ImplicitHeight) { + change.listener->itemImplicitHeightChanged(q); + } + } emit q->implicitHeightChanged(); } diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 6eddd0d0ba..10003d4e81 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4502,6 +4502,12 @@ void QQuickItem::resetWidth() void QQuickItemPrivate::implicitWidthChanged() { Q_Q(QQuickItem); + for (int ii = 0; ii < changeListeners.count(); ++ii) { + const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii); + if (change.types & QQuickItemPrivate::ImplicitWidth) { + change.listener->itemImplicitWidthChanged(q); + } + } emit q->implicitWidthChanged(); } @@ -4624,6 +4630,12 @@ void QQuickItem::resetHeight() void QQuickItemPrivate::implicitHeightChanged() { Q_Q(QQuickItem); + for (int ii = 0; ii < changeListeners.count(); ++ii) { + const QQuickItemPrivate::ChangeListener &change = changeListeners.at(ii); + if (change.types & QQuickItemPrivate::ImplicitHeight) { + change.listener->itemImplicitHeightChanged(q); + } + } emit q->implicitHeightChanged(); } diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 01e8b4d335..89c09ed015 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -302,6 +302,8 @@ public: Parent = 0x20, Children = 0x40, Rotation = 0x80, + ImplicitWidth = 0x100, + ImplicitHeight = 0x200 }; Q_DECLARE_FLAGS(ChangeTypes, ChangeType) diff --git a/src/quick/items/qquickitemchangelistener_p.h b/src/quick/items/qquickitemchangelistener_p.h index 3a5c25f5f5..cbdfb2b18b 100644 --- a/src/quick/items/qquickitemchangelistener_p.h +++ b/src/quick/items/qquickitemchangelistener_p.h @@ -74,6 +74,8 @@ public: virtual void itemChildRemoved(QQuickItem *, QQuickItem *) {} virtual void itemParentChanged(QQuickItem *, QQuickItem *) {} virtual void itemRotationChanged(QQuickItem *) {} + virtual void itemImplicitWidthChanged(QQuickItem *) {} + virtual void itemImplicitHeightChanged(QQuickItem *) {} virtual QQuickAnchorsPrivate *anchorPrivate() { return 0; } }; diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index f41ba44943..730dfd45d4 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -52,9 +52,11 @@ QT_BEGIN_NAMESPACE +static const QQuickItemPrivate::ChangeTypes watchedChanges + = QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight; + QQuickLoaderPrivate::QQuickLoaderPrivate() : item(0), component(0), itemContext(0), incubator(0), updatingSize(false), - itemWidthValid(false), itemHeightValid(false), active(true), loadingFromSource(false), asynchronous(false) { } @@ -69,16 +71,23 @@ QQuickLoaderPrivate::~QQuickLoaderPrivate() void QQuickLoaderPrivate::itemGeometryChanged(QQuickItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry) { - if (resizeItem == item) { - if (!updatingSize && newGeometry.width() != oldGeometry.width()) - itemWidthValid = true; - if (!updatingSize && newGeometry.height() != oldGeometry.height()) - itemHeightValid = true; + if (resizeItem == item) _q_updateSize(false); - } QQuickItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry); } +void QQuickLoaderPrivate::itemImplicitWidthChanged(QQuickItem *) +{ + Q_Q(QQuickLoader); + q->setImplicitWidth(getImplicitWidth()); +} + +void QQuickLoaderPrivate::itemImplicitHeightChanged(QQuickItem *) +{ + Q_Q(QQuickLoader); + q->setImplicitHeight(getImplicitHeight()); +} + void QQuickLoaderPrivate::clear() { Q_Q(QQuickLoader); @@ -103,7 +112,7 @@ void QQuickLoaderPrivate::clear() if (item) { QQuickItemPrivate *p = QQuickItemPrivate::get(item); - p->removeItemChangeListener(this, QQuickItemPrivate::Geometry); + p->removeItemChangeListener(this, watchedChanges); // We can't delete immediately because our item may have triggered // the Loader to load a different item. @@ -117,14 +126,32 @@ void QQuickLoaderPrivate::clear() void QQuickLoaderPrivate::initResize() { QQuickItemPrivate *p = QQuickItemPrivate::get(item); - p->addItemChangeListener(this, QQuickItemPrivate::Geometry); - // We may override the item's size, so we need to remember - // whether the item provided its own valid size. - itemWidthValid = p->widthValid; - itemHeightValid = p->heightValid; + p->addItemChangeListener(this, watchedChanges); _q_updateSize(); } +qreal QQuickLoaderPrivate::getImplicitWidth() const +{ + Q_Q(const QQuickLoader); + // If the Loader has a valid width then Loader has set an explicit width on the + // item, and we want the item's implicitWidth. If the Loader's width has + // not been set then its implicitWidth is the width of the item. + if (item) + return q->widthValid() ? item->implicitWidth() : item->width(); + return QQuickImplicitSizeItemPrivate::getImplicitWidth(); +} + +qreal QQuickLoaderPrivate::getImplicitHeight() const +{ + Q_Q(const QQuickLoader); + // If the Loader has a valid height then Loader has set an explicit height on the + // item, and we want the item's implicitHeight. If the Loader's height has + // not been set then its implicitHeight is the height of the item. + if (item) + return q->heightValid() ? item->implicitHeight() : item->height(); + return QQuickImplicitSizeItemPrivate::getImplicitHeight(); +} + /*! \qmlclass Loader QQuickLoader \inqmlmodule QtQuick 2 @@ -245,7 +272,7 @@ QQuickLoader::~QQuickLoader() Q_D(QQuickLoader); if (d->item) { QQuickItemPrivate *p = QQuickItemPrivate::get(d->item); - p->removeItemChangeListener(d, QQuickItemPrivate::Geometry); + p->removeItemChangeListener(d, watchedChanges); } } @@ -284,7 +311,7 @@ void QQuickLoader::setActive(bool newVal) } else { if (d->item) { QQuickItemPrivate *p = QQuickItemPrivate::get(d->item); - p->removeItemChangeListener(d, QQuickItemPrivate::Geometry); + p->removeItemChangeListener(d, watchedChanges); // We can't delete immediately because our item may have triggered // the Loader to load a different item. @@ -553,6 +580,14 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj) QQuickItem *item = qobject_cast<QQuickItem*>(obj); if (item) { + // If the item doesn't have an explicit size, but the Loader + // does, then set the item's size now before bindings are + // evaluated, otherwise we will end up resizing the item + // later and triggering any affected bindings/anchors. + if (widthValid && !QQuickItemPrivate::get(item)->widthValid) + item->setWidth(q->width()); + if (heightValid && !QQuickItemPrivate::get(item)->heightValid) + item->setHeight(q->height()); QQml_setParent_noEvent(itemContext, obj); QQml_setParent_noEvent(item, q); item->setParentItem(q); @@ -812,15 +847,13 @@ void QQuickLoaderPrivate::_q_updateSize(bool loaderGeometryChanged) updatingSize = true; - qreal iWidth = !itemWidthValid ? item->implicitWidth() : item->width(); - qreal iHeight = !itemHeightValid ? item->implicitHeight() : item->height(); - q->setImplicitSize(iWidth, iHeight); - if (loaderGeometryChanged && q->widthValid()) item->setWidth(q->width()); if (loaderGeometryChanged && q->heightValid()) item->setHeight(q->height()); + q->setImplicitSize(getImplicitWidth(), getImplicitHeight()); + updatingSize = false; } diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h index 1ad7756ed8..0978911315 100644 --- a/src/quick/items/qquickloader_p_p.h +++ b/src/quick/items/qquickloader_p_p.h @@ -87,6 +87,8 @@ public: ~QQuickLoaderPrivate(); void itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry); + void itemImplicitWidthChanged(QQuickItem *); + void itemImplicitHeightChanged(QQuickItem *); void clear(); void initResize(); void load(); @@ -97,6 +99,9 @@ public: QUrl resolveSourceUrl(QQmlV8Function *args); v8::Handle<v8::Object> extractInitialPropertyValues(QQmlV8Function *args, QObject *loader, bool *error); + virtual qreal getImplicitWidth() const; + virtual qreal getImplicitHeight() const; + QUrl source; QQuickItem *item; QQmlComponent *component; @@ -105,8 +110,6 @@ public: v8::Persistent<v8::Object> initialPropertyValues; v8::Persistent<v8::Object> qmlGlobalForIpv; bool updatingSize: 1; - bool itemWidthValid : 1; - bool itemHeightValid : 1; bool active : 1; bool loadingFromSource : 1; bool asynchronous : 1; diff --git a/tests/auto/quick/qquickloader/data/implicitSize.qml b/tests/auto/quick/qquickloader/data/implicitSize.qml index 5c8c8348ed..ae8c0b8b30 100644 --- a/tests/auto/quick/qquickloader/data/implicitSize.qml +++ b/tests/auto/quick/qquickloader/data/implicitSize.qml @@ -3,12 +3,17 @@ import QtQuick 2.0 Rectangle { property real implWidth: 0 property real implHeight: 0 + function changeImplicitSize () { + loader.item.implicitWidth = 200 + loader.item.implicitHeight = 300 + } color: "green" width: loader.implicitWidth+50 height: loader.implicitHeight+50 Loader { id: loader + objectName: "loader" sourceComponent: Item { anchors.centerIn: parent diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index 01781f7b54..ea35897004 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -842,6 +842,18 @@ void tst_QQuickLoader::implicitSize() QCOMPARE(item->property("implHeight").toReal(), 100.); QCOMPARE(item->property("implWidth").toReal(), 100.); + QQuickLoader *loader = item->findChild<QQuickLoader*>("loader"); + QSignalSpy implWidthSpy(loader, SIGNAL(implicitWidthChanged())); + QSignalSpy implHeightSpy(loader, SIGNAL(implicitHeightChanged())); + + QMetaObject::invokeMethod(item, "changeImplicitSize"); + + QCOMPARE(loader->property("implicitWidth").toReal(), 200.); + QCOMPARE(loader->property("implicitHeight").toReal(), 300.); + + QCOMPARE(implWidthSpy.count(), 1); + QCOMPARE(implHeightSpy.count(), 1); + delete item; } |