diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2016-09-08 10:10:12 +0200 |
---|---|---|
committer | Jani Heikkinen <jani.heikkinen@qt.io> | 2016-12-01 13:02:47 +0000 |
commit | 048447346bc1b78992be3ce4bf3292fc272f7e1a (patch) | |
tree | feb3a31098cba1ee7c6d090ac85e51778494c7ba /src/gui | |
parent | f4a33e345eb658996e171daa6478fdc2ef62ff17 (diff) |
QPointerUniqueId: make fit for release
- Declare as Q_MOVABLE_TYPE
- Prevent QList<QPointerUniqueId> from being instantiated
(use QVector instead)
- Add equality relational operators
- Add qHash() overload
- Replace non-default ctor with named ctor.
- Add Q_DECL_NOTHROW.
- Add Q_DECL_CONSTEXPR.
- Rename numeric() -> numericId().
- Update docs.
The extension vector for this class calls for additional
properties to be added later, but these are not user-
settable. It thus suffices to rely on the only data
member, a qint64, which can be reinterpreted to an index
into an array or hash with actual objects. This allows
to make the class a Trivial Type (ie. no overhead over
an int) while still supporting later extension. Cf.
QSslEllipticCurve as another example of such a class.
The extension has to maintain the following invariants,
encoded into user code by way of being used in inline
functions:
- m_numericId == -1 <=> !isValid()
This is trivial to support. An extension could not and
still cannot reinterpret the qint64 member as a d-pointer,
but a d-pointer is only necessary for user-settable
properties where updating a central private data structure
would cause too much contention.
Add a test.
Since this type is used in other modules, keep the existing
functions, but mark them as deprecated with the expectation
that these compat functions be removed before 5.8.0 final.
Task-number: QTBUG-54616
Change-Id: Ia3ede0ecaeeef4cd3ffa94a72b1050bd409713a5
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/kernel/qevent.cpp | 82 | ||||
-rw-r--r-- | src/gui/kernel/qevent.h | 36 |
2 files changed, 103 insertions, 15 deletions
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 254b8926c8..72cd374419 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -44,6 +44,7 @@ #include "qpa/qplatformdrag.h" #include "private/qevent_p.h" #include "qfile.h" +#include "qhashfunctions.h" #include "qmetaobject.h" #include "qmimedata.h" #include "private/qdnd_p.h" @@ -4474,7 +4475,7 @@ 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), + It is normally invalid (see \l {QPointerUniqueId::isValid()} {isValid()}), 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). @@ -4757,7 +4758,7 @@ void QTouchEvent::TouchPoint::setUniqueId(qint64 uid) { if (d->ref.load() != 1) d = d->detach(); - d->uniqueId = QPointerUniqueId(uid); + d->uniqueId = QPointerUniqueId::fromNumericId(uid); } /*! \internal */ @@ -5184,28 +5185,91 @@ Qt::ApplicationState QApplicationStateChangeEvent::applicationState() const \brief QPointerUniqueId identifies a unique object, such as a tagged token or stylus, which is used with a pointing device. + QPointerUniqueIds can be compared for equality, and can be used as keys in a QHash. + You get access to the numerical ID via numericId(), if the device supports such IDs. + For future extensions, though, you should not use that function, but compare objects + of this type using the equality operator. + + This class is a thin wrapper around an integer ID. You pass it into and out of + functions by value. + + This type actively prevents you from holding it in a QList, because doing so would + be very inefficient. Use a QVector instead, which has the same API as QList, but more + efficient storage. + \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. + \fn QPointerUniqueId::QPointerUniqueId() + Constructs an invalid unique pointer ID. +*/ + +/*! + Constructs a unique pointer ID from numeric ID \a id. */ -QPointerUniqueId::QPointerUniqueId(qint64 id) - : m_numericId(id) +QPointerUniqueId QPointerUniqueId::fromNumericId(qint64 id) { + QPointerUniqueId result; + result.m_numericId = id; + return result; } /*! - \property QPointerUniqueId::numeric + \fn bool QPointerUniqueId::isValid() + + Returns whether this unique pointer ID is valid, that is, it represents an actual + pointer. +*/ + +/*! + \property QPointerUniqueId::numericId \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; + If the device provides a numeric ID, isValid() returns true, and this + property provides the numeric ID; otherwise it is -1. + + You should not use the value of this property in portable code, but + instead rely on equality to identify pointers. + + \sa isValid() */ -qint64 QPointerUniqueId::numeric() const +qint64 QPointerUniqueId::numericId() const Q_DECL_NOTHROW { return m_numericId; } +/*! + \relates QPointerUniqueId + \since 5.8 + + Returns whether the two unique pointer IDs \a lhs and \a rhs identify the same pointer + (\c true) or not (\c false). +*/ +bool operator==(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW +{ + return lhs.numericId() == rhs.numericId(); +} + +/*! + \fn bool operator!=(QPointerUniqueId lhs, QPointerUniqueId rhs) + \relates QPointerUniqueId + \since 5.8 + + Returns whether the two unique pointer IDs \a lhs and \a rhs identify different pointers + (\c true) or not (\c false). +*/ + +/*! + \relates QPointerUniqueId + \since 5.8 + + Returns the hash value for \a key, using \a seed to seed the calculation. +*/ +uint qHash(QPointerUniqueId key, uint seed) Q_DECL_NOTHROW +{ + return qHash(key.numericId(), seed); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index a062331bd8..b7c0f3338e 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -793,21 +793,45 @@ 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) + // ### kept these to keep other modules compiling. Remove before 5.8.0 final! +#if QT_DEPRECATED_SINCE(5, 8) + Q_PROPERTY(qint64 numeric READ numericId CONSTANT) +#endif + Q_PROPERTY(qint64 numericId READ numericId CONSTANT) public: - explicit QPointerUniqueId(qint64 id = -1); + Q_ALWAYS_INLINE + Q_DECL_CONSTEXPR QPointerUniqueId() Q_DECL_NOTHROW : m_numericId(-1) {} + // compiler-generated copy/move ctor/assignment operators are ok! + // compiler-generated dtor is ok! + + static QPointerUniqueId fromNumericId(qint64 id); - qint64 numeric() const; + Q_ALWAYS_INLINE Q_DECL_CONSTEXPR bool isValid() const Q_DECL_NOTHROW { return m_numericId != -1; } + qint64 numericId() const Q_DECL_NOTHROW; + // ### kept these to keep other modules compiling. Remove before 5.8.0 final! +#if QT_DEPRECATED_SINCE(5, 8) + Q_ALWAYS_INLINE Q_DECL_DEPRECATED qint64 numeric() const { return numericId(); } + Q_ALWAYS_INLINE Q_DECL_DEPRECATED explicit QPointerUniqueId(qint64 id) : m_numericId(id) {} +#endif 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. + // TODO: for TUIO 2, or any other type of complex token ID, an internal + // array (or hash) can be added to hold additional properties. + // In this case, m_numericId will then turn into an index into that array (or hash). qint64 m_numericId; }; +Q_DECLARE_TYPEINFO(QPointerUniqueId, Q_MOVABLE_TYPE); +template <> class QList<QPointerUniqueId> {}; // to prevent instantiation: use QVector instead + +Q_GUI_EXPORT bool operator==(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW; +inline bool operator!=(QPointerUniqueId lhs, QPointerUniqueId rhs) Q_DECL_NOTHROW +{ return !operator==(lhs, rhs); } +Q_GUI_EXPORT uint qHash(QPointerUniqueId key, uint seed = 0) Q_DECL_NOTHROW; + + class QTouchEventTouchPointPrivate; class Q_GUI_EXPORT QTouchEvent : public QInputEvent |