From f9bafac9ef22f3c6962c85de7dbc8c3d177de625 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether <jan-arve.saether@digia.com> Date: Mon, 10 Feb 2014 14:38:52 +0100 Subject: [PATCH] Fixed wrong baseline alignment for TextInput [ChangeLog][QtQuick][Fixed wrong baseline alignment for TextInput] Task-number: QTBUG-36749 Change-Id: I6920fb0681f30d9e9943d1bd01f76cc3ae204f30 Reviewed-by: Alan Alpert <aalpert@blackberry.com> --- src/quick/items/qquicktextinput.cpp | 12 +++ .../qquicktextinput/tst_qquicktextinput.cpp | 91 +++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 9f155f9cf7..7ee1c937c6 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -2855,6 +2855,18 @@ void QQuickTextInputPrivate::updateLayout() else q->setImplicitHeight(height); + + QFontMetricsF fm(font); + qreal yoff = 0; + if (q->heightValid()) { + const qreal itemHeight = q->height(); + if (vAlign == QQuickTextInput::AlignBottom) + yoff = itemHeight - height; + else if (vAlign == QQuickTextInput::AlignVCenter) + yoff = (itemHeight - height)/2; + } + q->setBaselineOffset(fm.ascent() + yoff); + if (previousSize != contentSize) emit q->contentSizeChanged(); } diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index 697dba182c..73abddb2c7 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -229,6 +229,8 @@ private slots: void maskCharacter_data(); void maskCharacter(); void fixup(); + void baselineOffset_data(); + void baselineOffset(); private: void simulateKey(QWindow *, int key); @@ -6358,6 +6360,95 @@ void tst_qquicktextinput::fixup() QCOMPARE(input->text(), QStringLiteral("ok")); } +typedef qreal (*ExpectedBaseline)(QQuickTextInput *item); +Q_DECLARE_METATYPE(ExpectedBaseline) + +static qreal expectedBaselineTop(QQuickTextInput *item) +{ + QFontMetricsF fm(item->font()); + return fm.ascent(); +} + +static qreal expectedBaselineBottom(QQuickTextInput *item) +{ + QFontMetricsF fm(item->font()); + return item->height() - item->contentHeight() + fm.ascent(); +} + +static qreal expectedBaselineCenter(QQuickTextInput *item) +{ + QFontMetricsF fm(item->font()); + return ((item->height() - item->contentHeight()) / 2) + fm.ascent(); +} + +static qreal expectedBaselineMultilineBottom(QQuickTextInput *item) +{ + QFontMetricsF fm(item->font()); + return item->height() - item->contentHeight() + fm.ascent(); +} + +void tst_qquicktextinput::baselineOffset_data() +{ + QTest::addColumn<QString>("text"); + QTest::addColumn<QByteArray>("bindings"); + QTest::addColumn<ExpectedBaseline>("expectedBaseline"); + QTest::addColumn<ExpectedBaseline>("expectedBaselineEmpty"); + + QTest::newRow("normal") + << "Typography" + << QByteArray() + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("top align") + << "Typography" + << QByteArray("height: 200; verticalAlignment: Text.AlignTop") + << &expectedBaselineTop + << &expectedBaselineTop; + + QTest::newRow("bottom align") + << "Typography" + << QByteArray("height: 200; verticalAlignment: Text.AlignBottom") + << &expectedBaselineBottom + << &expectedBaselineBottom; + + QTest::newRow("center align") + << "Typography" + << QByteArray("height: 200; verticalAlignment: Text.AlignVCenter") + << &expectedBaselineCenter + << &expectedBaselineCenter; + + QTest::newRow("multiline bottom aligned") + << "The quick brown fox jumps over the lazy dog" + << QByteArray("height: 200; width: 30; verticalAlignment: Text.AlignBottom; wrapMode: TextInput.WordWrap") + << &expectedBaselineMultilineBottom + << &expectedBaselineBottom; +} + +void tst_qquicktextinput::baselineOffset() +{ + QFETCH(QString, text); + QFETCH(QByteArray, bindings); + QFETCH(ExpectedBaseline, expectedBaseline); + QFETCH(ExpectedBaseline, expectedBaselineEmpty); + + QQmlComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "TextInput {\n" + + bindings + "\n" + "}", QUrl()); + + QScopedPointer<QObject> object(component.create()); + QQuickTextInput *item = qobject_cast<QQuickTextInput *>(object.data()); + QVERIFY(item); + QCOMPARE(item->baselineOffset(), expectedBaselineEmpty(item)); + item->setText(text); + QCOMPARE(item->baselineOffset(), expectedBaseline(item)); + item->setText(QString()); + QCOMPARE(item->baselineOffset(), expectedBaselineEmpty(item)); +} + QTEST_MAIN(tst_qquicktextinput) #include "tst_qquicktextinput.moc" -- GitLab