1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include <QtTest/QtTest> |
30 | #include <QtTest/QSignalSpy> |
31 | #include <private/qquickmultipointtoucharea_p.h> |
32 | #include <private/qquickflickable_p.h> |
33 | #include <private/qquickmousearea_p.h> |
34 | #include <private/qquickwindow_p.h> |
35 | #include <qpa/qwindowsysteminterface.h> |
36 | #include <QtQuick/qquickview.h> |
37 | #include <QtGui/QScreen> |
38 | #include "../../shared/util.h" |
39 | #include "../shared/viewtestutil.h" |
40 | |
41 | Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests" ) |
42 | |
43 | class tst_QQuickMultiPointTouchArea : public QQmlDataTest |
44 | { |
45 | Q_OBJECT |
46 | public: |
47 | tst_QQuickMultiPointTouchArea() { } |
48 | |
49 | private slots: |
50 | void initTestCase() { |
51 | QQmlDataTest::initTestCase(); |
52 | if (!device) { |
53 | device = new QTouchDevice; |
54 | device->setType(QTouchDevice::TouchScreen); |
55 | QWindowSystemInterface::registerTouchDevice(device); |
56 | } |
57 | } |
58 | void cleanupTestCase() {} |
59 | |
60 | void properties(); |
61 | void signalTest(); |
62 | void release(); |
63 | void reuse(); |
64 | void nonOverlapping(); |
65 | void nested(); |
66 | void inFlickable(); |
67 | void inFlickable2(); |
68 | void inFlickableWithPressDelay(); |
69 | void inMouseArea(); |
70 | void mouseAsTouchpoint(); |
71 | void invisible(); |
72 | void transformedTouchArea_data(); |
73 | void transformedTouchArea(); |
74 | void mouseInteraction(); |
75 | void mouseInteraction_data(); |
76 | void mouseGestureStarted_data(); |
77 | void mouseGestureStarted(); |
78 | void cancel(); |
79 | void stationaryTouchWithChangingPressure(); |
80 | |
81 | private: |
82 | QQuickView *createAndShowView(const QString &file); |
83 | QTouchDevice *device = nullptr; |
84 | }; |
85 | |
86 | void tst_QQuickMultiPointTouchArea::properties() |
87 | { |
88 | QScopedPointer<QQuickView> window(createAndShowView(file: "properties.qml" )); |
89 | QVERIFY(window->rootObject() != nullptr); |
90 | |
91 | QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(object: window->rootObject()); |
92 | QVERIFY(area != nullptr); |
93 | |
94 | QCOMPARE(area->minimumTouchPoints(), 2); |
95 | QCOMPARE(area->maximumTouchPoints(), 4); |
96 | |
97 | QQmlListReference ref(area, "touchPoints" ); |
98 | QCOMPARE(ref.count(), 4); |
99 | } |
100 | |
101 | void tst_QQuickMultiPointTouchArea::signalTest() |
102 | { |
103 | QScopedPointer<QQuickView> window(createAndShowView(file: "signalTest.qml" )); |
104 | QVERIFY(window->rootObject() != nullptr); |
105 | |
106 | QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(object: window->rootObject()); |
107 | QVERIFY(area != nullptr); |
108 | |
109 | QPoint p1(20,100); |
110 | QPoint p2(40,100); |
111 | QPoint p3(60,100); |
112 | QPoint p4(80,100); |
113 | QPoint p5(100,100); |
114 | |
115 | QTest::QTouchEventSequence sequence = QTest::touchEvent(window: window.data(), device); |
116 | |
117 | sequence.press(touchId: 0, pt: p1).press(touchId: 1, pt: p2).commit(); |
118 | QQuickTouchUtils::flush(window: window.data()); |
119 | |
120 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 2); |
121 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 0); |
122 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 0); |
123 | QCOMPARE(area->property("touchCount" ).toInt(), 2); |
124 | QMetaObject::invokeMethod(obj: area, member: "clearCounts" ); |
125 | |
126 | sequence.stationary(touchId: 0).stationary(touchId: 1).press(touchId: 2, pt: p3).commit(); |
127 | QQuickTouchUtils::flush(window: window.data()); |
128 | |
129 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 1); |
130 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 0); |
131 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 0); |
132 | QCOMPARE(area->property("touchCount" ).toInt(), 3); |
133 | QMetaObject::invokeMethod(obj: area, member: "clearCounts" ); |
134 | |
135 | p1 -= QPoint(10,10); |
136 | p2 += QPoint(10,10); |
137 | sequence.move(touchId: 0, pt: p1).move(touchId: 1, pt: p2).stationary(touchId: 2).commit(); |
138 | QQuickTouchUtils::flush(window: window.data()); |
139 | |
140 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 0); |
141 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 2); |
142 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 0); |
143 | QCOMPARE(area->property("touchCount" ).toInt(), 3); |
144 | QMetaObject::invokeMethod(obj: area, member: "clearCounts" ); |
145 | |
146 | p3 += QPoint(10,10); |
147 | sequence.release(touchId: 0, pt: p1).release(touchId: 1, pt: p2) |
148 | .move(touchId: 2, pt: p3).press(touchId: 3, pt: p4).press(touchId: 4, pt: p5).commit(); |
149 | QQuickTouchUtils::flush(window: window.data()); |
150 | |
151 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 2); |
152 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 1); |
153 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 2); |
154 | QCOMPARE(area->property("touchCount" ).toInt(), 3); |
155 | QMetaObject::invokeMethod(obj: area, member: "clearCounts" ); |
156 | |
157 | sequence.release(touchId: 2, pt: p3).release(touchId: 3, pt: p4).release(touchId: 4, pt: p5).commit(); |
158 | QQuickTouchUtils::flush(window: window.data()); |
159 | |
160 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 0); |
161 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 0); |
162 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 3); |
163 | QCOMPARE(area->property("touchCount" ).toInt(), 0); |
164 | QCOMPARE(area->property("touchUpdatedHandled" ).toBool(), true); |
165 | QMetaObject::invokeMethod(obj: area, member: "clearCounts" ); |
166 | } |
167 | |
168 | void tst_QQuickMultiPointTouchArea::release() |
169 | { |
170 | QScopedPointer<QQuickView> window(createAndShowView(file: "basic.qml" )); |
171 | QVERIFY(window->rootObject() != nullptr); |
172 | |
173 | QQuickTouchPoint *point1 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point1" ); |
174 | |
175 | QCOMPARE(point1->pressed(), false); |
176 | |
177 | QPoint p1(20,100); |
178 | |
179 | QTest::QTouchEventSequence sequence = QTest::touchEvent(window: window.data(), device); |
180 | |
181 | sequence.press(touchId: 0, pt: p1).commit(); |
182 | QQuickTouchUtils::flush(window: window.data()); |
183 | |
184 | QCOMPARE(point1->pressed(), true); |
185 | |
186 | p1 += QPoint(0,10); |
187 | |
188 | sequence.move(touchId: 0, pt: p1).commit(); |
189 | QQuickTouchUtils::flush(window: window.data()); |
190 | |
191 | QCOMPARE(point1->pressed(), true); |
192 | QCOMPARE(point1->x(), qreal(20)); QCOMPARE(point1->y(), qreal(110)); |
193 | |
194 | p1 += QPoint(4,10); |
195 | |
196 | sequence.release(touchId: 0, pt: p1).commit(); |
197 | QQuickTouchUtils::flush(window: window.data()); |
198 | |
199 | //test that a release without a prior move to the release position successfully updates the point's position |
200 | QCOMPARE(point1->pressed(), false); |
201 | QCOMPARE(point1->x(), qreal(24)); QCOMPARE(point1->y(), qreal(120)); |
202 | } |
203 | |
204 | void tst_QQuickMultiPointTouchArea::reuse() |
205 | { |
206 | QScopedPointer<QQuickView> window(createAndShowView(file: "basic.qml" )); |
207 | QVERIFY(window->rootObject() != nullptr); |
208 | |
209 | QQuickTouchPoint *point1 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point1" ); |
210 | QQuickTouchPoint *point2 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point2" ); |
211 | QQuickTouchPoint *point3 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point3" ); |
212 | |
213 | QCOMPARE(point1->pressed(), false); |
214 | QCOMPARE(point2->pressed(), false); |
215 | |
216 | QPoint p1(20,100); |
217 | QPoint p2(40,100); |
218 | QPoint p3(60,100); |
219 | QPoint p4(80,100); |
220 | |
221 | QTest::QTouchEventSequence sequence = QTest::touchEvent(window: window.data(), device); |
222 | |
223 | sequence.press(touchId: 0, pt: p1).press(touchId: 1, pt: p2).commit(); |
224 | QQuickTouchUtils::flush(window: window.data()); |
225 | |
226 | QCOMPARE(point1->pressed(), true); |
227 | QCOMPARE(point2->pressed(), true); |
228 | QCOMPARE(point3->pressed(), false); |
229 | |
230 | sequence.release(touchId: 0, pt: p1).stationary(touchId: 1).press(touchId: 2, pt: p3).commit(); |
231 | QQuickTouchUtils::flush(window: window.data()); |
232 | |
233 | //we shouldn't reuse point 1 yet |
234 | QCOMPARE(point1->pressed(), false); |
235 | QCOMPARE(point2->pressed(), true); |
236 | QCOMPARE(point3->pressed(), true); |
237 | |
238 | //back to base state (no touches) |
239 | sequence.release(touchId: 1, pt: p2).release(touchId: 2, pt: p3).commit(); |
240 | QQuickTouchUtils::flush(window: window.data()); |
241 | |
242 | QCOMPARE(point1->pressed(), false); |
243 | QCOMPARE(point2->pressed(), false); |
244 | QCOMPARE(point3->pressed(), false); |
245 | |
246 | sequence.press(touchId: 0, pt: p1).press(touchId: 1, pt: p2).commit(); |
247 | QQuickTouchUtils::flush(window: window.data()); |
248 | |
249 | QCOMPARE(point1->pressed(), true); |
250 | QCOMPARE(point2->pressed(), true); |
251 | QCOMPARE(point3->pressed(), false); |
252 | |
253 | sequence.release(touchId: 0, pt: p1).stationary(touchId: 1).commit(); |
254 | QQuickTouchUtils::flush(window: window.data()); |
255 | |
256 | QCOMPARE(point1->pressed(), false); |
257 | QCOMPARE(point2->pressed(), true); |
258 | QCOMPARE(point3->pressed(), false); |
259 | |
260 | sequence.press(touchId: 4, pt: p4).stationary(touchId: 1).commit(); |
261 | QQuickTouchUtils::flush(window: window.data()); |
262 | |
263 | //the new touch point should reuse point 1 |
264 | QCOMPARE(point1->pressed(), true); |
265 | QCOMPARE(point2->pressed(), true); |
266 | QCOMPARE(point3->pressed(), false); |
267 | |
268 | QCOMPARE(point1->x(), qreal(80)); QCOMPARE(point1->y(), qreal(100)); |
269 | } |
270 | |
271 | void tst_QQuickMultiPointTouchArea::nonOverlapping() |
272 | { |
273 | QScopedPointer<QQuickView> window(createAndShowView(file: "nonOverlapping.qml" )); |
274 | QVERIFY(window->rootObject() != nullptr); |
275 | |
276 | QQuickTouchPoint *point11 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point11" ); |
277 | QQuickTouchPoint *point12 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point12" ); |
278 | QQuickTouchPoint *point21 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point21" ); |
279 | QQuickTouchPoint *point22 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point22" ); |
280 | QQuickTouchPoint *point23 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point23" ); |
281 | |
282 | QCOMPARE(point11->pressed(), false); |
283 | QCOMPARE(point12->pressed(), false); |
284 | QCOMPARE(point21->pressed(), false); |
285 | QCOMPARE(point22->pressed(), false); |
286 | QCOMPARE(point23->pressed(), false); |
287 | |
288 | QPoint p1(20,100); |
289 | QPoint p2(40,100); |
290 | QPoint p3(60,180); |
291 | QPoint p4(80,180); |
292 | QPoint p5(100,180); |
293 | |
294 | QTest::QTouchEventSequence sequence = QTest::touchEvent(window: window.data(), device); |
295 | |
296 | sequence.press(touchId: 0, pt: p1).commit(); |
297 | QQuickTouchUtils::flush(window: window.data()); |
298 | |
299 | QCOMPARE(point11->pressed(), false); |
300 | QCOMPARE(point12->pressed(), false); |
301 | QCOMPARE(point21->pressed(), false); |
302 | QCOMPARE(point22->pressed(), false); |
303 | QCOMPARE(point23->pressed(), false); |
304 | |
305 | sequence.stationary(touchId: 0).press(touchId: 1, pt: p2).commit(); |
306 | QQuickTouchUtils::flush(window: window.data()); |
307 | |
308 | QCOMPARE(point11->pressed(), true); |
309 | QCOMPARE(point12->pressed(), true); |
310 | QCOMPARE(point21->pressed(), false); |
311 | QCOMPARE(point22->pressed(), false); |
312 | QCOMPARE(point23->pressed(), false); |
313 | |
314 | QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100)); |
315 | QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100)); |
316 | |
317 | p1 += QPoint(0,10); |
318 | p2 += QPoint(5,0); |
319 | sequence.move(touchId: 0, pt: p1).move(touchId: 1, pt: p2).commit(); |
320 | QQuickTouchUtils::flush(window: window.data()); |
321 | |
322 | QCOMPARE(point11->pressed(), true); |
323 | QCOMPARE(point12->pressed(), true); |
324 | QCOMPARE(point21->pressed(), false); |
325 | QCOMPARE(point22->pressed(), false); |
326 | QCOMPARE(point23->pressed(), false); |
327 | |
328 | QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); |
329 | QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); |
330 | |
331 | sequence.stationary(touchId: 0).stationary(touchId: 1).press(touchId: 2, pt: p3).commit(); |
332 | QQuickTouchUtils::flush(window: window.data()); |
333 | |
334 | QCOMPARE(point11->pressed(), true); |
335 | QCOMPARE(point12->pressed(), true); |
336 | QCOMPARE(point21->pressed(), false); |
337 | QCOMPARE(point22->pressed(), false); |
338 | QCOMPARE(point23->pressed(), false); |
339 | |
340 | sequence.stationary(touchId: 0).stationary(touchId: 1).stationary(touchId: 2).press(touchId: 3, pt: p4).press(touchId: 4, pt: p5).commit(); |
341 | QQuickTouchUtils::flush(window: window.data()); |
342 | |
343 | QCOMPARE(point11->pressed(), true); |
344 | QCOMPARE(point12->pressed(), true); |
345 | QCOMPARE(point21->pressed(), true); |
346 | QCOMPARE(point22->pressed(), true); |
347 | QCOMPARE(point23->pressed(), true); |
348 | |
349 | QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); |
350 | QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); |
351 | QCOMPARE(point21->x(), qreal(60)); QCOMPARE(point21->y(), qreal(20)); |
352 | QCOMPARE(point22->x(), qreal(80)); QCOMPARE(point22->y(), qreal(20)); |
353 | QCOMPARE(point23->x(), qreal(100)); QCOMPARE(point23->y(), qreal(20)); |
354 | |
355 | p1 += QPoint(4,10); |
356 | p2 += QPoint(17,17); |
357 | p3 += QPoint(3,0); |
358 | p4 += QPoint(1,-1); |
359 | p5 += QPoint(-7,10); |
360 | sequence.move(touchId: 0, pt: p1).move(touchId: 1, pt: p2).move(touchId: 2, pt: p3).move(touchId: 3, pt: p4).move(touchId: 4, pt: p5).commit(); |
361 | QQuickTouchUtils::flush(window: window.data()); |
362 | |
363 | QCOMPARE(point11->pressed(), true); |
364 | QCOMPARE(point12->pressed(), true); |
365 | QCOMPARE(point21->pressed(), true); |
366 | QCOMPARE(point22->pressed(), true); |
367 | QCOMPARE(point23->pressed(), true); |
368 | |
369 | QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120)); |
370 | QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117)); |
371 | QCOMPARE(point21->x(), qreal(63)); QCOMPARE(point21->y(), qreal(20)); |
372 | QCOMPARE(point22->x(), qreal(81)); QCOMPARE(point22->y(), qreal(19)); |
373 | QCOMPARE(point23->x(), qreal(93)); QCOMPARE(point23->y(), qreal(30)); |
374 | |
375 | sequence.release(touchId: 0, pt: p1).release(touchId: 1, pt: p2).release(touchId: 2, pt: p3).release(touchId: 3, pt: p4).release(touchId: 4, pt: p5).commit(); |
376 | QQuickTouchUtils::flush(window: window.data()); |
377 | |
378 | QCOMPARE(point11->pressed(), false); |
379 | QCOMPARE(point12->pressed(), false); |
380 | QCOMPARE(point21->pressed(), false); |
381 | QCOMPARE(point22->pressed(), false); |
382 | QCOMPARE(point23->pressed(), false); |
383 | } |
384 | |
385 | void tst_QQuickMultiPointTouchArea::nested() |
386 | { |
387 | QScopedPointer<QQuickView> window(createAndShowView(file: "nested.qml" )); |
388 | QVERIFY(window->rootObject() != nullptr); |
389 | |
390 | QQuickTouchPoint *point11 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point11" ); |
391 | QQuickTouchPoint *point12 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point12" ); |
392 | QQuickTouchPoint *point21 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point21" ); |
393 | QQuickTouchPoint *point22 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point22" ); |
394 | QQuickTouchPoint *point23 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point23" ); |
395 | |
396 | QCOMPARE(point11->pressed(), false); |
397 | QCOMPARE(point12->pressed(), false); |
398 | QCOMPARE(point21->pressed(), false); |
399 | QCOMPARE(point22->pressed(), false); |
400 | QCOMPARE(point23->pressed(), false); |
401 | |
402 | QPoint p1(20,100); |
403 | QPoint p2(40,100); |
404 | QPoint p3(60,180); |
405 | |
406 | QTest::QTouchEventSequence sequence = QTest::touchEvent(window: window.data(), device); |
407 | |
408 | sequence.press(touchId: 0, pt: p1).commit(); |
409 | QQuickTouchUtils::flush(window: window.data()); |
410 | |
411 | QCOMPARE(point11->pressed(), false); |
412 | QCOMPARE(point12->pressed(), false); |
413 | QCOMPARE(point21->pressed(), false); |
414 | QCOMPARE(point22->pressed(), false); |
415 | QCOMPARE(point23->pressed(), false); |
416 | |
417 | sequence.stationary(touchId: 0).press(touchId: 1, pt: p2).commit(); |
418 | QQuickTouchUtils::flush(window: window.data()); |
419 | |
420 | QCOMPARE(point11->pressed(), true); |
421 | QCOMPARE(point12->pressed(), true); |
422 | QCOMPARE(point21->pressed(), false); |
423 | QCOMPARE(point22->pressed(), false); |
424 | QCOMPARE(point23->pressed(), false); |
425 | |
426 | QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100)); |
427 | QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100)); |
428 | |
429 | p1 += QPoint(0,10); |
430 | p2 += QPoint(5,0); |
431 | sequence.move(touchId: 0, pt: p1).move(touchId: 1, pt: p2).commit(); |
432 | QQuickTouchUtils::flush(window: window.data()); |
433 | |
434 | QCOMPARE(point11->pressed(), true); |
435 | QCOMPARE(point12->pressed(), true); |
436 | QCOMPARE(point21->pressed(), false); |
437 | QCOMPARE(point22->pressed(), false); |
438 | QCOMPARE(point23->pressed(), false); |
439 | |
440 | QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); |
441 | QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); |
442 | |
443 | sequence.stationary(touchId: 0).stationary(touchId: 1).press(touchId: 2, pt: p3).commit(); |
444 | QQuickTouchUtils::flush(window: window.data()); |
445 | |
446 | QCOMPARE(point11->pressed(), true); |
447 | QCOMPARE(point12->pressed(), true); |
448 | QCOMPARE(point21->pressed(), true); |
449 | QCOMPARE(point22->pressed(), true); |
450 | QCOMPARE(point23->pressed(), true); |
451 | |
452 | //point11 should be same as point21, point12 same as point22 |
453 | QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); |
454 | QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); |
455 | QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110)); |
456 | QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100)); |
457 | QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180)); |
458 | |
459 | sequence.stationary(touchId: 0).stationary(touchId: 1).stationary(touchId: 2).press(touchId: 3, pt: QPoint(80,180)).press(touchId: 4, pt: QPoint(100,180)).commit(); |
460 | QQuickTouchUtils::flush(window: window.data()); |
461 | |
462 | QCOMPARE(point11->pressed(), true); |
463 | QCOMPARE(point12->pressed(), true); |
464 | QCOMPARE(point21->pressed(), true); |
465 | QCOMPARE(point22->pressed(), true); |
466 | QCOMPARE(point23->pressed(), true); |
467 | |
468 | //new touch points should be ignored (have no impact on our existing touch points) |
469 | QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); |
470 | QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); |
471 | QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110)); |
472 | QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100)); |
473 | QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180)); |
474 | |
475 | sequence.stationary(touchId: 0).stationary(touchId: 1).stationary(touchId: 2).release(touchId: 3, pt: QPoint(80,180)).release(touchId: 4, pt: QPoint(100,180)).commit(); |
476 | |
477 | p1 += QPoint(4,10); |
478 | p2 += QPoint(17,17); |
479 | p3 += QPoint(3,0); |
480 | sequence.move(touchId: 0, pt: p1).move(touchId: 1, pt: p2).move(touchId: 2, pt: p3).commit(); |
481 | QQuickTouchUtils::flush(window: window.data()); |
482 | |
483 | QCOMPARE(point11->pressed(), true); |
484 | QCOMPARE(point12->pressed(), true); |
485 | QCOMPARE(point21->pressed(), true); |
486 | QCOMPARE(point22->pressed(), true); |
487 | QCOMPARE(point23->pressed(), true); |
488 | |
489 | QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); |
490 | QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); |
491 | QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); |
492 | QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); |
493 | QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180)); |
494 | |
495 | p1 += QPoint(4,10); |
496 | p2 += QPoint(17,17); |
497 | p3 += QPoint(3,0); |
498 | sequence.move(touchId: 0, pt: p1).move(touchId: 1, pt: p2).move(touchId: 2, pt: p3).commit(); |
499 | QQuickTouchUtils::flush(window: window.data()); |
500 | |
501 | QCOMPARE(point11->pressed(), false); |
502 | QCOMPARE(point12->pressed(), false); |
503 | QCOMPARE(point21->pressed(), true); |
504 | QCOMPARE(point22->pressed(), true); |
505 | QCOMPARE(point23->pressed(), true); |
506 | |
507 | //first two remain the same (touches now grabbed by inner touch area) |
508 | QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120)); |
509 | QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117)); |
510 | QCOMPARE(point21->x(), qreal(28)); QCOMPARE(point21->y(), qreal(130)); |
511 | QCOMPARE(point22->x(), qreal(79)); QCOMPARE(point22->y(), qreal(134)); |
512 | QCOMPARE(point23->x(), qreal(66)); QCOMPARE(point23->y(), qreal(180)); |
513 | |
514 | sequence.release(touchId: 0, pt: p1).release(touchId: 1, pt: p2).release(touchId: 2, pt: p3).commit(); |
515 | |
516 | sequence.press(touchId: 0, pt: p1).commit(); |
517 | QQuickTouchUtils::flush(window: window.data()); |
518 | |
519 | QCOMPARE(point11->pressed(), false); |
520 | QCOMPARE(point12->pressed(), false); |
521 | QCOMPARE(point21->pressed(), false); |
522 | QCOMPARE(point22->pressed(), false); |
523 | QCOMPARE(point23->pressed(), false); |
524 | |
525 | sequence.release(touchId: 0, pt: p1).commit(); |
526 | QQuickTouchUtils::flush(window: window.data()); |
527 | |
528 | //test with grabbing turned off |
529 | window->rootObject()->setProperty(name: "grabInnerArea" , value: false); |
530 | |
531 | sequence.press(touchId: 0, pt: p1).press(touchId: 1, pt: p2).press(touchId: 2, pt: p3).commit(); |
532 | QQuickTouchUtils::flush(window: window.data()); |
533 | |
534 | QCOMPARE(point11->pressed(), true); |
535 | QCOMPARE(point12->pressed(), true); |
536 | QCOMPARE(point21->pressed(), true); |
537 | QCOMPARE(point22->pressed(), true); |
538 | QCOMPARE(point23->pressed(), true); |
539 | |
540 | p1 -= QPoint(4,10); |
541 | p2 -= QPoint(17,17); |
542 | p3 -= QPoint(3,0); |
543 | sequence.move(touchId: 0, pt: p1).move(touchId: 1, pt: p2).move(touchId: 2, pt: p3).commit(); |
544 | QQuickTouchUtils::flush(window: window.data()); |
545 | |
546 | QCOMPARE(point11->pressed(), true); |
547 | QCOMPARE(point12->pressed(), true); |
548 | QCOMPARE(point21->pressed(), true); |
549 | QCOMPARE(point22->pressed(), true); |
550 | QCOMPARE(point23->pressed(), true); |
551 | |
552 | QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); |
553 | QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); |
554 | QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); |
555 | QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); |
556 | QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180)); |
557 | |
558 | p1 -= QPoint(4,10); |
559 | p2 -= QPoint(17,17); |
560 | p3 -= QPoint(3,0); |
561 | sequence.move(touchId: 0, pt: p1).move(touchId: 1, pt: p2).move(touchId: 2, pt: p3).commit(); |
562 | QQuickTouchUtils::flush(window: window.data()); |
563 | |
564 | QCOMPARE(point11->pressed(), true); |
565 | QCOMPARE(point12->pressed(), true); |
566 | QCOMPARE(point21->pressed(), true); |
567 | QCOMPARE(point22->pressed(), true); |
568 | QCOMPARE(point23->pressed(), true); |
569 | |
570 | //all change (touches not grabbed by inner touch area) |
571 | QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); |
572 | QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); |
573 | QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110)); |
574 | QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100)); |
575 | QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180)); |
576 | |
577 | sequence.release(touchId: 0, pt: p1).release(touchId: 1, pt: p2).release(touchId: 2, pt: p3).commit(); |
578 | QQuickTouchUtils::flush(window: window.data()); |
579 | } |
580 | |
581 | void tst_QQuickMultiPointTouchArea::inFlickable() |
582 | { |
583 | QScopedPointer<QQuickView> window(createAndShowView(file: "inFlickable.qml" )); |
584 | QVERIFY(window->rootObject() != nullptr); |
585 | |
586 | QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(object: window->rootObject()); |
587 | QVERIFY(flickable != nullptr); |
588 | |
589 | QQuickMultiPointTouchArea *mpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>(); |
590 | QVERIFY(mpta != nullptr); |
591 | |
592 | QQuickTouchPoint *point11 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point1" ); |
593 | QQuickTouchPoint *point12 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point2" ); |
594 | |
595 | QCOMPARE(point11->pressed(), false); |
596 | QCOMPARE(point12->pressed(), false); |
597 | |
598 | QPoint p1(20,100); |
599 | QPoint p2(40,100); |
600 | |
601 | //moving one point vertically |
602 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: p1); |
603 | QQuickTouchUtils::flush(window: window.data()); |
604 | |
605 | p1 += QPoint(0,15); |
606 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
607 | QQuickTouchUtils::flush(window: window.data()); |
608 | |
609 | p1 += QPoint(0,15); |
610 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
611 | QQuickTouchUtils::flush(window: window.data()); |
612 | |
613 | p1 += QPoint(0,15); |
614 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
615 | QQuickTouchUtils::flush(window: window.data()); |
616 | |
617 | p1 += QPoint(0,15); |
618 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
619 | QQuickTouchUtils::flush(window: window.data()); |
620 | |
621 | QVERIFY(flickable->contentY() < 0); |
622 | QCOMPARE(point11->pressed(), false); |
623 | QCOMPARE(point12->pressed(), false); |
624 | |
625 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: p1); |
626 | QQuickTouchUtils::flush(window: window.data()); |
627 | |
628 | QTRY_VERIFY(!flickable->isMoving()); |
629 | |
630 | //moving two points vertically |
631 | p1 = QPoint(20,100); |
632 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: p1).press(touchId: 1, pt: p2); |
633 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: p1); |
634 | QQuickTouchUtils::flush(window: window.data()); |
635 | |
636 | QCOMPARE(point11->pressed(), true); |
637 | QCOMPARE(point12->pressed(), true); |
638 | QCOMPARE(flickable->property("cancelCount" ).toInt(), 0); |
639 | QCOMPARE(flickable->property("touchCount" ).toInt(), 2); |
640 | |
641 | p1 += QPoint(0,15); p2 += QPoint(0,15); |
642 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
643 | QTest::mouseMove(window: window.data(), pos: p1); |
644 | QQuickTouchUtils::flush(window: window.data()); |
645 | |
646 | p1 += QPoint(0,15); p2 += QPoint(0,15); |
647 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
648 | QTest::mouseMove(window: window.data(), pos: p1); |
649 | QQuickTouchUtils::flush(window: window.data()); |
650 | |
651 | p1 += QPoint(0,15); p2 += QPoint(0,15); |
652 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
653 | QTest::mouseMove(window: window.data(), pos: p1); |
654 | QQuickTouchUtils::flush(window: window.data()); |
655 | |
656 | p1 += QPoint(0,15); p2 += QPoint(0,15); |
657 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
658 | QTest::mouseMove(window: window.data(), pos: p1); |
659 | QQuickTouchUtils::flush(window: window.data()); |
660 | |
661 | QVERIFY(flickable->contentY() < 0); |
662 | QCOMPARE(point11->pressed(), false); |
663 | QCOMPARE(point12->pressed(), false); |
664 | QCOMPARE(flickable->property("cancelCount" ).toInt(), 2); |
665 | QCOMPARE(flickable->property("touchCount" ).toInt(), 0); |
666 | |
667 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: p1).release(touchId: 1, pt: p2); |
668 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: p1); |
669 | QQuickTouchUtils::flush(window: window.data()); |
670 | |
671 | QTRY_VERIFY(!flickable->isMoving()); |
672 | |
673 | //moving two points horizontally, then one point vertically |
674 | p1 = QPoint(20,100); |
675 | p2 = QPoint(40,100); |
676 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: p1).press(touchId: 1, pt: p2); |
677 | QQuickTouchUtils::flush(window: window.data()); |
678 | // ensure that mouse events do not fall through to the Flickable |
679 | mpta->setMaximumTouchPoints(3); |
680 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: p1); |
681 | |
682 | QCOMPARE(point11->pressed(), true); |
683 | QCOMPARE(point12->pressed(), true); |
684 | |
685 | p1 += QPoint(15,0); p2 += QPoint(15,0); |
686 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
687 | QTest::mouseMove(window: window.data(), pos: p1); |
688 | QQuickTouchUtils::flush(window: window.data()); |
689 | |
690 | p1 += QPoint(15,0); p2 += QPoint(15,0); |
691 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
692 | QTest::mouseMove(window: window.data(), pos: p1); |
693 | QQuickTouchUtils::flush(window: window.data()); |
694 | |
695 | p1 += QPoint(15,0); p2 += QPoint(15,0); |
696 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
697 | QTest::mouseMove(window: window.data(), pos: p1); |
698 | QQuickTouchUtils::flush(window: window.data()); |
699 | |
700 | p1 += QPoint(15,0); p2 += QPoint(15,0); |
701 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
702 | QTest::mouseMove(window: window.data(), pos: p1); |
703 | QQuickTouchUtils::flush(window: window.data()); |
704 | |
705 | p1 += QPoint(0,15); p2 += QPoint(0,15); |
706 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
707 | QTest::mouseMove(window: window.data(), pos: p1); |
708 | QQuickTouchUtils::flush(window: window.data()); |
709 | |
710 | p1 += QPoint(0,15); p2 += QPoint(0,15); |
711 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
712 | QTest::mouseMove(window: window.data(), pos: p1); |
713 | QQuickTouchUtils::flush(window: window.data()); |
714 | |
715 | p1 += QPoint(0,15); p2 += QPoint(0,15); |
716 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
717 | QTest::mouseMove(window: window.data(), pos: p1); |
718 | QQuickTouchUtils::flush(window: window.data()); |
719 | |
720 | p1 += QPoint(0,15); p2 += QPoint(0,15); |
721 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1).move(touchId: 1, pt: p2); |
722 | QTest::mouseMove(window: window.data(), pos: p1); |
723 | QQuickTouchUtils::flush(window: window.data()); |
724 | |
725 | QCOMPARE(flickable->contentY(), qreal(0)); |
726 | QCOMPARE(point11->pressed(), true); |
727 | QCOMPARE(point12->pressed(), true); |
728 | |
729 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: p1).release(touchId: 1, pt: p2); |
730 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: p1); |
731 | QQuickTouchUtils::flush(window: window.data()); |
732 | } |
733 | |
734 | // test that dragging out of a Flickable containing a MPTA doesn't harm Flickable's state. |
735 | void tst_QQuickMultiPointTouchArea::inFlickable2() |
736 | { |
737 | QScopedPointer<QQuickView> window(createAndShowView(file: "inFlickable2.qml" )); |
738 | QVERIFY(window->rootObject() != nullptr); |
739 | |
740 | QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>(aName: "flickable" ); |
741 | QVERIFY(flickable != nullptr); |
742 | |
743 | QQuickTouchPoint *point11 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point1" ); |
744 | QVERIFY(point11); |
745 | |
746 | QCOMPARE(point11->pressed(), false); |
747 | |
748 | QPoint p1(50,100); |
749 | |
750 | // move point horizontally, out of Flickable area |
751 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: p1); |
752 | QQuickTouchUtils::flush(window: window.data()); |
753 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: p1); |
754 | |
755 | p1 += QPoint(15,0); |
756 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
757 | QQuickTouchUtils::flush(window: window.data()); |
758 | QTest::mouseMove(window: window.data(), pos: p1); |
759 | |
760 | p1 += QPoint(15,0); |
761 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
762 | QQuickTouchUtils::flush(window: window.data()); |
763 | QTest::mouseMove(window: window.data(), pos: p1); |
764 | |
765 | p1 += QPoint(15,0); |
766 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
767 | QQuickTouchUtils::flush(window: window.data()); |
768 | QTest::mouseMove(window: window.data(), pos: p1); |
769 | |
770 | p1 += QPoint(15,0); |
771 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
772 | QQuickTouchUtils::flush(window: window.data()); |
773 | QTest::mouseMove(window: window.data(), pos: p1); |
774 | |
775 | QVERIFY(!flickable->isMoving()); |
776 | QVERIFY(point11->pressed()); |
777 | |
778 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: p1); |
779 | QQuickTouchUtils::flush(window: window.data()); |
780 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: p1); |
781 | QTest::qWait(ms: 50); |
782 | |
783 | QTRY_VERIFY(!flickable->isMoving()); |
784 | |
785 | // Check that we can still move the Flickable |
786 | p1 = QPoint(50,100); |
787 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: p1); |
788 | QQuickTouchUtils::flush(window: window.data()); |
789 | |
790 | QCOMPARE(point11->pressed(), true); |
791 | |
792 | p1 += QPoint(0,15); |
793 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
794 | QQuickTouchUtils::flush(window: window.data()); |
795 | |
796 | p1 += QPoint(0,15); |
797 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
798 | QQuickTouchUtils::flush(window: window.data()); |
799 | |
800 | p1 += QPoint(0,15); |
801 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
802 | QQuickTouchUtils::flush(window: window.data()); |
803 | |
804 | p1 += QPoint(0,15); |
805 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
806 | QQuickTouchUtils::flush(window: window.data()); |
807 | |
808 | QVERIFY(flickable->contentY() < 0); |
809 | QVERIFY(flickable->isMoving()); |
810 | QCOMPARE(point11->pressed(), false); |
811 | |
812 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: p1); |
813 | QQuickTouchUtils::flush(window: window.data()); |
814 | QTest::qWait(ms: 50); |
815 | |
816 | QTRY_VERIFY(!flickable->isMoving()); |
817 | } |
818 | |
819 | void tst_QQuickMultiPointTouchArea::inFlickableWithPressDelay() // QTBUG-78818 |
820 | { |
821 | const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); |
822 | QScopedPointer<QQuickView> window(createAndShowView(file: "inFlickable.qml" )); |
823 | QVERIFY(window->rootObject() != nullptr); |
824 | QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(c: window.data()); |
825 | |
826 | QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(object: window->rootObject()); |
827 | QVERIFY(flickable != nullptr); |
828 | flickable->setPressDelay(50); |
829 | |
830 | QQuickMultiPointTouchArea *mpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>(); |
831 | QVERIFY(mpta != nullptr); |
832 | mpta->setMinimumTouchPoints(1); |
833 | QQuickTouchPoint *point11 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point1" ); |
834 | QPoint p1(20,100); |
835 | |
836 | // press: Flickable prevents delivery of TouchBegin, but sends mouse press instead, after the delay. |
837 | // MPTA handles the mouse press, and its first declared touchpoint is pressed. |
838 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: p1); |
839 | QQuickTouchUtils::flush(window: window.data()); |
840 | QTRY_COMPARE(point11->pressed(), true); |
841 | auto pointerEvent = windowPriv->pointerEventInstance(device: QQuickPointerDevice::touchDevices().at(i: 0)); |
842 | QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta); |
843 | |
844 | // release: MPTA receives TouchEnd (which is asymmetric with mouse press); does NOT emit canceled. |
845 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: p1); |
846 | QQuickTouchUtils::flush(window: window.data()); |
847 | QCOMPARE(flickable->property("cancelCount" ).toInt(), 0); |
848 | |
849 | // press again |
850 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: p1); |
851 | QQuickTouchUtils::flush(window: window.data()); |
852 | QTRY_COMPARE(point11->pressed(), true); // wait until pressDelay exceeded |
853 | QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta); |
854 | |
855 | // drag past the threshold: Flickable takes over the grab, MPTA gets touchUngrab and is no longer pressed |
856 | int i = 0; |
857 | for (; i < 10 && window->mouseGrabberItem() != flickable; ++i) { |
858 | p1 += QPoint(0,dragThreshold); |
859 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
860 | QQuickTouchUtils::flush(window: window.data()); |
861 | } |
862 | QCOMPARE(window->mouseGrabberItem(), flickable); |
863 | qCDebug(lcTests, "Flickable stole grab from MPTA after %d moves" , i); |
864 | QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), flickable); |
865 | QCOMPARE(point11->pressed(), false); |
866 | QVERIFY(flickable->property("cancelCount" ).toInt() > 0); // actually 2 because 2 touchPoints are declared... but only one was really cancelled |
867 | |
868 | // drag a little more and the Flickable moves |
869 | p1 += QPoint(0,1); |
870 | QTest::touchEvent(window: window.data(), device).move(touchId: 0, pt: p1); |
871 | QQuickTouchUtils::flush(window: window.data()); |
872 | QVERIFY(flickable->contentY() < 0); |
873 | QVERIFY(flickable->isMoving()); |
874 | |
875 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: p1); |
876 | QQuickTouchUtils::flush(window: window.data()); |
877 | |
878 | QTRY_VERIFY(!flickable->isMoving()); |
879 | } |
880 | |
881 | // QTBUG-31047 |
882 | void tst_QQuickMultiPointTouchArea::inMouseArea() |
883 | { |
884 | QScopedPointer<QQuickView> window(createAndShowView(file: "inMouseArea.qml" )); |
885 | QVERIFY(window->rootObject() != nullptr); |
886 | |
887 | QQuickMouseArea *mouseArea = qobject_cast<QQuickMouseArea *>(object: window->rootObject()); |
888 | QVERIFY(mouseArea != nullptr); |
889 | |
890 | QQuickMultiPointTouchArea *mpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>(aName: "mpta" ); |
891 | QVERIFY(mpta != nullptr); |
892 | |
893 | QPoint innerPoint(40,100); |
894 | QPoint outerPoint(10,100); |
895 | |
896 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: innerPoint); |
897 | QVERIFY(mpta->property("pressed" ).toBool()); |
898 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: innerPoint); |
899 | QVERIFY(!mpta->property("pressed" ).toBool()); |
900 | |
901 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: outerPoint); |
902 | QVERIFY(mouseArea->property("pressed" ).toBool()); |
903 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: outerPoint); |
904 | QVERIFY(!mouseArea->property("pressed" ).toBool()); |
905 | |
906 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: innerPoint); |
907 | QVERIFY(mpta->property("pressed" ).toBool()); |
908 | QVERIFY(!mouseArea->property("pressed" ).toBool()); |
909 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: innerPoint); |
910 | QVERIFY(!mpta->property("pressed" ).toBool()); |
911 | QVERIFY(!mouseArea->property("pressed" ).toBool()); |
912 | |
913 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: innerPoint); |
914 | QVERIFY(mpta->property("pressed" ).toBool()); |
915 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: innerPoint); |
916 | QVERIFY(!mpta->property("pressed" ).toBool()); |
917 | |
918 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: outerPoint); |
919 | QVERIFY(mouseArea->property("pressed" ).toBool()); |
920 | QVERIFY(!mpta->property("pressed" ).toBool()); |
921 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: outerPoint); |
922 | QVERIFY(!mouseArea->property("pressed" ).toBool()); |
923 | QVERIFY(!mpta->property("pressed" ).toBool()); |
924 | |
925 | // Right click should pass through |
926 | QTest::mousePress(window: window.data(), button: Qt::RightButton, stateKey: Qt::NoModifier, pos: innerPoint); |
927 | QVERIFY(mouseArea->property("pressed" ).toBool()); |
928 | QVERIFY(!mpta->property("pressed" ).toBool()); |
929 | QTest::mouseRelease(window: window.data(), button: Qt::RightButton, stateKey: Qt::NoModifier, pos: innerPoint); |
930 | |
931 | mpta->setProperty(name: "mouseEnabled" , value: false); |
932 | |
933 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: innerPoint); |
934 | QVERIFY(mpta->property("pressed" ).toBool()); |
935 | QVERIFY(!mouseArea->property("pressed" ).toBool()); |
936 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: innerPoint); |
937 | QVERIFY(!mpta->property("pressed" ).toBool()); |
938 | QVERIFY(!mouseArea->property("pressed" ).toBool()); |
939 | |
940 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: outerPoint); |
941 | QVERIFY(mouseArea->property("pressed" ).toBool()); |
942 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: outerPoint); |
943 | QVERIFY(!mouseArea->property("pressed" ).toBool()); |
944 | |
945 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: innerPoint); |
946 | QVERIFY(!mpta->property("pressed" ).toBool()); |
947 | QVERIFY(mouseArea->property("pressed" ).toBool()); |
948 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: innerPoint); |
949 | QVERIFY(!mpta->property("pressed" ).toBool()); |
950 | QVERIFY(!mouseArea->property("pressed" ).toBool()); |
951 | |
952 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: innerPoint); |
953 | QVERIFY(mpta->property("pressed" ).toBool()); |
954 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: innerPoint); |
955 | QVERIFY(!mpta->property("pressed" ).toBool()); |
956 | |
957 | QTest::touchEvent(window: window.data(), device).press(touchId: 0, pt: outerPoint); |
958 | QVERIFY(mouseArea->property("pressed" ).toBool()); |
959 | QVERIFY(!mpta->property("pressed" ).toBool()); |
960 | QTest::touchEvent(window: window.data(), device).release(touchId: 0, pt: outerPoint); |
961 | QVERIFY(!mouseArea->property("pressed" ).toBool()); |
962 | QVERIFY(!mpta->property("pressed" ).toBool()); |
963 | } |
964 | |
965 | void tst_QQuickMultiPointTouchArea::mouseAsTouchpoint() |
966 | { |
967 | QScopedPointer<QQuickView> window(createAndShowView(file: "dualGestures.qml" )); |
968 | QVERIFY(window->rootObject() != nullptr); |
969 | |
970 | QQuickMultiPointTouchArea *dualmpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>(aName: "dualTouchArea" ); |
971 | QVERIFY(dualmpta != nullptr); |
972 | |
973 | QQuickItem *touch1rect = window->rootObject()->findChild<QQuickItem*>(aName: "touch1rect" ); |
974 | QQuickItem *touch2rect = window->rootObject()->findChild<QQuickItem*>(aName: "touch2rect" ); |
975 | QQuickItem *touch3rect = window->rootObject()->findChild<QQuickItem*>(aName: "touch3rect" ); |
976 | QQuickItem *touch4rect = window->rootObject()->findChild<QQuickItem*>(aName: "touch4rect" ); |
977 | QQuickItem *touch5rect = window->rootObject()->findChild<QQuickItem*>(aName: "touch5rect" ); |
978 | |
979 | { |
980 | QPoint touch1(40,10); |
981 | QPoint touch2(40,100); |
982 | QPoint touch3(10,10); |
983 | |
984 | // Touch both, release one, manipulate other touchpoint with mouse |
985 | QTest::touchEvent(window: window.data(), device).press(touchId: 1, pt: touch1); |
986 | QQuickTouchUtils::flush(window: window.data()); |
987 | QTest::touchEvent(window: window.data(), device).move(touchId: 1, pt: touch1).press(touchId: 2, pt: touch2); |
988 | QQuickTouchUtils::flush(window: window.data()); |
989 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
990 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
991 | QCOMPARE(touch2rect->property("x" ).toInt(), touch2.x()); |
992 | QCOMPARE(touch2rect->property("y" ).toInt(), touch2.y()); |
993 | QTest::touchEvent(window: window.data(), device).release(touchId: 1, pt: touch1).move(touchId: 2, pt: touch2); |
994 | touch1.setY(20); |
995 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: touch1); |
996 | QQuickTouchUtils::flush(window: window.data()); |
997 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
998 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
999 | QCOMPARE(touch2rect->property("x" ).toInt(), touch2.x()); |
1000 | QCOMPARE(touch2rect->property("y" ).toInt(), touch2.y()); |
1001 | QTest::touchEvent(window: window.data(), device).release(touchId: 2, pt: touch2); |
1002 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: touch1); |
1003 | QQuickTouchUtils::flush(window: window.data()); |
1004 | |
1005 | // Start with mouse, move it, touch second point, move it |
1006 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: touch1); |
1007 | touch1.setX(60); |
1008 | QTest::mouseMove(window: window.data(), pos: touch1); |
1009 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
1010 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
1011 | touch2.setX(60); |
1012 | QTest::touchEvent(window: window.data(), device).press(touchId: 3, pt: touch2); |
1013 | QQuickTouchUtils::flush(window: window.data()); |
1014 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
1015 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
1016 | QCOMPARE(touch2rect->property("x" ).toInt(), touch2.x()); |
1017 | QCOMPARE(touch2rect->property("y" ).toInt(), touch2.y()); |
1018 | touch2.setY(150); |
1019 | QTest::touchEvent(window: window.data(), device).move(touchId: 3, pt: touch2); |
1020 | QQuickTouchUtils::flush(window: window.data()); |
1021 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
1022 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
1023 | QCOMPARE(touch2rect->property("x" ).toInt(), touch2.x()); |
1024 | QCOMPARE(touch2rect->property("y" ).toInt(), touch2.y()); |
1025 | |
1026 | // Touch third point - nothing happens |
1027 | QTest::touchEvent(window: window.data(), device).press(touchId: 4, pt: touch3); |
1028 | QQuickTouchUtils::flush(window: window.data()); |
1029 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
1030 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
1031 | QCOMPARE(touch2rect->property("x" ).toInt(), touch2.x()); |
1032 | QCOMPARE(touch2rect->property("y" ).toInt(), touch2.y()); |
1033 | |
1034 | // Release all |
1035 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: touch1); |
1036 | QTest::touchEvent(window: window.data(), device).release(touchId: 3, pt: touch2); |
1037 | QQuickTouchUtils::flush(window: window.data()); |
1038 | QTest::touchEvent(window: window.data(), device).release(touchId: 4, pt: touch3); |
1039 | QQuickTouchUtils::flush(window: window.data()); |
1040 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
1041 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
1042 | QCOMPARE(touch2rect->property("x" ).toInt(), touch2.x()); |
1043 | QCOMPARE(touch2rect->property("y" ).toInt(), touch2.y()); |
1044 | } |
1045 | |
1046 | // Mouse and touch on left, touch 3 points on right |
1047 | { |
1048 | QPoint mouse1(40,10); |
1049 | QPoint touch1(10,10); |
1050 | QPoint touch2(340,10); |
1051 | QPoint touch3(340,100); |
1052 | QPoint touch4(540,10); |
1053 | |
1054 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: mouse1); |
1055 | QCOMPARE(touch1rect->property("x" ).toInt(), mouse1.x()); |
1056 | QCOMPARE(touch1rect->property("y" ).toInt(), mouse1.y()); |
1057 | QTest::touchEvent(window: window.data(), device).press(touchId: 1, pt: touch1); |
1058 | QQuickTouchUtils::flush(window: window.data()); |
1059 | QCOMPARE(touch1rect->property("x" ).toInt(), mouse1.x()); |
1060 | QCOMPARE(touch1rect->property("y" ).toInt(), mouse1.y()); |
1061 | QCOMPARE(touch2rect->property("x" ).toInt(), touch1.x()); |
1062 | QCOMPARE(touch2rect->property("y" ).toInt(), touch1.y()); |
1063 | |
1064 | QTest::touchEvent(window: window.data(), device).press(touchId: 2, pt: touch2).press(touchId: 3, pt: touch3).press(touchId: 4, pt: touch4); |
1065 | QQuickTouchUtils::flush(window: window.data()); |
1066 | QCOMPARE(touch1rect->property("x" ).toInt(), mouse1.x()); |
1067 | QCOMPARE(touch1rect->property("y" ).toInt(), mouse1.y()); |
1068 | QCOMPARE(touch2rect->property("x" ).toInt(), touch1.x()); |
1069 | QCOMPARE(touch2rect->property("y" ).toInt(), touch1.y()); |
1070 | QCOMPARE(touch3rect->property("x" ).toInt(), touch2.x() - 320); |
1071 | QCOMPARE(touch3rect->property("y" ).toInt(), touch2.y()); |
1072 | QCOMPARE(touch4rect->property("x" ).toInt(), touch3.x() - 320); |
1073 | QCOMPARE(touch4rect->property("y" ).toInt(), touch3.y()); |
1074 | QCOMPARE(touch5rect->property("x" ).toInt(), touch4.x() - 320); |
1075 | QCOMPARE(touch5rect->property("y" ).toInt(), touch4.y()); |
1076 | |
1077 | // Release all |
1078 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: mouse1); |
1079 | QTest::touchEvent(window: window.data(), device).release(touchId: 1, pt: touch1).release(touchId: 2, pt: touch2).release(touchId: 3, pt: touch3).release(touchId: 4, pt: touch4); |
1080 | QQuickTouchUtils::flush(window: window.data()); |
1081 | } |
1082 | |
1083 | dualmpta->setProperty(name: "mouseEnabled" , value: false); |
1084 | { |
1085 | QPoint mouse1(40,10); |
1086 | QPoint touch1(10,10); |
1087 | QPoint touch2(100,10); |
1088 | |
1089 | touch1rect->setX(10); |
1090 | touch1rect->setY(10); |
1091 | touch2rect->setX(20); |
1092 | touch2rect->setY(10); |
1093 | |
1094 | // Start with mouse, move it, touch a point, move it, touch another. |
1095 | // Mouse is ignored, both touch points are heeded. |
1096 | QTest::mousePress(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: mouse1); |
1097 | mouse1.setX(60); |
1098 | QTest::mouseMove(window: window.data(), pos: mouse1); |
1099 | QCOMPARE(touch1rect->property("x" ).toInt(), 10); |
1100 | QCOMPARE(touch1rect->property("y" ).toInt(), 10); |
1101 | |
1102 | QTest::touchEvent(window: window.data(), device).press(touchId: 1, pt: touch1); |
1103 | QQuickTouchUtils::flush(window: window.data()); |
1104 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
1105 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
1106 | touch1.setY(150); |
1107 | QTest::touchEvent(window: window.data(), device).move(touchId: 1, pt: touch1); |
1108 | QQuickTouchUtils::flush(window: window.data()); |
1109 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
1110 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
1111 | QTest::touchEvent(window: window.data(), device).press(touchId: 2, pt: touch2); |
1112 | QQuickTouchUtils::flush(window: window.data()); |
1113 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
1114 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
1115 | QCOMPARE(touch2rect->property("x" ).toInt(), touch2.x()); |
1116 | QCOMPARE(touch2rect->property("y" ).toInt(), touch2.y()); |
1117 | |
1118 | // Release all |
1119 | QTest::mouseRelease(window: window.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: mouse1); |
1120 | QTest::touchEvent(window: window.data(), device).release(touchId: 1, pt: touch1); |
1121 | QQuickTouchUtils::flush(window: window.data()); |
1122 | QTest::touchEvent(window: window.data(), device).release(touchId: 2, pt: touch2); |
1123 | QQuickTouchUtils::flush(window: window.data()); |
1124 | QCOMPARE(touch1rect->property("x" ).toInt(), touch1.x()); |
1125 | QCOMPARE(touch1rect->property("y" ).toInt(), touch1.y()); |
1126 | QCOMPARE(touch2rect->property("x" ).toInt(), touch2.x()); |
1127 | QCOMPARE(touch2rect->property("y" ).toInt(), touch2.y()); |
1128 | } |
1129 | } |
1130 | |
1131 | // QTBUG-23327 |
1132 | void tst_QQuickMultiPointTouchArea::invisible() |
1133 | { |
1134 | QScopedPointer<QQuickView> window(createAndShowView(file: "signalTest.qml" )); |
1135 | QVERIFY(window->rootObject() != nullptr); |
1136 | |
1137 | QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(object: window->rootObject()); |
1138 | QVERIFY(area != nullptr); |
1139 | |
1140 | area->setVisible(false); |
1141 | |
1142 | QPoint p1(20,100); |
1143 | QPoint p2(40,100); |
1144 | |
1145 | QTest::QTouchEventSequence sequence = QTest::touchEvent(window: window.data(), device); |
1146 | |
1147 | sequence.press(touchId: 0, pt: p1).press(touchId: 1, pt: p2).commit(); |
1148 | |
1149 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 0); |
1150 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 0); |
1151 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 0); |
1152 | QCOMPARE(area->property("touchCount" ).toInt(), 0); |
1153 | } |
1154 | |
1155 | void tst_QQuickMultiPointTouchArea::transformedTouchArea_data() |
1156 | { |
1157 | QTest::addColumn<QPoint>(name: "p1" ); |
1158 | QTest::addColumn<QPoint>(name: "p2" ); |
1159 | QTest::addColumn<QPoint>(name: "p3" ); |
1160 | QTest::addColumn<int>(name: "total1" ); |
1161 | QTest::addColumn<int>(name: "total2" ); |
1162 | QTest::addColumn<int>(name: "total3" ); |
1163 | |
1164 | QTest::newRow(dataTag: "1st point inside" ) |
1165 | << QPoint(140, 200) << QPoint(260, 260) << QPoint(0, 140) << 1 << 1 << 1; |
1166 | |
1167 | QTest::newRow(dataTag: "2nd point inside" ) |
1168 | << QPoint(260, 260) << QPoint(200, 200) << QPoint(0, 0) << 0 << 1 << 1; |
1169 | |
1170 | QTest::newRow(dataTag: "3rd point inside" ) |
1171 | << QPoint(140, 260) << QPoint(260, 140) << QPoint(200, 140) << 0 << 0 << 1; |
1172 | QTest::newRow(dataTag: "all points inside" ) |
1173 | << QPoint(200, 140) << QPoint(200, 260) << QPoint(140, 200) << 1 << 2 << 3; |
1174 | |
1175 | QTest::newRow(dataTag: "all points outside" ) |
1176 | << QPoint(140, 140) << QPoint(260, 260) << QPoint(260, 140) << 0 << 0 << 0; |
1177 | |
1178 | QTest::newRow(dataTag: "1st and 2nd points inside" ) |
1179 | << QPoint(200, 260) << QPoint(200, 140) << QPoint(140, 140) << 1 << 2 << 2; |
1180 | |
1181 | QTest::newRow(dataTag: "1st and 3rd points inside" ) |
1182 | << QPoint(200, 200) << QPoint(0, 0) << QPoint(200, 260) << 1 << 1 << 2; |
1183 | } |
1184 | |
1185 | void tst_QQuickMultiPointTouchArea::transformedTouchArea() |
1186 | { |
1187 | QFETCH(QPoint, p1); |
1188 | QFETCH(QPoint, p2); |
1189 | QFETCH(QPoint, p3); |
1190 | QFETCH(int, total1); |
1191 | QFETCH(int, total2); |
1192 | QFETCH(int, total3); |
1193 | |
1194 | |
1195 | QScopedPointer<QQuickView> view(createAndShowView(file: "transformedMultiPointTouchArea.qml" )); |
1196 | QVERIFY(view->rootObject() != nullptr); |
1197 | |
1198 | QQuickMultiPointTouchArea *area = view->rootObject()->findChild<QQuickMultiPointTouchArea *>(aName: "touchArea" ); |
1199 | QVERIFY(area != nullptr); |
1200 | |
1201 | QTest::QTouchEventSequence sequence = QTest::touchEvent(window: view.data(), device); |
1202 | |
1203 | sequence.press(touchId: 0, pt: p1).commit(); |
1204 | QCOMPARE(area->property("pointCount" ).toInt(), total1); |
1205 | |
1206 | sequence.stationary(touchId: 0).press(touchId: 1, pt: p2).commit(); |
1207 | QCOMPARE(area->property("pointCount" ).toInt(), total2); |
1208 | |
1209 | sequence.stationary(touchId: 0).stationary(touchId: 1).press(touchId: 2, pt: p3).commit(); |
1210 | QCOMPARE(area->property("pointCount" ).toInt(), total3); |
1211 | } |
1212 | |
1213 | QQuickView *tst_QQuickMultiPointTouchArea::createAndShowView(const QString &file) |
1214 | { |
1215 | QScopedPointer<QQuickView> window(new QQuickView(nullptr)); |
1216 | window->setSource(testFileUrl(fileName: file)); |
1217 | if (window->status() != QQuickView::Ready) |
1218 | return nullptr; |
1219 | const QRect screenGeometry = window->screen()->availableGeometry(); |
1220 | const QSize size = window->size(); |
1221 | const QPoint offset = QPoint(size.width() / 2, size.height() / 2); |
1222 | window->setFramePosition(screenGeometry.center() - offset); |
1223 | window->show(); |
1224 | if (!QTest::qWaitForWindowExposed(window: window.data())) |
1225 | return nullptr; |
1226 | return window.take(); |
1227 | } |
1228 | |
1229 | void tst_QQuickMultiPointTouchArea::mouseInteraction_data() |
1230 | { |
1231 | QTest::addColumn<int>(name: "buttons" ); |
1232 | QTest::addColumn<int>(name: "accept" ); |
1233 | |
1234 | QTest::newRow(dataTag: "left" ) << (int) Qt::LeftButton << 1; |
1235 | QTest::newRow(dataTag: "right" ) << (int) Qt::RightButton << 0; |
1236 | QTest::newRow(dataTag: "middle" ) << (int) Qt::MiddleButton << 0; |
1237 | } |
1238 | |
1239 | void tst_QQuickMultiPointTouchArea::mouseInteraction() |
1240 | { |
1241 | QFETCH(int, buttons); |
1242 | QFETCH(int, accept); |
1243 | |
1244 | QScopedPointer<QQuickView> view(createAndShowView(file: "mouse.qml" )); |
1245 | QVERIFY(view->rootObject() != nullptr); |
1246 | |
1247 | QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(object: view->rootObject()); |
1248 | QVERIFY(area != nullptr); |
1249 | QQuickTouchPoint *point1 = view->rootObject()->findChild<QQuickTouchPoint*>(aName: "point1" ); |
1250 | QCOMPARE(point1->pressed(), false); |
1251 | |
1252 | QCOMPARE(area->property("touchCount" ).toInt(), 0); |
1253 | QPoint p1 = QPoint(100, 100); |
1254 | QTest::mousePress(window: view.data(), button: (Qt::MouseButton) buttons, stateKey: Qt::NoModifier, pos: p1); |
1255 | QCOMPARE(area->property("touchCount" ).toInt(), accept); |
1256 | QCOMPARE(point1->pressed(), accept != 0); |
1257 | p1 += QPoint(10, 10); |
1258 | QTest::mouseMove(window: view.data(), pos: p1); |
1259 | QCOMPARE(point1->pressed(), accept != 0); |
1260 | QCOMPARE(area->property("touchCount" ).toInt(), accept); |
1261 | p1 += QPoint(10, 10); |
1262 | QTest::mouseMove(window: view.data(), pos: p1); |
1263 | QCOMPARE(point1->pressed(), accept != 0); |
1264 | QCOMPARE(area->property("touchCount" ).toInt(), accept); |
1265 | QTest::mouseRelease(window: view.data(), button: (Qt::MouseButton) buttons); |
1266 | QCOMPARE(point1->pressed(), false); |
1267 | QCOMPARE(area->property("touchCount" ).toInt(), 0); |
1268 | } |
1269 | |
1270 | void tst_QQuickMultiPointTouchArea::mouseGestureStarted_data() |
1271 | { |
1272 | QTest::addColumn<bool>(name: "grabGesture" ); |
1273 | QTest::addColumn<int>(name: "distanceFromOrigin" ); |
1274 | |
1275 | QTest::newRow(dataTag: "near origin, don't grab" ) << false << 4; |
1276 | QTest::newRow(dataTag: "near origin, grab" ) << true << 4; |
1277 | QTest::newRow(dataTag: "away from origin, don't grab" ) << false << 100; |
1278 | QTest::newRow(dataTag: "away from origin, grab" ) << true << 100; |
1279 | } |
1280 | |
1281 | void tst_QQuickMultiPointTouchArea::mouseGestureStarted() // QTBUG-70258 |
1282 | { |
1283 | const int dragThreshold = QGuiApplication::styleHints()->startDragDistance(); |
1284 | QFETCH(bool, grabGesture); |
1285 | QFETCH(int, distanceFromOrigin); |
1286 | |
1287 | QScopedPointer<QQuickView> view(createAndShowView(file: "mouse.qml" )); |
1288 | QVERIFY(view->rootObject() != nullptr); |
1289 | |
1290 | QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(object: view->rootObject()); |
1291 | QVERIFY(area); |
1292 | area->setProperty(name: "grabGesture" , value: grabGesture); |
1293 | QQuickTouchPoint *point1 = view->rootObject()->findChild<QQuickTouchPoint*>(aName: "point1" ); |
1294 | QCOMPARE(point1->pressed(), false); |
1295 | QSignalSpy gestureStartedSpy(area, SIGNAL(gestureStarted(QQuickGrabGestureEvent *))); |
1296 | |
1297 | QPoint p1 = QPoint(distanceFromOrigin, distanceFromOrigin); |
1298 | QTest::mousePress(window: view.data(), button: Qt::LeftButton, stateKey: Qt::NoModifier, pos: p1); |
1299 | QCOMPARE(gestureStartedSpy.count(), 0); |
1300 | |
1301 | p1 += QPoint(dragThreshold, dragThreshold); |
1302 | QTest::mouseMove(window: view.data(), pos: p1); |
1303 | QCOMPARE(gestureStartedSpy.count(), 0); |
1304 | |
1305 | p1 += QPoint(1, 1); |
1306 | QTest::mouseMove(window: view.data(), pos: p1); |
1307 | QTRY_COMPARE(gestureStartedSpy.count(), 1); |
1308 | QTRY_COMPARE(area->property("gestureStartedX" ).toInt(), distanceFromOrigin); |
1309 | QCOMPARE(area->property("gestureStartedY" ).toInt(), distanceFromOrigin); |
1310 | |
1311 | p1 += QPoint(10, 10); |
1312 | QTest::mouseMove(window: view.data(), pos: p1); |
1313 | // if nobody called gesteure->grab(), gestureStarted will keep happening |
1314 | QTRY_COMPARE(gestureStartedSpy.count(), grabGesture ? 1 : 2); |
1315 | QCOMPARE(area->property("gestureStartedX" ).toInt(), distanceFromOrigin); |
1316 | QCOMPARE(area->property("gestureStartedY" ).toInt(), distanceFromOrigin); |
1317 | |
1318 | QTest::mouseRelease(window: view.data(), button: Qt::LeftButton); |
1319 | } |
1320 | |
1321 | void tst_QQuickMultiPointTouchArea::cancel() |
1322 | { |
1323 | QScopedPointer<QQuickView> window(createAndShowView(file: "cancel.qml" )); |
1324 | QVERIFY(window->rootObject() != nullptr); |
1325 | |
1326 | QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(object: window->rootObject()); |
1327 | QTest::QTouchEventSequence sequence = QTest::touchEvent(window: window.data(), device); |
1328 | QQuickTouchPoint *point1 = area->findChild<QQuickTouchPoint*>(aName: "point1" ); |
1329 | |
1330 | QPoint p1(20,100); |
1331 | sequence.press(touchId: 0, pt: p1).commit(); |
1332 | QQuickTouchUtils::flush(window: window.data()); |
1333 | QCOMPARE(point1->pressed(), true); |
1334 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 1); |
1335 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 0); |
1336 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 0); |
1337 | QCOMPARE(area->property("touchPointCancelCount" ).toInt(), 0); |
1338 | QCOMPARE(area->property("touchCount" ).toInt(), 1); |
1339 | QMetaObject::invokeMethod(obj: area, member: "clearCounts" ); |
1340 | |
1341 | area->setVisible(false); |
1342 | // we should get a onCancel signal |
1343 | QCOMPARE(point1->pressed(), false); |
1344 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 0); |
1345 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 0); |
1346 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 0); |
1347 | QCOMPARE(area->property("touchPointCancelCount" ).toInt(), 1); |
1348 | QCOMPARE(area->property("touchCount" ).toInt(), 0); |
1349 | QMetaObject::invokeMethod(obj: area, member: "clearCounts" ); |
1350 | area->setVisible(true); |
1351 | |
1352 | |
1353 | sequence.press(touchId: 0, pt: p1).commit(); |
1354 | QQuickTouchUtils::flush(window: window.data()); |
1355 | QCOMPARE(point1->pressed(), true); |
1356 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 1); |
1357 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 0); |
1358 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 0); |
1359 | QCOMPARE(area->property("touchPointCancelCount" ).toInt(), 0); |
1360 | QCOMPARE(area->property("touchCount" ).toInt(), 1); |
1361 | QMetaObject::invokeMethod(obj: area, member: "clearCounts" ); |
1362 | |
1363 | area->setEnabled(false); |
1364 | // we should get a onCancel signal |
1365 | QCOMPARE(point1->pressed(), false); |
1366 | QCOMPARE(area->property("touchPointPressCount" ).toInt(), 0); |
1367 | QCOMPARE(area->property("touchPointUpdateCount" ).toInt(), 0); |
1368 | QCOMPARE(area->property("touchPointReleaseCount" ).toInt(), 0); |
1369 | QCOMPARE(area->property("touchPointCancelCount" ).toInt(), 1); |
1370 | QCOMPARE(area->property("touchCount" ).toInt(), 0); |
1371 | QMetaObject::invokeMethod(obj: area, member: "clearCounts" ); |
1372 | |
1373 | } |
1374 | |
1375 | void tst_QQuickMultiPointTouchArea::stationaryTouchWithChangingPressure() // QTBUG-77142 |
1376 | { |
1377 | QScopedPointer<QQuickView> window(createAndShowView(file: "basic.qml" )); |
1378 | QVERIFY(window->rootObject() != nullptr); |
1379 | |
1380 | QQuickTouchPoint *point1 = window->rootObject()->findChild<QQuickTouchPoint*>(aName: "point1" ); |
1381 | QCOMPARE(point1->pressed(), false); |
1382 | |
1383 | QPoint p1(20,100); |
1384 | QTouchEvent::TouchPoint tp1(1); |
1385 | |
1386 | tp1.setScreenPos(window->mapToGlobal(pos: p1)); |
1387 | tp1.setState(Qt::TouchPointPressed); |
1388 | tp1.setPressure(0.5); |
1389 | qt_handleTouchEvent(w: window.data(), device, points: {tp1}); |
1390 | QQuickTouchUtils::flush(window: window.data()); |
1391 | |
1392 | QCOMPARE(point1->pressed(), true); |
1393 | QCOMPARE(point1->pressure(), 0.5); |
1394 | |
1395 | tp1.setState(Qt::TouchPointStationary); |
1396 | tp1.setPressure(0.6); |
1397 | qt_handleTouchEvent(w: window.data(), device, points: {tp1}); |
1398 | QQuickTouchUtils::flush(window: window.data()); |
1399 | |
1400 | QCOMPARE(point1->pressure(), 0.6); |
1401 | |
1402 | tp1.setState(Qt::TouchPointReleased); |
1403 | tp1.setPressure(0); |
1404 | qt_handleTouchEvent(w: window.data(), device, points: {tp1}); |
1405 | QQuickTouchUtils::flush(window: window.data()); |
1406 | |
1407 | QCOMPARE(point1->pressed(), false); |
1408 | QCOMPARE(point1->pressure(), 0); |
1409 | } |
1410 | |
1411 | |
1412 | QTEST_MAIN(tst_QQuickMultiPointTouchArea) |
1413 | |
1414 | #include "tst_qquickmultipointtoucharea.moc" |
1415 | |