aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktableview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items/qquicktableview.cpp')
-rw-r--r--src/quick/items/qquicktableview.cpp94
1 files changed, 54 insertions, 40 deletions
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 390d246170..1b564df125 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -1011,32 +1011,26 @@
\qmlmethod real QtQuick::TableView::implicitColumnWidth(int column)
\since 6.2
- Returns the implicit width of the given \a column. If the
- column is not loaded (and therefore not visible), the return value
- will be \c -1.
+ Returns the implicit width of the given \a column. This is the largest
+ \l implicitWidth found among the currently \l{isRowLoaded()}{loaded}
+ delegate items inside that column.
- The implicit width of a column is the largest implicitWidth
- found among the currently loaded delegate items inside that column.
- Widths returned by the \l columnWidthProvider will not be taken
- into account.
+ If the \a column is not loaded (and therefore not visible), the return value is \c -1.
- \sa columnWidthProvider, columnWidth(), isColumnLoaded(), {Row heights and column widths}
+ \sa columnWidth(), isRowLoaded(), {Row heights and column widths}
*/
/*!
\qmlmethod real QtQuick::TableView::implicitRowHeight(int row)
\since 6.2
- Returns the implicit height of the given \a row. If the
- row is not loaded (and therefore not visible), the return value
- will be \c -1.
+ Returns the implicit height of the given \a row. This is the largest
+ \l implicitHeight found among the currently \l{isColumnLoaded()}{loaded}
+ delegate items inside that row.
- The implicit height of a row is the largest implicitHeight
- found among the currently loaded delegate items inside that row.
- Heights returned by the \l rowHeightProvider will not be taken
- into account.
+ If the \a row is not loaded (and therefore not visible), the return value is \c -1.
- \sa rowHeightProvider, rowHeight(), isRowLoaded(), {Row heights and column widths}
+ \sa rowHeight(), isColumnLoaded(), {Row heights and column widths}
*/
/*!
@@ -1202,13 +1196,15 @@
Convenience function for doing:
\code
- modelIndex(cell.y, cell.x)
+ index(cell.y, cell.x)
\endcode
A cell is simply a \l point that combines row and column into
a single type.
\note \c {point.x} will map to the column, and \c {point.y} will map to the row.
+
+ \sa index()
*/
/*!
@@ -2155,11 +2151,13 @@ void QQuickTableViewPrivate::updateExtents()
const int nextTopRow = nextVisibleEdgeIndexAroundLoadedTable(Qt::TopEdge);
const int nextBottomRow = nextVisibleEdgeIndexAroundLoadedTable(Qt::BottomEdge);
+ QPointF prevOrigin = origin;
+ QSizeF prevEndExtent = endExtent;
+
if (syncHorizontally) {
const auto syncView_d = syncView->d_func();
origin.rx() = syncView_d->origin.x();
endExtent.rwidth() = syncView_d->endExtent.width();
- hData.markExtentsDirty();
} else if (nextLeftColumn == kEdgeIndexAtEnd) {
// There are no more columns to load on the left side of the table.
// In that case, we ensure that the origin match the beginning of the table.
@@ -2176,7 +2174,6 @@ void QQuickTableViewPrivate::updateExtents()
}
}
origin.rx() = loadedTableOuterRect.left();
- hData.markExtentsDirty();
} else if (loadedTableOuterRect.left() <= origin.x() + cellSpacing.width()) {
// The table rect is at the origin, or outside, but we still have more
// visible columns to the left. So we try to guesstimate how much space
@@ -2186,7 +2183,6 @@ void QQuickTableViewPrivate::updateExtents()
const qreal remainingSpacing = columnsRemaining * cellSpacing.width();
const qreal estimatedRemainingWidth = remainingColumnWidths + remainingSpacing;
origin.rx() = loadedTableOuterRect.left() - estimatedRemainingWidth;
- hData.markExtentsDirty();
} else if (nextRightColumn == kEdgeIndexAtEnd) {
// There are no more columns to load on the right side of the table.
// In that case, we ensure that the end of the content view match the end of the table.
@@ -2204,7 +2200,6 @@ void QQuickTableViewPrivate::updateExtents()
}
}
endExtent.rwidth() = loadedTableOuterRect.right() - q->contentWidth();
- hData.markExtentsDirty();
} else if (loadedTableOuterRect.right() >= q->contentWidth() + endExtent.width() - cellSpacing.width()) {
// The right-most column is outside the end of the content view, and we
// still have more visible columns in the model. This can happen if the application
@@ -2215,14 +2210,12 @@ void QQuickTableViewPrivate::updateExtents()
const qreal estimatedRemainingWidth = remainingColumnWidths + remainingSpacing;
const qreal pixelsOutsideContentWidth = loadedTableOuterRect.right() - q->contentWidth();
endExtent.rwidth() = pixelsOutsideContentWidth + estimatedRemainingWidth;
- hData.markExtentsDirty();
}
if (syncVertically) {
const auto syncView_d = syncView->d_func();
origin.ry() = syncView_d->origin.y();
endExtent.rheight() = syncView_d->endExtent.height();
- vData.markExtentsDirty();
} else if (nextTopRow == kEdgeIndexAtEnd) {
// There are no more rows to load on the top side of the table.
// In that case, we ensure that the origin match the beginning of the table.
@@ -2239,7 +2232,6 @@ void QQuickTableViewPrivate::updateExtents()
}
}
origin.ry() = loadedTableOuterRect.top();
- vData.markExtentsDirty();
} else if (loadedTableOuterRect.top() <= origin.y() + cellSpacing.height()) {
// The table rect is at the origin, or outside, but we still have more
// visible rows at the top. So we try to guesstimate how much space
@@ -2249,7 +2241,6 @@ void QQuickTableViewPrivate::updateExtents()
const qreal remainingSpacing = rowsRemaining * cellSpacing.height();
const qreal estimatedRemainingHeight = remainingRowHeights + remainingSpacing;
origin.ry() = loadedTableOuterRect.top() - estimatedRemainingHeight;
- vData.markExtentsDirty();
} else if (nextBottomRow == kEdgeIndexAtEnd) {
// There are no more rows to load on the bottom side of the table.
// In that case, we ensure that the end of the content view match the end of the table.
@@ -2267,7 +2258,6 @@ void QQuickTableViewPrivate::updateExtents()
}
}
endExtent.rheight() = loadedTableOuterRect.bottom() - q->contentHeight();
- vData.markExtentsDirty();
} else if (loadedTableOuterRect.bottom() >= q->contentHeight() + endExtent.height() - cellSpacing.height()) {
// The bottom-most row is outside the end of the content view, and we
// still have more visible rows in the model. This can happen if the application
@@ -2278,7 +2268,6 @@ void QQuickTableViewPrivate::updateExtents()
const qreal estimatedRemainingHeight = remainingRowHeigts + remainingSpacing;
const qreal pixelsOutsideContentHeight = loadedTableOuterRect.bottom() - q->contentHeight();
endExtent.rheight() = pixelsOutsideContentHeight + estimatedRemainingHeight;
- vData.markExtentsDirty();
}
if (tableMovedHorizontally || tableMovedVertically) {
@@ -2299,12 +2288,23 @@ void QQuickTableViewPrivate::updateExtents()
}
}
- if (hData.minExtentDirty || vData.minExtentDirty) {
- qCDebug(lcTableViewDelegateLifecycle) << "move origin and endExtent to:" << origin << endExtent;
+ if (prevOrigin != origin || prevEndExtent != endExtent) {
+ if (prevOrigin != origin)
+ qCDebug(lcTableViewDelegateLifecycle) << "move origin to:" << origin;
+ if (prevEndExtent != endExtent)
+ qCDebug(lcTableViewDelegateLifecycle) << "move endExtent to:" << endExtent;
// updateBeginningEnd() will let the new extents take effect. This will also change the
// visualArea of the flickable, which again will cause any attached scrollbars to adjust
// the position of the handle. Note the latter will cause the viewport to move once more.
+ hData.markExtentsDirty();
+ vData.markExtentsDirty();
updateBeginningEnd();
+ if (!q->isMoving()) {
+ // When we adjust the extents, the viewport can sometimes be left suspended in an
+ // overshooted state. It will bounce back again once the user clicks inside the
+ // viewport. But this comes across as a bug, so returnToBounds explicitly.
+ q->returnToBounds();
+ }
}
}
@@ -4318,11 +4318,18 @@ void QQuickTableViewPrivate::syncSyncView()
q->setRightMargin(syncView->rightMargin());
updateContentWidth();
- if (syncView->leftColumn() != q->leftColumn()) {
- // The left column is no longer the same as the left
- // column in syncView. This requires a rebuild.
- scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftColumn;
- scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly);
+ if (scheduledRebuildOptions & RebuildOption::LayoutOnly) {
+ if (syncView->leftColumn() != q->leftColumn()
+ || syncView->d_func()->loadedTableOuterRect.left() != loadedTableOuterRect.left()) {
+ // The left column is no longer the same, or at the same pos, as the left column in
+ // syncView. This can happen if syncView did a relayout that caused its left column
+ // to be resized so small that it ended up outside the viewport. It can also happen
+ // if the syncView loaded and unloaded columns after the relayout. We therefore need
+ // to sync our own left column and pos to be the same, which we do by rebuilding the
+ // whole viewport instead of just doing a plain LayoutOnly.
+ scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftColumn;
+ scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly);
+ }
}
}
@@ -4333,11 +4340,18 @@ void QQuickTableViewPrivate::syncSyncView()
q->setBottomMargin(syncView->bottomMargin());
updateContentHeight();
- if (syncView->topRow() != q->topRow()) {
- // The top row is no longer the same as the top
- // row in syncView. This requires a rebuild.
- scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftRow;
- scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly);
+ if (scheduledRebuildOptions & RebuildOption::LayoutOnly) {
+ if (syncView->topRow() != q->topRow()
+ || syncView->d_func()->loadedTableOuterRect.top() != loadedTableOuterRect.top()) {
+ // The top row is no longer the same, or at the same pos, as the top row in
+ // syncView. This can happen if syncView did a relayout that caused its top row
+ // to be resized so small that it ended up outside the viewport. It can also happen
+ // if the syncView loaded and unloaded rows after the relayout. We therefore need
+ // to sync our own top row and pos to be the same, which we do by rebuilding the
+ // whole viewport instead of just doing a plain LayoutOnly.
+ scheduledRebuildOptions |= QQuickTableViewPrivate::RebuildOption::CalculateNewTopLeftRow;
+ scheduledRebuildOptions.setFlag(RebuildOption::ViewportOnly);
+ }
}
}
@@ -4724,7 +4738,7 @@ void QQuickTableViewPrivate::syncViewportRect()
auto syncChild_d = syncChild->d_func();
if (syncChild_d->syncHorizontally)
w = qMax(w, syncChild->width());
- if (syncChild_d->syncHorizontally)
+ if (syncChild_d->syncVertically)
h = qMax(h, syncChild->height());
}