diff options
Diffstat (limited to 'src/qtquick1/graphicsitems/qdeclarativegridview.cpp')
-rw-r--r-- | src/qtquick1/graphicsitems/qdeclarativegridview.cpp | 114 |
1 files changed, 80 insertions, 34 deletions
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; |