diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-02-12 16:26:38 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2018-02-20 13:54:34 +0000 |
commit | ed3ed0b9db97a8fab0c03add23228b6b0a96f171 (patch) | |
tree | 130ebf9b291fa140dc39c331c0717cd55aab69b1 /src/widgets/graphicsview | |
parent | 76617fdb56a5498c01ad75bc461687ded7e8f8d7 (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/widgets/graphicsview')
-rw-r--r-- | src/widgets/graphicsview/qgraphicsitem.cpp | 25 | ||||
-rw-r--r-- | src/widgets/graphicsview/qgraphicsitem_p.h | 1 | ||||
-rw-r--r-- | src/widgets/graphicsview/qgraphicsscene.cpp | 26 |
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())); } } |