279 if (FxViewItem *item = visibleItem(modelIndex))
280 return static_cast<FxGridItemSG*>(item)->colPos();
281 if (!visibleItems.isEmpty()) {
282 if (modelIndex == visibleIndex) {
283 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.first());
284 return firstItem->colPos();
285 }
else if (modelIndex < visibleIndex) {
286 int count = (visibleIndex - modelIndex) % columns;
287 int col =
static_cast<FxGridItemSG*>(visibleItems.first())->colPos() / colSize();
289 return col * colSize();
291 FxGridItemSG *lastItem =
static_cast<FxGridItemSG*>(visibleItems.last());
292 int count = modelIndex - lastItem->index;
293 int col = lastItem->colPos() / colSize();
295 return col * colSize();
298 return (modelIndex % columns) * colSize();
303 if (FxViewItem *item = visibleItem(modelIndex))
304 return static_cast<FxGridItemSG*>(item)->rowPos();
305 if (!visibleItems.isEmpty()) {
306 if (modelIndex == visibleIndex) {
307 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.first());
308 return firstItem->rowPos();
309 }
else if (modelIndex < visibleIndex) {
310 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.first());
311 int firstCol = firstItem->colPos() / colSize();
312 int col = visibleIndex - modelIndex + (columns - firstCol - 1);
314 return firstItem->rowPos() - rows * rowSize();
316 FxGridItemSG *lastItem =
static_cast<FxGridItemSG*>(visibleItems.last());
317 int count = modelIndex - lastItem->index;
318 int col = lastItem->colPos() + count * colSize();
319 int rows = col / (columns * colSize());
320 return lastItem->rowPos() + rows * rowSize();
324 qreal rowPos = ((modelIndex / columns) * rowSize());
326 if (flow == QQuickGridView::FlowLeftToRight && verticalLayoutDirection == QQuickItemView::TopToBottom) {
339 rowPos += qMax(vData.startMargin, highlightRangeStart) + headerSize();
468 qreal colPos = colPosAt(visibleIndex);
469 qreal rowPos = rowPosAt(visibleIndex);
470 if (visibleItems.size()) {
471 FxGridItemSG *lastItem =
static_cast<FxGridItemSG*>(visibleItems.constLast());
472 rowPos = lastItem->rowPos();
473 int colNum = qFloor((lastItem->colPos()+colSize()/2) / colSize());
478 colPos = colNum * colSize();
481 int modelIndex = findLastVisibleIndex();
482 modelIndex = modelIndex < 0 ? visibleIndex : modelIndex + 1;
484 if (visibleItems.size() && (bufferFrom > rowPos + rowSize()*2
485 || bufferTo < rowPosAt(visibleIndex) - rowSize())) {
488 int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
489 releaseVisibleItems(reusableFlag);
491 if (modelIndex >= model->count())
492 modelIndex = model->count() - 1;
493 else if (modelIndex < 0)
496 visibleIndex = modelIndex;
497 colPos = colPosAt(visibleIndex);
498 rowPos = rowPosAt(visibleIndex);
501 int colNum = qFloor((colPos+colSize()/2) / colSize());
502 FxGridItemSG *item =
nullptr;
503 bool changed =
false;
505 QQmlIncubator::IncubationMode incubationMode = doBuffer ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested;
507 while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) {
508 qCDebug(lcItemViewDelegateLifecycle) <<
"refill: append item" << modelIndex << colPos << rowPos;
509 if (!(item =
static_cast<FxGridItemSG*>(createItem(modelIndex, incubationMode))))
511#if QT_CONFIG(quick_viewtransitions)
512 if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition,
true))
513 item->setPosition(colPos, rowPos,
true);
515 QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
516 visibleItems.append(item);
521 colPos = colNum * colSize();
526 if (doBuffer && requestedIndex != -1)
530 if (visibleItems.size()) {
531 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.constFirst());
532 rowPos = firstItem->rowPos();
533 colPos = firstItem->colPos();
535 colNum = qFloor((colPos+colSize()/2) / colSize());
542 colPos = colNum * colSize();
543 while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){
544 qCDebug(lcItemViewDelegateLifecycle) <<
"refill: prepend item" << visibleIndex-1 <<
"top pos" << rowPos << colPos;
545 if (!(item =
static_cast<FxGridItemSG*>(createItem(visibleIndex-1, incubationMode))))
548#if QT_CONFIG(quick_viewtransitions)
549 if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition,
true))
550 item->setPosition(colPos, rowPos,
true);
552 QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
553 visibleItems.prepend(item);
558 colPos = colNum * colSize();
581 FxGridItemSG *item =
nullptr;
582 bool changed =
false;
584 while (visibleItems.size() > 1
585 && (item =
static_cast<FxGridItemSG*>(visibleItems.constFirst()))
586 && item->rowPos()+rowSize()-1 < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) {
587 if (item->attached->delayRemove())
589 qCDebug(lcItemViewDelegateLifecycle) <<
"refill: remove first" << visibleIndex <<
"top end pos" << item->endRowPos();
590 if (item->index != -1)
592 visibleItems.removeFirst();
596 while (visibleItems.size() > 1
597 && (item =
static_cast<FxGridItemSG*>(visibleItems.constLast()))
598 && item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) {
599 if (item->attached->delayRemove())
601 qCDebug(lcItemViewDelegateLifecycle) <<
"refill: remove last" << visibleIndex+visibleItems.size()-1;
602 visibleItems.removeLast();
618 if (visibleItems.size()) {
619 const qreal from = isContentFlowReversed() ? -position()-displayMarginBeginning-size() : position()-displayMarginBeginning;
620 const qreal to = isContentFlowReversed() ? -position()+displayMarginEnd : position()+size()+displayMarginEnd;
622 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.constFirst());
623 qreal rowPos = firstItem->rowPos();
624 qreal colPos = firstItem->colPos();
625 int col = visibleIndex % columns;
626 if (colPos != col * colSize()) {
627 colPos = col * colSize();
628 firstItem->setPosition(colPos, rowPos);
630 firstItem->setVisible(firstItem->rowPos() + rowSize() >= from && firstItem->rowPos() <= to);
631 for (
int i = 1; i < visibleItems.size(); ++i) {
632 FxGridItemSG *item =
static_cast<FxGridItemSG*>(visibleItems.at(i));
637 colPos = col * colSize();
638 if (item->index >= fromModelIndex) {
639 item->setPosition(colPos, rowPos);
640 item->setVisible(item->rowPos() + rowSize() >= from && item->rowPos() <= to);
655 qreal pos = position();
656 if (flow == QQuickGridView::FlowLeftToRight) {
657 if (item->y() + item->height() > pos && item->y() < pos + q->height()) {
658 qreal y = (verticalLayoutDirection == QQuickItemView::TopToBottom)
660 : -rowPosAt(index) - item->height();
661 item->setPosition(QPointF(colPosAt(index), y));
664 if (item->x() + item->width() > pos && item->x() < pos + q->width()) {
665 qreal y = (verticalLayoutDirection == QQuickItemView::TopToBottom)
667 : -colPosAt(index) - item->height();
668 if (flow == QQuickGridView::FlowTopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft)
669 item->setPosition(QPointF(-rowPosAt(index)-item->width(), y));
671 item->setPosition(QPointF(rowPosAt(index), y));
697 bool changed =
false;
699 if (trackedItem == highlight.get())
700 trackedItem =
nullptr;
703 delete highlightXAnimator;
704 delete highlightYAnimator;
705 highlightXAnimator =
nullptr;
706 highlightYAnimator =
nullptr;
716 QQuickItem *item = createHighlightItem();
718 std::unique_ptr<FxGridItemSG> newHighlight
719 = std::make_unique<FxGridItemSG>(item, q,
true);
720 newHighlight->trackGeometry(
true);
723 highlightXAnimator =
new QSmoothedAnimation;
724 highlightXAnimator->target = QQmlProperty(item, QLatin1String(
"x"));
725 highlightXAnimator->userDuration = highlightMoveDuration;
726 highlightYAnimator =
new QSmoothedAnimation;
727 highlightYAnimator->target = QQmlProperty(item, QLatin1String(
"y"));
728 highlightYAnimator->userDuration = highlightMoveDuration;
730 highlight = std::move(newHighlight);
735 emit q->highlightItemChanged();
792 bool created =
false;
794 QQuickItem *item = createComponentItem(footerComponent, 1.0);
797 footer =
new FxGridItemSG(item, q,
true);
798 footer->trackGeometry(
true);
802 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(footer);
805 if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
806 if (flow == QQuickGridView::FlowTopToBottom)
807 rowOffset += gridItem->item->width() - cellWidth;
809 colOffset += gridItem->item->width() - cellWidth;
811 if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
812 if (flow == QQuickGridView::FlowTopToBottom)
813 colOffset += gridItem->item->height() - cellHeight;
815 rowOffset += gridItem->item->height() - cellHeight;
817 if (visibleItems.size()) {
818 qreal endPos = lastPosition();
819 if (findLastVisibleIndex() == model->count()-1) {
820 gridItem->setPosition(colOffset, endPos + rowOffset);
822 qreal visiblePos = isContentFlowReversed() ? -position() : position() + size();
823 if (endPos <= visiblePos || gridItem->endPosition() <= endPos + rowOffset)
824 gridItem->setPosition(colOffset, endPos + rowOffset);
827 gridItem->setPosition(colOffset, rowOffset);
831 emit q->footerItemChanged();
845 bool created =
false;
847 QQuickItem *item = createComponentItem(headerComponent, 1.0);
850 header =
new FxGridItemSG(item, q,
true);
851 header->trackGeometry(
true);
855 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(header);
857 qreal rowOffset = -headerSize();
858 if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
859 if (flow == QQuickGridView::FlowTopToBottom)
860 rowOffset += gridItem->item->width() - cellWidth;
862 colOffset += gridItem->item->width() - cellWidth;
864 if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
865 if (flow == QQuickGridView::FlowTopToBottom)
866 colOffset += gridItem->item->height() - cellHeight;
868 rowOffset += gridItem->item->height() - cellHeight;
870 if (visibleItems.size()) {
871 qreal startPos = originPosition();
872 if (visibleIndex == 0) {
873 gridItem->setPosition(colOffset, startPos + rowOffset);
875 qreal tempPos = isContentFlowReversed() ? -position()-size() : position();
876 qreal headerPos = isContentFlowReversed() ? gridItem->rowPos() + cellWidth - headerSize() : gridItem->rowPos();
877 if (tempPos <= startPos || headerPos > startPos + rowOffset)
878 gridItem->setPosition(colOffset, startPos + rowOffset);
882 gridItem->setPosition(colOffset, rowOffset);
884 gridItem->setPosition(colOffset, -headerSize());
888 emit q->headerItemChanged();
917 if ((flow == QQuickGridView::FlowTopToBottom && &data == &vData)
918 || (flow == QQuickGridView::FlowLeftToRight && &data == &hData))
921 fixupMode = moveReason == Mouse ? fixupMode : Immediate;
923 qreal viewPos = isContentFlowReversed() ? -position()-size() : position();
925 bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange;
926 if (snapMode != QQuickGridView::NoSnap) {
927 qreal tempPosition = isContentFlowReversed() ? -position()-size() : position();
928 if (snapMode == QQuickGridView::SnapOneRow && moveReason == Mouse) {
930 qreal dist = data.move.value() - data.pressPos;
936 if (isContentFlowReversed())
938 tempPosition -= bias;
940 FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
941 if (strictHighlightRange && currentItem && (!topItem || (topItem->index != currentIndex && fixupMode == Immediate))) {
944 topItem = currentItem;
946 FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
947 if (strictHighlightRange && currentItem && (!bottomItem || (bottomItem->index != currentIndex && fixupMode == Immediate))) {
950 bottomItem = currentItem;
953 bool isInBounds = -position() > maxExtent && -position() <= minExtent;
954 if (topItem && (isInBounds || strictHighlightRange)) {
955 qreal headerPos = header ?
static_cast<FxGridItemSG*>(header)->rowPos() : 0;
956 if (topItem->index == 0 && header && tempPosition+highlightRangeStart < headerPos+headerSize()/2 && !strictHighlightRange) {
957 pos = isContentFlowReversed() ? - headerPos + highlightRangeStart - size() : headerPos - highlightRangeStart;
959 if (isContentFlowReversed())
960 pos = qMax(qMin(-topItem->position() + highlightRangeStart - size(), -maxExtent), -minExtent);
962 pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
964 }
else if (bottomItem && isInBounds) {
965 if (isContentFlowReversed())
966 pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
968 pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
970 QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
974 qreal dist = qAbs(data.move + pos);
976 timeline.reset(data.move);
977 if (fixupMode != Immediate) {
978 timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
979 data.fixingUp =
true;
981 timeline.set(data.move, -pos);
983 vTime = timeline.time();
985 }
else if (haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange) {
988 qreal pos =
static_cast<FxGridItemSG*>(currentItem)->rowPos();
989 if (viewPos < pos + rowSize() - highlightRangeEnd)
990 viewPos = pos + rowSize() - highlightRangeEnd;
991 if (viewPos > pos - highlightRangeStart)
992 viewPos = pos - highlightRangeStart;
993 if (isContentFlowReversed())
994 viewPos = -viewPos-size();
995 timeline.reset(data.move);
996 if (viewPos != position()) {
997 if (fixupMode != Immediate) {
998 timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
999 data.fixingUp =
true;
1001 timeline.set(data.move, -viewPos);
1004 vTime = timeline.time();
1007 QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
1009 data.inOvershoot =
false;
1014 QQuickTimeLineCallback::Callback fixupCallback, QEvent::Type eventType, qreal velocity)
1016 data.fixingUp =
false;
1018 if ((!haveHighlightRange || highlightRange != QQuickGridView::StrictlyEnforceRange)
1019 && snapMode == QQuickGridView::NoSnap) {
1020 return QQuickItemViewPrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, eventType, velocity);
1022 qreal maxDistance = 0;
1023 qreal dataValue = isContentFlowReversed() ? -data.move.value()+size() : data.move.value();
1026 if (data.move.value() < minExtent) {
1027 if (snapMode == QQuickGridView::SnapOneRow) {
1029 qreal dist = data.move.value() - data.pressPos;
1030 qreal bias = dist < rowSize()/2 ? rowSize()/2 : 0;
1031 if (isContentFlowReversed())
1033 data.flickTarget = -snapPosAt(-dataValue - bias);
1034 maxDistance = qAbs(data.flickTarget - data.move.value());
1035 velocity = maxVelocity;
1037 maxDistance = qAbs(minExtent - data.move.value());
1040 if (snapMode == QQuickGridView::NoSnap && highlightRange != QQuickGridView::StrictlyEnforceRange)
1041 data.flickTarget = minExtent;
1043 if (data.move.value() > maxExtent) {
1044 if (snapMode == QQuickGridView::SnapOneRow) {
1046 qreal dist = data.move.value() - data.pressPos;
1047 qreal bias = -dist < rowSize()/2 ? rowSize()/2 : 0;
1048 if (isContentFlowReversed())
1050 data.flickTarget = -snapPosAt(-dataValue + bias);
1051 maxDistance = qAbs(data.flickTarget - data.move.value());
1052 velocity = -maxVelocity;
1054 maxDistance = qAbs(maxExtent - data.move.value());
1057 if (snapMode == QQuickGridView::NoSnap && highlightRange != QQuickGridView::StrictlyEnforceRange)
1058 data.flickTarget = maxExtent;
1060 bool overShoot = boundsBehavior & QQuickFlickable::OvershootBounds;
1061 if (maxDistance > 0 || overShoot) {
1064 if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
1070 qreal accel = eventType == QEvent::Wheel ? wheelDeceleration : deceleration;
1072 qreal overshootDist = 0.0;
1073 if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QQuickGridView::SnapOneRow) {
1075 qreal dist = v2 / (accel * 2.0) + rowSize()/4;
1076 dist = qMin(dist, maxDistance);
1079 if (snapMode != QQuickGridView::SnapOneRow) {
1080 qreal distTemp = isContentFlowReversed() ? -dist : dist;
1081 data.flickTarget = -snapPosAt(-dataValue + distTemp);
1085 if (data.flickTarget >= minExtent) {
1086 overshootDist = overShootDistance(vSize);
1087 data.flickTarget += overshootDist;
1088 }
else if (data.flickTarget <= maxExtent) {
1089 overshootDist = overShootDistance(vSize);
1090 data.flickTarget -= overshootDist;
1093 qreal adjDist = -data.flickTarget + data.move.value();
1094 if (qAbs(adjDist) > qAbs(dist)) {
1096 qreal adjv2 = accel * 2.0f * qAbs(adjDist);
1105 accel = v2 / (2.0f * qAbs(dist));
1107 data.flickTarget = velocity > 0 ? minExtent : maxExtent;
1108 overshootDist = overShoot ? overShootDistance(vSize) : 0;
1110 timeline.reset(data.move);
1111 timeline.accel(data.move, v, accel, maxDistance + overshootDist);
1112 timeline.callback(QQuickTimeLineCallback(&data.move, fixupCallback,
this));
1115 timeline.reset(data.move);
1116 fixup(data, minExtent, maxExtent);
2119void QQuickGridView::viewportMoved(Qt::Orientations orient)
2121 Q_D(QQuickGridView);
2122 QQuickItemView::viewportMoved(orient);
2125 if (d->inViewportMoved)
2127 d->inViewportMoved =
true;
2130 if (d->isContentFlowReversed())
2131 d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
2133 d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
2135 if (d->isContentFlowReversed())
2136 d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
2138 d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
2141 d->refillOrLayout();
2144 qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
2145 qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
2146 for (FxViewItem *item : std::as_const(d->visibleItems)) {
2147 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(item);
2148 QQuickItemPrivate::get(gridItem->item)->setCulled(gridItem->rowPos() + d->rowSize() < from || gridItem->rowPos() > to);
2150 if (d->currentItem) {
2151 FxGridItemSG *item =
static_cast<FxGridItemSG*>(d->currentItem);
2152 QQuickItemPrivate::get(item->item)->setCulled(item->rowPos() + d->rowSize() < from || item->rowPos() > to);
2155 if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
2156 d->moveReason = QQuickGridViewPrivate::Mouse;
2157 if (d->moveReason != QQuickGridViewPrivate::SetIndex) {
2158 if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
2160 qreal pos = d->highlight->position();
2161 qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
2162 if (pos > viewPos + d->highlightRangeEnd - d->highlight->size())
2163 pos = viewPos + d->highlightRangeEnd - d->highlight->size();
2164 if (pos < viewPos + d->highlightRangeStart)
2165 pos = viewPos + d->highlightRangeStart;
2167 if (pos != d->highlight->position()) {
2168 d->highlightXAnimator->stop();
2169 d->highlightYAnimator->stop();
2170 FxGridItemSG *sgHighlight =
static_cast<FxGridItemSG *>(d->highlight.get());
2171 sgHighlight->setPosition(sgHighlight->colPos(), pos);
2173 d->updateHighlight();
2177 int idx = d->snapIndex();
2178 if (idx >= 0 && idx != d->currentIndex) {
2179 d->updateCurrent(idx);
2181 &&
static_cast<FxGridItemSG*>(d->currentItem)->colPos()
2182 !=
static_cast<FxGridItemSG*>(d->highlight.get())->colPos()
2183 && d->autoHighlight) {
2184 if (d->flow == FlowLeftToRight)
2185 d->highlightXAnimator->to = d->currentItem->itemX();
2187 d->highlightYAnimator->to = d->currentItem->itemY();
2193 d->inViewportMoved =
false;
2271void QQuickGridView::moveCurrentIndexUp()
2273 Q_D(QQuickGridView);
2274 const int count = d->model ? d->model->count() : 0;
2277 if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
2278 if (d->flow == QQuickGridView::FlowLeftToRight) {
2279 if (currentIndex() >= d->columns || d->wrap) {
2280 int index = currentIndex() - d->columns;
2281 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2284 if (currentIndex() > 0 || d->wrap) {
2285 int index = currentIndex() - 1;
2286 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2290 if (d->flow == QQuickGridView::FlowLeftToRight) {
2291 if (currentIndex() < count - d->columns || d->wrap) {
2292 int index = currentIndex()+d->columns;
2293 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2296 if (currentIndex() < count - 1 || d->wrap) {
2297 int index = currentIndex() + 1;
2298 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2313void QQuickGridView::moveCurrentIndexDown()
2315 Q_D(QQuickGridView);
2316 const int count = d->model ? d->model->count() : 0;
2320 if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
2321 if (d->flow == QQuickGridView::FlowLeftToRight) {
2322 if (currentIndex() < count - d->columns || d->wrap) {
2323 int index = currentIndex()+d->columns;
2324 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2327 if (currentIndex() < count - 1 || d->wrap) {
2328 int index = currentIndex() + 1;
2329 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2333 if (d->flow == QQuickGridView::FlowLeftToRight) {
2334 if (currentIndex() >= d->columns || d->wrap) {
2335 int index = currentIndex() - d->columns;
2336 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2339 if (currentIndex() > 0 || d->wrap) {
2340 int index = currentIndex() - 1;
2341 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2356void QQuickGridView::moveCurrentIndexLeft()
2358 Q_D(QQuickGridView);
2359 const int count = d->model ? d->model->count() : 0;
2362 if (effectiveLayoutDirection() == Qt::LeftToRight) {
2363 if (d->flow == QQuickGridView::FlowLeftToRight) {
2364 if (currentIndex() > 0 || d->wrap) {
2365 int index = currentIndex() - 1;
2366 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2369 if (currentIndex() >= d->columns || d->wrap) {
2370 int index = currentIndex() - d->columns;
2371 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2375 if (d->flow == QQuickGridView::FlowLeftToRight) {
2376 if (currentIndex() < count - 1 || d->wrap) {
2377 int index = currentIndex() + 1;
2378 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2381 if (currentIndex() < count - d->columns || d->wrap) {
2382 int index = currentIndex() + d->columns;
2383 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2399void QQuickGridView::moveCurrentIndexRight()
2401 Q_D(QQuickGridView);
2402 const int count = d->model ? d->model->count() : 0;
2405 if (effectiveLayoutDirection() == Qt::LeftToRight) {
2406 if (d->flow == QQuickGridView::FlowLeftToRight) {
2407 if (currentIndex() < count - 1 || d->wrap) {
2408 int index = currentIndex() + 1;
2409 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2412 if (currentIndex() < count - d->columns || d->wrap) {
2413 int index = currentIndex()+d->columns;
2414 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2418 if (d->flow == QQuickGridView::FlowLeftToRight) {
2419 if (currentIndex() > 0 || d->wrap) {
2420 int index = currentIndex() - 1;
2421 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2424 if (currentIndex() >= d->columns || d->wrap) {
2425 int index = currentIndex() - d->columns;
2426 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2434 Q_Q(QQuickGridView);
2436 if (q->size().isNull())
2439 int modelIndex = change.index;
2440 int count = change.count;
2442 int index = visibleItems.size() ? mapFromModel(modelIndex) : 0;
2445 int i = visibleItems.size() - 1;
2446 while (i > 0 && visibleItems.at(i)->index == -1)
2448 if (visibleItems.at(i)->index + 1 == modelIndex) {
2450 index = visibleItems.size();
2452 if (modelIndex <= visibleIndex) {
2454 visibleIndex += count;
2455 for (FxViewItem *item : std::as_const(visibleItems)) {
2456 if (item->index != -1 && item->index >= modelIndex)
2457 item->index += count;
2464 qreal tempPos = isContentFlowReversed() ? -position()-size()+q->width()+1 : position();
2468 if (visibleItems.size()) {
2469 if (index < visibleItems.size()) {
2470 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(visibleItems.at(index));
2471 colPos = gridItem->colPos();
2472 rowPos = gridItem->rowPos();
2473 colNum = qFloor((colPos+colSize()/2) / colSize());
2476 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(visibleItems.at(index-1));
2477 rowPos = gridItem->rowPos();
2478 colNum = qFloor((gridItem->colPos()+colSize()/2) / colSize());
2481 rowPos += rowSize();
2483 colPos = colNum * colSize();
2487#if QT_CONFIG(quick_viewtransitions)
2489 for (FxViewItem *item : std::as_const(visibleItems)) {
2490 if (item->index != -1 && item->index >= modelIndex) {
2491 item->index += count;
2492 if (change.isMove())
2493 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition,
false);
2495 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
false);
2500 int prevVisibleCount = visibleItems.size();
2501 if (insertResult->visiblePos.isValid() && rowPos < insertResult->visiblePos) {
2503 int insertionIdx = index;
2505 int from = tempPos - buffer - displayMarginBeginning;
2507 if (rowPos > from && insertionIdx < visibleIndex) {
2509 insertResult->countChangeBeforeVisible += count;
2510 insertResult->sizeChangesBeforeVisiblePos += ((count + columns - 1) / columns) * rowSize();
2514 FxViewItem *item =
nullptr;
2515 if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
2516 item->index = modelIndex + i;
2518 item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
2522 QQuickItemPrivate::get(item->item)->setCulled(
false);
2523 visibleItems.insert(insertionIdx, item);
2524 if (insertionIdx == 0)
2525 insertResult->changedFirstItem =
true;
2526 if (!change.isMove()) {
2527 addedItems->append(item);
2528#if QT_CONFIG(quick_viewtransitions)
2530 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
true);
2533 item->moveTo(QPointF(colPos, rowPos),
true);
2535 insertResult->sizeChangesBeforeVisiblePos += rowSize();
2537 if (--colNum < 0 ) {
2539 rowPos -= rowSize();
2541 colPos = colNum * colSize();
2550 int firstOkIdx = -1;
2551 for (
int i = 0; i <= insertionIdx && i < visibleItems.size() - 1; i++) {
2552 if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) {
2558 for (
int i = 0; i < firstOkIdx; i++) {
2559 FxViewItem *nvItem = visibleItems.takeFirst();
2560 addedItems->removeOne(nvItem);
2566 int to = buffer+displayMarginEnd+tempPos+size()-1;
2567 while (i < count && rowPos <= to + rowSize()*(columns - colNum)/qreal(columns+1)) {
2568 FxViewItem *item =
nullptr;
2569 if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
2570 item->index = modelIndex + i;
2571 bool newItem = !item;
2573 item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
2577 QQuickItemPrivate::get(item->item)->setCulled(
false);
2578 visibleItems.insert(index, item);
2580 insertResult->changedFirstItem =
true;
2581 if (change.isMove()) {
2585#if QT_CONFIG(quick_viewtransitions)
2586 && transitioner && transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition,
true)
2589 movingIntoView->append(MovedItem(item, change.moveKey(item->index)));
2591 addedItems->append(item);
2592#if QT_CONFIG(quick_viewtransitions)
2594 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
true);
2597 item->moveTo(QPointF(colPos, rowPos),
true);
2599 insertResult->sizeChangesAfterVisiblePos += rowSize();
2603 rowPos += rowSize();
2605 colPos = colNum * colSize();
2611 updateVisibleIndex();
2613 return visibleItems.size() > prevVisibleCount;