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 qint64 msecsSinceReference() override {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();
62 void stretch_horizontal();
63 void stretch_vertical();
64 void hintingAnimation();
67 void flickAndHold(DirectionalDragArea *dragHandle, qreal distance);
68 DirectionalDragArea *fetchAndSetupDragHandle(const char *objectName);
69 qreal fetchDragThreshold(DirectionalDragArea *dragHandle);
70 void tryCompare(std::function<qreal ()> actualFunc, qreal expectedValue);
72 QQuickView *createView();
74 QTouchDevice *m_device;
75 FakeTimer *m_fakeTimer;
76 QSharedPointer<FakeTimeSource> m_fakeTimeSource;
80void tst_DragHandle::initTestCase()
83 m_device = new QTouchDevice;
84 m_device->setType(QTouchDevice::TouchScreen);
85 QWindowSystemInterface::registerTouchDevice(m_device);
91void tst_DragHandle::cleanupTestCase()
95void tst_DragHandle::init()
97 m_view = createView();
98 m_view->setSource(QUrl::fromLocalFile(TEST_DIR"/tst_DragHandle.qml"));
100 QVERIFY(QTest::qWaitForWindowExposed(m_view));
101 QVERIFY(m_view->rootObject() != 0);
102 qApp->processEvents();
104 m_fakeTimer = new FakeTimer;
105 m_fakeTimeSource.reset(new FakeTimeSource);
108void tst_DragHandle::cleanup()
116 m_fakeTimeSource.reset();
119QQuickView *tst_DragHandle::createView()
121 QQuickView *window = new QQuickView(0);
122 window->setResizeMode(QQuickView::SizeRootObjectToView);
123 window->resize(600, 600);
124 window->engine()->addImportPath(QLatin1String(UBUNTU_GESTURES_PLUGIN_DIR));
125 window->engine()->addImportPath(QLatin1String(TEST_DIR));
130void tst_DragHandle::tryCompare(std::function<qreal ()> actualFunc,
134 while (actualFunc() != expectedValue && waitCount < 100) {
138 QCOMPARE(actualFunc(), expectedValue);
142QPointF calculateDirectionVector(DirectionalDragArea *edgeDragArea)
145 switch (edgeDragArea->direction()) {
146 case Direction::Upwards:
147 return QPointF(0, -1);
148 case Direction::Downwards:
149 return QPointF(0, 1);
150 case Direction::Leftwards:
151 return QPointF(-1, 0);
152 default: // Direction::Rightwards:
153 return QPointF(1, 0);
158void tst_DragHandle::flickAndHold(DirectionalDragArea *dragHandle,
161 QPointF initialTouchPos = dragHandle->mapToScene(
162 QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
163 QPointF touchPoint = initialTouchPos;
165 qint64 flickTimeMs = 500;
166 qint64 timeStep = flickTimeMs / numSteps;
168 QPointF dragDirectionVector = calculateDirectionVector(dragHandle);
169 QPointF touchMovement = dragDirectionVector * (distance / (qreal)numSteps);
171 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
173 for (int i = 0; i < numSteps; ++i) {
174 touchPoint += touchMovement;
175 m_fakeTimeSource->m_msecsSinceReference += timeStep;
176 QTest::touchEvent(m_view, m_device).move(0, touchPoint.toPoint());
179 // Wait for quite a bit before finally releasing to make a very low flick/release
181 m_fakeTimeSource->m_msecsSinceReference += 5000;
182 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
185DirectionalDragArea *tst_DragHandle::fetchAndSetupDragHandle(const char *objectName)
187 DirectionalDragArea *dragHandle =
188 m_view->rootObject()->findChild<DirectionalDragArea*>(objectName);
189 Q_ASSERT(dragHandle != 0);
190 dragHandle->setRecognitionTimer(m_fakeTimer);
191 dragHandle->setTimeSource(m_fakeTimeSource);
193 AxisVelocityCalculator *edgeDragEvaluator =
194 dragHandle->findChild<AxisVelocityCalculator*>("edgeDragEvaluator");
195 Q_ASSERT(edgeDragEvaluator != 0);
196 edgeDragEvaluator->setTimeSource(m_fakeTimeSource);
201qreal tst_DragHandle::fetchDragThreshold(DirectionalDragArea *dragHandle)
203 AxisVelocityCalculator *edgeDragEvaluator =
204 dragHandle->findChild<AxisVelocityCalculator*>("edgeDragEvaluator");
205 Q_ASSERT(edgeDragEvaluator != 0);
207 return edgeDragEvaluator->property("dragThreshold").toReal();
211 Checks that ending a low-speed drag before dragThreshold results in the
212 Showable getting back to its original position, whereas ending after dragThreshold
213 results in Showable continuing until reaching its new states (shown or hidden)
215void tst_DragHandle::dragThreshold_horizontal()
217 DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("rightwardsDragHandle");
219 qreal dragThreshold = fetchDragThreshold(dragHandle);
221 // end before the threshold
222 flickAndHold(dragHandle, dragThreshold * 0.7);
225 QQuickItem *parentItem = dragHandle->parentItem();
226 tryCompare([&](){ return parentItem->x(); }, -parentItem->width());
227 QCOMPARE(parentItem->property("shown").toBool(), false);
229 // end after the threshold
230 flickAndHold(dragHandle, dragThreshold * 1.2);
232 // should keep going until completion
233 tryCompare([&](){ return parentItem->x(); }, 0);
234 QCOMPARE(parentItem->property("shown").toBool(), true);
236 dragHandle = fetchAndSetupDragHandle("leftwardsDragHandle");
238 dragThreshold = fetchDragThreshold(dragHandle);
240 // end before the threshold
241 flickAndHold(dragHandle, dragThreshold * 0.7);
244 tryCompare([&](){ return parentItem->x(); }, 0);
245 QCOMPARE(parentItem->property("shown").toBool(), true);
247 // end after the threshold
248 flickAndHold(dragHandle, dragThreshold * 1.2);
250 // should keep going until completion
251 tryCompare([&](){ return parentItem->x(); }, -parentItem->width());
252 QCOMPARE(parentItem->property("shown").toBool(), false);
255void tst_DragHandle::dragThreshold_vertical()
257 DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
259 qreal dragThreshold = fetchDragThreshold(dragHandle);
261 // end before the threshold
262 flickAndHold(dragHandle, dragThreshold * 0.7);
265 QQuickItem *parentItem = dragHandle->parentItem();
266 tryCompare([&](){ return parentItem->y(); }, -parentItem->height());
267 QCOMPARE(parentItem->property("shown").toBool(), false);
269 // end after the threshold
270 flickAndHold(dragHandle, dragThreshold * 1.2);
272 // should keep going until completion
273 tryCompare([&](){ return parentItem->y(); }, 0);
274 QCOMPARE(parentItem->property("shown").toBool(), true);
276 dragHandle = fetchAndSetupDragHandle("upwardsDragHandle");
278 dragThreshold = fetchDragThreshold(dragHandle);
280 // end before the threshold
281 flickAndHold(dragHandle, dragThreshold * 0.7);
284 tryCompare([&](){ return parentItem->y(); }, 0);
285 QCOMPARE(parentItem->property("shown").toBool(), true);
287 // end after the threshold
288 flickAndHold(dragHandle, dragThreshold * 1.2);
290 // should keep going until completion
291 tryCompare([&](){ return parentItem->y(); }, -parentItem->height());
292 QCOMPARE(parentItem->property("shown").toBool(), false);
296 Checks that when the stretch property is true, dragging the DragHandle increases
297 the width or height (depending on its direction) of its parent Showable
299void tst_DragHandle::stretch_horizontal()
301 DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("rightwardsDragHandle");
302 qreal totalDragDistance = dragHandle->property("maxTotalDragDistance").toReal();
303 QQuickItem *parentItem = dragHandle->parentItem();
305 // enable strech mode
306 m_view->rootObject()->setProperty("stretch", QVariant(true));
308 QCOMPARE(parentItem->width(), 0.0);
311 flickAndHold(dragHandle, totalDragDistance);
313 // should keep going until completion
314 // Parent item should now have its full height
315 tryCompare([&](){ return parentItem->width(); }, totalDragDistance);
316 QCOMPARE(parentItem->property("shown").toBool(), true);
318 dragHandle = fetchAndSetupDragHandle("leftwardsDragHandle");
321 flickAndHold(dragHandle, totalDragDistance);
323 // should keep going until completion
324 // Parent item should now have its full height
325 tryCompare([&](){ return parentItem->width(); }, 0.0);
326 QCOMPARE(parentItem->property("shown").toBool(), false);
329void tst_DragHandle::stretch_vertical()
331 DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
332 qreal totalDragDistance = dragHandle->property("maxTotalDragDistance").toReal();
333 QQuickItem *parentItem = dragHandle->parentItem();
335 // enable strech mode
336 m_view->rootObject()->setProperty("stretch", QVariant(true));
338 QCOMPARE(parentItem->height(), 0.0);
341 flickAndHold(dragHandle, totalDragDistance);
343 // should keep going until completion
344 // Parent item should now have its full height
345 tryCompare([&](){ return parentItem->height(); }, totalDragDistance);
346 QCOMPARE(parentItem->property("shown").toBool(), true);
348 dragHandle = fetchAndSetupDragHandle("upwardsDragHandle");
351 flickAndHold(dragHandle, totalDragDistance);
353 // should keep going until completion
354 // Parent item should now have its full height
355 tryCompare([&](){ return parentItem->height(); }, 0.0);
356 QCOMPARE(parentItem->property("shown").toBool(), false);
360 Set DragHandle.hintDisplacement to a value bigger than zero.
361 Then lay a finger on the DragHandle.
362 The expected behavior is that it will move or strech its parent Showable
363 by hintDisplacement pixels.
365void tst_DragHandle::hintingAnimation()
367 DirectionalDragArea *dragHandle = fetchAndSetupDragHandle("downwardsDragHandle");
368 QQuickItem *parentItem = dragHandle->parentItem();
369 qreal hintDisplacement = 100.0;
371 // enable hinting animations and stretch mode
372 m_view->rootObject()->setProperty("hintDisplacement", QVariant(hintDisplacement));
373 m_view->rootObject()->setProperty("stretch", QVariant(true));
375 QCOMPARE(parentItem->height(), 0.0);
377 QPointF initialTouchPos = dragHandle->mapToScene(
378 QPointF(dragHandle->width() / 2.0, dragHandle->height() / 2.0));
379 QPointF touchPoint = initialTouchPos;
381 // Pressing causes the Showable to be stretched by hintDisplacement pixels
382 QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
383 tryCompare([&](){ return parentItem->height(); }, hintDisplacement);
385 // Releasing causes the Showable to shrink back to 0 pixels.
386 QTest::touchEvent(m_view, m_device).release(0, touchPoint.toPoint());
387 tryCompare([&](){ return parentItem->height(); }, 0.0);
389 QCOMPARE(parentItem->property("shown").toBool(), false);
392QTEST_MAIN(tst_DragHandle)
394#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