diff options
Diffstat (limited to 'tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp')
-rw-r--r-- | tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp | 225 |
1 files changed, 190 insertions, 35 deletions
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 26831002ce..4f4a11a79c 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -38,6 +38,7 @@ #include <QAbstractTextDocumentLayout> #include <QBitmap> #include <QCursor> +#include <QDesktopWidget> #include <QScreen> #include <QLabel> #include <QDial> @@ -54,10 +55,13 @@ #include <QPushButton> #include <QLineEdit> #include <QGraphicsLinearLayout> +#include <QTransform> #include <float.h> #include <QStyleHints> Q_DECLARE_METATYPE(QPainterPath) +Q_DECLARE_METATYPE(QSizeF) +Q_DECLARE_METATYPE(QTransform) #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) #include <windows.h> @@ -435,6 +439,8 @@ private slots: void focusHandling(); void touchEventPropagation_data(); void touchEventPropagation(); + void touchEventTransformation_data(); + void touchEventTransformation(); void deviceCoordinateCache_simpleRotations(); void resolvePaletteForItemChildren(); @@ -465,6 +471,7 @@ private slots: private: QList<QGraphicsItem *> paintedItems; + QTouchDevice *m_touchDevice = nullptr; }; void tst_QGraphicsItem::construction() @@ -10945,6 +10952,95 @@ void tst_QGraphicsItem::focusHandling() QCOMPARE(scene.focusItem(), focusableUnder); } +class TouchEventTestee : public QGraphicsRectItem +{ +public: + TouchEventTestee(const QSizeF &size = QSizeF(100, 100)) : + QGraphicsRectItem(QRectF(QPointF(), size)) + { + setAcceptTouchEvents(true); + setFlag(QGraphicsItem::ItemIsFocusable, false); + } + + QList<QTouchEvent::TouchPoint> touchBeginPoints() const { return m_touchBeginPoints; } + int touchBeginEventCount() const { return m_touchBeginPoints.size(); } + + QList<QTouchEvent::TouchPoint> touchUpdatePoints() const { return m_touchUpdatePoints; } + int touchUpdateEventCount() const { return m_touchUpdatePoints.size(); } + +protected: + bool sceneEvent(QEvent *ev) override + { + switch (ev->type()) { + case QEvent::TouchBegin: + m_touchBeginPoints.append(static_cast<const QTouchEvent *>(ev)->touchPoints().constFirst()); + ev->accept(); + return true; + case QEvent::TouchUpdate: + m_touchUpdatePoints.append(static_cast<const QTouchEvent *>(ev)->touchPoints().constFirst()); + ev->accept(); + return true; + default: + break; + } + + return QGraphicsRectItem::sceneEvent(ev); + } + +private: + QList<QTouchEvent::TouchPoint> m_touchBeginPoints; + QList<QTouchEvent::TouchPoint> m_touchUpdatePoints; +}; + +static QList<QTouchEvent::TouchPoint> + createTouchPoints(const QGraphicsView &view, + const QPointF &scenePos, + const QSizeF &ellipseDiameters, + Qt::TouchPointState state = Qt::TouchPointPressed) +{ + QTouchEvent::TouchPoint tp(0); + tp.setState(state); + tp.setScenePos(scenePos); + tp.setStartScenePos(scenePos); + tp.setLastScenePos(scenePos); + const QPointF screenPos = view.viewport()->mapToGlobal(view.mapFromScene(scenePos)); + tp.setScreenPos(screenPos); + tp.setStartScreenPos(screenPos); + tp.setLastScreenPos(screenPos); + tp.setEllipseDiameters(ellipseDiameters); + const QSizeF screenSize = QApplication::desktop()->screenGeometry(&view).size(); + tp.setNormalizedPos(QPointF(screenPos.x() / screenSize.width(), screenPos.y() / screenSize.height())); + return QList<QTouchEvent::TouchPoint>() << tp; +} + +static bool comparePointF(const QPointF &p1, const QPointF &p2) +{ + return qFuzzyCompare(p1.x(), p2.x()) && qFuzzyCompare(p1.y(), p2.y()); +} + +static bool compareSizeF(const QSizeF &s1, const QSizeF &s2) +{ + return qFuzzyCompare(s1.width(), s2.width()) && qFuzzyCompare(s1.height(), s2.height()); +} + +static QByteArray msgPointFComparisonFailed(const QPointF &p1, const QPointF &p2) +{ + return QByteArray::number(p1.x()) + ", " + QByteArray::number(p1.y()) + + " != " + QByteArray::number(p2.x()) + ", " + QByteArray::number(p2.y()); +} + +static QByteArray msgSizeFComparisonFailed(const QSizeF &s1, const QSizeF &s2) +{ + return QByteArray::number(s1.width()) + 'x' + QByteArray::number(s1.height()) + + " != " + QByteArray::number(s2.width()) + 'x' + QByteArray::number(s2.height()); +} + +#define COMPARE_POINTF(ACTUAL, EXPECTED) \ + QVERIFY2(comparePointF(ACTUAL, EXPECTED), msgPointFComparisonFailed(ACTUAL, EXPECTED).constData()) + +#define COMPARE_SIZEF(ACTUAL, EXPECTED) \ + QVERIFY2(compareSizeF(ACTUAL, EXPECTED), msgSizeFComparisonFailed(ACTUAL, EXPECTED).constData()) + void tst_QGraphicsItem::touchEventPropagation_data() { QTest::addColumn<QGraphicsItem::GraphicsItemFlag>("flag"); @@ -10963,29 +11059,7 @@ void tst_QGraphicsItem::touchEventPropagation() QFETCH(QGraphicsItem::GraphicsItemFlag, flag); QFETCH(int, expectedCount); - class Testee : public QGraphicsRectItem - { - public: - int touchBeginEventCount; - - Testee() - : QGraphicsRectItem(0, 0, 100, 100) - , touchBeginEventCount(0) - { - setAcceptTouchEvents(true); - setFlag(QGraphicsItem::ItemIsFocusable, false); - } - - bool sceneEvent(QEvent *ev) - { - if (ev->type() == QEvent::TouchBegin) - ++touchBeginEventCount; - - return QGraphicsRectItem::sceneEvent(ev); - } - }; - - Testee *touchEventReceiver = new Testee; + TouchEventTestee *touchEventReceiver = new TouchEventTestee; QGraphicsItem *topMost = new QGraphicsRectItem(touchEventReceiver->boundingRect()); QGraphicsScene scene; @@ -10998,26 +11072,107 @@ void tst_QGraphicsItem::touchEventPropagation() topMost->setFlag(flag, true); QGraphicsView view(&scene); + view.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1String("::") + + QLatin1String(QTest::currentDataTag())); view.setSceneRect(touchEventReceiver->boundingRect()); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); - QCOMPARE(touchEventReceiver->touchBeginEventCount, 0); + QCOMPARE(touchEventReceiver->touchBeginEventCount(), 0); - QTouchEvent::TouchPoint tp(0); - tp.setState(Qt::TouchPointPressed); - tp.setScenePos(view.sceneRect().center()); - tp.setLastScenePos(view.sceneRect().center()); + const QPointF scenePos = view.sceneRect().center(); + sendMousePress(&scene, scenePos); + if (m_touchDevice == nullptr) + m_touchDevice = QTest::createTouchDevice(); + QTouchEvent touchBegin(QEvent::TouchBegin, m_touchDevice, Qt::NoModifier, Qt::TouchPointPressed, + createTouchPoints(view, scenePos, QSizeF(10, 10))); + touchBegin.setTarget(view.viewport()); - QList<QTouchEvent::TouchPoint> touchPoints; - touchPoints << tp; + qApp->sendEvent(&scene, &touchBegin); + QCOMPARE(touchEventReceiver->touchBeginEventCount(), expectedCount); +} - sendMousePress(&scene, tp.scenePos()); - QTouchDevice *device = QTest::createTouchDevice(); - QTouchEvent touchBegin(QEvent::TouchBegin, device, Qt::NoModifier, Qt::TouchPointPressed, touchPoints); +void tst_QGraphicsItem::touchEventTransformation_data() +{ + QTest::addColumn<QGraphicsItem::GraphicsItemFlag>("flag"); + QTest::addColumn<QTransform>("viewTransform"); + QTest::addColumn<QPointF>("touchScenePos"); + QTest::addColumn<QSizeF>("ellipseDiameters"); + QTest::addColumn<QPointF>("expectedItemPos"); + + QTest::newRow("notransform") + << QGraphicsItem::ItemIsSelectable << QTransform() + << QPointF(150, 150) << QSizeF(7, 8) << QPointF(50, 50); + QTest::newRow("scaled") + << QGraphicsItem::ItemIsSelectable << QTransform::fromScale(0.5, 0.5) + << QPointF(150, 150) << QSizeF(7, 8) << QPointF(50, 50); + // QTBUG-66192: When the item ignores the downscaling transformation, + // it will receive the touch point at 25,25 instead of 50,50. + QTest::newRow("scaled/ItemIgnoresTransformations") + << QGraphicsItem::ItemIgnoresTransformations << QTransform::fromScale(0.5, 0.5) + << QPointF(150, 150) << QSizeF(7, 8) << QPointF(25, 25); +} + +void tst_QGraphicsItem::touchEventTransformation() +{ + QFETCH(QGraphicsItem::GraphicsItemFlag, flag); + QFETCH(QTransform, viewTransform); + QFETCH(QPointF, touchScenePos); + QFETCH(QSizeF, ellipseDiameters); + QFETCH(QPointF, expectedItemPos); + + TouchEventTestee *touchEventReceiver = new TouchEventTestee; + + QGraphicsScene scene; + scene.addItem(touchEventReceiver); + const QPointF itemPos(100, 100); + + touchEventReceiver->setPos(itemPos); + + touchEventReceiver->setFlag(flag, true); + + QGraphicsView view(&scene); + view.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + QLatin1String("::") + + QLatin1String(QTest::currentDataTag())); + view.setSceneRect(QRectF(QPointF(0, 0), QSizeF(300, 300))); + view.setTransform(viewTransform); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QCOMPARE(touchEventReceiver->touchBeginEventCount(), 0); + + if (m_touchDevice == nullptr) + m_touchDevice = QTest::createTouchDevice(); + QTouchEvent touchBegin(QEvent::TouchBegin, m_touchDevice, Qt::NoModifier, Qt::TouchPointPressed, + createTouchPoints(view, touchScenePos, ellipseDiameters)); + touchBegin.setTarget(view.viewport()); + + QCoreApplication::sendEvent(&scene, &touchBegin); + QCOMPARE(touchEventReceiver->touchBeginEventCount(), 1); + + const QTouchEvent::TouchPoint touchBeginPoint = touchEventReceiver->touchBeginPoints().constFirst(); + + COMPARE_POINTF(touchBeginPoint.scenePos(), touchScenePos); + COMPARE_POINTF(touchBeginPoint.startScenePos(), touchScenePos); + COMPARE_POINTF(touchBeginPoint.lastScenePos(), touchScenePos); + COMPARE_POINTF(touchBeginPoint.pos(), expectedItemPos); + COMPARE_SIZEF(touchBeginPoint.ellipseDiameters(), ellipseDiameters); // Must remain untransformed + + QTouchEvent touchUpdate(QEvent::TouchUpdate, m_touchDevice, Qt::NoModifier, Qt::TouchPointMoved, + createTouchPoints(view, touchScenePos, ellipseDiameters, Qt::TouchPointMoved)); + touchUpdate.setTarget(view.viewport()); + + QCoreApplication::sendEvent(&scene, &touchUpdate); + QCOMPARE(touchEventReceiver->touchUpdateEventCount(), 1); + + const QTouchEvent::TouchPoint touchUpdatePoint = touchEventReceiver->touchUpdatePoints().constFirst(); + + COMPARE_POINTF(touchUpdatePoint.scenePos(), touchScenePos); + COMPARE_POINTF(touchBeginPoint.startScenePos(), touchScenePos); + COMPARE_POINTF(touchUpdatePoint.lastScenePos(), touchScenePos); + COMPARE_POINTF(touchUpdatePoint.pos(), expectedItemPos); + COMPARE_SIZEF(touchUpdatePoint.ellipseDiameters(), ellipseDiameters); // Must remain untransformed - qApp->sendEvent(&scene, &touchBegin); - QCOMPARE(touchEventReceiver->touchBeginEventCount, expectedCount); } void tst_QGraphicsItem::deviceCoordinateCache_simpleRotations() |