diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2017-02-07 13:54:29 +0100 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@qt.io> | 2017-02-23 13:45:52 +0000 |
commit | 2556bfdab42dc0aefb34bb7cf304063c7db0ff00 (patch) | |
tree | 5b9d638a3a7a6a6a78781022fe8e2831a844a7a1 /tests/auto/quick/qquickpositioners | |
parent | 3681514f80a2f6a568b0508a58b5e486cee00b0f (diff) |
Positioners: allow distinguishing between implicit/explicit child size
In Qt Quick Controls 2, we plan on using positioners to layout an icon
next to text in a button, for example.
Consider the following example:
AbstractButton {
id: button
text: "Button"
contentItem: Row {
Text {
text: button.text
width: parent.width
}
}
background: Rectangle {
radius: 5
color: "lightsteelblue"
opacity: button.pressed ? 1.0 : 0.8
}
}
In Qt Quick Controls 2, implicit size propagates "up" from the
delegates/building blocks to the control, whereas explicit size
propagates "down" from the control to the delegates/building blocks.
Providing a reasonable implicit size is important to make controls
behave well in layouts, etc., and the internal building blocks must
follow the size of the control to retain sensible looks when a control
is resized.
In the example above, contentItem needs to have a "natural" (implicit)
size representing the ideal fit of the content, but it needs to respect
the explicitly provided size from the control too.
With the current behavior, as the explicit width of the Row is 0, the
Text item (via the width binding) sets explicit width to 0, and Row
uses that explicit width rather than the implicit width, thus, Row here
will have an implicit width of 0, which is not what the control wants.
This patch:
- Allows subclasses of positioners to set
QQuickBasePositionerPrivate::useImplicitSize to true in order to tell
positioners to use implicit size rather than explicit size. This is
not exposed as public API, as this behavior is typically not
something desirable in the positioners themselves. For example,
Row { Rectangle { width: 100; height: 100 } } would have an implicit
size of 0, as Rectangle has no implicit size.
- Adds QQuickImplicitRow and QQuickImplicitGrid, which are private
subclasses of their respective positioners that simply set
useImplicitSize to true in their constructors.
- Exports the wrappers privately so that they can be registered by
other modules as QML types.
Change-Id: Ie68aabd7fbf6c76375badf6e338f2f238f3fc392
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Reviewed-by: Robin Burchell <robin.burchell@crimson.no>
Diffstat (limited to 'tests/auto/quick/qquickpositioners')
3 files changed, 65 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickpositioners/data/implicitGridOneItem.qml b/tests/auto/quick/qquickpositioners/data/implicitGridOneItem.qml new file mode 100644 index 0000000000..8da9fc270d --- /dev/null +++ b/tests/auto/quick/qquickpositioners/data/implicitGridOneItem.qml @@ -0,0 +1,12 @@ +import QtQuick 2.9 +import PositionerTest 1.0 + +ImplicitGrid { + columns: 2 + rows: 1 + + Text { + text: "Text" + width: parent.width + } +} diff --git a/tests/auto/quick/qquickpositioners/data/implicitRowOneItem.qml b/tests/auto/quick/qquickpositioners/data/implicitRowOneItem.qml new file mode 100644 index 0000000000..25a287cf31 --- /dev/null +++ b/tests/auto/quick/qquickpositioners/data/implicitRowOneItem.qml @@ -0,0 +1,9 @@ +import QtQuick 2.9 +import PositionerTest 1.0 + +ImplicitRow { + Text { + text: "Text" + width: parent.width + } +} diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp index 1b3939401a..4c4afb7a7b 100644 --- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp +++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp @@ -98,6 +98,8 @@ private slots: void test_attachedproperties(); void test_attachedproperties_data(); void test_attachedproperties_dynamic(); + void test_useImplicitSize_oneItem_data(); + void test_useImplicitSize_oneItem(); void populateTransitions_row(); void populateTransitions_row_data(); @@ -304,6 +306,8 @@ void tst_qquickpositioners::moveTransitions_flow_data() tst_qquickpositioners::tst_qquickpositioners() { + qmlRegisterType<QQuickImplicitRow>("PositionerTest", 1, 0, "ImplicitRow"); + qmlRegisterType<QQuickImplicitGrid>("PositionerTest", 1, 0, "ImplicitGrid"); } void tst_qquickpositioners::test_horizontal() @@ -4004,6 +4008,46 @@ void tst_qquickpositioners::test_attachedproperties_dynamic() } +void tst_qquickpositioners::test_useImplicitSize_oneItem_data() +{ + QTest::addColumn<QString>("positionerType"); + + QTest::newRow("Grid") << "Grid"; + QTest::newRow("Row") << "Row"; +} + +void tst_qquickpositioners::test_useImplicitSize_oneItem() +{ + QFETCH(QString, positionerType); + + QQuickView view; + view.setSource(testFileUrl(QString::fromLatin1("implicit%1OneItem.qml").arg(positionerType))); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QQuickItem *positioner = view.rootObject(); + QVERIFY(positioner); + const qreal oldPositionerImplicitWidth = positioner->implicitWidth(); + + QQuickText *text = qobject_cast<QQuickText*>(positioner->childItems().first()); + QVERIFY(text); + const qreal oldTextImplicitWidth = text->implicitWidth(); + QCOMPARE(positioner->implicitWidth(), text->implicitWidth()); + + // Ensure that the implicit size of the positioner changes when the implicit size + // of one of its children changes. + text->setText(QLatin1String("Even More Text")); + const qreal textImplicitWidthIncrease = text->implicitWidth() - oldTextImplicitWidth; + QVERIFY(textImplicitWidthIncrease > 0); + QTRY_COMPARE(positioner->implicitWidth(), oldPositionerImplicitWidth + textImplicitWidthIncrease); + + // Ensure that the implicit size of the positioner does not change when the + // explicit size of one of its children changes. + text->setWidth(10); + QTRY_COMPARE(positioner->implicitWidth(), oldPositionerImplicitWidth + textImplicitWidthIncrease); +} + QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait) { QQuickView *window = new QQuickView(0); |