summaryrefslogtreecommitdiffstats
path: root/qkineticscroller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qkineticscroller.cpp')
-rw-r--r--qkineticscroller.cpp81
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);
}