From 55cfbdb7c64068ae68f7baaceb8acfb96cb0c07e Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Tue, 28 Jun 2011 15:35:58 +1000 Subject: Velocities reported by Flickable in onFlickStarted can be 0 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: I00f8bbf1fe91faeea752b093c4658ad0f53ad06d Task-number: QTBUG-19676 Reviewed-by: Bea Lam (cherry picked from commit a2d97672bfaace677a4308db93f5802ba53af46e) --- .../graphicsitems/qdeclarativeflickable.cpp | 30 +++++++--- .../tst_qdeclarativeflickable.cpp | 69 ++++++++++++++++++++++ 2 files changed, 90 insertions(+), 9 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 4a465cc..b8577e9 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -910,18 +910,24 @@ void QDeclarativeFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEv 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(); @@ -1121,19 +1127,25 @@ void QDeclarativeFlickable::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/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp index b077fdc..31a6b10 100644 --- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp +++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp @@ -78,6 +78,7 @@ private slots: void testQtQuick11Attributes(); void testQtQuick11Attributes_data(); void wheel(); + void flickVelocity(); private: QDeclarativeEngine engine; @@ -480,6 +481,74 @@ void tst_qdeclarativeflickable::wheel() delete canvas; } +void tst_qdeclarativeflickable::flickVelocity() +{ + QDeclarativeView *canvas = new QDeclarativeView; + canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/flickable03.qml")); + canvas->show(); + canvas->setFocus(); + QVERIFY(canvas->rootObject() != 0); + + QDeclarativeFlickable *flickable = qobject_cast(canvas->rootObject()); + QVERIFY(flickable != 0); + + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 90))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,80)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,70)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,60)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,50)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 50))); + + QVERIFY(flickable->verticalVelocity() > 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 10))); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,20)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,30)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,40)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + { + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(20,50)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + } + QTest::qWait(10); + + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(20, 50))); + + QVERIFY(flickable->verticalVelocity() < 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + delete canvas; +} + template T *tst_qdeclarativeflickable::findItem(QGraphicsObject *parent, const QString &objectName) -- cgit v0.12