summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@digia.com>2016-03-14 14:28:55 +0100
committerShawn Rutledge <shawn.rutledge@theqtcompany.com>2016-04-07 12:35:03 +0000
commit5f136bccd80d44eaca8928c9307a5dd25b33bf6d (patch)
tree57f4a7a15ba7a22a5857e313d0bda59e1e11e9a5 /src/gui/kernel
parentccb693299e6ef633d3ac330961c872a03815c93c (diff)
QTouchEvent: add uniqueId and rotation; TUIO: support fiducial tokens
TUIO supports tracking tagged physical objects on touchscreens by various means (QR codes, RFIDs etc.) It can detect both position and rotation. Likewise, it may be possible for some touchscreens or drivers to detect orientation of the fingers. So, just as QTabletEvent has rotation, each touchpoint needs to include the rotation value. When using tokens, each object has a permanent unique ID, whereas QTouchEvent::TouchPoint::id() is a transient ID which usually auto- increments each time a finger is pressed to the device. So we need to make that available too, to identify each token. Different platforms may use different kinds of IDs (int, UUID, QR code etc.); however for TUIO 1.x, the unique IDs are just 32-bit integers. QPointerUniqueId is added, storing only a qint64 for now (like QTabletEvent::uniqueId()) but able to be expanded as necessary later on. Task-number: QTBUG-51844 Change-Id: I04182042f47fa2954728079139a4664a31184b54 Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qevent.cpp79
-rw-r--r--src/gui/kernel/qevent.h23
-rw-r--r--src/gui/kernel/qevent_p.h2
-rw-r--r--src/gui/kernel/qguiapplication.cpp4
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp3
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h5
6 files changed, 113 insertions, 3 deletions
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 2b3b153537..2d3707c049 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -4421,6 +4421,7 @@ QTouchEvent::~QTouchEvent()
The values of this enum describe additional information about a touch point.
\value Pen Indicates that the contact has been made by a designated pointing device (e.g. a pen) instead of a finger.
+ \value Token Indicates that the contact has been made by a fiducial object (e.g. a knob or other token) instead of a finger.
*/
/*!
@@ -4467,6 +4468,22 @@ int QTouchEvent::TouchPoint::id() const
}
/*!
+ \since 5.8
+ Returns the unique ID of this touch point or token, if any.
+
+ It is normally invalid (with a \l {QPointerUniqueId::numeric()} {numeric()} value of -1),
+ because touchscreens cannot uniquely identify fingers. But when the
+ \l {TouchPoint::InfoFlag} {Token} flag is set, it is expected to uniquely
+ identify a specific token (fiducial object).
+
+ \sa flags
+*/
+QPointerUniqueId QTouchEvent::TouchPoint::uniqueId() const
+{
+ return d->uniqueId;
+}
+
+/*!
Returns the current state of this touch point.
*/
Qt::TouchPointState QTouchEvent::TouchPoint::state() const
@@ -4670,6 +4687,19 @@ qreal QTouchEvent::TouchPoint::pressure() const
}
/*!
+ \since 5.8
+ Returns the angular orientation of this touch point. The return value is in degrees,
+ where zero (the default) indicates the finger or token is pointing upwards,
+ a negative angle means it's rotated to the left, and a positive angle means
+ it's rotated to the right. Most touchscreens do not detect rotation, so
+ zero is the most common value.
+*/
+qreal QTouchEvent::TouchPoint::rotation() const
+{
+ return d->rotation;
+}
+
+/*!
Returns a velocity vector for this touch point.
The vector is in the screen's coordinate system, using pixels per seconds for the magnitude.
@@ -4720,6 +4750,14 @@ void QTouchEvent::TouchPoint::setId(int id)
}
/*! \internal */
+void QTouchEvent::TouchPoint::setUniqueId(qint64 uid)
+{
+ if (d->ref.load() != 1)
+ d = d->detach();
+ d->uniqueId = QPointerUniqueId(uid);
+}
+
+/*! \internal */
void QTouchEvent::TouchPoint::setState(Qt::TouchPointStates state)
{
if (d->ref.load() != 1)
@@ -4856,6 +4894,14 @@ void QTouchEvent::TouchPoint::setPressure(qreal pressure)
}
/*! \internal */
+void QTouchEvent::TouchPoint::setRotation(qreal angle)
+{
+ if (d->ref.load() != 1)
+ d = d->detach();
+ d->rotation = angle;
+}
+
+/*! \internal */
void QTouchEvent::TouchPoint::setVelocity(const QVector2D &v)
{
if (d->ref.load() != 1)
@@ -5126,4 +5172,37 @@ Qt::ApplicationState QApplicationStateChangeEvent::applicationState() const
return m_applicationState;
}
+/*!
+ \class QPointerUniqueId
+ \since 5.8
+ \ingroup events
+ \inmodule QtGui
+
+ \brief QPointerUniqueId identifies a unique object, such as a tagged token
+ or stylus, which is used with a pointing device.
+
+ \sa QTouchEvent::TouchPoint
+*/
+
+/*!
+ Constructs a unique pointer ID with a numeric \a id provided by the hardware.
+ The default is -1, which means an invalid pointer ID.
+*/
+QPointerUniqueId::QPointerUniqueId(qint64 id)
+ : m_numericId(id)
+{
+}
+
+/*!
+ \property QPointerUniqueId::numeric
+ \brief the numeric unique ID of the token represented by a touchpoint
+
+ This is the numeric unique ID if the device provides that type of ID;
+ otherwise it is -1.
+*/
+qint64 QPointerUniqueId::numeric()
+{
+ return m_numericId;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 1c42c61e85..785884681f 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -790,6 +790,22 @@ inline bool operator==(QKeyEvent *e, QKeySequence::StandardKey key){return (e ?
inline bool operator==(QKeySequence::StandardKey key, QKeyEvent *e){return (e ? e->matches(key) : false);}
#endif // QT_NO_SHORTCUT
+class QPointerUniqueIdPrivate;
+class Q_GUI_EXPORT QPointerUniqueId
+{
+ Q_GADGET
+ Q_PROPERTY(qint64 numeric READ numeric CONSTANT)
+public:
+ explicit QPointerUniqueId(qint64 id = -1);
+
+ qint64 numeric();
+
+private:
+ // TODO for TUIO 2, or any other type of complex token ID, a d-pointer can replace
+ // m_numericId without changing the size of this class.
+ qint64 m_numericId;
+};
+
class QTouchEventTouchPointPrivate;
class Q_GUI_EXPORT QTouchEvent : public QInputEvent
{
@@ -798,7 +814,8 @@ public:
{
public:
enum InfoFlag {
- Pen = 0x0001
+ Pen = 0x0001,
+ Token = 0x0002
};
#ifndef Q_MOC_RUN
// otherwise moc gives
@@ -824,6 +841,7 @@ public:
{ qSwap(d, other.d); }
int id() const;
+ QPointerUniqueId uniqueId() const;
Qt::TouchPointState state() const;
@@ -848,12 +866,14 @@ public:
QRectF screenRect() const;
qreal pressure() const;
+ qreal rotation() const;
QVector2D velocity() const;
InfoFlags flags() const;
QVector<QPointF> rawScreenPositions() const;
// internal
void setId(int id);
+ void setUniqueId(qint64 uid);
void setState(Qt::TouchPointStates state);
void setPos(const QPointF &pos);
void setScenePos(const QPointF &scenePos);
@@ -871,6 +891,7 @@ public:
void setSceneRect(const QRectF &sceneRect);
void setScreenRect(const QRectF &screenRect);
void setPressure(qreal pressure);
+ void setRotation(qreal angle);
void setVelocity(const QVector2D &v);
void setFlags(InfoFlags flags);
void setRawScreenPositions(const QVector<QPointF> &positions);
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index 726aa05d36..2d6a6560da 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -79,12 +79,14 @@ public:
QAtomicInt ref;
int id;
+ QPointerUniqueId uniqueId;
Qt::TouchPointStates state;
QRectF rect, sceneRect, screenRect;
QPointF normalizedPos,
startPos, startScenePos, startScreenPos, startNormalizedPos,
lastPos, lastScenePos, lastScreenPos, lastNormalizedPos;
qreal pressure;
+ qreal rotation;
QVector2D velocity;
QTouchEvent::TouchPoint::InfoFlags flags;
QVector<QPointF> rawScreenPositions;
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 3855c9dab9..c97d3bb61a 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2518,7 +2518,9 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
// Stationary points might not be delivered down to the receiving item
// and get their position transformed, keep the old values instead.
- if (touchPoint.state() != Qt::TouchPointStationary)
+ if (touchPoint.state() == Qt::TouchPointStationary)
+ touchInfo.touchPoint.setVelocity(touchPoint.velocity());
+ else
touchInfo.touchPoint = touchPoint;
break;
}
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 5b91f1bc7e..abcd6c113b 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -468,7 +468,10 @@ QList<QTouchEvent::TouchPoint>
QList<QWindowSystemInterface::TouchPoint>::const_iterator end = points.constEnd();
while (point != end) {
p.setId(point->id);
+ if (point->uniqueId >= 0)
+ p.setUniqueId(point->uniqueId);
p.setPressure(point->pressure);
+ p.setRotation(point->rotation);
states |= point->state;
p.setState(point->state);
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index eff3986788..cde70a1102 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -117,11 +117,14 @@ public:
static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods = Qt::NoModifier);
struct TouchPoint {
- TouchPoint() : id(0), pressure(0), state(Qt::TouchPointStationary), flags(0) { }
+ TouchPoint() : id(0), uniqueId(-1), pressure(0), rotation(0), state(Qt::TouchPointStationary), flags(0) { }
int id; // for application use
+ qint64 uniqueId; // for TUIO: object/token ID; otherwise empty
+ // TODO for TUIO 2.0: add registerPointerUniqueID(QPointerUniqueId)
QPointF normalPosition; // touch device coordinates, (0 to 1, 0 to 1)
QRectF area; // the touched area, centered at position in screen coordinates
qreal pressure; // 0 to 1
+ qreal rotation; // 0 means pointing straight up; 0 if unknown (like QTabletEvent::rotation)
Qt::TouchPointState state; //Qt::TouchPoint{Pressed|Moved|Stationary|Released}
QVector2D velocity; // in screen coordinate system, pixels / seconds
QTouchEvent::TouchPoint::InfoFlags flags;