From 0f043c594b559f2f936333c8cf9779283a480c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pasi=20Pet=C3=A4j=C3=A4j=C3=A4rvi?= Date: Fri, 20 Oct 2017 11:09:22 +0300 Subject: Fix providing correct velocity when using index based scrolling Index based scrolling does not enable moving and flicking properties. Task-number: QTBUG-34576 Change-Id: Ief06d37115ca389027670c97ce6c0457a74d4872 Reviewed-by: Qt CI Bot Reviewed-by: Shawn Rutledge --- src/quick/items/qquickflickable.cpp | 6 +- src/quick/items/qquickitemview.cpp | 3 - .../auto/quick/qquicklistview/data/qtbug34576.qml | 102 +++++++++++++++++++++ .../quick/qquicklistview/tst_qquicklistview.cpp | 50 ++++++++++ 4 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 tests/auto/quick/qquicklistview/data/qtbug34576.qml diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 3462752370..e0f8b6de00 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -748,7 +748,8 @@ void QQuickFlickable::setContentX(qreal pos) d->hData.explicitValue = true; d->resetTimeline(d->hData); d->hData.vTime = d->timeline.time(); - movementEnding(true, false); + if (isMoving() || isFlicking()) + movementEnding(true, false); if (-pos != d->hData.move.value()) d->hData.move.setValue(-pos); } @@ -765,7 +766,8 @@ void QQuickFlickable::setContentY(qreal pos) d->vData.explicitValue = true; d->resetTimeline(d->vData); d->vData.vTime = d->timeline.time(); - movementEnding(false, true); + if (isMoving() || isFlicking()) + movementEnding(false, true); if (-pos != d->vData.move.value()) d->vData.move.setValue(-pos); } diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 66438ee37d..478499e209 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -926,7 +926,6 @@ void QQuickItemView::setDisplacedTransition(QQuickTransition *transition) void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode) { - Q_Q(QQuickItemView); if (!isValid()) return; if (mode < QQuickItemView::Beginning || mode > QQuickItemView::SnapPosition) @@ -988,7 +987,6 @@ void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode) qreal minExtent = calculatedMinExtent(); pos = qMax(pos, minExtent); moveReason = QQuickItemViewPrivate::Other; - q->cancelFlick(); setPosition(pos); if (highlight) { @@ -1394,7 +1392,6 @@ void QQuickItemView::trackedPositionChanged() pos = qMax(trackedPos, toItemPos); } if (viewPos != pos) { - cancelFlick(); d->calcVelocity = true; d->setPosition(pos); d->calcVelocity = false; diff --git a/tests/auto/quick/qquicklistview/data/qtbug34576.qml b/tests/auto/quick/qquicklistview/data/qtbug34576.qml new file mode 100644 index 0000000000..f407d8ebe3 --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/qtbug34576.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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:GPL-EXCEPT$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +import QtQuick 2.7 + +Rectangle { + id: root + width: 320 + height: 240 + color: "black" + + property int current: list.currentIndex + property int horizontalVelocityZeroCount: 0 + + ListView { + id: list + objectName: "list" + anchors.fill: parent + + focus: true + + orientation: ListView.Horizontal + + snapMode: ListView.SnapToItem + flickableDirection: Flickable.HorizontalFlick + + model: 10 + delegate: Item { + width: root.width / 3 + height: root.height + Rectangle { + anchors.centerIn: parent + width: 50 + height: 50 + color: list.currentIndex === index ? "red" : "white" + } + } + + onHorizontalVelocityChanged: { + if (list.horizontalVelocity === 0.0) + root.horizontalVelocityZeroCount++ + } + + } + + Rectangle { + color: "red" + width: 50 + height: 50 + anchors.left: parent.left + anchors.bottom: parent.bottom + + MouseArea { + anchors.fill: parent + onClicked: { + list.currentIndex--; + } + } + } + + Rectangle { + color: "red" + width: 50 + height: 50 + anchors.right: parent.right + anchors.bottom: parent.bottom + + MouseArea { + anchors.fill: parent + onClicked: { + list.currentIndex++; + } + } + } +} + diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 2e9c54c5a3..42049fa9ca 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -259,6 +259,8 @@ private slots: void itemFiltered(); void releaseItems(); + void QTBUG_34576_velocityZero(); + private: template void items(const QUrl &source); template void changed(const QUrl &source); @@ -8607,6 +8609,54 @@ void tst_QQuickListView::releaseItems() listview->setModel(123); } +void tst_QQuickListView::QTBUG_34576_velocityZero() +{ + QQuickView *window = new QQuickView(0); + window->setGeometry(0,0,240,320); + + QQmlContext *ctxt = window->rootContext(); + + QString filename(testFile("qtbug34576.qml")); + window->setSource(QUrl::fromLocalFile(filename)); + window->show(); + QVERIFY(QTest::qWaitForWindowExposed(window)); + + QQuickListView *listview = findItem(window->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false); + + QSignalSpy horizontalVelocitySpy(listview, SIGNAL(horizontalVelocityChanged())); + + // currentIndex is initialized to 0 + QCOMPARE(listview->currentIndex(), 0); + + // set currentIndex to last item currently visible item + window->rootObject()->setProperty("horizontalVelocityZeroCount", QVariant(0)); + listview->setCurrentIndex(2); + QTRY_COMPARE(window->rootObject()->property("current").toInt(), 2); + QTRY_COMPARE(horizontalVelocitySpy.count(), 0); + QTRY_COMPARE(window->rootObject()->property("horizontalVelocityZeroCount").toInt(), 0); + + // click button which increases currentIndex + QTest::mousePress(window, Qt::LeftButton, 0, QPoint(295,215)); + QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(295,215)); + + // verify that currentIndexChanged is triggered + QVERIFY(horizontalVelocitySpy.wait()); + + // set currentIndex to item out of view to cause listview scroll + QTRY_COMPARE(window->rootObject()->property("current").toInt(), 3); + QTRY_COMPARE(horizontalVelocitySpy.count() > 0, true); + QVERIFY(horizontalVelocitySpy.wait(1000)); + + // velocity should be always > 0.0 + QTRY_COMPARE(window->rootObject()->property("horizontalVelocityZeroCount").toInt(), 0); + + delete window; +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" -- cgit v1.2.3