From 97e530bbc0066cf9f60891b99a5a974e4c3ced85 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Wed, 13 May 2020 11:04:23 +0200 Subject: [PATCH] QQuickItemView: Fix max(X/Y)Extent() QQuickFlickable maxXExtent() and maxYExtent() return the amount of space that is not shown when inside a ScrollView. QQuickItemView however just returned width() if vertical and height() if horizontal. In these cases just defer to the QQuickFlickable base implementation like minXExtent() and minYExtent() already do. Fixes: QTBUG-83890 Pick-to: 6.2 6.4 Change-Id: I7f4060c2f46ae07611bedceca0d322c5f7f6affb Reviewed-by: Richard Moe Gustavsen Reviewed-by: Shawn Rutledge (cherry picked from commit 99047ae219ff6689da38cc988a25030fece655da) --- src/quick/items/qquickitemview.cpp | 4 +- .../qquickgridview/tst_qquickgridview.cpp | 29 +++--- .../qquicklistview/tst_qquicklistview.cpp | 14 ++- .../quick/qquicklistview2/data/maxXExtent.qml | 29 ++++++ .../quick/qquicklistview2/data/maxYExtent.qml | 30 ++++++ .../qquicklistview2/tst_qquicklistview2.cpp | 94 +++++++++++++++++++ tests/auto/quick/quick.pro | 1 + 7 files changed, 174 insertions(+), 27 deletions(-) create mode 100644 tests/auto/quick/qquicklistview2/data/maxXExtent.qml create mode 100644 tests/auto/quick/qquicklistview2/data/maxYExtent.qml create mode 100644 tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index f8ad168a17..a797bec4ef 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -1393,7 +1393,7 @@ qreal QQuickItemView::maxYExtent() const { Q_D(const QQuickItemView); if (d->layoutOrientation() == Qt::Horizontal) - return height(); + return QQuickFlickable::maxYExtent(); if (d->vData.maxExtentDirty) { d->maxExtent = d->maxExtentForAxis(d->vData, false); @@ -1421,7 +1421,7 @@ qreal QQuickItemView::maxXExtent() const { Q_D(const QQuickItemView); if (d->layoutOrientation() == Qt::Vertical) - return width(); + return QQuickFlickable::maxXExtent(); if (d->hData.maxExtentDirty) { d->maxExtent = d->maxExtentForAxis(d->hData, true); diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index 46e3457d6e..7f79968440 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -3543,51 +3543,46 @@ void tst_QQuickGridView::extents_data() QTest::newRow("LeftToRight, LtR, TtB") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::TopToBottom - << QPointF(0, -20) << QPointF(0, 0) - << QPointF(0, 20) << QPointF(240, 20) + << QPointF(0, -20) << QPointF(0, 0) << QPointF(0, 20) << QPointF(0, 20) << QPointF(0, -20) << QPointF(0, -20); QTest::newRow("LeftToRight, RtL, TtB") << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::TopToBottom - << QPointF(0, -20) << QPointF(0, 0) - << QPointF(0, 20) << QPointF(240, 20) + << QPointF(0, -20) << QPointF(0, 0) << QPointF(0, 20) << QPointF(0, 20) << QPointF(0, -20) << QPointF(0, -20); QTest::newRow("LeftToRight, LtR, BtT") << QQuickGridView::FlowLeftToRight << Qt::LeftToRight << QQuickItemView::BottomToTop - << QPointF(0, 0) << QPointF(0, -30) - << QPointF(0, 320 - 20) << QPointF(240, 320 - 20) // content flow is reversed + << QPointF(0, 0) << QPointF(0, -30) << QPointF(0, 320 - 20) + << QPointF(0, 320 - 20) // content flow is reversed << QPointF(0, -30) << QPointF(0, (-60.0 * 10) - 30); QTest::newRow("LeftToRight, RtL, BtT") << QQuickGridView::FlowLeftToRight << Qt::RightToLeft << QQuickItemView::BottomToTop - << QPointF(0, 0) << QPointF(0, -30) - << QPointF(0, 320 - 20) << QPointF(240, 320 - 20) // content flow is reversed + << QPointF(0, 0) << QPointF(0, -30) << QPointF(0, 320 - 20) + << QPointF(0, 320 - 20) // content flow is reversed << QPointF(0, -30) << QPointF(0, (-60.0 * 10) - 30); - QTest::newRow("TopToBottom, LtR, TtB") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::TopToBottom - << QPointF(-20, 0) << QPointF(0, 0) - << QPointF(20, 0) << QPointF(20, 320) + << QPointF(-20, 0) << QPointF(0, 0) << QPointF(20, 0) << QPointF(20, 0) << QPointF(-20, 0) << QPointF(-20, 0); QTest::newRow("TopToBottom, RtL, TtB") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::TopToBottom - << QPointF(0, 0) << QPointF(-30, 0) - << QPointF(240 - 20, 0) << QPointF(240 - 20, 320) // content flow is reversed + << QPointF(0, 0) << QPointF(-30, 0) << QPointF(240 - 20, 0) + << QPointF(240 - 20, 0) // content flow is reversed << QPointF(-30, 0) << QPointF((-80.0 * 6) - 30, 0); QTest::newRow("TopToBottom, LtR, BtT") << QQuickGridView::FlowTopToBottom << Qt::LeftToRight << QQuickItemView::BottomToTop - << QPointF(-20, -320) << QPointF(0, -320) - << QPointF(20, 0) << QPointF(20, 320) + << QPointF(-20, -320) << QPointF(0, -320) << QPointF(20, 0) << QPointF(20, 0) << QPointF(-20, 0) << QPointF(-20, 0); QTest::newRow("TopToBottom, RtL, BtT") << QQuickGridView::FlowTopToBottom << Qt::RightToLeft << QQuickItemView::BottomToTop - << QPointF(0, -320) << QPointF(-30, -320) - << QPointF(240 - 20, 0) << QPointF(240 - 20, 320) // content flow is reversed + << QPointF(0, -320) << QPointF(-30, -320) << QPointF(240 - 20, 0) + << QPointF(240 - 20, 0) // content flow is reversed << QPointF(-30, 0) << QPointF((-80.0 * 6) - 30, 0); } diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index d3deb513d0..2de6f5435c 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -4278,26 +4278,24 @@ void tst_QQuickListView::extents_data() QTest::newRow("Vertical, TopToBottom") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::TopToBottom - << QPointF(0, -20) << QPointF(0, 0) - << QPointF(0, 20) << QPointF(240, 20) + << QPointF(0, -20) << QPointF(0, 0) << QPointF(0, 20) << QPointF(0, 20) << QPointF(0, -20) << QPointF(0, -20) << QPointF(0, -20); QTest::newRow("Vertical, BottomToTop") << QQuickListView::Vertical << Qt::LeftToRight << QQuickItemView::BottomToTop - << QPointF(0, 0) << QPointF(0, -30) - << QPointF(0, 320 - 20) << QPointF(240, 320 - 20) // content flow is reversed + << QPointF(0, 0) << QPointF(0, -30) << QPointF(0, 320 - 20) + << QPointF(0, 320 - 20) // content flow is reversed << QPointF(0, -30) << QPointF(0, (-30.0 * 3) - 30) << QPointF(0, (-30.0 * 30) - 30); QTest::newRow("Horizontal, LeftToRight") << QQuickListView::Horizontal << Qt::LeftToRight << QQuickItemView::TopToBottom - << QPointF(-20, 0) << QPointF(0, 0) - << QPointF(20, 0) << QPointF(20, 320) + << QPointF(-20, 0) << QPointF(0, 0) << QPointF(20, 0) << QPointF(20, 0) << QPointF(-20, 0) << QPointF(-20, 0) << QPointF(-20, 0); QTest::newRow("Horizontal, RightToLeft") << QQuickListView::Horizontal << Qt::RightToLeft << QQuickItemView::TopToBottom - << QPointF(0, 0) << QPointF(-30, 0) - << QPointF(240 - 20, 0) << QPointF(240 - 20, 320) // content flow is reversed + << QPointF(0, 0) << QPointF(-30, 0) << QPointF(240 - 20, 0) + << QPointF(240 - 20, 0) // content flow is reversed << QPointF(-30, 0) << QPointF((-240.0 * 3) - 30, 0) << QPointF((-240.0 * 30) - 30, 0); } diff --git a/tests/auto/quick/qquicklistview2/data/maxXExtent.qml b/tests/auto/quick/qquicklistview2/data/maxXExtent.qml new file mode 100644 index 0000000000..b9e88cfc9e --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/maxXExtent.qml @@ -0,0 +1,29 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick + +Item { + property alias view: view + + ListView { + id: view + model: 10 + width: 200 + height: 200 + + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: "darkorange" + } + + delegate: Rectangle { + width: 100 + height: 100 + Text { + text: modelData + } + } + } +} diff --git a/tests/auto/quick/qquicklistview2/data/maxYExtent.qml b/tests/auto/quick/qquicklistview2/data/maxYExtent.qml new file mode 100644 index 0000000000..3be8948691 --- /dev/null +++ b/tests/auto/quick/qquicklistview2/data/maxYExtent.qml @@ -0,0 +1,30 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick + +Item { + property alias view: view + + ListView { + id: view + model: 10 + width: 200 + height: 200 + orientation: ListView.Horizontal + + Rectangle { + anchors.fill: parent + color: "transparent" + border.color: "darkorange" + } + + delegate: Rectangle { + width: 100 + height: 100 + Text { + text: modelData + } + } + } +} diff --git a/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp new file mode 100644 index 0000000000..40b440d9cd --- /dev/null +++ b/tests/auto/quick/qquicklistview2/tst_qquicklistview2.cpp @@ -0,0 +1,94 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests") + +using namespace QQuickViewTestUtils; +using namespace QQuickVisualTestUtils; + +class tst_QQuickListView2 : public QQmlDataTest +{ + Q_OBJECT +public: + tst_QQuickListView2(); + +private slots: + void maxExtent_data(); + void maxExtent(); +}; + +tst_QQuickListView2::tst_QQuickListView2() + : QQmlDataTest(QT_QMLTEST_DATADIR) +{ +} + +class FriendlyItemView : public QQuickItemView +{ + friend class ItemViewAccessor; +}; + +class ItemViewAccessor +{ +public: + ItemViewAccessor(QQuickItemView *itemView) : + mItemView(reinterpret_cast(itemView)) + { + } + + qreal maxXExtent() const + { + return mItemView->maxXExtent(); + } + + qreal maxYExtent() const + { + return mItemView->maxYExtent(); + } + +private: + FriendlyItemView *mItemView = nullptr; +}; + +void tst_QQuickListView2::maxExtent_data() +{ + QTest::addColumn("qmlFilePath"); + QTest::addRow("maxXExtent") << "maxXExtent.qml"; + QTest::addRow("maxYExtent") << "maxYExtent.qml"; +} + +void tst_QQuickListView2::maxExtent() +{ + QFETCH(QString, qmlFilePath); + + QScopedPointer window(createView()); + QVERIFY(window); + window->setSource(testFileUrl(qmlFilePath)); + QVERIFY2(window->status() == QQuickView::Ready, qPrintable(QDebug::toString(window->errors()))); + window->resize(640, 480); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickListView *view = window->rootObject()->property("view").value(); + QVERIFY(view); + ItemViewAccessor viewAccessor(view); + if (view->orientation() == QQuickListView::Vertical) + QCOMPARE(viewAccessor.maxXExtent(), 0); + else if (view->orientation() == QQuickListView::Horizontal) + QCOMPARE(viewAccessor.maxYExtent(), 0); +} + +QTEST_MAIN(tst_QQuickListView2) + +#include "tst_qquicklistview2.moc" diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro index 45bcf8a9ce..00f7d64d1e 100644 --- a/tests/auto/quick/quick.pro +++ b/tests/auto/quick/quick.pro @@ -67,6 +67,7 @@ QUICKTESTS += \ qquickitem2 \ qquickitemlayer \ qquicklistview \ + qquicklistview2 \ qquicktableview \ qquickloader \ qquickmousearea \ -- GitLab