summaryrefslogtreecommitdiffstats
path: root/src/declarative/graphicsitems
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2010-02-26 06:21:39 (GMT)
committerMartin Jones <martin.jones@nokia.com>2010-02-26 06:21:39 (GMT)
commitdfda902012adee3869a1619ba96d9c0b1bf339f2 (patch)
treea2dff43133984ec39a55196aea031ee750562b21 /src/declarative/graphicsitems
parent91b4b6ce6684503b117817fc72b30812ab0e7722 (diff)
downloadQt-dfda902012adee3869a1619ba96d9c0b1bf339f2.zip
Qt-dfda902012adee3869a1619ba96d9c0b1bf339f2.tar.gz
Qt-dfda902012adee3869a1619ba96d9c0b1bf339f2.tar.bz2
Make Flickable overshoot behavior nicer.
Diffstat (limited to 'src/declarative/graphicsitems')
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp67
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable_p_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp16
3 files changed, 58 insertions, 27 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index 333ad60..3f4a9ce 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -128,7 +128,7 @@ QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate()
, vWidth(-1), vHeight(-1), overShoot(true), flicked(false), moving(false), stealMouse(false)
, pressed(false), atXEnd(false), atXBeginning(true), atYEnd(false), atYBeginning(true)
, interactive(true), deceleration(500), maxVelocity(2000), reportedVelocitySmoothing(100)
- , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(200)
+ , delayedPressEvent(0), delayedPressTarget(0), pressDelay(0), fixupDuration(600)
, horizontalVelocity(this), verticalVelocity(this), vTime(0), visibleArea(0)
, flickDirection(QDeclarativeFlickable::AutoFlickDirection)
{
@@ -148,6 +148,23 @@ void QDeclarativeFlickablePrivate::init()
QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(widthChange()));
}
+/*
+ Returns the amount to overshoot by given a velocity.
+ Will be roughly in range 0 - size/4
+*/
+qreal QDeclarativeFlickablePrivate::overShootDistance(qreal velocity, qreal size)
+{
+ Q_Q(QDeclarativeFlickable);
+ if (maxVelocity <= 0)
+ return 0.0;
+
+ velocity = qAbs(velocity);
+ if (velocity > maxVelocity)
+ velocity = maxVelocity;
+ qreal dist = size / 4 * velocity / maxVelocity;
+ return dist;
+}
+
void QDeclarativeFlickablePrivate::flickX(qreal velocity)
{
Q_Q(QDeclarativeFlickable);
@@ -156,12 +173,12 @@ void QDeclarativeFlickablePrivate::flickX(qreal velocity)
if (velocity > 0) {
const qreal minX = q->minXExtent();
if (_moveX.value() < minX)
- maxDistance = qAbs(minX -_moveX.value() + (overShoot?30:0));
+ maxDistance = qAbs(minX -_moveX.value() + (overShoot?overShootDistance(velocity,q->width()):0));
flickTargetX = minX;
} else {
const qreal maxX = q->maxXExtent();
if (_moveX.value() > maxX)
- maxDistance = qAbs(maxX - _moveX.value()) + (overShoot?30:0);
+ maxDistance = qAbs(maxX - _moveX.value()) + (overShoot?overShootDistance(velocity,q->width()):0);
flickTargetX = maxX;
}
if (maxDistance > 0) {
@@ -194,12 +211,12 @@ void QDeclarativeFlickablePrivate::flickY(qreal velocity)
if (velocity > 0) {
const qreal minY = q->minYExtent();
if (_moveY.value() < minY)
- maxDistance = qAbs(minY -_moveY.value() + (overShoot?30:0));
+ maxDistance = qAbs(minY -_moveY.value() + (overShoot?overShootDistance(velocity,q->height()):0));
flickTargetY = minY;
} else {
const qreal maxY = q->maxYExtent();
if (_moveY.value() > maxY)
- maxDistance = qAbs(maxY - _moveY.value()) + (overShoot?30:0);
+ maxDistance = qAbs(maxY - _moveY.value()) + (overShoot?overShootDistance(velocity,q->height()):0);
flickTargetY = maxY;
}
if (maxDistance > 0) {
@@ -233,18 +250,24 @@ void QDeclarativeFlickablePrivate::fixupX()
if (_moveX.value() > q->minXExtent() || (q->maxXExtent() > q->minXExtent())) {
timeline.reset(_moveX);
if (_moveX.value() != q->minXExtent()) {
- if (fixupDuration)
- timeline.move(_moveX, q->minXExtent(), QEasingCurve(QEasingCurve::InOutQuad), fixupDuration);
- else
- _moveY.setValue(q->minYExtent());
+ if (fixupDuration) {
+ qreal dist = q->minXExtent() - _moveX;
+ timeline.move(_moveX, q->minXExtent() - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+ timeline.move(_moveX, q->minXExtent(), QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
+ } else {
+ _moveX.setValue(q->minXExtent());
+ }
}
//emit flickingChanged();
} else if (_moveX.value() < q->maxXExtent()) {
timeline.reset(_moveX);
- if (fixupDuration)
- timeline.move(_moveX, q->maxXExtent(), QEasingCurve(QEasingCurve::InOutQuad), fixupDuration);
- else
- _moveY.setValue(q->maxYExtent());
+ if (fixupDuration) {
+ qreal dist = q->maxXExtent() - _moveX;
+ timeline.move(_moveX, q->maxXExtent() - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+ timeline.move(_moveX, q->maxXExtent(), QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
+ } else {
+ _moveX.setValue(q->maxXExtent());
+ }
//emit flickingChanged();
} else {
flicked = false;
@@ -272,18 +295,24 @@ void QDeclarativeFlickablePrivate::fixupY()
if (_moveY.value() > q->minYExtent() || (q->maxYExtent() > q->minYExtent())) {
timeline.reset(_moveY);
if (_moveY.value() != q->minYExtent()) {
- if (fixupDuration)
- timeline.move(_moveY, q->minYExtent(), QEasingCurve(QEasingCurve::InOutQuad), fixupDuration);
- else
+ if (fixupDuration) {
+ qreal dist = q->minYExtent() - _moveY;
+ timeline.move(_moveY, q->minYExtent() - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+ timeline.move(_moveY, q->minYExtent(), QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
+ } else {
_moveY.setValue(q->minYExtent());
+ }
}
//emit flickingChanged();
} else if (_moveY.value() < q->maxYExtent()) {
timeline.reset(_moveY);
- if (fixupDuration)
- timeline.move(_moveY, q->maxYExtent(), QEasingCurve(QEasingCurve::InOutQuad), fixupDuration);
- else
+ if (fixupDuration) {
+ qreal dist = q->maxYExtent() - _moveY;
+ timeline.move(_moveY, q->maxYExtent() - dist/2, QEasingCurve(QEasingCurve::InQuad), fixupDuration/4);
+ timeline.move(_moveY, q->maxYExtent(), QEasingCurve(QEasingCurve::OutQuint), 3*fixupDuration/4);
+ } else {
_moveY.setValue(q->maxYExtent());
+ }
//emit flickingChanged();
} else {
flicked = false;
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
index dc3a8a2..1ff4f92 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h
@@ -85,6 +85,8 @@ public:
void setRoundedViewportX(qreal x);
void setRoundedViewportY(qreal y);
+ qreal overShootDistance(qreal velocity, qreal size);
+
public:
QDeclarativeItem *viewport;
QDeclarativeTimeLineValueProxy<QDeclarativeFlickablePrivate> _moveX;
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 6421018..c496c97 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -1073,7 +1073,7 @@ void QDeclarativeListViewPrivate::fixupY()
qreal pos = currentItem->position() - highlightRangeStart;
timeline.reset(_moveY);
if (fixupDuration)
- timeline.move(_moveY, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration);
+ timeline.move(_moveY, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
else
_moveY.setValue(-pos);
vTime = timeline.time();
@@ -1085,7 +1085,7 @@ void QDeclarativeListViewPrivate::fixupY()
if (dist > 0) {
timeline.reset(_moveY);
if (fixupDuration)
- timeline.move(_moveY, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration);
+ timeline.move(_moveY, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
else
_moveY.setValue(-pos);
vTime = timeline.time();
@@ -1155,7 +1155,7 @@ void QDeclarativeListViewPrivate::flickX(qreal velocity)
if (FxListItem *item = firstVisibleItem())
maxDistance = qAbs(item->position() + _moveX.value());
} else if (_moveX.value() < minX) {
- maxDistance = qAbs(minX -_moveX.value() + (overShoot?30:0));
+ maxDistance = qAbs(minX -_moveX.value() + (overShoot?overShootDistance(velocity, q->width()):0));
}
if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
flickTargetX = minX;
@@ -1164,7 +1164,7 @@ void QDeclarativeListViewPrivate::flickX(qreal velocity)
if (FxListItem *item = nextVisibleItem())
maxDistance = qAbs(item->position() + _moveX.value());
} else if (_moveX.value() > maxX) {
- maxDistance = qAbs(maxX - _moveX.value()) + (overShoot?30:0);
+ maxDistance = qAbs(maxX - _moveX.value()) + (overShoot?overShootDistance(velocity, q->width()):0);
}
if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
flickTargetX = maxX;
@@ -1196,7 +1196,7 @@ void QDeclarativeListViewPrivate::flickX(qreal velocity)
overshootDist = 0.0;
} else {
flickTargetX = velocity > 0 ? minX : maxX;
- overshootDist = overShoot ? 30 : 0;
+ overshootDist = overShoot ? overShootDistance(v, q->width()) : 0;
}
timeline.reset(_moveX);
timeline.accel(_moveX, v, accel, maxDistance + overshootDist);
@@ -1253,7 +1253,7 @@ void QDeclarativeListViewPrivate::flickY(qreal velocity)
if (FxListItem *item = firstVisibleItem())
maxDistance = qAbs(item->position() + _moveY.value());
} else if (_moveY.value() < minY) {
- maxDistance = qAbs(minY -_moveY.value() + (overShoot?30:0));
+ maxDistance = qAbs(minY -_moveY.value() + (overShoot?overShootDistance(velocity, q->height()):0));
}
if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
flickTargetY = minY;
@@ -1262,7 +1262,7 @@ void QDeclarativeListViewPrivate::flickY(qreal velocity)
if (FxListItem *item = nextVisibleItem())
maxDistance = qAbs(item->position() + _moveY.value());
} else if (_moveY.value() > maxY) {
- maxDistance = qAbs(maxY - _moveY.value()) + (overShoot?30:0);
+ maxDistance = qAbs(maxY - _moveY.value()) + (overShoot?overShootDistance(velocity, q->height()):0);
}
if (snapMode != QDeclarativeListView::SnapToItem && highlightRange != QDeclarativeListView::StrictlyEnforceRange)
flickTargetY = maxY;
@@ -1294,7 +1294,7 @@ void QDeclarativeListViewPrivate::flickY(qreal velocity)
overshootDist = 0.0;
} else {
flickTargetY = velocity > 0 ? minY : maxY;
- overshootDist = overShoot ? 30 : 0;
+ overshootDist = overShoot ? overShootDistance(v, q->height()) : 0;
}
timeline.reset(_moveY);
timeline.accel(_moveY, v, accel, maxDistance + overshootDist);