summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/declarative/listview/listview.qml1
-rw-r--r--examples/declarative/parallax/ParallaxView.qml3
-rw-r--r--src/declarative/fx/qfxflickable.cpp26
-rw-r--r--src/declarative/fx/qfxlistview.cpp80
4 files changed, 92 insertions, 18 deletions
diff --git a/examples/declarative/listview/listview.qml b/examples/declarative/listview/listview.qml
index b614904..92acce1 100644
--- a/examples/declarative/listview/listview.qml
+++ b/examples/declarative/listview/listview.qml
@@ -72,5 +72,6 @@ Rectangle {
preferredHighlightBegin: 125
preferredHighlightEnd: 125
highlightRangeMode: "StrictlyEnforceRange"
+ flickDeceleration: 1000
}
}
diff --git a/examples/declarative/parallax/ParallaxView.qml b/examples/declarative/parallax/ParallaxView.qml
index bad9b85..50ab72c 100644
--- a/examples/declarative/parallax/ParallaxView.qml
+++ b/examples/declarative/parallax/ParallaxView.qml
@@ -25,7 +25,8 @@ Item {
anchors.fill: parent
model: VisualItemModel { id: visualModel }
- highlight: Item { height: 1; width: 1}
+ highlight: Rectangle { height: 1; width: 1 }
+ highlightMoveSpeed: 2000
preferredHighlightBegin: 0
preferredHighlightEnd: 0
highlightRangeMode: "StrictlyEnforceRange"
diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp
index 92e79dd..659193d 100644
--- a/src/declarative/fx/qfxflickable.cpp
+++ b/src/declarative/fx/qfxflickable.cpp
@@ -57,6 +57,8 @@ QT_BEGIN_NAMESPACE
static const int DragThreshold = 8;
static const int FlickThreshold = 20;
+// Really slow flicks can be annoying.
+static const int minimumFlickVelocity = 200;
class QFxFlickableVisibleArea : public QObject
{
@@ -183,6 +185,8 @@ void QFxFlickablePrivate::flickX(qreal velocity)
{
Q_Q(QFxFlickable);
qreal maxDistance = -1;
+ if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks.
+ velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity;
// -ve velocity means list is moving up
if (velocity > 0) {
if (_moveX.value() < q->minXExtent())
@@ -686,8 +690,8 @@ void QFxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event)
if (rejectX) velocityX = 0;
if (moved) {
- q->viewportMoved();
q->movementStarting();
+ q->viewportMoved();
}
lastPos = event->pos();
@@ -707,15 +711,23 @@ void QFxFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *even
}
vTime = timeline.time();
- if (qAbs(velocityY) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold)
- flickY(velocityY);
- else
+ if (qAbs(velocityY) > 10 && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) {
+ qreal velocity = velocityY;
+ if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks.
+ velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity;
+ flickY(velocity);
+ } else {
fixupY();
+ }
- if (qAbs(velocityX) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold)
- flickX(velocityX);
- else
+ if (qAbs(velocityX) > 10 && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) {
+ qreal velocity = velocityX;
+ if (qAbs(velocity) < minimumFlickVelocity) // Minimum velocity to avoid annoyingly slow flicks.
+ velocity = velocity < 0 ? -minimumFlickVelocity : minimumFlickVelocity;
+ flickX(velocity);
+ } else {
fixupX();
+ }
stealMouse = false;
lastPosTime = QTime();
diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp
index fbb91b1..e970ddd 100644
--- a/src/declarative/fx/qfxlistview.cpp
+++ b/src/declarative/fx/qfxlistview.cpp
@@ -691,8 +691,7 @@ void QFxListViewPrivate::updateHighlight()
{
if ((!currentItem && highlight) || (currentItem && !highlight))
createHighlight();
- updateTrackedItem();
- if (currentItem && autoHighlight && highlight && !pressed && moveReason != QFxListViewPrivate::Mouse) {
+ if (currentItem && autoHighlight && highlight && !moving) {
// auto-update highlight
highlightPosAnimator->setSourceValue(currentItem->position());
highlightSizeAnimator->setSourceValue(currentItem->size());
@@ -704,6 +703,7 @@ void QFxListViewPrivate::updateHighlight()
highlight->item->setHeight(currentItem->item->height());
}
}
+ updateTrackedItem();
}
void QFxListViewPrivate::updateSections()
@@ -832,8 +832,10 @@ void QFxListViewPrivate::flickX(qreal velocity)
{
Q_Q(QFxListView);
- if (!haveHighlightRange || highlightRange != QFxListView::StrictlyEnforceRange)
+ if (!haveHighlightRange || highlightRange != QFxListView::StrictlyEnforceRange) {
QFxFlickablePrivate::flickX(velocity);
+ return;
+ }
qreal maxDistance = -1;
// -ve velocity means list is moving up
@@ -855,19 +857,20 @@ void QFxListViewPrivate::flickX(qreal velocity)
v = maxVelocity;
}
qreal accel = deceleration;
- qreal maxAccel = (v * v) / (2.0f * maxDistance);
+ qreal v2 = v * v;
+ qreal maxAccel = v2 / (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;
+ qreal dist = v2 / accel / 2.0;
if (v > 0)
dist = -dist;
- dist = -_moveX.value() - snapPosAt(-_moveX.value() + dist + highlightRangeStart);
+ dist = -_moveX.value() - snapPosAt(-(_moveX.value() - highlightRangeStart) + dist) + highlightRangeStart;
if (v < 0 && dist >= 0 || v > 0 && dist <= 0) {
timeline.reset(_moveX);
fixupX();
return;
}
- accel = (v * v) / (2.0f * qAbs(dist));
+ accel = v2 / (2.0f * qAbs(dist));
}
timeline.reset(_moveX);
timeline.accel(_moveX, v, accel, maxDistance);
@@ -885,7 +888,60 @@ void QFxListViewPrivate::flickX(qreal velocity)
void QFxListViewPrivate::flickY(qreal velocity)
{
- QFxFlickablePrivate::flickY(velocity);
+ Q_Q(QFxListView);
+
+ if (!haveHighlightRange || highlightRange != QFxListView::StrictlyEnforceRange) {
+ QFxFlickablePrivate::flickY(velocity);
+ return;
+ }
+
+ qreal maxDistance = -1;
+ // -ve velocity means list is moving up
+ if (velocity > 0) {
+ if (_moveY.value() < q->minYExtent())
+ maxDistance = qAbs(q->minYExtent() -_moveY.value() + (overShoot?30:0));
+ flickTargetY = q->minYExtent();
+ } else {
+ if (_moveY.value() > q->maxYExtent())
+ maxDistance = qAbs(q->maxYExtent() - _moveY.value()) + (overShoot?30:0);
+ flickTargetY = q->maxYExtent();
+ }
+ if (maxDistance > 0) {
+ qreal v = velocity;
+ if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
+ if (v < 0)
+ v = -maxVelocity;
+ else
+ v = maxVelocity;
+ }
+ qreal accel = deceleration;
+ qreal v2 = v * v;
+ qreal maxAccel = v2 / (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 = v2 / accel / 2.0;
+ if (v > 0)
+ dist = -dist;
+ dist = -_moveY.value() - snapPosAt(-(_moveY.value() - highlightRangeStart) + dist) + highlightRangeStart;
+ if (v < 0 && dist >= 0 || v > 0 && dist <= 0) {
+ timeline.reset(_moveY);
+ fixupY();
+ return;
+ }
+ accel = v2 / (2.0f * qAbs(dist));
+ }
+ timeline.reset(_moveY);
+ timeline.accel(_moveY, v, accel, maxDistance);
+ timeline.execute(fixupYEvent);
+ if (!flicked) {
+ flicked = true;
+ emit q->flickingChanged();
+ emit q->flickStarted();
+ }
+ } else {
+ timeline.reset(_moveY);
+ fixupY();
+ }
}
//----------------------------------------------------------------------------
@@ -1185,6 +1241,10 @@ void QFxListView::setHighlight(QmlComponent *highlight)
\snippet doc/src/snippets/declarative/listview/highlight.qml 1
+ Note that the highlight animation also affects the way that the view
+ is scrolled. This is because the view moves to maintain the
+ highlight within the preferred highlight range (or visible viewport).
+
\sa highlight
*/
bool QFxListView::highlightFollowsCurrentItem() const
@@ -1445,7 +1505,7 @@ void QFxListView::viewportMoved()
Q_D(QFxListView);
QFxFlickable::viewportMoved();
refill();
- if (isFlicking() || d->pressed)
+ if (isFlicking() || d->moving)
d->moveReason = QFxListViewPrivate::Mouse;
if (d->moveReason == QFxListViewPrivate::Mouse) {
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
@@ -1606,7 +1666,7 @@ void QFxListView::trackedPositionChanged()
Q_D(QFxListView);
if (!d->trackedItem)
return;
- if (!isFlicking() && !d->pressed && d->moveReason != QFxListViewPrivate::Mouse) {
+ if (!isFlicking() && !d->moving && d->moveReason != QFxListViewPrivate::Mouse) {
const qreal trackedPos = d->trackedItem->position();
if (d->haveHighlightRange) {
if (d->highlightRange == StrictlyEnforceRange) {