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

Task-number: QTBUG-96879
Change-Id: I8199196c671e4aa96732f382e8057468f676b8d7
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
(cherry picked from commit d99b0cfed21e05f6e84b97fe8edb68271a34deb2)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 4f1752a6b9072083ee8408c4cc7f3e821c9661a6)
This commit is contained in:
Thorbjørn Lindeijer 2024-01-10 14:21:52 +01:00 committed by Qt Cherry-pick Bot
parent 3411f2984a
commit f7add7ad0f

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;
}