diff options
Diffstat (limited to 'tests/auto/quick/qquickflickable/tst_qquickflickable.cpp')
-rw-r--r-- | tests/auto/quick/qquickflickable/tst_qquickflickable.cpp | 122 |
1 files changed, 120 insertions, 2 deletions
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp index f3659290eb..62f7c67dd4 100644 --- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp +++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp @@ -27,10 +27,10 @@ ****************************************************************************/ #include <qtest.h> #include <QtTest/QSignalSpy> +#include <QtQuick/qquickview.h> #include <QtGui/QStyleHints> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcomponent.h> -#include <QtQuick/qquickview.h> #include <private/qquickflickable_p.h> #include <private/qquickflickable_p_p.h> #include <private/qquickmousearea_p.h> @@ -206,6 +206,8 @@ private slots: void synchronousDrag_data(); void synchronousDrag(); void visibleAreaBinding(); + void setContentPositionWhileDragging_data(); + void setContentPositionWhileDragging(); private: void flickWithTouch(QQuickWindow *window, const QPoint &from, const QPoint &to); @@ -870,6 +872,7 @@ void tst_qquickflickable::wheel() QVERIFY(flick != nullptr); QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(flick); QSignalSpy moveEndSpy(flick, SIGNAL(movementEnded())); + quint64 timestamp = 10; // test a vertical flick { @@ -877,6 +880,7 @@ void tst_qquickflickable::wheel() QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(0,-120), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); event.setAccepted(false); + event.setTimestamp(timestamp); QGuiApplication::sendEvent(window.data(), &event); } @@ -887,6 +891,7 @@ void tst_qquickflickable::wheel() QCOMPARE(fp->velocityTimeline.isActive(), false); QCOMPARE(fp->timeline.isActive(), false); QTest::qWait(50); // make sure that onContentYChanged won't sneak in again + timestamp += 50; QCOMPARE(flick->property("movementsAfterEnd").value<int>(), 0); // QTBUG-55886 // get ready to test horizontal flick @@ -900,8 +905,8 @@ void tst_qquickflickable::wheel() QPoint pos(200, 200); QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(-120,0), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); - event.setAccepted(false); + event.setTimestamp(timestamp); QGuiApplication::sendEvent(window.data(), &event); } @@ -926,11 +931,13 @@ void tst_qquickflickable::trackpad() QVERIFY(flick != nullptr); QSignalSpy moveEndSpy(flick, SIGNAL(movementEnded())); QPoint pos(200, 200); + quint64 timestamp = 10; { QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,-100), QPoint(0,-120), Qt::NoButton, Qt::NoModifier, Qt::ScrollBegin, false); event.setAccepted(false); + event.setTimestamp(timestamp++); QGuiApplication::sendEvent(window.data(), &event); } @@ -944,6 +951,7 @@ void tst_qquickflickable::trackpad() QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(-100,0), QPoint(-120,0), Qt::NoButton, Qt::NoModifier, Qt::ScrollUpdate, false); event.setAccepted(false); + event.setTimestamp(timestamp++); QGuiApplication::sendEvent(window.data(), &event); } @@ -954,6 +962,7 @@ void tst_qquickflickable::trackpad() QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(0,0), QPoint(0,0), Qt::NoButton, Qt::NoModifier, Qt::ScrollEnd, false); event.setAccepted(false); + event.setTimestamp(timestamp++); QGuiApplication::sendEvent(window.data(), &event); } @@ -2551,6 +2560,115 @@ void tst_qquickflickable::visibleAreaBinding() // Shouldn't crash. } +void tst_qquickflickable::setContentPositionWhileDragging_data() +{ + QTest::addColumn<bool>("isHorizontal"); + QTest::addColumn<int>("newPos"); + QTest::addColumn<int>("newExtent"); + QTest::newRow("horizontal, setContentX") << true << 0 << -1; + QTest::newRow("vertical, setContentY") << false << 0 << -1; + QTest::newRow("horizontal, setContentWidth") << true << -1 << 200; + QTest::newRow("vertical, setContentHeight") << false << -1 << 200; +} + +void tst_qquickflickable::setContentPositionWhileDragging() // QTBUG-104966 +{ + QFETCH(bool, isHorizontal); + QFETCH(int, newPos); + QFETCH(int, newExtent); + + QScopedPointer<QQuickView> window(new QQuickView); + window->setSource(testFileUrl("contentPosWhileDragging.qml")); + QTRY_COMPARE(window->status(), QQuickView::Ready); + QQuickViewTestUtil::centerOnScreen(window.data()); + QQuickViewTestUtil::moveMouseAway(window.data()); + window->show(); + QVERIFY(QTest::qWaitForWindowActive(window.data())); + QQuickItem *rootItem = window->rootObject(); + QVERIFY(rootItem); + + QVERIFY(window->isVisible()); + QQuickFlickable *flickable = rootItem->findChild<QQuickFlickable *>(); + QVERIFY(flickable); + + const auto contentPos = [flickable]() -> QPoint { + return QPoint(flickable->contentX(), flickable->contentY()); + }; + const qreal threshold = + qApp->styleHints()->startDragDistance() * flickable->parentItem()->scale(); + const QPoint thresholdPnt(qRound(threshold), qRound(threshold)); + const auto flickableCenterPos = flickable->mapToScene({flickable->width() / 2, flickable->height() / 2}).toPoint(); + + // Drag the mouse until we have surpassed the mouse drag threshold and a drag is initiated + // by checking for flickable->isDragging() + QPoint pos = flickableCenterPos; + moveAndPress(window.data(), pos); + int j = 1; + QVERIFY(!flickable->isDragging()); + while (!flickable->isDragging()) { + pos = flickableCenterPos - QPoint(j, j); + QTest::mouseMove(window.data(), pos); + j++; + } + + // Now we have entered the drag state + QVERIFY(flickable->isDragging()); + QCOMPARE(flickable->contentX(), 0); + QCOMPARE(flickable->contentY(), 0); + QVERIFY(flickable->width() > 0); + QVERIFY(flickable->height() > 0); + + + const int moveLength = 50; + const QPoint unitDelta(isHorizontal ? 1 : 0, isHorizontal ? 0 : 1); + const QPoint moveDelta = unitDelta * moveLength; + + pos -= 3*moveDelta; + QTest::mouseMove(window.data(), pos); + // Should be positive because we drag in the opposite direction + QCOMPARE(contentPos(), 3 * moveDelta); + QPoint expectedContentPos; + + // Set the content item position back to zero *while dragging* (!!) + if (newPos >= 0) { + if (isHorizontal) { + flickable->setContentX(newPos); + } else { + flickable->setContentY(newPos); + } + // Continue dragging + pos -= moveDelta; + expectedContentPos = moveDelta; + } else if (newExtent >= 0) { + // ...or reduce the content size be be less than current (contentX, contentY) position + // This forces the content item to move. + // contentY: 150 + // 320 - 150 = 170 pixels down to bottom + // Now reduce contentHeight to 200 + // since we are at the bottom, and the flickable is 100 pixels tall, contentY must land + // at newExtent - 100. + + if (isHorizontal) { + flickable->setContentWidth(newExtent); + } else { + flickable->setContentHeight(newExtent); + } + // Assumption is that the contentItem is aligned to the bottom of the flickable + // We therefore cannot scroll/flick it further down. Drag it up towards the top instead + // (by moving mouse down). + pos += moveDelta; + expectedContentPos = unitDelta * (newExtent - (isHorizontal ? flickable->width() : flickable->height())); + } + + QTest::mouseMove(window.data(), pos); + + // Make sure that the contentItem was only dragged the delta in mouse movement since the last + // setContentX/Y() call. + QCOMPARE(contentPos(), expectedContentPos); + QTest::mouseRelease(window.data(), Qt::LeftButton, Qt::NoModifier, pos); + QVERIFY(!flickable->isDragging()); +} + QTEST_MAIN(tst_qquickflickable) #include "tst_qquickflickable.moc" |