diff options
author | Lauri Laanmets <lauri.laanmets@eesti.ee> | 2021-09-30 17:31:02 +0300 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2021-11-09 10:28:41 +0100 |
commit | 18aae46a744adb4510a2b04c7322c3f66bded474 (patch) | |
tree | 2eb58fa28871554b35f8a48ec3c29e0adcc041d2 /src | |
parent | d25bffff3453338405feb4470249998e4622612c (diff) | |
download | qtlocation-18aae46a744adb4510a2b04c7322c3f66bded474.tar.gz |
Mouse/touch input handling re-work
Mouse and touch input part is re-written to support new 'exclusiveGrabber' and to be able to share different touch points between different child items. For example, one finger can pan the map and another finger can scroll child ListView or pinch can be started even when first finger touched child mouse area but started moving together with the second finger.
This is part of a bigger work to port QtLocation maps to Qt6.
Fixes: QTBUG-68771
Task-number: QTBUG-96795
Change-Id: Ie4022350156ab0129b6cbba0a442a19bb1ee74d9
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src')
4 files changed, 109 insertions, 173 deletions
diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp index f5bb156c..ba6d7835 100644 --- a/src/location/declarativemaps/qdeclarativegeomap.cpp +++ b/src/location/declarativemaps/qdeclarativegeomap.cpp @@ -196,6 +196,7 @@ QDeclarativeGeoMap::QDeclarativeGeoMap(QQuickItem *parent) m_userMaximumFieldOfView(qQNaN()) { setAcceptHoverEvents(false); + setAcceptTouchEvents(true); setAcceptedMouseButtons(Qt::LeftButton); setFlags(QQuickItem::ItemHasContents | QQuickItem::ItemClipsChildrenToShape); setFiltersChildMouseEvents(true); // needed for childMouseEventFilter to work. @@ -2484,7 +2485,7 @@ void QDeclarativeGeoMap::fitViewportToMapItemsRefine(const QList<QPointer<QDecla */ void QDeclarativeGeoMap::mousePressEvent(QMouseEvent *event) { - if (isInteractive()) + if (isInteractive() && event->source() == Qt::MouseEventNotSynthesized) m_gestureArea->handleMousePressEvent(event); else QQuickItem::mousePressEvent(event); @@ -2495,7 +2496,7 @@ void QDeclarativeGeoMap::mousePressEvent(QMouseEvent *event) */ void QDeclarativeGeoMap::mouseMoveEvent(QMouseEvent *event) { - if (isInteractive()) + if (isInteractive() && event->source() == Qt::MouseEventNotSynthesized) m_gestureArea->handleMouseMoveEvent(event); else QQuickItem::mouseMoveEvent(event); @@ -2506,23 +2507,12 @@ void QDeclarativeGeoMap::mouseMoveEvent(QMouseEvent *event) */ void QDeclarativeGeoMap::mouseReleaseEvent(QMouseEvent *event) { - if (isInteractive()) + if (isInteractive() && event->source() == Qt::MouseEventNotSynthesized) m_gestureArea->handleMouseReleaseEvent(event); else QQuickItem::mouseReleaseEvent(event); } -/*! - \internal -*/ -void QDeclarativeGeoMap::mouseUngrabEvent() -{ - if (isInteractive()) - m_gestureArea->handleMouseUngrabEvent(); - else - QQuickItem::mouseUngrabEvent(); -} - void QDeclarativeGeoMap::touchUngrabEvent() { if (isInteractive()) @@ -2568,10 +2558,20 @@ bool QDeclarativeGeoMap::childMouseEventFilter(QQuickItem *item, QEvent *event) return QQuickItem::childMouseEventFilter(item, event); switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + case QEvent::TouchCancel: + return sendTouchEvent(static_cast<QTouchEvent *>(event)); case QEvent::MouseButtonPress: case QEvent::MouseMove: case QEvent::MouseButtonRelease: - return sendMouseEvent(static_cast<QMouseEvent *>(event)); + { + auto mEvent = static_cast<QMouseEvent*>(event); + if (mEvent->source() == Qt::MouseEventNotSynthesized){ + return sendTouchEvent(mEvent); + } + } case QEvent::UngrabMouse: { QQuickWindow *win = window(); if (!win) break; @@ -2585,17 +2585,6 @@ bool QDeclarativeGeoMap::childMouseEventFilter(QQuickItem *item, QEvent *event) } break; } - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - case QEvent::TouchEnd: - case QEvent::TouchCancel: - if (static_cast<QTouchEvent *>(event)->touchPoints().count() >= 2) { - // 1 touch point = handle with MouseEvent (event is always synthesized) - // let the synthesized mouse event grab the mouse, - // note there is no mouse grabber at this point since - // touch event comes first (see Qt::AA_SynthesizeMouseForUnhandledTouchEvents) - return sendTouchEvent(static_cast<QTouchEvent *>(event)); - } default: break; } @@ -2604,34 +2593,24 @@ bool QDeclarativeGeoMap::childMouseEventFilter(QQuickItem *item, QEvent *event) bool QDeclarativeGeoMap::sendMouseEvent(QMouseEvent *event) { - QPointF localPos = mapFromScene(event->windowPos()); - QQuickWindow *win = window(); - QQuickItem *grabber = win ? win->mouseGrabberItem() : 0; bool stealEvent = m_gestureArea->isActive(); - if ((stealEvent || contains(localPos)) && (!grabber || (!grabber->keepMouseGrab() && !grabber->keepTouchGrab()))) { - QScopedPointer<QMouseEvent> mouseEvent(QQuickWindowPrivate::cloneMouseEvent(event, &localPos)); - mouseEvent->setAccepted(false); - - switch (mouseEvent->type()) { + if ((stealEvent || contains(mapFromScene(event->scenePosition())))) { + switch (event->type()) { case QEvent::MouseMove: - m_gestureArea->handleMouseMoveEvent(mouseEvent.data()); + m_gestureArea->handleMouseMoveEvent(event); break; case QEvent::MouseButtonPress: - m_gestureArea->handleMousePressEvent(mouseEvent.data()); + m_gestureArea->handleMousePressEvent(event); break; case QEvent::MouseButtonRelease: - m_gestureArea->handleMouseReleaseEvent(mouseEvent.data()); + m_gestureArea->handleMouseReleaseEvent(event); break; default: break; } stealEvent = m_gestureArea->isActive(); - grabber = win ? win->mouseGrabberItem() : 0; - - if (grabber && stealEvent && !grabber->keepMouseGrab() && !grabber->keepTouchGrab() && grabber != this) - grabMouse(); if (stealEvent) { //do not deliver @@ -2641,55 +2620,28 @@ bool QDeclarativeGeoMap::sendMouseEvent(QMouseEvent *event) return false; } } - return false; } -bool QDeclarativeGeoMap::sendTouchEvent(QTouchEvent *event) +bool QDeclarativeGeoMap::sendTouchEvent(QPointerEvent *event) { - QQuickPointerDevice *touchDevice = QQuickPointerDevice::touchDevice(event->device()); - const QTouchEvent::TouchPoint &point = event->touchPoints().first(); - QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window()); - - auto touchPointGrabberItem = [touchDevice, windowPriv](const QTouchEvent::TouchPoint &point) -> QQuickItem* { - if (QQuickEventPoint *eventPointer = windowPriv->pointerEventInstance(touchDevice)->pointById(point.id())) - return eventPointer->grabberItem(); - return nullptr; - }; - - QQuickItem *grabber = touchPointGrabberItem(point); + const QTouchEvent::TouchPoint &point = event->points().first(); bool stealEvent = m_gestureArea->isActive(); - bool containsPoint = contains(mapFromScene(point.scenePos())); + bool containsPoint = contains(mapFromScene(point.scenePosition())); - if ((stealEvent || containsPoint) && (!grabber || !grabber->keepTouchGrab())) { - QScopedPointer<QTouchEvent> touchEvent(new QTouchEvent(event->type(), event->device(), event->modifiers(), event->touchPointStates(), event->touchPoints())); - touchEvent->setTimestamp(event->timestamp()); - touchEvent->setAccepted(false); + if ((stealEvent || containsPoint)) { - m_gestureArea->handleTouchEvent(touchEvent.data()); + m_gestureArea->handleTouchEvent(event); stealEvent = m_gestureArea->isActive(); - grabber = touchPointGrabberItem(point); - - if (grabber && stealEvent && !grabber->keepTouchGrab() && grabber != this) { - QList<int> ids; - foreach (const QTouchEvent::TouchPoint &tp, event->touchPoints()) { - if (!(tp.state() & Qt::TouchPointReleased)) { - ids.append(tp.id()); - } - } - grabTouchPoints(ids); - } if (stealEvent) { - //do not deliver - event->setAccepted(true); - return true; + //event->setAccepted(true); + //return true; } else { return false; } } - return false; } diff --git a/src/location/declarativemaps/qdeclarativegeomap_p.h b/src/location/declarativemaps/qdeclarativegeomap_p.h index 2a7ea6b1..fe4440c6 100644 --- a/src/location/declarativemaps/qdeclarativegeomap_p.h +++ b/src/location/declarativemaps/qdeclarativegeomap_p.h @@ -242,7 +242,6 @@ protected: void mousePressEvent(QMouseEvent *event) override ; void mouseMoveEvent(QMouseEvent *event) override ; void mouseReleaseEvent(QMouseEvent *event) override ; - void mouseUngrabEvent() override ; void touchUngrabEvent() override; void touchEvent(QTouchEvent *event) override ; #if QT_CONFIG(wheelevent) @@ -251,7 +250,7 @@ protected: bool childMouseEventFilter(QQuickItem *item, QEvent *event) override; bool sendMouseEvent(QMouseEvent *event); - bool sendTouchEvent(QTouchEvent *event); + bool sendTouchEvent(QPointerEvent *event); void componentComplete() override; QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override; diff --git a/src/location/declarativemaps/qquickgeomapgesturearea.cpp b/src/location/declarativemaps/qquickgeomapgesturearea.cpp index 44f67469..bc37f2bc 100644 --- a/src/location/declarativemaps/qquickgeomapgesturearea.cpp +++ b/src/location/declarativemaps/qquickgeomapgesturearea.cpp @@ -869,21 +869,6 @@ void QQuickGeoMapGestureArea::setFlickDeceleration(qreal deceleration) emit flickDecelerationChanged(); } -/*! - \internal -*/ -QTouchEvent::TouchPoint* createTouchPointFromMouseEvent(QMouseEvent *event, Qt::TouchPointState state) -{ - // this is only partially filled. But since it is only partially used it works - // more robust would be to store a list of QPointFs rather than TouchPoints - QTouchEvent::TouchPoint* newPoint = new QTouchEvent::TouchPoint(); - newPoint->setPos(event->position()); - newPoint->setScenePos(event->windowPos()); - newPoint->setScreenPos(event->screenPos()); - newPoint->setState(state); - newPoint->setId(0); - return newPoint; -} /*! \internal @@ -895,10 +880,7 @@ void QQuickGeoMapGestureArea::handleMousePressEvent(QMouseEvent *event) return; } - m_mousePoint.reset(createTouchPointFromMouseEvent(event, QEventPoint::State::Pressed)); - if (m_touchPoints.isEmpty()) - update(); - event->accept(); + handleTouchEvent(event); } /*! @@ -911,10 +893,7 @@ void QQuickGeoMapGestureArea::handleMouseMoveEvent(QMouseEvent *event) return; } - m_mousePoint.reset(createTouchPointFromMouseEvent(event, QEventPoint::State::Updated)); - if (m_touchPoints.isEmpty()) - update(); - event->accept(); + handleTouchEvent(event); } /*! @@ -927,28 +906,7 @@ void QQuickGeoMapGestureArea::handleMouseReleaseEvent(QMouseEvent *event) return; } - if (!m_mousePoint.isNull()) { - //this looks super ugly , however is required in case we do not get synthesized MouseReleaseEvent - //and we reset the point already in handleTouchUngrabEvent - m_mousePoint.reset(createTouchPointFromMouseEvent(event, QEventPoint::State::Released)); - if (m_touchPoints.isEmpty()) - update(); - } - event->accept(); -} - -/*! - \internal -*/ -void QQuickGeoMapGestureArea::handleMouseUngrabEvent() -{ - - if (m_touchPoints.isEmpty() && !m_mousePoint.isNull()) { - m_mousePoint.reset(); - update(); - } else { - m_mousePoint.reset(); - } + handleTouchEvent(event); } /*! @@ -957,35 +915,69 @@ void QQuickGeoMapGestureArea::handleMouseUngrabEvent() void QQuickGeoMapGestureArea::handleTouchUngrabEvent() { m_touchPoints.clear(); - //this is needed since in some cases mouse release is not delivered - //(second touch point breaks mouse synthesized events) - m_mousePoint.reset(); update(); } /*! \internal */ -void QQuickGeoMapGestureArea::handleTouchEvent(QTouchEvent *event) +void QQuickGeoMapGestureArea::handleTouchEvent(QPointerEvent *event) { if (m_map && m_map->handleEvent(event)) { event->accept(); return; } - m_touchPoints.clear(); - m_mousePoint.reset(); + // m_touchPoints.clear(); + + // Update the points we are going to use ourselves. + for (const auto &point: event->points()){ + auto grabber = qobject_cast<QQuickItem*>(event->exclusiveGrabber(point)); + // qDebug() << event->type() << point.state() << point << grabber; + + bool canBeGrabbed = grabber == nullptr || grabber == m_declarativeMap || (!grabber->keepTouchGrab() && !grabber->keepMouseGrab()); + // if (canBeGrabbed) m_touchPoints << point; + + //TODO: Testing shows that events are not always propagated with full set of points. + // Therefore, it can happen that our first point is a different point for a moment + // and that will trigger pan or pinch right away. So we keep track of points by their states + // an IDs but then testing shows that sometimes not all points are finished with Release. + // They just dissapear. Child MouseArea will 'eat up' second touch point if first point + // is grabbed by child ListView, for example. Maybe it's a bug in 6.2 RC? + if (point.state() == QEventPoint::Released || !canBeGrabbed){ + for (int i = 0; i < m_touchPoints.count(); ++i) { + if (m_touchPoints.at(i).id() == point.id()){ + m_touchPoints.removeAt(i); + } + } + }else{ + bool replaced = false; + for (int i = 0; i < m_touchPoints.count(); ++i) { + if (m_touchPoints.at(i).id() == point.id()){ + m_touchPoints.replace(i, point); + replaced = true; + } + } + if (!replaced){ + m_touchPoints << point; + } + } - for (int i = 0; i < event->touchPoints().count(); ++i) { - auto point = event->touchPoints().at(i); - if (point.state() != QEventPoint::State::Released) - m_touchPoints << point; } - if (event->touchPoints().count() >= 2) - event->accept(); - else - event->ignore(); + // qDebug() << "m_touchPoints.count=" << m_touchPoints.count(); update(); + + if (isPanActive()){ + // In case we are pannin, we are using only the first point + // We let others to grab the second, if needed. + if (m_touchPoints.count() > 0){ + event->setExclusiveGrabber(m_touchPoints.at(0), m_declarativeMap); + } + }else if (isActive()){ + for (const auto &point: m_touchPoints) { + event->setExclusiveGrabber(point, m_declarativeMap); + } + } } #if QT_CONFIG(wheelevent) @@ -1026,7 +1018,7 @@ void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event) if (preZoomPoint != postZoomPoint) // need to re-anchor the wheel geoPos to the event position m_declarativeMap->alignCoordinateToPoint(wheelGeoPos, preZoomPoint); } - event->accept(); + // event->accept(); } #endif @@ -1112,8 +1104,6 @@ void QQuickGeoMapGestureArea::update() //combine touch with mouse event m_allPoints.clear(); m_allPoints << m_touchPoints; - if (m_allPoints.isEmpty() && !m_mousePoint.isNull()) - m_allPoints << *m_mousePoint.data(); std::sort(m_allPoints.begin(), m_allPoints.end(), [](const QTouchEvent::TouchPoint &tp1, const QTouchEvent::TouchPoint &tp2) { return tp1.id() < tp2.id(); }); touchPointStateMachine(); @@ -1213,7 +1203,8 @@ void QQuickGeoMapGestureArea::startOneTouchPoint() */ void QQuickGeoMapGestureArea::updateOneTouchPoint() { - m_touchPointsCentroid = mapFromScene(m_allPoints.at(0).scenePos()); + m_sceneStartPoint1 = mapFromScene(m_allPoints.at(0).scenePressPosition()); + m_touchPointsCentroid = mapFromScene(m_allPoints.at(0).scenePosition()); updateFlickParameters(m_touchPointsCentroid); } @@ -1222,8 +1213,8 @@ void QQuickGeoMapGestureArea::updateOneTouchPoint() */ void QQuickGeoMapGestureArea::startTwoTouchPoints() { - m_sceneStartPoint1 = mapFromScene(m_allPoints.at(0).scenePos()); - m_sceneStartPoint2 = mapFromScene(m_allPoints.at(1).scenePos()); + m_sceneStartPoint1 = mapFromScene(m_allPoints.at(0).scenePressPosition()); + m_sceneStartPoint2 = mapFromScene(m_allPoints.at(1).scenePressPosition()); QPointF startPos = (m_sceneStartPoint1 + m_sceneStartPoint2) * 0.5; m_lastPos = startPos; m_lastPosTime.start(); @@ -1242,8 +1233,10 @@ void QQuickGeoMapGestureArea::startTwoTouchPoints() */ void QQuickGeoMapGestureArea::updateTwoTouchPoints() { - QPointF p1 = mapFromScene(m_allPoints.at(0).scenePos()); - QPointF p2 = mapFromScene(m_allPoints.at(1).scenePos()); + m_sceneStartPoint1 = mapFromScene(m_allPoints.at(0).scenePressPosition()); + QPointF p1 = mapFromScene(m_allPoints.at(0).scenePosition()); + m_sceneStartPoint2 = mapFromScene(m_allPoints.at(1).scenePressPosition()); + QPointF p2 = mapFromScene(m_allPoints.at(1).scenePosition()); m_distanceBetweenTouchPoints = distanceBetweenTouchPoints(p1, p2); m_touchPointsCentroid = (p1 + p2) / 2; updateFlickParameters(m_touchPointsCentroid); @@ -1262,7 +1255,6 @@ void QQuickGeoMapGestureArea::tiltStateMachine() case tiltInactive: if (m_allPoints.count() >= 2) { if (!isRotationActive() && !isPinchActive() && canStartTilt()) { // only gesture that can be overridden: pan/flick - m_declarativeMap->setKeepMouseGrab(true); m_declarativeMap->setKeepTouchGrab(true); startTilt(); setTiltState(tiltActive); @@ -1276,7 +1268,6 @@ void QQuickGeoMapGestureArea::tiltStateMachine() setTiltState(tiltInactive); } else { if (!isRotationActive() && !isPinchActive() && canStartTilt()) { // only gesture that can be overridden: pan/flick - m_declarativeMap->setKeepMouseGrab(true); m_declarativeMap->setKeepTouchGrab(true); startTilt(); setTiltState(tiltActive); @@ -1286,7 +1277,6 @@ void QQuickGeoMapGestureArea::tiltStateMachine() case tiltActive: if (m_allPoints.count() <= 1) { setTiltState(tiltInactive); - m_declarativeMap->setKeepMouseGrab(m_preventStealing); m_declarativeMap->setKeepTouchGrab(m_preventStealing); endTilt(); } @@ -1321,8 +1311,8 @@ bool validateTouchAngleForTilting(const qreal angle) bool QQuickGeoMapGestureArea::canStartTilt() { if (m_allPoints.count() >= 2) { - QPointF p1 = mapFromScene(m_allPoints.at(0).scenePos()); - QPointF p2 = mapFromScene(m_allPoints.at(1).scenePos()); + QPointF p1 = mapFromScene(m_allPoints.at(0).scenePosition()); + QPointF p2 = mapFromScene(m_allPoints.at(1).scenePosition()); if (validateTouchAngleForTilting(m_twoTouchAngle) && movingParallelVertical(m_sceneStartPoint1, p1, m_sceneStartPoint2, p2) && qAbs(m_twoTouchPointsCentroidStart.y() - m_touchPointsCentroid.y()) > MinimumPanToTiltDelta) { @@ -1368,8 +1358,8 @@ void QQuickGeoMapGestureArea::updateTilt() m_pinch.m_event.setCenter(mapFromScene(m_touchPointsCentroid)); m_pinch.m_event.setAngle(m_twoTouchAngle); - m_pinch.m_lastPoint1 = mapFromScene(m_allPoints.at(0).scenePos()); - m_pinch.m_lastPoint2 = mapFromScene(m_allPoints.at(1).scenePos()); + m_pinch.m_lastPoint1 = mapFromScene(m_allPoints.at(0).scenePosition()); + m_pinch.m_lastPoint2 = mapFromScene(m_allPoints.at(1).scenePosition()); m_pinch.m_event.setPoint1(m_pinch.m_lastPoint1); m_pinch.m_event.setPoint2(m_pinch.m_lastPoint2); m_pinch.m_event.setPointCount(m_allPoints.count()); @@ -1405,7 +1395,6 @@ void QQuickGeoMapGestureArea::rotationStateMachine() case rotationInactive: if (m_allPoints.count() >= 2) { if (!isTiltActive() && canStartRotation()) { - m_declarativeMap->setKeepMouseGrab(true); m_declarativeMap->setKeepTouchGrab(true); startRotation(); setRotationState(rotationActive); @@ -1419,7 +1408,6 @@ void QQuickGeoMapGestureArea::rotationStateMachine() setRotationState(rotationInactive); } else { if (!isTiltActive() && canStartRotation()) { - m_declarativeMap->setKeepMouseGrab(true); m_declarativeMap->setKeepTouchGrab(true); startRotation(); setRotationState(rotationActive); @@ -1429,7 +1417,6 @@ void QQuickGeoMapGestureArea::rotationStateMachine() case rotationActive: if (m_allPoints.count() <= 1) { setRotationState(rotationInactive); - m_declarativeMap->setKeepMouseGrab(m_preventStealing); m_declarativeMap->setKeepTouchGrab(m_preventStealing); endRotation(); } @@ -1459,8 +1446,8 @@ void QQuickGeoMapGestureArea::rotationStateMachine() bool QQuickGeoMapGestureArea::canStartRotation() { if (m_allPoints.count() >= 2) { - QPointF p1 = mapFromScene(m_allPoints.at(0).scenePos()); - QPointF p2 = mapFromScene(m_allPoints.at(1).scenePos()); + QPointF p1 = mapFromScene(m_allPoints.at(0).scenePosition()); + QPointF p2 = mapFromScene(m_allPoints.at(1).scenePosition()); if (pointDragged(m_sceneStartPoint1, p1) || pointDragged(m_sceneStartPoint2, p2)) { qreal delta = angleDelta(m_twoTouchAngleStart, m_twoTouchAngle); if (qAbs(delta) < MinimumRotationStartingAngle) { @@ -1506,8 +1493,8 @@ void QQuickGeoMapGestureArea::updateRotation() m_pinch.m_event.setCenter(mapFromScene(m_touchPointsCentroid)); m_pinch.m_event.setAngle(m_twoTouchAngle); - m_pinch.m_lastPoint1 = mapFromScene(m_allPoints.at(0).scenePos()); - m_pinch.m_lastPoint2 = mapFromScene(m_allPoints.at(1).scenePos()); + m_pinch.m_lastPoint1 = mapFromScene(m_allPoints.at(0).scenePosition()); + m_pinch.m_lastPoint2 = mapFromScene(m_allPoints.at(1).scenePosition()); m_pinch.m_event.setPoint1(m_pinch.m_lastPoint1); m_pinch.m_event.setPoint2(m_pinch.m_lastPoint2); m_pinch.m_event.setPointCount(m_allPoints.count()); @@ -1543,7 +1530,6 @@ void QQuickGeoMapGestureArea::pinchStateMachine() case pinchInactive: if (m_allPoints.count() >= 2) { if (!isTiltActive() && canStartPinch()) { - m_declarativeMap->setKeepMouseGrab(true); m_declarativeMap->setKeepTouchGrab(true); startPinch(); setPinchState(pinchActive); @@ -1557,7 +1543,6 @@ void QQuickGeoMapGestureArea::pinchStateMachine() setPinchState(pinchInactive); } else { if (!isTiltActive() && canStartPinch()) { - m_declarativeMap->setKeepMouseGrab(true); m_declarativeMap->setKeepTouchGrab(true); startPinch(); setPinchState(pinchActive); @@ -1567,7 +1552,6 @@ void QQuickGeoMapGestureArea::pinchStateMachine() case pinchActive: if (m_allPoints.count() <= 1) { // Once started, pinch goes off only when finger(s) are release setPinchState(pinchInactive); - m_declarativeMap->setKeepMouseGrab(m_preventStealing); m_declarativeMap->setKeepTouchGrab(m_preventStealing); endPinch(); } @@ -1597,8 +1581,8 @@ void QQuickGeoMapGestureArea::pinchStateMachine() bool QQuickGeoMapGestureArea::canStartPinch() { if (m_allPoints.count() >= 2) { - QPointF p1 = mapFromScene(m_allPoints.at(0).scenePos()); - QPointF p2 = mapFromScene(m_allPoints.at(1).scenePos()); + QPointF p1 = mapFromScene(m_allPoints.at(0).scenePosition()); + QPointF p2 = mapFromScene(m_allPoints.at(1).scenePosition()); if (qAbs(m_distanceBetweenTouchPoints - m_distanceBetweenTouchPointsStart) > MinimumPinchDelta) { m_pinch.m_event.setCenter(mapFromScene(m_touchPointsCentroid)); m_pinch.m_event.setAngle(m_twoTouchAngle); @@ -1622,8 +1606,8 @@ void QQuickGeoMapGestureArea::startPinch() m_pinch.m_zoom.m_previous = m_declarativeMap->zoomLevel(); m_pinch.m_lastAngle = m_twoTouchAngle; - m_pinch.m_lastPoint1 = mapFromScene(m_allPoints.at(0).scenePos()); - m_pinch.m_lastPoint2 = mapFromScene(m_allPoints.at(1).scenePos()); + m_pinch.m_lastPoint1 = mapFromScene(m_allPoints.at(0).scenePosition()); + m_pinch.m_lastPoint2 = mapFromScene(m_allPoints.at(1).scenePosition()); m_pinch.m_zoom.m_start = m_declarativeMap->zoomLevel(); } @@ -1648,8 +1632,8 @@ void QQuickGeoMapGestureArea::updatePinch() m_pinch.m_event.setCenter(mapFromScene(m_touchPointsCentroid)); m_pinch.m_event.setAngle(m_twoTouchAngle); - m_pinch.m_lastPoint1 = mapFromScene(m_allPoints.at(0).scenePos()); - m_pinch.m_lastPoint2 = mapFromScene(m_allPoints.at(1).scenePos()); + m_pinch.m_lastPoint1 = mapFromScene(m_allPoints.at(0).scenePosition()); + m_pinch.m_lastPoint2 = mapFromScene(m_allPoints.at(1).scenePosition()); m_pinch.m_event.setPoint1(m_pinch.m_lastPoint1); m_pinch.m_event.setPoint2(m_pinch.m_lastPoint2); m_pinch.m_event.setPointCount(m_allPoints.count()); @@ -1701,6 +1685,7 @@ void QQuickGeoMapGestureArea::panStateMachine() m_startCoord.setLongitude(newStartCoord.longitude()); m_startCoord.setLatitude(newStartCoord.latitude()); m_declarativeMap->setKeepMouseGrab(true); + m_declarativeMap->setKeepTouchGrab(true); setFlickState(panActive); } break; @@ -1712,6 +1697,7 @@ void QQuickGeoMapGestureArea::panStateMachine() // mark as inactive for use by camera if (m_pinchState == pinchInactive && m_rotationState == rotationInactive && m_tiltState == tiltInactive) { m_declarativeMap->setKeepMouseGrab(m_preventStealing); + m_declarativeMap->setKeepTouchGrab(m_preventStealing); m_map->prefetchData(); } emit panFinished(); @@ -1726,6 +1712,7 @@ void QQuickGeoMapGestureArea::panStateMachine() if (m_allPoints.count() > 0) { // re touched before movement ended stopFlick(); m_declarativeMap->setKeepMouseGrab(true); + m_declarativeMap->setKeepTouchGrab(true); setFlickState(panActive); } break; @@ -1753,18 +1740,18 @@ void QQuickGeoMapGestureArea::panStateMachine() */ bool QQuickGeoMapGestureArea::canStartPan() { - if (m_allPoints.count() == 0 || (m_acceptedGestures & PanGesture) == 0 - || (m_mousePoint && m_mousePoint->state() == QEventPoint::State::Released)) // mouseReleaseEvent handling does not clear m_mousePoint, only ungrabMouse does -- QTBUG-66534 + if (m_allPoints.count() == 0 || (m_acceptedGestures & PanGesture) == 0) return false; // Check if thresholds for normal panning are met. // (normal panning vs flicking: flicking will start from mouse release event). const int startDragDistance = qApp->styleHints()->startDragDistance() * 2; - QPointF p1 = mapFromScene(m_allPoints.at(0).scenePos()); + QPointF p1 = mapFromScene(m_allPoints.at(0).scenePosition()); int dyFromPress = int(p1.y() - m_sceneStartPoint1.y()); int dxFromPress = int(p1.x() - m_sceneStartPoint1.x()); if ((qAbs(dyFromPress) >= startDragDistance || qAbs(dxFromPress) >= startDragDistance)) return true; + return false; } diff --git a/src/location/declarativemaps/qquickgeomapgesturearea_p.h b/src/location/declarativemaps/qquickgeomapgesturearea_p.h index dfbe682d..a13dd4c6 100644 --- a/src/location/declarativemaps/qquickgeomapgesturearea_p.h +++ b/src/location/declarativemaps/qquickgeomapgesturearea_p.h @@ -162,14 +162,13 @@ public: qreal flickDeceleration() const; void setFlickDeceleration(qreal deceleration); - void handleTouchEvent(QTouchEvent *event); + void handleTouchEvent(QPointerEvent *event); #if QT_CONFIG(wheelevent) void handleWheelEvent(QWheelEvent *event); #endif void handleMousePressEvent(QMouseEvent *event); void handleMouseMoveEvent(QMouseEvent *event); void handleMouseReleaseEvent(QMouseEvent *event); - void handleMouseUngrabEvent(); void handleTouchUngrabEvent(); void setMinimumZoomLevel(qreal min); @@ -333,7 +332,6 @@ private: QPointF m_lastPos; QList<QTouchEvent::TouchPoint> m_allPoints; QList<QTouchEvent::TouchPoint> m_touchPoints; - QScopedPointer<QTouchEvent::TouchPoint> m_mousePoint; QPointF m_sceneStartPoint1; // only set when two points in contact |