diff options
Diffstat (limited to 'src/quick/items/qquickflickable.cpp')
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 43405db40d..b568db1d26 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -59,6 +59,8 @@ static const int FlickThreshold = 15; // will ensure the Flickable retains the grab on consecutive flicks. static const int RetainGrabVelocity = 100; +static const int MovementEndingTimerInterval = 100; + static qreal EaseOvershoot(qreal t) { return qAtan(t); } @@ -238,6 +240,8 @@ void QQuickFlickablePrivate::init() contentItem->setParentItem(q); qmlobject_connect(&timeline, QQuickTimeLine, SIGNAL(completed()), q, QQuickFlickable, SLOT(timelineCompleted())) + qmlobject_connect(&velocityTimeline, QQuickTimeLine, SIGNAL(completed()), + q, QQuickFlickable, SLOT(velocityTimelineCompleted())) q->setAcceptedMouseButtons(Qt::LeftButton); q->setFiltersChildMouseEvents(true); QQuickItemPrivate *viewportPrivate = QQuickItemPrivate::get(contentItem); @@ -1196,6 +1200,8 @@ void QQuickFlickablePrivate::drag(qint64 currentTimestamp, QEvent::Type eventTyp hData.velocity = 0; } + if (momentum && !hData.flicking && !vData.flicking) + flickingStarted(hData.velocity != 0, vData.velocity != 0); draggingStarting(); if ((hMoved && !prevHMoved) || (vMoved && !prevVMoved)) @@ -1385,9 +1391,15 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) d->maybeBeginDrag(currentTimestamp, event->posF()); break; case Qt::ScrollUpdate: + if (d->scrollingPhase) { + d->pressed = true; + d->movementEndingTimer.start(MovementEndingTimerInterval, this); + } break; case Qt::ScrollEnd: + d->pressed = false; d->scrollingPhase = false; + d->movementEndingTimer.start(MovementEndingTimerInterval, this); d->draggingEnding(); event->accept(); returnToBounds(); @@ -1409,7 +1421,6 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) valid = true; } if (valid) { - d->vData.flicking = false; d->flickY(d->vData.velocity); d->flickingStarted(false, true); if (d->vData.flicking) { @@ -1429,7 +1440,6 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) valid = true; } if (valid) { - d->hData.flicking = false; d->flickX(d->hData.velocity); d->flickingStarted(true, false); if (d->hData.flicking) { @@ -1542,6 +1552,12 @@ void QQuickFlickable::timerEvent(QTimerEvent *event) if (d->delayedPressEvent) { d->replayDelayedPress(); } + } else if (event->timerId() == d->movementEndingTimer.timerId()) { + d->movementEndingTimer.stop(); + d->pressed = false; + d->stealMouse = false; + if (!d->velocityTimeline.isActive()) + movementEnding(true, true); } } @@ -2469,6 +2485,22 @@ bool QQuickFlickable::isMovingVertically() const return d->vData.moving; } +void QQuickFlickable::velocityTimelineCompleted() +{ + Q_D(QQuickFlickable); + if ( (d->hData.transitionToBounds && d->hData.transitionToBounds->isActive()) + || (d->vData.transitionToBounds && d->vData.transitionToBounds->isActive()) ) { + return; + } + // With subclasses such as GridView, velocityTimeline.completed is emitted repeatedly: + // for example setting currentIndex results in a visual "flick" which the user + // didn't initiate directly. We don't want to end movement repeatedly, and in + // that case movementEnding will happen after the sequence of movements ends. + if (d->vData.flicking) + movementEnding(); + d->updateBeginningEnd(); +} + void QQuickFlickable::timelineCompleted() { Q_D(QQuickFlickable); |