aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquickimplicitsizeitem.cpp12
-rw-r--r--src/quick/items/qquickitem.cpp12
-rw-r--r--src/quick/items/qquickitem_p.h2
-rw-r--r--src/quick/items/qquickitemchangelistener_p.h2
-rw-r--r--src/quick/items/qquickloader.cpp71
-rw-r--r--src/quick/items/qquickloader_p_p.h7
-rw-r--r--tests/auto/quick/qquickloader/data/implicitSize.qml5
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp12
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;
}