aboutsummaryrefslogtreecommitdiffstats
path: root/src/qtquick1
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2011-09-26 13:13:02 +1000
committerQt by Nokia <qt-info@nokia.com>2011-09-28 01:12:34 +0200
commit40864ee84e41d53c412dd1b350624dcde07b009a (patch)
treefbdf72cd3e01a408e54f025bd2a8d5fe375ec905 /src/qtquick1
parent6c0215a523b1294015e238018dc34cf56a46024c (diff)
Manually apply SnapOneItem/Row changes from Qt 4.7
Apply following changes to Qt 5 for both QtQuick1 and QtQuick2 items: cf23188de237009136fa1480ab8fd9e3ca364769 f85819fe083ae7c6804c884de68e906d153a6d11 09cd2f818208a83489fae034b80e6497b7cc83af Task-number: QTBUG-20683 Change-Id: I974764e57e3004514bb4c9f46c5152ad07c136a7 Reviewed-on: http://codereview.qt-project.org/5484 Reviewed-by: Bea Lam <bea.lam@nokia.com>
Diffstat (limited to 'src/qtquick1')
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativeflickable.cpp107
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h8
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativegridview.cpp114
-rw-r--r--src/qtquick1/graphicsitems/qdeclarativelistview.cpp150
4 files changed, 223 insertions, 156 deletions
diff --git a/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp b/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp
index 6fa92b3bfa..6a7f6ae246 100644
--- a/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativeflickable.cpp
@@ -170,9 +170,7 @@ QDeclarative1FlickablePrivate::QDeclarative1FlickablePrivate()
: contentItem(new QDeclarativeItem)
, hData(this, &QDeclarative1FlickablePrivate::setRoundedViewportX)
, vData(this, &QDeclarative1FlickablePrivate::setRoundedViewportY)
- , flickingHorizontally(false), flickingVertically(false)
, hMoved(false), vMoved(false)
- , movingHorizontally(false), movingVertically(false)
, stealMouse(false), pressed(false), interactive(true), calcVelocity(false)
, deceleration(QML_FLICK_DEFAULTDECELERATION)
, maxVelocity(QML_FLICK_DEFAULTMAXVELOCITY), reportedVelocitySmoothing(100)
@@ -296,18 +294,18 @@ void QDeclarative1FlickablePrivate::flick(AxisData &data, qreal minExtent, qreal
else
timeline.accel(data.move, v, deceleration, maxDistance);
timeline.callback(QDeclarative1TimeLineCallback(&data.move, fixupCallback, this));
- if (!flickingHorizontally && q->xflick()) {
- flickingHorizontally = true;
+ if (!hData.flicking && q->xflick()) {
+ hData.flicking = true;
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
- if (!flickingVertically)
+ if (!vData.flicking)
emit q->flickStarted();
}
- if (!flickingVertically && q->yflick()) {
- flickingVertically = true;
+ if (!vData.flicking && q->yflick()) {
+ vData.flicking = true;
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
- if (!flickingHorizontally)
+ if (!hData.flicking)
emit q->flickStarted();
}
} else {
@@ -617,11 +615,11 @@ void QDeclarative1Flickable::setInteractive(bool interactive)
Q_D(QDeclarative1Flickable);
if (interactive != d->interactive) {
d->interactive = interactive;
- if (!interactive && (d->flickingHorizontally || d->flickingVertically)) {
+ if (!interactive && (d->hData.flicking || d->vData.flicking)) {
d->timeline.clear();
d->vTime = d->timeline.time();
- d->flickingHorizontally = false;
- d->flickingVertically = false;
+ d->hData.flicking = false;
+ d->vData.flicking = false;
emit flickingChanged();
emit flickingHorizontallyChanged();
emit flickingVerticallyChanged();
@@ -774,8 +772,8 @@ void QDeclarative1FlickablePrivate::handleMousePressEvent(QGraphicsSceneMouseEve
pressPos = event->pos();
hData.pressPos = hData.move.value();
vData.pressPos = vData.move.value();
- flickingHorizontally = false;
- flickingVertically = false;
+ hData.flicking = false;
+ vData.flicking = false;
QDeclarativeItemPrivate::start(pressTime);
QDeclarativeItemPrivate::start(velocityTime);
}
@@ -900,17 +898,14 @@ void QDeclarative1FlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseE
return;
// if we drag then pause before release we should not cause a flick.
- if (QDeclarativeItemPrivate::elapsed(lastPosTime) < 100) {
- vData.updateVelocity();
- hData.updateVelocity();
- } else {
- hData.velocity = 0.0;
- vData.velocity = 0.0;
- }
+ qint64 elapsed = QDeclarativeItemPrivate::elapsed(lastPosTime);
+
+ vData.updateVelocity();
+ hData.updateVelocity();
vTime = timeline.time();
- qreal velocity = vData.velocity;
+ qreal velocity = elapsed < 100 ? vData.velocity : 0;
if (vData.atBeginning || vData.atEnd)
velocity /= 2;
if (q->yflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().y() - pressPos.y()) > FlickThreshold) {
@@ -921,7 +916,7 @@ void QDeclarative1FlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseE
fixupY();
}
- velocity = hData.velocity;
+ velocity = elapsed < 100 ? hData.velocity : 0;
if (hData.atBeginning || hData.atEnd)
velocity /= 2;
if (q->xflick() && qAbs(velocity) > MinimumFlickVelocity && qAbs(event->pos().x() - pressPos.x()) > FlickThreshold) {
@@ -987,9 +982,9 @@ void QDeclarative1Flickable::wheelEvent(QGraphicsSceneWheelEvent *event)
valid = true;
}
if (valid) {
- d->flickingVertically = false;
+ d->vData.flicking = false;
d->flickY(d->vData.velocity);
- if (d->flickingVertically) {
+ if (d->vData.flicking) {
d->vMoved = true;
movementStarting();
}
@@ -1005,9 +1000,9 @@ void QDeclarative1Flickable::wheelEvent(QGraphicsSceneWheelEvent *event)
valid = true;
}
if (valid) {
- d->flickingHorizontally = false;
+ d->hData.flicking = false;
d->flickX(d->hData.velocity);
- if (d->flickingHorizontally) {
+ if (d->hData.flicking) {
d->hMoved = true;
movementStarting();
}
@@ -1156,7 +1151,7 @@ void QDeclarative1Flickable::viewportMoved()
}
}
- if (!d->vData.inOvershoot && !d->vData.fixingUp && d->flickingVertically
+ 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()) > 100) {
// Increase deceleration if we've passed a bound
@@ -1166,7 +1161,7 @@ void QDeclarative1Flickable::viewportMoved()
d->timeline.accel(d->vData.move, -d->vData.smoothVelocity.value(), d->deceleration*QML_FLICK_OVERSHOOTFRICTION, maxDistance);
d->timeline.callback(QDeclarative1TimeLineCallback(&d->vData.move, d->fixupY_callback, d));
}
- if (!d->hData.inOvershoot && !d->hData.fixingUp && d->flickingHorizontally
+ 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()) > 100) {
// Increase deceleration if we've passed a bound
@@ -1198,7 +1193,7 @@ void QDeclarative1Flickable::geometryChanged(const QRectF &newGeometry,
emit contentWidthChanged();
}
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QDeclarative1FlickablePrivate::Immediate;
d->fixupX();
}
@@ -1211,7 +1206,7 @@ void QDeclarative1Flickable::geometryChanged(const QRectF &newGeometry,
emit contentHeightChanged();
}
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QDeclarative1FlickablePrivate::Immediate;
d->fixupY();
}
@@ -1366,7 +1361,7 @@ void QDeclarative1Flickable::setContentWidth(qreal w)
else
d->contentItem->setWidth(w);
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QDeclarative1FlickablePrivate::Immediate;
d->fixupX();
} else if (!d->pressed && d->hData.fixingUp) {
@@ -1394,7 +1389,7 @@ void QDeclarative1Flickable::setContentHeight(qreal h)
else
d->contentItem->setHeight(h);
// Make sure that we're entirely in view.
- if (!d->pressed && !d->movingHorizontally && !d->movingVertically) {
+ if (!d->pressed && !d->hData.moving && !d->vData.moving) {
d->fixupMode = QDeclarative1FlickablePrivate::Immediate;
d->fixupY();
} else if (!d->pressed && d->vData.fixingUp) {
@@ -1651,7 +1646,7 @@ void QDeclarative1Flickable::setFlickDeceleration(qreal deceleration)
bool QDeclarative1Flickable::isFlicking() const
{
Q_D(const QDeclarative1Flickable);
- return d->flickingHorizontally || d->flickingVertically;
+ return d->hData.flicking || d->vData.flicking;
}
/*!
@@ -1665,13 +1660,13 @@ bool QDeclarative1Flickable::isFlicking() const
bool QDeclarative1Flickable::isFlickingHorizontally() const
{
Q_D(const QDeclarative1Flickable);
- return d->flickingHorizontally;
+ return d->hData.flicking;
}
bool QDeclarative1Flickable::isFlickingVertically() const
{
Q_D(const QDeclarative1Flickable);
- return d->flickingVertically;
+ return d->vData.flicking;
}
/*!
@@ -1707,7 +1702,7 @@ void QDeclarative1Flickable::setPressDelay(int delay)
bool QDeclarative1Flickable::isMoving() const
{
Q_D(const QDeclarative1Flickable);
- return d->movingHorizontally || d->movingVertically;
+ return d->hData.moving || d->vData.moving;
}
/*!
@@ -1722,30 +1717,30 @@ bool QDeclarative1Flickable::isMoving() const
bool QDeclarative1Flickable::isMovingHorizontally() const
{
Q_D(const QDeclarative1Flickable);
- return d->movingHorizontally;
+ return d->hData.moving;
}
bool QDeclarative1Flickable::isMovingVertically() const
{
Q_D(const QDeclarative1Flickable);
- return d->movingVertically;
+ return d->vData.moving;
}
void QDeclarative1Flickable::movementStarting()
{
Q_D(QDeclarative1Flickable);
- if (d->hMoved && !d->movingHorizontally) {
- d->movingHorizontally = true;
+ if (d->hMoved && !d->hData.moving) {
+ d->hData.moving = true;
emit movingChanged();
emit movingHorizontallyChanged();
- if (!d->movingVertically)
+ if (!d->vData.moving)
emit movementStarted();
}
- else if (d->vMoved && !d->movingVertically) {
- d->movingVertically = true;
+ else if (d->vMoved && !d->vData.moving) {
+ d->vData.moving = true;
emit movingChanged();
emit movingVerticallyChanged();
- if (!d->movingHorizontally)
+ if (!d->hData.moving)
emit movementStarted();
}
}
@@ -1762,20 +1757,20 @@ void QDeclarative1Flickable::movementEnding()
void QDeclarative1Flickable::movementXEnding()
{
Q_D(QDeclarative1Flickable);
- if (d->flickingHorizontally) {
- d->flickingHorizontally = false;
+ if (d->hData.flicking) {
+ d->hData.flicking = false;
emit flickingChanged();
emit flickingHorizontallyChanged();
- if (!d->flickingVertically)
+ if (!d->vData.flicking)
emit flickEnded();
}
if (!d->pressed && !d->stealMouse) {
- if (d->movingHorizontally) {
- d->movingHorizontally = false;
+ if (d->hData.moving) {
+ d->hData.moving = false;
d->hMoved = false;
emit movingChanged();
emit movingHorizontallyChanged();
- if (!d->movingVertically)
+ if (!d->vData.moving)
emit movementEnded();
}
}
@@ -1785,20 +1780,20 @@ void QDeclarative1Flickable::movementXEnding()
void QDeclarative1Flickable::movementYEnding()
{
Q_D(QDeclarative1Flickable);
- if (d->flickingVertically) {
- d->flickingVertically = false;
+ if (d->vData.flicking) {
+ d->vData.flicking = false;
emit flickingChanged();
emit flickingVerticallyChanged();
- if (!d->flickingHorizontally)
+ if (!d->hData.flicking)
emit flickEnded();
}
if (!d->pressed && !d->stealMouse) {
- if (d->movingVertically) {
- d->movingVertically = false;
+ if (d->vData.moving) {
+ d->vData.moving = false;
d->vMoved = false;
emit movingChanged();
emit movingVerticallyChanged();
- if (!d->movingHorizontally)
+ if (!d->hData.moving)
emit movementEnded();
}
}
diff --git a/src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h b/src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h
index 5bbeb27c9e..c76da83da0 100644
--- a/src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h
+++ b/src/qtquick1/graphicsitems/qdeclarativeflickable_p_p.h
@@ -94,7 +94,7 @@ public:
struct AxisData {
AxisData(QDeclarative1FlickablePrivate *fp, void (QDeclarative1FlickablePrivate::*func)(qreal))
: move(fp, func), viewSize(-1), smoothVelocity(fp), atEnd(false), atBeginning(true)
- , fixingUp(false), inOvershoot(false)
+ , fixingUp(false), inOvershoot(false), moving(false), flicking(false)
{}
void reset() {
@@ -121,6 +121,8 @@ public:
bool atBeginning : 1;
bool fixingUp : 1;
bool inOvershoot : 1;
+ bool moving : 1;
+ bool flicking : 1;
};
void flickX(qreal velocity);
@@ -152,12 +154,8 @@ public:
AxisData vData;
QDeclarative1TimeLine timeline;
- bool flickingHorizontally : 1;
- bool flickingVertically : 1;
bool hMoved : 1;
bool vMoved : 1;
- bool movingHorizontally : 1;
- bool movingVertically : 1;
bool stealMouse : 1;
bool pressed : 1;
bool interactive : 1;
diff --git a/src/qtquick1/graphicsitems/qdeclarativegridview.cpp b/src/qtquick1/graphicsitems/qdeclarativegridview.cpp
index f2511a15c9..feabbf0387 100644
--- a/src/qtquick1/graphicsitems/qdeclarativegridview.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativegridview.cpp
@@ -51,11 +51,13 @@
#include <qmath.h>
#include <math.h>
+#include "qplatformdefs.h"
QT_BEGIN_NAMESPACE
-
-
+#ifndef QML_FLICK_SNAPONETHRESHOLD
+#define QML_FLICK_SNAPONETHRESHOLD 30
+#endif
//----------------------------------------------------------------------------
@@ -346,9 +348,12 @@ public:
Q_Q(const QDeclarative1GridView);
qreal snapPos = 0;
if (!visibleItems.isEmpty()) {
+ qreal highlightStart = isRightToLeftTopToBottom() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
+ pos += highlightStart;
pos += rowSize()/2;
snapPos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize();
snapPos = pos - fmodf(pos - snapPos, qreal(rowSize()));
+ snapPos -= highlightStart;
qreal maxExtent;
qreal minExtent;
if (isRightToLeftTopToBottom()) {
@@ -876,7 +881,7 @@ void QDeclarative1GridViewPrivate::updateHighlight()
{
if ((!currentItem && highlight) || (currentItem && !highlight))
createHighlight();
- if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) {
+ if (currentItem && autoHighlight && highlight && !hData.moving && !vData.moving) {
// auto-update highlight
highlightXAnimator->to = currentItem->item->x();
highlightYAnimator->to = currentItem->item->y();
@@ -1061,12 +1066,36 @@ void QDeclarative1GridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
highlightEnd = highlightRangeEnd;
}
+ bool strictHighlightRange = haveHighlightRange && highlightRange == QDeclarative1GridView::StrictlyEnforceRange;
+
if (snapMode != QDeclarative1GridView::NoSnap) {
qreal tempPosition = isRightToLeftTopToBottom() ? -position()-size() : position();
+ if (snapMode == QDeclarative1GridView::SnapOneRow && moveReason == Mouse) {
+ // if we've been dragged < rowSize()/2 then bias towards the next row
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = 0;
+ if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < rowSize()/2)
+ bias = rowSize()/2;
+ else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -rowSize()/2)
+ bias = -rowSize()/2;
+ if (isRightToLeftTopToBottom())
+ bias = -bias;
+ tempPosition -= bias;
+ }
FxGridItem1 *topItem = snapItemAt(tempPosition+highlightStart);
+ if (!topItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ topItem = currentItem;
+ }
FxGridItem1 *bottomItem = snapItemAt(tempPosition+highlightEnd);
+ if (!bottomItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ bottomItem = currentItem;
+ }
qreal pos;
- if (topItem && bottomItem && haveHighlightRange && highlightRange == QDeclarative1GridView::StrictlyEnforceRange) {
+ if (topItem && bottomItem && strictHighlightRange) {
qreal topPos = qMin(topItem->rowPos() - highlightStart, -maxExtent);
qreal bottomPos = qMax(bottomItem->rowPos() - highlightEnd, -minExtent);
pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos;
@@ -1074,7 +1103,7 @@ void QDeclarative1GridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
qreal headerPos = 0;
if (header)
headerPos = isRightToLeftTopToBottom() ? header->rowPos() + cellWidth - headerSize() : header->rowPos();
- if (topItem->index == 0 && header && tempPosition+highlightStart < headerPos+headerSize()/2) {
+ if (topItem->index == 0 && header && tempPosition+highlightStart < headerPos+headerSize()/2 && !strictHighlightRange) {
pos = isRightToLeftTopToBottom() ? - headerPos + highlightStart - size() : headerPos - highlightStart;
} else {
if (isRightToLeftTopToBottom())
@@ -1084,25 +1113,13 @@ void QDeclarative1GridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
}
} else if (bottomItem) {
if (isRightToLeftTopToBottom())
- pos = qMax(qMin(-bottomItem->rowPos() + highlightStart - size(), -maxExtent), -minExtent);
+ pos = qMax(qMin(-bottomItem->rowPos() + highlightEnd - size(), -maxExtent), -minExtent);
else
- pos = qMax(qMin(bottomItem->rowPos() - highlightStart, -maxExtent), -minExtent);
+ pos = qMax(qMin(bottomItem->rowPos() - highlightEnd, -maxExtent), -minExtent);
} else {
QDeclarative1FlickablePrivate::fixup(data, minExtent, maxExtent);
return;
}
- if (currentItem && haveHighlightRange && highlightRange == QDeclarative1GridView::StrictlyEnforceRange) {
- updateHighlight();
- qreal currPos = currentItem->rowPos();
- if (isRightToLeftTopToBottom())
- pos = -pos-size(); // Transform Pos if required
- if (pos < currPos + rowSize() - highlightEnd)
- pos = currPos + rowSize() - highlightEnd;
- if (pos > currPos - highlightStart)
- pos = currPos - highlightStart;
- if (isRightToLeftTopToBottom())
- pos = -pos-size(); // Untransform
- }
qreal dist = qAbs(data.move + pos);
if (dist > 0) {
timeline.reset(data.move);
@@ -1159,9 +1176,14 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
if (velocity > 0) {
if (data.move.value() < minExtent) {
if (snapMode == QDeclarative1GridView::SnapOneRow) {
- if (FxGridItem1 *item = firstVisibleItem()) {
- maxDistance = qAbs(item->rowPos() + dataValue);
- }
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = dist < rowSize()/2 ? rowSize()/2 : 0;
+ if (isRightToLeftTopToBottom())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-dataValue - bias);
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = maxVelocity;
} else {
maxDistance = qAbs(minExtent - data.move.value());
}
@@ -1171,8 +1193,14 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
} else {
if (data.move.value() > maxExtent) {
if (snapMode == QDeclarative1GridView::SnapOneRow) {
- qreal pos = snapPosAt(-dataValue) + (isRightToLeftTopToBottom() ? 0 : rowSize());
- maxDistance = qAbs(pos + dataValue);
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = -dist < rowSize()/2 ? rowSize()/2 : 0;
+ if (isRightToLeftTopToBottom())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-dataValue + bias);
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = -maxVelocity;
} else {
maxDistance = qAbs(maxExtent - data.move.value());
}
@@ -1182,7 +1210,6 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
}
bool overShoot = boundsBehavior == QDeclarative1Flickable::DragAndOvershootBounds;
- qreal highlightStart = isRightToLeftTopToBottom() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
if (maxDistance > 0 || overShoot) {
// This mode requires the grid to stop exactly on a row boundary.
@@ -1202,9 +1229,20 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
dist = qMin(dist, maxDistance);
if (v > 0)
dist = -dist;
- qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist;
- data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart;
+ if (snapMode != QDeclarative1GridView::SnapOneRow) {
+ qreal distTemp = isRightToLeftTopToBottom() ? -dist : dist;
+ data.flickTarget = -snapPosAt(-dataValue + distTemp);
+ }
data.flickTarget = isRightToLeftTopToBottom() ? -data.flickTarget+size() : data.flickTarget;
+ if (overShoot) {
+ if (data.flickTarget >= minExtent) {
+ overshootDist = overShootDistance(vSize);
+ data.flickTarget += overshootDist;
+ } else if (data.flickTarget <= maxExtent) {
+ overshootDist = overShootDistance(vSize);
+ data.flickTarget -= overshootDist;
+ }
+ }
qreal adjDist = -data.flickTarget + data.move.value();
if (qAbs(adjDist) > qAbs(dist)) {
// Prevent painfully slow flicking - adjust velocity to suit flickDeceleration
@@ -1225,14 +1263,14 @@ void QDeclarative1GridViewPrivate::flick(AxisData &data, qreal minExtent, qreal
timeline.reset(data.move);
timeline.accel(data.move, v, accel, maxDistance + overshootDist);
timeline.callback(QDeclarative1TimeLineCallback(&data.move, fixupCallback, this));
- if (!flickingHorizontally && q->xflick()) {
- flickingHorizontally = true;
+ if (!hData.flicking && q->xflick()) {
+ hData.flicking = true;
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
emit q->flickStarted();
}
- if (!flickingVertically && q->yflick()) {
- flickingVertically = true;
+ if (!vData.flicking && q->yflick()) {
+ vData.flicking = true;
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
emit q->flickStarted();
@@ -1557,6 +1595,8 @@ void QDeclarative1GridView::setCurrentIndex(int index)
if (index == d->currentIndex)
return;
if (isComponentComplete() && d->isValid()) {
+ if (d->layoutScheduled)
+ d->layout();
d->moveReason = QDeclarative1GridViewPrivate::SetIndex;
d->updateCurrent(index);
} else {
@@ -2110,7 +2150,8 @@ bool QDeclarative1GridView::event(QEvent *event)
{
Q_D(QDeclarative1GridView);
if (event->type() == QEvent::User) {
- d->layout();
+ if (d->layoutScheduled)
+ d->layout();
return true;
}
@@ -2124,7 +2165,7 @@ void QDeclarative1GridView::viewportMoved()
if (!d->itemCount)
return;
d->lazyRelease = true;
- if (d->flickingHorizontally || d->flickingVertically) {
+ if (d->hData.flicking || d->vData.flicking) {
if (yflick()) {
if (d->vData.velocity > 0)
d->bufferMode = QDeclarative1GridViewPrivate::BufferBefore;
@@ -2140,7 +2181,7 @@ void QDeclarative1GridView::viewportMoved()
}
}
refill();
- if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically)
+ if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
d->moveReason = QDeclarative1GridViewPrivate::Mouse;
if (d->moveReason != QDeclarative1GridViewPrivate::SetIndex) {
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
@@ -2928,6 +2969,11 @@ void QDeclarative1GridView::itemsRemoved(int modelIndex, int count)
}
}
+ // If we removed items before visible items a layout may be
+ // required to ensure item 0 is in the first column.
+ if (!removedVisible && modelIndex < d->visibleIndex)
+ d->scheduleLayout();
+
// fix current
if (d->currentIndex >= modelIndex + count) {
d->currentIndex -= count;
diff --git a/src/qtquick1/graphicsitems/qdeclarativelistview.cpp b/src/qtquick1/graphicsitems/qdeclarativelistview.cpp
index 5119c0e1fb..7b9cb12e90 100644
--- a/src/qtquick1/graphicsitems/qdeclarativelistview.cpp
+++ b/src/qtquick1/graphicsitems/qdeclarativelistview.cpp
@@ -52,10 +52,13 @@
#include <qmath.h>
#include <QKeyEvent>
+#include "qplatformdefs.h"
QT_BEGIN_NAMESPACE
-
+#ifndef QML_FLICK_SNAPONETHRESHOLD
+#define QML_FLICK_SNAPONETHRESHOLD 30
+#endif
void QDeclarative1ViewSection::setProperty(const QString &property)
{
@@ -235,21 +238,6 @@ public:
return visibleItems.count() ? visibleItems.first() : 0;
}
- FxListItem1 *nextVisibleItem() const {
- const qreal pos = isRightToLeft() ? -position()-size() : position();
- bool foundFirst = false;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxListItem1 *item = visibleItems.at(i);
- if (item->index != -1) {
- if (foundFirst)
- return item;
- else if (item->position() < pos && item->endPosition() > pos)
- foundFirst = true;
- }
- }
- return 0;
- }
-
// Returns the item before modelIndex, if created.
// May return an item marked for removal.
FxListItem1 *itemBefore(int modelIndex) const {
@@ -1013,7 +1001,7 @@ void QDeclarative1ListViewPrivate::updateHighlight()
{
if ((!currentItem && highlight) || (currentItem && !highlight))
createHighlight();
- if (currentItem && autoHighlight && highlight && !movingHorizontally && !movingVertically) {
+ if (currentItem && autoHighlight && highlight && !hData.moving && !vData.moving) {
// auto-update highlight
highlightPosAnimator->to = isRightToLeft()
? -currentItem->itemPosition()-currentItem->itemSize()
@@ -1308,6 +1296,7 @@ void QDeclarative1ListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
correctFlick = false;
fixupMode = moveReason == Mouse ? fixupMode : Immediate;
+ bool strictHighlightRange = haveHighlightRange && highlightRange == QDeclarative1ListView::StrictlyEnforceRange;
qreal highlightStart;
qreal highlightEnd;
@@ -1323,35 +1312,36 @@ void QDeclarative1ListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
highlightEnd = highlightRangeEnd;
}
- if (currentItem && haveHighlightRange && highlightRange == QDeclarative1ListView::StrictlyEnforceRange
- && moveReason != QDeclarative1ListViewPrivate::SetIndex) {
- updateHighlight();
- qreal pos = currentItem->itemPosition();
- if (viewPos < pos + currentItem->itemSize() - highlightEnd)
- viewPos = pos + currentItem->itemSize() - highlightEnd;
- if (viewPos > pos - highlightStart)
- viewPos = pos - highlightStart;
- if (isRightToLeft())
- viewPos = -viewPos-size();
-
- timeline.reset(data.move);
- if (viewPos != position()) {
- if (fixupMode != Immediate) {
- timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
- data.fixingUp = true;
- } else {
- timeline.set(data.move, -viewPos);
- }
- }
- vTime = timeline.time();
- } else if (snapMode != QDeclarative1ListView::NoSnap && moveReason != QDeclarative1ListViewPrivate::SetIndex) {
+ if (snapMode != QDeclarative1ListView::NoSnap && moveReason != QDeclarative1ListViewPrivate::SetIndex) {
qreal tempPosition = isRightToLeft() ? -position()-size() : position();
+ if (snapMode == QDeclarative1ListView::SnapOneItem && moveReason == Mouse) {
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = 0;
+ if (data.velocity > 0 && dist > QML_FLICK_SNAPONETHRESHOLD && dist < averageSize/2)
+ bias = averageSize/2;
+ else if (data.velocity < 0 && dist < -QML_FLICK_SNAPONETHRESHOLD && dist > -averageSize/2)
+ bias = -averageSize/2;
+ if (isRightToLeft())
+ bias = -bias;
+ tempPosition -= bias;
+ }
FxListItem1 *topItem = snapItemAt(tempPosition+highlightStart);
+ if (!topItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ topItem = currentItem;
+ }
FxListItem1 *bottomItem = snapItemAt(tempPosition+highlightEnd);
+ if (!bottomItem && strictHighlightRange && currentItem) {
+ // StrictlyEnforceRange always keeps an item in range
+ updateHighlight();
+ bottomItem = currentItem;
+ }
qreal pos;
- bool isInBounds = -position() > maxExtent && -position() < minExtent;
- if (topItem && isInBounds) {
- if (topItem->index == 0 && header && tempPosition+highlightStart < header->position()+header->size()/2) {
+ bool isInBounds = -position() > maxExtent && -position() <= minExtent;
+ if (topItem && (isInBounds || strictHighlightRange)) {
+ if (topItem->index == 0 && header && tempPosition+highlightStart < header->position()+header->size()/2 && !strictHighlightRange) {
pos = isRightToLeft() ? - header->position() + highlightStart - size() : header->position() - highlightStart;
} else {
if (isRightToLeft())
@@ -1361,9 +1351,9 @@ void QDeclarative1ListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
}
} else if (bottomItem && isInBounds) {
if (isRightToLeft())
- pos = qMax(qMin(-bottomItem->position() + highlightStart - size(), -maxExtent), -minExtent);
+ pos = qMax(qMin(-bottomItem->position() + highlightEnd - size(), -maxExtent), -minExtent);
else
- pos = qMax(qMin(bottomItem->position() - highlightStart, -maxExtent), -minExtent);
+ pos = qMax(qMin(bottomItem->position() - highlightEnd, -maxExtent), -minExtent);
} else {
QDeclarative1FlickablePrivate::fixup(data, minExtent, maxExtent);
return;
@@ -1380,6 +1370,27 @@ void QDeclarative1ListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal
}
vTime = timeline.time();
}
+ } else if (currentItem && strictHighlightRange
+ && moveReason != QDeclarative1ListViewPrivate::SetIndex) {
+ updateHighlight();
+ qreal pos = currentItem->itemPosition();
+ if (viewPos < pos + currentItem->itemSize() - highlightEnd)
+ viewPos = pos + currentItem->itemSize() - highlightEnd;
+ if (viewPos > pos - highlightStart)
+ viewPos = pos - highlightStart;
+ if (isRightToLeft())
+ viewPos = -viewPos-size();
+
+ timeline.reset(data.move);
+ if (viewPos != position()) {
+ if (fixupMode != Immediate) {
+ timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
+ data.fixingUp = true;
+ } else {
+ timeline.set(data.move, -viewPos);
+ }
+ }
+ vTime = timeline.time();
} else {
QDeclarative1FlickablePrivate::fixup(data, minExtent, maxExtent);
}
@@ -1401,12 +1412,19 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
}
qreal maxDistance = 0;
qreal dataValue = isRightToLeft() ? -data.move.value()+size() : data.move.value();
+ qreal highlightStart = isRightToLeft() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
// -ve velocity means list is moving up/left
if (velocity > 0) {
if (data.move.value() < minExtent) {
- if (snapMode == QDeclarative1ListView::SnapOneItem) {
- if (FxListItem1 *item = isRightToLeft() ? nextVisibleItem() : firstVisibleItem())
- maxDistance = qAbs(item->position() + dataValue);
+ if (snapMode == QDeclarative1ListView::SnapOneItem && !hData.flicking && !vData.flicking) {
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = dist < averageSize/2 ? averageSize/2 : 0;
+ if (isRightToLeft())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-(dataValue - highlightStart) - bias) + highlightStart;
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = maxVelocity;
} else {
maxDistance = qAbs(minExtent - data.move.value());
}
@@ -1415,9 +1433,15 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
data.flickTarget = minExtent;
} else {
if (data.move.value() > maxExtent) {
- if (snapMode == QDeclarative1ListView::SnapOneItem) {
- if (FxListItem1 *item = isRightToLeft() ? firstVisibleItem() : nextVisibleItem())
- maxDistance = qAbs(item->position() + dataValue);
+ if (snapMode == QDeclarative1ListView::SnapOneItem && !hData.flicking && !vData.flicking) {
+ // if we've been dragged < averageSize/2 then bias towards the next item
+ qreal dist = data.move.value() - (data.pressPos - data.dragStartOffset);
+ qreal bias = -dist < averageSize/2 ? averageSize/2 : 0;
+ if (isRightToLeft())
+ bias = -bias;
+ data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + bias) + highlightStart;
+ maxDistance = qAbs(data.flickTarget - data.move.value());
+ velocity = -maxVelocity;
} else {
maxDistance = qAbs(maxExtent - data.move.value());
}
@@ -1427,7 +1451,6 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
}
bool overShoot = boundsBehavior == QDeclarative1Flickable::DragAndOvershootBounds;
- qreal highlightStart = isRightToLeft() && highlightRangeStartValid ? size()-highlightRangeEnd : highlightRangeStart;
if (maxDistance > 0 || overShoot) {
// These modes require the list to stop exactly on an item boundary.
@@ -1441,7 +1464,7 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
else
v = maxVelocity;
}
- if (!flickingHorizontally && !flickingVertically) {
+ if (!hData.flicking && !vData.flicking) {
// the initial flick - estimate boundary
qreal accel = deceleration;
qreal v2 = v * v;
@@ -1453,8 +1476,10 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
if (v > 0)
dist = -dist;
if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarative1ListView::SnapOneItem) {
- qreal distTemp = isRightToLeft() ? -dist : dist;
- data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart;
+ if (snapMode != QDeclarative1ListView::SnapOneItem) {
+ qreal distTemp = isRightToLeft() ? -dist : dist;
+ data.flickTarget = -snapPosAt(-(dataValue - highlightStart) + distTemp) + highlightStart;
+ }
data.flickTarget = isRightToLeft() ? -data.flickTarget+size() : data.flickTarget;
if (overShoot) {
if (data.flickTarget >= minExtent) {
@@ -1492,14 +1517,14 @@ void QDeclarative1ListViewPrivate::flick(AxisData &data, qreal minExtent, qreal
timeline.reset(data.move);
timeline.accel(data.move, v, accel, maxDistance + overshootDist);
timeline.callback(QDeclarative1TimeLineCallback(&data.move, fixupCallback, this));
- if (!flickingHorizontally && q->xflick()) {
- flickingHorizontally = true;
+ if (!hData.flicking && q->xflick()) {
+ hData.flicking = true;
emit q->flickingChanged();
emit q->flickingHorizontallyChanged();
emit q->flickStarted();
}
- if (!flickingVertically && q->yflick()) {
- flickingVertically = true;
+ if (!vData.flicking && q->yflick()) {
+ vData.flicking = true;
emit q->flickingChanged();
emit q->flickingVerticallyChanged();
emit q->flickStarted();
@@ -1876,6 +1901,8 @@ void QDeclarative1ListView::setCurrentIndex(int index)
if (index == d->currentIndex)
return;
if (isComponentComplete() && d->isValid()) {
+ if (d->layoutScheduled)
+ d->layout();
d->moveReason = QDeclarative1ListViewPrivate::SetIndex;
d->updateCurrent(index);
} else if (d->currentIndex != index) {
@@ -2568,7 +2595,8 @@ bool QDeclarative1ListView::event(QEvent *event)
{
Q_D(QDeclarative1ListView);
if (event->type() == QEvent::User) {
- d->layout();
+ if (d->layoutScheduled)
+ d->layout();
return true;
}
@@ -2587,7 +2615,7 @@ void QDeclarative1ListView::viewportMoved()
d->inViewportMoved = true;
d->lazyRelease = true;
refill();
- if (d->flickingHorizontally || d->flickingVertically || d->movingHorizontally || d->movingVertically)
+ if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
d->moveReason = QDeclarative1ListViewPrivate::Mouse;
if (d->moveReason != QDeclarative1ListViewPrivate::SetIndex) {
if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
@@ -2621,7 +2649,7 @@ void QDeclarative1ListView::viewportMoved()
}
}
- if ((d->flickingHorizontally || d->flickingVertically) && d->correctFlick && !d->inFlickCorrection) {
+ if ((d->hData.flicking || d->vData.flicking) && d->correctFlick && !d->inFlickCorrection) {
d->inFlickCorrection = true;
// Near an end and it seems that the extent has changed?
// Recalculate the flick so that we don't end up in an odd position.