diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2016-06-25 12:16:25 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2016-12-29 11:43:59 +0000 |
commit | bb594453f9cb96bf8f2975d4a8aa5379cfc46e23 (patch) | |
tree | ce081a574c6fb7e54cb3d519c9556fe3536e38c2 /tests/auto/quick | |
parent | 9a272ad1854d744ea57296ba633b9d0dc19d1625 (diff) |
Flickable: add horizontal/verticalOvershoot properties
[ChangeLog][QtQuick][Flickable] Added horizontalOvershoot and
verticalOvershoot properties that can be used for implementing
boundary actions and effects.
Task-number: QTBUG-38515
Change-Id: I06379348a67d03507b56788d6fc7020bbb2d375f
Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
Diffstat (limited to 'tests/auto/quick')
3 files changed, 330 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickflickable/data/overshoot.qml b/tests/auto/quick/qquickflickable/data/overshoot.qml new file mode 100644 index 0000000000..4235156479 --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/overshoot.qml @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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.9 + +Flickable { + width: 200; height: 200 + contentWidth: rect.width; contentHeight: rect.height + + property real minContentY: 0 + property real maxContentY: 0 + onContentYChanged: { + minContentY = Math.min(contentY, minContentY) + maxContentY = Math.max(contentY, maxContentY) + } + + property real minContentX: 0 + property real maxContentX: 0 + onContentXChanged: { + minContentX = Math.min(contentX, minContentX) + maxContentX = Math.max(contentX, maxContentX) + } + + property real minVerticalOvershoot: 0 + property real maxVerticalOvershoot: 0 + onVerticalOvershootChanged: { + minVerticalOvershoot = Math.min(verticalOvershoot, minVerticalOvershoot) + maxVerticalOvershoot = Math.max(verticalOvershoot, maxVerticalOvershoot) + } + + property real minHorizontalOvershoot: 0 + property real maxHorizontalOvershoot: 0 + onHorizontalOvershootChanged: { + minHorizontalOvershoot = Math.min(horizontalOvershoot, minHorizontalOvershoot) + maxHorizontalOvershoot = Math.max(horizontalOvershoot, maxHorizontalOvershoot) + } + + function reset() { + minContentY = contentY + maxContentY = contentY + minContentX = contentX + maxContentX = contentX + minVerticalOvershoot = 0 + maxVerticalOvershoot = 0 + minHorizontalOvershoot = 0 + maxHorizontalOvershoot = 0 + } + + Rectangle { + id: rect + color: "red" + width: 400; height: 400 + } +} diff --git a/tests/auto/quick/qquickflickable/data/overshoot_reentrant.qml b/tests/auto/quick/qquickflickable/data/overshoot_reentrant.qml new file mode 100644 index 0000000000..bc7abba25a --- /dev/null +++ b/tests/auto/quick/qquickflickable/data/overshoot_reentrant.qml @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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.9 + +Flickable { + width: 200; height: 200 + contentWidth: rect.width; contentHeight: rect.height + + property real contentPosAdjustment: 0.0 + + onContentXChanged: { + var adjustment = contentPosAdjustment + contentPosAdjustment = 0.0 + contentX += adjustment + } + + onContentYChanged: { + var adjustment = contentPosAdjustment + contentPosAdjustment = 0.0 + contentY += adjustment + } + + Rectangle { + id: rect + border.color: "red" + border.width: 5 + width: 400; height: 400 + } +} diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index 942e99018f..1ad691d1c1 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -95,6 +95,9 @@ private slots: void ratios_smallContent(); void contentXYNotTruncatedToInt(); void keepGrab(); + void overshoot(); + void overshoot_data(); + void overshoot_reentrant(); private: void flickWithTouch(QQuickWindow *window, QTouchDevice *touchDevice, const QPoint &from, const QPoint &to); @@ -2037,6 +2040,199 @@ void tst_qquickflickable::keepGrab() QVERIFY(flickable->contentY() != 0.0); } +Q_DECLARE_METATYPE(QQuickFlickable::BoundsBehavior) + +void tst_qquickflickable::overshoot() +{ + QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior); + + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("overshoot.qml")); + window->show(); + + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); + QVERIFY(flickable); + + QCOMPARE(flickable->width(), 200.0); + QCOMPARE(flickable->height(), 200.0); + QCOMPARE(flickable->contentWidth(), 400.0); + QCOMPARE(flickable->contentHeight(), 400.0); + + flickable->setBoundsBehavior(boundsBehavior); + + // drag past the beginning + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(10, 10)); + QTest::mouseMove(window.data(), QPoint(20, 20)); + QTest::mouseMove(window.data(), QPoint(30, 30)); + QTest::mouseMove(window.data(), QPoint(40, 40)); + QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(50, 50)); + + if (boundsBehavior & QQuickFlickable::DragOverBounds) { + QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0); + QVERIFY(flickable->property("minHorizontalOvershoot").toReal() < 0.0); + QCOMPARE(flickable->property("minContentY").toReal(), + flickable->property("minVerticalOvershoot").toReal()); + QCOMPARE(flickable->property("minContentX").toReal(), + flickable->property("minHorizontalOvershoot").toReal()); + } else { + QCOMPARE(flickable->property("minContentY").toReal(), 0.0); + QCOMPARE(flickable->property("minContentX").toReal(), 0.0); + QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0); + } + QCOMPARE(flickable->property("maxContentY").toReal(), 0.0); + QCOMPARE(flickable->property("maxContentX").toReal(), 0.0); + QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0); + + flickable->setContentX(20.0); + flickable->setContentY(20.0); + QMetaObject::invokeMethod(flickable, "reset"); + + // flick past the beginning + flick(window.data(), QPoint(10, 10), QPoint(50, 50), 100); + QTRY_VERIFY(!flickable->property("flicking").toBool()); + + if (boundsBehavior & QQuickFlickable::OvershootBounds) { + QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0); + QVERIFY(flickable->property("minHorizontalOvershoot").toReal() < 0.0); + QCOMPARE(flickable->property("minContentY").toReal(), + flickable->property("minVerticalOvershoot").toReal()); + QCOMPARE(flickable->property("minContentX").toReal(), + flickable->property("minHorizontalOvershoot").toReal()); + } else { + QCOMPARE(flickable->property("minContentY").toReal(), 0.0); + QCOMPARE(flickable->property("minContentX").toReal(), 0.0); + QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0); + } + QCOMPARE(flickable->property("maxContentY").toReal(), 20.0); + QCOMPARE(flickable->property("maxContentX").toReal(), 20.0); + QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0); + + flickable->setContentX(200.0); + flickable->setContentY(200.0); + QMetaObject::invokeMethod(flickable, "reset"); + + // drag past the end + QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(50, 50)); + QTest::mouseMove(window.data(), QPoint(40, 40)); + QTest::mouseMove(window.data(), QPoint(30, 30)); + QTest::mouseMove(window.data(), QPoint(20, 20)); + QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(10, 10)); + + if (boundsBehavior & QQuickFlickable::DragOverBounds) { + QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0); + QVERIFY(flickable->property("maxHorizontalOvershoot").toReal() > 0.0); + QCOMPARE(flickable->property("maxContentY").toReal() - 200.0, + flickable->property("maxVerticalOvershoot").toReal()); + QCOMPARE(flickable->property("maxContentX").toReal() - 200.0, + flickable->property("maxHorizontalOvershoot").toReal()); + } else { + QCOMPARE(flickable->property("maxContentY").toReal(), 200.0); + QCOMPARE(flickable->property("maxContentX").toReal(), 200.0); + QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0); + } + QCOMPARE(flickable->property("minContentY").toReal(), 200.0); + QCOMPARE(flickable->property("minContentX").toReal(), 200.0); + QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0); + + flickable->setContentX(180.0); + flickable->setContentY(180.0); + QMetaObject::invokeMethod(flickable, "reset"); + + // flick past the end + flick(window.data(), QPoint(50, 50), QPoint(10, 10), 100); + QTRY_VERIFY(!flickable->property("flicking").toBool()); + + if (boundsBehavior & QQuickFlickable::OvershootBounds) { + QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0); + QVERIFY(flickable->property("maxHorizontalOvershoot").toReal() > 0.0); + QCOMPARE(flickable->property("maxContentY").toReal() - 200.0, + flickable->property("maxVerticalOvershoot").toReal()); + QCOMPARE(flickable->property("maxContentX").toReal() - 200.0, + flickable->property("maxHorizontalOvershoot").toReal()); + } else { + QCOMPARE(flickable->property("maxContentY").toReal(), 200.0); + QCOMPARE(flickable->property("maxContentX").toReal(), 200.0); + QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0); + } + QCOMPARE(flickable->property("minContentY").toReal(), 180.0); + QCOMPARE(flickable->property("minContentX").toReal(), 180.0); + QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0); + QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0); +} + +void tst_qquickflickable::overshoot_data() +{ + QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior"); + + QTest::newRow("StopAtBounds") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds); + QTest::newRow("DragOverBounds") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds); + QTest::newRow("OvershootBounds") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds); + QTest::newRow("DragAndOvershootBounds") + << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds); +} + +void tst_qquickflickable::overshoot_reentrant() +{ + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("overshoot_reentrant.qml")); + window->show(); + + QVERIFY(QTest::qWaitForWindowExposed(window.data())); + + QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject()); + QVERIFY(flickable); + + // horizontal + flickable->setContentX(-10.0); + QCOMPARE(flickable->contentX(), -10.0); + QCOMPARE(flickable->horizontalOvershoot(), -10.0); + + flickable->setProperty("contentPosAdjustment", -5.0); + flickable->setContentX(-20.0); + QCOMPARE(flickable->contentX(), -25.0); + QCOMPARE(flickable->horizontalOvershoot(), -25.0); + + flickable->setContentX(210); + QCOMPARE(flickable->contentX(), 210.0); + QCOMPARE(flickable->horizontalOvershoot(), 10.0); + + flickable->setProperty("contentPosAdjustment", 5.0); + flickable->setContentX(220.0); + QCOMPARE(flickable->contentX(), 225.0); + QCOMPARE(flickable->horizontalOvershoot(), 25.0); + + // vertical + flickable->setContentY(-10.0); + QCOMPARE(flickable->contentY(), -10.0); + QCOMPARE(flickable->verticalOvershoot(), -10.0); + + flickable->setProperty("contentPosAdjustment", -5.0); + flickable->setContentY(-20.0); + QCOMPARE(flickable->contentY(), -25.0); + QCOMPARE(flickable->verticalOvershoot(), -25.0); + + flickable->setContentY(210); + QCOMPARE(flickable->contentY(), 210.0); + QCOMPARE(flickable->verticalOvershoot(), 10.0); + + flickable->setProperty("contentPosAdjustment", 5.0); + flickable->setContentY(220.0); + QCOMPARE(flickable->contentY(), 225.0); + QCOMPARE(flickable->verticalOvershoot(), 25.0); +} + QTEST_MAIN(tst_qquickflickable) #include "tst_qquickflickable.moc" |