aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2012-06-13 11:17:44 +1000
committerQt by Nokia <qt-info@nokia.com>2012-06-13 09:07:03 +0200
commit6a1f3c1b355ae1834ed6b6515a575f46f6f58897 (patch)
treece02ee14ff0513b716b9de9fec3f2b712310a530 /src/quick/items
parent86cbb55522f9a4ca76854be860a8131f006553a8 (diff)
Update Flickable velocity/overbound for each axis independently
We were attempting to update velocities/overbound correction for both axes even if only one of them had changed, leading to inaccurate values for one of the axes. Also removes a bunch of code duplication. Change-Id: I6a50b908992c976889373f541bdd1abad462e247 Reviewed-by: Bea Lam <bea.lam@nokia.com>
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickflickable.cpp120
-rw-r--r--src/quick/items/qquickflickable_p.h2
-rw-r--r--src/quick/items/qquickflickable_p_p.h10
-rw-r--r--src/quick/items/qquickgridview.cpp4
-rw-r--r--src/quick/items/qquickgridview_p.h2
-rw-r--r--src/quick/items/qquicklistview.cpp4
-rw-r--r--src/quick/items/qquicklistview_p.h2
7 files changed, 66 insertions, 78 deletions
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 57fb712e78..9e65d962b2 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -330,13 +330,16 @@ void QQuickFlickablePrivate::itemGeometryChanged(QQuickItem *item, const QRectF
{
Q_Q(QQuickFlickable);
if (item == contentItem) {
- bool xChanged = newGeom.x() != oldGeom.x();
- bool yChanged = newGeom.y() != oldGeom.y();
- if (xChanged || yChanged)
- q->viewportMoved();
- if (xChanged)
+ Qt::Orientations orient = 0;
+ if (newGeom.x() != oldGeom.x())
+ orient |= Qt::Horizontal;
+ if (newGeom.y() != oldGeom.y())
+ orient |= Qt::Vertical;
+ if (orient)
+ q->viewportMoved(orient);
+ if (orient & Qt::Horizontal)
emit q->contentXChanged();
- if (yChanged)
+ if (orient & Qt::Vertical)
emit q->contentYChanged();
}
}
@@ -496,7 +499,7 @@ void QQuickFlickablePrivate::fixup(AxisData &data, qreal minExtent, qreal maxExt
}
data.inOvershoot = false;
fixupMode = Normal;
- vTime = timeline.time();
+ data.vTime = timeline.time();
}
void QQuickFlickablePrivate::updateBeginningEnd()
@@ -718,7 +721,7 @@ void QQuickFlickable::setContentX(qreal pos)
Q_D(QQuickFlickable);
d->hData.explicitValue = true;
d->resetTimeline(d->hData);
- d->vTime = d->timeline.time();
+ d->hData.vTime = d->timeline.time();
movementEnding(true, false);
if (-pos != d->hData.move.value())
d->hData.move.setValue(-pos);
@@ -735,7 +738,7 @@ void QQuickFlickable::setContentY(qreal pos)
Q_D(QQuickFlickable);
d->vData.explicitValue = true;
d->resetTimeline(d->vData);
- d->vTime = d->timeline.time();
+ d->vData.vTime = d->timeline.time();
movementEnding(false, true);
if (-pos != d->vData.move.value())
d->vData.move.setValue(-pos);
@@ -767,7 +770,7 @@ void QQuickFlickable::setInteractive(bool interactive)
d->interactive = interactive;
if (!interactive && (d->hData.flicking || d->vData.flicking)) {
d->clearTimeline();
- d->vTime = d->timeline.time();
+ d->hData.vTime = d->vData.vTime = d->timeline.time();
d->hData.flicking = false;
d->vData.flicking = false;
emit flickingChanged();
@@ -982,7 +985,8 @@ void QQuickFlickablePrivate::handleMousePressEvent(QMouseEvent *event)
if (wasFlicking)
emit q->flickingChanged();
lastPosTime = lastPressTime = computeCurrentTime(event);
- QQuickItemPrivate::start(velocityTime);
+ QQuickItemPrivate::start(vData.velocityTime);
+ QQuickItemPrivate::start(hData.velocityTime);
}
void QQuickFlickablePrivate::handleMouseMoveEvent(QMouseEvent *event)
@@ -1131,7 +1135,7 @@ void QQuickFlickablePrivate::handleMouseReleaseEvent(QMouseEvent *event)
if (lastPosTime == -1)
return;
- vTime = timeline.time();
+ hData.vTime = vData.vTime = timeline.time();
bool canBoost = false;
@@ -1382,77 +1386,57 @@ void QQuickFlickable::componentComplete()
setContentY(-minYExtent());
}
-void QQuickFlickable::viewportMoved()
+void QQuickFlickable::viewportMoved(Qt::Orientations orient)
{
Q_D(QQuickFlickable);
+ if (orient & Qt::Vertical)
+ d->viewportAxisMoved(d->vData, minYExtent(), maxYExtent(), height(), d->fixupY_callback);
+ if (orient & Qt::Horizontal)
+ d->viewportAxisMoved(d->hData, minXExtent(), maxXExtent(), width(), d->fixupX_callback);
+ d->updateBeginningEnd();
+}
- qreal prevX = d->lastFlickablePosition.x();
- qreal prevY = d->lastFlickablePosition.y();
- if (d->pressed || d->calcVelocity) {
- int elapsed = QQuickItemPrivate::restart(d->velocityTime);
+void QQuickFlickablePrivate::viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+ QQuickTimeLineCallback::Callback fixupCallback)
+{
+ if (pressed || calcVelocity) {
+ int elapsed = QQuickItemPrivate::restart(data.velocityTime);
if (elapsed > 0) {
- qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / elapsed;
- if (qAbs(horizontalVelocity) > 0) {
- d->velocityTimeline.reset(d->hData.smoothVelocity);
- if (d->calcVelocity)
- d->velocityTimeline.set(d->hData.smoothVelocity, horizontalVelocity);
+ qreal velocity = (data.lastPos - data.move.value()) * 1000 / elapsed;
+ if (qAbs(velocity) > 0) {
+ velocityTimeline.reset(data.smoothVelocity);
+ if (calcVelocity)
+ velocityTimeline.set(data.smoothVelocity, velocity);
else
- d->velocityTimeline.move(d->hData.smoothVelocity, horizontalVelocity, d->reportedVelocitySmoothing);
- d->velocityTimeline.move(d->hData.smoothVelocity, 0, d->reportedVelocitySmoothing);
- }
- qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / elapsed;
- if (qAbs(verticalVelocity) > 0) {
- d->velocityTimeline.reset(d->vData.smoothVelocity);
- if (d->calcVelocity)
- d->velocityTimeline.set(d->vData.smoothVelocity, verticalVelocity);
- else
- d->velocityTimeline.move(d->vData.smoothVelocity, verticalVelocity, d->reportedVelocitySmoothing);
- d->velocityTimeline.move(d->vData.smoothVelocity, 0, d->reportedVelocitySmoothing);
+ velocityTimeline.move(data.smoothVelocity, velocity, reportedVelocitySmoothing);
+ velocityTimeline.move(data.smoothVelocity, 0, reportedVelocitySmoothing);
}
}
} else {
- if (d->timeline.time() > d->vTime) {
- d->velocityTimeline.clear();
- qreal horizontalVelocity = (prevX - d->hData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
- qreal verticalVelocity = (prevY - d->vData.move.value()) * 1000 / (d->timeline.time() - d->vTime);
- d->hData.smoothVelocity.setValue(horizontalVelocity);
- d->vData.smoothVelocity.setValue(verticalVelocity);
+ if (timeline.time() > data.vTime) {
+ velocityTimeline.reset(data.smoothVelocity);
+ qreal velocity = (data.lastPos - data.move.value()) * 1000 / (timeline.time() - data.vTime);
+ data.smoothVelocity.setValue(velocity);
}
}
- if (!d->vData.inOvershoot && !d->vData.fixingUp && d->vData.flicking
- && (d->vData.move.value() > minYExtent() || d->vData.move.value() < maxYExtent())
- && qAbs(d->vData.smoothVelocity.value()) > 10) {
- // Increase deceleration if we've passed a bound
- qreal overBound = d->vData.move.value() > minYExtent()
- ? d->vData.move.value() - minYExtent()
- : maxYExtent() - d->vData.move.value();
- d->vData.inOvershoot = true;
- qreal maxDistance = d->overShootDistance(height()) - overBound;
- d->resetTimeline(d->vData);
- if (maxDistance > 0)
- d->timeline.accel(d->vData.move, -d->vData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
- d->timeline.callback(QQuickTimeLineCallback(&d->vData.move, d->fixupY_callback, d));
- }
- if (!d->hData.inOvershoot && !d->hData.fixingUp && d->hData.flicking
- && (d->hData.move.value() > minXExtent() || d->hData.move.value() < maxXExtent())
- && qAbs(d->hData.smoothVelocity.value()) > 10) {
+ if (!data.inOvershoot && !data.fixingUp && data.flicking
+ && (data.move.value() > minExtent || data.move.value() < maxExtent)
+ && qAbs(data.smoothVelocity.value()) > 10) {
// Increase deceleration if we've passed a bound
- qreal overBound = d->hData.move.value() > minXExtent()
- ? d->hData.move.value() - minXExtent()
- : maxXExtent() - d->hData.move.value();
- d->hData.inOvershoot = true;
- qreal maxDistance = d->overShootDistance(width()) - overBound;
- d->resetTimeline(d->hData);
+ qreal overBound = data.move.value() > minExtent
+ ? data.move.value() - minExtent
+ : maxExtent - data.move.value();
+ data.inOvershoot = true;
+ qreal maxDistance = overShootDistance(vSize) - overBound;
+ resetTimeline(data);
if (maxDistance > 0)
- d->timeline.accel(d->hData.move, -d->hData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
- d->timeline.callback(QQuickTimeLineCallback(&d->hData.move, d->fixupX_callback, d));
+ timeline.accel(data.move, -data.smoothVelocity.value(), deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
+ timeline.callback(QQuickTimeLineCallback(&data.move, fixupCallback, this));
}
- d->lastFlickablePosition = QPointF(d->hData.move.value(), d->vData.move.value());
-
- d->vTime = d->timeline.time();
- d->updateBeginningEnd();
+ data.lastPos = data.move.value();
+ data.vTime = timeline.time();
}
void QQuickFlickable::geometryChanged(const QRectF &newGeometry,
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index 81135c27df..68e6caee1e 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -253,7 +253,7 @@ protected:
qreal vWidth() const;
qreal vHeight() const;
virtual void componentComplete();
- virtual void viewportMoved();
+ virtual void viewportMoved(Qt::Orientations orient);
virtual void geometryChanged(const QRectF &newGeometry,
const QRectF &oldGeometry);
void mouseUngrabEvent();
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 64335c8240..e0fa526d15 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -103,7 +103,7 @@ public:
, transitionToBounds(0)
, viewSize(-1), startMargin(0), endMargin(0)
, transitionTo(0)
- , continuousFlickVelocity(0)
+ , continuousFlickVelocity(0), vTime(0)
, smoothVelocity(fp), atEnd(false), atBeginning(true)
, transitionToSet(false)
, fixingUp(false), inOvershoot(false), moving(false), flicking(false)
@@ -138,6 +138,7 @@ public:
QQuickFlickableReboundTransition *transitionToBounds;
qreal viewSize;
qreal pressPos;
+ qreal lastPos;
qreal dragStartOffset;
qreal dragMinBound;
qreal dragMaxBound;
@@ -147,6 +148,8 @@ public:
qreal endMargin;
qreal transitionTo;
qreal continuousFlickVelocity;
+ QElapsedTimer velocityTime;
+ int vTime;
QQuickFlickablePrivate::Velocity smoothVelocity;
QPODVector<qreal,10> velocityBuffer;
bool atEnd : 1;
@@ -215,8 +218,6 @@ public:
QPointF pressPos;
qreal deceleration;
qreal maxVelocity;
- QElapsedTimer velocityTime;
- QPointF lastFlickablePosition;
qreal reportedVelocitySmoothing;
QMouseEvent *delayedPressEvent;
QQuickItem *delayedPressTarget;
@@ -239,6 +240,9 @@ public:
QQuickFlickable::BoundsBehavior boundsBehavior;
QQuickTransition *rebound;
+ void viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
+ QQuickTimeLineCallback::Callback fixupCallback);
+
void handleMousePressEvent(QMouseEvent *);
void handleMouseMoveEvent(QMouseEvent *);
void handleMouseReleaseEvent(QMouseEvent *);
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index fa1e96c824..65ca1aee25 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -1986,10 +1986,10 @@ void QQuickGridView::setSnapMode(SnapMode mode)
\sa addDisplaced, moveDisplaced, removeDisplaced, ViewTransition
*/
-void QQuickGridView::viewportMoved()
+void QQuickGridView::viewportMoved(Qt::Orientations orient)
{
Q_D(QQuickGridView);
- QQuickItemView::viewportMoved();
+ QQuickItemView::viewportMoved(orient);
if (!d->itemCount)
return;
if (d->inViewportMoved)
diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h
index 789c6411a5..aa4e56ec17 100644
--- a/src/quick/items/qquickgridview_p.h
+++ b/src/quick/items/qquickgridview_p.h
@@ -109,7 +109,7 @@ Q_SIGNALS:
void snapModeChanged();
protected:
- virtual void viewportMoved();
+ virtual void viewportMoved(Qt::Orientations);
virtual void keyPressEvent(QKeyEvent *);
virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
};
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 5401abc442..17851cd76b 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -2631,10 +2631,10 @@ void QQuickListView::setSnapMode(SnapMode mode)
\sa addDisplaced, moveDisplaced, removeDisplaced, ViewTransition
*/
-void QQuickListView::viewportMoved()
+void QQuickListView::viewportMoved(Qt::Orientations orient)
{
Q_D(QQuickListView);
- QQuickItemView::viewportMoved();
+ QQuickItemView::viewportMoved(orient);
if (!d->itemCount)
return;
// Recursion can occur due to refill changing the content size.
diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h
index ef989ba839..be8da90788 100644
--- a/src/quick/items/qquicklistview_p.h
+++ b/src/quick/items/qquicklistview_p.h
@@ -167,7 +167,7 @@ Q_SIGNALS:
void snapModeChanged();
protected:
- virtual void viewportMoved();
+ virtual void viewportMoved(Qt::Orientations orient);
virtual void keyPressEvent(QKeyEvent *);
virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry);