aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2016-11-25 15:38:42 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2017-01-03 07:05:58 +0000
commit5c6245b7ff7a941c0a2425f32909c0dc0982e199 (patch)
tree7ece0d257763e37a75b1b0caa9caa35813665342 /src
parentf1fa7f18b09cad465867ff036ea500d4e2eda868 (diff)
QQPSingleHandler: copy some values from QQuickEventPoint to properties
We can't copy the eventpoint and we can't continue to refer to it after delivery, either. So we can't have an event property. Some QML use cases depend on being able to access last-known values between events. Change-Id: Ice8a1763015f2554275d0cb76824fd0366eaef56 Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quick/handlers/qquickdraghandler.cpp2
-rw-r--r--src/quick/handlers/qquickpointersinglehandler.cpp80
-rw-r--r--src/quick/handlers/qquickpointersinglehandler_p.h39
3 files changed, 96 insertions, 25 deletions
diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp
index 945d60119d..6caee6be13 100644
--- a/src/quick/handlers/qquickdraghandler.cpp
+++ b/src/quick/handlers/qquickdraghandler.cpp
@@ -69,7 +69,7 @@ QQuickDragHandler::~QQuickDragHandler()
bool QQuickDragHandler::wantsEventPoint(QQuickEventPoint *point)
{
// If we've already been interested in a point, stay interested, even if it has strayed outside bounds.
- return ((point->state() != QQuickEventPoint::Pressed && currentPointId() == point->pointId())
+ return ((point->state() != QQuickEventPoint::Pressed && pointId() == point->pointId())
|| QQuickPointerSingleHandler::wantsEventPoint(point));
}
diff --git a/src/quick/handlers/qquickpointersinglehandler.cpp b/src/quick/handlers/qquickpointersinglehandler.cpp
index 3a67d66e8c..f39d8ac976 100644
--- a/src/quick/handlers/qquickpointersinglehandler.cpp
+++ b/src/quick/handlers/qquickpointersinglehandler.cpp
@@ -52,7 +52,9 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_TOUCH_TARGET)
QQuickPointerSingleHandler::QQuickPointerSingleHandler(QObject *parent)
: QQuickPointerDeviceHandler(parent)
- , m_currentPointId(0)
+ , m_pointId(0)
+ , m_rotation(0)
+ , m_pressure(0)
{
}
@@ -60,11 +62,11 @@ bool QQuickPointerSingleHandler::wantsPointerEvent(QQuickPointerEvent *event)
{
if (!QQuickPointerDeviceHandler::wantsPointerEvent(event))
return false;
- if (m_currentPointId) {
+ if (m_pointId) {
// We already know which one we want, so check whether it's there.
// It's expected to be an update or a release.
// If we no longer want it, cancel the grab.
- if (auto point = event->pointById(m_currentPointId)) {
+ if (auto point = event->pointById(m_pointId)) {
if (wantsEventPoint(point)) {
point->setAccepted();
return true;
@@ -72,45 +74,62 @@ bool QQuickPointerSingleHandler::wantsPointerEvent(QQuickPointerEvent *event)
point->cancelGrab();
}
} else {
- qCWarning(DBG_TOUCH_TARGET) << this << "pointId" << m_currentPointId
+ qCWarning(DBG_TOUCH_TARGET) << this << "pointId" << m_pointId
<< "is missing from current event, but was neither canceled nor released";
return false;
}
} else {
// We have not yet chosen a point; choose the first one for which wantsEventPoint() returns true.
int c = event->pointCount();
- for (int i = 0; i < c && !m_currentPointId; ++i) {
+ for (int i = 0; i < c && !m_pointId; ++i) {
QQuickEventPoint *p = event->point(i);
if (!p->grabber() && wantsEventPoint(p)) {
- m_currentPointId = p->pointId();
+ m_pointId = p->pointId();
p->setAccepted();
}
}
}
- return m_currentPointId;
+ return m_pointId;
}
void QQuickPointerSingleHandler::handlePointerEventImpl(QQuickPointerEvent *event)
{
QQuickPointerDeviceHandler::handlePointerEventImpl(event);
- QQuickEventPoint *currentPoint = event->pointById(m_currentPointId);
+ QQuickEventPoint *currentPoint = event->pointById(m_pointId);
Q_ASSERT(currentPoint);
- if (!m_currentPointId || !currentPoint->isAccepted()) {
- m_currentPointId = 0;
- setPressedButtons(Qt::NoButton);
+ bool grab = false;
+ if (!m_pointId || !currentPoint->isAccepted() || currentPoint->state() == QQuickEventPoint::Released) {
+ reset();
+ grab = false;
} else {
- setPressedButtons(event->buttons());
+ if (event->asPointerTouchEvent()) {
+ QQuickEventTouchPoint *tp = static_cast<QQuickEventTouchPoint *>(currentPoint);
+ m_uniquePointId = tp->uniqueId();
+ m_rotation = tp->rotation();
+ m_pressure = tp->pressure();
+ m_ellipseDiameters = tp->ellipseDiameters();
+ } else if (event->asPointerTabletEvent()) {
+ // TODO
+ } else {
+ m_uniquePointId = event->device()->uniqueId();
+ m_rotation = 0;
+ m_pressure = event->buttons() ? 1 : 0;
+ m_ellipseDiameters = QSizeF();
+ }
+ m_pos = currentPoint->pos();
+ m_velocity = currentPoint->velocity();
handleEventPoint(currentPoint);
- if (currentPoint->state() == QQuickEventPoint::Released) {
- m_currentPointId = 0;
- setPressedButtons(Qt::NoButton);
- setGrab(currentPoint, false);
+ if (currentPoint->state() == QQuickEventPoint::Pressed) {
+ m_pressPos = currentPoint->pos();
+ emit pointIdChanged();
}
+ setPressedButtons(event->buttons());
+ grab = true;
}
- bool grab = currentPoint->isAccepted() && currentPoint->state() != QQuickEventPoint::Released;
+ emit eventPointHandled();
+ // TODO don't call setGrab(true) here, only setGrab(false), because concrete subclasses may
+ // wait for the drag threshold to be exceeded, for example
setGrab(currentPoint, grab);
- if (!grab)
- m_currentPointId = 0;
}
bool QQuickPointerSingleHandler::wantsEventPoint(QQuickEventPoint *point)
@@ -121,14 +140,16 @@ bool QQuickPointerSingleHandler::wantsEventPoint(QQuickEventPoint *point)
void QQuickPointerSingleHandler::handleGrabCancel(QQuickEventPoint *point)
{
QQuickPointerHandler::handleGrabCancel(point);
- m_currentPointId = 0;
- setPressedButtons(Qt::NoButton);
+ reset();
}
void QQuickPointerSingleHandler::onGrabChanged(QQuickEventPoint *point)
{
bool grabbing = (point->grabber() == this);
setActive(grabbing);
+ if (grabbing)
+ m_sceneGrabPos = point->sceneGrabPos();
+ emit singlePointGrabChanged();
}
void QQuickPointerSingleHandler::setPressedButtons(Qt::MouseButtons buttons)
@@ -139,4 +160,21 @@ void QQuickPointerSingleHandler::setPressedButtons(Qt::MouseButtons buttons)
}
}
+void QQuickPointerSingleHandler::reset()
+{
+ bool pointIdChange = m_pointId != 0;
+ m_pointId = 0;
+ m_uniquePointId = QPointingDeviceUniqueId();
+ m_pos = QPointF();
+ m_pressPos = QPointF();
+ m_sceneGrabPos = QPointF();
+ m_velocity = QVector2D();
+ m_rotation = 0;
+ m_pressure = 0;
+ m_ellipseDiameters = QSizeF();
+ setPressedButtons(Qt::NoButton);
+ if (pointIdChange)
+ emit pointIdChanged();
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointersinglehandler_p.h b/src/quick/handlers/qquickpointersinglehandler_p.h
index e3c6bfaddf..8858b2c080 100644
--- a/src/quick/handlers/qquickpointersinglehandler_p.h
+++ b/src/quick/handlers/qquickpointersinglehandler_p.h
@@ -58,33 +58,66 @@ QT_BEGIN_NAMESPACE
class Q_QUICK_PRIVATE_EXPORT QQuickPointerSingleHandler : public QQuickPointerDeviceHandler
{
Q_OBJECT
+ Q_PROPERTY(quint64 pointId READ pointId NOTIFY pointIdChanged)
+ Q_PROPERTY(QPointingDeviceUniqueId uniquePointId READ uniquePointId NOTIFY pointIdChanged)
+ Q_PROPERTY(QPointF pos READ pos NOTIFY eventPointHandled)
+ Q_PROPERTY(QPointF scenePos READ scenePos NOTIFY eventPointHandled)
+ Q_PROPERTY(QPointF pressPos READ pressPos NOTIFY pressedButtonsChanged)
+ Q_PROPERTY(QPointF scenePressPos READ scenePressPos NOTIFY pressedButtonsChanged)
+ Q_PROPERTY(QPointF sceneGrabPos READ sceneGrabPos NOTIFY singlePointGrabChanged)
Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons NOTIFY pressedButtonsChanged)
+ Q_PROPERTY(QVector2D velocity READ velocity NOTIFY eventPointHandled)
+ Q_PROPERTY(qreal rotation READ rotation NOTIFY eventPointHandled)
+ Q_PROPERTY(qreal pressure READ pressure NOTIFY eventPointHandled)
+ Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters NOTIFY eventPointHandled)
public:
QQuickPointerSingleHandler(QObject *parent = 0);
virtual ~QQuickPointerSingleHandler() { }
Qt::MouseButtons pressedButtons() const { return m_pressedButtons; }
+ QPointF pressPos() const { return m_pressPos; }
+ QPointF scenePressPos() const { return parentItem()->mapToScene(m_pressPos); }
+ QPointF sceneGrabPos() const { return m_sceneGrabPos; }
+ QPointF pos() const { return m_pos; }
+ QPointF scenePos() const { return parentItem()->mapToScene(m_pos); }
+ QVector2D velocity() const { return m_velocity; }
+ qreal rotation() const { return m_rotation; }
+ qreal pressure() const { return m_pressure; }
+ QSizeF ellipseDiameters() const { return m_ellipseDiameters; }
+ QPointingDeviceUniqueId uniquePointId() const { return m_uniquePointId; }
signals:
+ void pointIdChanged();
void pressedButtonsChanged();
+ void singlePointGrabChanged(); // QQuickPointerHandler::grabChanged signal can't be a property notifier here
+ void eventPointHandled();
protected:
bool wantsPointerEvent(QQuickPointerEvent *event) override;
virtual bool wantsEventPoint(QQuickEventPoint *point);
void handlePointerEventImpl(QQuickPointerEvent *event) override;
virtual void handleEventPoint(QQuickEventPoint *point) = 0;
- quint64 currentPointId() const { return m_currentPointId; }
- QQuickEventPoint *currentPoint(QQuickPointerEvent *ev) { return ev->pointById(m_currentPointId); }
+ quint64 pointId() const { return m_pointId; }
+ QQuickEventPoint *currentPoint(QQuickPointerEvent *ev) { return ev->pointById(m_pointId); }
void handleGrabCancel(QQuickEventPoint *point) override;
void onGrabChanged(QQuickEventPoint *point) override;
private:
void setPressedButtons(Qt::MouseButtons buttons);
+ void reset();
private:
- quint64 m_currentPointId;
+ quint64 m_pointId;
+ QPointingDeviceUniqueId m_uniquePointId;
Qt::MouseButtons m_pressedButtons;
+ QPointF m_pos;
+ QPointF m_pressPos;
+ QPointF m_sceneGrabPos;
+ QVector2D m_velocity;
+ qreal m_rotation;
+ qreal m_pressure;
+ QSizeF m_ellipseDiameters;
};
QT_END_NAMESPACE