summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widgets/util/qscroller.cpp63
-rw-r--r--src/widgets/util/qscroller_p.h5
2 files changed, 43 insertions, 25 deletions
diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp
index 4482134c7b..e39ed9c0a5 100644
--- a/src/widgets/util/qscroller.cpp
+++ b/src/widgets/util/qscroller.cpp
@@ -58,6 +58,7 @@
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QDesktopWidget>
+#include <QVector2D>
#include <QtCore/qmath.h>
#include <QtGui/qevent.h>
#include <qnumeric.h>
@@ -1160,11 +1161,10 @@ void QScrollerPrivate::recalcScrollingSegments(bool forceRecalc)
releaseVelocity = q->velocity();
- if (forceRecalc || !scrollingSegmentsValid(Qt::Horizontal))
- createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal);
-
- if (forceRecalc || !scrollingSegmentsValid(Qt::Vertical))
- createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical);
+ if (forceRecalc ||
+ !scrollingSegmentsValid(Qt::Horizontal) ||
+ !scrollingSegmentsValid(Qt::Vertical))
+ createScrollingSegments(releaseVelocity, contentPosition + overshootPosition, ppm);
}
/*! \internal
@@ -1256,7 +1256,9 @@ void QScrollerPrivate::createScrollToSegments(qreal v, qreal deltaTime, qreal en
/*! \internal
*/
-void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation)
+void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos,
+ qreal deltaTime, qreal deltaPos,
+ Qt::Orientation orientation)
{
const QScrollerPropertiesPrivate *sp = properties.d.data();
@@ -1287,22 +1289,6 @@ void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos, qreal pp
qScrollerDebug() << "v = " << v << ", decelerationFactor = " << sp->decelerationFactor << ", curveType = " << sp->scrollingCurve.type();
- // This is only correct for QEasingCurve::OutQuad (linear velocity,
- // constant deceleration), but the results look and feel ok for OutExpo
- // and OutSine as well
-
- // v(t) = deltaTime * a * 0.5 * differentialForProgress(t / deltaTime)
- // v(0) = vrelease
- // v(deltaTime) = 0
- // deltaTime = (2 * vrelease) / (a * differntial(0))
-
- // pos(t) = integrate(v(t)dt)
- // pos(t) = vrelease * t - 0.5 * a * t * t
- // pos(t) = deltaTime * a * 0.5 * progress(t / deltaTime) * deltaTime
- // deltaPos = pos(deltaTime)
-
- qreal deltaTime = (qreal(2) * qAbs(v)) / (sp->decelerationFactor * differentialForProgress(sp->scrollingCurve, 0));
- qreal deltaPos = qSign(v) * deltaTime * deltaTime * qreal(0.5) * sp->decelerationFactor * ppm;
qreal endPos = startPos + deltaPos;
qScrollerDebug() << " Real Delta:" << deltaPos;
@@ -1414,6 +1400,36 @@ void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos, qreal pp
}
+void QScrollerPrivate::createScrollingSegments(const QPointF &v,
+ const QPointF &startPos,
+ const QPointF &ppm)
+{
+ const QScrollerPropertiesPrivate *sp = properties.d.data();
+
+ // This is only correct for QEasingCurve::OutQuad (linear velocity,
+ // constant deceleration), but the results look and feel ok for OutExpo
+ // and OutSine as well
+
+ // v(t) = deltaTime * a * 0.5 * differentialForProgress(t / deltaTime)
+ // v(0) = vrelease
+ // v(deltaTime) = 0
+ // deltaTime = (2 * vrelease) / (a * differntial(0))
+
+ // pos(t) = integrate(v(t)dt)
+ // pos(t) = vrelease * t - 0.5 * a * t * t
+ // pos(t) = deltaTime * a * 0.5 * progress(t / deltaTime) * deltaTime
+ // deltaPos = pos(deltaTime)
+
+ QVector2D vel(v);
+ qreal deltaTime = (qreal(2) * vel.length()) / (sp->decelerationFactor * differentialForProgress(sp->scrollingCurve, 0));
+ QPointF deltaPos = (vel.normalized() * QVector2D(ppm)).toPointF() * deltaTime * deltaTime * qreal(0.5) * sp->decelerationFactor;
+
+ createScrollingSegments(v.x(), startPos.x(), deltaTime, deltaPos.x(),
+ Qt::Horizontal);
+ createScrollingSegments(v.y(), startPos.y(), deltaTime, deltaPos.y(),
+ Qt::Vertical);
+}
+
/*! \internal
Prepares scrolling by sending a QScrollPrepareEvent to the receiver widget.
Returns true if the scrolling was accepted and a target was returned.
@@ -1650,8 +1666,7 @@ bool QScrollerPrivate::releaseWhileDragging(const QPointF &position, qint64 time
}
QPointF ppm = q->pixelPerMeter();
- createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal);
- createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical);
+ createScrollingSegments(releaseVelocity, contentPosition + overshootPosition, ppm);
qScrollerDebug() << "QScroller::releaseWhileDragging() -- velocity:" << releaseVelocity << "-- minimum velocity:" << sp->minimumVelocity << "overshoot" << overshootPosition;
diff --git a/src/widgets/util/qscroller_p.h b/src/widgets/util/qscroller_p.h
index 6463f03573..26bd64461f 100644
--- a/src/widgets/util/qscroller_p.h
+++ b/src/widgets/util/qscroller_p.h
@@ -131,7 +131,10 @@ public:
qreal scrollingSegmentsEndPos(Qt::Orientation orientation) const;
bool scrollingSegmentsValid(Qt::Orientation orientation);
void createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type);
- void createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation);
+ void createScrollingSegments(qreal v, qreal startPos,
+ qreal deltaTime, qreal deltaPos,
+ Qt::Orientation orientation);
+ void createScrollingSegments(const QPointF &v, const QPointF &startPos, const QPointF &ppm);
void setContentPositionHelperDragging(const QPointF &deltaPos);
void setContentPositionHelperScrolling();