Commit Graph

21 Commits

Author SHA1 Message Date
Shawn Rutledge a432970b25 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 in
60d11e1f69. PinchHandler.scale is
equivalent to persistentScale, whereas rotation is equivalent to
activeRotation; so we have a reason to deprecate those properties, as in
ea63ee5233.

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>
2022-12-10 19:18:21 +01:00
Marc Mutz 958cd3ee10 Port from container::count() and length() to size()
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8:

  auto QtContainerClass = anyOf(
      expr(hasType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))))).bind(o),
      expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o));
  makeRule(cxxMemberCallExpr(on(QtContainerClass),
                             callee(cxxMethodDecl(hasAnyName({"count", "length"),
                                                  parameterCountIs(0))))),
           changeTo(cat(access(o, cat("size"), "()"))),
           cat("use 'size()' instead of 'count()/length()'"))

a.k.a qt-port-to-std-compatible-api with config Scope: 'Container',
with the extended set of container classes recognized.

Change-Id: Idb1f75dfe2323bd1d9e8b4d58d54f1b4b80c7ed7
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-10-07 23:38:48 +02:00
Lucie Gérard 0dc4fd240a Use SPDX license identifiers
Replace the current license disclaimer in files by
a SPDX-License-Identifier.
Files that have to be modified by hand are modified.
License files are organized under LICENSES directory.

Pick-to: 6.4
Task-number: QTBUG-67283
Change-Id: I63563bbeb6f60f89d2c99660400dca7fab78a294
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2022-06-11 08:05:15 +02:00
Mitch Curtis e310dadef7 Consolidate test helpers into private libraries
Previously each test would include and build sources from the shared
folder. Now we make those sources a library, build it once, then have
each test link to it instead.

We also take the opportunity to move some helpers that qtquickcontrols2
had added into the quicktestutils library where it makes sense, and
for the helpers that don't make sense to be there, move them into
quickcontrolstestutils.

We add the libraries to src/ so that they are internal modules built as
part of Qt, rather than tests. That way we can use them in a standalone
test outside of qtdeclarative.

Task-number: QTBUG-95621
Pick-to: 6.2
Change-Id: I0a2ab3976fdbff2e4414df7bdc0808f16453b80a
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-09-13 21:17:04 +02:00
Shawn Rutledge 1e1674849a Allow parent to filter out-of-bounds synth-mouse for grabbing handler
Consider

Flickable {
	Text {
		TapHandler { gesturePolicy: TapHandler.ReleaseWithinBounds }
	}
}

On press, TapHandler gets the exclusive grab.  Now drag vertically.
The Text is short in stature, so your finger soon strays out of bounds
of the Text, likely before you have dragged past the drag threshold.
In this case, we want Flickable to continue to filter the move events
because of the fact that TapHandler is the grabber.  If it was a
MouseArea instead of a TapHandler, it already worked that way; so this
makes behavior of handlers more consistent with that.

More specifically: QQuickPointerTouchEvent::touchEventForItem() now
generates a touch event even if the touchpoint is not within the bounds
of the given item, but is grabbed by one of that item's handlers.  Until
now, we had that exception only if it was grabbed by the item itself.

tst_FlickableInterop::touchAndDragHandlerOnFlickable now always drags
the delegate at index 2 (the third one) from its upper-right corner,
upwards and to the left.  The first drag goes outside the delegate's
bounds, but the Flickable/ListView/TableView filters and takes over
anyway (on the next drag), to prove that it is correctly depending
on the grab that the TapHandler (or DragHandler) took on press.

Pick-to: 5.15
Pick-to: 6.0
Fixes: QTBUG-75223
Change-Id: Ie4e22c87be0af9aa3ff0146067b7705949b15c40
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2020-11-30 18:16:26 +01:00
Shawn Rutledge d0ae3a312a Remove QQuickPointerDevice in favor of QPointingDevice
...and generally deal with changes immediately required after adding
QInputDevice and QPointingDevice.

Also fixed a few usages of deprecated accessors that weren't taken
care of in 212c2bffbb.

Task-number: QTBUG-46412
Task-number: QTBUG-69433
Task-number: QTBUG-72167
Change-Id: I93a2643162878afa216556f10808fd92e0b20071
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2020-06-23 17:44:03 +02:00
Ulf Hermann bb2dce1d90 Try to fix flakiness in flickableinterop test
The usual problem is that Flickable doesn't instantly jump to the
expected position but moves there after a delay.

Change-Id: Iafc9dd493b97629377e7f7c60ae7adde13427bae
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2019-02-07 14:39:37 +00:00
Shawn Rutledge a8729cf143 TapHander: do not "want" an eventPoint that is outside parent bounds
So far it was checking parentContains() on press, release, or when
the gesturePolicy is WithinBounds, but not for each movement when the
policy is DragThreshold (the default).  This might explain most of the
remaining warning noise: "pointId is missing from current event, but was
neither canceled nor released" because it was possible for TapHandler
to remember wanting a point that it should not have wanted, but without
taking any kind of grab, and then complaining when that point was no
longer present.  Since it did not grab, it did not get the release,
unless the release was part of an event containing a point that it
DID grab.

Fixes: QTBUG-71887
Change-Id: I26ce62279574cf6b0150f24e486f224a604ac6b1
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2019-01-30 16:16:01 +00:00
Shawn Rutledge 8380e4c4a4 Add handlers declared as Flickable children to its contentItem
QQuickItemPrivate::data_append() was not invoked when any kind of
Pointer Handler was directly declared in a Flickable (or subclass)
because QQuickFlickable redefines the default property to be its own
flickableData property. So we need to repeat the special handling
in QQuickFlickablePrivate::data_append() too.  The handler must
be added to the private->extra->pointerHandlers vector, so that
QQuickItemPrivate::handlePointerEvent() will attempt to deliver
events to those handlers.

TapHandler seems OK (especially with its default gesturePolicy
so that it does not do an exclusive grab).

PointHandler seems OK.

DragHandler competes with Flickable for the exclusive grab.
pressDelay can help; or set acceptedDevices: PointerDevice.Mouse
to allow the mouse to drag but not flick, and the touchscreen
to flick but not drag.

Fixes: QTBUG-71918
Fixes: QTBUG-73035
Change-Id: Icb97ed5230abe0cb6ec0230b5b5759a0528df7e8
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2019-01-22 21:38:36 +00:00
Shawn Rutledge acf7c8073b QQuickWindow: obey AA_SynthesizeMouseForUnhandledTouchEvents
Until now, AA_SynthesizeMouseForUnhandledTouchEvents has only affected
behavior of QGuiApplicationPrivate::processTouchEvent, but had no
effect in Qt Quick.  QQuickWindow also accepts the touch event
just to make sure that QGuiApplication will not synthesize mouse
from touch, because it would be redundant: QQuickWindow does that
for itself.

Now we make it have an effect in Qt Quick too: skip mouse synthesis
if it is set to false.  This provides a way to simplify the
event delivery.  If you set it false, then you cannot manipulate old
mouse-only items like MouseArea and Flickable on a touchscreen.
(You can of course use event handlers for that.)

[ChangeLog][QtQuick][QQuickWindow] You can now disable touch->mouse
event synthesis in QtQuick by calling
qGuiApp.setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
This will simplify and speed up event delivery, and it will also prevent
any and all interaction with mouse-only items like MouseArea and
Flickable on a touchscreen.

Task-number: QTBUG-52748
Change-Id: I71f1731b5abaeabd9dbce1112cd23bc97d24c12a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2018-08-06 12:46:08 +00:00
Shawn Rutledge 814ff4c73c tst_FlickableInterop: use categorized logging rather than qDebug
Don't slow down CI for logging unless the test fails.

Change-Id: I2d5faedf3fadb30ec5a732445d695bda7e290233
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2018-08-06 12:46:02 +00:00
Jan Arve Sæther 888e191ec8 Call clearGrabbers each time we get a press event
This is important in order for passive grabbers to be in the same order
as if the points were pressed at the same time.

In our case, the problem occurred when we had a single-point DragHandler
together with a two-finger PinchHandler:

* One finger was pressed and moved
  => DragHandler called setPassiveGrab()
     => point0->passiveGrabbers: [DragHandler]
* A second finger was pressed and moved
  => PinchHandler called setPassiveGrab() for both points
     => point0->passiveGrabbers: [DragHandler,PinchHandler]
     => point1->passiveGrabbers: [PinchHandler]

So then as one keeps on dragging the *two* fingers, the DragHandler will
get the chance to do an exclusive grab first, (since its the first listed
passive grabber of point0), and the PinchHandler won't get the opportunity
to grab. This is not expected since their declaration order implies that
the PinchHandler should get a chance to grab first.

Change-Id: I4e82ed186eeb5bf1dae1679d393e5563072175d1
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2018-07-19 10:56:15 +00:00
Shawn Rutledge ca7cdd71ee Make DragHandler a MultiPointHandler
That is, minimumPointCount can now be set to a value > 1 to require
multiple fingers to do the dragging, or to track the displacement
of multiple fingers to adjust some value (such as the tilt of a map).

Task-number: QTBUG-68106
Change-Id: Ib35823e36deb81c8b277d3070fcc758c7c019564
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2018-07-19 10:56:06 +00:00
Shawn Rutledge 090cfda4ed tst_FlickableInterop: test both usages of DragHandler in a Slider
When there's a DragHandler on one Item and a TapHandler on another,
we have more trouble with Flickable stealing the grab.  We need a
test to ensure that this problem doesn't reappear after fixing.

Task-number: QTBUG-64846
Change-Id: Ia3bc3b7c9654f09aa96ad70968d82b566686e030
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2018-07-12 20:22:39 +00:00
Shawn Rutledge 284979ae8a Input handler tests: remember positions of stationary points
We need Handlers to receive accurate positions for stationary touch
points: that is, the last-known position from the previous touch
event.  (And we hope that all actual touch-capable platforms also send
proper QPA events with correct positions for stationary points.
We assert that it's a bug if they don't.)

As explained in qtbase 7cef4b6463fdb73ff602ade64b222333dd23e46c, it's
OK to retain a copy of a QTest::QTouchEventSequence for this purpose,
so that the QMap<int, QTouchEvent::TouchPoint> previousPoints will not
be discarded between events.

We have done this in other tests, but not consistently; e.g.
468626e99a fixed the PinchArea test.

Change-Id: I4dbe69f8dcc4b1cca30fd7ce91d7d2ecf5ec4bc3
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2018-07-03 15:07:13 +00:00
Shawn Rutledge b8aecb02ad Add cat. logging in wantsEventPoint; improve FlickableInterop test
It was too hard to debug behavior in this test.

Change-Id: Iaec9534cca17bdd90b94cfa8fa8b21b7026839ae
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2018-06-29 14:42:27 +00:00
Jan Arve Sæther e4bea7805a Fix draghandler to respect axis constraints
..while its (ancestor) coordinate system has changed during the drag.

For example, ensure that a DragHandler-based Slider keeps its knob centered.
If the Slider is used on a Flickable which you are flicking with a second
finger, then the coordinate system is changing underneath the Slider.

The problem was that DragHandler stored the initial drag position of the
target when the target item was pressed, and used that throughout the
whole drag operation. Unfortunately if the target item was inside a
Flickable that got flicked during a drag operation, that initial position
was not updated (and thus, incorrect).

Instead of storing the initial target position in scene coordinates, we
now store the position that got pressed in local target coordinates, and
ensure that in any further updates the touchpoint have the same local
position (by moving the target).

Task-number: QTBUG-64852
Change-Id: I25012d34d88f45c7eb9c711db0037d530cf10854
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2018-02-21 20:13:00 +00:00
Jan Arve Saether 5bcbba1312 Make sure passive grabbers are cleared on release
This got regressed by change e6d4df156e. Before
that change, we always cleared both the exclusive and passive grabbers.

Task-number: QTBUG-66152
Change-Id: I93d2568bd2a23ddd55a5294d544f978a50a5543e
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2018-02-02 12:45:20 +00:00
Jan Arve Sæther 5cb76fb370 Fix a bug with TapHandler+DragHandler on top of Flickable
If an item that had a TapHandler and a DragHandler was placed inside a
Flickable it would call sendFilteredPointerEvent() for each of the
handlers, even if they were siblings.

This is not ideal, and because of a mechanism in flickable it even caused
the DragHandler to not drag the item as expected.
This is because of a mechanism in Flickable where the value returned is
actually derived from the previous call to filterMouseEvent() (stored in
member variable stealGrab).

Below are the relevant steps it went through when the mouse drag exceeded
the drag threshold (mouse pointer started on the item):

Precondition: QQuickFlickablePrivate::stealMouse == false
1. Mouse Drag (which exceeded drag threshold)

2. sendFilteredPointerEvent(tapHandler->parentItem()) returns false.
   (but since it moved beyond threshold, it would set stealGrab-> true).

3. tapHandler->handlePointerEvent() declined and ungrabbed (due to
   DragThreshold gesture policy).

4. sendFilteredPointerEvent(dragHandler->parentItem()) returns true
   (because the previous call to sendFilteredPointerEvent() set stealGrab
   to true).

As a consequence of (4), dragHandler->handlePointerEvent() was not called,
and the flickable would start to flick instead of the item starting to drag.

Change-Id: Ia99eae91cad0903ebbaedaaafcdf92a25705a922
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
2017-10-27 14:43:23 +00:00
Shawn Rutledge 80e5e6976a tst_flickableinterop: test buttons with all gesturePolicy values
Change-Id: If3d9e10bb54fc75a7e72bc6367de3e083611a45f
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2017-05-15 17:22:01 +00:00
Shawn Rutledge 4c84de4a93 Add tst_flickableinterop: verify drag and tap handlers inside Flickable
Flickable can steal the grab from a PointerHandler the same way it can
steal from an Item: by filtering the children's events.  But within
the drag threshold, or if the DragHandler is dragging, the handlers
behave normally.

Change-Id: If1bc1f2e8d9aaebb590f3434a3018a9f1a1f1dac
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
2017-04-28 08:58:15 +00:00