summaryrefslogtreecommitdiffstats
path: root/src/declarative/fx
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2009-10-27 06:30:51 (GMT)
committerMartin Jones <martin.jones@nokia.com>2009-10-27 06:30:51 (GMT)
commit7a5fdc99bb3d7fde52428a5fbc4ae1f25de12b5c (patch)
treebbab318f1d04903680fdf8ed93194a150e889d4f /src/declarative/fx
parenta8fb485e1f2a7c2d6de913a2f0b3809b95c47e36 (diff)
downloadQt-7a5fdc99bb3d7fde52428a5fbc4ae1f25de12b5c.zip
Qt-7a5fdc99bb3d7fde52428a5fbc4ae1f25de12b5c.tar.gz
Qt-7a5fdc99bb3d7fde52428a5fbc4ae1f25de12b5c.tar.bz2
Try to be a bit more clever with snapping.
Diffstat (limited to 'src/declarative/fx')
-rw-r--r--src/declarative/fx/qfxflickable.cpp26
-rw-r--r--src/declarative/fx/qfxflickable.h4
-rw-r--r--src/declarative/fx/qfxflickable_p.h5
-rw-r--r--src/declarative/fx/qfxlistview.cpp69
4 files changed, 97 insertions, 7 deletions
diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp
index cbfe9f6..92e79dd 100644
--- a/src/declarative/fx/qfxflickable.cpp
+++ b/src/declarative/fx/qfxflickable.cpp
@@ -157,7 +157,7 @@ QFxFlickablePrivate::QFxFlickablePrivate()
: viewport(new QFxItem), _moveX(viewport, &QFxItem::setX), _moveY(viewport, &QFxItem::setY)
, vWidth(-1), vHeight(-1), overShoot(true), flicked(false), moving(false), stealMouse(false)
, pressed(false), atXEnd(false), atXBeginning(true), atYEnd(false), atYBeginning(true)
- , interactive(true), maxVelocity(5000), reportedVelocitySmoothing(100)
+ , interactive(true), deceleration(500), maxVelocity(5000), reportedVelocitySmoothing(100)
, delayedPressEvent(0), delayedPressTarget(0), pressDelay(0)
, horizontalVelocity(this), verticalVelocity(this), vTime(0), visibleArea(0)
{
@@ -202,7 +202,7 @@ void QFxFlickablePrivate::flickX(qreal velocity)
v = maxVelocity;
}
timeline.reset(_moveX);
- timeline.accel(_moveX, v, 500, maxDistance);
+ timeline.accel(_moveX, v, deceleration, maxDistance);
timeline.execute(fixupXEvent);
if (!flicked) {
flicked = true;
@@ -238,7 +238,7 @@ void QFxFlickablePrivate::flickY(qreal velocity)
v = maxVelocity;
}
timeline.reset(_moveY);
- timeline.accel(_moveY, v, 500, maxDistance);
+ timeline.accel(_moveY, v, deceleration, maxDistance);
timeline.execute(fixupYEvent);
if (!flicked) {
flicked = true;
@@ -1131,7 +1131,7 @@ bool QFxFlickable::sceneEventFilter(QGraphicsItem *i, QEvent *e)
}
/*!
- \qmlproperty int Flickable::maximumFlickVelocity
+ \qmlproperty real Flickable::maximumFlickVelocity
This property holds the maximum velocity that the user can flick the view in pixels/second.
The default is 5000 pixels/s
@@ -1150,6 +1150,24 @@ void QFxFlickable::setMaximumFlickVelocity(qreal v)
d->maxVelocity = v;
}
+/*!
+ \qmlproperty real Flickable::maximumFlickVelocity
+ This property holds the rate at which a flick will decelerate.
+
+ The default is 500.
+*/
+qreal QFxFlickable::flickDeceleration() const
+{
+ Q_D(const QFxFlickable);
+ return d->deceleration;
+}
+
+void QFxFlickable::setFlickDeceleration(qreal deceleration)
+{
+ Q_D(QFxFlickable);
+ d->deceleration = deceleration;
+}
+
bool QFxFlickable::isFlicking() const
{
Q_D(const QFxFlickable);
diff --git a/src/declarative/fx/qfxflickable.h b/src/declarative/fx/qfxflickable.h
index aaf4e0f..4c80e8f 100644
--- a/src/declarative/fx/qfxflickable.h
+++ b/src/declarative/fx/qfxflickable.h
@@ -67,6 +67,7 @@ class Q_DECLARATIVE_EXPORT QFxFlickable : public QFxItem
Q_PROPERTY(bool overShoot READ overShoot WRITE setOverShoot)
Q_PROPERTY(qreal maximumFlickVelocity READ maximumFlickVelocity WRITE setMaximumFlickVelocity)
+ Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration)
Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged)
Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged)
@@ -118,6 +119,9 @@ public:
qreal maximumFlickVelocity() const;
void setMaximumFlickVelocity(qreal);
+ qreal flickDeceleration() const;
+ void setFlickDeceleration(qreal);
+
bool isInteractive() const;
void setInteractive(bool);
diff --git a/src/declarative/fx/qfxflickable_p.h b/src/declarative/fx/qfxflickable_p.h
index 7224f21..07d66b8 100644
--- a/src/declarative/fx/qfxflickable_p.h
+++ b/src/declarative/fx/qfxflickable_p.h
@@ -70,8 +70,8 @@ class QFxFlickablePrivate : public QFxItemPrivate
public:
QFxFlickablePrivate();
void init();
- void flickX(qreal velocity);
- void flickY(qreal velocity);
+ virtual void flickX(qreal velocity);
+ virtual void flickY(qreal velocity);
virtual void fixupX();
virtual void fixupY();
void updateBeginningEnd();
@@ -106,6 +106,7 @@ public:
QTime pressTime;
QmlTimeLineEvent fixupXEvent;
QmlTimeLineEvent fixupYEvent;
+ qreal deceleration;
qreal maxVelocity;
QTime velocityTime;
QPointF lastFlickablePosition;
diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp
index 28d2bb2..ca3132f 100644
--- a/src/declarative/fx/qfxlistview.cpp
+++ b/src/declarative/fx/qfxlistview.cpp
@@ -287,6 +287,11 @@ public:
return index;
}
+ //XXX Rough. Only works for fixed size items.
+ qreal snapPosAt(qreal pos) {
+ return qRound((pos - startPosition()) / averageSize) * averageSize + startPosition();
+ }
+
int lastVisibleIndex() const {
int lastIndex = -1;
for (int i = visibleItems.count()-1; i >= 0; --i) {
@@ -365,6 +370,8 @@ public:
void fixupPosition();
virtual void fixupY();
virtual void fixupX();
+ virtual void flickX(qreal velocity);
+ virtual void flickY(qreal velocity);
QFxVisualModel *model;
QVariant modelVariant;
@@ -750,7 +757,6 @@ void QFxListViewPrivate::updateCurrent(int modelIndex)
updateHighlight();
return;
}
-
FxListItem *oldCurrentItem = currentItem;
currentIndex = modelIndex;
currentItem = createItem(modelIndex);
@@ -822,6 +828,67 @@ void QFxListViewPrivate::fixupX()
}
}
+void QFxListViewPrivate::flickX(qreal velocity)
+{
+ Q_Q(QFxListView);
+
+ if (!haveHighlightRange || highlightRange != QFxListView::StrictlyEnforceRange)
+ QFxFlickablePrivate::flickX(velocity);
+
+ qreal maxDistance = -1;
+ // -ve velocity means list is moving up
+ if (velocity > 0) {
+ if (_moveX.value() < q->minXExtent())
+ maxDistance = qAbs(q->minXExtent() -_moveX.value() + (overShoot?30:0));
+ flickTargetX = q->minXExtent();
+ } else {
+ if (_moveX.value() > q->maxXExtent())
+ maxDistance = qAbs(q->maxXExtent() - _moveX.value()) + (overShoot?30:0);
+ flickTargetX = q->maxXExtent();
+ }
+ if (maxDistance > 0) {
+ qreal v = velocity;
+ if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
+ if (v < 0)
+ v = -maxVelocity;
+ else
+ v = maxVelocity;
+ }
+ qreal accel = deceleration;
+ qreal maxAccel = (v * v) / (2.0f * maxDistance);
+ if (maxAccel < accel) {
+ // If we are not flicking to the end then attempt to stop exactly on an item boundary
+ qreal dist = (v * v) / accel / 2.0;
+ if (v > 0)
+ dist = -dist;
+ dist = -_moveX.value() - snapPosAt(-_moveX.value() + dist + highlightRangeStart);
+ if (v < 0 && dist >= 0 || v > 0 && dist <= 0) {
+ timeline.reset(_moveX);
+ fixupX();
+ return;
+ }
+ accel = (v * v) / (2.0f * qAbs(dist));
+ }
+ timeline.reset(_moveX);
+ timeline.accel(_moveX, v, accel, maxDistance);
+ timeline.execute(fixupXEvent);
+ if (!flicked) {
+ flicked = true;
+ emit q->flickingChanged();
+ emit q->flickStarted();
+ }
+ } else {
+ timeline.reset(_moveX);
+ fixupX();
+ }
+}
+
+void QFxListViewPrivate::flickY(qreal velocity)
+{
+ if (!haveHighlightRange || highlightRange != QFxListView::StrictlyEnforceRange)
+ QFxFlickablePrivate::flickY(velocity);
+}
+
//----------------------------------------------------------------------------
/*!