diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 628e19dbec66f7e70f19c55df2f4db9840379ee1..cf06dc228f7b3cd935e1ae20a9acc2fc5a93b8ba 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4600,7 +4600,9 @@ void QQuickItem::setImplicitWidth(qreal w) if (d->width == w || widthValid()) { if (changed) d->implicitWidthChanged(); - return; + if (d->width == w || widthValid()) + return; + changed = false; } qreal oldWidth = d->width; @@ -4695,7 +4697,9 @@ void QQuickItem::setImplicitHeight(qreal h) if (d->height == h || heightValid()) { if (changed) d->implicitHeightChanged(); - return; + if (d->height == h || heightValid()) + return; + changed = false; } qreal oldHeight = d->height; @@ -4724,12 +4728,14 @@ void QQuickItem::setImplicitSize(qreal w, qreal h) if (d->width == w || widthValid()) { if (wChanged) d->implicitWidthChanged(); - wDone = true; + wDone = d->width == w || widthValid(); + wChanged = false; } if (d->height == h || heightValid()) { if (hChanged) d->implicitHeightChanged(); - hDone = true; + hDone = d->height == h || heightValid(); + hChanged = false; } if (wDone && hDone) return; diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index f52138cfa8401b84df2e8834f62648c62e38e56a..2a6a6da19dee6aa69a6e4729a57b0f1a5c3ff7ba 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -700,8 +700,9 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons layout.setTextOption(textOption); layout.setFont(font); - if ((q->widthValid() && q->width() <= 0. && elideMode != QQuickText::ElideNone) - || (q->heightValid() && q->height() <= 0. && wrapMode != QQuickText::NoWrap && elideMode == QQuickText::ElideRight)) { + if (!requireImplicitWidth + && ((q->widthValid() && q->width() <= 0. && elideMode != QQuickText::ElideNone) + || (q->heightValid() && q->height() <= 0. && wrapMode != QQuickText::NoWrap && elideMode == QQuickText::ElideRight))) { // we are elided and we have a zero width or height if (!truncated) { truncated = true; @@ -712,25 +713,6 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons emit q->lineCountChanged(); } - if (requireImplicitWidth) { - // Layout to determine the implicit width. - layout.beginLayout(); - - for (int i = 0; i < maximumLineCount(); ++i) { - QTextLine line = layout.createLine(); - if (!line.isValid()) - break; - } - layout.endLayout(); - *naturalWidth = layout.maximumWidth(); - layout.clearLayout(); - - bool wasInLayout = internalWidthUpdate; - internalWidthUpdate = true; - q->setImplicitWidth(*naturalWidth); - internalWidthUpdate = wasInLayout; - } - QFontMetricsF fm(font); qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : fm.height() * lineHeight(); *baseline = fm.ascent(); @@ -743,15 +725,16 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons const bool customLayout = isLineLaidOutConnected(); const bool wasTruncated = truncated; - const bool singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid(); - const bool multilineElide = elideMode == QQuickText::ElideRight + bool singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid(); + bool multilineElide = elideMode == QQuickText::ElideRight && q->widthValid() && (q->heightValid() || maximumLineCountValid); - const bool canWrap = wrapMode != QQuickText::NoWrap && q->widthValid(); + bool canWrap = wrapMode != QQuickText::NoWrap && q->widthValid(); - const bool horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid(); - const bool verticalFit = fontSizeMode() & QQuickText::VerticalFit + bool horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid(); + bool verticalFit = fontSizeMode() & QQuickText::VerticalFit && (q->heightValid() || (maximumLineCountValid && canWrap)); + const bool pixelSize = font.pixelSize() != -1; QString layoutText = layout.text(); @@ -922,6 +905,16 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons q->setImplicitWidth(*naturalWidth); internalWidthUpdate = wasInLayout; + singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid(); + multilineElide = elideMode == QQuickText::ElideRight + && q->widthValid() + && (q->heightValid() || maximumLineCountValid); + canWrap = wrapMode != QQuickText::NoWrap && q->widthValid(); + + horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid(); + verticalFit = fontSizeMode() & QQuickText::VerticalFit + && (q->heightValid() || (maximumLineCountValid && canWrap)); + const qreal oldWidth = lineWidth; lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX; if (lineWidth != oldWidth && (singlelineElide || multilineElide || canWrap || horizontalFit)) diff --git a/tests/auto/quick/qquickitem2/data/implicitsize.qml b/tests/auto/quick/qquickitem2/data/implicitsize.qml index cc6aaf7d6023e0ab0ddfdff3b04fa6ae13dea050..756e230a873fe704d2c7e2518a94628846634c78 100644 --- a/tests/auto/quick/qquickitem2/data/implicitsize.qml +++ b/tests/auto/quick/qquickitem2/data/implicitsize.qml @@ -16,4 +16,19 @@ Item { implicitWidth = 150 implicitHeight = 80 } + + function increaseImplicit() { + implicitWidth = 200 + implicitHeight = 100 + } + + function assignImplicitBinding() { + width = Qt.binding(function() { return implicitWidth < 175 ? implicitWidth : 175 }) + height = Qt.binding(function() { return implicitHeight < 90 ? implicitHeight : 90 }) + } + + function assignUndefinedBinding() { + width = Qt.binding(function() { return implicitWidth < 175 ? undefined : 175 }) + height = Qt.binding(function() { return implicitHeight < 90 ? undefined : 90 }) + } } diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 34f51875c918e1e2b78632ecafa45d5321daa9b1..44b05586ce4aca4da7c5b7f39a81199ebd984d5e 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -1350,6 +1350,48 @@ void tst_QQuickItem::implicitSize() QCOMPARE(item->width(), qreal(150)); QCOMPARE(item->height(), qreal(80)); + QMetaObject::invokeMethod(item, "assignImplicitBinding"); + + QCOMPARE(item->implicitWidth(), qreal(150)); + QCOMPARE(item->implicitHeight(), qreal(80)); + QCOMPARE(item->width(), qreal(150)); + QCOMPARE(item->height(), qreal(80)); + + QMetaObject::invokeMethod(item, "increaseImplicit"); + + QCOMPARE(item->implicitWidth(), qreal(200)); + QCOMPARE(item->implicitHeight(), qreal(100)); + QCOMPARE(item->width(), qreal(175)); + QCOMPARE(item->height(), qreal(90)); + + QMetaObject::invokeMethod(item, "changeImplicit"); + + QCOMPARE(item->implicitWidth(), qreal(150)); + QCOMPARE(item->implicitHeight(), qreal(80)); + QCOMPARE(item->width(), qreal(150)); + QCOMPARE(item->height(), qreal(80)); + + QMetaObject::invokeMethod(item, "assignUndefinedBinding"); + + QCOMPARE(item->implicitWidth(), qreal(150)); + QCOMPARE(item->implicitHeight(), qreal(80)); + QCOMPARE(item->width(), qreal(150)); + QCOMPARE(item->height(), qreal(80)); + + QMetaObject::invokeMethod(item, "increaseImplicit"); + + QCOMPARE(item->implicitWidth(), qreal(200)); + QCOMPARE(item->implicitHeight(), qreal(100)); + QCOMPARE(item->width(), qreal(175)); + QCOMPARE(item->height(), qreal(90)); + + QMetaObject::invokeMethod(item, "changeImplicit"); + + QCOMPARE(item->implicitWidth(), qreal(150)); + QCOMPARE(item->implicitHeight(), qreal(80)); + QCOMPARE(item->width(), qreal(150)); + QCOMPARE(item->height(), qreal(80)); + delete canvas; } diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index 125e056dada0a264e586fed8c2cd32329e3815f7..297fa0106f6d2d0fa19f3a860814c39635f87d1d 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -72,6 +72,8 @@ private slots: void elide(); void multilineElide_data(); void multilineElide(); + void implicitElide_data(); + void implicitElide(); void textFormat(); void alignments_data(); @@ -531,6 +533,56 @@ void tst_qquicktext::multilineElide() delete canvas; } +void tst_qquicktext::implicitElide_data() +{ + QTest::addColumn<QString>("width"); + QTest::addColumn<QString>("initialText"); + QTest::addColumn<QString>("text"); + + QTest::newRow("maximum width, empty") + << "Math.min(implicitWidth, 100)" + << ""; + QTest::newRow("maximum width, short") + << "Math.min(implicitWidth, 100)" + << "the"; + QTest::newRow("maximum width, long") + << "Math.min(implicitWidth, 100)" + << "the quick brown fox jumped over the lazy dog"; + QTest::newRow("reset width, empty") + << "implicitWidth > 100 ? 100 : undefined" + << ""; + QTest::newRow("reset width, short") + << "implicitWidth > 100 ? 100 : undefined" + << "the"; + QTest::newRow("reset width, long") + << "implicitWidth > 100 ? 100 : undefined" + << "the quick brown fox jumped over the lazy dog"; +} + +void tst_qquicktext::implicitElide() +{ + QFETCH(QString, width); + QFETCH(QString, initialText); + + QString componentStr = + "import QtQuick 2.0\n" + "Text {\n" + "width: " + width + "\n" + "text: \"" + initialText + "\"\n" + "elide: Text.ElideRight\n" + "}"; + QQmlComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create()); + + QVERIFY(textObject->contentWidth() <= textObject->width()); + + textObject->setText("the quick brown fox jumped over"); + + QVERIFY(textObject->contentWidth() > 0); + QVERIFY(textObject->contentWidth() <= textObject->width()); +} + void tst_qquicktext::textFormat() { {