diff options
author | Robin Burchell <robin.burchell@jollamobile.com> | 2014-04-01 15:16:04 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-04-02 09:33:19 +0200 |
commit | 87031acc3ca30cb40f57e16577826c3a79865d82 (patch) | |
tree | d08876ba73906cfa44062a073761de8c561f374b /src/quick/items/qquickpincharea.cpp | |
parent | 81ba77d736f07efac37d284cd741d71f9dad4149 (diff) |
QQuickPinchArea: Don't jump around when a finger is lifted.
Change-Id: I580348c2323896e3229f068745ce9c89334a5abc
Done-with: Martin Jones <martin.jones@jollamobile.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
Diffstat (limited to 'src/quick/items/qquickpincharea.cpp')
-rw-r--r-- | src/quick/items/qquickpincharea.cpp | 102 |
1 files changed, 55 insertions, 47 deletions
diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index f741a08512..c2ca66f840 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -303,7 +303,6 @@ void QQuickPinchArea::touchEvent(QTouchEvent *event) // it's always going to accept the touches, and that means the item underneath // will not get them (unless the PA's parent is doing parent filtering, // as the Flickable does, for example). - switch (event->type()) { case QEvent::TouchBegin: case QEvent::TouchUpdate: @@ -316,49 +315,54 @@ void QQuickPinchArea::touchEvent(QTouchEvent *event) updatePinch(); break; case QEvent::TouchEnd: - d->touchPoints.clear(); - updatePinch(); + clearPinch(); break; default: QQuickItem::event(event); } } -void QQuickPinchArea::updatePinch() +void QQuickPinchArea::clearPinch() { Q_D(QQuickPinchArea); - if (d->touchPoints.count() == 0) { - if (d->inPinch) { - d->inPinch = false; - QPointF pinchCenter = mapFromScene(d->sceneLastCenter); - QQuickPinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation); - pe.setStartCenter(d->pinchStartCenter); - pe.setPreviousCenter(pinchCenter); - pe.setPreviousAngle(d->pinchLastAngle); - pe.setPreviousScale(d->pinchLastScale); - pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); - pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); - pe.setPoint1(mapFromScene(d->lastPoint1)); - pe.setPoint2(mapFromScene(d->lastPoint2)); - emit pinchFinished(&pe); - d->pinchStartDist = 0; - d->pinchActivated = false; - if (d->pinch && d->pinch->target()) - d->pinch->setActive(false); - } - d->initPinch = false; - d->pinchRejected = false; - d->stealMouse = false; - setKeepMouseGrab(false); - return; - } - if (d->touchPoints.count() == 1) { - setKeepMouseGrab(false); + d->touchPoints.clear(); + if (d->inPinch) { + d->inPinch = false; + QPointF pinchCenter = mapFromScene(d->sceneLastCenter); + QQuickPinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation); + pe.setStartCenter(d->pinchStartCenter); + pe.setPreviousCenter(pinchCenter); + pe.setPreviousAngle(d->pinchLastAngle); + pe.setPreviousScale(d->pinchLastScale); + pe.setStartPoint1(mapFromScene(d->sceneStartPoint1)); + pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); + pe.setPoint1(mapFromScene(d->lastPoint1)); + pe.setPoint2(mapFromScene(d->lastPoint2)); + emit pinchFinished(&pe); + if (d->pinch && d->pinch->target()) + d->pinch->setActive(false); } + d->pinchStartDist = 0; + d->pinchActivated = false; + d->initPinch = false; + d->pinchRejected = false; + d->stealMouse = false; + d->id1 = -1; + QQuickWindow *win = window(); + if (win && win->mouseGrabberItem() == this) + ungrabMouse(); + setKeepMouseGrab(false); +} + +void QQuickPinchArea::updatePinch() +{ + Q_D(QQuickPinchArea); + QQuickWindow *win = window(); QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0); QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0); + QRectF bounds = clipRect(); // Pinch is not started unless there are exactly two touch points // AND one or more of the points has just now been pressed (wasn't pressed already) @@ -371,6 +375,13 @@ void QQuickPinchArea::updatePinch() d->sceneStartPoint2 = touchPoint2.scenePos(); d->pinchActivated = true; d->initPinch = true; + + int touchMouseId = QQuickWindowPrivate::get(win)->touchMouseId; + if (touchPoint1.id() == touchMouseId || touchPoint2.id() == touchMouseId) { + if (win && win->mouseGrabberItem() != this) { + grabMouse(); + } + } } if (d->pinchActivated && !d->pinchRejected) { const int dragThreshold = qApp->styleHints()->startDragDistance(); @@ -421,12 +432,12 @@ void QQuickPinchArea::updatePinch() pe.setPointCount(d->touchPoints.count()); emit pinchStarted(&pe); if (pe.accepted()) { - d->inPinch = true; - d->stealMouse = true; - QQuickWindow *c = window(); - if (c && c->mouseGrabberItem() != this) + if (win && win->mouseGrabberItem() != this) grabMouse(); setKeepMouseGrab(true); + grabTouchPoints(QVector<int>() << touchPoint1.id() << touchPoint2.id()); + d->inPinch = true; + d->stealMouse = true; if (d->pinch && d->pinch->target()) { d->pinchStartPos = pinch()->target()->position(); d->pinchStartScale = d->pinch->target()->scale(); @@ -501,22 +512,19 @@ bool QQuickPinchArea::childMouseEventFilter(QQuickItem *i, QEvent *e) return QQuickItem::childMouseEventFilter(i, e); switch (e->type()) { case QEvent::TouchBegin: + clearPinch(); // fall through case QEvent::TouchUpdate: { - QTouchEvent *touch = static_cast<QTouchEvent*>(e); - if (touch->touchPoints().count() > 1) { - touchEvent(touch); - } else { - d->touchPoints.clear(); - for (int i = 0; i < touch->touchPoints().count(); ++i) - if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased)) - d->touchPoints << touch->touchPoints().at(i); - updatePinch(); - } + QTouchEvent *touch = static_cast<QTouchEvent*>(e); + d->touchPoints.clear(); + for (int i = 0; i < touch->touchPoints().count(); ++i) + if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased)) + d->touchPoints << touch->touchPoints().at(i); + updatePinch(); } + e->setAccepted(d->inPinch); return d->inPinch; case QEvent::TouchEnd: - d->touchPoints.clear(); - updatePinch(); + clearPinch(); break; default: break; |