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);
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);
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;
925 bool strictHighlightRange = haveHighlightRange && highlightRange == QQuickGridView::StrictlyEnforceRange;
926 if (snapMode != QQuickGridView::NoSnap) {
928 if (snapMode == QQuickGridView::SnapOneRow && moveReason == Mouse) {
930 qreal dist = data.move.value() - data.pressPos;
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;
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;
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;
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;
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) {
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);
2109void QQuickGridView::viewportMoved(Qt::Orientations orient)
2111 Q_D(QQuickGridView);
2112 QQuickItemView::viewportMoved(orient);
2115 if (d->inViewportMoved)
2117 d->inViewportMoved =
true;
2120 if (d->isContentFlowReversed())
2121 d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
2123 d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
2125 if (d->isContentFlowReversed())
2126 d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
2128 d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
2131 d->refillOrLayout();
2134 qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
2135 qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
2136 for (FxViewItem *item : std::as_const(d->visibleItems)) {
2137 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(item);
2138 QQuickItemPrivate::get(gridItem->item)->setCulled(gridItem->rowPos() + d->rowSize() < from || gridItem->rowPos() > to);
2140 if (d->currentItem) {
2141 FxGridItemSG *item =
static_cast<FxGridItemSG*>(d->currentItem);
2142 QQuickItemPrivate::get(item->item)->setCulled(item->rowPos() + d->rowSize() < from || item->rowPos() > to);
2145 if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
2146 d->moveReason = QQuickGridViewPrivate::Mouse;
2147 if (d->moveReason != QQuickGridViewPrivate::SetIndex) {
2148 if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
2150 qreal pos = d->highlight->position();
2151 qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
2152 if (pos > viewPos + d->highlightRangeEnd - d->highlight->size())
2153 pos = viewPos + d->highlightRangeEnd - d->highlight->size();
2154 if (pos < viewPos + d->highlightRangeStart)
2155 pos = viewPos + d->highlightRangeStart;
2157 if (pos != d->highlight->position()) {
2158 d->highlightXAnimator->stop();
2159 d->highlightYAnimator->stop();
2160 FxGridItemSG *sgHighlight =
static_cast<FxGridItemSG *>(d->highlight.get());
2161 sgHighlight->setPosition(sgHighlight->colPos(), pos);
2163 d->updateHighlight();
2167 int idx = d->snapIndex();
2168 if (idx >= 0 && idx != d->currentIndex) {
2169 d->updateCurrent(idx);
2171 &&
static_cast<FxGridItemSG*>(d->currentItem)->colPos()
2172 !=
static_cast<FxGridItemSG*>(d->highlight.get())->colPos()
2173 && d->autoHighlight) {
2174 if (d->flow == FlowLeftToRight)
2175 d->highlightXAnimator->to = d->currentItem->itemX();
2177 d->highlightYAnimator->to = d->currentItem->itemY();
2183 d->inViewportMoved =
false;
2261void QQuickGridView::moveCurrentIndexUp()
2263 Q_D(QQuickGridView);
2264 const int count = d->model ? d->model->count() : 0;
2267 if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
2268 if (d->flow == QQuickGridView::FlowLeftToRight) {
2269 if (currentIndex() >= d->columns || d->wrap) {
2270 int index = currentIndex() - d->columns;
2271 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2274 if (currentIndex() > 0 || d->wrap) {
2275 int index = currentIndex() - 1;
2276 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2280 if (d->flow == QQuickGridView::FlowLeftToRight) {
2281 if (currentIndex() < count - d->columns || d->wrap) {
2282 int index = currentIndex()+d->columns;
2283 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2286 if (currentIndex() < count - 1 || d->wrap) {
2287 int index = currentIndex() + 1;
2288 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2303void QQuickGridView::moveCurrentIndexDown()
2305 Q_D(QQuickGridView);
2306 const int count = d->model ? d->model->count() : 0;
2310 if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
2311 if (d->flow == QQuickGridView::FlowLeftToRight) {
2312 if (currentIndex() < count - d->columns || d->wrap) {
2313 int index = currentIndex()+d->columns;
2314 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2317 if (currentIndex() < count - 1 || d->wrap) {
2318 int index = currentIndex() + 1;
2319 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2323 if (d->flow == QQuickGridView::FlowLeftToRight) {
2324 if (currentIndex() >= d->columns || d->wrap) {
2325 int index = currentIndex() - d->columns;
2326 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2329 if (currentIndex() > 0 || d->wrap) {
2330 int index = currentIndex() - 1;
2331 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2346void QQuickGridView::moveCurrentIndexLeft()
2348 Q_D(QQuickGridView);
2349 const int count = d->model ? d->model->count() : 0;
2352 if (effectiveLayoutDirection() == Qt::LeftToRight) {
2353 if (d->flow == QQuickGridView::FlowLeftToRight) {
2354 if (currentIndex() > 0 || d->wrap) {
2355 int index = currentIndex() - 1;
2356 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2359 if (currentIndex() >= d->columns || d->wrap) {
2360 int index = currentIndex() - d->columns;
2361 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2365 if (d->flow == QQuickGridView::FlowLeftToRight) {
2366 if (currentIndex() < count - 1 || d->wrap) {
2367 int index = currentIndex() + 1;
2368 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2371 if (currentIndex() < count - d->columns || d->wrap) {
2372 int index = currentIndex() + d->columns;
2373 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2389void QQuickGridView::moveCurrentIndexRight()
2391 Q_D(QQuickGridView);
2392 const int count = d->model ? d->model->count() : 0;
2395 if (effectiveLayoutDirection() == Qt::LeftToRight) {
2396 if (d->flow == QQuickGridView::FlowLeftToRight) {
2397 if (currentIndex() < count - 1 || d->wrap) {
2398 int index = currentIndex() + 1;
2399 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2402 if (currentIndex() < count - d->columns || d->wrap) {
2403 int index = currentIndex()+d->columns;
2404 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2408 if (d->flow == QQuickGridView::FlowLeftToRight) {
2409 if (currentIndex() > 0 || d->wrap) {
2410 int index = currentIndex() - 1;
2411 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2414 if (currentIndex() >= d->columns || d->wrap) {
2415 int index = currentIndex() - d->columns;
2416 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2424 Q_Q(QQuickGridView);
2426 if (q->size().isNull())
2429 int modelIndex = change.index;
2430 int count = change.count;
2432 int index = visibleItems.size() ? mapFromModel(modelIndex) : 0;
2435 int i = visibleItems.size() - 1;
2436 while (i > 0 && visibleItems.at(i)->index == -1)
2438 if (visibleItems.at(i)->index + 1 == modelIndex) {
2440 index = visibleItems.size();
2442 if (modelIndex <= visibleIndex) {
2444 visibleIndex += count;
2445 for (FxViewItem *item : std::as_const(visibleItems)) {
2446 if (item->index != -1 && item->index >= modelIndex)
2447 item->index += count;
2454 qreal tempPos = isContentFlowReversed() ? -position()-size()+q->width()+1 : position();
2458 if (visibleItems.size()) {
2459 if (index < visibleItems.size()) {
2460 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(visibleItems.at(index));
2461 colPos = gridItem->colPos();
2462 rowPos = gridItem->rowPos();
2463 colNum = qFloor((colPos+colSize()/2) / colSize());
2466 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(visibleItems.at(index-1));
2467 rowPos = gridItem->rowPos();
2468 colNum = qFloor((gridItem->colPos()+colSize()/2) / colSize());
2471 rowPos += rowSize();
2473 colPos = colNum * colSize();
2477#if QT_CONFIG(quick_viewtransitions)
2479 for (FxViewItem *item : std::as_const(visibleItems)) {
2480 if (item->index != -1 && item->index >= modelIndex) {
2481 item->index += count;
2482 if (change.isMove())
2483 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition,
false);
2485 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
false);
2490 int prevVisibleCount = visibleItems.size();
2491 if (insertResult->visiblePos.isValid() && rowPos < insertResult->visiblePos) {
2493 int insertionIdx = index;
2495 int from = tempPos - buffer - displayMarginBeginning;
2497 if (rowPos > from && insertionIdx < visibleIndex) {
2499 insertResult->countChangeBeforeVisible += count;
2500 insertResult->sizeChangesBeforeVisiblePos += ((count + columns - 1) / columns) * rowSize();
2504 FxViewItem *item =
nullptr;
2505 if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
2506 item->index = modelIndex + i;
2508 item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
2512 QQuickItemPrivate::get(item->item)->setCulled(
false);
2513 visibleItems.insert(insertionIdx, item);
2514 if (insertionIdx == 0)
2515 insertResult->changedFirstItem =
true;
2516 if (!change.isMove()) {
2517 addedItems->append(item);
2518#if QT_CONFIG(quick_viewtransitions)
2520 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
true);
2523 item->moveTo(QPointF(colPos, rowPos),
true);
2525 insertResult->sizeChangesBeforeVisiblePos += rowSize();
2527 if (--colNum < 0 ) {
2529 rowPos -= rowSize();
2531 colPos = colNum * colSize();
2540 int firstOkIdx = -1;
2541 for (
int i = 0; i <= insertionIdx && i < visibleItems.size() - 1; i++) {
2542 if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) {
2548 for (
int i = 0; i < firstOkIdx; i++) {
2549 FxViewItem *nvItem = visibleItems.takeFirst();
2550 addedItems->removeOne(nvItem);
2556 int to = buffer+displayMarginEnd+tempPos+size()-1;
2557 while (i < count && rowPos <= to + rowSize()*(columns - colNum)/qreal(columns+1)) {
2558 FxViewItem *item =
nullptr;
2559 if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
2560 item->index = modelIndex + i;
2561 bool newItem = !item;
2563 item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
2567 QQuickItemPrivate::get(item->item)->setCulled(
false);
2568 visibleItems.insert(index, item);
2570 insertResult->changedFirstItem =
true;
2571 if (change.isMove()) {
2575#if QT_CONFIG(quick_viewtransitions)
2576 && transitioner && transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition,
true)
2579 movingIntoView->append(MovedItem(item, change.moveKey(item->index)));
2581 addedItems->append(item);
2582#if QT_CONFIG(quick_viewtransitions)
2584 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
true);
2587 item->moveTo(QPointF(colPos, rowPos),
true);
2589 insertResult->sizeChangesAfterVisiblePos += rowSize();
2593 rowPos += rowSize();
2595 colPos = colNum * colSize();
2601 updateVisibleIndex();
2603 return visibleItems.size() > prevVisibleCount;