Standardize Drag/PinchHandler active/persistent scale, rotation, translation
PinchHandler.scale is persistent between gestures, whereas rotation and translation were active-gesture properties; that wasn't consistent. We fixed up DragHandler in just this way in 6.2. The translationChanged() signal now comes with a vector delta, which is often useful when writing an onTranslationChanged JS handler. Likewise, scaleChanged() and rotationChanged() come with qreal deltas. The scaleChanged() delta is multiplicative rather than additive, because an additive delta would not be useful in cases when some target item's scale can be adjusted by alternative means: you need to multiply it in your onScaleChanged function. Now that PinchHandler has 4 axes as grouped properties, some properties in the handlers themselves begin to look redundant; but at least the translation properties are useful to group x and y together. So in this patch we continue to follow the pattern that was set in60d11e1f69
. PinchHandler.scale is equivalent to persistentScale, whereas rotation is equivalent to activeRotation; so we have a reason to deprecate those properties, as inea63ee5233
. The persistent values have setters, to provide another way for applications to compensate when the values are adjusted by other means, as an alternative to incremental changes via a script such as rotationAxis.onValueDelta, onRotationChanged etc. [ChangeLog][QtQuick][Event Handlers] PinchHandler.activeTranslation now holds the amount of movement since the pinch gesture began. PinchHandler.persistentTranslation holds the accumulated sum of movement that has occurred during subsequent pinch gestures, and can be set to arbitrary values between gestures. Likewise, activeScale, persistentScale, activeRotation and persistentRotation follow the same pattern. The scaleChanged, rotationChanged, and translationChanged signals include delta arguments, which are useful for incrementally adjusting a non-default item property when the target is null. Fixes: QTBUG-76739 Task-number: QTBUG-94168 Change-Id: I6aaa1aa3356b85e6d27abc64bfa67781ecb4f062 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
74634a9317
commit
a432970b25
Binary file not shown.
After Width: | Height: | Size: 896 KiB |
|
@ -1,22 +1,31 @@
|
|||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
//![0]
|
||||
import QtQuick 2.12
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
width: 640
|
||||
height: 480
|
||||
Window {
|
||||
width: 320; height: 240
|
||||
visible: true
|
||||
title: handler.persistentRotation.toFixed(1) + "° " +
|
||||
handler.persistentTranslation.x.toFixed(1) + ", " +
|
||||
handler.persistentTranslation.y.toFixed(1) + " " +
|
||||
(handler.persistentScale * 100).toFixed(1) + "%"
|
||||
|
||||
PinchHandler {
|
||||
id: handler
|
||||
target: null
|
||||
persistentScale: 0.25
|
||||
onTranslationChanged: (delta) => {
|
||||
image.x -= delta.x
|
||||
image.y -= delta.y
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
color: handler.active ? "darkgreen" : "black"
|
||||
text: handler.rotation.toFixed(1) + " degrees\n" +
|
||||
handler.translation.x.toFixed(1) + ", " + handler.translation.y.toFixed(1) + "\n" +
|
||||
(handler.scale * 100).toFixed(1) + "%"
|
||||
Image {
|
||||
id: image
|
||||
source: "images/album-cover.jpg"
|
||||
scale: handler.persistentScale
|
||||
x: -600; y: -450
|
||||
}
|
||||
}
|
||||
//![0]
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
//![0]
|
||||
import QtQuick
|
||||
|
||||
Rectangle {
|
||||
width: 100; height: 100
|
||||
color: "lightsteelblue"
|
||||
|
||||
PinchHandler {
|
||||
id: handler
|
||||
target: null
|
||||
onRotationChanged: (delta) => parent.rotation += delta // add
|
||||
onScaleChanged: (delta) => parent.scale *= delta // multiply
|
||||
}
|
||||
}
|
||||
//![0]
|
|
@ -290,7 +290,7 @@ void QQuickDragHandler::setPersistentTranslation(const QVector2D &trans)
|
|||
|
||||
m_xAxis.updateValue(m_xAxis.activeValue(), trans.x());
|
||||
m_yAxis.updateValue(m_yAxis.activeValue(), trans.y());
|
||||
emit translationChanged();
|
||||
emit translationChanged({});
|
||||
}
|
||||
|
||||
void QQuickDragHandler::setActiveTranslation(const QVector2D &trans)
|
||||
|
@ -304,7 +304,7 @@ void QQuickDragHandler::setActiveTranslation(const QVector2D &trans)
|
|||
|
||||
qCDebug(lcDragHandler) << "translation: delta" << delta
|
||||
<< "active" << trans << "accumulated" << persistentTranslation();
|
||||
emit translationChanged();
|
||||
emit translationChanged(delta);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
void enforceConstraints();
|
||||
|
||||
Q_SIGNALS:
|
||||
void translationChanged();
|
||||
void translationChanged(QVector2D delta);
|
||||
Q_REVISION(2, 14) void snapModeChanged();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -96,6 +96,78 @@ void QQuickPinchHandler::setMaximumScale(qreal maximumScale)
|
|||
emit maximumScaleChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty real QtQuick::PinchHandler::activeScale
|
||||
|
||||
The scale factor while the pinch gesture is being performed.
|
||||
It is 1.0 when the gesture begins, increases as the touchpoints are spread
|
||||
apart, and decreases as the touchpoints are brought together.
|
||||
If \l target is not null, its \l {Item::scale}{scale} will be automatically
|
||||
multiplied by this value.
|
||||
Otherwise, bindings can be used to do arbitrary things with this value.
|
||||
|
||||
\sa QtQuick::PinchHandler::scaleAxis.activeValue
|
||||
*/
|
||||
|
||||
void QQuickPinchHandler::setActiveScale(qreal scale)
|
||||
{
|
||||
if (scale == activeScale())
|
||||
return;
|
||||
|
||||
qreal delta = scale / m_scaleAxis.activeValue();
|
||||
m_scaleAxis.updateValue(scale, m_scaleAxis.m_startValue * scale, delta);
|
||||
emit scaleChanged(delta);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlsignal QtQuick::PinchHandler::scaleChanged(qreal delta)
|
||||
|
||||
The \c scaleChanged signal is emitted when \l activeScale (and therefore
|
||||
\l persistentScale) changes. The \a delta value gives the multiplicative
|
||||
change in scale. For example, if the user moves fingers to change the pinch
|
||||
distance so that \c activeScale changes from 2 to 2.5, \c
|
||||
scaleChanged(1.25) will be emitted. You can use that to incrementally
|
||||
change the scale of an item:
|
||||
|
||||
\snippet pointerHandlers/pinchHandlerScaleOrRotationChanged.qml 0
|
||||
|
||||
\note If you set the \l persistentScale property directly, \c delta is \c 1.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty QVector2D QtQuick::PinchHandler::scale
|
||||
\deprecated [6.5] Use persistentScale
|
||||
*/
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty real QtQuick::PinchHandler::persistentScale
|
||||
|
||||
The scale factor that will automatically be set on the \l target if it is not null.
|
||||
Otherwise, bindings can be used to do arbitrary things with this value.
|
||||
While the pinch gesture is being performed, it is continuously multiplied by
|
||||
\l activeScale; after the gesture ends, it stays the same; and when the next
|
||||
pinch gesture begins, it begins to be multiplied by activeScale again.
|
||||
|
||||
It's possible to set this property, as a way of synchronizing the basis
|
||||
scale with a scale that was set in some other way, for example by another
|
||||
handler. If you set this property directly, \c activeScale does not change,
|
||||
and \c scaleChanged(1) is emitted.
|
||||
|
||||
\sa QtQuick::PinchHandler::scaleAxis.persistentValue
|
||||
*/
|
||||
|
||||
void QQuickPinchHandler::setPersistentScale(qreal rot)
|
||||
{
|
||||
if (rot == persistentScale())
|
||||
return;
|
||||
|
||||
m_scaleAxis.updateValue(m_scaleAxis.activeValue(), rot);
|
||||
emit scaleChanged(1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlproperty real QtQuick::PinchHandler::minimumRotation
|
||||
|
||||
|
@ -126,6 +198,136 @@ void QQuickPinchHandler::setMaximumRotation(qreal maximumRotation)
|
|||
emit maximumRotationChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlsignal QtQuick::PinchHandler::rotationChanged(qreal delta)
|
||||
|
||||
The \c rotationChanged signal is emitted when \l activeRotation (and
|
||||
therefore \l persistentRotation) changes. The \a delta value gives the
|
||||
additive change in rotation. For example, if the user moves fingers to
|
||||
change the pinch distance so that \c activeRotation changes from 10 to 30
|
||||
degrees, \c rotationChanged(20) will be emitted. You can use that to
|
||||
incrementally change the rotation of an item:
|
||||
|
||||
\snippet pointerHandlers/pinchHandlerScaleOrRotationChanged.qml 0
|
||||
|
||||
\note If you set the \l persistentRotation property directly, \c delta is \c 0.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty QVector2D QtQuick::PinchHandler::rotation
|
||||
\deprecated [6.5] Use activeRotation
|
||||
*/
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty real QtQuick::PinchHandler::activeRotation
|
||||
|
||||
The rotation of the pinch gesture in degrees, with positive values clockwise.
|
||||
It is \c 0 when the gesture begins. If \l target is not null, this will be
|
||||
automatically added to its \l {Item::rotation}{rotation}. Otherwise,
|
||||
bindings can be used to do arbitrary things with this value.
|
||||
|
||||
\sa QtQuick::PinchHandler::rotationAxis.activeValue
|
||||
*/
|
||||
|
||||
void QQuickPinchHandler::setActiveRotation(qreal rot)
|
||||
{
|
||||
if (rot == activeRotation())
|
||||
return;
|
||||
|
||||
qreal delta = rot - m_rotationAxis.activeValue();
|
||||
m_rotationAxis.updateValue(rot, m_rotationAxis.m_startValue + rot, delta);
|
||||
emit rotationChanged(delta);
|
||||
}
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty real QtQuick::PinchHandler::persistentRotation
|
||||
|
||||
The rotation to be applied to the \l target if it is not null.
|
||||
Otherwise, bindings can be used to do arbitrary things with this value.
|
||||
While the pinch gesture is being performed, \l activeRotation is continuously
|
||||
added; after the gesture ends, it stays the same; and when the next
|
||||
pinch gesture begins, it begins to be modified by activeRotation again.
|
||||
|
||||
\sa QtQuick::PinchHandler::rotationAxis.persistentValue
|
||||
|
||||
It's possible to set this property, as a way of synchronizing the basis
|
||||
rotation with a rotation that was set in some other way, for example by
|
||||
another handler. If you set this property directly, \c activeRotation does
|
||||
not change, and \c rotationChanged(0) is emitted.
|
||||
*/
|
||||
|
||||
void QQuickPinchHandler::setPersistentRotation(qreal rot)
|
||||
{
|
||||
if (rot == persistentRotation())
|
||||
return;
|
||||
|
||||
m_rotationAxis.updateValue(m_rotationAxis.activeValue(), rot);
|
||||
emit rotationChanged(0);
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlsignal QtQuick::PinchHandler::translationChanged(QVector2D delta)
|
||||
|
||||
The \c translationChanged signal is emitted when \l activeTranslation (and
|
||||
therefore \l persistentTranslation) changes. The \a delta vector gives the
|
||||
change in translation. You can use that to incrementally change the
|
||||
position of an item:
|
||||
|
||||
\snippet pointerHandlers/pinchHandlerNullTarget.qml 0
|
||||
|
||||
\note If you set the \l persistentTranslation property directly,
|
||||
\c delta is \c {0, 0}.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty QVector2D QtQuick::PinchHandler::translation
|
||||
\deprecated [6.5] Use activeTranslation
|
||||
*/
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty QPointF QtQuick::PinchHandler::activeTranslation
|
||||
|
||||
The translation of the cluster of points while the pinch gesture is being
|
||||
performed. It is \c {0, 0} when the gesture begins, and increases as the
|
||||
event point(s) are dragged downward and to the right. After the gesture
|
||||
ends, it stays the same; and when the next pinch gesture begins, it is
|
||||
reset to \c {0, 0} again.
|
||||
|
||||
\note On some touchpads, such as on a \macos trackpad, native gestures do
|
||||
not generate any translation values, and this property stays at \c (0, 0).
|
||||
*/
|
||||
|
||||
/*!
|
||||
\qmlproperty QPointF QtQuick::PinchHandler::persistentTranslation
|
||||
|
||||
The translation to be applied to the \l target if it is not \c null.
|
||||
Otherwise, bindings can be used to do arbitrary things with this value.
|
||||
While the pinch gesture is being performed, \l activeTranslation is
|
||||
continuously added to it; after the gesture ends, it stays the same.
|
||||
|
||||
It's possible to set this property, as a way of synchronizing the basis
|
||||
translation with a translation that was set in some other way, for example
|
||||
by another handler. If you set this property directly, \c activeTranslation
|
||||
does not change, and \c translationChanged({0, 0}) is emitted.
|
||||
|
||||
\note On some touchpads, such as on a \macos trackpad, native gestures do
|
||||
not generate any translation values, and this property stays at \c (0, 0).
|
||||
*/
|
||||
|
||||
void QQuickPinchHandler::setPersistentTranslation(const QPointF &trans)
|
||||
{
|
||||
if (trans == persistentTranslation())
|
||||
return;
|
||||
|
||||
m_xAxis.updateValue(m_xAxis.activeValue(), trans.x());
|
||||
m_yAxis.updateValue(m_yAxis.activeValue(), trans.y());
|
||||
emit translationChanged({});
|
||||
}
|
||||
|
||||
bool QQuickPinchHandler::wantsPointerEvent(QPointerEvent *event)
|
||||
{
|
||||
if (!QQuickMultiPointHandler::wantsPointerEvent(event))
|
||||
|
@ -221,7 +423,7 @@ bool QQuickPinchHandler::wantsPointerEvent(QPointerEvent *event)
|
|||
\c maximum is the maximum acceptable scale.
|
||||
If \c enabled is true, scaling is allowed.
|
||||
\c activeValue is the same as \l {QtQuick::PinchHandler::activeScale}.
|
||||
\c persistentValue is the same as \l {QtQuick::PinchHandler::scale}.
|
||||
\c persistentValue is the same as \l {QtQuick::PinchHandler::persistentScale}.
|
||||
|
||||
The \c activeValueChanged signal is emitted when \c activeValue (and therefore
|
||||
\c persistentValue) changes, to provide the multiplier for the incremental change.
|
||||
|
@ -249,8 +451,8 @@ bool QQuickPinchHandler::wantsPointerEvent(QPointerEvent *event)
|
|||
\c minimum is the minimum acceptable rotation.
|
||||
\c maximum is the maximum acceptable rotation.
|
||||
If \c enabled is true, rotation is allowed.
|
||||
\c activeValue is the same as \l {QtQuick::PinchHandler::rotation}.
|
||||
\c persistentValue holds the accumulated value across multiple gestures.
|
||||
\c activeValue is the same as \l {QtQuick::PinchHandler::activeRotation}.
|
||||
\c persistentValue is the same as \l {QtQuick::PinchHandler::persistentRotation}.
|
||||
|
||||
The \c activeValueChanged signal is emitted when \c activeValue (and therefore
|
||||
\c persistentValue) changes, to provide the increment by which it changed.
|
||||
|
@ -324,11 +526,10 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event)
|
|||
emit updated();
|
||||
return;
|
||||
case Qt::ZoomNativeGesture:
|
||||
m_scaleAxis.updateValue(1 + gesture->value(), m_scaleAxis.m_startValue * (1 + gesture->value()));
|
||||
setActiveScale(1 + gesture->value());
|
||||
break;
|
||||
case Qt::RotateNativeGesture:
|
||||
m_rotationAxis.updateValue(m_rotationAxis.m_activeValue + gesture->value(),
|
||||
m_rotationAxis.m_startValue + m_rotationAxis.m_activeValue + gesture->value());
|
||||
setActiveRotation(m_rotationAxis.activeValue() + gesture->value());
|
||||
break;
|
||||
default:
|
||||
// Nothing of interest (which is unexpected, because wantsPointerEvent() should have returned false)
|
||||
|
@ -461,17 +662,14 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event)
|
|||
activeScale = dist / m_startDistance;
|
||||
activeScale = qBound(m_scaleAxis.minimum() / m_scaleAxis.m_startValue, activeScale,
|
||||
m_scaleAxis.maximum() / m_scaleAxis.m_startValue);
|
||||
m_scaleAxis.updateValue(activeScale, m_scaleAxis.m_startValue * activeScale,
|
||||
activeScale / m_scaleAxis.activeValue());
|
||||
setActiveScale(activeScale);
|
||||
}
|
||||
|
||||
// 2. rotate
|
||||
if (m_rotationAxis.enabled()) {
|
||||
QVector<PointData> newAngles = angles(centroid().scenePosition());
|
||||
const qreal angleDelta = averageAngleDelta(m_startAngles, newAngles);
|
||||
m_rotationAxis.updateValue(m_rotationAxis.m_activeValue + angleDelta,
|
||||
m_rotationAxis.m_startValue + m_rotationAxis.m_activeValue + angleDelta,
|
||||
angleDelta);
|
||||
setActiveRotation(m_rotationAxis.m_activeValue + angleDelta);
|
||||
m_startAngles = std::move(newAngles);
|
||||
}
|
||||
|
||||
|
@ -484,10 +682,10 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event)
|
|||
const QPointF centroidParentPos = target()->parentItem()->mapFromScene(centroid().scenePosition());
|
||||
// 3. Drag/translate
|
||||
const QPointF centroidStartParentPos = target()->parentItem()->mapFromScene(centroid().sceneGrabPosition());
|
||||
auto activeTranslation = QVector2D(centroidParentPos - centroidStartParentPos);
|
||||
auto activeTranslation = centroidParentPos - centroidStartParentPos;
|
||||
// apply rotation + scaling around the centroid - then apply translation.
|
||||
QPointF pos = QQuickItemPrivate::get(target())->adjustedPosForTransform(centroidParentPos,
|
||||
startPos(), activeTranslation,
|
||||
startPos(), QVector2D(activeTranslation),
|
||||
m_scaleAxis.m_startValue,
|
||||
m_scaleAxis.persistentValue() / m_scaleAxis.m_startValue,
|
||||
m_rotationAxis.m_startValue,
|
||||
|
@ -502,18 +700,22 @@ void QQuickPinchHandler::handlePointerEventImpl(QPointerEvent *event)
|
|||
else
|
||||
pos.ry() -= qreal(activeTranslation.y());
|
||||
|
||||
m_xAxis.updateValue(activeTranslation.x(), pos.x(), activeTranslation.x() - m_xAxis.activeValue());
|
||||
m_yAxis.updateValue(activeTranslation.y(), pos.y(), activeTranslation.y() - m_yAxis.activeValue());
|
||||
const QVector2D delta(activeTranslation.x() - m_xAxis.activeValue(),
|
||||
activeTranslation.y() - m_yAxis.activeValue());
|
||||
m_xAxis.updateValue(activeTranslation.x(), pos.x(), delta.x());
|
||||
m_yAxis.updateValue(activeTranslation.y(), pos.y(), delta.y());
|
||||
emit translationChanged(delta);
|
||||
target()->setPosition(QPointF(m_xAxis.persistentValue(), m_yAxis.persistentValue()));
|
||||
target()->setRotation(m_rotationAxis.persistentValue());
|
||||
target()->setScale(m_scaleAxis.persistentValue());
|
||||
} else {
|
||||
auto activeTranslation = centroid().scenePosition() - centroid().scenePressPosition();
|
||||
auto accumulated = QPointF(m_xAxis.m_startValue, m_yAxis.m_startValue) + activeTranslation;
|
||||
m_xAxis.updateValue(activeTranslation.x(), accumulated.x(),
|
||||
activeTranslation.x() - m_xAxis.activeValue());
|
||||
m_yAxis.updateValue(activeTranslation.y(), accumulated.y(),
|
||||
activeTranslation.y() - m_yAxis.activeValue());
|
||||
const QVector2D delta(activeTranslation.x() - m_xAxis.activeValue(),
|
||||
activeTranslation.y() - m_yAxis.activeValue());
|
||||
m_xAxis.updateValue(activeTranslation.x(), accumulated.x(), delta.x());
|
||||
m_yAxis.updateValue(activeTranslation.y(), accumulated.y(), delta.y());
|
||||
emit translationChanged(delta);
|
||||
}
|
||||
|
||||
qCDebug(lcPinchHandler) << "centroid" << centroid().scenePressPosition() << "->" << centroid().scenePosition()
|
||||
|
@ -538,50 +740,6 @@ QPointF QQuickPinchHandler::startPos()
|
|||
The \l target will be rotated around this point.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty real QtQuick::PinchHandler::scale
|
||||
|
||||
The scale factor that will automatically be set on the \l target if it is not null.
|
||||
Otherwise, bindings can be used to do arbitrary things with this value.
|
||||
While the pinch gesture is being performed, it is continuously multiplied by
|
||||
\l activeScale; after the gesture ends, it stays the same; and when the next
|
||||
pinch gesture begins, it begins to be multiplied by activeScale again.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty real QtQuick::PinchHandler::activeScale
|
||||
|
||||
The scale factor while the pinch gesture is being performed.
|
||||
It is 1.0 when the gesture begins, increases as the touchpoints are spread
|
||||
apart, and decreases as the touchpoints are brought together.
|
||||
If \l target is not null, its \l {Item::scale}{scale} will be automatically
|
||||
multiplied by this value.
|
||||
Otherwise, bindings can be used to do arbitrary things with this value.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty real QtQuick::PinchHandler::rotation
|
||||
|
||||
The rotation of the pinch gesture in degrees, with positive values clockwise.
|
||||
It is 0 when the gesture begins. If \l target is not null, this will be
|
||||
automatically applied to its \l {Item::rotation}{rotation}. Otherwise,
|
||||
bindings can be used to do arbitrary things with this value.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\readonly
|
||||
\qmlproperty QVector2D QtQuick::PinchHandler::translation
|
||||
|
||||
The translation of the gesture \l centroid. It is \c (0, 0) when the
|
||||
gesture begins.
|
||||
|
||||
\note On some touchpads, such as on a \macos trackpad, native gestures do
|
||||
not generate any translation values, and this property stays at \c (0, 0).
|
||||
*/
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_qquickpinchhandler_p.cpp"
|
||||
|
|
|
@ -28,45 +28,73 @@ using namespace Qt::StringLiterals;
|
|||
class Q_QUICK_PRIVATE_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QQuickDragAxis *scaleAxis READ scaleAxis CONSTANT)
|
||||
Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged)
|
||||
Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
|
||||
#if QT_DEPRECATED_SINCE(6, 5)
|
||||
Q_PROPERTY(qreal scale READ scale NOTIFY updated)
|
||||
#endif
|
||||
Q_PROPERTY(qreal activeScale READ activeScale NOTIFY scaleChanged)
|
||||
Q_PROPERTY(qreal persistentScale READ persistentScale WRITE setPersistentScale NOTIFY scaleChanged)
|
||||
|
||||
Q_PROPERTY(QQuickDragAxis *rotationAxis READ rotationAxis CONSTANT)
|
||||
Q_PROPERTY(qreal minimumRotation READ minimumRotation WRITE setMinimumRotation NOTIFY minimumRotationChanged)
|
||||
Q_PROPERTY(qreal maximumRotation READ maximumRotation WRITE setMaximumRotation NOTIFY maximumRotationChanged)
|
||||
Q_PROPERTY(qreal scale READ scale NOTIFY updated)
|
||||
Q_PROPERTY(qreal activeScale READ activeScale NOTIFY updated)
|
||||
#if QT_DEPRECATED_SINCE(6, 5)
|
||||
Q_PROPERTY(qreal rotation READ rotation NOTIFY updated)
|
||||
Q_PROPERTY(QVector2D translation READ translation NOTIFY updated)
|
||||
#endif
|
||||
Q_PROPERTY(qreal activeRotation READ activeRotation NOTIFY rotationChanged)
|
||||
Q_PROPERTY(qreal persistentRotation READ persistentRotation WRITE setPersistentRotation NOTIFY rotationChanged)
|
||||
|
||||
Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT)
|
||||
Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
|
||||
Q_PROPERTY(QQuickDragAxis * scaleAxis READ scaleAxis CONSTANT)
|
||||
Q_PROPERTY(QQuickDragAxis * rotationAxis READ rotationAxis CONSTANT)
|
||||
#if QT_DEPRECATED_SINCE(6, 5)
|
||||
Q_PROPERTY(QVector2D translation READ translation NOTIFY updated)
|
||||
#endif
|
||||
Q_PROPERTY(QPointF activeTranslation READ activeTranslation NOTIFY translationChanged REVISION(6, 5))
|
||||
Q_PROPERTY(QPointF persistentTranslation READ persistentTranslation WRITE setPersistentTranslation NOTIFY translationChanged REVISION(6, 5))
|
||||
|
||||
QML_NAMED_ELEMENT(PinchHandler)
|
||||
QML_ADDED_IN_VERSION(2, 12)
|
||||
|
||||
public:
|
||||
explicit QQuickPinchHandler(QQuickItem *parent = nullptr);
|
||||
|
||||
qreal minimumScale() const { return m_scaleAxis.minimum(); }
|
||||
void setMinimumScale(qreal minimumScale);
|
||||
|
||||
qreal maximumScale() const { return m_scaleAxis.maximum(); }
|
||||
void setMaximumScale(qreal maximumScale);
|
||||
|
||||
qreal minimumRotation() const { return m_rotationAxis.minimum(); }
|
||||
void setMinimumRotation(qreal minimumRotation);
|
||||
|
||||
qreal maximumRotation() const { return m_rotationAxis.maximum(); }
|
||||
void setMaximumRotation(qreal maximumRotation);
|
||||
|
||||
QVector2D translation() const { return QVector2D(QPointF(m_xAxis.activeValue(), m_yAxis.activeValue())); }
|
||||
qreal scale() const { return m_scaleAxis.m_accumulatedValue; }
|
||||
qreal activeScale() const { return m_scaleAxis.m_activeValue; }
|
||||
qreal rotation() const { return m_rotationAxis.m_accumulatedValue; }
|
||||
|
||||
QQuickDragAxis *xAxis() { return &m_xAxis; }
|
||||
QQuickDragAxis *yAxis() { return &m_yAxis; }
|
||||
#if QT_DEPRECATED_SINCE(6, 5)
|
||||
QVector2D translation() const { return QVector2D(activeTranslation()); }
|
||||
#endif
|
||||
QPointF activeTranslation() const { return QPointF(m_xAxis.activeValue(), m_yAxis.activeValue()); }
|
||||
QPointF persistentTranslation() const { return QPointF(m_xAxis.persistentValue(), m_yAxis.persistentValue()); }
|
||||
void setPersistentTranslation(const QPointF &trans);
|
||||
|
||||
QQuickDragAxis *scaleAxis() { return &m_scaleAxis; }
|
||||
qreal minimumScale() const { return m_scaleAxis.minimum(); }
|
||||
void setMinimumScale(qreal minimumScale);
|
||||
qreal maximumScale() const { return m_scaleAxis.maximum(); }
|
||||
void setMaximumScale(qreal maximumScale);
|
||||
#if QT_DEPRECATED_SINCE(6, 5)
|
||||
qreal scale() const { return persistentScale(); }
|
||||
#endif
|
||||
qreal activeScale() const { return m_scaleAxis.activeValue(); }
|
||||
void setActiveScale(qreal scale);
|
||||
qreal persistentScale() const { return m_scaleAxis.persistentValue(); }
|
||||
void setPersistentScale(qreal scale);
|
||||
|
||||
QQuickDragAxis *rotationAxis() { return &m_rotationAxis; }
|
||||
qreal minimumRotation() const { return m_rotationAxis.minimum(); }
|
||||
void setMinimumRotation(qreal minimumRotation);
|
||||
qreal maximumRotation() const { return m_rotationAxis.maximum(); }
|
||||
void setMaximumRotation(qreal maximumRotation);
|
||||
#if QT_DEPRECATED_SINCE(6, 5)
|
||||
qreal rotation() const { return activeRotation(); }
|
||||
#endif
|
||||
qreal activeRotation() const { return m_rotationAxis.activeValue(); }
|
||||
void setActiveRotation(qreal rot);
|
||||
qreal persistentRotation() const { return m_rotationAxis.persistentValue(); }
|
||||
void setPersistentRotation(qreal rot);
|
||||
|
||||
Q_SIGNALS:
|
||||
void minimumScaleChanged();
|
||||
|
@ -74,6 +102,9 @@ Q_SIGNALS:
|
|||
void minimumRotationChanged();
|
||||
void maximumRotationChanged();
|
||||
void updated();
|
||||
Q_REVISION(6, 5) void scaleChanged(qreal delta);
|
||||
Q_REVISION(6, 5) void rotationChanged(qreal delta);
|
||||
Q_REVISION(6, 5) void translationChanged(QVector2D delta);
|
||||
|
||||
protected:
|
||||
bool wantsPointerEvent(QPointerEvent *event) override;
|
||||
|
|
|
@ -273,7 +273,7 @@ void tst_FlickableInterop::touchDragSlider()
|
|||
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
|
||||
QVERIFY(flickable);
|
||||
QSignalSpy tappedSpy(knob->parent(), SIGNAL(tapped()));
|
||||
QSignalSpy translationChangedSpy(drag, SIGNAL(translationChanged()));
|
||||
QSignalSpy translationChangedSpy(drag, &QQuickDragHandler::translationChanged);
|
||||
|
||||
// Drag the slider in the allowed (vertical) direction
|
||||
tappedSpy.clear();
|
||||
|
@ -353,7 +353,7 @@ void tst_FlickableInterop::mouseDragSlider()
|
|||
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
|
||||
QVERIFY(flickable);
|
||||
QSignalSpy tappedSpy(knob->parent(), SIGNAL(tapped()));
|
||||
QSignalSpy translationChangedSpy(drag, SIGNAL(translationChanged()));
|
||||
QSignalSpy translationChangedSpy(drag, &QQuickDragHandler::translationChanged);
|
||||
|
||||
// Drag the slider
|
||||
tappedSpy.clear();
|
||||
|
@ -411,7 +411,7 @@ void tst_FlickableInterop::touchDragFlickableBehindSlider()
|
|||
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
|
||||
QVERIFY(flickable);
|
||||
QSignalSpy tappedSpy(knob->parent(), SIGNAL(tapped()));
|
||||
QSignalSpy translationChangedSpy(drag, SIGNAL(translationChanged()));
|
||||
QSignalSpy translationChangedSpy(drag, &QQuickDragHandler::translationChanged);
|
||||
|
||||
// Button is no longer pressed if touchpoint goes beyond dragThreshold,
|
||||
// because Flickable steals the grab
|
||||
|
@ -457,7 +457,7 @@ void tst_FlickableInterop::mouseDragFlickableBehindSlider()
|
|||
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
|
||||
QVERIFY(flickable);
|
||||
QSignalSpy tappedSpy(knob->parent(), SIGNAL(tapped()));
|
||||
QSignalSpy translationChangedSpy(drag, SIGNAL(translationChanged()));
|
||||
QSignalSpy translationChangedSpy(drag, &QQuickDragHandler::translationChanged);
|
||||
|
||||
// Button is no longer pressed if touchpoint goes beyond dragThreshold,
|
||||
// because Flickable steals the grab
|
||||
|
|
|
@ -141,7 +141,7 @@ void tst_DragHandler::touchDrag()
|
|||
dragHandler->setDragThreshold(dragThreshold);
|
||||
}
|
||||
|
||||
QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
|
||||
QSignalSpy translationChangedSpy(dragHandler, &QQuickDragHandler::translationChanged);
|
||||
QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged()));
|
||||
QSignalSpy xDeltaSpy(dragHandler->xAxis(), &QQuickDragAxis::activeValueChanged);
|
||||
|
||||
|
@ -189,6 +189,8 @@ void tst_DragHandler::touchDrag()
|
|||
QCOMPARE(dragHandler->activeTranslation().x(), dragThreshold + 20);
|
||||
QCOMPARE(dragHandler->persistentTranslation().y(), 0);
|
||||
QCOMPARE(dragHandler->activeTranslation().y(), 0);
|
||||
QCOMPARE(translationChangedSpy.size(), 1);
|
||||
QCOMPARE(translationChangedSpy.first().first().value<QVector2D>(), QVector2D(dragThreshold + 20, 0));
|
||||
QVERIFY(dragHandler->centroid().velocity().x() > 0);
|
||||
QCOMPARE(centroidChangedSpy.size(), 4);
|
||||
QTest::touchEvent(window, touchDevice).release(1, p1, window);
|
||||
|
@ -285,7 +287,7 @@ void tst_DragHandler::mouseDrag()
|
|||
QVERIFY(dragHandler);
|
||||
dragHandler->setAcceptedButtons(acceptedButtons); // QTBUG-76875
|
||||
|
||||
QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
|
||||
QSignalSpy translationChangedSpy(dragHandler, &QQuickDragHandler::translationChanged);
|
||||
QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged()));
|
||||
QSignalSpy xDeltaSpy(dragHandler->xAxis(), &QQuickDragAxis::activeValueChanged);
|
||||
|
||||
|
@ -352,9 +354,11 @@ void tst_DragHandler::mouseDrag()
|
|||
QTest::mouseRelease(window, static_cast<Qt::MouseButton>(int(dragButton)), Qt::NoModifier, p1);
|
||||
QTRY_VERIFY(!dragHandler->active());
|
||||
QCOMPARE(dragHandler->centroid().pressedButtons(), Qt::NoButton);
|
||||
if (shouldDrag)
|
||||
QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
|
||||
QCOMPARE(translationChangedSpy.size(), shouldDrag ? 1 : 0);
|
||||
if (shouldDrag) {
|
||||
QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
|
||||
QCOMPARE(translationChangedSpy.first().first().value<QVector2D>(), QVector2D(dragThreshold + 20, 0));
|
||||
}
|
||||
QCOMPARE(xDeltaSpy.size(), shouldDrag ? 1 : 0);
|
||||
QCOMPARE(centroidChangedSpy.size(), shouldDrag ? 5 : 0);
|
||||
#if QT_CONFIG(cursor)
|
||||
|
@ -390,7 +394,7 @@ void tst_DragHandler::mouseDragThreshold()
|
|||
dragHandler->setDragThreshold(dragThreshold);
|
||||
}
|
||||
|
||||
QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
|
||||
QSignalSpy translationChangedSpy(dragHandler, &QQuickDragHandler::translationChanged);
|
||||
QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged()));
|
||||
QSignalSpy xDeltaSpy(dragHandler->xAxis(), &QQuickDragAxis::activeValueChanged);
|
||||
|
||||
|
@ -416,6 +420,8 @@ void tst_DragHandler::mouseDragThreshold()
|
|||
QTest::mouseMove(window, p1);
|
||||
QTRY_VERIFY(dragHandler->active());
|
||||
QCOMPARE(translationChangedSpy.size(), dragThreshold ? 0 : 1);
|
||||
if (!dragThreshold)
|
||||
QCOMPARE(translationChangedSpy.first().first().value<QVector2D>(), QVector2D(2, 0));
|
||||
QCOMPARE(xDeltaSpy.size(), dragThreshold ? 0 : 1);
|
||||
QCOMPARE(centroidChangedSpy.size(), 3);
|
||||
#if QT_DEPRECATED_SINCE(6, 2)
|
||||
|
@ -442,6 +448,9 @@ QT_WARNING_POP
|
|||
#endif
|
||||
QCOMPARE(dragHandler->activeTranslation().x(), dragThreshold + (dragThreshold ? 20 : 21));
|
||||
QCOMPARE(dragHandler->activeTranslation().y(), 0.0);
|
||||
QCOMPARE(translationChangedSpy.size(), dragThreshold ? 1 : 2);
|
||||
QCOMPARE(translationChangedSpy.first().first().value<QVector2D>(),
|
||||
QVector2D(dragThreshold ? dragThreshold + 20 : 2, 0));
|
||||
QVERIFY(dragHandler->centroid().velocity().x() > 0);
|
||||
QCOMPARE(centroidChangedSpy.size(), 4);
|
||||
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
|
||||
|
@ -586,7 +595,7 @@ void tst_DragHandler::touchDragMulti()
|
|||
QVERIFY(ball1);
|
||||
QQuickDragHandler *dragHandler1 = ball1->findChild<QQuickDragHandler*>();
|
||||
QVERIFY(dragHandler1);
|
||||
QSignalSpy translationChangedSpy1(dragHandler1, SIGNAL(translationChanged()));
|
||||
QSignalSpy translationChangedSpy1(dragHandler1, &QQuickDragHandler::translationChanged);
|
||||
QSignalSpy centroidChangedSpy1(dragHandler1, SIGNAL(centroidChanged()));
|
||||
QSignalSpy xDeltaSpy1(dragHandler1->xAxis(), &QQuickDragAxis::activeValueChanged);
|
||||
|
||||
|
@ -594,7 +603,7 @@ void tst_DragHandler::touchDragMulti()
|
|||
QVERIFY(ball2);
|
||||
QQuickDragHandler *dragHandler2 = ball2->findChild<QQuickDragHandler*>();
|
||||
QVERIFY(dragHandler2);
|
||||
QSignalSpy translationChangedSpy2(dragHandler2, SIGNAL(translationChanged()));
|
||||
QSignalSpy translationChangedSpy2(dragHandler2, &QQuickDragHandler::translationChanged);
|
||||
QSignalSpy centroidChangedSpy2(dragHandler1, SIGNAL(centroidChanged()));
|
||||
QSignalSpy yDeltaSpy2(dragHandler2->yAxis(), &QQuickDragAxis::activeValueChanged);
|
||||
|
||||
|
@ -702,6 +711,10 @@ QT_WARNING_POP
|
|||
QCOMPARE(xDeltaSpy1.first().first().toReal(), dragThreshold + 20);
|
||||
QCOMPARE(yDeltaSpy2.size(), 1);
|
||||
QCOMPARE(yDeltaSpy2.first().first().toReal(), dragThreshold + 20);
|
||||
QCOMPARE(translationChangedSpy1.size(), 1);
|
||||
QCOMPARE(translationChangedSpy1.first().first().value<QVector2D>(), QVector2D(dragThreshold + 20, 0));
|
||||
QCOMPARE(translationChangedSpy2.size(), 1);
|
||||
QCOMPARE(translationChangedSpy2.first().first().value<QVector2D>(), QVector2D(0, dragThreshold + 20));
|
||||
touchSeq.release(1, p1, window).stationary(2).commit();
|
||||
QQuickTouchUtils::flush(window);
|
||||
QTRY_VERIFY(!dragHandler1->active());
|
||||
|
|
|
@ -225,6 +225,7 @@ void tst_QQuickPinchHandler::scale()
|
|||
QQuickItem *blackRect = (hasTarget ? pinchHandler->target() : pinchHandler->parentItem());
|
||||
QVERIFY(blackRect != nullptr);
|
||||
QSignalSpy grabChangedSpy(pinchHandler, SIGNAL(grabChanged(QPointingDevice::GrabTransition, QEventPoint)));
|
||||
QSignalSpy scaleChangedSpy(pinchHandler, &QQuickPinchHandler::scaleChanged);
|
||||
if (lcPointerTests().isDebugEnabled()) QTest::qWait(500);
|
||||
|
||||
QPoint p0(80, 80);
|
||||
|
@ -263,6 +264,7 @@ void tst_QQuickPinchHandler::scale()
|
|||
|
||||
// move the same point even further and observe the change in scale
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
qreal lastScale = pinchHandler->activeScale();
|
||||
p1 += pd;
|
||||
pinchSequence.stationary(0).move(1, p1, &window).commit();
|
||||
QQuickTouchUtils::flush(&window);
|
||||
|
@ -270,13 +272,18 @@ void tst_QQuickPinchHandler::scale()
|
|||
line.setP2(p1);
|
||||
qreal expectedScale = line.length() / startLength;
|
||||
qCDebug(lcPointerTests) << "pinchScale" << root->property("pinchScale").toReal()
|
||||
<< "expected" << expectedScale << "; target scale" << blackRect->scale();
|
||||
<< "expected" << expectedScale << "; target scale" << blackRect->scale()
|
||||
<< "increments" << scaleChangedSpy.size()
|
||||
<< "multiplier" << scaleChangedSpy.last().first().toReal();
|
||||
QVERIFY(qFloatDistance(root->property("pinchScale").toReal(), expectedScale) < 10);
|
||||
QVERIFY(qFloatDistance(blackRect->scale(), expectedScale) < 10);
|
||||
QCOMPARE(pinchHandler->scale(), root->property("pinchScale").toReal());
|
||||
QCOMPARE(pinchHandler->scale(), pinchHandler->activeScale()); // in sync for the first gesture
|
||||
QCOMPARE(pinchHandler->scaleAxis()->persistentValue(), pinchHandler->activeScale());
|
||||
QCOMPARE(pinchHandler->scaleAxis()->activeValue(), pinchHandler->activeScale());
|
||||
const qreal expectedIncrement = pinchHandler->activeScale() / lastScale;
|
||||
QCOMPARE(scaleChangedSpy.size(), i + 1);
|
||||
QCOMPARE(scaleChangedSpy.last().first().toReal(), expectedIncrement);
|
||||
QPointF expectedCentroid = p0 + (p1 - p0) / 2;
|
||||
QCOMPARE(pinchHandler->centroid().scenePosition(), expectedCentroid);
|
||||
}
|
||||
|
@ -315,15 +322,21 @@ void tst_QQuickPinchHandler::scale()
|
|||
line.setP2(p1);
|
||||
qreal expectedActiveScale = line.length() / startLength;
|
||||
qCDebug(lcPointerTests) << i << "activeScale" << pinchHandler->activeScale()
|
||||
<< "expected" << expectedActiveScale << "; scale" << pinchHandler->scale();
|
||||
<< "expected" << expectedActiveScale << "; scale" << pinchHandler->scale()
|
||||
<< "increments" << scaleChangedSpy.size()
|
||||
<< "multiplier" << scaleChangedSpy.last().first().toReal();
|
||||
QVERIFY(qFloatDistance(pinchHandler->activeScale(), expectedActiveScale) < 10);
|
||||
QCOMPARE(pinchHandler->scale(), root->property("pinchScale").toReal());
|
||||
QCOMPARE(pinchHandler->scaleAxis()->persistentValue(), root->property("pinchScale").toReal());
|
||||
QCOMPARE_NE(pinchHandler->scale(), pinchHandler->activeScale()); // not in sync anymore
|
||||
QCOMPARE(pinchHandler->scaleAxis()->activeValue(), pinchHandler->activeScale());
|
||||
const qreal expectedIncrement = pinchHandler->scale() / lastScale;
|
||||
QCOMPARE(scaleChangedSpy.size(), i + 3);
|
||||
QCOMPARE(scaleChangedSpy.last().first().toReal(), expectedIncrement);
|
||||
}
|
||||
|
||||
// scale beyond maximumScale
|
||||
lastScale = pinchHandler->activeScale();
|
||||
p1 = QPoint(310, 310);
|
||||
pinchSequence.stationary(0).move(1, p1, &window).commit();
|
||||
QQuickTouchUtils::flush(&window);
|
||||
|
@ -331,6 +344,9 @@ void tst_QQuickPinchHandler::scale()
|
|||
QCOMPARE(blackRect->scale(), qreal(4));
|
||||
QCOMPARE(pinchHandler->scale(), qreal(4)); // limited by maximumScale
|
||||
QCOMPARE(pinchHandler->scaleAxis()->persistentValue(), 4);
|
||||
const qreal expectedIncrement = pinchHandler->activeScale() / lastScale;
|
||||
QCOMPARE(scaleChangedSpy.size(), 5);
|
||||
QCOMPARE(scaleChangedSpy.last().first().toReal(), expectedIncrement);
|
||||
pinchSequence.release(0, p0, &window).release(1, p1, &window).commit();
|
||||
QQuickTouchUtils::flush(&window);
|
||||
QCOMPARE(pinchHandler->active(), false);
|
||||
|
@ -530,6 +546,7 @@ void tst_QQuickPinchHandler::pan()
|
|||
|
||||
QQuickPinchHandler *pinchHandler = window->rootObject()->findChild<QQuickPinchHandler*>("pinchHandler");
|
||||
QVERIFY(pinchHandler != nullptr);
|
||||
QSignalSpy translationChangedSpy(pinchHandler, &QQuickPinchHandler::translationChanged);
|
||||
|
||||
QQuickItem *root = qobject_cast<QQuickItem*>(window->rootObject());
|
||||
QVERIFY(root != nullptr);
|
||||
|
@ -578,6 +595,8 @@ void tst_QQuickPinchHandler::pan()
|
|||
// blackrect starts at 50,50
|
||||
QCOMPARE(blackRect->x(), 50.0);
|
||||
QCOMPARE(blackRect->y(), 50.0);
|
||||
QCOMPARE(translationChangedSpy.size(), 1);
|
||||
QCOMPARE(translationChangedSpy.first().first().value<QVector2D>(), QVector2D(0, 0));
|
||||
|
||||
p0 += QPoint(10, 0);
|
||||
p1 += QPoint(10, 0);
|
||||
|
@ -586,6 +605,8 @@ void tst_QQuickPinchHandler::pan()
|
|||
QCOMPARE(pinchHandler->centroid().scenePosition(), QPointF(90 + dragThreshold + 11, 90));
|
||||
QCOMPARE(blackRect->x(), 60.0);
|
||||
QCOMPARE(blackRect->y(), 50.0);
|
||||
QCOMPARE(translationChangedSpy.size(), 2);
|
||||
QCOMPARE(translationChangedSpy.last().first().value<QVector2D>(), QVector2D(10, 0));
|
||||
|
||||
p0 += QPoint(0, 10);
|
||||
p1 += QPoint(0, 10);
|
||||
|
@ -594,6 +615,8 @@ void tst_QQuickPinchHandler::pan()
|
|||
QCOMPARE(pinchHandler->centroid().scenePosition(), QPointF(90 + dragThreshold + 11, 90 + 10));
|
||||
QCOMPARE(blackRect->x(), 60.0);
|
||||
QCOMPARE(blackRect->y(), 60.0);
|
||||
QCOMPARE(translationChangedSpy.size(), 3);
|
||||
QCOMPARE(translationChangedSpy.last().first().value<QVector2D>(), QVector2D(0, 10));
|
||||
|
||||
p0 += QPoint(10, 10);
|
||||
p1 += QPoint(10, 10);
|
||||
|
@ -603,6 +626,8 @@ void tst_QQuickPinchHandler::pan()
|
|||
QCOMPARE(pinchHandler->centroid().scenePosition(), QPointF(90 + dragThreshold + 21, 90 + 20));
|
||||
QCOMPARE(blackRect->x(), 70.0);
|
||||
QCOMPARE(blackRect->y(), 70.0);
|
||||
QCOMPARE(translationChangedSpy.size(), 4);
|
||||
QCOMPARE(translationChangedSpy.last().first().value<QVector2D>(), QVector2D(10, 10));
|
||||
}
|
||||
|
||||
// pan x beyond bound
|
||||
|
@ -613,6 +638,8 @@ void tst_QQuickPinchHandler::pan()
|
|||
|
||||
QCOMPARE(blackRect->x(), 140.0);
|
||||
QCOMPARE(blackRect->y(), 170.0);
|
||||
QCOMPARE(translationChangedSpy.size(), 5);
|
||||
QCOMPARE(translationChangedSpy.last().first().value<QVector2D>(), QVector2D(100, 100));
|
||||
|
||||
QTest::touchEvent(window, touchscreen).release(0, p0, window).release(1, p1, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
|
|
Loading…
Reference in New Issue