From: Martin Jones Date: Tue, 13 Sep 2011 02:50:48 +0000 (+1000) Subject: Velocities reported by Flickable in onFlickStarted can be 0 X-Git-Tag: qt-v5.0.0-alpha1~1671 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e79c448e28c67cb6acd63e8b4bac6c7b08c1f897;p=profile%2Fivi%2Fqtdeclarative.git 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 Reviewed-by: Martin Jones --- diff --git a/src/declarative/items/qsgflickable.cpp b/src/declarative/items/qsgflickable.cpp index ce8afa1..36d7db2 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 f145312..6fa92b3 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 e34b63b..ebc49ba 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 0b9fdf0..d12008f 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 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(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 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 a3e92fe..8359ad1 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 80bf71a..2d8c75b 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 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(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 T *tst_qdeclarativeflickable::findItem(QGraphicsObject *parent, const QString &objectName) {