diff options
Diffstat (limited to 'src/quick/items/qquickpincharea.cpp')
-rw-r--r-- | src/quick/items/qquickpincharea.cpp | 94 |
1 files changed, 42 insertions, 52 deletions
diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index b41815d88b..482941b9ba 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtSG module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qquickpincharea_p_p.h" #include "qquickwindow.h" @@ -283,7 +247,7 @@ QQuickPinchArea::QQuickPinchArea(QQuickItem *parent) Q_D(QQuickPinchArea); d->init(); setAcceptTouchEvents(true); -#ifdef Q_OS_OSX +#ifdef Q_OS_MACOS setAcceptHoverEvents(true); // needed to enable touch events on mouse hover. #endif } @@ -360,7 +324,7 @@ void QQuickPinchArea::touchEvent(QTouchEvent *event) void QQuickPinchArea::clearPinch(QTouchEvent *event) { Q_D(QQuickPinchArea); - qCDebug(lcPA, "clear: %lld touchpoints", d->touchPoints.count()); + qCDebug(lcPA, "clear: %" PRIdQSIZETYPE " touchpoints", d->touchPoints.size()); d->touchPoints.clear(); if (d->inPinch) { d->inPinch = false; @@ -390,12 +354,13 @@ void QQuickPinchArea::clearPinch(QTouchEvent *event) } } setKeepTouchGrab(false); + setKeepMouseGrab(false); } void QQuickPinchArea::cancelPinch(QTouchEvent *event) { Q_D(QQuickPinchArea); - qCDebug(lcPA, "cancel: %lld touchpoints", d->touchPoints.count()); + qCDebug(lcPA, "cancel: %" PRIdQSIZETYPE " touchpoints", d->touchPoints.size()); d->touchPoints.clear(); if (d->inPinch) { d->inPinch = false; @@ -431,15 +396,17 @@ void QQuickPinchArea::cancelPinch(QTouchEvent *event) event->setExclusiveGrabber(point, nullptr); } setKeepTouchGrab(false); + setKeepMouseGrab(false); } void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) { Q_D(QQuickPinchArea); - if (d->touchPoints.count() < 2) { + if (d->touchPoints.size() < 2) { // A pinch gesture is not occurring, so stealing the grab is permitted. setKeepTouchGrab(false); + setKeepMouseGrab(false); // During filtering, there's no need to hold a grab for one point, // because filtering happens for every event anyway. // But if we receive the event via direct delivery, and give up the grab, @@ -450,7 +417,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) event->setExclusiveGrabber(d->touchPoints.first(), nullptr); } - if (d->touchPoints.count() == 0) { + if (d->touchPoints.size() == 0) { if (d->inPinch) { d->inPinch = false; QPointF pinchCenter = mapFromScene(d->sceneLastCenter); @@ -463,6 +430,8 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); pe.setPoint1(mapFromScene(d->lastPoint1)); pe.setPoint2(mapFromScene(d->lastPoint2)); + setKeepTouchGrab(false); + setKeepMouseGrab(false); emit pinchFinished(&pe); d->pinchStartDist = 0; d->pinchActivated = false; @@ -475,7 +444,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) } QEventPoint touchPoint1 = d->touchPoints.at(0); - QEventPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0); + QEventPoint touchPoint2 = d->touchPoints.at(d->touchPoints.size() >= 2 ? 1 : 0); if (touchPoint1.state() == QEventPoint::State::Pressed) d->sceneStartPoint1 = touchPoint1.scenePosition(); @@ -489,7 +458,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) // 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) // AND both points are inside the bounds. - if (d->touchPoints.count() == 2 + if (d->touchPoints.size() == 2 && (touchPoint1.state() == QEventPoint::State::Pressed || touchPoint2.state() == QEventPoint::State::Pressed) && bounds.contains(touchPoint1.position()) && bounds.contains(touchPoint2.position())) { d->id1 = touchPoint1.id(); @@ -499,6 +468,8 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) d->initPinch = true; event->setExclusiveGrabber(touchPoint1, this); event->setExclusiveGrabber(touchPoint2, this); + setKeepTouchGrab(true); + setKeepMouseGrab(true); } if (d->pinchActivated && !d->pinchRejected) { const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); @@ -509,7 +480,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) qreal dist = qSqrt(dx*dx + dy*dy); QPointF sceneCenter = (p1 + p2)/2; qreal angle = QLineF(p1, p2).angle(); - if (d->touchPoints.count() == 1) { + if (d->touchPoints.size() == 1) { // If we only have one point then just move the center if (d->id1 == touchPoint1.id()) sceneCenter = d->sceneLastCenter + touchPoint1.scenePosition() - d->lastPoint1; @@ -523,7 +494,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) qCDebug(lcPA, "pinch \u2316 %.1lf,%.1lf \u21e4%.1lf\u21e5 \u2220 %.1lf", sceneCenter.x(), sceneCenter.y(), dist, angle); if (!d->inPinch || d->initPinch) { - if (d->touchPoints.count() >= 2) { + if (d->touchPoints.size() >= 2) { if (d->initPinch) { if (!d->inPinch) d->pinchStartDist = dist; @@ -554,16 +525,22 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); pe.setPoint1(mapFromScene(d->lastPoint1)); pe.setPoint2(mapFromScene(d->lastPoint2)); - pe.setPointCount(d->touchPoints.count()); + pe.setPointCount(d->touchPoints.size()); emit pinchStarted(&pe); if (pe.accepted()) { d->inPinch = true; event->setExclusiveGrabber(touchPoint1, this); event->setExclusiveGrabber(touchPoint2, this); setKeepTouchGrab(true); + // So that PinchArea works in PathView, grab mouse events too. + // We should be able to remove these setKeepMouseGrab calls when QTBUG-105567 is fixed. + setKeepMouseGrab(true); d->inPinch = true; if (d->pinch && d->pinch->target()) { - d->pinchStartPos = pinch()->target()->position(); + auto targetParent = pinch()->target()->parentItem(); + d->pinchStartPos = targetParent ? + targetParent->mapToScene(pinch()->target()->position()) : + pinch()->target()->position(); d->pinchStartScale = d->pinch->target()->scale(); d->pinchStartRotation = d->pinch->target()->rotation(); d->pinch->setActive(true); @@ -591,7 +568,7 @@ void QQuickPinchArea::updatePinch(QTouchEvent *event, bool filtering) pe.setStartPoint2(mapFromScene(d->sceneStartPoint2)); pe.setPoint1(touchPoint1.position()); pe.setPoint2(touchPoint2.position()); - pe.setPointCount(d->touchPoints.count()); + pe.setPointCount(d->touchPoints.size()); d->pinchLastScale = scale; d->sceneLastCenter = sceneCenter; d->pinchLastAngle = angle; @@ -611,6 +588,9 @@ void QQuickPinchArea::updatePinchTarget() s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale()); pinch()->target()->setScale(s); QPointF pos = d->sceneLastCenter - d->sceneStartCenter + d->pinchStartPos; + if (auto targetParent = pinch()->target()->parentItem()) + pos = targetParent->mapFromScene(pos); + if (pinch()->axis() & QQuickPinch::XAxis) { qreal x = pos.x(); if (x < pinch()->xmin()) @@ -721,6 +701,8 @@ bool QQuickPinchArea::event(QEvent *event) clearPinch(nullptr); break; case Qt::ZoomNativeGesture: { + if (d->pinchRejected) + break; qreal scale = d->pinchLastScale * (1.0 + gesture->value()); QQuickPinchEvent pe(d->pinchStartCenter, scale, d->pinchLastAngle, 0.0); pe.setStartCenter(d->pinchStartCenter); @@ -738,7 +720,10 @@ bool QQuickPinchArea::event(QEvent *event) else emit pinchStarted(&pe); d->inPinch = true; - updatePinchTarget(); + if (pe.accepted()) + updatePinchTarget(); + else + d->pinchRejected = true; } break; case Qt::SmartZoomNativeGesture: { if (gesture->value() > 0.0 && d->pinch && d->pinch->target()) { @@ -762,6 +747,8 @@ bool QQuickPinchArea::event(QEvent *event) emit smartZoom(&pe); } break; case Qt::RotateNativeGesture: { + if (d->pinchRejected) + break; qreal angle = d->pinchLastAngle + gesture->value(); QQuickPinchEvent pe(d->pinchStartCenter, d->pinchLastScale, angle, 0.0); pe.setStartCenter(d->pinchStartCenter); @@ -780,7 +767,10 @@ bool QQuickPinchArea::event(QEvent *event) emit pinchStarted(&pe); d->inPinch = true; d->pinchRotation = angle; - updatePinchTarget(); + if (pe.accepted()) + updatePinchTarget(); + else + d->pinchRejected = true; } break; default: return QQuickItem::event(event); |