diff options
author | J-P Nurmi <jpnurmi@qt.io> | 2017-01-03 13:06:15 +0100 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-01-03 17:04:49 +0000 |
commit | cad7ffa361381556620ab826dd60adf0b080367c (patch) | |
tree | 5760e6edb8dbb4fdcb0e4bc9f0a2cbf95a055ace /src/quicktemplates2/qquickrangeslider.cpp | |
parent | 842d7a51fb9e97a5562300068194374ed7b3c911 (diff) |
QQuickRangeSlider: handle touch events
This makes it possible to interact with both handles and multiple
sliders at the same time.
Change-Id: Iba47b8ec31619b3dbec09dbc9ea176735f984e8b
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quicktemplates2/qquickrangeslider.cpp')
-rw-r--r-- | src/quicktemplates2/qquickrangeslider.cpp | 133 |
1 files changed, 108 insertions, 25 deletions
diff --git a/src/quicktemplates2/qquickrangeslider.cpp b/src/quicktemplates2/qquickrangeslider.cpp index 460bbffc..6a629d62 100644 --- a/src/quicktemplates2/qquickrangeslider.cpp +++ b/src/quicktemplates2/qquickrangeslider.cpp @@ -92,7 +92,8 @@ public: handle(nullptr), slider(slider), pressed(false), - hovered(false) + hovered(false), + touchId(-1) { } @@ -103,9 +104,6 @@ public: static QQuickRangeSliderNodePrivate *get(QQuickRangeSliderNode *node); -private: - friend class QQuickRangeSlider; - qreal value; bool isPendingValue; qreal pendingValue; @@ -114,6 +112,7 @@ private: QQuickRangeSlider *slider; bool pressed; bool hovered; + int touchId; }; bool QQuickRangeSliderNodePrivate::isFirst() const @@ -327,9 +326,10 @@ public: { } - void handlePress(const QPointF &point); - void handleMove(const QPointF &point); - void handleRelease(const QPointF &point); + QQuickRangeSliderNode *pressedNode(int touchId = -1) const; + void handlePress(const QPointF &point, int touchId = -1); + void handleMove(const QPointF &point, int touchId = -1); + void handleRelease(const QPointF &point, int touchId = -1); void handleUngrab(); void updateHover(const QPointF &pos); @@ -384,15 +384,26 @@ static qreal positionAt(const QQuickRangeSlider *slider, QQuickItem *handle, con return 0; } -void QQuickRangeSliderPrivate::handlePress(const QPointF &point) +QQuickRangeSliderNode *QQuickRangeSliderPrivate::pressedNode(int touchId) const +{ + if (touchId == -1) + return first->isPressed() ? first : (second->isPressed() ? second : nullptr); + if (QQuickRangeSliderNodePrivate::get(first)->touchId == touchId) + return first; + if (QQuickRangeSliderNodePrivate::get(second)->touchId == touchId) + return second; + return nullptr; +} + +void QQuickRangeSliderPrivate::handlePress(const QPointF &point, int touchId) { Q_Q(QQuickRangeSlider); pressPoint = point; QQuickItem *firstHandle = first->handle(); QQuickItem *secondHandle = second->handle(); - const bool firstHit = firstHandle && firstHandle->contains(q->mapToItem(firstHandle, point)); - const bool secondHit = secondHandle && secondHandle->contains(q->mapToItem(secondHandle, point)); + const bool firstHit = firstHandle && !first->isPressed() && firstHandle->contains(q->mapToItem(firstHandle, point)); + const bool secondHit = secondHandle && !second->isPressed() && secondHandle->contains(q->mapToItem(secondHandle, point)); QQuickRangeSliderNode *hitNode = nullptr; QQuickRangeSliderNode *otherNode = nullptr; @@ -436,17 +447,18 @@ void QQuickRangeSliderPrivate::handlePress(const QPointF &point) if (hitNode) { hitNode->setPressed(true); hitNode->handle()->setZ(1); + QQuickRangeSliderNodePrivate::get(hitNode)->touchId = touchId; } if (otherNode) otherNode->handle()->setZ(0); } -void QQuickRangeSliderPrivate::handleMove(const QPointF &point) +void QQuickRangeSliderPrivate::handleMove(const QPointF &point, int touchId) { Q_Q(QQuickRangeSlider); if (!q->keepMouseGrab()) return; - QQuickRangeSliderNode *pressedNode = first->isPressed() ? first : (second->isPressed() ? second : nullptr); + QQuickRangeSliderNode *pressedNode = QQuickRangeSliderPrivate::pressedNode(touchId); if (pressedNode) { qreal pos = positionAt(q, pressedNode->handle(), point); if (snapMode == QQuickRangeSlider::SnapAlways) @@ -458,27 +470,29 @@ void QQuickRangeSliderPrivate::handleMove(const QPointF &point) } } -void QQuickRangeSliderPrivate::handleRelease(const QPointF &point) +void QQuickRangeSliderPrivate::handleRelease(const QPointF &point, int touchId) { Q_Q(QQuickRangeSlider); pressPoint = QPointF(); - if (!q->keepMouseGrab()) - return; - QQuickRangeSliderNode *pressedNode = first->isPressed() ? first : (second->isPressed() ? second : nullptr); + QQuickRangeSliderNode *pressedNode = QQuickRangeSliderPrivate::pressedNode(touchId); if (!pressedNode) return; + QQuickRangeSliderNodePrivate *pressedNodePrivate = QQuickRangeSliderNodePrivate::get(pressedNode); - qreal pos = positionAt(q, pressedNode->handle(), point); - if (snapMode != QQuickRangeSlider::NoSnap) - pos = snapPosition(q, pos); - qreal val = valueAt(q, pos); - if (!qFuzzyCompare(val, pressedNode->value())) - pressedNode->setValue(val); - else if (snapMode != QQuickRangeSlider::NoSnap) - QQuickRangeSliderNodePrivate::get(pressedNode)->setPosition(pos); - q->setKeepMouseGrab(false); + if (q->keepMouseGrab()) { + qreal pos = positionAt(q, pressedNode->handle(), point); + if (snapMode != QQuickRangeSlider::NoSnap) + pos = snapPosition(q, pos); + qreal val = valueAt(q, pos); + if (!qFuzzyCompare(val, pressedNode->value())) + pressedNode->setValue(val); + else if (snapMode != QQuickRangeSlider::NoSnap) + pressedNodePrivate->setPosition(pos); + q->setKeepMouseGrab(false); + } pressedNode->setPressed(false); + pressedNodePrivate->touchId = -1; } void QQuickRangeSliderPrivate::handleUngrab() @@ -486,6 +500,8 @@ void QQuickRangeSliderPrivate::handleUngrab() pressPoint = QPointF(); first->setPressed(false); second->setPressed(false); + QQuickRangeSliderNodePrivate::get(first)->touchId = -1; + QQuickRangeSliderNodePrivate::get(second)->touchId = -1; } void QQuickRangeSliderPrivate::updateHover(const QPointF &pos) @@ -976,6 +992,73 @@ void QQuickRangeSlider::mouseUngrabEvent() d->handleUngrab(); } +void QQuickRangeSlider::touchEvent(QTouchEvent *event) +{ + Q_D(QQuickRangeSlider); + switch (event->type()) { + case QEvent::TouchBegin: + if (!d->first->isPressed() || !d->second->isPressed()) { + const QTouchEvent::TouchPoint point = event->touchPoints().first(); + d->handlePress(point.pos(), point.id()); + } else { + event->ignore(); + } + break; + + case QEvent::TouchUpdate: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + switch (point.state()) { + case Qt::TouchPointPressed: + if (!d->first->isPressed() || !d->second->isPressed()) + d->handlePress(point.pos(), point.id()); + break; + case Qt::TouchPointMoved: + if (!keepMouseGrab()) { + if (d->orientation == Qt::Horizontal) + setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().x() - point.startPos().x(), Qt::XAxis, &point)); + else + setKeepMouseGrab(QQuickWindowPrivate::dragOverThreshold(point.pos().y() - point.startPos().y(), Qt::YAxis, &point)); + } + if (point.id() == QQuickRangeSliderNodePrivate::get(d->first)->touchId + || point.id() == QQuickRangeSliderNodePrivate::get(d->second)->touchId) + d->handleMove(point.pos(), point.id()); + break; + case Qt::TouchPointReleased: + if (point.id() == QQuickRangeSliderNodePrivate::get(d->first)->touchId + || point.id() == QQuickRangeSliderNodePrivate::get(d->second)->touchId) + d->handleRelease(point.pos(), point.id()); + break; + default: + break; + } + } + break; + + case QEvent::TouchEnd: + for (const QTouchEvent::TouchPoint &point : event->touchPoints()) { + if (point.id() == QQuickRangeSliderNodePrivate::get(d->first)->touchId + || point.id() == QQuickRangeSliderNodePrivate::get(d->second)->touchId) + d->handleRelease(point.pos(), point.id()); + } + break; + + case QEvent::TouchCancel: + d->handleUngrab(); + break; + + default: + QQuickControl::touchEvent(event); + break; + } +} + +void QQuickRangeSlider::touchUngrabEvent() +{ + Q_D(QQuickRangeSlider); + QQuickControl::touchUngrabEvent(); + d->handleUngrab(); +} + void QQuickRangeSlider::mirrorChange() { Q_D(QQuickRangeSlider); |