Add QQuickItem::setImplicitSize()
authorMichael Brasser <michael.brasser@nokia.com>
Tue, 29 Nov 2011 00:19:01 +0000 (10:19 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 30 Nov 2011 03:34:34 +0000 (04:34 +0100)
This allows us to batch up size changes better, leading to fewer layout
recalculations.

Change-Id: I423113fab78666a99ca05439f852f57c92f6f821
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/declarative/items/qquickborderimage.cpp
src/declarative/items/qquickimage.cpp
src/declarative/items/qquickimagebase.cpp
src/declarative/items/qquickitem.cpp
src/declarative/items/qquickitem.h
src/declarative/items/qquickloader.cpp
src/declarative/items/qquickpositioners.cpp
src/declarative/items/qquicktext.cpp
src/declarative/items/qquicktextedit.cpp
src/declarative/items/qquicktextinput.cpp
tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp

index 4e713c0..fac7543 100644 (file)
@@ -299,8 +299,7 @@ void QQuickBorderImage::load()
     if (d->url.isEmpty()) {
         d->pix.clear(this);
         d->status = Null;
-        setImplicitWidth(0);
-        setImplicitHeight(0);
+        setImplicitSize(0, 0);
         emit statusChanged(d->status);
         update();
     } else {
@@ -331,8 +330,7 @@ void QQuickBorderImage::load()
                 d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64)));
             } else {
                 QSize impsize = d->pix.implicitSize();
-                setImplicitWidth(impsize.width());
-                setImplicitHeight(impsize.height());
+                setImplicitSize(impsize.width(), impsize.height());
 
                 if (d->pix.isReady()) {
                     d->status = Ready;
@@ -474,8 +472,7 @@ void QQuickBorderImage::setGridScaledImage(const QQuickGridScaledImage& sci)
         } else {
 
             QSize impsize = d->pix.implicitSize();
-            setImplicitWidth(impsize.width());
-            setImplicitHeight(impsize.height());
+            setImplicitSize(impsize.width(), impsize.height());
 
             if (d->pix.isReady()) {
                 d->status = Ready;
@@ -505,8 +502,7 @@ void QQuickBorderImage::requestFinished()
         d->status = Ready;
     }
 
-    setImplicitWidth(impsize.width());
-    setImplicitHeight(impsize.height());
+    setImplicitSize(impsize.width(), impsize.height());
 
     if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
         emit sourceSizeChanged();
index 598d6be..6d2e1b3 100644 (file)
@@ -478,8 +478,7 @@ void QQuickImage::updatePaintedGeometry()
 
     if (d->fillMode == PreserveAspectFit) {
         if (!d->pix.width() || !d->pix.height()) {
-            setImplicitWidth(0);
-            setImplicitHeight(0);
+            setImplicitSize(0, 0);
             return;
         }
         qreal w = widthValid() ? width() : d->pix.width();
@@ -493,16 +492,10 @@ void QQuickImage::updatePaintedGeometry()
             d->paintedWidth = heightScale * qreal(d->pix.width());
             d->paintedHeight = h;
         }
-        if (widthValid() && !heightValid()) {
-            setImplicitHeight(d->paintedHeight);
-        } else {
-            setImplicitHeight(d->pix.height());
-        }
-        if (heightValid() && !widthValid()) {
-            setImplicitWidth(d->paintedWidth);
-        } else {
-            setImplicitWidth(d->pix.width());
-        }
+        qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : d->pix.height();
+        qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : d->pix.width();
+        setImplicitSize(iWidth, iHeight);
+
     } else if (d->fillMode == PreserveAspectCrop) {
         if (!d->pix.width() || !d->pix.height())
             return;
index 3eb196d..e5030c5 100644 (file)
@@ -284,8 +284,7 @@ void QQuickImageBase::componentComplete()
 void QQuickImageBase::pixmapChange()
 {
     Q_D(QQuickImageBase);
-    setImplicitWidth(d->pix.width());
-    setImplicitHeight(d->pix.height());
+    setImplicitSize(d->pix.width(), d->pix.height());
 }
 
 QT_END_NAMESPACE
index a4a5ab4..3978cf8 100644 (file)
@@ -4412,6 +4412,48 @@ void QQuickItem::setImplicitHeight(qreal h)
         d->implicitHeightChanged();
 }
 
+void QQuickItem::setImplicitSize(qreal w, qreal h)
+{
+    Q_D(QQuickItem);
+    bool wChanged = w != d->implicitWidth;
+    bool hChanged = h != d->implicitHeight;
+
+    d->implicitWidth = w;
+    d->implicitHeight = h;
+
+    bool wDone = false;
+    bool hDone = false;
+    if (d->width == w || widthValid()) {
+        if (wChanged)
+            d->implicitWidthChanged();
+        wDone = true;
+    }
+    if (d->height == h || heightValid()) {
+        if (hChanged)
+            d->implicitHeightChanged();
+        hDone = true;
+    }
+    if (wDone && hDone)
+        return;
+
+    qreal oldWidth = d->width;
+    qreal oldHeight = d->height;
+    if (!wDone)
+        d->width = w;
+    if (!hDone)
+        d->height = h;
+
+    d->dirty(QQuickItemPrivate::Size);
+
+    geometryChanged(QRectF(x(), y(), width(), height()),
+                    QRectF(x(), y(), oldWidth, oldHeight));
+
+    if (!wDone && wChanged)
+        d->implicitWidthChanged();
+    if (!hDone && hChanged)
+        d->implicitHeightChanged();
+}
+
 /*!
     Returns whether the height property has been set explicitly.
 */
index 0cbcfb8..a3baecb 100644 (file)
@@ -359,6 +359,7 @@ protected:
     bool widthValid() const; // ### better name?
     void setImplicitHeight(qreal);
     bool heightValid() const; // ### better name?
+    void setImplicitSize(qreal, qreal);
 
     virtual void classBegin();
     virtual void componentComplete();
index 73f5707..242d9f3 100644 (file)
@@ -783,17 +783,12 @@ void QQuickLoaderPrivate::_q_updateSize(bool loaderGeometryChanged)
 
     updatingSize = true;
 
-    if (!itemWidthValid)
-        q->setImplicitWidth(item->implicitWidth());
-    else
-        q->setImplicitWidth(item->width());
+    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 (!itemHeightValid)
-        q->setImplicitHeight(item->implicitHeight());
-    else
-        q->setImplicitHeight(item->height());
     if (loaderGeometryChanged && q->heightValid())
         item->setHeight(q->height());
 
index 8d20493..08fa4b1 100644 (file)
@@ -245,8 +245,7 @@ void QQuickBasePositioner::prePositioning()
         finishApplyTransitions();
     d->doingPositioning = false;
     //Set implicit size to the size of its children
-    setImplicitHeight(contentSize.height());
-    setImplicitWidth(contentSize.width());
+    setImplicitSize(contentSize.width(), contentSize.height());
 }
 
 void QQuickBasePositioner::positionX(int x, const PositionedItem &target)
index e3286f0..22f29cb 100644 (file)
@@ -293,8 +293,7 @@ void QQuickTextPrivate::updateSize()
 
     QFontMetrics fm(font);
     if (text.isEmpty()) {
-        q->setImplicitWidth(0);
-        q->setImplicitHeight(fm.height());
+        q->setImplicitSize(0, fm.height());
         paintedSize = QSize(0, fm.height());
         emit q->paintedSizeChanged();
         q->update();
@@ -356,13 +355,17 @@ void QQuickTextPrivate::updateSize()
 
     //### need to comfirm cost of always setting these for richText
     internalWidthUpdate = true;
+    qreal iWidth = -1;
     if (!q->widthValid())
-        q->setImplicitWidth(size.width());
+        iWidth = size.width();
     else if (requireImplicitWidth)
-        q->setImplicitWidth(naturalWidth);
+        iWidth = naturalWidth;
+    if (iWidth > -1)
+        q->setImplicitSize(iWidth, size.height());
     internalWidthUpdate = false;
 
-    q->setImplicitHeight(size.height());
+    if (iWidth == -1)
+        q->setImplicitHeight(size.height());
     if (paintedSize != size) {
         paintedSize = size;
         emit q->paintedSizeChanged();
index 51231e1..b40b5c0 100644 (file)
@@ -1804,12 +1804,16 @@ void QQuickTextEdit::updateSize()
         if (!widthValid() && d->document->textWidth() != newWidth)
             d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug)
         // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
+        qreal iWidth = -1;
         if (!widthValid())
-            setImplicitWidth(newWidth);
+            iWidth = newWidth;
         else if (d->requireImplicitWidth)
-            setImplicitWidth(naturalWidth);
+            iWidth = naturalWidth;
         qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height();
-        setImplicitHeight(newHeight);
+        if (iWidth > -1)
+            setImplicitSize(iWidth, newHeight);
+        else
+            setImplicitHeight(newHeight);
 
         d->paintedSize = QSize(newWidth, newHeight);
         emit paintedSizeChanged();
index c9469ba..c46eba1 100644 (file)
@@ -1971,8 +1971,7 @@ void QQuickTextInput::updateSize(bool needsRedraw)
     Q_D(QQuickTextInput);
     int w = width();
     int h = height();
-    setImplicitHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
-    setImplicitWidth(d->calculateTextWidth());
+    setImplicitSize(d->calculateTextWidth(), d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
     if (w==width() && h==height() && needsRedraw)
         update();
 }
index cfdab7f..00b52eb 100644 (file)
@@ -283,7 +283,6 @@ void tst_qquickanchors::loops()
         QString expect = source.toString() + ":6:5: QML Text: Possible anchor loop detected on horizontal anchor.";
         QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
         QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
-        QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
 
         QQuickView *view = new QQuickView;
         view->setSource(source);