diff options
author | Ralf Engels <ralf.engels@nokia.com> | 2010-04-14 15:34:17 +0200 |
---|---|---|
committer | Ralf Engels <ralf.engels@nokia.com> | 2010-04-14 15:34:17 +0200 |
commit | 0503f713d3769746b12970f46760488c240c4705 (patch) | |
tree | c430d06255c4aa504346ae9b72ac964f62389667 | |
parent | 3a80c2e66884dd706a16fc4e89835410811d3d2c (diff) |
Fix scrollTo
-rw-r--r-- | qkineticscroller.cpp | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/qkineticscroller.cpp b/qkineticscroller.cpp index bdf4cfa..47d3aed 100644 --- a/qkineticscroller.cpp +++ b/qkineticscroller.cpp @@ -860,6 +860,9 @@ void QKineticScroller::scrollTo(const QPointF &pos, int scrollTime) { Q_D(QKineticScroller); + if (scrollTime <= 0) + scrollTime = 1; + qreal time = qreal(scrollTime) / 1000; if ((pos == contentPosition()) || @@ -887,18 +890,25 @@ void QKineticScroller::scrollTo(const QPointF &pos, int scrollTime) // v(t) = vstart * exponentialDecelerationBase ^ t - linearDecelerationFactor * t // pos(t) = integrate(v(t) * dt) - // pos(t) = vstart * eDB ^ t / ln(eDB) - lDF / 2 * t ^ 2 + // pos(t) = vstart * (eDB ^ t / ln(eDB) + C) - lDF / 2 * t ^ 2 // - // pos(scrollTime) = pos - contentsPos() - // vstart = ((lDF / 2) * scrollTime ^ 2 + (pos - contentPos())) * ln(eDB) / eDB ^ scrollTime + // pos(time) = pos - contentsPos() + // vstart = ((lDF / 2) * time ^ 2 + (pos - contentPos())) / (eDB ^ time / ln(eDB) + C) + // (for C = -1/ln(eDB) ) + + QPointF scrollDir(qSign(pos.x()-contentPosition().x()), + qSign(pos.y()-contentPosition().y())); - QPointF v = (QPointF(1, 1) * (d->linearDecelerationFactor / qreal(2)) * qreal(time) * qreal(time) + (pos - contentPosition()) / d->pixelPerMeter); + QPointF v = (scrollDir * (d->linearDecelerationFactor / qreal(2)) * qreal(time) * qreal(time) + (pos - contentPosition()) / d->pixelPerMeter); if (d->exponentialDecelerationBase != qreal(1)) - v *= qLn(d->exponentialDecelerationBase) / qPow(d->exponentialDecelerationBase, time); + v /= (qPow(d->exponentialDecelerationBase, time) - 1) / qLn(d->exponentialDecelerationBase); + else + v /= time; - qKSDebug() << "QAbstractKineticScroller::scrollTo(" << pos << ", " << v; - qKSDebug() << "QAbstr " << d->linearDecelerationFactor <<" 1: "<< (qreal(2) * qreal(scrollTime) * qreal(scrollTime)) << " 2: " << (pos - contentPosition()) << " 3: " << - qLn(d->exponentialDecelerationBase) << "4: " << qPow(d->exponentialDecelerationBase, scrollTime); + qKSDebug() << "QAbstractKineticScroller::scrollTo pos:" << pos << "v:" << v <<"minV:"<<vMin; + qKSDebug() << "QAbstr " << d->linearDecelerationFactor <<" 1: "<< (qreal(2) * qreal(time) * qreal(scrollTime)) << " 2: " << (pos - contentPosition()) << " 3: " << + qLn(d->exponentialDecelerationBase) << "4: " << qPow(d->exponentialDecelerationBase, time) + << " 5: "<<((qPow(d->exponentialDecelerationBase, time) - 1) / qLn(d->exponentialDecelerationBase)); // start the scrolling @@ -990,6 +1000,12 @@ void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &deltaPos) qreal newOvershootX = (maxPos.x() || alwaysOvershoot) ? newPos.x() - newClampedPos.x() : 0; qreal newOvershootY = (maxPos.y() || alwaysOvershoot) ? newPos.y() - newClampedPos.y() : 0; + // --- sanity check for scrollTo in case we can't even scroll that direction + if (!(maxPos.x() || alwaysOvershoot)) + scrollToX = false; + if (!(maxPos.y() || alwaysOvershoot)) + scrollToY = false; + QPointF oldScrollToDist = scrollToPosition - oldPos; QPointF newScrollToDist = scrollToPosition - newPos; @@ -997,7 +1013,12 @@ void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &deltaPos) qDebug() << "oldOver: " << oldOvershootY << " newOver: " << newOvershootY; // -- x axis - if (oldOvershootX && (qSign(oldOvershootX) != qSign(newOvershootX))) { + if (scrollToX && qSign(oldScrollToDist.x()) != qSign(newScrollToDist.x())) { + newClampedPos.setX(scrollToPosition.x()); + releaseVelocity.setX(0); + scrollToX = false; + + } else if (oldOvershootX && (qSign(oldOvershootX) != qSign(newOvershootX))) { newClampedPos.setX((oldOvershootX < 0) ? 0 : maxPos.x()); realOvershootDistance.setX(0); releaseVelocity.setX(0); @@ -1012,15 +1033,15 @@ void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &deltaPos) overshootX = true; } realOvershootDistance.setX(newOvershootX); - - } else if (scrollToX && qSign(oldScrollToDist.x()) != qSign(newScrollToDist.x())) { - newClampedPos.setX(scrollToPosition.x()); - releaseVelocity.setX(0); - scrollToX = false; } // -- y axis - if (oldOvershootY && (qSign(oldOvershootY) != qSign(newOvershootY))) { + if (scrollToY && qSign(oldScrollToDist.y()) != qSign(newScrollToDist.y())) { + newClampedPos.setY(scrollToPosition.y()); + releaseVelocity.setY(0); + scrollToY = false; + + } else if (oldOvershootY && (qSign(oldOvershootY) != qSign(newOvershootY))) { newClampedPos.setY((oldOvershootY < 0) ? 0 : maxPos.y()); realOvershootDistance.setY(0); releaseVelocity.setY(0); @@ -1035,11 +1056,6 @@ void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &deltaPos) overshootY = true; } realOvershootDistance.setY(newOvershootY); - - } else if (scrollToY && qSign(oldScrollToDist.y()) != qSign(newScrollToDist.y())) { - newClampedPos.setY(scrollToPosition.y()); - releaseVelocity.setY(0); - scrollToY = false; } overshootPosition = realOvershootDistance; @@ -1059,7 +1075,8 @@ void QKineticScrollerPrivate::setContentPositionHelper(const QPointF &deltaPos) q->setContentPosition(newClampedPos, realOvershootDistance); - qDebug() << "setContentPositionHelper" << newClampedPos << " overshoot:" << realOvershootDistance; + qDebug() << "setContentPositionHelper" << newClampedPos << " overshoot:" << realOvershootDistance << + "Overshoot: "<<overshootX<<","<<overshootY<<"ScrollTo:"<<scrollToX<<","<<scrollToY; } |