diff options
-rw-r--r-- | src/quick/items/qquickevents.cpp | 129 | ||||
-rw-r--r-- | src/quick/items/qquickevents_p_p.h | 100 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 3 | ||||
-rw-r--r-- | tests/auto/quick/qquickwindow/tst_qquickwindow.cpp | 67 |
4 files changed, 151 insertions, 148 deletions
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index d7f5d347ce..cb48255c4e 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -441,6 +441,11 @@ Item { \l inverted always returns false. */ + +QQuickEventTouchPoint::QQuickEventTouchPoint(QQuickPointerTouchEvent *parent) + : QQuickEventPoint(parent), m_rotation(0), m_pressure(0) +{} + /*! \internal \class QQuickPointerEvent @@ -455,23 +460,11 @@ Item { dynamically create and destroy objects of this type for each event. */ -/*! - \internal - Reset the current event to \a ev, which must be a touch, mouse or tablet event. -*/ -QQuickPointerEvent *QQuickPointerEvent::reset(QEvent *ev) { - m_event = static_cast<QInputEvent*>(ev); - if (isMouseEvent()) { - initFromMouse(static_cast<QMouseEvent*>(ev)); - } else if (isTouchEvent()) { - initFromTouch(static_cast<QTouchEvent*>(ev)); - } else { - Q_ASSERT_X(false, "", "invalid event type"); - } - return this; -} +QQuickPointerEvent::~QQuickPointerEvent() +{} -void QQuickPointerEvent::initFromMouse(QMouseEvent *ev) { +QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event) { + auto ev = static_cast<QMouseEvent*>(event); m_device = QQuickWindowPrivate::genericMouseDevice; m_event = ev; m_button = ev->button(); @@ -491,14 +484,12 @@ void QQuickPointerEvent::initFromMouse(QMouseEvent *ev) { default: break; } - - if (!m_mousePoint) - m_mousePoint = new QQuickEventPoint(this); - m_pointCount = 1; m_mousePoint->reset(state, ev->windowPos(), 0, ev->timestamp()); // mouse is 0 + return this; } -void QQuickPointerEvent::initFromTouch(QTouchEvent *ev) { +QQuickPointerEvent *QQuickPointerTouchEvent::reset(QEvent *event) { + auto ev = static_cast<QTouchEvent*>(event); m_device = QQuickWindowPrivate::touchDevice(ev->device()); m_event = ev; m_button = Qt::NoButton; @@ -512,6 +503,7 @@ void QQuickPointerEvent::initFromTouch(QTouchEvent *ev) { for (int i = 0; i < m_pointCount; ++i) m_touchPoints.at(i)->reset(tps.at(i), ev->timestamp()); + return this; } /*! @@ -534,34 +526,16 @@ QMouseEvent *QQuickPointerEvent::asMouseEvent() const { return nullptr; } -bool QQuickPointerEvent::isMouseEvent() const -{ - return m_event - && m_event->type() >= QEvent::MouseButtonPress - && m_event->type() <= QEvent::MouseMove; -} - -bool QQuickPointerEvent::isTouchEvent() const -{ - return m_event - && ((m_event->type() >= QEvent::TouchBegin && m_event->type() <= QEvent::TouchEnd) - || m_event->type() == QEvent::TouchCancel); +QQuickEventPoint *QQuickPointerMouseEvent::point(int i) const { + if (i == 0) + return m_mousePoint; + return nullptr; } -bool QQuickPointerEvent::isTabletEvent() const -{ - if (!m_event) - return false; - switch (m_event->type()) { - case QEvent::TabletPress: - case QEvent::TabletRelease: - case QEvent::TabletMove: - case QEvent::TabletEnterProximity: - case QEvent::TabletLeaveProximity: - return true; - default: - return false; - } +QQuickEventPoint *QQuickPointerTouchEvent::point(int i) const { + if (i >= 0 && i < m_pointCount) + return m_touchPoints.at(i); + return nullptr; } QQuickEventPoint::QQuickEventPoint(QQuickPointerEvent *parent) @@ -576,27 +550,14 @@ QQuickPointerEvent *QQuickEventPoint::pointerEvent() const return static_cast<QQuickPointerEvent *>(parent()); } -QQuickEventPoint *QQuickPointerEvent::point(int i) const { - if (Q_UNLIKELY(i < 0 || i >= m_pointCount)) - return nullptr; - if (isTouchEvent()) - return m_touchPoints.at(i); - if (isMouseEvent()) - return m_mousePoint; - return nullptr; +bool QQuickPointerMouseEvent::allPointsAccepted() const { + return m_mousePoint->isAccepted(); } -bool QQuickPointerEvent::allPointsAccepted() const -{ - Q_ASSERT(m_event && !isTabletEvent()); - if (isMouseEvent()) { - return m_mousePoint->isAccepted(); - } - if (isTouchEvent()) { - for (int i = 0; i < m_pointCount; ++i) { - if (!m_touchPoints.at(i)->isAccepted()) - return false; - } +bool QQuickPointerTouchEvent::allPointsAccepted() const { + for (int i = 0; i < m_pointCount; ++i) { + if (!m_touchPoints.at(i)->isAccepted()) + return false; } return true; } @@ -608,7 +569,7 @@ bool QQuickPointerEvent::allPointsAccepted() const If the touchpoint cannot be found, this returns nullptr. Ownership of the event is NOT transferred to the caller. */ -QMouseEvent *QQuickPointerEvent::syntheticMouseEvent(int pointID, QQuickItem *relativeTo) const { +QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickItem *relativeTo) const { const QTouchEvent::TouchPoint *p = touchPointById(pointID); if (!p) return nullptr; @@ -652,30 +613,34 @@ QMouseEvent *QQuickPointerEvent::syntheticMouseEvent(int pointID, QQuickItem *re Returns a pointer to the QQuickEventPoint which has the \a pointId as \l {QQuickEventPoint::pointId}{pointId}. Returns nullptr if there is no point with that ID. + + \fn QQuickPointerEvent::pointById(quint64 pointId) const */ -QQuickEventPoint *QQuickPointerEvent::pointById(quint64 pointId) const { - if (isMouseEvent()) { - if (m_mousePoint && pointId == m_mousePoint->pointId()) - return m_mousePoint; - } - if (isTouchEvent()) { - auto it = std::find_if(m_touchPoints.constBegin(), m_touchPoints.constEnd(), - [pointId](const QQuickEventTouchPoint *tp) { return tp->pointId() == pointId; } ); - if (it != m_touchPoints.constEnd()) { - return *it; - } - } - // TODO it could alternatively be a tablet point + + + +QQuickEventPoint *QQuickPointerMouseEvent::pointById(quint64 pointId) const { + if (m_mousePoint && pointId == m_mousePoint->pointId()) + return m_mousePoint; return nullptr; } +QQuickEventPoint *QQuickPointerTouchEvent::pointById(quint64 pointId) const { + auto it = std::find_if(m_touchPoints.constBegin(), m_touchPoints.constEnd(), + [pointId](const QQuickEventTouchPoint *tp) { return tp->pointId() == pointId; } ); + if (it != m_touchPoints.constEnd()) + return *it; + return nullptr; +} + + /*! \internal Returns a pointer to the original TouchPoint which has the same \l {QTouchEvent::TouchPoint::id}{id} as \a pointId, if the original event is a QTouchEvent, and if that point is found. Otherwise, returns nullptr. */ -const QTouchEvent::TouchPoint *QQuickPointerEvent::touchPointById(int pointId) const { +const QTouchEvent::TouchPoint *QQuickPointerTouchEvent::touchPointById(int pointId) const { const QTouchEvent *ev = asTouchEvent(); if (!ev) return nullptr; @@ -690,7 +655,7 @@ const QTouchEvent::TouchPoint *QQuickPointerEvent::touchPointById(int pointId) c \internal Make a new QTouchEvent, giving it a subset of the original touch points. */ -QTouchEvent *QQuickPointerEvent::touchEventForItem(const QList<const QQuickEventPoint *> &newPoints, QQuickItem *relativeTo) const +QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(const QList<const QQuickEventPoint *> &newPoints, QQuickItem *relativeTo) const { QList<QTouchEvent::TouchPoint> touchPoints; Qt::TouchPointStates eventStates; diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index ceebe6207d..123d5e5280 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -63,6 +63,8 @@ QT_BEGIN_NAMESPACE class QQuickItem; class QQuickPointerDevice; +class QQuickPointerEvent; +class QQuickPointerTouchEvent; class QQuickKeyEvent : public QObject { @@ -241,8 +243,6 @@ private: bool _accepted; }; -class QQuickPointerEvent; - class Q_QUICK_PRIVATE_EXPORT QQuickEventPoint : public QObject { Q_OBJECT @@ -298,7 +298,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventTouchPoint : public QQuickEventPoint Q_PROPERTY(QPointerUniqueId uniqueId READ uniqueId) public: - QQuickEventTouchPoint(QQuickPointerEvent *parent) : QQuickEventPoint(parent), m_rotation(0), m_pressure(0) { } + QQuickEventTouchPoint(QQuickPointerTouchEvent *parent); void reset(const QTouchEvent::TouchPoint &tp, ulong timestamp) { @@ -333,10 +333,10 @@ public: , m_event(nullptr) , m_button(Qt::NoButton) , m_pressedButtons(Qt::NoButton) - , m_pointCount(0) - , m_mousePoint(nullptr) , m_synthMouseEvent(QEvent::MouseMove, QPointF(), Qt::NoButton, Qt::NoButton, Qt::NoModifier) { } + virtual ~QQuickPointerEvent(); + public: // property accessors const QQuickPointerDevice *device() const { return m_device; } Qt::KeyboardModifiers modifiers() const { return m_event ? m_event->modifiers() : Qt::NoModifier; } @@ -344,44 +344,74 @@ public: // property accessors Qt::MouseButtons buttons() const { return m_pressedButtons; } public: // helpers for C++ only (during event delivery) - QQuickPointerEvent *reset(QEvent *ev); + virtual QQuickPointerEvent *reset(QEvent *ev) = 0; QTouchEvent *asTouchEvent() const; QMouseEvent *asMouseEvent() const; - bool isMouseEvent() const; - bool isTouchEvent() const; - bool isTabletEvent() const; + virtual bool isMouseEvent() const { return false; } + virtual bool isTouchEvent() const { return false; } + virtual bool isTabletEvent() const { return false; } bool isValid() const { return m_event != nullptr; } - bool allPointsAccepted() const; - - int pointCount() const { return m_pointCount; } - QQuickEventPoint *point(int i) const; - QQuickEventPoint *pointById(quint64 pointId) const; + virtual bool allPointsAccepted() const = 0; - const QTouchEvent::TouchPoint *touchPointById(int pointId) const; + virtual int pointCount() const = 0; + virtual QQuickEventPoint *point(int i) const = 0; + virtual QQuickEventPoint *pointById(quint64 pointId) const = 0; - QTouchEvent *touchEventForItem(const QList<const QQuickEventPoint *> &newPoints, QQuickItem *relativeTo) const; - - QMouseEvent *syntheticMouseEvent(int pointID, QQuickItem *relativeTo) const; - -private: - void initFromMouse(QMouseEvent *ev); - void initFromTouch(QTouchEvent *ev); +protected: -private: const QQuickPointerDevice *m_device; QInputEvent *m_event; // original event as received by QQuickWindow Qt::MouseButton m_button; Qt::MouseButtons m_pressedButtons; - int m_pointCount; - QVector<QQuickEventTouchPoint *> m_touchPoints; - QQuickEventPoint *m_mousePoint; mutable QMouseEvent m_synthMouseEvent; Q_DISABLE_COPY(QQuickPointerEvent) }; +class Q_QUICK_PRIVATE_EXPORT QQuickPointerMouseEvent : public QQuickPointerEvent +{ +public: + QQuickPointerMouseEvent(QObject *parent = nullptr) + : QQuickPointerEvent(parent), m_mousePoint(new QQuickEventPoint(this)) + { + } + + QQuickPointerEvent *reset(QEvent *) override; + bool isMouseEvent() const override { return true; } + int pointCount() const override { return 1; } + QQuickEventPoint *point(int i) const override; + QQuickEventPoint *pointById(quint64 pointId) const override; + bool allPointsAccepted() const override; + +private: + QQuickEventPoint *m_mousePoint; +}; + +class Q_QUICK_PRIVATE_EXPORT QQuickPointerTouchEvent : public QQuickPointerEvent +{ +public: + QQuickPointerTouchEvent(QObject *parent = nullptr) + : QQuickPointerEvent(parent) + {} + + QQuickPointerEvent *reset(QEvent *) override; + bool isTouchEvent() const override { return true; } + int pointCount() const override { return m_pointCount; } + QQuickEventPoint *point(int i) const override; + QQuickEventPoint *pointById(quint64 pointId) const override; + const QTouchEvent::TouchPoint *touchPointById(int pointId) const; + bool allPointsAccepted() const override; + + QMouseEvent *syntheticMouseEvent(int pointID, QQuickItem *relativeTo) const; + QTouchEvent *touchEventForItem(const QList<const QQuickEventPoint *> &newPoints, QQuickItem *relativeTo) const; + +private: + int m_pointCount; + QVector<QQuickEventTouchPoint *> m_touchPoints; +}; + // ### Qt 6: move this to qtbase, replace QTouchDevice and the enums in QTabletEvent class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject { @@ -439,10 +469,18 @@ public: QQuickPointerDevice(DeviceType devType, PointerType pType, Capabilities caps, int maxPoints, int buttonCount, const QString &name, qint64 uniqueId = 0) : m_deviceType(devType), m_pointerType(pType), m_capabilities(caps) - , m_maximumTouchPoints(maxPoints), m_buttonCount(buttonCount), m_name(name), m_uniqueId(uniqueId) - {} + , m_maximumTouchPoints(maxPoints), m_buttonCount(buttonCount), m_name(name), m_uniqueId(uniqueId), m_event(nullptr) + { + if (m_deviceType == Mouse) { + m_event = new QQuickPointerMouseEvent; + } else if (m_deviceType == TouchScreen || m_deviceType == TouchPad) { + m_event = new QQuickPointerTouchEvent; + } else { + Q_ASSERT(false); + } + } - ~QQuickPointerDevice() { } + ~QQuickPointerDevice() { delete m_event; } DeviceType type() const { return m_deviceType; } PointerType pointerType() const { return m_pointerType; } Capabilities capabilities() const { return m_capabilities; } @@ -451,7 +489,7 @@ public: int buttonCount() const { return m_buttonCount; } QString name() const { return m_name; } qint64 uniqueId() const { return m_uniqueId; } - QQuickPointerEvent *pointerEvent() const { return &m_event; } + QQuickPointerEvent *pointerEvent() const { return m_event; } private: DeviceType m_deviceType; @@ -462,7 +500,7 @@ private: QString m_name; qint64 m_uniqueId; // the device-specific event instance which is reused during event delivery - mutable QQuickPointerEvent m_event; + QQuickPointerEvent *m_event; Q_DISABLE_COPY(QQuickPointerDevice) }; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 9a0cff1abc..2210194114 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2365,7 +2365,8 @@ bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, const QQ const QSet<quint64> &matchingNewPoints, const QList<const QQuickEventPoint *> &matchingPoints, QSet<QQuickItem *> *hasFiltered) { - QScopedPointer<QTouchEvent> touchEvent(event->touchEventForItem(matchingPoints, item)); + auto pointerTouchEvent = static_cast<const QQuickPointerTouchEvent*>(event); + QScopedPointer<QTouchEvent> touchEvent(pointerTouchEvent->touchEventForItem(matchingPoints, item)); if (touchEvent.data()->touchPoints().isEmpty()) return false; bool touchEventAccepted = false; diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp index fd1024a8b3..18f1b28b02 100644 --- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp +++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp @@ -2322,48 +2322,47 @@ void tst_qquickwindow::testHoverChildMouseEventFilter() void tst_qquickwindow::pointerEventTypeAndPointCount() { - QQuickPointerEvent pe; QMouseEvent me(QEvent::MouseButtonPress, QPointF(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QTouchEvent te(QEvent::TouchBegin, touchDevice, Qt::NoModifier, Qt::TouchPointPressed, QList<QTouchEvent::TouchPoint>() << QTouchEvent::TouchPoint(1)); - QVERIFY(!pe.isValid()); - - pe.reset(&me); - QVERIFY(pe.isValid()); - QVERIFY(pe.isMouseEvent()); - QVERIFY(!pe.isTouchEvent()); - QVERIFY(!pe.isTabletEvent()); - QVERIFY(pe.asMouseEvent()); - QVERIFY(!pe.asTouchEvent()); -// QVERIFY(!pe.asTabletEvent()); // TODO - QCOMPARE(pe.pointCount(), 1); - - pe.reset(&te); - QVERIFY(pe.isValid()); - QVERIFY(!pe.isMouseEvent()); - QVERIFY(pe.isTouchEvent()); - QVERIFY(!pe.isTabletEvent()); - QVERIFY(!pe.asMouseEvent()); - QVERIFY(pe.asTouchEvent()); -// QVERIFY(!pe.asTabletEvent()); // TODO - QCOMPARE(pe.pointCount(), 1); - QCOMPARE(pe.touchPointById(1)->id(), 1); - QVERIFY(!pe.touchPointById(0)); + QQuickPointerMouseEvent pme; + pme.reset(&me); + QVERIFY(pme.isValid()); + QVERIFY(pme.isMouseEvent()); + QVERIFY(!pme.isTouchEvent()); + QVERIFY(!pme.isTabletEvent()); + QVERIFY(pme.asMouseEvent()); + QVERIFY(!pme.asTouchEvent()); +// QVERIFY(!pe->asTabletEvent()); // TODO + QCOMPARE(pme.pointCount(), 1); + + QQuickPointerTouchEvent pte; + pte.reset(&te); + QVERIFY(pte.isValid()); + QVERIFY(!pte.isMouseEvent()); + QVERIFY(pte.isTouchEvent()); + QVERIFY(!pte.isTabletEvent()); + QVERIFY(!pte.asMouseEvent()); + QVERIFY(pte.asTouchEvent()); +// QVERIFY(!pte.asTabletEvent()); // TODO + QCOMPARE(pte.pointCount(), 1); + QCOMPARE(pte.touchPointById(1)->id(), 1); + QVERIFY(!pte.touchPointById(0)); te.setTouchPoints(QList<QTouchEvent::TouchPoint>() << QTouchEvent::TouchPoint(1) << QTouchEvent::TouchPoint(2)); - pe.reset(&te); - QCOMPARE(pe.pointCount(), 2); - QCOMPARE(pe.touchPointById(1)->id(), 1); - QCOMPARE(pe.touchPointById(2)->id(), 2); - QVERIFY(!pe.touchPointById(0)); + pte.reset(&te); + QCOMPARE(pte.pointCount(), 2); + QCOMPARE(pte.touchPointById(1)->id(), 1); + QCOMPARE(pte.touchPointById(2)->id(), 2); + QVERIFY(!pte.touchPointById(0)); te.setTouchPoints(QList<QTouchEvent::TouchPoint>() << QTouchEvent::TouchPoint(2)); - pe.reset(&te); - QCOMPARE(pe.pointCount(), 1); - QCOMPARE(pe.touchPointById(2)->id(), 2); - QVERIFY(!pe.touchPointById(1)); - QVERIFY(!pe.touchPointById(0)); + pte.reset(&te); + QCOMPARE(pte.pointCount(), 1); + QCOMPARE(pte.touchPointById(2)->id(), 2); + QVERIFY(!pte.touchPointById(1)); + QVERIFY(!pte.touchPointById(0)); } QTEST_MAIN(tst_qquickwindow) |