From b25c27d37a5d5dded723946900f9a518c38385de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timur=20Krist=C3=B3f?= Date: Fri, 27 Sep 2019 18:07:41 +0200 Subject: Add API to get more information for each line in a QML Text element Previously there was no way to know what area is occupied by each line in a QML Text element. This commit adds new API to expose implicitWidth and isLast on QQuickTextLine for use in the lineLaidOut signal. It also adds improved documentation to the lineLaidOut signal and an example usage of the new API to the text layout example. An example use case of the new API is eg. to allow embedding timestamps and indicators within a text paragraph, to enable creating more efficient layouts. [ChangeLog][QtQuick][Text] Added new API that exposes implicitWidth, and isLast on the QQuickTextLine for use in the lineLaidOut signal. This allows the user to layout other items relative to the lines of text. Fixes: QTBUG-78277 Change-Id: Ibc754db17c78efb01468106aba32e30d70d2f4df Reviewed-by: Shawn Rutledge --- tests/auto/quick/qquicktext/tst_qquicktext.cpp | 56 ++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'tests/auto/quick/qquicktext/tst_qquicktext.cpp') diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index e62db81d27..06ce730091 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -119,6 +120,7 @@ private slots: void lineLaidOut(); void lineLaidOutRelayout(); void lineLaidOutHAlign(); + void lineLaidOutImplicitWidth(); void imgTagsBaseUrl_data(); void imgTagsBaseUrl(); @@ -2871,6 +2873,13 @@ void tst_qquicktext::lineLaidOut() QCOMPARE(r.height(), qreal(20)); } } + + // Ensure that isLast was correctly emitted + int lastLineNumber = myText->property("lastLineNumber").toInt(); + QCOMPARE(lastLineNumber, myText->lineCount() - 1); + // Ensure that only one line was considered last (after changing its width) + bool receivedMultipleLastLines = myText->property("receivedMultipleLastLines").toBool(); + QVERIFY(!receivedMultipleLastLines); } void tst_qquicktext::lineLaidOutRelayout() @@ -2975,6 +2984,53 @@ void tst_qquicktext::imgTagsBaseUrl_data() << 181.; } +void tst_qquicktext::lineLaidOutImplicitWidth() +{ + QScopedPointer window(createView(testFile("lineLayoutImplicitWidth.qml"))); + + QQuickText *myText = window->rootObject()->findChild("myText"); + QVERIFY(myText != nullptr); + + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText); + QVERIFY(textPrivate != nullptr); + + // Retrieve the saved implicitWidth values of each rendered line + QVariant widthsProperty = myText->property("lineImplicitWidths"); + QVERIFY(!widthsProperty.isNull()); + QVERIFY(widthsProperty.isValid()); + QVERIFY(widthsProperty.canConvert()); + QJSValue widthsValue = widthsProperty.value(); + QVERIFY(widthsValue.isArray()); + int lineCount = widthsValue.property("length").toInt(); + QVERIFY(lineCount > 0); + + // Create the same text layout by hand + // Note that this approach needs additional processing for styled text, + // so we only use it for plain text here. + QTextLayout layout; + layout.setCacheEnabled(true); + layout.setText(myText->text()); + layout.setTextOption(textPrivate->layout.textOption()); + layout.setFont(myText->font()); + layout.beginLayout(); + for (QTextLine line = layout.createLine(); line.isValid(); line = layout.createLine()) { + line.setLineWidth(myText->width()); + } + layout.endLayout(); + + // Line count of the just created layout should match the rendered text + QCOMPARE(lineCount, layout.lineCount()); + + // Go through each line and verify that the values emitted by lineLaidOut are correct + for (int i = 0; i < layout.lineCount(); ++i) { + qreal implicitWidth = widthsValue.property(i).toNumber(); + QVERIFY(implicitWidth > 0); + + QTextLine line = layout.lineAt(i); + QCOMPARE(implicitWidth, line.naturalTextWidth()); + } +} + static QUrl substituteTestServerUrl(const QUrl &serverUrl, const QUrl &testUrl) { QUrl result = testUrl; -- cgit v1.2.3