diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-04-23 09:33:25 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-04-23 09:34:29 +0200 |
commit | 580fa7dc88aae23053e44ffa335a15f6af112a20 (patch) | |
tree | 5bc915d7c2e252739122d9441bd0d7fa7175d0c2 /src/quick/handlers | |
parent | 6767114285db9d0e16dc278d08f231e8561546b4 (diff) | |
parent | c00283bb3bb966bf60c307ec8283bd98c12318bf (diff) |
Merge remote-tracking branch 'origin/dev' into wip/scenegraphng
Change-Id: Ifec879473540b609403ac951967f6d9ecb0bb6f0
Diffstat (limited to 'src/quick/handlers')
-rw-r--r-- | src/quick/handlers/handlers.pri | 1 | ||||
-rw-r--r-- | src/quick/handlers/qquickdragaxis.cpp | 3 | ||||
-rw-r--r-- | src/quick/handlers/qquickdragaxis_p.h | 11 | ||||
-rw-r--r-- | src/quick/handlers/qquickdraghandler.cpp | 15 | ||||
-rw-r--r-- | src/quick/handlers/qquickdraghandler_p.h | 2 | ||||
-rw-r--r-- | src/quick/handlers/qquickhoverhandler_p.h | 2 | ||||
-rw-r--r-- | src/quick/handlers/qquickmultipointhandler.cpp | 168 | ||||
-rw-r--r-- | src/quick/handlers/qquickmultipointhandler_p.h | 18 | ||||
-rw-r--r-- | src/quick/handlers/qquickmultipointhandler_p_p.h | 83 | ||||
-rw-r--r-- | src/quick/handlers/qquickpinchhandler.cpp | 58 | ||||
-rw-r--r-- | src/quick/handlers/qquickpinchhandler_p.h | 3 | ||||
-rw-r--r-- | src/quick/handlers/qquickpointerdevicehandler_p.h | 2 | ||||
-rw-r--r-- | src/quick/handlers/qquickpointerdevicehandler_p_p.h | 2 | ||||
-rw-r--r-- | src/quick/handlers/qquickpointhandler_p.h | 2 | ||||
-rw-r--r-- | src/quick/handlers/qquicktaphandler_p.h | 2 |
15 files changed, 260 insertions, 112 deletions
diff --git a/src/quick/handlers/handlers.pri b/src/quick/handlers/handlers.pri index 226cca22cb..fa2f25c793 100644 --- a/src/quick/handlers/handlers.pri +++ b/src/quick/handlers/handlers.pri @@ -3,6 +3,7 @@ HEADERS += \ $$PWD/qquickhandlerpoint_p.h \ $$PWD/qquickhoverhandler_p.h \ $$PWD/qquickmultipointhandler_p.h \ + $$PWD/qquickmultipointhandler_p_p.h \ $$PWD/qquickpinchhandler_p.h \ $$PWD/qquickpointerdevicehandler_p.h \ $$PWD/qquickpointerdevicehandler_p_p.h \ diff --git a/src/quick/handlers/qquickdragaxis.cpp b/src/quick/handlers/qquickdragaxis.cpp index 5efe19b2fe..88470c8a7d 100644 --- a/src/quick/handlers/qquickdragaxis.cpp +++ b/src/quick/handlers/qquickdragaxis.cpp @@ -39,6 +39,8 @@ #include "qquickdragaxis_p.h" #include <limits> +QT_BEGIN_NAMESPACE + QQuickDragAxis::QQuickDragAxis() : m_minimum(-std::numeric_limits<qreal>::max()) , m_maximum(std::numeric_limits<qreal>::max()) @@ -73,3 +75,4 @@ void QQuickDragAxis::setEnabled(bool enabled) emit enabledChanged(); } +QT_END_NAMESPACE diff --git a/src/quick/handlers/qquickdragaxis_p.h b/src/quick/handlers/qquickdragaxis_p.h index 2c2e0a426d..a4649d5eb9 100644 --- a/src/quick/handlers/qquickdragaxis_p.h +++ b/src/quick/handlers/qquickdragaxis_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtQuick module of the Qt Toolkit. @@ -51,10 +51,11 @@ // We mean it. // -#include <QtCore/qobject.h> -#include <QtCore/qglobal.h> +#include <private/qtquickglobal_p.h> -class Q_AUTOTEST_EXPORT QQuickDragAxis : public QObject +QT_BEGIN_NAMESPACE + +class Q_QUICK_PRIVATE_EXPORT QQuickDragAxis : public QObject { Q_OBJECT Q_PROPERTY(qreal minimum READ minimum WRITE setMinimum NOTIFY minimumChanged) @@ -84,4 +85,6 @@ private: bool m_enabled; }; +QT_END_NAMESPACE + #endif // QQUICKDRAGAXIS_P_H diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp index 48f0599284..22fe3df4d0 100644 --- a/src/quick/handlers/qquickdraghandler.cpp +++ b/src/quick/handlers/qquickdraghandler.cpp @@ -103,7 +103,7 @@ bool QQuickDragHandler::targetContainsCentroid() QPointF QQuickDragHandler::targetCentroidPosition() { - QPointF pos = m_centroid.position(); + QPointF pos = centroid().position(); if (target() != parentItem()) pos = parentItem()->mapToItem(target(), pos); return pos; @@ -112,14 +112,13 @@ QPointF QQuickDragHandler::targetCentroidPosition() void QQuickDragHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) { QQuickMultiPointHandler::onGrabChanged(grabber, transition, point); - if (grabber == this && transition == QQuickEventPoint::GrabExclusive) { + if (grabber == this && transition == QQuickEventPoint::GrabExclusive && target()) { // In case the grab got handed over from another grabber, we might not get the Press. if (!m_pressedInsideTarget) { - if (target()) + if (target() != parentItem()) m_pressTargetPos = QPointF(target()->width(), target()->height()) / 2; } else if (m_pressTargetPos.isNull()) { - if (target()) - m_pressTargetPos = targetCentroidPosition(); + m_pressTargetPos = targetCentroidPosition(); } } } @@ -154,7 +153,7 @@ void QQuickDragHandler::handlePointerEventImpl(QQuickPointerEvent *event) if (active()) { // Calculate drag delta, taking into account the axis enabled constraint // i.e. if xAxis is not enabled, then ignore the horizontal component of the actual movement - QVector2D accumulatedDragDelta = QVector2D(m_centroid.scenePosition() - m_centroid.scenePressPosition()); + QVector2D accumulatedDragDelta = QVector2D(centroid().scenePosition() - centroid().scenePressPosition()); if (!m_xAxis.enabled()) accumulatedDragDelta.setX(0); if (!m_yAxis.enabled()) @@ -170,9 +169,9 @@ void QQuickDragHandler::handlePointerEventImpl(QQuickPointerEvent *event) QVector <QQuickEventPoint *> chosenPoints; if (event->isPressEvent()) - m_pressedInsideTarget = target() && m_currentPoints.count() > 0; + m_pressedInsideTarget = target() && currentPoints().count() > 0; - for (const QQuickHandlerPoint &p : m_currentPoints) { + for (const QQuickHandlerPoint &p : currentPoints()) { if (!allOverThreshold) break; QQuickEventPoint *point = event->pointById(p.id()); diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h index 387a81eb43..748026488a 100644 --- a/src/quick/handlers/qquickdraghandler_p.h +++ b/src/quick/handlers/qquickdraghandler_p.h @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickDragHandler : public QQuickMultiPointHandler +class Q_QUICK_PRIVATE_EXPORT QQuickDragHandler : public QQuickMultiPointHandler { Q_OBJECT Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT) diff --git a/src/quick/handlers/qquickhoverhandler_p.h b/src/quick/handlers/qquickhoverhandler_p.h index 1ee2aeb7e6..d8e5fc00a1 100644 --- a/src/quick/handlers/qquickhoverhandler_p.h +++ b/src/quick/handlers/qquickhoverhandler_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickHoverHandler : public QQuickSinglePointHandler +class Q_QUICK_PRIVATE_EXPORT QQuickHoverHandler : public QQuickSinglePointHandler { Q_OBJECT Q_PROPERTY(bool hovered READ isHovered NOTIFY hoveredChanged) diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp index baa68e5e53..5c10ecce75 100644 --- a/src/quick/handlers/qquickmultipointhandler.cpp +++ b/src/quick/handlers/qquickmultipointhandler.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qquickmultipointhandler_p.h" +#include "qquickmultipointhandler_p_p.h" #include <private/qquickitem_p.h> #include <QLineF> #include <QMouseEvent> @@ -59,14 +60,13 @@ QT_BEGIN_NAMESPACE of multiple touchpoints. */ QQuickMultiPointHandler::QQuickMultiPointHandler(QQuickItem *parent, int minimumPointCount, int maximumPointCount) - : QQuickPointerDeviceHandler(parent) - , m_minimumPointCount(minimumPointCount) - , m_maximumPointCount(maximumPointCount) + : QQuickPointerDeviceHandler(*(new QQuickMultiPointHandlerPrivate(minimumPointCount, maximumPointCount)), parent) { } bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event) { + Q_D(QQuickMultiPointHandler); if (!QQuickPointerDeviceHandler::wantsPointerEvent(event)) return false; @@ -83,14 +83,14 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event) // handle a specific number of points, so a differing number of points will // usually result in different behavior. But otherwise if the currentPoints // are all still there in the event, we're good to go (do not reset - // m_currentPoints, because we don't want to lose the pressPosition, and do + // currentPoints, because we don't want to lose the pressPosition, and do // not want to reshuffle the order either). const QVector<QQuickEventPoint *> candidatePoints = eligiblePoints(event); - if (candidatePoints.count() != m_currentPoints.count()) { - m_currentPoints.clear(); + if (candidatePoints.count() != d->currentPoints.count()) { + d->currentPoints.clear(); if (active()) { setActive(false); - m_centroid.reset(); + d->centroid.reset(); emit centroidChanged(); } } else if (hasCurrentPoints(event)) { @@ -100,57 +100,60 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event) const bool ret = (candidatePoints.size() >= minimumPointCount() && candidatePoints.size() <= maximumPointCount()); if (ret) { const int c = candidatePoints.count(); - m_currentPoints.resize(c); + d->currentPoints.resize(c); for (int i = 0; i < c; ++i) { - m_currentPoints[i].reset(candidatePoints[i]); - m_currentPoints[i].localize(parentItem()); + d->currentPoints[i].reset(candidatePoints[i]); + d->currentPoints[i].localize(parentItem()); } } else { - m_currentPoints.clear(); + d->currentPoints.clear(); } return ret; } void QQuickMultiPointHandler::handlePointerEventImpl(QQuickPointerEvent *event) { + Q_D(QQuickMultiPointHandler); QQuickPointerHandler::handlePointerEventImpl(event); - // event's points can be reordered since the previous event, which is why m_currentPoints + // event's points can be reordered since the previous event, which is why currentPoints // is _not_ a shallow copy of the QQuickPointerTouchEvent::m_touchPoints vector. - // So we have to update our m_currentPoints instances based on the given event. - for (QQuickHandlerPoint &p : m_currentPoints) { + // So we have to update our currentPoints instances based on the given event. + for (QQuickHandlerPoint &p : d->currentPoints) { const QQuickEventPoint *ep = event->pointById(p.id()); if (ep) p.reset(ep); } - QPointF sceneGrabPos = m_centroid.sceneGrabPosition(); - m_centroid.reset(m_currentPoints); - m_centroid.m_sceneGrabPosition = sceneGrabPos; // preserve as it was + QPointF sceneGrabPos = d->centroid.sceneGrabPosition(); + d->centroid.reset(d->currentPoints); + d->centroid.m_sceneGrabPosition = sceneGrabPos; // preserve as it was emit centroidChanged(); } void QQuickMultiPointHandler::onActiveChanged() { + Q_D(QQuickMultiPointHandler); if (active()) { - m_centroid.m_sceneGrabPosition = m_centroid.m_scenePosition; + d->centroid.m_sceneGrabPosition = d->centroid.m_scenePosition; } else { - // Don't call m_centroid.reset() here, because in a QML onActiveChanged + // Don't call centroid.reset() here, because in a QML onActiveChanged // callback, we'd like to see what the position _was_, what the velocity _was_, etc. // (having them undefined is not useful) // But pressedButtons and pressedModifiers are meant to be more real-time than those // (which seems a bit inconsistent, from one side). - m_centroid.m_pressedButtons = Qt::NoButton; - m_centroid.m_pressedModifiers = Qt::NoModifier; + d->centroid.m_pressedButtons = Qt::NoButton; + d->centroid.m_pressedModifiers = Qt::NoModifier; } } void QQuickMultiPointHandler::onGrabChanged(QQuickPointerHandler *, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *) { + Q_D(QQuickMultiPointHandler); // If another handler or item takes over this set of points, assume it has // decided that it's the better fit for them. Don't immediately re-grab // at the next opportunity. This should help to avoid grab cycles // (e.g. between DragHandler and PinchHandler). if (transition == QQuickEventPoint::UngrabExclusive || transition == QQuickEventPoint::CancelGrabExclusive) - m_currentPoints.clear(); + d->currentPoints.clear(); } QVector<QQuickEventPoint *> QQuickMultiPointHandler::eligiblePoints(QQuickPointerEvent *event) @@ -190,14 +193,21 @@ QVector<QQuickEventPoint *> QQuickMultiPointHandler::eligiblePoints(QQuickPointe The default value is 2. */ +int QQuickMultiPointHandler::minimumPointCount() const +{ + Q_D(const QQuickMultiPointHandler); + return d->minimumPointCount; +} + void QQuickMultiPointHandler::setMinimumPointCount(int c) { - if (m_minimumPointCount == c) + Q_D(QQuickMultiPointHandler); + if (d->minimumPointCount == c) return; - m_minimumPointCount = c; + d->minimumPointCount = c; emit minimumPointCountChanged(); - if (m_maximumPointCount < 0) + if (d->maximumPointCount < 0) emit maximumPointCountChanged(); } @@ -216,22 +226,61 @@ void QQuickMultiPointHandler::setMinimumPointCount(int c) The default value is the same as \l minimumPointCount. */ +int QQuickMultiPointHandler::maximumPointCount() const +{ + Q_D(const QQuickMultiPointHandler); + return d->maximumPointCount >= 0 ? d->maximumPointCount : d->minimumPointCount; +} + void QQuickMultiPointHandler::setMaximumPointCount(int maximumPointCount) { - if (m_maximumPointCount == maximumPointCount) + Q_D(QQuickMultiPointHandler); + if (d->maximumPointCount == maximumPointCount) return; - m_maximumPointCount = maximumPointCount; + d->maximumPointCount = maximumPointCount; emit maximumPointCountChanged(); } +/*! + \readonly + \qmlproperty QtQuick::HandlerPoint QtQuick::MultiPointHandler::centroid + + A point exactly in the middle of the currently-pressed touch points. + If only one point is pressed, it's the same as that point. + A handler that has a \l target will normally transform it relative to this point. +*/ +const QQuickHandlerPoint &QQuickMultiPointHandler::centroid() const +{ + Q_D(const QQuickMultiPointHandler); + return d->centroid; +} + +/*! + Returns a modifiable reference to the point that will be returned by the + \l centroid property. If you modify it, you are responsible to emit + \l centroidChanged. +*/ +QQuickHandlerPoint &QQuickMultiPointHandler::mutableCentroid() +{ + Q_D(QQuickMultiPointHandler); + return d->centroid; +} + +QVector<QQuickHandlerPoint> &QQuickMultiPointHandler::currentPoints() +{ + Q_D(QQuickMultiPointHandler); + return d->currentPoints; +} + bool QQuickMultiPointHandler::hasCurrentPoints(QQuickPointerEvent *event) { - if (event->pointCount() < m_currentPoints.size() || m_currentPoints.size() == 0) + Q_D(const QQuickMultiPointHandler); + if (event->pointCount() < d->currentPoints.size() || d->currentPoints.size() == 0) return false; // TODO optimize: either ensure the points are sorted, // or use std::equal with a predicate - for (const QQuickHandlerPoint &p : qAsConst(m_currentPoints)) { + for (const QQuickHandlerPoint &p : qAsConst(d->currentPoints)) { const QQuickEventPoint *ep = event->pointById(p.id()); if (!ep) return false; @@ -243,30 +292,33 @@ bool QQuickMultiPointHandler::hasCurrentPoints(QQuickPointerEvent *event) qreal QQuickMultiPointHandler::averageTouchPointDistance(const QPointF &ref) { + Q_D(const QQuickMultiPointHandler); qreal ret = 0; - if (Q_UNLIKELY(m_currentPoints.size() == 0)) + if (Q_UNLIKELY(d->currentPoints.size() == 0)) return ret; - for (const QQuickHandlerPoint &p : m_currentPoints) + for (const QQuickHandlerPoint &p : d->currentPoints) ret += QVector2D(p.scenePosition() - ref).length(); - return ret / m_currentPoints.size(); + return ret / d->currentPoints.size(); } qreal QQuickMultiPointHandler::averageStartingDistance(const QPointF &ref) { + Q_D(const QQuickMultiPointHandler); // TODO cache it in setActive()? qreal ret = 0; - if (Q_UNLIKELY(m_currentPoints.size() == 0)) + if (Q_UNLIKELY(d->currentPoints.size() == 0)) return ret; - for (const QQuickHandlerPoint &p : m_currentPoints) + for (const QQuickHandlerPoint &p : d->currentPoints) ret += QVector2D(p.sceneGrabPosition() - ref).length(); - return ret / m_currentPoints.size(); + return ret / d->currentPoints.size(); } QVector<QQuickMultiPointHandler::PointData> QQuickMultiPointHandler::angles(const QPointF &ref) const { + Q_D(const QQuickMultiPointHandler); QVector<PointData> angles; - angles.reserve(m_currentPoints.count()); - for (const QQuickHandlerPoint &p : m_currentPoints) { + angles.reserve(d->currentPoints.count()); + for (const QQuickHandlerPoint &p : d->currentPoints) { qreal angle = QLineF(ref, p.scenePosition()).angle(); angles.append(PointData(p.id(), -angle)); // convert to clockwise, to be consistent with QQuickItem::rotation } @@ -331,17 +383,41 @@ bool QQuickMultiPointHandler::grabPoints(QVector<QQuickEventPoint *> points) void QQuickMultiPointHandler::moveTarget(QPointF pos) { - target()->setPosition(pos); - m_centroid.m_position = target()->mapFromScene(m_centroid.m_scenePosition); + Q_D(QQuickMultiPointHandler); + if (QQuickItem *t = target()) { + d->xMetaProperty().write(t, pos.x()); + d->yMetaProperty().write(t, pos.y()); + d->centroid.m_position = t->mapFromScene(d->centroid.m_scenePosition); + } else { + qWarning() << "moveTarget: target is null"; + } } -/*! - \readonly - \qmlproperty QtQuick::HandlerPoint QtQuick::MultiPointHandler::centroid +QQuickMultiPointHandlerPrivate::QQuickMultiPointHandlerPrivate(int minPointCount, int maxPointCount) + : QQuickPointerDeviceHandlerPrivate() + , minimumPointCount(minPointCount) + , maximumPointCount(maxPointCount) +{ +} - A point exactly in the middle of the currently-pressed touch points. - If only one point is pressed, it's the same as that point. - A handler that has a \l target will normally transform it relative to this point. -*/ +QMetaProperty &QQuickMultiPointHandlerPrivate::xMetaProperty() const +{ + Q_Q(const QQuickMultiPointHandler); + if (!xProperty.isValid() && q->target()) { + const QMetaObject *targetMeta = q->target()->metaObject(); + xProperty = targetMeta->property(targetMeta->indexOfProperty("x")); + } + return xProperty; +} + +QMetaProperty &QQuickMultiPointHandlerPrivate::yMetaProperty() const +{ + Q_Q(const QQuickMultiPointHandler); + if (!yProperty.isValid() && q->target()) { + const QMetaObject *targetMeta = q->target()->metaObject(); + yProperty = targetMeta->property(targetMeta->indexOfProperty("y")); + } + return yProperty; +} QT_END_NAMESPACE diff --git a/src/quick/handlers/qquickmultipointhandler_p.h b/src/quick/handlers/qquickmultipointhandler_p.h index 94142013cc..eeb4b13b83 100644 --- a/src/quick/handlers/qquickmultipointhandler_p.h +++ b/src/quick/handlers/qquickmultipointhandler_p.h @@ -58,7 +58,9 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickMultiPointHandler : public QQuickPointerDeviceHandler +class QQuickMultiPointHandlerPrivate; + +class Q_QUICK_PRIVATE_EXPORT QQuickMultiPointHandler : public QQuickPointerDeviceHandler { Q_OBJECT Q_PROPERTY(int minimumPointCount READ minimumPointCount WRITE setMinimumPointCount NOTIFY minimumPointCountChanged) @@ -68,13 +70,13 @@ class Q_AUTOTEST_EXPORT QQuickMultiPointHandler : public QQuickPointerDeviceHand public: explicit QQuickMultiPointHandler(QQuickItem *parent = nullptr, int minimumPointCount = 2, int maximumPointCount = -1); - int minimumPointCount() const { return m_minimumPointCount; } + int minimumPointCount() const; void setMinimumPointCount(int c); - int maximumPointCount() const { return m_maximumPointCount >= 0 ? m_maximumPointCount : m_minimumPointCount; } + int maximumPointCount() const; void setMaximumPointCount(int maximumPointCount); - QQuickHandlerPoint centroid() const { return m_centroid; } + const QQuickHandlerPoint ¢roid() const; signals: void minimumPointCountChanged(); @@ -94,6 +96,8 @@ protected: void handlePointerEventImpl(QQuickPointerEvent *event) override; void onActiveChanged() override; void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point) override; + QVector<QQuickHandlerPoint> ¤tPoints(); + QQuickHandlerPoint &mutableCentroid(); bool hasCurrentPoints(QQuickPointerEvent *event); QVector<QQuickEventPoint *> eligiblePoints(QQuickPointerEvent *event); qreal averageTouchPointDistance(const QPointF &ref); @@ -106,11 +110,7 @@ protected: bool grabPoints(QVector<QQuickEventPoint *> points); void moveTarget(QPointF pos); -protected: - QVector<QQuickHandlerPoint> m_currentPoints; - QQuickHandlerPoint m_centroid; - int m_minimumPointCount; - int m_maximumPointCount; + Q_DECLARE_PRIVATE(QQuickMultiPointHandler) }; QT_END_NAMESPACE diff --git a/src/quick/handlers/qquickmultipointhandler_p_p.h b/src/quick/handlers/qquickmultipointhandler_p_p.h new file mode 100644 index 0000000000..406e4a1fdf --- /dev/null +++ b/src/quick/handlers/qquickmultipointhandler_p_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQuick 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$ +** +****************************************************************************/ + +#ifndef QQUICKPOINTERMULTIHANDLER_P_H +#define QQUICKPOINTERMULTIHANDLER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquickhandlerpoint_p.h" +#include "qquickpointerdevicehandler_p_p.h" +#include "qquickmultipointhandler_p.h" + +QT_BEGIN_NAMESPACE + +class Q_QUICK_PRIVATE_EXPORT QQuickMultiPointHandlerPrivate : public QQuickPointerDeviceHandlerPrivate +{ + Q_DECLARE_PUBLIC(QQuickMultiPointHandler) + +public: + static QQuickMultiPointHandlerPrivate* get(QQuickMultiPointHandler *q) { return q->d_func(); } + static const QQuickMultiPointHandlerPrivate* get(const QQuickMultiPointHandler *q) { return q->d_func(); } + + QQuickMultiPointHandlerPrivate(int minPointCount, int maxPointCount); + + QMetaProperty &xMetaProperty() const; + QMetaProperty &yMetaProperty() const; + + QVector<QQuickHandlerPoint> currentPoints; + QQuickHandlerPoint centroid; + int minimumPointCount; + int maximumPointCount; + mutable QMetaProperty xProperty; + mutable QMetaProperty yProperty; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPOINTERMULTIHANDLER_P_H diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp index 9ae2116d39..4025cd7fbf 100644 --- a/src/quick/handlers/qquickpinchhandler.cpp +++ b/src/quick/handlers/qquickpinchhandler.cpp @@ -267,20 +267,14 @@ void QQuickPinchHandler::onActiveChanged() { QQuickMultiPointHandler::onActiveChanged(); if (active()) { - m_startMatrix = QMatrix4x4(); - m_startAngles = angles(m_centroid.sceneGrabPosition()); - m_startDistance = averageTouchPointDistance(m_centroid.sceneGrabPosition()); + m_startAngles = angles(centroid().sceneGrabPosition()); + m_startDistance = averageTouchPointDistance(centroid().sceneGrabPosition()); m_activeRotation = 0; m_activeTranslation = QVector2D(); if (const QQuickItem *t = target()) { m_startScale = t->scale(); // TODO incompatible with independent x/y scaling m_startRotation = t->rotation(); - QVector3D xformOrigin(t->transformOriginPoint()); - m_startMatrix.translate(float(t->x()), float(t->y())); - m_startMatrix.translate(xformOrigin); - m_startMatrix.scale(float(m_startScale)); - m_startMatrix.rotate(float(m_startRotation), 0, 0, -1); - m_startMatrix.translate(-xformOrigin); + m_startPos = t->position(); } else { m_startScale = m_accumulatedScale; m_startRotation = 0; @@ -294,7 +288,7 @@ void QQuickPinchHandler::onActiveChanged() void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) { if (Q_UNLIKELY(lcPinchHandler().isDebugEnabled())) { - for (const QQuickHandlerPoint &p : m_currentPoints) + for (const QQuickHandlerPoint &p : currentPoints()) qCDebug(lcPinchHandler) << hex << p.id() << p.sceneGrabPosition() << "->" << p.scenePosition(); } QQuickMultiPointHandler::handlePointerEventImpl(event); @@ -302,13 +296,13 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) qreal dist = 0; #if QT_CONFIG(gestures) if (const auto gesture = event->asPointerNativeGestureEvent()) { - m_centroid.reset(event->point(0)); + mutableCentroid().reset(event->point(0)); switch (gesture->type()) { case Qt::EndNativeGesture: m_activeScale = 1; m_activeRotation = 0; m_activeTranslation = QVector2D(); - m_centroid.reset(); + mutableCentroid().reset(); setActive(false); emit updated(); return; @@ -333,7 +327,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) { const bool containsReleasedPoints = event->isReleaseEvent(); QVector<QQuickEventPoint *> chosenPoints; - for (const QQuickHandlerPoint &p : m_currentPoints) { + for (const QQuickHandlerPoint &p : currentPoints()) { QQuickEventPoint *ep = event->pointById(p.id()); chosenPoints << ep; } @@ -341,8 +335,8 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) // Verify that at least one of the points has moved beyond threshold needed to activate the handler int numberOfPointsDraggedOverThreshold = 0; QVector2D accumulatedDrag; - const QVector2D currentCentroid(m_centroid.scenePosition()); - const QVector2D pressCentroid(m_centroid.scenePressPosition()); + const QVector2D currentCentroid(centroid().scenePosition()); + const QVector2D pressCentroid(centroid().scenePressPosition()); QStyleHints *styleHints = QGuiApplication::styleHints(); const int dragThreshold = styleHints->startDragDistance(); @@ -410,9 +404,9 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) } const bool requiredNumberOfPointsDraggedOverThreshold = numberOfPointsDraggedOverThreshold >= minimumPointCount() && numberOfPointsDraggedOverThreshold <= maximumPointCount(); - accumulatedMovementMagnitude /= m_currentPoints.count(); + accumulatedMovementMagnitude /= currentPoints().count(); - QVector2D avgDrag = accumulatedDrag / m_currentPoints.count(); + QVector2D avgDrag = accumulatedDrag / currentPoints().count(); if (!xAxis()->enabled()) avgDrag.setX(0); if (!yAxis()->enabled()) @@ -445,12 +439,12 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) // avoid mapping the minima and maxima, as they might have unmappable values // such as -inf/+inf. Because of this we perform the bounding to min/max in local coords. // 1. scale - dist = averageTouchPointDistance(m_centroid.scenePosition()); + dist = averageTouchPointDistance(centroid().scenePosition()); m_activeScale = dist / m_startDistance; m_activeScale = qBound(m_minimumScale/m_startScale, m_activeScale, m_maximumScale/m_startScale); // 2. rotate - QVector<PointData> newAngles = angles(m_centroid.scenePosition()); + QVector<PointData> newAngles = angles(centroid().scenePosition()); const qreal angleDelta = averageAngleDelta(m_startAngles, newAngles); m_activeRotation += angleDelta; m_startAngles = std::move(newAngles); @@ -465,25 +459,15 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) m_accumulatedScale = m_startScale * m_activeScale; if (target() && target()->parentItem()) { - const QPointF centroidParentPos = target()->parentItem()->mapFromScene(m_centroid.scenePosition()); + const QPointF centroidParentPos = target()->parentItem()->mapFromScene(centroid().scenePosition()); // 3. Drag/translate - const QPointF centroidStartParentPos = target()->parentItem()->mapFromScene(m_centroid.sceneGrabPosition()); + const QPointF centroidStartParentPos = target()->parentItem()->mapFromScene(centroid().sceneGrabPosition()); m_activeTranslation = QVector2D(centroidParentPos - centroidStartParentPos); // apply rotation + scaling around the centroid - then apply translation. - QMatrix4x4 mat; - - const QVector3D centroidParentVector(centroidParentPos); - mat.translate(centroidParentVector); - mat.rotate(float(m_activeRotation), 0, 0, 1); - mat.scale(float(m_activeScale)); - mat.translate(-centroidParentVector); - mat.translate(QVector3D(m_activeTranslation)); - - mat = mat * m_startMatrix; - - QPointF xformOriginPoint = target()->transformOriginPoint(); - QPointF pos = mat * xformOriginPoint; - pos -= xformOriginPoint; + QPointF pos = QQuickItemPrivate::get(target())->adjustedPosForTransform(centroidParentPos, + m_startPos, m_activeTranslation, + m_startScale, m_activeScale, + m_startRotation, m_activeRotation); if (xAxis()->enabled()) pos.setX(qBound(xAxis()->minimum(), pos.x(), xAxis()->maximum())); @@ -498,10 +482,10 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event) target()->setRotation(rotation); target()->setScale(m_accumulatedScale); } else { - m_activeTranslation = QVector2D(m_centroid.scenePosition() - m_centroid.scenePressPosition()); + m_activeTranslation = QVector2D(centroid().scenePosition() - centroid().scenePressPosition()); } - qCDebug(lcPinchHandler) << "centroid" << m_centroid.scenePressPosition() << "->" << m_centroid.scenePosition() + qCDebug(lcPinchHandler) << "centroid" << centroid().scenePressPosition() << "->" << centroid().scenePosition() << ", distance" << m_startDistance << "->" << dist << ", startScale" << m_startScale << "->" << m_accumulatedScale << ", activeRotation" << m_activeRotation diff --git a/src/quick/handlers/qquickpinchhandler_p.h b/src/quick/handlers/qquickpinchhandler_p.h index 1afc028758..cea794f0c8 100644 --- a/src/quick/handlers/qquickpinchhandler_p.h +++ b/src/quick/handlers/qquickpinchhandler_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler +class Q_QUICK_PRIVATE_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler { Q_OBJECT Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged) @@ -158,7 +158,6 @@ private: qreal m_accumulatedStartCentroidDistance = 0; QVector<PointData> m_startAngles; QQuickMatrix4x4 m_transform; - QMatrix4x4 m_startMatrix; }; QT_END_NAMESPACE diff --git a/src/quick/handlers/qquickpointerdevicehandler_p.h b/src/quick/handlers/qquickpointerdevicehandler_p.h index 82b24369d3..bb15142824 100644 --- a/src/quick/handlers/qquickpointerdevicehandler_p.h +++ b/src/quick/handlers/qquickpointerdevicehandler_p.h @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE class QQuickPointerDeviceHandlerPrivate; -class Q_AUTOTEST_EXPORT QQuickPointerDeviceHandler : public QQuickPointerHandler +class Q_QUICK_PRIVATE_EXPORT QQuickPointerDeviceHandler : public QQuickPointerHandler { Q_OBJECT Q_PROPERTY(QQuickPointerDevice::DeviceTypes acceptedDevices READ acceptedDevices WRITE setAcceptedDevices NOTIFY acceptedDevicesChanged) diff --git a/src/quick/handlers/qquickpointerdevicehandler_p_p.h b/src/quick/handlers/qquickpointerdevicehandler_p_p.h index 6a950590f3..03272d9f69 100644 --- a/src/quick/handlers/qquickpointerdevicehandler_p_p.h +++ b/src/quick/handlers/qquickpointerdevicehandler_p_p.h @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickPointerDeviceHandlerPrivate : public QQuickPointerHandlerPrivate +class Q_QUICK_PRIVATE_EXPORT QQuickPointerDeviceHandlerPrivate : public QQuickPointerHandlerPrivate { Q_DECLARE_PUBLIC(QQuickPointerDeviceHandler) diff --git a/src/quick/handlers/qquickpointhandler_p.h b/src/quick/handlers/qquickpointhandler_p.h index 380ce1f90f..c197cb4f20 100644 --- a/src/quick/handlers/qquickpointhandler_p.h +++ b/src/quick/handlers/qquickpointhandler_p.h @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickPointHandler : public QQuickSinglePointHandler +class Q_QUICK_PRIVATE_EXPORT QQuickPointHandler : public QQuickSinglePointHandler { Q_OBJECT Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged) diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h index 6ec5d55227..56e08590b2 100644 --- a/src/quick/handlers/qquicktaphandler_p.h +++ b/src/quick/handlers/qquicktaphandler_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE -class Q_AUTOTEST_EXPORT QQuickTapHandler : public QQuickSinglePointHandler +class Q_QUICK_PRIVATE_EXPORT QQuickTapHandler : public QQuickSinglePointHandler { Q_OBJECT Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged) |