diff options
Diffstat (limited to 'tests/auto/quick/qquicklistview')
3 files changed, 247 insertions, 0 deletions
diff --git a/tests/auto/quick/qquicklistview/data/delegateWithMouseArea2.qml b/tests/auto/quick/qquicklistview/data/delegateWithMouseArea2.qml new file mode 100644 index 0000000000..dee89ae4cd --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/delegateWithMouseArea2.qml @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.15 + +Rectangle { + + width: 240 + height: 320 + color: "#ffffff" + + Component { + id: myDelegate + Rectangle { + id: wrapper + width: list.orientation == ListView.Vertical ? 240 : 20 + height: list.orientation == ListView.Vertical ? 20 : 240 + border.width: 1 + border.color: "black" + MouseArea { + anchors.fill: parent + } + Text { + text: index + ":" + (list.orientation == ListView.Vertical ? parent.y : parent.x).toFixed(0) + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 200 + clip: true + model: 30 + headerPositioning: ListView.OverlayHeader + delegate: myDelegate + + header: Rectangle { + width: list.orientation == Qt.Vertical ? 240 : 30 + height: list.orientation == Qt.Vertical ? 30 : 240 + color: "green" + z: 11 + Text { + anchors.centerIn: parent + text: "header " + (list.orientation == ListView.Vertical ? parent.y : parent.x).toFixed(1) + } + } + } + + // debug + Rectangle { + color: "#40ff0000" + border.width: txt.x + border.color: "black" + radius: 5 + width: txt.implicitWidth + 50 + height: txt.implicitHeight + 2 * txt.x + anchors.bottom: parent.bottom + anchors.right: parent.right + anchors.left: parent.left + + Text { + id: txt + x: 3 + y: x + text: "header position: " + (list.orientation == ListView.Vertical ? list.headerItem.y : list.headerItem.x).toFixed(1) + + "\ncontent position: " + (list.orientation == ListView.Vertical ? list.contentY : list.contentX).toFixed(1) + } + } +} diff --git a/tests/auto/quick/qquicklistview/data/qtbug86744.qml b/tests/auto/quick/qquicklistview/data/qtbug86744.qml new file mode 100644 index 0000000000..6dc82d57eb --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug86744.qml @@ -0,0 +1,21 @@ +import QtQuick 2.15 +import QtQml.Models 2.15 + +Item { + height: 200 + width: 100 + DelegateModel { + id: dm + model: 2 + delegate: Item { + width: 100; height: 20 + property bool isCurrent: ListView.isCurrentItem + } + } + ListView { + objectName: "listView" + model: dm + currentIndex: 1 + anchors.fill: parent + } +} diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index a7aefbe432..df329f8318 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -299,6 +299,9 @@ private slots: void requiredObjectListModel(); void clickHeaderAndFooterWhenClip(); void animatedDelegate(); + void dragDelegateWithMouseArea(); + void dragDelegateWithMouseArea_data(); + void isCurrentItem_DelegateModel(); private: template <class T> void items(const QUrl &source); @@ -10109,6 +10112,109 @@ void tst_QQuickListView::animatedDelegate() } } +static void dragListView(QWindow *window, QPoint *startPos, const QPoint &delta) +{ + auto drag_helper = [&](QWindow *window, QPoint *startPos, const QPoint &d) { + QPoint pos = *startPos; + const int dragDistance = d.manhattanLength(); + const QPoint unitVector(qBound(-1, d.x(), 1), qBound(-1, d.y(), 1)); + for (int i = 0; i < dragDistance; ++i) { + QTest::mouseMove(window, pos); + pos += unitVector; + } + // Move to the final position + pos = *startPos + d; + QTest::mouseMove(window, pos); + *startPos = pos; + }; + + if (delta.manhattanLength() == 0) + return; + const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); + const QPoint unitVector(qBound(-1, delta.x(), 1), qBound(-1, delta.y(), 1)); + // go just beyond the drag theshold + drag_helper(window, startPos, unitVector * (dragThreshold + 1)); + drag_helper(window, startPos, unitVector); + + // next drag will actually scroll the listview + drag_helper(window, startPos, delta); +} + +void tst_QQuickListView::dragDelegateWithMouseArea() +{ + QFETCH(QQuickItemView::LayoutDirection, layoutDirection); + + QScopedPointer<QQuickView> window(createView()); + QVERIFY(window); + window->setSource(testFileUrl("delegateWithMouseArea2.qml")); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list"); + QVERIFY(listview != nullptr); + + const bool horizontal = layoutDirection < QQuickItemView::VerticalTopToBottom; + listview->setOrientation(horizontal ? QQuickListView::Horizontal : QQuickListView::Vertical); + + if (horizontal) + listview->setLayoutDirection(static_cast<Qt::LayoutDirection>(layoutDirection)); + else + listview->setVerticalLayoutDirection(static_cast<QQuickItemView::VerticalLayoutDirection>(layoutDirection)); + + QVERIFY(QQuickTest::qWaitForItemPolished(listview)); + + auto contentPosition = [&](QQuickListView *listview) { + return (listview->orientation() == QQuickListView::Horizontal ? listview->contentX(): listview->contentY()); + }; + + qreal expectedContentPosition = contentPosition(listview); + QPoint startPos = (QPointF(listview->width(), listview->height())/2).toPoint(); + QTest::mousePress(window.data(), Qt::LeftButton, Qt::NoModifier, startPos, 200); + + QPoint dragDelta(0, -10); + + if (layoutDirection == QQuickItemView::RightToLeft || layoutDirection == QQuickItemView::VerticalBottomToTop) + dragDelta = -dragDelta; + expectedContentPosition -= dragDelta.y(); + if (horizontal) + dragDelta = dragDelta.transposed(); + + dragListView(window.data(), &startPos, dragDelta); + + QTest::mouseRelease(window.data(), Qt::LeftButton, Qt::NoModifier, startPos, 200); // Wait 200 ms before we release to avoid trigger a flick + + // wait for the "fixup" animation to finish + QVERIFY(QTest::qWaitFor([&]() + { return !listview->isMoving();} + )); + + QCOMPARE(contentPosition(listview), expectedContentPosition); +} + +void tst_QQuickListView::dragDelegateWithMouseArea_data() +{ + QTest::addColumn<QQuickItemView::LayoutDirection>("layoutDirection"); + + for (int layDir = QQuickItemView::LeftToRight; layDir <= (int)QQuickItemView::VerticalBottomToTop; layDir++) { + const char *enumValueName = QMetaEnum::fromType<QQuickItemView::LayoutDirection>().valueToKey(layDir); + QTest::newRow(enumValueName) << static_cast<QQuickItemView::LayoutDirection>(layDir); + } +} + +void tst_QQuickListView::isCurrentItem_DelegateModel() +{ + QScopedPointer<QQuickView> window(createView()); + window->setSource(testFileUrl("qtbug86744.qml")); + window->resize(640, 480); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickListView* listView = window->rootObject()->findChild<QQuickListView*>("listView"); + QVERIFY(listView); + QVariant value = listView->itemAtIndex(1)->property("isCurrent"); + QVERIFY(value.toBool() == true); +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" |