From 9fe43ff4e313220a1ecb02a990324cb6b768e585 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 25 Feb 2010 16:48:33 +0100 Subject: Fixed coordinate system conversion for gestures. When converting hotspot position (which is in global coordinates) to graphics scene coordinates we should use the viewport because the mapToScene() takes a position in a viewport. Task-number: related to QTBUG-6876 Reviewed-by: Thomas Zander --- src/gui/graphicsview/qgraphicsscene.cpp | 8 +++--- tests/auto/gestures/tst_gestures.cpp | 45 ++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 365afdd..a72761a 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5972,12 +5972,12 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) QList allGestures = event->gestures(); DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" - << "Delivering gestures:" << allGestures; + << "Gestures:" << allGestures; QSet startedGestures; - QPoint delta = graphicsView->mapFromGlobal(QPoint()); - QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y()) - * graphicsView->viewportTransform().inverted(); + QPoint delta = viewport->mapFromGlobal(QPoint()); + QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y()) + * graphicsView->viewportTransform().inverted(); foreach (QGesture *gesture, allGestures) { // cache scene coordinates of the hot spot if (gesture->hasHotSpot()) { diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index a2058cd..a1afa0a 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -58,7 +58,7 @@ static QPointF mapToGlobal(const QPointF &pt, QGraphicsItem *item, QGraphicsView *view) { - return view->mapToGlobal(view->mapFromScene(item->mapToScene(pt))); + return view->viewport()->mapToGlobal(view->mapFromScene(item->mapToScene(pt))); } class CustomGesture : public QGesture @@ -353,6 +353,7 @@ private slots: void deleteGestureTargetWidget(); void deleteGestureTargetItem_data(); void deleteGestureTargetItem(); + void viewportCoordinates(); }; tst_Gestures::tst_Gestures() @@ -742,7 +743,6 @@ public: ignoredFinishedGestures.clear(); } -protected: QRectF boundingRect() const { return size; @@ -1771,7 +1771,6 @@ void tst_Gestures::panelStacksBehindParent() void tst_Gestures::deleteGestureTargetWidget() { - } void tst_Gestures::deleteGestureTargetItem_data() @@ -1857,5 +1856,45 @@ void tst_Gestures::deleteGestureTargetItem() sendCustomGesture(&event, item1, &scene); } +class GraphicsView : public QGraphicsView +{ +public: + GraphicsView(QGraphicsScene *scene, QWidget *parent = 0) + : QGraphicsView(scene, parent) + { + } + + using QGraphicsView::setViewportMargins; +}; + +// just making sure that even if the graphicsview has margins hotspot still +// works properly. It should use viewport for converting global coordinates to +// scene coordinates. +void tst_Gestures::viewportCoordinates() +{ + QGraphicsScene scene; + GraphicsView view(&scene); + view.setViewportMargins(10,20,15,25); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); + + GestureItem *item1 = new GestureItem("item1"); + item1->grabGesture(CustomGesture::GestureType); + item1->size = QRectF(0, 0, 3, 3); + item1->setZValue(2); + scene.addItem(item1); + + view.show(); + QTest::qWaitForWindowShown(&view); + view.ensureVisible(scene.sceneRect()); + + view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren); + + CustomEvent event; + event.hotSpot = mapToGlobal(item1->boundingRect().center(), item1, &view); + event.hasHotSpot = true; + sendCustomGesture(&event, item1, &scene); + QVERIFY(item1->gestureEventsReceived != 0); +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" -- cgit v0.12 From 51bfbc326be268f552650dc30408479150a36744 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 1 Mar 2010 15:21:32 +0100 Subject: Extended gesture autotest. Make sure partial gestures do not propagate further if an item that expects partial gestures received it. Task-number: resulted from QTBUG-6876 Reviewed-by: trustme --- src/gui/graphicsview/qgraphicsscene.cpp | 7 ++++- tests/auto/gestures/tst_gestures.cpp | 53 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a72761a..6bc02cc 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -6003,7 +6003,8 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) cachedTargetItems = cachedItemGestures.keys(); qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst); DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" - << "Conflicting gestures:" << conflictedGestures; + << "Normal gestures:" << normalGestures + << "Conflicting gestures:" << conflictedGestures; // deliver conflicted gestures as override events AND remember // initial gesture targets @@ -6080,6 +6081,10 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event) const Qt::GestureFlags flags = d->gestureContext.value(gesture->gestureType()); if (flags & Qt::IgnoredGesturesPropagateToParent) parentPropagatedGestures.insert(gesture); + } else { + DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:" + << "no target for" << gesture << "at" + << gesture->hotSpot() << gesture->d_func()->sceneHotSpot; } } qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst); diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index a1afa0a..f8ecca3 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -354,6 +354,7 @@ private slots: void deleteGestureTargetItem_data(); void deleteGestureTargetItem(); void viewportCoordinates(); + void partialGesturePropagation(); }; tst_Gestures::tst_Gestures() @@ -1896,5 +1897,57 @@ void tst_Gestures::viewportCoordinates() QVERIFY(item1->gestureEventsReceived != 0); } +void tst_Gestures::partialGesturePropagation() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + view.setWindowFlags(Qt::X11BypassWindowManagerHint); + + GestureItem *item1 = new GestureItem("item1"); + item1->grabGesture(CustomGesture::GestureType); + item1->setZValue(8); + scene.addItem(item1); + + GestureItem *item2 = new GestureItem("item2[partial]"); + item2->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures); + item2->setZValue(6); + scene.addItem(item2); + + GestureItem *item3 = new GestureItem("item3"); + item3->grabGesture(CustomGesture::GestureType); + item3->setZValue(4); + scene.addItem(item3); + + GestureItem *item4 = new GestureItem("item4[partial]"); + item4->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures); + item4->setZValue(2); + scene.addItem(item4); + + view.show(); + QTest::qWaitForWindowShown(&view); + view.ensureVisible(scene.sceneRect()); + + view.viewport()->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren); + + item1->ignoredUpdatedGestures << CustomGesture::GestureType; + + CustomEvent event; + event.hotSpot = mapToGlobal(QPointF(5, 5), item1, &view); + event.hasHotSpot = true; + sendCustomGesture(&event, item1, &scene); + + static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; + + QCOMPARE(item1->gestureOverrideEventsReceived, 1); + QCOMPARE(item2->gestureOverrideEventsReceived, 1); + QCOMPARE(item3->gestureOverrideEventsReceived, 1); + QCOMPARE(item4->gestureOverrideEventsReceived, 1); + + QCOMPARE(item1->gestureEventsReceived, TotalGestureEventsCount); + QCOMPARE(item2->gestureEventsReceived, TotalGestureEventsCount-2); // except for started and finished + QCOMPARE(item3->gestureEventsReceived, 0); + QCOMPARE(item4->gestureEventsReceived, 0); +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" -- cgit v0.12