2 * Copyright (C) 2013 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18#include <QtTest/QtTest>
19#include <QtCore/QObject>
20#include <qpa/qwindowsysteminterface.h>
21#include <QtQuick/QQuickView>
22#include <QtQml/QQmlEngine>
24#include <DirectionalDragArea.h>
26class FakeTimer : public UbuntuGestures::AbstractTimer
30 FakeTimer(QObject *parent = 0)
31 : UbuntuGestures::AbstractTimer(parent)
34 virtual int interval() const { return m_duration; }
35 virtual void setInterval(int msecs) { m_duration = msecs; }
40class FakeTimeSource : public UbuntuGestures::TimeSource
43 FakeTimeSource() { m_msecsSinceReference = 0; }
44 virtual qint64 msecsSinceReference() {return m_msecsSinceReference;}
45 qint64 m_msecsSinceReference;
48class tst_DragHandle: public QObject
52 tst_DragHandle() : m_device(0) { }
54 void initTestCase(); // will be called before the first test function is executed
55 void cleanupTestCase(); // will be called after the last test function was executed.
57 void init(); // called right before each and every test function is executed
58 void cleanup(); // called right after each and every test function is executed
60 void dragThreshold_horizontal();
61 void dragThreshold_vertical();
64 void flickAndHold(DirectionalDragArea *dragHandle, qreal distance);
65 DirectionalDragArea *fetchAndSetupDragHandle(const char *objectName);
66 qreal fetchDragThreshold(DirectionalDragArea *dragHandle);
67 void tryCompare(std::function<qreal ()> actualFunc, qreal expectedValue);
69 QQuickView *createView();
71 QTouchDevice *m_device;
72 FakeTimer *m_fakeTimer;
73 FakeTimeSource *m_fakeTimeSource;
77void tst_DragHandle::initTestCase()
80 m_device = new QTouchDevice;
81 m_device->setType(QTouchDevice::TouchScreen);
82 QWindowSystemInterface::registerTouchDevice(m_device);
88void tst_DragHandle::cleanupTestCase()
92void tst_DragHandle::init()
94 m_view = createView();
95 m_view->setSource(QUrl::fromLocalFile(TEST_DIR"/tst_DragHandle.qml"));
97 QVERIFY(QTest::qWaitForWindowExposed(m_view));
98 QVERIFY(m_view->rootObject() != 0);
99 qApp->processEvents();
101 m_fakeTimer = new FakeTimer;
102 m_fakeTimeSource = new FakeTimeSource;
105void tst_DragHandle::cleanup()
113 delete m_fakeTimeSource;
114 m_fakeTimeSource = 0;
117QQuickView *tst_DragHandle::createView()
119 QQuickView *window = new QQuickView(0);
120 window->setResizeMode(QQuickView::SizeRootObjectToView);
121 window->resize(600, 600);
122 window->engine()->addImportPath(QLatin1String(UBUNTU_GESTURES_PLUGIN_DIR));
123 window->engine()->addImportPath(QLatin1String(TEST_DIR));
128void tst_DragHandle::tryCompare(std::function<qreal ()> actualFunc,
132 while (actualFunc() != expectedValue && waitCount < 100) {
136 QCOMPARE(actualFunc(), expectedValue);
140QPointF calculateDirectionVector(DirectionalDragArea *edgeDragArea)
143 switch (edgeDragArea->direction()) {
144 case Direction::Upwards:
145 return QPointF(0, -1);
146 case Direction::Downwards:
147 return QPointF(0, 1);
148 case Direction::Leftwards:
149 return QPointF(-1, 0);
150 default: // Direction::Rightwards:
151 return QPointF(1, 0);
156void tst_DragHandle::flickAndHold(DirectionalDragArea *dragHandle,
159 QPointF initialTouchPos = dragHandle->mapToScene(
160 QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
161 QPointF touchPoint = initialTouchPos;
163 qint64 flickTimeMs = 500;
164 qint64 timeStep = flickTimeMs / numSteps;
166 QPointF dragDirectionVector = calculateDirectionVector(dragHandle);
167 QPointF touchMovement = dragDirectionVector * (distance / (qreal)numSteps);
169 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
171 for (int i = 0; i < numSteps; ++i) {
172 touchPoint += touchMovement;
173 m_fakeTimeSource->m_msecsSinceReference += timeStep;
174 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
177 // Wait for quite a bit before finally releasing to make a very low flick/release
179 m_fakeTimeSource->m_msecsSinceReference += 5000;
180 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
183DirectionalDragArea *tst_DragHandle::fetchAndSetupDragHandle(const char *objectName)
185 DirectionalDragArea *dragHandle =
186 m_view->rootObject()->findChild<DirectionalDragArea*>(objectName);
187 Q_ASSERT(dragHandle != 0);
188 dragHandle->setRecognitionTimer(m_fakeTimer);
189 dragHandle->setTimeSource(m_fakeTimeSource);
191 AxisVelocityCalculator *edgeDragEvaluator =
192 dragHandle->findChild<AxisVelocityCalculator*>("edgeDragEvaluator");
193 Q_ASSERT(edgeDragEvaluator != 0);
194 edgeDragEvaluator->setTimeSource(m_fakeTimeSource);
199qreal tst_DragHandle::fetchDragThreshold(DirectionalDragArea *dragHandle)
201 AxisVelocityCalculator *edgeDragEvaluator =
202 dragHandle->findChild<AxisVelocityCalculator*>("edgeDragEvaluator");
203 Q_ASSERT(edgeDragEvaluator != 0);
205 return edgeDragEvaluator->property("dragThreshold").toReal();
209 Checks that ending a low-speed drag before dragThreshold results in the
210 Showable getting back to its original position, whereas ending after dragThreshold
211 results in Showable continuing until reaching its new states (shown or hidden)
213void tst_DragHandle::dragThreshold_horizontal()
215 DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("rightwardsDragHandle");
217 qreal dragThreshold = fetchDragThreshold(dragHandle);
219 // end before the threshold
220 flickAndHold(dragHandle, dragThreshold * 0.7);
223 QQuickItem *parentItem = dragHandle->parentItem();
224 tryCompare([&](){ return parentItem->x(); }, -parentItem->width());
225 QCOMPARE(parentItem->property("shown").toBool(), false);
227 // end after the threshold
228 flickAndHold(dragHandle, dragThreshold * 1.2);
230 // should keep going until completion
231 tryCompare([&](){ return parentItem->x(); }, 0);
232 QCOMPARE(parentItem->property("shown").toBool(), true);
234 dragHandle = fetchAndSetupDragHandle("leftwardsDragHandle");
236 dragThreshold = fetchDragThreshold(dragHandle);
238 // end before the threshold
239 flickAndHold(dragHandle, dragThreshold * 0.7);
242 tryCompare([&](){ return parentItem->x(); }, 0);
243 QCOMPARE(parentItem->property("shown").toBool(), true);
245 // end after the threshold
246 flickAndHold(dragHandle, dragThreshold * 1.2);
248 // should keep going until completion
249 tryCompare([&](){ return parentItem->x(); }, -parentItem->width());
250 QCOMPARE(parentItem->property("shown").toBool(), false);
253void tst_DragHandle::dragThreshold_vertical()
255 DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
257 qreal dragThreshold = fetchDragThreshold(dragHandle);
259 // end before the threshold
260 flickAndHold(dragHandle, dragThreshold * 0.7);
263 QQuickItem *parentItem = dragHandle->parentItem();
264 tryCompare([&](){ return parentItem->y(); }, -parentItem->height());
265 QCOMPARE(parentItem->property("shown").toBool(), false);
267 // end after the threshold
268 flickAndHold(dragHandle, dragThreshold * 1.2);
270 // should keep going until completion
271 tryCompare([&](){ return parentItem->y(); }, 0);
272 QCOMPARE(parentItem->property("shown").toBool(), true);
274 dragHandle = fetchAndSetupDragHandle("upwardsDragHandle");
276 dragThreshold = fetchDragThreshold(dragHandle);
278 // end before the threshold
279 flickAndHold(dragHandle, dragThreshold * 0.7);
282 tryCompare([&](){ return parentItem->y(); }, 0);
283 QCOMPARE(parentItem->property("shown").toBool(), true);
285 // end after the threshold
286 flickAndHold(dragHandle, dragThreshold * 1.2);
288 // should keep going until completion
289 tryCompare([&](){ return parentItem->y(); }, -parentItem->height());
290 QCOMPARE(parentItem->property("shown").toBool(), false);
293QTEST_MAIN(tst_DragHandle)
295#include "tst_DragHandle.moc"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list