aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickevents_p_p.h
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@theqtcompany.com>2015-06-03 18:13:28 +0200
committerFrederik Gladhorn <frederik.gladhorn@qt.io>2016-07-07 14:12:56 +0000
commit649b309ea9ed7d03aa74565d51edb416c23460d9 (patch)
tree7f90aa25acf77f1a22f2d33d702587fb6ee30d3c /src/quick/items/qquickevents_p_p.h
parent2b171025bfedcbe5ac1c296a1f57400cd227ce2f (diff)
add QQuickPointerEvent and QQuickPointerDevice
QQuickPointerEvent is first of all a wrapper for mouse and touch events to help unify event delivery. Because the instances are reused between deliveries (as in change 0ac9389dbd7facaa424dc175e5f5dac514630eef), it is allowed to be a QObject. This will facilitate exposing pointer events to QML later on, as with the other event classes in qquickevents_p_p.h. It allows both device-agnostic and device-specific handling of point-based interaction using mice and touchscreens (tablet support will come later). The interface of QQuickPointerDevice is a superset of QTouchDevice plus the relevant mouse and tablet device info. The instances are long-lived, and included by pointer in each QQuickPointerEvent. Applications and device-specific event handlers can use the device info to filter out irrelevant events. Change-Id: Iacb42d41889a9a8634d57331ec6cc65c6b36f71f Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
Diffstat (limited to 'src/quick/items/qquickevents_p_p.h')
-rw-r--r--src/quick/items/qquickevents_p_p.h258
1 files changed, 258 insertions, 0 deletions
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 39c5a060b5..979d6e441a 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -222,10 +222,268 @@ private:
bool _accepted;
};
+// ### Qt 6: move this to qtbase, replace QTouchDevice and the enums in QTabletEvent
+class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(DeviceType type READ type CONSTANT)
+ Q_PROPERTY(PointerType pointerType READ pointerType CONSTANT)
+ Q_PROPERTY(Capabilities capabilities READ capabilities CONSTANT)
+ Q_PROPERTY(int maximumTouchPoints READ maximumTouchPoints CONSTANT)
+ Q_PROPERTY(int buttonCount READ buttonCount CONSTANT)
+ Q_PROPERTY(QString name READ name CONSTANT)
+ Q_PROPERTY(qint64 uniqueId READ uniqueId CONSTANT)
+
+public:
+ enum DeviceType {
+ UnknownDevice = 0x0000,
+ Mouse = 0x0001,
+ TouchScreen = 0x0002,
+ TouchPad = 0x0004,
+ Puck = 0x0008,
+ Stylus = 0x0010,
+ Airbrush = 0x0020,
+ AllDevices = 0x003F
+ };
+ Q_DECLARE_FLAGS(DeviceTypes, DeviceType)
+ Q_ENUM(DeviceType)
+ Q_FLAG(DeviceTypes)
+
+ enum PointerType {
+ GenericPointer = 0x0001,
+ Finger = 0x0002,
+ Pen = 0x0004,
+ Eraser = 0x0008,
+ Cursor = 0x0010,
+ AllPointerTypes = 0x001F
+ };
+ Q_DECLARE_FLAGS(PointerTypes, PointerType)
+ Q_ENUM(PointerType)
+ Q_FLAG(PointerTypes)
+
+ enum CapabilityFlag {
+ Position = 0x0001,
+ Area = 0x0002,
+ Pressure = 0x0004,
+ Velocity = 0x0008,
+ // some bits reserved in case we need more of QTouchDevice::Capabilities
+ Scroll = 0x0100, // mouse has a wheel, or there is OS-level scroll gesture recognition (dubious?)
+ Hover = 0x0200,
+ Rotation = 0x0400,
+ XTilt = 0x0800,
+ YTilt = 0x1000
+ };
+ Q_DECLARE_FLAGS(Capabilities, CapabilityFlag)
+ Q_ENUM(CapabilityFlag)
+ Q_FLAG(Capabilities)
+
+ 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)
+ {}
+
+ ~QQuickPointerDevice() { }
+ DeviceType type() const { return m_deviceType; }
+ PointerType pointerType() const { return m_pointerType; }
+ Capabilities capabilities() const { return m_capabilities; }
+ bool hasCapability(CapabilityFlag cap) { return m_capabilities & cap; }
+ int maximumTouchPoints() const { return m_maximumTouchPoints; }
+ int buttonCount() const { return m_buttonCount; }
+ QString name() const { return m_name; }
+ qint64 uniqueId() const { return m_uniqueId; }
+
+private:
+ DeviceType m_deviceType;
+ PointerType m_pointerType;
+ Capabilities m_capabilities;
+ int m_maximumTouchPoints;
+ int m_buttonCount;
+ QString m_name;
+ qint64 m_uniqueId;
+
+ Q_DISABLE_COPY(QQuickPointerDevice)
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPointerDevice::DeviceTypes)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPointerDevice::PointerTypes)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPointerDevice::Capabilities)
+
+class Q_QUICK_PRIVATE_EXPORT QQuickEventPoint : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QPointF scenePos READ scenePos)
+ Q_PROPERTY(Qt::TouchPointState state READ state)
+ Q_PROPERTY(quint64 pointId READ pointId)
+ Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+
+public:
+ QQuickEventPoint() : QObject(), m_pointId(0), m_valid(false), m_accept(false), m_state(Qt::TouchPointReleased)
+ {
+ Q_UNUSED(m_reserved);
+ }
+
+ void reset(Qt::TouchPointState state, QPointF scenePos, quint64 pointId)
+ {
+ m_scenePos = scenePos;
+ m_pointId = pointId;
+ m_valid = true;
+ m_accept = false;
+ m_state = state;
+ }
+
+ void invalidate() { m_valid = false; }
+
+ QPointF scenePos() const { return m_scenePos; }
+ Qt::TouchPointState state() const { return m_state; }
+ quint64 pointId() const { return m_pointId; }
+ bool isValid() const { return m_valid; }
+ bool isAccepted() const { return m_accept; }
+ void setAccepted(bool accepted) { m_accept = accepted; }
+
+private:
+ QPointF m_scenePos;
+ quint64 m_pointId;
+ bool m_valid : 1;
+ bool m_accept : 1;
+ Qt::TouchPointState m_state : 4;
+ int m_reserved : 26;
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickEventTouchPoint : public QQuickEventPoint
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal rotation READ rotation)
+ Q_PROPERTY(qreal pressure READ pressure)
+ Q_PROPERTY(QPointerUniqueId uniqueId READ uniqueId)
+
+public:
+ QQuickEventTouchPoint() : QQuickEventPoint(), m_rotation(0), m_pressure(0) { }
+
+ void reset(const QTouchEvent::TouchPoint &tp)
+ {
+ QQuickEventPoint::reset(tp.state(), tp.scenePos(), tp.id());
+ // TODO times and velocity
+ m_rotation = tp.rotation();
+ m_pressure = tp.pressure();
+ m_uniqueId = tp.uniqueId();
+ }
+
+ qreal rotation() const { return m_rotation; }
+ qreal pressure() const { return m_pressure; }
+ QPointerUniqueId uniqueId() const { return m_uniqueId; }
+
+private:
+ qreal m_rotation;
+ qreal m_pressure;
+ QPointerUniqueId m_uniqueId;
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickPointerEvent : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(const QQuickPointerDevice *device READ device)
+ Q_PROPERTY(Qt::KeyboardModifiers modifiers READ modifiers)
+ Q_PROPERTY(Qt::MouseButtons button READ button)
+ Q_PROPERTY(Qt::MouseButtons buttons READ buttons)
+
+public:
+ QQuickPointerEvent(QObject *parent = nullptr)
+ : QObject(parent)
+ , m_device(nullptr)
+ , m_event(nullptr)
+ , m_button(Qt::NoButton)
+ , m_pressedButtons(Qt::NoButton)
+ , m_mousePoint(nullptr) { }
+
+ void reset(const QQuickPointerDevice* dev, const QMouseEvent *ev) {
+ m_device = dev;
+ m_event = ev;
+ m_button = ev->button();
+ m_pressedButtons = ev->buttons();
+ Qt::TouchPointState state = Qt::TouchPointStationary;
+ switch (ev->type()) {
+ case QEvent::MouseButtonPress:
+ state = Qt::TouchPointPressed;
+ break;
+ case QEvent::MouseButtonRelease:
+ state = Qt::TouchPointReleased;
+ break;
+ case QEvent::MouseMove:
+ state = Qt::TouchPointMoved;
+ break;
+ default:
+ break;
+ }
+
+ if (!m_mousePoint)
+ m_mousePoint = new QQuickEventPoint;
+ m_mousePoint->reset(state, ev->windowPos(), 0); // mouse is 0
+ }
+
+ void reset(const QQuickPointerDevice* dev, const QTouchEvent *ev) {
+ m_device = dev;
+ m_event = ev;
+ m_button = Qt::NoButton;
+ m_pressedButtons = Qt::NoButton;
+
+ const QList<QTouchEvent::TouchPoint> &tps = ev->touchPoints();
+ const int pointCount = tps.count();
+ while (pointCount > m_touchPoints.count())
+ m_touchPoints.append(new QQuickEventTouchPoint);
+
+ for (int i = 0; i < pointCount; ++i)
+ m_touchPoints.at(i)->reset(tps.at(i));
+ }
+
+ const QQuickPointerDevice *device() const { return m_device; }
+ Qt::KeyboardModifiers modifiers() const { return m_event ? m_event->modifiers() : Qt::NoModifier; }
+ Qt::MouseButton button() const { return m_button; }
+ Qt::MouseButtons buttons() const { return m_pressedButtons; }
+
+ const QTouchEvent *asTouchEvent() const {
+ if (!m_event)
+ return nullptr;
+ switch (m_event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchCancel:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ return static_cast<const QTouchEvent *>(m_event);
+ default:
+ break;
+ }
+ return nullptr;
+ }
+
+ // helpers for C++ event delivery, not for QML properties
+ int pointCount() const { return asTouchEvent() ? m_touchPoints.count() : 1; }
+ const QQuickEventPoint *point(int i) const {
+ if (asTouchEvent())
+ return m_touchPoints.at(i);
+ return i == 0 ? m_mousePoint : nullptr;
+ }
+
+protected:
+ bool isValid() const { return m_event != nullptr; }
+
+protected:
+ const QQuickPointerDevice *m_device;
+ const QInputEvent *m_event; // original event as received by QQuickWindow
+ Qt::MouseButton m_button;
+ Qt::MouseButtons m_pressedButtons;
+ QVector<QQuickEventTouchPoint *> m_touchPoints;
+ QQuickEventPoint *m_mousePoint;
+
+ Q_DISABLE_COPY(QQuickPointerEvent)
+};
+
QT_END_NAMESPACE
QML_DECLARE_TYPE(QQuickKeyEvent)
QML_DECLARE_TYPE(QQuickMouseEvent)
QML_DECLARE_TYPE(QQuickWheelEvent)
+QML_DECLARE_TYPE(QQuickPointerDevice)
+QML_DECLARE_TYPE(QPointerUniqueId)
+QML_DECLARE_TYPE(QQuickPointerEvent)
#endif // QQUICKEVENTS_P_P_H