summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-02-12 16:26:38 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-02-20 13:54:34 +0000
commited3ed0b9db97a8fab0c03add23228b6b0a96f171 (patch)
tree130ebf9b291fa140dc39c331c0717cd55aab69b1 /src
parent76617fdb56a5498c01ad75bc461687ded7e8f8d7 (diff)
Fix touch point positions of non-transformable QGraphicsItems
TouchEvent::TouchPoint::pos was not updated in QGraphicsScenePrivate::updateTouchPointsForItem(). To prevent the transformation being calculated repeatedly for each touch point member, extract a function genericMapFromSceneTransform() from genericMapFromScene() returning the transformation and use that whereever multiple points are transformed. Add a test, extracting helper functionality from tst_QGraphicsItem::touchEventPropagation(). In addition, fold tst_QGraphicsScene::checkTouchPointsEllipseDiameters() from c48f4bde0044bd5b23af231f3639d0779ecbdb03 into this test, so that it is testing all transformations. Task-number: QTBUG-66192 Change-Id: If71886d2c14c4e216f7781ea2f22f1adc444e6cf Reviewed-by: Andy Shaw <andy.shaw@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp25
-rw-r--r--src/widgets/graphicsview/qgraphicsitem_p.h1
-rw-r--r--src/widgets/graphicsview/qgraphicsscene.cpp26
3 files changed, 35 insertions, 17 deletions
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 0bc3af2f77..cef1d1b6da 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -1134,19 +1134,26 @@ void QGraphicsItemPrivate::remapItemPos(QEvent *event, QGraphicsItem *item)
is untransformable, this function will correctly map \a pos from the scene using the
view's transformation.
*/
-QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
- const QWidget *viewport) const
+
+QTransform QGraphicsItemPrivate::genericMapFromSceneTransform(const QWidget *viewport) const
{
Q_Q(const QGraphicsItem);
if (!itemIsUntransformable())
- return q->mapFromScene(pos);
- QGraphicsView *view = 0;
- if (viewport)
- view = qobject_cast<QGraphicsView *>(viewport->parentWidget());
- if (!view)
- return q->mapFromScene(pos);
+ return sceneTransform.inverted();
+ const QGraphicsView *view = viewport
+ ? qobject_cast<QGraphicsView *>(viewport->parentWidget())
+ : nullptr;
+ if (view == nullptr)
+ return sceneTransform.inverted();
// ### More ping pong than needed.
- return q->deviceTransform(view->viewportTransform()).inverted().map(view->mapFromScene(pos));
+ const QTransform viewportTransform = view->viewportTransform();
+ return viewportTransform * q->deviceTransform(viewportTransform).inverted();
+}
+
+QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos,
+ const QWidget *viewport) const
+{
+ return genericMapFromSceneTransform(viewport).map(pos);
}
/*!
diff --git a/src/widgets/graphicsview/qgraphicsitem_p.h b/src/widgets/graphicsview/qgraphicsitem_p.h
index bae38473f9..9fc6c0794a 100644
--- a/src/widgets/graphicsview/qgraphicsitem_p.h
+++ b/src/widgets/graphicsview/qgraphicsitem_p.h
@@ -190,6 +190,7 @@ public:
void updateAncestorFlags();
void setIsMemberOfGroup(bool enabled);
void remapItemPos(QEvent *event, QGraphicsItem *item);
+ QTransform genericMapFromSceneTransform(const QWidget *viewport = nullptr) const;
QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const;
inline bool itemIsUntransformable() const
{
diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp
index 25b77aa02f..37c631483a 100644
--- a/src/widgets/graphicsview/qgraphicsscene.cpp
+++ b/src/widgets/graphicsview/qgraphicsscene.cpp
@@ -1286,10 +1286,11 @@ void QGraphicsScenePrivate::sendHoverEvent(QEvent::Type type, QGraphicsItem *ite
{
QGraphicsSceneHoverEvent event(type);
event.setWidget(hoverEvent->widget());
- event.setPos(item->d_ptr->genericMapFromScene(hoverEvent->scenePos(), hoverEvent->widget()));
+ const QTransform mapFromScene = item->d_ptr->genericMapFromSceneTransform(hoverEvent->widget());
+ event.setPos(mapFromScene.map(hoverEvent->scenePos()));
event.setScenePos(hoverEvent->scenePos());
event.setScreenPos(hoverEvent->screenPos());
- event.setLastPos(item->d_ptr->genericMapFromScene(hoverEvent->lastScenePos(), hoverEvent->widget()));
+ event.setLastPos(mapFromScene.map(hoverEvent->lastScenePos()));
event.setLastScenePos(hoverEvent->lastScenePos());
event.setLastScreenPos(hoverEvent->lastScreenPos());
event.setModifiers(hoverEvent->modifiers());
@@ -1312,14 +1313,16 @@ void QGraphicsScenePrivate::sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent)
if (item->isBlockedByModalPanel())
return;
+ const QTransform mapFromScene = item->d_ptr->genericMapFromSceneTransform(mouseEvent->widget());
+ const QPointF itemPos = mapFromScene.map(mouseEvent->scenePos());
for (int i = 0x1; i <= 0x10; i <<= 1) {
Qt::MouseButton button = Qt::MouseButton(i);
- mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget())));
+ mouseEvent->setButtonDownPos(button, mouseGrabberButtonDownPos.value(button, itemPos));
mouseEvent->setButtonDownScenePos(button, mouseGrabberButtonDownScenePos.value(button, mouseEvent->scenePos()));
mouseEvent->setButtonDownScreenPos(button, mouseGrabberButtonDownScreenPos.value(button, mouseEvent->screenPos()));
}
- mouseEvent->setPos(item->d_ptr->genericMapFromScene(mouseEvent->scenePos(), mouseEvent->widget()));
- mouseEvent->setLastPos(item->d_ptr->genericMapFromScene(mouseEvent->lastScenePos(), mouseEvent->widget()));
+ mouseEvent->setPos(itemPos);
+ mouseEvent->setLastPos(mapFromScene.map(mouseEvent->lastScenePos()));
sendEvent(item, mouseEvent);
}
@@ -5858,10 +5861,17 @@ void QGraphicsScenePrivate::removeView(QGraphicsView *view)
void QGraphicsScenePrivate::updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent)
{
+ const QTransform mapFromScene =
+ item->d_ptr->genericMapFromSceneTransform(static_cast<const QWidget *>(touchEvent->target()));
+
for (auto &touchPoint : touchEvent->_touchPoints) {
- touchPoint.setRect(item->mapFromScene(touchPoint.sceneRect()).boundingRect());
- touchPoint.setStartPos(item->d_ptr->genericMapFromScene(touchPoint.startScenePos(), static_cast<QWidget *>(touchEvent->target())));
- touchPoint.setLastPos(item->d_ptr->genericMapFromScene(touchPoint.lastScenePos(), static_cast<QWidget *>(touchEvent->target())));
+ // Deprecated TouchPoint::setRect clobbers ellipseDiameters, restore
+ const QSizeF ellipseDiameters = touchPoint.ellipseDiameters();
+ touchPoint.setRect(mapFromScene.map(touchPoint.sceneRect()).boundingRect());
+ touchPoint.setEllipseDiameters(ellipseDiameters);
+ touchPoint.setPos(mapFromScene.map(touchPoint.scenePos()));
+ touchPoint.setStartPos(mapFromScene.map(touchPoint.startScenePos()));
+ touchPoint.setLastPos(mapFromScene.map(touchPoint.lastScenePos()));
}
}