summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Engels <ralf.engels@nokia.com>2010-04-14 15:34:17 +0200
committerRalf Engels <ralf.engels@nokia.com>2010-04-14 15:34:17 +0200
commit0503f713d3769746b12970f46760488c240c4705 (patch)
treec430d06255c4aa504346ae9b72ac964f62389667
parent3a80c2e66884dd706a16fc4e89835410811d3d2c (diff)
Fix scrollTo
-rw-r--r--qkineticscroller.cpp59
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;
}