278 if (FxViewItem *item = visibleItem(modelIndex))
279 return static_cast<FxGridItemSG*>(item)->colPos();
280 if (!visibleItems.isEmpty()) {
281 if (modelIndex == visibleIndex) {
282 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.first());
283 return firstItem->colPos();
284 }
else if (modelIndex < visibleIndex) {
285 int count = (visibleIndex - modelIndex) % columns;
286 int col =
static_cast<FxGridItemSG*>(visibleItems.first())->colPos() / colSize();
288 return col * colSize();
290 FxGridItemSG *lastItem =
static_cast<FxGridItemSG*>(visibleItems.last());
291 int count = modelIndex - lastItem->index;
292 int col = lastItem->colPos() / colSize();
294 return col * colSize();
297 return (modelIndex % columns) * colSize();
302 if (FxViewItem *item = visibleItem(modelIndex))
303 return static_cast<FxGridItemSG*>(item)->rowPos();
304 if (!visibleItems.isEmpty()) {
305 if (modelIndex == visibleIndex) {
306 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.first());
307 return firstItem->rowPos();
308 }
else if (modelIndex < visibleIndex) {
309 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.first());
310 int firstCol = firstItem->colPos() / colSize();
311 int col = visibleIndex - modelIndex + (columns - firstCol - 1);
313 return firstItem->rowPos() - rows * rowSize();
315 FxGridItemSG *lastItem =
static_cast<FxGridItemSG*>(visibleItems.last());
316 int count = modelIndex - lastItem->index;
317 int col = lastItem->colPos() + count * colSize();
318 int rows = col / (columns * colSize());
319 return lastItem->rowPos() + rows * rowSize();
323 qreal rowPos = ((modelIndex / columns) * rowSize());
325 if (flow == QQuickGridView::FlowLeftToRight && verticalLayoutDirection == QQuickItemView::TopToBottom) {
338 rowPos += qMax(vData.startMargin, highlightRangeStart) + headerSize();
467 qreal colPos = colPosAt(visibleIndex);
468 qreal rowPos = rowPosAt(visibleIndex);
469 if (visibleItems.size()) {
470 FxGridItemSG *lastItem =
static_cast<FxGridItemSG*>(visibleItems.constLast());
471 rowPos = lastItem->rowPos();
472 int colNum = qFloor((lastItem->colPos()+colSize()/2) / colSize());
477 colPos = colNum * colSize();
480 int modelIndex = findLastVisibleIndex();
481 modelIndex = modelIndex < 0 ? visibleIndex : modelIndex + 1;
483 if (visibleItems.size() && (bufferFrom > rowPos + rowSize()*2
484 || bufferTo < rowPosAt(visibleIndex) - rowSize())) {
487 int count = (fillFrom - (rowPos + rowSize())) / (rowSize()) * columns;
488 releaseVisibleItems(reusableFlag);
490 if (modelIndex >= model->count())
491 modelIndex = model->count() - 1;
492 else if (modelIndex < 0)
495 visibleIndex = modelIndex;
496 colPos = colPosAt(visibleIndex);
497 rowPos = rowPosAt(visibleIndex);
500 int colNum = qFloor((colPos+colSize()/2) / colSize());
501 FxGridItemSG *item =
nullptr;
502 bool changed =
false;
504 QQmlIncubator::IncubationMode incubationMode = doBuffer ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested;
506 while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) {
507 qCDebug(lcItemViewDelegateLifecycle) <<
"refill: append item" << modelIndex << colPos << rowPos;
508 if (!(item =
static_cast<FxGridItemSG*>(createItem(modelIndex, incubationMode))))
510#if QT_CONFIG(quick_viewtransitions)
511 if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition,
true))
512 item->setPosition(colPos, rowPos,
true);
514 QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
515 visibleItems.append(item);
520 colPos = colNum * colSize();
525 if (doBuffer && requestedIndex != -1)
529 if (visibleItems.size()) {
530 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.constFirst());
531 rowPos = firstItem->rowPos();
532 colPos = firstItem->colPos();
534 colNum = qFloor((colPos+colSize()/2) / colSize());
541 colPos = colNum * colSize();
542 while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){
543 qCDebug(lcItemViewDelegateLifecycle) <<
"refill: prepend item" << visibleIndex-1 <<
"top pos" << rowPos << colPos;
544 if (!(item =
static_cast<FxGridItemSG*>(createItem(visibleIndex-1, incubationMode))))
547#if QT_CONFIG(quick_viewtransitions)
548 if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition,
true))
549 item->setPosition(colPos, rowPos,
true);
551 QQuickItemPrivate::get(item->item)->setCulled(doBuffer);
552 visibleItems.prepend(item);
557 colPos = colNum * colSize();
580 FxGridItemSG *item =
nullptr;
581 bool changed =
false;
583 while (visibleItems.size() > 1
584 && (item =
static_cast<FxGridItemSG*>(visibleItems.constFirst()))
585 && item->rowPos()+rowSize()-1 < bufferFrom - rowSize()*(item->colPos()/colSize()+1)/(columns+1)) {
586 if (item->attached->delayRemove())
588 qCDebug(lcItemViewDelegateLifecycle) <<
"refill: remove first" << visibleIndex <<
"top end pos" << item->endRowPos();
589 if (item->index != -1)
591 visibleItems.removeFirst();
595 while (visibleItems.size() > 1
596 && (item =
static_cast<FxGridItemSG*>(visibleItems.constLast()))
597 && item->rowPos() > bufferTo + rowSize()*(columns - item->colPos()/colSize())/(columns+1)) {
598 if (item->attached->delayRemove())
600 qCDebug(lcItemViewDelegateLifecycle) <<
"refill: remove last" << visibleIndex+visibleItems.size()-1;
601 visibleItems.removeLast();
617 if (visibleItems.size()) {
618 const qreal from = isContentFlowReversed() ? -position()-displayMarginBeginning-size() : position()-displayMarginBeginning;
619 const qreal to = isContentFlowReversed() ? -position()+displayMarginEnd : position()+size()+displayMarginEnd;
621 FxGridItemSG *firstItem =
static_cast<FxGridItemSG*>(visibleItems.constFirst());
622 qreal rowPos = firstItem->rowPos();
623 qreal colPos = firstItem->colPos();
624 int col = visibleIndex % columns;
625 if (colPos != col * colSize()) {
626 colPos = col * colSize();
627 firstItem->setPosition(colPos, rowPos);
629 firstItem->setVisible(firstItem->rowPos() + rowSize() >= from && firstItem->rowPos() <= to);
630 for (
int i = 1; i < visibleItems.size(); ++i) {
631 FxGridItemSG *item =
static_cast<FxGridItemSG*>(visibleItems.at(i));
636 colPos = col * colSize();
637 if (item->index >= fromModelIndex) {
638 item->setPosition(colPos, rowPos);
639 item->setVisible(item->rowPos() + rowSize() >= from && item->rowPos() <= to);
654 qreal pos = position();
655 if (flow == QQuickGridView::FlowLeftToRight) {
656 if (item->y() + item->height() > pos && item->y() < pos + q->height()) {
657 qreal y = (verticalLayoutDirection == QQuickItemView::TopToBottom)
659 : -rowPosAt(index) - item->height();
660 item->setPosition(QPointF(colPosAt(index), y));
663 if (item->x() + item->width() > pos && item->x() < pos + q->width()) {
664 qreal y = (verticalLayoutDirection == QQuickItemView::TopToBottom)
666 : -colPosAt(index) - item->height();
667 if (flow == QQuickGridView::FlowTopToBottom && q->effectiveLayoutDirection() == Qt::RightToLeft)
668 item->setPosition(QPointF(-rowPosAt(index)-item->width(), y));
670 item->setPosition(QPointF(rowPosAt(index), y));
696 bool changed =
false;
698 if (trackedItem == highlight.get())
699 trackedItem =
nullptr;
702 delete highlightXAnimator;
703 delete highlightYAnimator;
704 highlightXAnimator =
nullptr;
705 highlightYAnimator =
nullptr;
715 QQuickItem *item = createHighlightItem();
717 std::unique_ptr<FxGridItemSG> newHighlight
718 = std::make_unique<FxGridItemSG>(item, q,
true);
719 newHighlight->trackGeometry(
true);
722 highlightXAnimator =
new QSmoothedAnimation;
723 highlightXAnimator->target = QQmlProperty(item, QLatin1String(
"x"));
724 highlightXAnimator->userDuration = highlightMoveDuration;
725 highlightYAnimator =
new QSmoothedAnimation;
726 highlightYAnimator->target = QQmlProperty(item, QLatin1String(
"y"));
727 highlightYAnimator->userDuration = highlightMoveDuration;
729 highlight = std::move(newHighlight);
734 emit q->highlightItemChanged();
791 bool created =
false;
793 QQuickItem *item = createComponentItem(footerComponent, 1.0);
796 footer =
new FxGridItemSG(item, q,
true);
797 footer->trackGeometry(
true);
801 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(footer);
804 if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
805 if (flow == QQuickGridView::FlowTopToBottom)
806 rowOffset += gridItem->item->width() - cellWidth;
808 colOffset += gridItem->item->width() - cellWidth;
810 if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
811 if (flow == QQuickGridView::FlowTopToBottom)
812 colOffset += gridItem->item->height() - cellHeight;
814 rowOffset += gridItem->item->height() - cellHeight;
816 if (visibleItems.size()) {
817 qreal endPos = lastPosition();
818 if (findLastVisibleIndex() == model->count()-1) {
819 gridItem->setPosition(colOffset, endPos + rowOffset);
822 if (endPos <= visiblePos || gridItem->endPosition() <= endPos + rowOffset)
823 gridItem->setPosition(colOffset, endPos + rowOffset);
826 gridItem->setPosition(colOffset, rowOffset);
830 emit q->footerItemChanged();
844 bool created =
false;
846 QQuickItem *item = createComponentItem(headerComponent, 1.0);
849 header =
new FxGridItemSG(item, q,
true);
850 header->trackGeometry(
true);
854 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(header);
856 qreal rowOffset = -headerSize();
857 if (q->effectiveLayoutDirection() == Qt::RightToLeft) {
858 if (flow == QQuickGridView::FlowTopToBottom)
859 rowOffset += gridItem->item->width() - cellWidth;
861 colOffset += gridItem->item->width() - cellWidth;
863 if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
864 if (flow == QQuickGridView::FlowTopToBottom)
865 colOffset += gridItem->item->height() - cellHeight;
867 rowOffset += gridItem->item->height() - cellHeight;
869 if (visibleItems.size()) {
870 qreal startPos = originPosition();
871 if (visibleIndex == 0) {
872 gridItem->setPosition(colOffset, startPos + rowOffset);
875 qreal headerPos = isContentFlowReversed() ? gridItem->rowPos() + cellWidth - headerSize() : gridItem->rowPos();
876 if (tempPos <= startPos || headerPos > startPos + rowOffset)
877 gridItem->setPosition(colOffset, startPos + rowOffset);
881 gridItem->setPosition(colOffset, rowOffset);
883 gridItem->setPosition(colOffset, -headerSize());
887 emit q->headerItemChanged();
916 if ((flow == QQuickGridView::FlowTopToBottom && &data == &vData)
917 || (flow == QQuickGridView::FlowLeftToRight && &data == &hData))
920 fixupMode = moveReason == Mouse ? fixupMode : Immediate;
924 bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange;
925 if (snapMode != QQuickGridView::NoSnap) {
927 if (snapMode == QQuickGridView::SnapOneRow && moveReason == Mouse) {
929 qreal dist = data.move.value() - data.pressPos;
937 tempPosition -= bias;
939 FxViewItem *topItem = snapItemAt(tempPosition+highlightRangeStart);
940 if (strictHighlightRange && currentItem && (!topItem || (topItem->index != currentIndex && fixupMode == Immediate))) {
943 topItem = currentItem;
945 FxViewItem *bottomItem = snapItemAt(tempPosition+highlightRangeEnd);
946 if (strictHighlightRange && currentItem && (!bottomItem || (bottomItem->index != currentIndex && fixupMode == Immediate))) {
949 bottomItem = currentItem;
952 bool isInBounds = -position() > maxExtent && -position() <= minExtent;
953 if (topItem && (isInBounds || strictHighlightRange)) {
954 qreal headerPos = header ?
static_cast<FxGridItemSG*>(header)->rowPos() : 0;
955 if (topItem->index == 0 && header && tempPosition+highlightRangeStart < headerPos+headerSize()/2 && !strictHighlightRange) {
956 pos = isContentFlowReversed() ? - headerPos + highlightRangeStart - size() : headerPos - highlightRangeStart;
958 if (isContentFlowReversed())
959 pos = qMax(qMin(-topItem->position() + highlightRangeStart - size(), -maxExtent), -minExtent);
961 pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent);
963 }
else if (bottomItem && isInBounds) {
964 if (isContentFlowReversed())
965 pos = qMax(qMin(-bottomItem->position() + highlightRangeEnd - size(), -maxExtent), -minExtent);
967 pos = qMax(qMin(bottomItem->position() - highlightRangeEnd, -maxExtent), -minExtent);
969 QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
973 qreal dist = qAbs(data.move + pos);
975 timeline.reset(data.move);
976 if (fixupMode != Immediate) {
977 timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
978 data.fixingUp =
true;
980 timeline.set(data.move, -pos);
982 vTime = timeline.time();
984 }
else if (haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange) {
987 qreal pos =
static_cast<FxGridItemSG*>(currentItem)->rowPos();
988 if (viewPos < pos + rowSize() - highlightRangeEnd)
989 viewPos = pos + rowSize() - highlightRangeEnd;
990 if (viewPos > pos - highlightRangeStart)
991 viewPos = pos - highlightRangeStart;
993 viewPos = -viewPos-size();
994 timeline.reset(data.move);
995 if (viewPos != position()) {
996 if (fixupMode != Immediate) {
997 timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2);
998 data.fixingUp =
true;
1000 timeline.set(data.move, -viewPos);
1003 vTime = timeline.time();
1006 QQuickItemViewPrivate::fixup(data, minExtent, maxExtent);
1008 data.inOvershoot =
false;
1013 QQuickTimeLineCallback::Callback fixupCallback, QEvent::Type eventType, qreal velocity)
1015 data.fixingUp =
false;
1017 if ((!haveHighlightRange || highlightRange != QQuickGridView::StrictlyEnforceRange)
1018 && snapMode == QQuickGridView::NoSnap) {
1019 return QQuickItemViewPrivate::flick(data, minExtent, maxExtent, vSize, fixupCallback, eventType, velocity);
1021 qreal maxDistance = 0;
1025 if (data.move.value() < minExtent) {
1026 if (snapMode == QQuickGridView::SnapOneRow) {
1028 qreal dist = data.move.value() - data.pressPos;
1029 qreal bias = dist < rowSize()/2 ? rowSize()/2 : 0;
1032 data.flickTarget = -snapPosAt(-dataValue - bias);
1033 maxDistance = qAbs(data.flickTarget - data.move.value());
1034 velocity = maxVelocity;
1036 maxDistance = qAbs(minExtent - data.move.value());
1039 if (snapMode == QQuickGridView::NoSnap && highlightRange != QQuickGridView::StrictlyEnforceRange)
1040 data.flickTarget = minExtent;
1042 if (data.move.value() > maxExtent) {
1043 if (snapMode == QQuickGridView::SnapOneRow) {
1045 qreal dist = data.move.value() - data.pressPos;
1046 qreal bias = -dist < rowSize()/2 ? rowSize()/2 : 0;
1049 data.flickTarget = -snapPosAt(-dataValue + bias);
1050 maxDistance = qAbs(data.flickTarget - data.move.value());
1051 velocity = -maxVelocity;
1053 maxDistance = qAbs(maxExtent - data.move.value());
1056 if (snapMode == QQuickGridView::NoSnap && highlightRange != QQuickGridView::StrictlyEnforceRange)
1057 data.flickTarget = maxExtent;
1059 bool overShoot = boundsBehavior & QQuickFlickable::OvershootBounds;
1060 if (maxDistance > 0 || overShoot) {
1063 if (maxVelocity != -1 && maxVelocity < qAbs(v)) {
1069 qreal accel = eventType == QEvent::Wheel ? wheelDeceleration : deceleration;
1071 qreal overshootDist = 0.0;
1072 if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QQuickGridView::SnapOneRow) {
1074 qreal dist = v2 / (accel * 2.0) + rowSize()/4;
1075 dist = qMin(dist, maxDistance);
1078 if (snapMode != QQuickGridView::SnapOneRow) {
1080 data.flickTarget = -snapPosAt(-dataValue + distTemp);
1084 if (data.flickTarget >= minExtent) {
1085 overshootDist = overShootDistance(vSize);
1086 data.flickTarget += overshootDist;
1087 }
else if (data.flickTarget <= maxExtent) {
1088 overshootDist = overShootDistance(vSize);
1089 data.flickTarget -= overshootDist;
1092 qreal adjDist = -data.flickTarget + data.move.value();
1093 if (qAbs(adjDist) > qAbs(dist)) {
1095 qreal adjv2 = accel * 2.0f * qAbs(adjDist);
1104 accel = v2 / (2.0f * qAbs(dist));
1106 data.flickTarget = velocity > 0 ? minExtent : maxExtent;
1107 overshootDist = overShoot ? overShootDistance(vSize) : 0;
1109 timeline.reset(data.move);
1110 timeline.accel(data.move, v, accel, maxDistance + overshootDist);
1111 timeline.callback(QQuickTimeLineCallback(&data.move, fixupCallback,
this));
1114 timeline.reset(data.move);
1115 fixup(data, minExtent, maxExtent);
2101void QQuickGridView::viewportMoved(Qt::Orientations orient)
2103 Q_D(QQuickGridView);
2104 QQuickItemView::viewportMoved(orient);
2107 if (d->inViewportMoved)
2109 d->inViewportMoved =
true;
2112 if (d->isContentFlowReversed())
2113 d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
2115 d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
2117 if (d->isContentFlowReversed())
2118 d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
2120 d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
2123 d->refillOrLayout();
2126 qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
2127 qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
2128 for (FxViewItem *item : std::as_const(d->visibleItems)) {
2129 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(item);
2130 QQuickItemPrivate::get(gridItem->item)->setCulled(gridItem->rowPos() + d->rowSize() < from || gridItem->rowPos() > to);
2132 if (d->currentItem) {
2133 FxGridItemSG *item =
static_cast<FxGridItemSG*>(d->currentItem);
2134 QQuickItemPrivate::get(item->item)->setCulled(item->rowPos() + d->rowSize() < from || item->rowPos() > to);
2137 if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
2138 d->moveReason = QQuickGridViewPrivate::Mouse;
2139 if (d->moveReason != QQuickGridViewPrivate::SetIndex) {
2140 if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
2142 qreal pos = d->highlight->position();
2143 qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
2144 if (pos > viewPos + d->highlightRangeEnd - d->highlight->size())
2145 pos = viewPos + d->highlightRangeEnd - d->highlight->size();
2146 if (pos < viewPos + d->highlightRangeStart)
2147 pos = viewPos + d->highlightRangeStart;
2149 if (pos != d->highlight->position()) {
2150 d->highlightXAnimator->stop();
2151 d->highlightYAnimator->stop();
2152 FxGridItemSG *sgHighlight =
static_cast<FxGridItemSG *>(d->highlight.get());
2153 sgHighlight->setPosition(sgHighlight->colPos(), pos);
2155 d->updateHighlight();
2159 int idx = d->snapIndex();
2160 if (idx >= 0 && idx != d->currentIndex) {
2161 d->updateCurrent(idx);
2163 &&
static_cast<FxGridItemSG*>(d->currentItem)->colPos()
2164 !=
static_cast<FxGridItemSG*>(d->highlight.get())->colPos()
2165 && d->autoHighlight) {
2166 if (d->flow == FlowLeftToRight)
2167 d->highlightXAnimator->to = d->currentItem->itemX();
2169 d->highlightYAnimator->to = d->currentItem->itemY();
2175 d->inViewportMoved =
false;
2253void QQuickGridView::moveCurrentIndexUp()
2255 Q_D(QQuickGridView);
2256 const int count = d->model ? d->model->count() : 0;
2259 if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
2260 if (d->flow == QQuickGridView::FlowLeftToRight) {
2261 if (currentIndex() >= d->columns || d->wrap) {
2262 int index = currentIndex() - d->columns;
2263 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2266 if (currentIndex() > 0 || d->wrap) {
2267 int index = currentIndex() - 1;
2268 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2272 if (d->flow == QQuickGridView::FlowLeftToRight) {
2273 if (currentIndex() < count - d->columns || d->wrap) {
2274 int index = currentIndex()+d->columns;
2275 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2278 if (currentIndex() < count - 1 || d->wrap) {
2279 int index = currentIndex() + 1;
2280 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2295void QQuickGridView::moveCurrentIndexDown()
2297 Q_D(QQuickGridView);
2298 const int count = d->model ? d->model->count() : 0;
2302 if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
2303 if (d->flow == QQuickGridView::FlowLeftToRight) {
2304 if (currentIndex() < count - d->columns || d->wrap) {
2305 int index = currentIndex()+d->columns;
2306 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2309 if (currentIndex() < count - 1 || d->wrap) {
2310 int index = currentIndex() + 1;
2311 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2315 if (d->flow == QQuickGridView::FlowLeftToRight) {
2316 if (currentIndex() >= d->columns || d->wrap) {
2317 int index = currentIndex() - d->columns;
2318 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2321 if (currentIndex() > 0 || d->wrap) {
2322 int index = currentIndex() - 1;
2323 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2338void QQuickGridView::moveCurrentIndexLeft()
2340 Q_D(QQuickGridView);
2341 const int count = d->model ? d->model->count() : 0;
2344 if (effectiveLayoutDirection() == Qt::LeftToRight) {
2345 if (d->flow == QQuickGridView::FlowLeftToRight) {
2346 if (currentIndex() > 0 || d->wrap) {
2347 int index = currentIndex() - 1;
2348 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2351 if (currentIndex() >= d->columns || d->wrap) {
2352 int index = currentIndex() - d->columns;
2353 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2357 if (d->flow == QQuickGridView::FlowLeftToRight) {
2358 if (currentIndex() < count - 1 || d->wrap) {
2359 int index = currentIndex() + 1;
2360 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2363 if (currentIndex() < count - d->columns || d->wrap) {
2364 int index = currentIndex() + d->columns;
2365 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2381void QQuickGridView::moveCurrentIndexRight()
2383 Q_D(QQuickGridView);
2384 const int count = d->model ? d->model->count() : 0;
2387 if (effectiveLayoutDirection() == Qt::LeftToRight) {
2388 if (d->flow == QQuickGridView::FlowLeftToRight) {
2389 if (currentIndex() < count - 1 || d->wrap) {
2390 int index = currentIndex() + 1;
2391 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2394 if (currentIndex() < count - d->columns || d->wrap) {
2395 int index = currentIndex()+d->columns;
2396 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2400 if (d->flow == QQuickGridView::FlowLeftToRight) {
2401 if (currentIndex() > 0 || d->wrap) {
2402 int index = currentIndex() - 1;
2403 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2406 if (currentIndex() >= d->columns || d->wrap) {
2407 int index = currentIndex() - d->columns;
2408 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2416 Q_Q(QQuickGridView);
2418 if (q->size().isNull())
2421 int modelIndex = change.index;
2422 int count = change.count;
2424 int index = visibleItems.size() ? mapFromModel(modelIndex) : 0;
2427 int i = visibleItems.size() - 1;
2428 while (i > 0 && visibleItems.at(i)->index == -1)
2430 if (visibleItems.at(i)->index + 1 == modelIndex) {
2432 index = visibleItems.size();
2434 if (modelIndex <= visibleIndex) {
2436 visibleIndex += count;
2437 for (FxViewItem *item : std::as_const(visibleItems)) {
2438 if (item->index != -1 && item->index >= modelIndex)
2439 item->index += count;
2446 qreal tempPos = isContentFlowReversed() ? -position()-size()+q->width()+1 : position();
2450 if (visibleItems.size()) {
2451 if (index < visibleItems.size()) {
2452 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(visibleItems.at(index));
2453 colPos = gridItem->colPos();
2454 rowPos = gridItem->rowPos();
2455 colNum = qFloor((colPos+colSize()/2) / colSize());
2458 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(visibleItems.at(index-1));
2459 rowPos = gridItem->rowPos();
2460 colNum = qFloor((gridItem->colPos()+colSize()/2) / colSize());
2463 rowPos += rowSize();
2465 colPos = colNum * colSize();
2469#if QT_CONFIG(quick_viewtransitions)
2471 for (FxViewItem *item : std::as_const(visibleItems)) {
2472 if (item->index != -1 && item->index >= modelIndex) {
2473 item->index += count;
2474 if (change.isMove())
2475 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition,
false);
2477 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
false);
2482 int prevVisibleCount = visibleItems.size();
2483 if (insertResult->visiblePos.isValid() && rowPos < insertResult->visiblePos) {
2485 int insertionIdx = index;
2487 int from = tempPos - buffer - displayMarginBeginning;
2489 if (rowPos > from && insertionIdx < visibleIndex) {
2491 insertResult->countChangeBeforeVisible += count;
2492 insertResult->sizeChangesBeforeVisiblePos += ((count + columns - 1) / columns) * rowSize();
2496 FxViewItem *item =
nullptr;
2497 if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
2498 item->index = modelIndex + i;
2500 item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
2504 QQuickItemPrivate::get(item->item)->setCulled(
false);
2505 visibleItems.insert(insertionIdx, item);
2506 if (insertionIdx == 0)
2507 insertResult->changedFirstItem =
true;
2508 if (!change.isMove()) {
2509 addedItems->append(item);
2510#if QT_CONFIG(quick_viewtransitions)
2512 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
true);
2515 item->moveTo(QPointF(colPos, rowPos),
true);
2517 insertResult->sizeChangesBeforeVisiblePos += rowSize();
2519 if (--colNum < 0 ) {
2521 rowPos -= rowSize();
2523 colPos = colNum * colSize();
2532 int firstOkIdx = -1;
2533 for (
int i = 0; i <= insertionIdx && i < visibleItems.size() - 1; i++) {
2534 if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) {
2540 for (
int i = 0; i < firstOkIdx; i++) {
2541 FxViewItem *nvItem = visibleItems.takeFirst();
2542 addedItems->removeOne(nvItem);
2548 int to = buffer+displayMarginEnd+tempPos+size()-1;
2549 while (i < count && rowPos <= to + rowSize()*(columns - colNum)/qreal(columns+1)) {
2550 FxViewItem *item =
nullptr;
2551 if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
2552 item->index = modelIndex + i;
2553 bool newItem = !item;
2555 item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
2559 QQuickItemPrivate::get(item->item)->setCulled(
false);
2560 visibleItems.insert(index, item);
2562 insertResult->changedFirstItem =
true;
2563 if (change.isMove()) {
2567#if QT_CONFIG(quick_viewtransitions)
2568 && transitioner && transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition,
true)
2571 movingIntoView->append(MovedItem(item, change.moveKey(item->index)));
2573 addedItems->append(item);
2574#if QT_CONFIG(quick_viewtransitions)
2576 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
true);
2579 item->moveTo(QPointF(colPos, rowPos),
true);
2581 insertResult->sizeChangesAfterVisiblePos += rowSize();
2585 rowPos += rowSize();
2587 colPos = colNum * colSize();
2593 updateVisibleIndex();
2595 return visibleItems.size() > prevVisibleCount;