Increase precision for QGraphicsView::AnchorUnderMouse

* Use a more precise view center for views with odd width/height
* Use the QPointF version of mapToScene to avoid rounding
* Round instead of truncate when setting scroll bar values

These changes increase the precision of AnchorUnderMouse, which is
important when for example wheel scrolling is used to change the scale
of the view. Without these changes, the view shifts slightly with each
change in the transform.

[ChangeLog][QtWidgets][QGraphicsView] Increase precision for QGraphicsView::AnchorUnderMouse and QGraphicsView::centerOn

Pick-to: 6.6 6.7
Task-number: QTBUG-96879
Change-Id: I8199196c671e4aa96732f382e8057468f676b8d7
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
bb10
Thorbjørn Lindeijer 2024-01-10 14:21:52 +01:00
parent cde7d5d3ff
commit d99b0cfed2
1 changed files with 6 additions and 7 deletions

View File

@ -483,8 +483,8 @@ void QGraphicsViewPrivate::centerView(QGraphicsView::ViewportAnchor anchor)
if (q->underMouse()) {
// Last scene pos: lastMouseMoveScenePoint
// Current mouse pos:
QPointF transformationDiff = q->mapToScene(viewport->rect().center())
- q->mapToScene(viewport->mapFromGlobal(QCursor::pos()));
QPointF transformationDiff = mapToScene(viewport->rect().toRectF().center())
- mapToScene(viewport->mapFromGlobal(QCursor::pos().toPointF()));
q->centerOn(lastMouseMoveScenePoint + transformationDiff);
} else {
q->centerOn(lastCenterPoint);
@ -504,8 +504,7 @@ void QGraphicsViewPrivate::centerView(QGraphicsView::ViewportAnchor anchor)
*/
void QGraphicsViewPrivate::updateLastCenterPoint()
{
Q_Q(QGraphicsView);
lastCenterPoint = q->mapToScene(viewport->rect().center());
lastCenterPoint = mapToScene(viewport->rect().toRectF().center());
}
/*!
@ -1892,14 +1891,14 @@ void QGraphicsView::centerOn(const QPointF &pos)
qint64 horizontal = 0;
horizontal += horizontalScrollBar()->minimum();
horizontal += horizontalScrollBar()->maximum();
horizontal -= int(viewPoint.x() - width / 2.0);
horizontal -= qRound(viewPoint.x() - width / 2.0);
horizontalScrollBar()->setValue(horizontal);
} else {
horizontalScrollBar()->setValue(int(viewPoint.x() - width / 2.0));
horizontalScrollBar()->setValue(qRound(viewPoint.x() - width / 2.0));
}
}
if (!d->topIndent)
verticalScrollBar()->setValue(int(viewPoint.y() - height / 2.0));
verticalScrollBar()->setValue(qRound(viewPoint.y() - height / 2.0));
d->lastCenterPoint = oldCenterPoint;
}