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);
2108void QQuickGridView::viewportMoved(Qt::Orientations orient)
2110 Q_D(QQuickGridView);
2111 QQuickItemView::viewportMoved(orient);
2114 if (d->inViewportMoved)
2116 d->inViewportMoved =
true;
2119 if (d->isContentFlowReversed())
2120 d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
2122 d->bufferMode = d->vData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
2124 if (d->isContentFlowReversed())
2125 d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferAfter : QQuickItemViewPrivate::BufferBefore;
2127 d->bufferMode = d->hData.smoothVelocity < 0 ? QQuickItemViewPrivate::BufferBefore : QQuickItemViewPrivate::BufferAfter;
2130 d->refillOrLayout();
2133 qreal from = d->isContentFlowReversed() ? -d->position()-d->displayMarginBeginning-d->size() : d->position()-d->displayMarginBeginning;
2134 qreal to = d->isContentFlowReversed() ? -d->position()+d->displayMarginEnd : d->position()+d->size()+d->displayMarginEnd;
2135 for (FxViewItem *item : std::as_const(d->visibleItems)) {
2136 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(item);
2137 QQuickItemPrivate::get(gridItem->item)->setCulled(gridItem->rowPos() + d->rowSize() < from || gridItem->rowPos() > to);
2139 if (d->currentItem) {
2140 FxGridItemSG *item =
static_cast<FxGridItemSG*>(d->currentItem);
2141 QQuickItemPrivate::get(item->item)->setCulled(item->rowPos() + d->rowSize() < from || item->rowPos() > to);
2144 if (d->hData.flicking || d->vData.flicking || d->hData.moving || d->vData.moving)
2145 d->moveReason = QQuickGridViewPrivate::Mouse;
2146 if (d->moveReason != QQuickGridViewPrivate::SetIndex) {
2147 if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange && d->highlight) {
2149 qreal pos = d->highlight->position();
2150 qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
2151 if (pos > viewPos + d->highlightRangeEnd - d->highlight->size())
2152 pos = viewPos + d->highlightRangeEnd - d->highlight->size();
2153 if (pos < viewPos + d->highlightRangeStart)
2154 pos = viewPos + d->highlightRangeStart;
2156 if (pos != d->highlight->position()) {
2157 d->highlightXAnimator->stop();
2158 d->highlightYAnimator->stop();
2159 FxGridItemSG *sgHighlight =
static_cast<FxGridItemSG *>(d->highlight.get());
2160 sgHighlight->setPosition(sgHighlight->colPos(), pos);
2162 d->updateHighlight();
2166 int idx = d->snapIndex();
2167 if (idx >= 0 && idx != d->currentIndex) {
2168 d->updateCurrent(idx);
2170 &&
static_cast<FxGridItemSG*>(d->currentItem)->colPos()
2171 !=
static_cast<FxGridItemSG*>(d->highlight.get())->colPos()
2172 && d->autoHighlight) {
2173 if (d->flow == FlowLeftToRight)
2174 d->highlightXAnimator->to = d->currentItem->itemX();
2176 d->highlightYAnimator->to = d->currentItem->itemY();
2182 d->inViewportMoved =
false;
2260void QQuickGridView::moveCurrentIndexUp()
2262 Q_D(QQuickGridView);
2263 const int count = d->model ? d->model->count() : 0;
2266 if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
2267 if (d->flow == QQuickGridView::FlowLeftToRight) {
2268 if (currentIndex() >= d->columns || d->wrap) {
2269 int index = currentIndex() - d->columns;
2270 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2273 if (currentIndex() > 0 || d->wrap) {
2274 int index = currentIndex() - 1;
2275 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2279 if (d->flow == QQuickGridView::FlowLeftToRight) {
2280 if (currentIndex() < count - d->columns || d->wrap) {
2281 int index = currentIndex()+d->columns;
2282 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2285 if (currentIndex() < count - 1 || d->wrap) {
2286 int index = currentIndex() + 1;
2287 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2302void QQuickGridView::moveCurrentIndexDown()
2304 Q_D(QQuickGridView);
2305 const int count = d->model ? d->model->count() : 0;
2309 if (d->verticalLayoutDirection == QQuickItemView::TopToBottom) {
2310 if (d->flow == QQuickGridView::FlowLeftToRight) {
2311 if (currentIndex() < count - d->columns || d->wrap) {
2312 int index = currentIndex()+d->columns;
2313 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2316 if (currentIndex() < count - 1 || d->wrap) {
2317 int index = currentIndex() + 1;
2318 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2322 if (d->flow == QQuickGridView::FlowLeftToRight) {
2323 if (currentIndex() >= d->columns || d->wrap) {
2324 int index = currentIndex() - d->columns;
2325 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2328 if (currentIndex() > 0 || d->wrap) {
2329 int index = currentIndex() - 1;
2330 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2345void QQuickGridView::moveCurrentIndexLeft()
2347 Q_D(QQuickGridView);
2348 const int count = d->model ? d->model->count() : 0;
2351 if (effectiveLayoutDirection() == Qt::LeftToRight) {
2352 if (d->flow == QQuickGridView::FlowLeftToRight) {
2353 if (currentIndex() > 0 || d->wrap) {
2354 int index = currentIndex() - 1;
2355 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2358 if (currentIndex() >= d->columns || d->wrap) {
2359 int index = currentIndex() - d->columns;
2360 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2364 if (d->flow == QQuickGridView::FlowLeftToRight) {
2365 if (currentIndex() < count - 1 || d->wrap) {
2366 int index = currentIndex() + 1;
2367 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2370 if (currentIndex() < count - d->columns || d->wrap) {
2371 int index = currentIndex() + d->columns;
2372 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2388void QQuickGridView::moveCurrentIndexRight()
2390 Q_D(QQuickGridView);
2391 const int count = d->model ? d->model->count() : 0;
2394 if (effectiveLayoutDirection() == Qt::LeftToRight) {
2395 if (d->flow == QQuickGridView::FlowLeftToRight) {
2396 if (currentIndex() < count - 1 || d->wrap) {
2397 int index = currentIndex() + 1;
2398 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2401 if (currentIndex() < count - d->columns || d->wrap) {
2402 int index = currentIndex()+d->columns;
2403 setCurrentIndex((index >= 0 && index < count) ? index : 0);
2407 if (d->flow == QQuickGridView::FlowLeftToRight) {
2408 if (currentIndex() > 0 || d->wrap) {
2409 int index = currentIndex() - 1;
2410 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2413 if (currentIndex() >= d->columns || d->wrap) {
2414 int index = currentIndex() - d->columns;
2415 setCurrentIndex((index >= 0 && index < count) ? index : count-1);
2423 Q_Q(QQuickGridView);
2425 if (q->size().isNull())
2428 int modelIndex = change.index;
2429 int count = change.count;
2431 int index = visibleItems.size() ? mapFromModel(modelIndex) : 0;
2434 int i = visibleItems.size() - 1;
2435 while (i > 0 && visibleItems.at(i)->index == -1)
2437 if (visibleItems.at(i)->index + 1 == modelIndex) {
2439 index = visibleItems.size();
2441 if (modelIndex <= visibleIndex) {
2443 visibleIndex += count;
2444 for (FxViewItem *item : std::as_const(visibleItems)) {
2445 if (item->index != -1 && item->index >= modelIndex)
2446 item->index += count;
2453 qreal tempPos = isContentFlowReversed() ? -position()-size()+q->width()+1 : position();
2457 if (visibleItems.size()) {
2458 if (index < visibleItems.size()) {
2459 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(visibleItems.at(index));
2460 colPos = gridItem->colPos();
2461 rowPos = gridItem->rowPos();
2462 colNum = qFloor((colPos+colSize()/2) / colSize());
2465 FxGridItemSG *gridItem =
static_cast<FxGridItemSG*>(visibleItems.at(index-1));
2466 rowPos = gridItem->rowPos();
2467 colNum = qFloor((gridItem->colPos()+colSize()/2) / colSize());
2470 rowPos += rowSize();
2472 colPos = colNum * colSize();
2476#if QT_CONFIG(quick_viewtransitions)
2478 for (FxViewItem *item : std::as_const(visibleItems)) {
2479 if (item->index != -1 && item->index >= modelIndex) {
2480 item->index += count;
2481 if (change.isMove())
2482 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition,
false);
2484 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
false);
2489 int prevVisibleCount = visibleItems.size();
2490 if (insertResult->visiblePos.isValid() && rowPos < insertResult->visiblePos) {
2492 int insertionIdx = index;
2494 int from = tempPos - buffer - displayMarginBeginning;
2496 if (rowPos > from && insertionIdx < visibleIndex) {
2498 insertResult->countChangeBeforeVisible += count;
2499 insertResult->sizeChangesBeforeVisiblePos += ((count + columns - 1) / columns) * rowSize();
2503 FxViewItem *item =
nullptr;
2504 if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
2505 item->index = modelIndex + i;
2507 item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
2511 QQuickItemPrivate::get(item->item)->setCulled(
false);
2512 visibleItems.insert(insertionIdx, item);
2513 if (insertionIdx == 0)
2514 insertResult->changedFirstItem =
true;
2515 if (!change.isMove()) {
2516 addedItems->append(item);
2517#if QT_CONFIG(quick_viewtransitions)
2519 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
true);
2522 item->moveTo(QPointF(colPos, rowPos),
true);
2524 insertResult->sizeChangesBeforeVisiblePos += rowSize();
2526 if (--colNum < 0 ) {
2528 rowPos -= rowSize();
2530 colPos = colNum * colSize();
2539 int firstOkIdx = -1;
2540 for (
int i = 0; i <= insertionIdx && i < visibleItems.size() - 1; i++) {
2541 if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) {
2547 for (
int i = 0; i < firstOkIdx; i++) {
2548 FxViewItem *nvItem = visibleItems.takeFirst();
2549 addedItems->removeOne(nvItem);
2555 int to = buffer+displayMarginEnd+tempPos+size()-1;
2556 while (i < count && rowPos <= to + rowSize()*(columns - colNum)/qreal(columns+1)) {
2557 FxViewItem *item =
nullptr;
2558 if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
2559 item->index = modelIndex + i;
2560 bool newItem = !item;
2562 item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
2566 QQuickItemPrivate::get(item->item)->setCulled(
false);
2567 visibleItems.insert(index, item);
2569 insertResult->changedFirstItem =
true;
2570 if (change.isMove()) {
2574#if QT_CONFIG(quick_viewtransitions)
2575 && transitioner && transitioner->canTransition(QQuickItemViewTransitioner::MoveTransition,
true)
2578 movingIntoView->append(MovedItem(item, change.moveKey(item->index)));
2580 addedItems->append(item);
2581#if QT_CONFIG(quick_viewtransitions)
2583 item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition,
true);
2586 item->moveTo(QPointF(colPos, rowPos),
true);
2588 insertResult->sizeChangesAfterVisiblePos += rowSize();
2592 rowPos += rowSize();
2594 colPos = colNum * colSize();
2600 updateVisibleIndex();
2602 return visibleItems.size() > prevVisibleCount;