diff options
Diffstat (limited to 'qkineticscroller.cpp')
-rw-r--r-- | qkineticscroller.cpp | 81 |
1 files changed, 60 insertions, 21 deletions
diff --git a/qkineticscroller.cpp b/qkineticscroller.cpp index ec46f08..005abb8 100644 --- a/qkineticscroller.cpp +++ b/qkineticscroller.cpp @@ -169,10 +169,10 @@ void QKineticScroller::resetScrollMetrics() static QMap<ScrollMetric, QVariant> metrics; #ifdef Q_WS_MAEMO_5 - metrics.insert(DragVelocitySmoothingFactor, qreal(0.85)); + metrics.insert(DragVelocitySmoothingFactor, qreal(0.15)); metrics.insert(FrictionCoefficent, qreal(0.85)); metrics.insert(OvershootSpringConstant, qreal(0.1)); - metrics.insert(OvershootMaximumDistance, qreal(150)); + metrics.insert(OvershootMaximumDistance, QPointF(qreal(150), qreal(150))); metrics.insert(OvershootMaximumVelocity, qreal(2600)); metrics.insert(DragStartDistance, qreal(25)); metrics.insert(DragStartDirectionErrorMargin, qreal(10)); @@ -186,15 +186,16 @@ void QKineticScroller::resetScrollMetrics() metrics.insert(FastSwipeMaximumTime, qreal(0.125)); metrics.insert(FramesPerSecond, qreal(20)); #else - metrics.insert(DragVelocitySmoothingFactor, qreal(0.85)); - metrics.insert(FrictionCoefficent, qreal(0.95)); - metrics.insert(OvershootSpringConstant, qreal(0.1)); - metrics.insert(OvershootMaximumDistance, qreal(14.25 / 1000)); + metrics.insert(DragVelocitySmoothingFactor, qreal(0.02)); + metrics.insert(FrictionCoefficent, qreal(0.05)); + metrics.insert(OvershootSpringConstant, qreal(2.0)); + metrics.insert(OvershootMaximumDistance, QPointF(qreal(14.25 / 1000), qreal(14.25 / 1000))); metrics.insert(OvershootMaximumVelocity, qreal(247.0 / 1000)); metrics.insert(DragStartDistance, qreal(2.5 / 1000)); metrics.insert(DragStartDirectionErrorMargin, qreal(1.0 / 1000)); metrics.insert(MaximumVelocity, qreal(6650.0 / 1000)); - metrics.insert(MinimumVelocity, qreal(19.0 / 1000)); + metrics.insert(MaximumVelocity, qreal(6650.0 / 1000)); + metrics.insert(MinimumVelocity, qreal(30.0 / 1000)); metrics.insert(MaximumNonAcceleratedVelocity, qreal(532.0 / 1000)); metrics.insert(MaximumClickThroughVelocity, qreal(66.5 / 1000)); metrics.insert(AxisLockThreshold, qreal(0)); @@ -281,6 +282,8 @@ bool QKineticScroller::handleInput(Input input, const QPointF &position, qint64 { Q_D(QKineticScroller); + +qKSDebug() << __PRETTY_FUNCTION__ << input << "pos: " << position << "timestamp: " << timestamp; struct statechange { State state; Input input; @@ -441,13 +444,18 @@ void QKineticScrollerPrivate::updateVelocity(const QPointF &deltaPixelRaw, qint6 if (((deltaPixelRaw / qreal(deltaTime)).manhattanLength() / pixelPerMeter * 1000) > qreal(2.5)) deltaPixel = deltaPixelRaw * qreal(2.5) * pixelPerMeter / 1000 / (deltaPixelRaw / qreal(deltaTime)).manhattanLength(); - QPointF newv = -deltaPixel / qreal(deltaTime) * 1000 / pixelPerMeter; - newv = newv * dragVelocitySmoothingFactor + velocity * (qreal(1) - dragVelocitySmoothingFactor); + qreal inversSmoothingFactor = ((qreal(1) - dragVelocitySmoothingFactor) * qreal(deltaTime) / qreal(1000)); + QPointF newv = -deltaPixel / qreal(deltaTime) * qreal(1000) / pixelPerMeter; + newv = newv * (qreal(1) - inversSmoothingFactor) + velocity * inversSmoothingFactor; + + // newv = newv * dragVelocitySmoothingFactor + velocity * (qreal(1) - dragVelocitySmoothingFactor); if (deltaPixel.x()) velocity.setX(qBound(-maximumVelocity, newv.x(), maximumVelocity)); if (deltaPixel.y()) velocity.setY(qBound(-maximumVelocity, newv.y(), maximumVelocity)); + + qKSDebug() << "resulting new velocity:" << velocity; } @@ -549,7 +557,10 @@ bool QKineticScrollerPrivate::pressWhileInactive(QKineticScroller::Input, const bool QKineticScrollerPrivate::releaseWhilePressed(QKineticScroller::Input, const QPointF &, qint64) { - setState(QKineticScroller::StateInactive); + if (!overshootDistance.isNull()) + setState(QKineticScroller::StateScrolling); + else + setState(QKineticScroller::StateInactive); return false; } @@ -608,7 +619,7 @@ void QKineticScrollerPrivate::timerEventWhileDragging(qint64) Q_Q(QKineticScroller); if (!dragDistance.isNull()) { - setContentPositionHelper(q->contentPosition() - overshootDistance - dragDistance); + setContentPositionHelper(q->contentPosition() + overshootDistance - dragDistance); dragDistance = QPointF(0, 0); } } @@ -654,7 +665,11 @@ bool QKineticScrollerPrivate::releaseWhileDragging(QKineticScroller::Input, cons } - if (!overshootDistance.isNull() || velocity >= minimumVelocity) + qKSDebug() << "release While dragging, velocity: "<<velocity<<"minimum velocity"<<minimumVelocity; + if (!overshootDistance.isNull()) { + velocity = QPointF(0, 0); + setState(QKineticScroller::StateScrolling); + } else if (velocity >= minimumVelocity) setState(QKineticScroller::StateScrolling); else setState(QKineticScroller::StateInactive); @@ -671,6 +686,8 @@ void QKineticScrollerPrivate::timerEventWhileScrolling(qint64 time) // calculate the new overshoot distance (convert from [m/s] to [pixel/frame] QPointF newOvershootDistance = overshootDistance + velocity * qreal(time) / 1000 * pixelPerMeter; + qKSDebug() << "Overshooting, old: "<<overshootDistance<<"new:"<<newOvershootDistance; + // -- check if we going back. Then stop if (overshootDistance.x() && ((overshootDistance.x() > 0) != (newOvershootDistance.x() > 0))) { overshootDistance.setX(0); @@ -685,9 +702,11 @@ void QKineticScrollerPrivate::timerEventWhileScrolling(qint64 time) } // -- move (convert from [m/s] to [pix/frame] - setContentPositionHelper(q->contentPosition() - overshootDistance + velocity * qreal(time) / 1000 * pixelPerMeter); + setContentPositionHelper(q->contentPosition() + overshootDistance + velocity * qreal(time) / 1000 * pixelPerMeter); + // --- (de)accelerate overshooting axis using spring constant or friction + // actually we would need to calculate a root and not just divide qreal forcePerFrame = overshootSpringConstant * qreal(time) / 1000; qreal frictionPerFrame = (qreal(1) - ((qreal(1) - frictionCoefficent) * qreal(time) / 1000)); @@ -695,7 +714,7 @@ void QKineticScrollerPrivate::timerEventWhileScrolling(qint64 time) // -- x coordinate if (overshootDistance.x()) { - velocity.rx() += forcePerFrame * overshootDistance.x() / pixelPerMeter; + velocity.rx() -= forcePerFrame * overshootDistance.x() / pixelPerMeter; velocity.setX(qBound(-overshootMaximumVelocity, velocity.x(), overshootMaximumVelocity)); } else if (scrollToX) { @@ -715,7 +734,7 @@ void QKineticScrollerPrivate::timerEventWhileScrolling(qint64 time) // -- y coordinate if (overshootDistance.y()) { - velocity.ry() += forcePerFrame * overshootDistance.y() / pixelPerMeter; + velocity.ry() -= forcePerFrame * overshootDistance.y() / pixelPerMeter; velocity.setY(qBound(-overshootMaximumVelocity, velocity.y(), overshootMaximumVelocity)); } else if (scrollToY) { @@ -752,7 +771,7 @@ void QKineticScrollerPrivate::setState(QKineticScroller::State newstate) if (state == newstate) return; - qWarning() << "Switiching to state " << stateName(newstate); + qWarning() << "Switching to state " << stateName(newstate); switch (newstate) { case QKineticScroller::StateInactive: @@ -768,6 +787,10 @@ void QKineticScrollerPrivate::setState(QKineticScroller::State newstate) break; case QKineticScroller::StatePressed: + if (timerId) { + killTimer(timerId); + timerId = 0; + } velocity = QPointF(0, 0); break; @@ -784,6 +807,11 @@ void QKineticScrollerPrivate::setState(QKineticScroller::State newstate) break; case QKineticScroller::StateScrolling: + if (state == QKineticScroller::StatePressed) { + if (!timerId) { + timerId = startTimer(1000 / framesPerSecond); + } + } scrollTimer.start(); break; } @@ -886,18 +914,29 @@ void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &pos) clampedPos.setY(qBound(qreal(0), pos.y(), maxPos.y())); bool alwaysOvershoot = (overshootPolicy == QKineticScroller::OvershootAlwaysOn); - qreal overshootX = (maxPos.x() || alwaysOvershoot) ? clampedPos.x() - pos.x() : 0; - qreal overshootY = (maxPos.y() || alwaysOvershoot) ? clampedPos.y() - pos.y() : 0; + qreal overshootX = (maxPos.x() || alwaysOvershoot) ? pos.x() - clampedPos.x() : 0; + qreal overshootY = (maxPos.y() || alwaysOvershoot) ? pos.y() - clampedPos.y() : 0; + // -- stop at the maximum overshoot distance (if set) if (!overshootMaximumDistance.isNull()) { - overshootDistance.setX(qBound(-overshootMaximumDistance.x(), overshootX, overshootMaximumDistance.x())); - overshootDistance.setY(qBound(-overshootMaximumDistance.y(), overshootY, overshootMaximumDistance.y())); + + qreal x = qBound(-overshootMaximumDistance.x() * pixelPerMeter, overshootX, overshootMaximumDistance.x() * pixelPerMeter); + if (x != overshootX) + velocity.setX(0); + overshootDistance.setX(x); + + qKSDebug() << "Overshoot y: "<<(overshootMaximumDistance.y() * pixelPerMeter)<<"distance: "<<overshootY; + qreal y = qBound(-overshootMaximumDistance.y() * pixelPerMeter, overshootY, overshootMaximumDistance.y() * pixelPerMeter); + if (y != overshootY) + velocity.setY(0); + overshootDistance.setY(y); + } else { overshootDistance = QPointF(overshootX, overshootY); } qKSDebug() << "setPosition raw: " << pos << ", clamped: " << clampedPos << ", overshoot: " << overshootDistance; - q->setContentPosition(clampedPos, overshootPolicy == QKineticScroller::OvershootAlwaysOff ? QPoint() : overshootDistance); + q->setContentPosition(clampedPos, overshootPolicy == QKineticScroller::OvershootAlwaysOff ? QPointF() : overshootDistance); } |