diff options
author | Martin Jones <[email protected]> | 2011-09-13 12:50:48 +1000 |
---|---|---|
committer | Qt by Nokia <[email protected]> | 2011-09-16 02:15:03 +0200 |
commit | e79c448e28c67cb6acd63e8b4bac6c7b08c1f897 (patch) | |
tree | fddd6c707e744849f73f4aca4cb14b70a17fcd10 | |
parent | 8c175bee55f1e0e0bb27cbf72911fedf370c26c6 (diff) |
Velocities reported by Flickable in onFlickStarted can be 0
Change 55cfbdb7c64068ae68f7baaceb8acfb96cb0c07e manually applied
from Qt 4.7
Ensure the smoothed velocity is set at the start of the flick. Ensure
that the smoothed velocity animation isn't restarted unless there is
new valid data.
Change-Id: Ia77249be9980aba268a1bfa0ea3f69c49fa09e5e
Reviewed-by: Bea Lam
Reviewed-on: http://codereview.qt-project.org/4712
Reviewed-by: Qt Sanity Bot <[email protected]>
Reviewed-by: Martin Jones <[email protected]>
6 files changed, 141 insertions, 20 deletions
diff --git a/src/declarative/items/qsgflickable.cpp b/src/declarative/items/qsgflickable.cpp index ce8afa1f4c..36d7db217c 100644 --- a/src/declarative/items/qsgflickable.cpp +++ b/src/declarative/items/qsgflickable.cpp @@ -962,18 +962,24 @@ void QSGFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event) qreal velocity = vData.velocity; if (vData.atBeginning || vData.atEnd) velocity /= 2; - if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->localPos().y() - pressPos.y()) > FlickThreshold) + if (q->yflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->localPos().y() - pressPos.y()) > FlickThreshold) { + velocityTimeline.reset(vData.smoothVelocity); + vData.smoothVelocity.setValue(-velocity); flickY(velocity); - else + } else { fixupY(); + } velocity = hData.velocity; if (hData.atBeginning || hData.atEnd) velocity /= 2; - if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->localPos().x() - pressPos.x()) > FlickThreshold) + if (q->xflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->localPos().x() - pressPos.x()) > FlickThreshold) { + velocityTimeline.reset(hData.smoothVelocity); + hData.smoothVelocity.setValue(-velocity); flickX(velocity); - else + } else { fixupX(); + } if (!timeline.isActive()) q->movementEnding(); @@ -1156,19 +1162,25 @@ void QSGFlickable::viewportMoved() qreal prevX = d->lastFlickablePosition.x(); qreal prevY = d->lastFlickablePosition.y(); - d->velocityTimeline.clear(); if (d->pressed || d->calcVelocity) { int elapsed = QSGItemPrivate::restart(d->velocityTime); if (elapsed > 0) { qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed; + if (qAbs(horizontalVelocity) > 0) { + d->velocityTimeline.reset(d->hData.smoothVelocity); + d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing); + d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing); + } qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed; - d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing); - d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing); - d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing); - d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing); + if (qAbs(verticalVelocity) > 0) { + d->velocityTimeline.reset(d->vData.smoothVelocity); + d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing); + d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing); + } } } else { if (d->timeline.time() > d->vTime) { + d->velocityTimeline.clear(); qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime); qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime); d->hData.smoothVelocity.setValue(horizontalVelocity); diff --git a/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp b/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp index f145312334..6fa92b3bfa 100644 --- a/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp +++ b/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp @@ -913,18 +913,24 @@ void QDeclarative1FlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseE qreal velocity = vData.velocity; if (vData.atBeginning || vData.atEnd) velocity /= 2; - if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) + if (q->yflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) { + velocityTimeline.reset(vData.smoothVelocity); + vData.smoothVelocity.setValue(-velocity); flickY(velocity); - else + } else { fixupY(); + } velocity = hData.velocity; if (hData.atBeginning || hData.atEnd) velocity /= 2; - if (qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) + if (q->xflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) { + velocityTimeline.reset(hData.smoothVelocity); + hData.smoothVelocity.setValue(-velocity); flickX(velocity); - else + } else { fixupX(); + } if (!timeline.isActive()) q->movementEnding(); @@ -1124,19 +1130,25 @@ void QDeclarative1Flickable::viewportMoved() qreal prevX = d->lastFlickablePosition.x(); qreal prevY = d->lastFlickablePosition.y(); - d->velocityTimeline.clear(); if (d->pressed || d->calcVelocity) { int elapsed = QDeclarativeItemPrivate::restart(d->velocityTime); if (elapsed > 0) { qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed; + if (qAbs(horizontalVelocity) > 0) { + d->velocityTimeline.reset(d->hData.smoothVelocity); + d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing); + d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing); + } qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed; - d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing); - d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing); - d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing); - d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing); + if (qAbs(verticalVelocity) > 0) { + d->velocityTimeline.reset(d->vData.smoothVelocity); + d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing); + d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing); + } } } else { if (d->timeline.time() > d->vTime) { + d->velocityTimeline.clear(); qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime); qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime); d->hData.smoothVelocity.setValue(horizontalVelocity); diff --git a/tests/auto/declarative/qsgflickable/data/flickable03.qml b/tests/auto/declarative/qsgflickable/data/flickable03.qml index e34b63b6ac..ebc49ba90a 100644 --- a/tests/auto/declarative/qsgflickable/data/flickable03.qml +++ b/tests/auto/declarative/qsgflickable/data/flickable03.qml @@ -1,7 +1,7 @@ import QtQuick 2.0 Flickable { - width: 100; height: 100 + width: 100; height: 200 contentWidth: column.width; contentHeight: column.height Column { diff --git a/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp b/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp index 0b9fdf0004..d12008f5b7 100644 --- a/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp +++ b/tests/auto/declarative/qsgflickable/tst_qsgflickable.cpp @@ -79,10 +79,12 @@ private slots: void wheel(); void movingAndDragging(); void disabled(); + void flickVelocity(); private: QDeclarativeEngine engine; + void flick(QSGView *canvas, const QPoint &from, const QPoint &to, int duration); template<typename T> T *findItem(QSGItem *parent, const QString &objectName); }; @@ -545,6 +547,52 @@ void tst_qsgflickable::disabled() QVERIFY(canvas->rootObject()->property("clicked").toBool() == true); } +void tst_qsgflickable::flickVelocity() +{ +#ifdef Q_WS_MAC + QSKIP("Producing flicks on Mac CI impossible due to timing problems", SkipAll); +#endif + + QSGView *canvas = new QSGView; + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/flickable03.qml")); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QSGFlickable *flickable = qobject_cast<QSGFlickable*>(canvas->rootObject()); + QVERIFY(flickable != 0); + + // flick up + flick(canvas, QPoint(20,190), QPoint(20, 50), 200); + QVERIFY(flickable->verticalVelocity() > 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + // flick down + flick(canvas, QPoint(20,10), QPoint(20, 140), 200); + QVERIFY(flickable->verticalVelocity() < 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + delete canvas; +} + +void tst_qsgflickable::flick(QSGView *canvas, const QPoint &from, const QPoint &to, int duration) +{ + const int pointCount = 5; + QPoint diff = to - from; + + // send press, five equally spaced moves, and release. + QTest::mousePress(canvas, Qt::LeftButton, 0, from); + + for (int i = 0; i < pointCount; ++i) { + QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas, &mv); + QTest::qWait(duration/pointCount); + QCoreApplication::processEvents(); + } + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, to); +} + template<typename T> T *tst_qsgflickable::findItem(QSGItem *parent, const QString &objectName) { diff --git a/tests/auto/qtquick1/qdeclarativeflickable/data/flickable03.qml b/tests/auto/qtquick1/qdeclarativeflickable/data/flickable03.qml index a3e92fe6a6..8359ad1bb4 100644 --- a/tests/auto/qtquick1/qdeclarativeflickable/data/flickable03.qml +++ b/tests/auto/qtquick1/qdeclarativeflickable/data/flickable03.qml @@ -1,7 +1,7 @@ import QtQuick 1.0 Flickable { - width: 100; height: 100 + width: 100; height: 200 contentWidth: column.width; contentHeight: column.height Column { diff --git a/tests/auto/qtquick1/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/qtquick1/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index 80bf71a191..2d8c75ba22 100644 --- a/tests/auto/qtquick1/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/qtquick1/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -79,10 +79,12 @@ private slots: void testQtQuick11Attributes_data(); void wheel(); void disabled(); + void flickVelocity(); private: QDeclarativeEngine engine; + void flick(QGraphicsView *canvas, const QPoint &from, const QPoint &to, int duration); template<typename T> T *findItem(QGraphicsObject *parent, const QString &objectName); }; @@ -514,6 +516,53 @@ void tst_qdeclarativeflickable::disabled() QVERIFY(canvas->rootObject()->property("clicked").toBool() == true); } +void tst_qdeclarativeflickable::flickVelocity() +{ +#ifdef Q_WS_MAC + QSKIP("Producing flicks on Mac CI impossible due to timing problems", SkipAll); +#endif + + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/flickable03.qml")); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QDeclarative1Flickable *flickable = qobject_cast<QDeclarative1Flickable*>(canvas->rootObject()); + QVERIFY(flickable != 0); + + // flick up + flick(canvas, QPoint(20,190), QPoint(20, 50), 200); + QVERIFY(flickable->verticalVelocity() > 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + // flick down + flick(canvas, QPoint(20,10), QPoint(20, 140), 200); + QVERIFY(flickable->verticalVelocity() < 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + delete canvas; +} + +void tst_qdeclarativeflickable::flick(QGraphicsView *canvas, const QPoint &from, const QPoint &to, int duration) +{ + const int pointCount = 5; + QPoint diff = to - from; + + // send press, five equally spaced moves, and release. + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(from)); + + for (int i = 0; i < pointCount; ++i) { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(from + (i+1)*diff/pointCount), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::qWait(duration/pointCount); + QCoreApplication::processEvents(); + } + + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(to)); +} + + template<typename T> T *tst_qdeclarativeflickable::findItem(QGraphicsObject *parent, const QString &objectName) { |