QWidget::mapTo/FromGlobal(): Fix transformation in case of QGraphicsItem::ItemIgnoresTransformations
Extract a helper returning the transform from QGraphicsViewPrivate::mapToViewRect() and use that. Fixes: QTBUG-128913 Change-Id: Idc31f653c23cd7d0e5bbb8af560f010f01ac4d4b Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> (cherry picked from commit deb4e08c1212aa3d43f62f9e7211bf69d3be0ada) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
5f3e64235e
commit
5d612a72ad
@ -885,16 +885,14 @@ void QGraphicsViewPrivate::populateSceneDragDropEvent(QGraphicsSceneDragDropEven
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const
|
||||
QTransform QGraphicsViewPrivate::mapToViewTransform(const QGraphicsItem *item) const
|
||||
{
|
||||
Q_Q(const QGraphicsView);
|
||||
if (dirtyScroll)
|
||||
const_cast<QGraphicsViewPrivate *>(this)->updateScroll();
|
||||
|
||||
if (item->d_ptr->itemIsUntransformable()) {
|
||||
QTransform itv = item->deviceTransform(q->viewportTransform());
|
||||
return itv.mapRect(rect).toAlignedRect();
|
||||
}
|
||||
if (item->d_ptr->itemIsUntransformable())
|
||||
return item->deviceTransform(q->viewportTransform());
|
||||
|
||||
// Translate-only
|
||||
// COMBINE
|
||||
@ -908,21 +906,20 @@ QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRect
|
||||
offset += itemd->pos;
|
||||
} while ((parentItem = itemd->parent));
|
||||
|
||||
QRectF baseRect = rect.translated(offset.x(), offset.y());
|
||||
QTransform move = QTransform::fromTranslate(offset.x(), offset.y());
|
||||
if (!parentItem) {
|
||||
if (identityMatrix) {
|
||||
baseRect.translate(-scrollX, -scrollY);
|
||||
return baseRect.toAlignedRect();
|
||||
}
|
||||
return matrix.mapRect(baseRect).translated(-scrollX, -scrollY).toAlignedRect();
|
||||
move.translate(-scrollX, -scrollY);
|
||||
return identityMatrix ? move : matrix * move;
|
||||
}
|
||||
|
||||
QTransform tr = parentItem->sceneTransform();
|
||||
if (!identityMatrix)
|
||||
tr *= matrix;
|
||||
QRectF r = tr.mapRect(baseRect);
|
||||
r.translate(-scrollX, -scrollY);
|
||||
return r.toAlignedRect();
|
||||
return move * tr * QTransform::fromTranslate(-scrollX, -scrollY);
|
||||
}
|
||||
|
||||
QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const
|
||||
{
|
||||
return mapToViewTransform(item).mapRect(rect).toAlignedRect();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -139,6 +139,7 @@ public:
|
||||
void populateSceneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
|
||||
QDropEvent *source);
|
||||
|
||||
QTransform mapToViewTransform(const QGraphicsItem *item) const;
|
||||
QRect mapToViewRect(const QGraphicsItem *item, const QRectF &rect) const;
|
||||
QRegion mapToViewRegion(const QGraphicsItem *item, const QRectF &rect) const;
|
||||
QRegion dirtyRegion;
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "QtWidgets/qgraphicsproxywidget.h"
|
||||
#include "QtWidgets/qgraphicsscene.h"
|
||||
#include "private/qgraphicsproxywidget_p.h"
|
||||
#include "private/qgraphicsview_p.h"
|
||||
#endif
|
||||
#include "QtWidgets/qabstractscrollarea.h"
|
||||
#include "private/qabstractscrollarea_p.h"
|
||||
@ -12644,8 +12645,8 @@ static MapToGlobalTransformResult mapToGlobalTransform(const QWidget *w)
|
||||
if (const QGraphicsScene *scene = qgpw->scene()) {
|
||||
const QList <QGraphicsView *> views = scene->views();
|
||||
if (!views.isEmpty()) {
|
||||
result.transform *= qgpw->sceneTransform();
|
||||
result.transform *= views.first()->viewportTransform();
|
||||
auto *viewP = static_cast<QGraphicsViewPrivate *>(qt_widget_private(views.constFirst()));
|
||||
result.transform *= viewP->mapToViewTransform(qgpw);
|
||||
w = views.first()->viewport();
|
||||
}
|
||||
}
|
||||
|
@ -135,6 +135,7 @@ private slots:
|
||||
void QTBUG_6986_sendMouseEventToAlienWidget();
|
||||
void mapToGlobal();
|
||||
void mapToGlobalWithoutScene();
|
||||
void mapToGlobalIgnoreTranformation();
|
||||
void QTBUG_43780_visibility();
|
||||
#if QT_CONFIG(wheelevent)
|
||||
void wheelEventPropagation();
|
||||
@ -3552,6 +3553,55 @@ void tst_QGraphicsProxyWidget::mapToGlobalWithoutScene() // QTBUG-44509
|
||||
QCOMPARE(embeddedWidget->mapFromGlobal(globalPos), localPos);
|
||||
}
|
||||
|
||||
// QTBUG-128913, QGraphicsProxyWidget with ItemIgnoresTransformations
|
||||
void tst_QGraphicsProxyWidget::mapToGlobalIgnoreTranformation()
|
||||
{
|
||||
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
const QSize size = availableGeometry.size() / 2;
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
view.setWindowTitle(QLatin1StringView(QTest::currentTestFunction()));
|
||||
view.setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
view.setTransform(QTransform::fromScale(2, 2));
|
||||
view.resize(size);
|
||||
view.move(availableGeometry.bottomRight() - QPoint(size.width(), size.height())
|
||||
- QPoint(100, 100));
|
||||
|
||||
static constexpr int labelWidth = 200;
|
||||
static constexpr int labelHeight = 50;
|
||||
auto *transforming = new QGraphicsProxyWidget();
|
||||
auto *transformingLabel = new QLabel("Transforming"_L1);
|
||||
transformingLabel->resize(labelWidth, labelHeight);
|
||||
transforming->setWidget(transformingLabel);
|
||||
transforming->setPos(0, 0);
|
||||
scene.addItem(transforming);
|
||||
|
||||
auto *nonTransforming = new QGraphicsProxyWidget();
|
||||
nonTransforming->setFlag(QGraphicsItem::ItemIgnoresTransformations);
|
||||
auto *nonTransformingLabel = new QLabel("NonTransforming"_L1);
|
||||
nonTransformingLabel->resize(labelWidth, labelHeight);
|
||||
nonTransforming->setWidget(nonTransformingLabel);
|
||||
nonTransforming->setPos(labelWidth, 0);
|
||||
scene.addItem(nonTransforming);
|
||||
|
||||
view.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
||||
|
||||
const QPoint labelCenter{ labelWidth / 2, labelHeight / 2 };
|
||||
const QPoint topPos = view.geometry().topLeft() + view.viewport()->geometry().topLeft();
|
||||
const QPoint transformingGlobal = transformingLabel->mapToGlobal(labelCenter);
|
||||
const QPoint nonTransformingGlobal = nonTransformingLabel->mapToGlobal(labelCenter);
|
||||
|
||||
// Center of label at 0,0 scaled by 2 should match size
|
||||
QCOMPARE(transformingGlobal - topPos, QPoint(labelWidth, labelHeight));
|
||||
|
||||
// Center of non-transforming label at 200 (scaled by 2), 0
|
||||
QCOMPARE(nonTransformingGlobal - topPos,
|
||||
QPoint(labelWidth * 2 + labelWidth / 2, labelHeight / 2));
|
||||
}
|
||||
|
||||
// QTBUG_43780: Embedded widgets have isWindow()==true but showing them should not
|
||||
// trigger the top-level widget code path of show() that closes all popups
|
||||
// (for example combo popups).
|
||||
|
Loading…
x
Reference in New Issue
Block a user