From 0fa73f20da54029c1eb9729c8df6730d1a02c008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= Date: Wed, 24 Aug 2022 15:41:29 +0200 Subject: StackLayout: Do not set size of children to (-1, -1) The item-size-hint-cache in StackLayout was not always valid when QQuickStackLayout::rearrange() was entered, so it would end up setting the size of the item to (-1, -1) Fixes: QTBUG-105899 Change-Id: I632aa18bb10b84d59af35cd3c7cb0c675d8d1692 Reviewed-by: Oliver Eftevaag (cherry picked from commit 9a4874ab7f18a54b2497f689dfd7f7a2ee0516b8) Reviewed-by: Qt Cherry-pick Bot --- src/quicklayouts/qquickstacklayout.cpp | 15 +++++-- src/quicklayouts/qquickstacklayout_p.h | 1 + .../quick/qquicklayouts/data/tst_stacklayout.qml | 51 ++++++++++++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/quicklayouts/qquickstacklayout.cpp b/src/quicklayouts/qquickstacklayout.cpp index 5b2b0dcbcd..c81b0b5acc 100644 --- a/src/quicklayouts/qquickstacklayout.cpp +++ b/src/quicklayouts/qquickstacklayout.cpp @@ -190,10 +190,8 @@ QSizeF QQuickStackLayout::sizeHint(Qt::SizeHint whichSizeHint) const maxS = QSizeF(std::numeric_limits::infinity(), std::numeric_limits::infinity()); const int count = itemCount(); - m_cachedItemSizeHints.resize(count); for (int i = 0; i < count; ++i) { - SizeHints &hints = m_cachedItemSizeHints[i]; - QQuickStackLayout::collectItemSizeHints(itemAt(i), hints.array); + SizeHints &hints = cachedItemSizeHints(i); minS = minS.expandedTo(hints.min()); prefS = prefS.expandedTo(hints.pref()); //maxS = maxS.boundedTo(hints.max()); // Can be resized to be larger than any of its items. @@ -287,6 +285,7 @@ void QQuickStackLayout::childItemsChanged() if (count != d->count) { d->count = count; emit countChanged(); + m_cachedItemSizeHints.resize(count); } for (int i = 0; i < count; ++i) { QQuickItem *child = itemAt(i); @@ -302,6 +301,14 @@ void QQuickStackLayout::childItemsChanged() } } +QQuickStackLayout::SizeHints &QQuickStackLayout::cachedItemSizeHints(int index) const { + SizeHints &hints = m_cachedItemSizeHints[index]; + if (!hints.min().isValid()) + QQuickStackLayout::collectItemSizeHints(itemAt(index), hints.array); + return hints; +} + + void QQuickStackLayout::rearrange(const QSizeF &newSize) { Q_D(QQuickStackLayout); @@ -312,7 +319,7 @@ void QQuickStackLayout::rearrange(const QSizeF &newSize) if (d->currentIndex == -1 || d->currentIndex >= m_cachedItemSizeHints.count()) return; - QQuickStackLayout::SizeHints &hints = m_cachedItemSizeHints[d->currentIndex]; + QQuickStackLayout::SizeHints &hints = cachedItemSizeHints(d->currentIndex); QQuickItem *item = itemAt(d->currentIndex); Q_ASSERT(item); item->setPosition(QPointF(0,0)); // ### respect alignment? diff --git a/src/quicklayouts/qquickstacklayout_p.h b/src/quicklayouts/qquickstacklayout_p.h index c7c174450e..bf52e83e73 100644 --- a/src/quicklayouts/qquickstacklayout_p.h +++ b/src/quicklayouts/qquickstacklayout_p.h @@ -76,6 +76,7 @@ private: mutable QVector m_cachedItemSizeHints; mutable QSizeF m_cachedSizeHints[Qt::NSizeHints]; + SizeHints &cachedItemSizeHints(int index) const; }; class QQuickStackLayoutPrivate : public QQuickLayoutPrivate diff --git a/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml b/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml index a04e7a9dd7..3455dd5cc1 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_stacklayout.qml @@ -263,5 +263,56 @@ Item { compare(layout.implicitWidth, 20) compare(layout.implicitHeight, 20) } + + Component { + id: layout_setCurrentIndex_Component + + StackLayout { + width: 200 + height: 200 + + property alias firstItem : rect + property alias secondItem: rowLayout + + Rectangle { + id: rect + color: "red" + implicitWidth: 10 + implicitHeight: 10 + } + RowLayout { + id: rowLayout + spacing: 0 + Rectangle { + color: "green" + implicitWidth: 10 + implicitHeight: 10 + Layout.fillWidth: true + Layout.fillHeight: true + } + Rectangle { + color: "blue" + implicitWidth: 10 + implicitHeight: 10 + Layout.fillWidth: true + Layout.fillHeight: true + } + } + } + } + + function test_setCurrentIndex() + { + var layout = layout_setCurrentIndex_Component.createObject(container) + compare(layout.firstItem.width, 200) + + // Invalidate the StackLayout (and its cached size hints) + layout.firstItem.implicitWidth = 42 + + layout.currentIndex = 1 + compare(layout.secondItem.width, 200) // width should not be -1 + layout.destroy() + } + } } -- cgit v1.2.3