| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the $MODULE$ 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$ |
| ** |
| ****************************************************************************/ |
| |
| #include <QtGui> |
| #include <QtWidgets> |
| #include <QtTest> |
| #include <qpa/qwindowsysteminterface.h> |
| |
| // #include <QDebug> |
| |
| class tst_QScrollerWidget : public QWidget |
| { |
| public: |
| tst_QScrollerWidget() |
| : QWidget() |
| { |
| reset(); |
| } |
| |
| void reset() |
| { |
| receivedPrepare = false; |
| receivedScroll = false; |
| receivedFirst = false; |
| receivedLast = false; |
| receivedOvershoot = false; |
| } |
| |
| bool event(QEvent *e) |
| { |
| switch (e->type()) { |
| case QEvent::Gesture: |
| e->setAccepted(false); // better reject the event or QGestureManager will make trouble |
| return false; |
| |
| case QEvent::ScrollPrepare: |
| { |
| receivedPrepare = true; |
| QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e); |
| se->setViewportSize(QSizeF(100,100)); |
| se->setContentPosRange(scrollArea); |
| se->setContentPos(scrollPosition); |
| se->accept(); |
| return true; |
| } |
| |
| case QEvent::Scroll: |
| { |
| receivedScroll = true; |
| QScrollEvent *se = static_cast<QScrollEvent *>(e); |
| // qDebug() << "Scroll for"<<this<<"pos"<<se->scrollPos()<<"ov"<<se->overshoot()<<"first"<<se->isFirst()<<"last"<<se->isLast(); |
| |
| if (se->scrollState() == QScrollEvent::ScrollStarted) |
| receivedFirst = true; |
| if (se->scrollState() == QScrollEvent::ScrollFinished) |
| receivedLast = true; |
| |
| currentPos = se->contentPos(); |
| overshoot = se->overshootDistance(); |
| if (!qFuzzyCompare(overshoot.x() + 1.0, 1.0) || |
| !qFuzzyCompare(overshoot.y() + 1.0, 1.0)) |
| receivedOvershoot = true; |
| return true; |
| } |
| |
| default: |
| return QObject::event(e); |
| } |
| } |
| |
| |
| QRectF scrollArea; |
| QPointF scrollPosition; |
| |
| bool receivedPrepare; |
| bool receivedScroll; |
| bool receivedFirst; |
| bool receivedLast; |
| bool receivedOvershoot; |
| |
| QPointF currentPos; |
| QPointF overshoot; |
| }; |
| |
| |
| class tst_QScroller : public QObject |
| { |
| Q_OBJECT |
| public: |
| tst_QScroller() { } |
| ~tst_QScroller() { } |
| |
| private: |
| void kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); |
| void kineticScrollNoTest(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); |
| |
| private slots: |
| void staticScrollers(); |
| void scrollerProperties(); |
| void scrollTo(); |
| void scroll(); |
| void overshoot(); |
| void multipleWindows(); |
| |
| private: |
| QTouchDevice *m_touchScreen = QTest::createTouchDevice(); |
| }; |
| |
| /*! \internal |
| Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling. |
| Tests some in between states but does not wait until scrolling is finished. |
| */ |
| void tst_QScroller::kineticScroll(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) |
| { |
| sw->scrollPosition = from; |
| sw->currentPos= from; |
| |
| QScroller *s1 = QScroller::scroller(sw); |
| QCOMPARE(s1->state(), QScroller::Inactive); |
| |
| QScrollerProperties sp1 = QScroller::scroller(sw)->scrollerProperties(); |
| |
| QTouchEvent::TouchPoint rawTouchPoint; |
| rawTouchPoint.setId(0); |
| |
| // send the touch begin event |
| QTouchEvent::TouchPoint touchPoint(0); |
| touchPoint.setState(Qt::TouchPointPressed); |
| touchPoint.setPos(touchStart); |
| touchPoint.setScenePos(touchStart); |
| touchPoint.setScreenPos(touchStart); |
| QTouchEvent touchEvent1(QEvent::TouchBegin, |
| m_touchScreen, |
| Qt::NoModifier, |
| Qt::TouchPointPressed, |
| (QList<QTouchEvent::TouchPoint>() << touchPoint)); |
| QApplication::sendEvent(sw, &touchEvent1); |
| |
| QCOMPARE(s1->state(), QScroller::Pressed); |
| |
| // send the touch update far enough to trigger a scroll |
| QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second. |
| touchPoint.setPos(touchUpdate); |
| touchPoint.setScenePos(touchUpdate); |
| touchPoint.setScreenPos(touchUpdate); |
| QTouchEvent touchEvent2(QEvent::TouchUpdate, |
| m_touchScreen, |
| Qt::NoModifier, |
| Qt::TouchPointMoved, |
| (QList<QTouchEvent::TouchPoint>() << touchPoint)); |
| QApplication::sendEvent(sw, &touchEvent2); |
| |
| QCOMPARE(s1->state(), QScroller::Dragging); |
| QCOMPARE(sw->receivedPrepare, true); |
| |
| |
| QTRY_COMPARE(sw->receivedFirst, true); |
| QCOMPARE(sw->receivedScroll, true); |
| QCOMPARE(sw->receivedOvershoot, false); |
| |
| // note that the scrolling goes in a different direction than the mouse move |
| QPoint calculatedPos = from.toPoint() - touchUpdate - touchStart; |
| QVERIFY(qAbs(sw->currentPos.x() - calculatedPos.x()) < 1.0); |
| QVERIFY(qAbs(sw->currentPos.y() - calculatedPos.y()) < 1.0); |
| |
| // send the touch end |
| touchPoint.setPos(touchEnd); |
| touchPoint.setScenePos(touchEnd); |
| touchPoint.setScreenPos(touchEnd); |
| QTouchEvent touchEvent5(QEvent::TouchEnd, |
| m_touchScreen, |
| Qt::NoModifier, |
| Qt::TouchPointReleased, |
| (QList<QTouchEvent::TouchPoint>() << touchPoint)); |
| QApplication::sendEvent(sw, &touchEvent5); |
| } |
| |
| /*! \internal |
| Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling. |
| This function does not have any in between tests, it does not expect the scroller to actually scroll. |
| */ |
| void tst_QScroller::kineticScrollNoTest(tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) |
| { |
| sw->scrollPosition = from; |
| sw->currentPos = from; |
| |
| QScroller *s1 = QScroller::scroller(sw); |
| QCOMPARE(s1->state(), QScroller::Inactive); |
| |
| QScrollerProperties sp1 = s1->scrollerProperties(); |
| int fps = 60; |
| |
| QTouchEvent::TouchPoint rawTouchPoint; |
| rawTouchPoint.setId(0); |
| |
| // send the touch begin event |
| QTouchEvent::TouchPoint touchPoint(0); |
| touchPoint.setState(Qt::TouchPointPressed); |
| touchPoint.setPos(touchStart); |
| touchPoint.setScenePos(touchStart); |
| touchPoint.setScreenPos(touchStart); |
| QTouchEvent touchEvent1(QEvent::TouchBegin, |
| m_touchScreen, |
| Qt::NoModifier, |
| Qt::TouchPointPressed, |
| (QList<QTouchEvent::TouchPoint>() << touchPoint)); |
| QApplication::sendEvent(sw, &touchEvent1); |
| |
| // send the touch update far enough to trigger a scroll |
| QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second. |
| touchPoint.setPos(touchUpdate); |
| touchPoint.setScenePos(touchUpdate); |
| touchPoint.setScreenPos(touchUpdate); |
| QTouchEvent touchEvent2(QEvent::TouchUpdate, |
| m_touchScreen, |
| Qt::NoModifier, |
| Qt::TouchPointMoved, |
| (QList<QTouchEvent::TouchPoint>() << touchPoint)); |
| QApplication::sendEvent(sw, &touchEvent2); |
| |
| QTest::qWait(1000 / fps * 2); // wait until the first scroll move |
| |
| // send the touch end |
| touchPoint.setPos(touchEnd); |
| touchPoint.setScenePos(touchEnd); |
| touchPoint.setScreenPos(touchEnd); |
| QTouchEvent touchEvent5(QEvent::TouchEnd, |
| m_touchScreen, |
| Qt::NoModifier, |
| Qt::TouchPointReleased, |
| (QList<QTouchEvent::TouchPoint>() << touchPoint)); |
| QApplication::sendEvent(sw, &touchEvent5); |
| } |
| |
| |
| void tst_QScroller::staticScrollers() |
| { |
| // scrollers |
| { |
| QObject *o1 = new QObject(this); |
| QObject *o2 = new QObject(this); |
| |
| // get scroller for object |
| QScroller *s1 = QScroller::scroller(o1); |
| QScroller *s2 = QScroller::scroller(o2); |
| |
| QVERIFY(s1); |
| QVERIFY(s2); |
| QVERIFY(s1 != s2); |
| |
| QVERIFY(!QScroller::scroller(static_cast<const QObject*>(0))); |
| QCOMPARE(QScroller::scroller(o1), s1); |
| |
| delete o1; |
| delete o2; |
| } |
| |
| // the same for properties |
| { |
| QObject *o1 = new QObject(this); |
| QObject *o2 = new QObject(this); |
| |
| // get scroller for object |
| QScrollerProperties sp1 = QScroller::scroller(o1)->scrollerProperties(); |
| QScrollerProperties sp2 = QScroller::scroller(o2)->scrollerProperties(); |
| |
| // default properties should be the same |
| QCOMPARE(sp1, sp2); |
| |
| QCOMPARE(QScroller::scroller(o1)->scrollerProperties(), sp1); |
| |
| delete o1; |
| delete o2; |
| } |
| } |
| |
| void tst_QScroller::scrollerProperties() |
| { |
| QObject *o1 = new QObject(this); |
| QScrollerProperties sp1 = QScroller::scroller(o1)->scrollerProperties(); |
| |
| QScrollerProperties::ScrollMetric metrics[] = |
| { |
| QScrollerProperties::MousePressEventDelay, // qreal [s] |
| QScrollerProperties::DragStartDistance, // qreal [m] |
| QScrollerProperties::DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF) |
| QScrollerProperties::AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|) |
| |
| QScrollerProperties::DecelerationFactor, // slope of the curve |
| |
| QScrollerProperties::MinimumVelocity, // qreal [m/s] |
| QScrollerProperties::MaximumVelocity, // qreal [m/s] |
| QScrollerProperties::MaximumClickThroughVelocity, // qreal [m/s] |
| |
| QScrollerProperties::AcceleratingFlickMaximumTime, // qreal [s] |
| QScrollerProperties::AcceleratingFlickSpeedupFactor, // qreal [1..] |
| |
| QScrollerProperties::SnapPositionRatio, // qreal [0..1] |
| QScrollerProperties::SnapTime, // qreal [s] |
| |
| QScrollerProperties::OvershootDragResistanceFactor, // qreal [0..1] |
| QScrollerProperties::OvershootDragDistanceFactor, // qreal [0..1] |
| QScrollerProperties::OvershootScrollDistanceFactor, // qreal [0..1] |
| QScrollerProperties::OvershootScrollTime, // qreal [s] |
| }; |
| |
| for (unsigned int i = 0; i < sizeof(metrics) / sizeof(metrics[0]); i++) { |
| sp1.setScrollMetric(metrics[i], 0.9); |
| QCOMPARE(sp1.scrollMetric(metrics[i]).toDouble(), 0.9); |
| } |
| sp1.setScrollMetric(QScrollerProperties::ScrollingCurve, QEasingCurve(QEasingCurve::OutQuart)); |
| QCOMPARE(sp1.scrollMetric(QScrollerProperties::ScrollingCurve).toEasingCurve().type(), QEasingCurve::OutQuart); |
| |
| sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); |
| QCOMPARE(sp1.scrollMetric(QScrollerProperties::HorizontalOvershootPolicy).value<QScrollerProperties::OvershootPolicy>(), QScrollerProperties::OvershootAlwaysOff); |
| |
| sp1.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); |
| QCOMPARE(sp1.scrollMetric(QScrollerProperties::VerticalOvershootPolicy).value<QScrollerProperties::OvershootPolicy>(), QScrollerProperties::OvershootAlwaysOn); |
| |
| sp1.setScrollMetric(QScrollerProperties::FrameRate, QVariant::fromValue(QScrollerProperties::Fps20)); |
| QCOMPARE(sp1.scrollMetric(QScrollerProperties::FrameRate).value<QScrollerProperties::FrameRates>(), QScrollerProperties::Fps20); |
| } |
| |
| void tst_QScroller::scrollTo() |
| { |
| QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget); |
| sw->show(); |
| QApplication::setActiveWindow(sw.data()); |
| if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data())) |
| QSKIP("Failed to show and activate window"); |
| |
| sw->scrollArea = QRectF(0, 0, 1000, 1000); |
| sw->scrollPosition = QPointF(500, 500); |
| |
| QScroller *s1 = QScroller::scroller(sw.data()); |
| QCOMPARE(s1->state(), QScroller::Inactive); |
| |
| // a normal scroll |
| s1->scrollTo(QPointF(100,100), 100); |
| QTest::qWait(200); |
| |
| QTRY_COMPARE(sw->receivedPrepare, true); |
| QCOMPARE(sw->receivedScroll, true); |
| QCOMPARE(sw->receivedFirst, true); |
| QCOMPARE(sw->receivedLast, true); |
| QCOMPARE(sw->receivedOvershoot, false); |
| QTRY_VERIFY(qFuzzyCompare(sw->currentPos.x(), 100)); |
| QVERIFY(qFuzzyCompare(sw->currentPos.y(), 100)); |
| } |
| |
| void tst_QScroller::scroll() |
| { |
| #if QT_CONFIG(gestures) && QT_CONFIG(scroller) |
| // -- good case. normal scroll |
| QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget()); |
| sw->scrollArea = QRectF(0, 0, 1000, 1000); |
| QScroller::grabGesture(sw.data(), QScroller::TouchGesture); |
| sw->setGeometry(100, 100, 400, 300); |
| sw->show(); |
| QApplication::setActiveWindow(sw.data()); |
| if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data())) |
| QSKIP("Failed to show and activate window"); |
| |
| QScroller *s1 = QScroller::scroller(sw.data()); |
| kineticScroll(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); |
| // now we should be scrolling |
| QTRY_COMPARE(s1->state(), QScroller::Scrolling); |
| |
| // wait until finished, check that no further first scroll is sent |
| sw->receivedFirst = false; |
| sw->receivedScroll = false; |
| QTRY_VERIFY(s1->state() != QScroller::Scrolling); |
| |
| QCOMPARE(sw->receivedFirst, false); |
| QCOMPARE(sw->receivedScroll, true); |
| QCOMPARE(sw->receivedLast, true); |
| QVERIFY(sw->currentPos.x() < 400); |
| QVERIFY(sw->currentPos.y() < 400); |
| |
| // -- try to scroll when nothing to scroll |
| |
| sw->reset(); |
| sw->scrollArea = QRectF(0, 0, 0, 1000); |
| kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(100, 0), QPoint(200, 0)); |
| |
| QTRY_COMPARE(s1->state(), QScroller::Inactive); |
| |
| QCOMPARE(sw->currentPos.x(), 0.0); |
| QCOMPARE(sw->currentPos.y(), 500.0); |
| #endif |
| } |
| |
| void tst_QScroller::overshoot() |
| { |
| #if QT_CONFIG(gestures) && QT_CONFIG(scroller) |
| QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget); |
| sw->scrollArea = QRectF(0, 0, 1000, 1000); |
| QScroller::grabGesture(sw.data(), QScroller::TouchGesture); |
| sw->setGeometry(100, 100, 400, 300); |
| sw->show(); |
| QApplication::setActiveWindow(sw.data()); |
| if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data())) |
| QSKIP("Failed to show and activate window"); |
| |
| QScroller *s1 = QScroller::scroller(sw.data()); |
| QScrollerProperties sp1 = s1->scrollerProperties(); |
| |
| sp1.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.5); |
| sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.2); |
| sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.2); |
| |
| // -- try to scroll with overshoot (when scrollable good case) |
| |
| sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable)); |
| s1->setScrollerProperties(sp1); |
| kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); |
| |
| QTRY_COMPARE(s1->state(), QScroller::Inactive); |
| |
| //qDebug() << "Overshoot fuzzy: "<<sw->currentPos; |
| QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); |
| QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); |
| QCOMPARE(sw->receivedOvershoot, true); |
| |
| // -- try to scroll with overshoot (when scrollable bad case) |
| sw->reset(); |
| sw->scrollArea = QRectF(0, 0, 0, 1000); |
| |
| sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable)); |
| s1->setScrollerProperties(sp1); |
| kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); |
| |
| QTRY_COMPARE(s1->state(), QScroller::Inactive); |
| |
| //qDebug() << "Overshoot fuzzy: "<<sw->currentPos; |
| QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); |
| QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); |
| QCOMPARE(sw->receivedOvershoot, false); |
| |
| // -- try to scroll with overshoot (always on) |
| sw->reset(); |
| sw->scrollArea = QRectF(0, 0, 0, 1000); |
| |
| sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); |
| s1->setScrollerProperties(sp1); |
| kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); |
| |
| QTRY_COMPARE(s1->state(), QScroller::Inactive); |
| |
| //qDebug() << "Overshoot fuzzy: "<<sw->currentPos; |
| |
| QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); |
| QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); |
| QCOMPARE(sw->receivedOvershoot, true); |
| |
| // -- try to scroll with overshoot (always off) |
| sw->reset(); |
| sw->scrollArea = QRectF(0, 0, 1000, 1000); |
| |
| sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); |
| s1->setScrollerProperties(sp1); |
| kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); |
| |
| QTRY_COMPARE(s1->state(), QScroller::Inactive); |
| |
| QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); |
| QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); |
| QCOMPARE(sw->receivedOvershoot, false); |
| |
| // -- try to scroll with overshoot (always on but max overshoot = 0) |
| sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0); |
| sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0); |
| sw->reset(); |
| sw->scrollArea = QRectF(0, 0, 1000, 1000); |
| |
| sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); |
| s1->setScrollerProperties(sp1); |
| kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); |
| |
| QTRY_COMPARE(s1->state(), QScroller::Inactive); |
| |
| QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); |
| QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); |
| QCOMPARE(sw->receivedOvershoot, false); |
| #endif |
| } |
| |
| void tst_QScroller::multipleWindows() |
| { |
| #if QT_CONFIG(gestures) && QT_CONFIG(scroller) |
| QScopedPointer<tst_QScrollerWidget> sw1(new tst_QScrollerWidget); |
| sw1->scrollArea = QRectF(0, 0, 1000, 1000); |
| QScroller::grabGesture(sw1.data(), QScroller::TouchGesture); |
| sw1->setGeometry(100, 100, 400, 300); |
| |
| QScroller *s1 = QScroller::scroller(sw1.data()); |
| kineticScroll(sw1.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); |
| // now we should be scrolling |
| QTRY_COMPARE(s1->state(), QScroller::Scrolling); |
| |
| // That was fun! Do it again! |
| QScopedPointer<tst_QScrollerWidget> sw2(new tst_QScrollerWidget()); |
| sw2->scrollArea = QRectF(0, 0, 1000, 1000); |
| QScroller::grabGesture(sw2.data(), QScroller::TouchGesture); |
| sw2->setGeometry(100, 100, 400, 300); |
| |
| QScroller *s2 = QScroller::scroller(sw2.data()); |
| kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); |
| // now we should be scrolling |
| QTRY_COMPARE(s2->state(), QScroller::Scrolling); |
| |
| // wait for both to stop |
| QTRY_VERIFY(s1->state() != QScroller::Scrolling); |
| QTRY_VERIFY(s2->state() != QScroller::Scrolling); |
| |
| sw1.reset(); // destroy one window |
| sw2->reset(); // reset the other scroller's internal state |
| // make sure we can still scroll the remaining one without crashing (QTBUG-71232) |
| kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); |
| #endif |
| } |
| |
| QTEST_MAIN(tst_QScroller) |
| |
| #include "tst_qscroller.moc" |