From: Michael Brasser Date: Tue, 29 Nov 2011 00:19:01 +0000 (+1000) Subject: Add QQuickItem::setImplicitSize() X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=3bdefb5c1cf10a38de971c679bee5486bc6bd5f6;p=konrad%2Fqtdeclarative.git Add QQuickItem::setImplicitSize() This allows us to batch up size changes better, leading to fewer layout recalculations. Change-Id: I423113fab78666a99ca05439f852f57c92f6f821 Reviewed-by: Martin Jones --- diff --git a/src/declarative/items/qquickborderimage.cpp b/src/declarative/items/qquickborderimage.cpp index 4e713c0..fac7543 100644 --- a/src/declarative/items/qquickborderimage.cpp +++ b/src/declarative/items/qquickborderimage.cpp @@ -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(); diff --git a/src/declarative/items/qquickimage.cpp b/src/declarative/items/qquickimage.cpp index 598d6be..6d2e1b3 100644 --- a/src/declarative/items/qquickimage.cpp +++ b/src/declarative/items/qquickimage.cpp @@ -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; diff --git a/src/declarative/items/qquickimagebase.cpp b/src/declarative/items/qquickimagebase.cpp index 3eb196d..e5030c5 100644 --- a/src/declarative/items/qquickimagebase.cpp +++ b/src/declarative/items/qquickimagebase.cpp @@ -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 diff --git a/src/declarative/items/qquickitem.cpp b/src/declarative/items/qquickitem.cpp index a4a5ab4..3978cf8 100644 --- a/src/declarative/items/qquickitem.cpp +++ b/src/declarative/items/qquickitem.cpp @@ -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. */ diff --git a/src/declarative/items/qquickitem.h b/src/declarative/items/qquickitem.h index 0cbcfb8..a3baecb 100644 --- a/src/declarative/items/qquickitem.h +++ b/src/declarative/items/qquickitem.h @@ -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(); diff --git a/src/declarative/items/qquickloader.cpp b/src/declarative/items/qquickloader.cpp index 73f5707..242d9f3 100644 --- a/src/declarative/items/qquickloader.cpp +++ b/src/declarative/items/qquickloader.cpp @@ -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()); diff --git a/src/declarative/items/qquickpositioners.cpp b/src/declarative/items/qquickpositioners.cpp index 8d20493..08fa4b1 100644 --- a/src/declarative/items/qquickpositioners.cpp +++ b/src/declarative/items/qquickpositioners.cpp @@ -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) diff --git a/src/declarative/items/qquicktext.cpp b/src/declarative/items/qquicktext.cpp index e3286f0..22f29cb 100644 --- a/src/declarative/items/qquicktext.cpp +++ b/src/declarative/items/qquicktext.cpp @@ -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(); diff --git a/src/declarative/items/qquicktextedit.cpp b/src/declarative/items/qquicktextedit.cpp index 51231e1..b40b5c0 100644 --- a/src/declarative/items/qquicktextedit.cpp +++ b/src/declarative/items/qquicktextedit.cpp @@ -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(); diff --git a/src/declarative/items/qquicktextinput.cpp b/src/declarative/items/qquicktextinput.cpp index c9469ba..c46eba1 100644 --- a/src/declarative/items/qquicktextinput.cpp +++ b/src/declarative/items/qquicktextinput.cpp @@ -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(); } diff --git a/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp b/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp index cfdab7f..00b52eb 100644 --- a/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp +++ b/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp @@ -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);