1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QSignalSpy>
43 #include <QtGui/QStyleHints>
44 #include <QtQml/qqmlengine.h>
45 #include <QtQml/qqmlcomponent.h>
46 #include <QtQuick/qquickview.h>
47 #include <private/qquickflickable_p.h>
48 #include <private/qquickflickable_p_p.h>
49 #include <private/qquicktransition_p.h>
50 #include <private/qqmlvaluetype_p.h>
52 #include "../../shared/util.h"
53 #include "../shared/viewtestutil.h"
54 #include "../shared/visualtestutil.h"
56 using namespace QQuickViewTestUtil;
57 using namespace QQuickVisualTestUtil;
59 class tst_qquickflickable : public QQmlDataTest
66 void horizontalViewportSize();
67 void verticalViewportSize();
69 void boundsBehavior();
71 void maximumFlickVelocity();
72 void flickDeceleration();
74 void nestedPressDelay();
75 void flickableDirection();
77 void returnToBounds();
78 void returnToBounds_data();
80 void movingAndFlicking();
81 void movingAndFlicking_data();
82 void movingAndDragging();
83 void movingAndDragging_data();
84 void flickOnRelease();
85 void pressWhileFlicking();
89 void cancelOnMouseGrab();
90 void clickAndDragWhenTransformed();
96 void tst_qquickflickable::create()
99 QQmlComponent c(&engine, testFileUrl("flickable01.qml"));
100 QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
103 QCOMPARE(obj->isAtXBeginning(), true);
104 QCOMPARE(obj->isAtXEnd(), false);
105 QCOMPARE(obj->isAtYBeginning(), true);
106 QCOMPARE(obj->isAtYEnd(), false);
107 QCOMPARE(obj->contentX(), 0.);
108 QCOMPARE(obj->contentY(), 0.);
110 QCOMPARE(obj->horizontalVelocity(), 0.);
111 QCOMPARE(obj->verticalVelocity(), 0.);
113 QCOMPARE(obj->isInteractive(), true);
114 QCOMPARE(obj->boundsBehavior(), QQuickFlickable::DragAndOvershootBounds);
115 QCOMPARE(obj->pressDelay(), 0);
116 QCOMPARE(obj->maximumFlickVelocity(), 2500.);
121 void tst_qquickflickable::horizontalViewportSize()
124 QQmlComponent c(&engine, testFileUrl("flickable02.qml"));
125 QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
128 QCOMPARE(obj->contentWidth(), 800.);
129 QCOMPARE(obj->contentHeight(), 300.);
130 QCOMPARE(obj->isAtXBeginning(), true);
131 QCOMPARE(obj->isAtXEnd(), false);
132 QCOMPARE(obj->isAtYBeginning(), true);
133 QCOMPARE(obj->isAtYEnd(), false);
138 void tst_qquickflickable::verticalViewportSize()
141 QQmlComponent c(&engine, testFileUrl("flickable03.qml"));
142 QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
145 QCOMPARE(obj->contentWidth(), 200.);
146 QCOMPARE(obj->contentHeight(), 6000.);
147 QCOMPARE(obj->isAtXBeginning(), true);
148 QCOMPARE(obj->isAtXEnd(), false);
149 QCOMPARE(obj->isAtYBeginning(), true);
150 QCOMPARE(obj->isAtYEnd(), false);
155 void tst_qquickflickable::properties()
158 QQmlComponent c(&engine, testFileUrl("flickable04.qml"));
159 QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
162 QCOMPARE(obj->isInteractive(), false);
163 QCOMPARE(obj->boundsBehavior(), QQuickFlickable::StopAtBounds);
164 QCOMPARE(obj->pressDelay(), 200);
165 QCOMPARE(obj->maximumFlickVelocity(), 2000.);
167 QVERIFY(obj->property("ok").toBool() == false);
168 QMetaObject::invokeMethod(obj, "check");
169 QVERIFY(obj->property("ok").toBool() == true);
174 void tst_qquickflickable::boundsBehavior()
176 QQmlComponent component(&engine);
177 component.setData("import QtQuick 2.0; Flickable { boundsBehavior: Flickable.StopAtBounds }", QUrl::fromLocalFile(""));
178 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
179 QSignalSpy spy(flickable, SIGNAL(boundsBehaviorChanged()));
182 QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds);
184 flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
185 QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragAndOvershootBounds);
186 QCOMPARE(spy.count(),1);
187 flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
188 QCOMPARE(spy.count(),1);
190 flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds);
191 QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragOverBounds);
192 QCOMPARE(spy.count(),2);
193 flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds);
194 QCOMPARE(spy.count(),2);
196 flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds);
197 QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds);
198 QCOMPARE(spy.count(),3);
199 flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds);
200 QCOMPARE(spy.count(),3);
205 void tst_qquickflickable::rebound()
207 QQuickView *window = new QQuickView;
208 window->setSource(testFileUrl("rebound.qml"));
210 window->requestActivateWindow();
211 QVERIFY(window->rootObject() != 0);
213 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
214 QVERIFY(flickable != 0);
216 QQuickTransition *rebound = window->rootObject()->findChild<QQuickTransition*>("rebound");
218 QSignalSpy reboundSpy(rebound, SIGNAL(runningChanged()));
220 QSignalSpy movementStartedSpy(flickable, SIGNAL(movementStarted()));
221 QSignalSpy movementEndedSpy(flickable, SIGNAL(movementEnded()));
222 QSignalSpy vMoveSpy(flickable, SIGNAL(movingVerticallyChanged()));
223 QSignalSpy hMoveSpy(flickable, SIGNAL(movingHorizontallyChanged()));
225 // flick and test the transition is run
226 flick(window, QPoint(20,20), QPoint(120,120), 200);
228 QTRY_COMPARE(window->rootObject()->property("transitionsStarted").toInt(), 2);
229 QCOMPARE(hMoveSpy.count(), 1);
230 QCOMPARE(vMoveSpy.count(), 1);
231 QCOMPARE(movementStartedSpy.count(), 1);
232 QCOMPARE(movementEndedSpy.count(), 0);
233 QVERIFY(rebound->running());
235 QTRY_VERIFY(!flickable->isMoving());
236 QCOMPARE(flickable->contentX(), 0.0);
237 QCOMPARE(flickable->contentY(), 0.0);
239 QCOMPARE(hMoveSpy.count(), 2);
240 QCOMPARE(vMoveSpy.count(), 2);
241 QCOMPARE(movementStartedSpy.count(), 1);
242 QCOMPARE(movementEndedSpy.count(), 1);
243 QCOMPARE(window->rootObject()->property("transitionsStarted").toInt(), 2);
244 QVERIFY(!rebound->running());
245 QCOMPARE(reboundSpy.count(), 2);
249 movementStartedSpy.clear();
250 movementEndedSpy.clear();
251 window->rootObject()->setProperty("transitionsStarted", 0);
252 window->rootObject()->setProperty("transitionsFinished", 0);
255 QSKIP("QTBUG-26696 - sometimes fails on Mac");
260 // flick and trigger the transition multiple times
261 // (moving signals are emitted as soon as the first transition starts)
262 flick(window, QPoint(20,20), QPoint(120,120), 200); // both x and y will bounce back
263 flick(window, QPoint(20,120), QPoint(120,20), 200); // only x will bounce back
265 QVERIFY(flickable->isMoving());
266 QVERIFY(window->rootObject()->property("transitionsStarted").toInt() >= 1);
267 QCOMPARE(hMoveSpy.count(), 1);
268 QCOMPARE(vMoveSpy.count(), 1);
269 QCOMPARE(movementStartedSpy.count(), 1);
271 QTRY_VERIFY(!flickable->isMoving());
272 QCOMPARE(flickable->contentX(), 0.0);
274 // moving started/stopped signals should only have been emitted once,
275 // and when they are, all transitions should have finished
276 QCOMPARE(hMoveSpy.count(), 2);
277 QCOMPARE(vMoveSpy.count(), 2);
278 QCOMPARE(movementStartedSpy.count(), 1);
279 QCOMPARE(movementEndedSpy.count(), 1);
283 movementStartedSpy.clear();
284 movementEndedSpy.clear();
285 window->rootObject()->setProperty("transitionsStarted", 0);
286 window->rootObject()->setProperty("transitionsFinished", 0);
288 // disable and the default transition should run
289 // (i.e. moving but transition->running = false)
290 window->rootObject()->setProperty("transitionEnabled", false);
292 flick(window, QPoint(20,20), QPoint(120,120), 200);
293 QCOMPARE(window->rootObject()->property("transitionsStarted").toInt(), 0);
294 QCOMPARE(hMoveSpy.count(), 1);
295 QCOMPARE(vMoveSpy.count(), 1);
296 QCOMPARE(movementStartedSpy.count(), 1);
297 QCOMPARE(movementEndedSpy.count(), 0);
299 QTRY_VERIFY(!flickable->isMoving());
300 QCOMPARE(hMoveSpy.count(), 2);
301 QCOMPARE(vMoveSpy.count(), 2);
302 QCOMPARE(movementStartedSpy.count(), 1);
303 QCOMPARE(movementEndedSpy.count(), 1);
304 QCOMPARE(window->rootObject()->property("transitionsStarted").toInt(), 0);
309 void tst_qquickflickable::maximumFlickVelocity()
311 QQmlComponent component(&engine);
312 component.setData("import QtQuick 2.0; Flickable { maximumFlickVelocity: 1.0; }", QUrl::fromLocalFile(""));
313 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
314 QSignalSpy spy(flickable, SIGNAL(maximumFlickVelocityChanged()));
317 QCOMPARE(flickable->maximumFlickVelocity(), 1.0);
319 flickable->setMaximumFlickVelocity(2.0);
320 QCOMPARE(flickable->maximumFlickVelocity(), 2.0);
321 QCOMPARE(spy.count(),1);
322 flickable->setMaximumFlickVelocity(2.0);
323 QCOMPARE(spy.count(),1);
328 void tst_qquickflickable::flickDeceleration()
330 QQmlComponent component(&engine);
331 component.setData("import QtQuick 2.0; Flickable { flickDeceleration: 1.0; }", QUrl::fromLocalFile(""));
332 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
333 QSignalSpy spy(flickable, SIGNAL(flickDecelerationChanged()));
336 QCOMPARE(flickable->flickDeceleration(), 1.0);
338 flickable->setFlickDeceleration(2.0);
339 QCOMPARE(flickable->flickDeceleration(), 2.0);
340 QCOMPARE(spy.count(),1);
341 flickable->setFlickDeceleration(2.0);
342 QCOMPARE(spy.count(),1);
347 void tst_qquickflickable::pressDelay()
349 QQmlComponent component(&engine);
350 component.setData("import QtQuick 2.0; Flickable { pressDelay: 100; }", QUrl::fromLocalFile(""));
351 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
352 QSignalSpy spy(flickable, SIGNAL(pressDelayChanged()));
355 QCOMPARE(flickable->pressDelay(), 100);
357 flickable->setPressDelay(200);
358 QCOMPARE(flickable->pressDelay(), 200);
359 QCOMPARE(spy.count(),1);
360 flickable->setPressDelay(200);
361 QCOMPARE(spy.count(),1);
367 void tst_qquickflickable::nestedPressDelay()
369 QQuickView *window = new QQuickView;
370 window->setSource(testFileUrl("nestedPressDelay.qml"));
372 window->requestActivateWindow();
373 QVERIFY(window->rootObject() != 0);
375 QQuickFlickable *outer = qobject_cast<QQuickFlickable*>(window->rootObject());
378 QQuickFlickable *inner = window->rootObject()->findChild<QQuickFlickable*>("innerFlickable");
381 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(150, 150));
382 // the MouseArea is not pressed immediately
383 QVERIFY(outer->property("pressed").toBool() == false);
385 // The outer pressDelay will prevail (50ms, vs. 10sec)
386 // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec.
387 QTRY_VERIFY(outer->property("pressed").toBool() == true);
389 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(150, 150));
394 void tst_qquickflickable::flickableDirection()
396 QQmlComponent component(&engine);
397 component.setData("import QtQuick 2.0; Flickable { flickableDirection: Flickable.VerticalFlick; }", QUrl::fromLocalFile(""));
398 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(component.create());
399 QSignalSpy spy(flickable, SIGNAL(flickableDirectionChanged()));
402 QCOMPARE(flickable->flickableDirection(), QQuickFlickable::VerticalFlick);
404 flickable->setFlickableDirection(QQuickFlickable::HorizontalAndVerticalFlick);
405 QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalAndVerticalFlick);
406 QCOMPARE(spy.count(),1);
408 flickable->setFlickableDirection(QQuickFlickable::AutoFlickDirection);
409 QCOMPARE(flickable->flickableDirection(), QQuickFlickable::AutoFlickDirection);
410 QCOMPARE(spy.count(),2);
412 flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick);
413 QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick);
414 QCOMPARE(spy.count(),3);
416 flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick);
417 QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick);
418 QCOMPARE(spy.count(),3);
424 void tst_qquickflickable::resizeContent()
427 engine.rootContext()->setContextProperty("setRebound", false);
428 QQmlComponent c(&engine, testFileUrl("resize.qml"));
429 QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
430 QQuickFlickable *obj = findItem<QQuickFlickable>(root, "flick");
433 QCOMPARE(obj->contentX(), 0.);
434 QCOMPARE(obj->contentY(), 0.);
435 QCOMPARE(obj->contentWidth(), 300.);
436 QCOMPARE(obj->contentHeight(), 300.);
438 QMetaObject::invokeMethod(root, "resizeContent");
440 QCOMPARE(obj->contentX(), 100.);
441 QCOMPARE(obj->contentY(), 100.);
442 QCOMPARE(obj->contentWidth(), 600.);
443 QCOMPARE(obj->contentHeight(), 600.);
448 void tst_qquickflickable::returnToBounds()
450 QFETCH(bool, setRebound);
452 QQuickView *window = new QQuickView;
453 window->rootContext()->setContextProperty("setRebound", setRebound);
454 window->setSource(testFileUrl("resize.qml"));
455 QVERIFY(window->rootObject() != 0);
456 QQuickFlickable *obj = findItem<QQuickFlickable>(window->rootObject(), "flick");
458 QQuickTransition *rebound = window->rootObject()->findChild<QQuickTransition*>("rebound");
460 QSignalSpy reboundSpy(rebound, SIGNAL(runningChanged()));
463 QCOMPARE(obj->contentX(), 0.);
464 QCOMPARE(obj->contentY(), 0.);
465 QCOMPARE(obj->contentWidth(), 300.);
466 QCOMPARE(obj->contentHeight(), 300.);
468 obj->setContentX(100);
469 obj->setContentY(400);
470 QTRY_COMPARE(obj->contentX(), 100.);
471 QTRY_COMPARE(obj->contentY(), 400.);
473 QMetaObject::invokeMethod(window->rootObject(), "returnToBounds");
476 QTRY_VERIFY(rebound->running());
478 QTRY_COMPARE(obj->contentX(), 0.);
479 QTRY_COMPARE(obj->contentY(), 0.);
481 QVERIFY(!rebound->running());
482 QCOMPARE(reboundSpy.count(), setRebound ? 2 : 0);
487 void tst_qquickflickable::returnToBounds_data()
489 QTest::addColumn<bool>("setRebound");
491 QTest::newRow("with bounds transition") << true;
492 QTest::newRow("with bounds transition") << false;
495 void tst_qquickflickable::wheel()
497 QQuickView *window = new QQuickView;
498 window->setSource(testFileUrl("wheel.qml"));
500 window->requestActivateWindow();
501 QVERIFY(window->rootObject() != 0);
503 QQuickFlickable *flick = window->rootObject()->findChild<QQuickFlickable*>("flick");
507 QPoint pos(200, 200);
508 QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(0,-120), -120, Qt::Vertical, Qt::NoButton, Qt::NoModifier);
509 event.setAccepted(false);
510 QGuiApplication::sendEvent(window, &event);
513 QTRY_VERIFY(flick->contentY() > 0);
514 QVERIFY(flick->contentX() == 0);
516 flick->setContentY(0);
517 QVERIFY(flick->contentY() == 0);
520 QPoint pos(200, 200);
521 QWheelEvent event(pos, window->mapToGlobal(pos), QPoint(), QPoint(-120,0), -120, Qt::Horizontal, Qt::NoButton, Qt::NoModifier);
523 event.setAccepted(false);
524 QGuiApplication::sendEvent(window, &event);
527 QTRY_VERIFY(flick->contentX() > 0);
528 QVERIFY(flick->contentY() == 0);
533 void tst_qquickflickable::movingAndFlicking_data()
535 QTest::addColumn<bool>("verticalEnabled");
536 QTest::addColumn<bool>("horizontalEnabled");
537 QTest::addColumn<QPoint>("flickToWithoutSnapBack");
538 QTest::addColumn<QPoint>("flickToWithSnapBack");
540 QTest::newRow("vertical")
545 QTest::newRow("horizontal")
550 QTest::newRow("both")
556 void tst_qquickflickable::movingAndFlicking()
558 QFETCH(bool, verticalEnabled);
559 QFETCH(bool, horizontalEnabled);
560 QFETCH(QPoint, flickToWithoutSnapBack);
561 QFETCH(QPoint, flickToWithSnapBack);
563 const QPoint flickFrom(50, 200); // centre
565 QQuickView *window = new QQuickView;
566 window->setSource(testFileUrl("flickable03.qml"));
568 window->requestActivateWindow();
569 QTest::qWaitForWindowActive(window);
570 QVERIFY(window->rootObject() != 0);
572 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
573 QVERIFY(flickable != 0);
575 QSignalSpy vMoveSpy(flickable, SIGNAL(movingVerticallyChanged()));
576 QSignalSpy hMoveSpy(flickable, SIGNAL(movingHorizontallyChanged()));
577 QSignalSpy moveSpy(flickable, SIGNAL(movingChanged()));
578 QSignalSpy vFlickSpy(flickable, SIGNAL(flickingVerticallyChanged()));
579 QSignalSpy hFlickSpy(flickable, SIGNAL(flickingHorizontallyChanged()));
580 QSignalSpy flickSpy(flickable, SIGNAL(flickingChanged()));
582 QSignalSpy moveStartSpy(flickable, SIGNAL(movementStarted()));
583 QSignalSpy moveEndSpy(flickable, SIGNAL(movementEnded()));
584 QSignalSpy flickStartSpy(flickable, SIGNAL(flickStarted()));
585 QSignalSpy flickEndSpy(flickable, SIGNAL(flickEnded()));
587 // do a flick that keeps the view within the bounds
588 flick(window, flickFrom, flickToWithoutSnapBack, 200);
590 QVERIFY(flickable->isMoving());
591 QCOMPARE(flickable->isMovingHorizontally(), horizontalEnabled);
592 QCOMPARE(flickable->isMovingVertically(), verticalEnabled);
593 QVERIFY(flickable->isFlicking());
594 QCOMPARE(flickable->isFlickingHorizontally(), horizontalEnabled);
595 QCOMPARE(flickable->isFlickingVertically(), verticalEnabled);
597 QCOMPARE(moveSpy.count(), 1);
598 QCOMPARE(vMoveSpy.count(), verticalEnabled ? 1 : 0);
599 QCOMPARE(hMoveSpy.count(), horizontalEnabled ? 1 : 0);
600 QCOMPARE(flickSpy.count(), 1);
601 QCOMPARE(vFlickSpy.count(), verticalEnabled ? 1 : 0);
602 QCOMPARE(hFlickSpy.count(), horizontalEnabled ? 1 : 0);
604 QCOMPARE(moveStartSpy.count(), 1);
605 QCOMPARE(flickStartSpy.count(), 1);
607 // wait for any motion to end
608 QTRY_VERIFY(!flickable->isMoving());
610 QVERIFY(!flickable->isMovingHorizontally());
611 QVERIFY(!flickable->isMovingVertically());
612 QVERIFY(!flickable->isFlicking());
613 QVERIFY(!flickable->isFlickingHorizontally());
614 QVERIFY(!flickable->isFlickingVertically());
616 QCOMPARE(moveSpy.count(), 2);
617 QCOMPARE(vMoveSpy.count(), verticalEnabled ? 2 : 0);
618 QCOMPARE(hMoveSpy.count(), horizontalEnabled ? 2 : 0);
619 QCOMPARE(flickSpy.count(), 2);
620 QCOMPARE(vFlickSpy.count(), verticalEnabled ? 2 : 0);
621 QCOMPARE(hFlickSpy.count(), horizontalEnabled ? 2 : 0);
623 QCOMPARE(moveStartSpy.count(), 1);
624 QCOMPARE(moveEndSpy.count(), 1);
625 QCOMPARE(flickStartSpy.count(), 1);
626 QCOMPARE(flickEndSpy.count(), 1);
628 // Stop on a full pixel after user interaction
630 QCOMPARE(flickable->contentY(), (qreal)qRound(flickable->contentY()));
631 if (horizontalEnabled)
632 QCOMPARE(flickable->contentX(), (qreal)qRound(flickable->contentX()));
634 // clear for next flick
635 vMoveSpy.clear(); hMoveSpy.clear(); moveSpy.clear();
636 vFlickSpy.clear(); hFlickSpy.clear(); flickSpy.clear();
637 moveStartSpy.clear(); moveEndSpy.clear();
638 flickStartSpy.clear(); flickEndSpy.clear();
640 // do a flick that flicks the view out of bounds
641 flickable->setContentX(0);
642 flickable->setContentY(0);
643 QTRY_VERIFY(!flickable->isMoving());
644 flick(window, flickFrom, flickToWithSnapBack, 200);
646 QVERIFY(flickable->isMoving());
647 QCOMPARE(flickable->isMovingHorizontally(), horizontalEnabled);
648 QCOMPARE(flickable->isMovingVertically(), verticalEnabled);
649 QVERIFY(flickable->isFlicking());
650 QCOMPARE(flickable->isFlickingHorizontally(), horizontalEnabled);
651 QCOMPARE(flickable->isFlickingVertically(), verticalEnabled);
653 QCOMPARE(moveSpy.count(), 1);
654 QCOMPARE(vMoveSpy.count(), verticalEnabled ? 1 : 0);
655 QCOMPARE(hMoveSpy.count(), horizontalEnabled ? 1 : 0);
656 QCOMPARE(flickSpy.count(), 1);
657 QCOMPARE(vFlickSpy.count(), verticalEnabled ? 1 : 0);
658 QCOMPARE(hFlickSpy.count(), horizontalEnabled ? 1 : 0);
660 QCOMPARE(moveStartSpy.count(), 1);
661 QCOMPARE(moveEndSpy.count(), 0);
662 QCOMPARE(flickStartSpy.count(), 1);
663 QCOMPARE(flickEndSpy.count(), 0);
665 // wait for any motion to end
666 QTRY_VERIFY(!flickable->isMoving());
668 QVERIFY(!flickable->isMovingHorizontally());
669 QVERIFY(!flickable->isMovingVertically());
670 QVERIFY(!flickable->isFlicking());
671 QVERIFY(!flickable->isFlickingHorizontally());
672 QVERIFY(!flickable->isFlickingVertically());
674 QCOMPARE(moveSpy.count(), 2);
675 QCOMPARE(vMoveSpy.count(), verticalEnabled ? 2 : 0);
676 QCOMPARE(hMoveSpy.count(), horizontalEnabled ? 2 : 0);
677 QCOMPARE(flickSpy.count(), 2);
678 QCOMPARE(vFlickSpy.count(), verticalEnabled ? 2 : 0);
679 QCOMPARE(hFlickSpy.count(), horizontalEnabled ? 2 : 0);
681 QCOMPARE(moveStartSpy.count(), 1);
682 QCOMPARE(moveEndSpy.count(), 1);
683 QCOMPARE(flickStartSpy.count(), 1);
684 QCOMPARE(flickEndSpy.count(), 1);
686 QCOMPARE(flickable->contentX(), 0.0);
687 QCOMPARE(flickable->contentY(), 0.0);
693 void tst_qquickflickable::movingAndDragging_data()
695 QTest::addColumn<bool>("verticalEnabled");
696 QTest::addColumn<bool>("horizontalEnabled");
697 QTest::addColumn<QPoint>("moveByWithoutSnapBack");
698 QTest::addColumn<QPoint>("moveByWithSnapBack");
700 QTest::newRow("vertical")
705 QTest::newRow("horizontal")
710 QTest::newRow("both")
716 void tst_qquickflickable::movingAndDragging()
718 QFETCH(bool, verticalEnabled);
719 QFETCH(bool, horizontalEnabled);
720 QFETCH(QPoint, moveByWithoutSnapBack);
721 QFETCH(QPoint, moveByWithSnapBack);
723 const QPoint moveFrom(50, 200); // centre
725 QQuickView *window = new QQuickView;
726 window->setSource(testFileUrl("flickable03.qml"));
728 window->requestActivateWindow();
729 QVERIFY(QTest::qWaitForWindowExposed(window));
730 QVERIFY(window->rootObject() != 0);
732 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
733 QVERIFY(flickable != 0);
735 QSignalSpy vDragSpy(flickable, SIGNAL(draggingVerticallyChanged()));
736 QSignalSpy hDragSpy(flickable, SIGNAL(draggingHorizontallyChanged()));
737 QSignalSpy dragSpy(flickable, SIGNAL(draggingChanged()));
738 QSignalSpy vMoveSpy(flickable, SIGNAL(movingVerticallyChanged()));
739 QSignalSpy hMoveSpy(flickable, SIGNAL(movingHorizontallyChanged()));
740 QSignalSpy moveSpy(flickable, SIGNAL(movingChanged()));
742 QSignalSpy dragStartSpy(flickable, SIGNAL(dragStarted()));
743 QSignalSpy dragEndSpy(flickable, SIGNAL(dragEnded()));
744 QSignalSpy moveStartSpy(flickable, SIGNAL(movementStarted()));
745 QSignalSpy moveEndSpy(flickable, SIGNAL(movementEnded()));
748 QTest::mousePress(window, Qt::LeftButton, 0, moveFrom);
749 QTest::mouseMove(window, moveFrom + moveByWithoutSnapBack);
750 QTest::mouseMove(window, moveFrom + moveByWithoutSnapBack*2);
751 QTest::mouseMove(window, moveFrom + moveByWithoutSnapBack*3);
753 QTRY_VERIFY(flickable->isMoving());
754 QCOMPARE(flickable->isMovingHorizontally(), horizontalEnabled);
755 QCOMPARE(flickable->isMovingVertically(), verticalEnabled);
756 QVERIFY(flickable->isDragging());
757 QCOMPARE(flickable->isDraggingHorizontally(), horizontalEnabled);
758 QCOMPARE(flickable->isDraggingVertically(), verticalEnabled);
760 QCOMPARE(moveSpy.count(), 1);
761 QCOMPARE(vMoveSpy.count(), verticalEnabled ? 1 : 0);
762 QCOMPARE(hMoveSpy.count(), horizontalEnabled ? 1 : 0);
763 QCOMPARE(dragSpy.count(), 1);
764 QCOMPARE(vDragSpy.count(), verticalEnabled ? 1 : 0);
765 QCOMPARE(hDragSpy.count(), horizontalEnabled ? 1 : 0);
767 QCOMPARE(moveStartSpy.count(), 1);
768 QCOMPARE(dragStartSpy.count(), 1);
770 QTest::mouseRelease(window, Qt::LeftButton, 0, moveFrom + moveByWithoutSnapBack*3);
772 QVERIFY(!flickable->isDragging());
773 QVERIFY(!flickable->isDraggingHorizontally());
774 QVERIFY(!flickable->isDraggingVertically());
775 QCOMPARE(dragSpy.count(), 2);
776 QCOMPARE(vDragSpy.count(), verticalEnabled ? 2 : 0);
777 QCOMPARE(hDragSpy.count(), horizontalEnabled ? 2 : 0);
778 QCOMPARE(dragStartSpy.count(), 1);
779 QCOMPARE(dragEndSpy.count(), 1);
780 // Don't test whether moving finished because a flick could occur
782 // wait for any motion to end
783 QTRY_VERIFY(flickable->isMoving() == false);
785 QVERIFY(!flickable->isMovingHorizontally());
786 QVERIFY(!flickable->isMovingVertically());
787 QVERIFY(!flickable->isDragging());
788 QVERIFY(!flickable->isDraggingHorizontally());
789 QVERIFY(!flickable->isDraggingVertically());
791 QCOMPARE(dragSpy.count(), 2);
792 QCOMPARE(vDragSpy.count(), verticalEnabled ? 2 : 0);
793 QCOMPARE(hDragSpy.count(), horizontalEnabled ? 2 : 0);
794 QCOMPARE(moveSpy.count(), 2);
795 QCOMPARE(vMoveSpy.count(), verticalEnabled ? 2 : 0);
796 QCOMPARE(hMoveSpy.count(), horizontalEnabled ? 2 : 0);
798 QCOMPARE(dragStartSpy.count(), 1);
799 QCOMPARE(dragEndSpy.count(), 1);
800 QCOMPARE(moveStartSpy.count(), 1);
801 QCOMPARE(moveEndSpy.count(), 1);
803 // Stop on a full pixel after user interaction
805 QCOMPARE(flickable->contentY(), (qreal)qRound(flickable->contentY()));
806 if (horizontalEnabled)
807 QCOMPARE(flickable->contentX(), (qreal)qRound(flickable->contentX()));
809 // clear for next drag
810 vMoveSpy.clear(); hMoveSpy.clear(); moveSpy.clear();
811 vDragSpy.clear(); hDragSpy.clear(); dragSpy.clear();
812 moveStartSpy.clear(); moveEndSpy.clear();
813 dragStartSpy.clear(); dragEndSpy.clear();
815 // do a drag that drags the view out of bounds
816 flickable->setContentX(0);
817 flickable->setContentY(0);
818 QTRY_VERIFY(!flickable->isMoving());
819 QTest::mousePress(window, Qt::LeftButton, 0, moveFrom);
820 QTest::mouseMove(window, moveFrom + moveByWithSnapBack);
821 QTest::mouseMove(window, moveFrom + moveByWithSnapBack*2);
822 QTest::mouseMove(window, moveFrom + moveByWithSnapBack*3);
824 QVERIFY(flickable->isMoving());
825 QCOMPARE(flickable->isMovingHorizontally(), horizontalEnabled);
826 QCOMPARE(flickable->isMovingVertically(), verticalEnabled);
827 QVERIFY(flickable->isDragging());
828 QCOMPARE(flickable->isDraggingHorizontally(), horizontalEnabled);
829 QCOMPARE(flickable->isDraggingVertically(), verticalEnabled);
831 QCOMPARE(moveSpy.count(), 1);
832 QCOMPARE(vMoveSpy.count(), verticalEnabled ? 1 : 0);
833 QCOMPARE(hMoveSpy.count(), horizontalEnabled ? 1 : 0);
834 QCOMPARE(dragSpy.count(), 1);
835 QCOMPARE(vDragSpy.count(), verticalEnabled ? 1 : 0);
836 QCOMPARE(hDragSpy.count(), horizontalEnabled ? 1 : 0);
838 QCOMPARE(moveStartSpy.count(), 1);
839 QCOMPARE(moveEndSpy.count(), 0);
840 QCOMPARE(dragStartSpy.count(), 1);
841 QCOMPARE(dragEndSpy.count(), 0);
843 QTest::mouseRelease(window, Qt::LeftButton, 0, moveFrom + moveByWithSnapBack*3);
845 // should now start snapping back to bounds (moving but not dragging)
846 QVERIFY(flickable->isMoving());
847 QCOMPARE(flickable->isMovingHorizontally(), horizontalEnabled);
848 QCOMPARE(flickable->isMovingVertically(), verticalEnabled);
849 QVERIFY(!flickable->isDragging());
850 QVERIFY(!flickable->isDraggingHorizontally());
851 QVERIFY(!flickable->isDraggingVertically());
853 QCOMPARE(moveSpy.count(), 1);
854 QCOMPARE(vMoveSpy.count(), verticalEnabled ? 1 : 0);
855 QCOMPARE(hMoveSpy.count(), horizontalEnabled ? 1 : 0);
856 QCOMPARE(dragSpy.count(), 2);
857 QCOMPARE(vDragSpy.count(), verticalEnabled ? 2 : 0);
858 QCOMPARE(hDragSpy.count(), horizontalEnabled ? 2 : 0);
860 QCOMPARE(moveStartSpy.count(), 1);
861 QCOMPARE(moveEndSpy.count(), 0);
863 // wait for any motion to end
864 QTRY_VERIFY(!flickable->isMoving());
866 QVERIFY(!flickable->isMovingHorizontally());
867 QVERIFY(!flickable->isMovingVertically());
868 QVERIFY(!flickable->isDragging());
869 QVERIFY(!flickable->isDraggingHorizontally());
870 QVERIFY(!flickable->isDraggingVertically());
872 QCOMPARE(moveSpy.count(), 2);
873 QCOMPARE(vMoveSpy.count(), verticalEnabled ? 2 : 0);
874 QCOMPARE(hMoveSpy.count(), horizontalEnabled ? 2 : 0);
875 QCOMPARE(dragSpy.count(), 2);
876 QCOMPARE(vDragSpy.count(), verticalEnabled ? 2 : 0);
877 QCOMPARE(hDragSpy.count(), horizontalEnabled ? 2 : 0);
879 QCOMPARE(moveStartSpy.count(), 1);
880 QCOMPARE(moveEndSpy.count(), 1);
881 QCOMPARE(dragStartSpy.count(), 1);
882 QCOMPARE(dragEndSpy.count(), 1);
884 QCOMPARE(flickable->contentX(), 0.0);
885 QCOMPARE(flickable->contentY(), 0.0);
890 void tst_qquickflickable::flickOnRelease()
892 QQuickView *window = new QQuickView;
893 window->setSource(testFileUrl("flickable03.qml"));
895 window->requestActivateWindow();
896 QVERIFY(QTest::qWaitForWindowExposed(window));
897 QVERIFY(window->rootObject() != 0);
899 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
900 QVERIFY(flickable != 0);
902 // Vertical with a quick press-move-release: should cause a flick in release.
903 QSignalSpy vFlickSpy(flickable, SIGNAL(flickingVerticallyChanged()));
904 // Use something that generates a huge velocity just to make it testable.
905 // In practice this feature matters on touchscreen devices where the
906 // underlying drivers will hopefully provide a pre-calculated velocity
907 // (based on more data than what the UI gets), thus making this use case
908 // working even with small movements.
909 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(50, 300));
910 QTest::mouseMove(window, QPoint(50, 10), 10);
911 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(50, 10), 10);
913 QCOMPARE(vFlickSpy.count(), 1);
915 // wait for any motion to end
916 QTRY_VERIFY(flickable->isMoving() == false);
919 QEXPECT_FAIL("", "QTBUG-26094 stopping on a full pixel doesn't work on OS X", Continue);
921 // Stop on a full pixel after user interaction
922 QCOMPARE(flickable->contentY(), (qreal)qRound(flickable->contentY()));
927 void tst_qquickflickable::pressWhileFlicking()
929 QQuickView *window = new QQuickView;
930 window->setSource(testFileUrl("flickable03.qml"));
932 window->requestActivateWindow();
933 QVERIFY(QTest::qWaitForWindowExposed(window));
934 QVERIFY(window->rootObject() != 0);
936 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
937 QVERIFY(flickable != 0);
939 QSignalSpy vMoveSpy(flickable, SIGNAL(movingVerticallyChanged()));
940 QSignalSpy hMoveSpy(flickable, SIGNAL(movingHorizontallyChanged()));
941 QSignalSpy moveSpy(flickable, SIGNAL(movingChanged()));
942 QSignalSpy hFlickSpy(flickable, SIGNAL(flickingHorizontallyChanged()));
943 QSignalSpy vFlickSpy(flickable, SIGNAL(flickingVerticallyChanged()));
944 QSignalSpy flickSpy(flickable, SIGNAL(flickingChanged()));
946 // flick then press while it is still moving
947 // flicking == false, moving == true;
948 flick(window, QPoint(20,190), QPoint(20, 50), 200);
949 QVERIFY(flickable->verticalVelocity() > 0.0);
950 QVERIFY(flickable->isFlicking());
951 QVERIFY(flickable->isFlickingVertically());
952 QVERIFY(!flickable->isFlickingHorizontally());
953 QVERIFY(flickable->isMoving());
954 QVERIFY(flickable->isMovingVertically());
955 QVERIFY(!flickable->isMovingHorizontally());
956 QCOMPARE(vMoveSpy.count(), 1);
957 QCOMPARE(hMoveSpy.count(), 0);
958 QCOMPARE(moveSpy.count(), 1);
959 QCOMPARE(vFlickSpy.count(), 1);
960 QCOMPARE(hFlickSpy.count(), 0);
961 QCOMPARE(flickSpy.count(), 1);
963 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(20, 50));
964 QTRY_VERIFY(!flickable->isFlicking());
965 QVERIFY(!flickable->isFlickingVertically());
966 QVERIFY(flickable->isMoving());
967 QVERIFY(flickable->isMovingVertically());
969 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(20,50));
970 QVERIFY(!flickable->isFlicking());
971 QVERIFY(!flickable->isFlickingVertically());
972 QTRY_VERIFY(!flickable->isMoving());
973 QVERIFY(!flickable->isMovingVertically());
974 // Stop on a full pixel after user interaction
975 QCOMPARE(flickable->contentX(), (qreal)qRound(flickable->contentX()));
980 void tst_qquickflickable::disabled()
982 QQuickView *window = new QQuickView;
983 window->setSource(testFileUrl("disabled.qml"));
985 window->requestActivateWindow();
986 QVERIFY(window->rootObject() != 0);
988 QQuickFlickable *flick = window->rootObject()->findChild<QQuickFlickable*>("flickable");
991 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(50, 90));
993 QTest::mouseMove(window, QPoint(50, 80));
994 QTest::mouseMove(window, QPoint(50, 70));
995 QTest::mouseMove(window, QPoint(50, 60));
997 QVERIFY(flick->isMoving() == false);
999 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(50, 60));
1001 // verify that mouse clicks on other elements still work (QTBUG-20584)
1002 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(50, 10));
1003 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(50, 10));
1005 QTRY_VERIFY(window->rootObject()->property("clicked").toBool() == true);
1010 void tst_qquickflickable::flickVelocity()
1012 QQuickView *window = new QQuickView;
1013 window->setSource(testFileUrl("flickable03.qml"));
1015 window->requestActivateWindow();
1016 QVERIFY(window->rootObject() != 0);
1018 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
1019 QVERIFY(flickable != 0);
1022 flick(window, QPoint(20,190), QPoint(20, 50), 200);
1023 QVERIFY(flickable->verticalVelocity() > 0.0);
1024 QTRY_VERIFY(flickable->verticalVelocity() == 0.0);
1027 flick(window, QPoint(20,10), QPoint(20, 140), 200);
1028 QVERIFY(flickable->verticalVelocity() < 0.0);
1029 QTRY_VERIFY(flickable->verticalVelocity() == 0.0);
1032 QSKIP("boost doesn't work on OS X");
1037 // Flick multiple times and verify that flick acceleration is applied.
1038 QQuickFlickablePrivate *fp = QQuickFlickablePrivate::get(flickable);
1039 bool boosted = false;
1040 for (int i = 0; i < 6; ++i) {
1041 flick(window, QPoint(20,390), QPoint(20, 50), 100);
1042 boosted |= fp->flickBoost > 1.0;
1046 // Flick in opposite direction -> boost cancelled.
1047 flick(window, QPoint(20,10), QPoint(20, 340), 200);
1048 QTRY_VERIFY(flickable->verticalVelocity() < 0.0);
1049 QVERIFY(fp->flickBoost == 1.0);
1054 void tst_qquickflickable::margins()
1057 QQmlComponent c(&engine, testFileUrl("margins.qml"));
1058 QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
1059 QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(root);
1063 QCOMPARE(obj->contentX(), -40.);
1064 QCOMPARE(obj->contentY(), -20.);
1065 QCOMPARE(obj->contentWidth(), 1600.);
1066 QCOMPARE(obj->contentHeight(), 600.);
1067 QCOMPARE(obj->originX(), 0.);
1068 QCOMPARE(obj->originY(), 0.);
1070 // Reduce left margin
1071 obj->setLeftMargin(30);
1072 QTRY_COMPARE(obj->contentX(), -30.);
1074 // Reduce top margin
1075 obj->setTopMargin(20);
1076 QTRY_COMPARE(obj->contentY(), -20.);
1078 // position to the far right, including margin
1079 obj->setContentX(1600 + 50 - obj->width());
1080 obj->returnToBounds();
1082 QCOMPARE(obj->contentX(), 1600. + 50. - obj->width());
1084 // position beyond the far right, including margin
1085 obj->setContentX(1600 + 50 - obj->width() + 1.);
1086 obj->returnToBounds();
1087 QTRY_COMPARE(obj->contentX(), 1600. + 50. - obj->width());
1089 // Reduce right margin
1090 obj->setRightMargin(40);
1091 QTRY_COMPARE(obj->contentX(), 1600. + 40. - obj->width());
1092 QCOMPARE(obj->contentWidth(), 1600.);
1094 // position to the far bottom, including margin
1095 obj->setContentY(600 + 30 - obj->height());
1096 obj->returnToBounds();
1098 QCOMPARE(obj->contentY(), 600. + 30. - obj->height());
1100 // position beyond the far bottom, including margin
1101 obj->setContentY(600 + 30 - obj->height() + 1.);
1102 obj->returnToBounds();
1103 QTRY_COMPARE(obj->contentY(), 600. + 30. - obj->height());
1105 // Reduce bottom margin
1106 obj->setBottomMargin(20);
1107 QTRY_COMPARE(obj->contentY(), 600. + 20. - obj->height());
1108 QCOMPARE(obj->contentHeight(), 600.);
1113 void tst_qquickflickable::cancelOnMouseGrab()
1115 QQuickView *window = new QQuickView;
1116 window->setSource(testFileUrl("cancel.qml"));
1118 window->requestActivateWindow();
1119 QVERIFY(window->rootObject() != 0);
1121 QQuickFlickable *flickable = qobject_cast<QQuickFlickable*>(window->rootObject());
1122 QVERIFY(flickable != 0);
1124 QTest::mousePress(window, Qt::LeftButton, 0, QPoint(10, 10));
1125 // drag out of bounds
1126 QTest::mouseMove(window, QPoint(50, 50));
1127 QTest::mouseMove(window, QPoint(100, 100));
1128 QTest::mouseMove(window, QPoint(150, 150));
1130 QVERIFY(flickable->contentX() != 0);
1131 QVERIFY(flickable->contentY() != 0);
1132 QVERIFY(flickable->isMoving());
1133 QVERIFY(flickable->isDragging());
1135 // grabbing mouse will cancel flickable interaction.
1136 QQuickItem *item = window->rootObject()->findChild<QQuickItem*>("row");
1139 QTRY_COMPARE(flickable->contentX(), 0.);
1140 QTRY_COMPARE(flickable->contentY(), 0.);
1141 QTRY_VERIFY(!flickable->isMoving());
1142 QTRY_VERIFY(!flickable->isDragging());
1144 QTest::mouseRelease(window, Qt::LeftButton, 0, QPoint(50, 10));
1149 void tst_qquickflickable::clickAndDragWhenTransformed()
1151 QQuickView *view = new QQuickView;
1152 view->setSource(testFileUrl("transformedFlickable.qml"));
1154 view->requestActivateWindow();
1155 QVERIFY(QTest::qWaitForWindowExposed(view));
1156 QVERIFY(view->rootObject() != 0);
1158 QQuickFlickable *flickable = view->rootObject()->findChild<QQuickFlickable*>("flickable");
1159 QVERIFY(flickable != 0);
1161 // click outside child rect
1162 QTest::mousePress(view, Qt::LeftButton, 0, QPoint(190, 190));
1164 QCOMPARE(flickable->property("itemPressed").toBool(), false);
1165 QTest::mouseRelease(view, Qt::LeftButton, 0, QPoint(190, 190));
1167 // click inside child rect
1168 QTest::mousePress(view, Qt::LeftButton, 0, QPoint(200, 200));
1170 QCOMPARE(flickable->property("itemPressed").toBool(), true);
1171 QTest::mouseRelease(view, Qt::LeftButton, 0, QPoint(200, 200));
1173 const int threshold = qApp->styleHints()->startDragDistance();
1175 // drag outside bounds
1176 QTest::mousePress(view, Qt::LeftButton, 0, QPoint(160, 160));
1178 QTest::mouseMove(view, QPoint(160 + threshold * 2, 160));
1179 QTest::mouseMove(view, QPoint(160 + threshold * 3, 160));
1180 QCOMPARE(flickable->isDragging(), false);
1181 QCOMPARE(flickable->property("itemPressed").toBool(), false);
1182 QTest::mouseRelease(view, Qt::LeftButton, 0, QPoint(180, 160));
1184 // drag inside bounds
1185 QTest::mousePress(view, Qt::LeftButton, 0, QPoint(200, 140));
1187 QTest::mouseMove(view, QPoint(200 + threshold * 2, 140));
1188 QTest::mouseMove(view, QPoint(200 + threshold * 3, 140));
1189 QCOMPARE(flickable->isDragging(), true);
1190 QCOMPARE(flickable->property("itemPressed").toBool(), false);
1191 QTest::mouseRelease(view, Qt::LeftButton, 0, QPoint(220, 140));
1196 QTEST_MAIN(tst_qquickflickable)
1198 #include "tst_qquickflickable.moc"