2
* Copyright (C) 2016 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/>.
17
#include "GestureTest.h"
19
#include <TouchGestureArea.h>
26
QPointF calculateInitialTouchPos(TouchGestureArea *edgeDragArea)
28
QPointF localCenter(edgeDragArea->width() / 2., edgeDragArea->height() / 2.);
29
return edgeDragArea->mapToScene(localCenter);
33
class tst_TouchGestureArea: public GestureTest
37
tst_TouchGestureArea();
39
void init() override; // called right before each and every test function is executed
41
void minimumTouchPoints();
42
void maximumTouchPoints();
43
void minimumAndMaximumTouchPoints();
44
void rejectGestureAfterRecognitionPeriod();
45
void releaseAndPressRecognisedGestureDoesNotRejectForPeriod();
46
void topAreaReceivesOwnershipFirstWithEqualPoints();
47
void topAreaReceivesOwnershipFirstWithMorePoints();
50
void initGestureComponent(TouchGestureArea *area);
52
QQuickItem *m_blueRect;
53
TouchGestureArea *m_gestureBottom;
54
TouchGestureArea *m_gestureMiddle;
55
TouchGestureArea *m_gestureTop;
58
tst_TouchGestureArea::tst_TouchGestureArea()
59
: GestureTest(QStringLiteral("tst_TouchGestureArea.qml"))
63
inline void tst_TouchGestureArea::initGestureComponent(TouchGestureArea* area)
65
area->setRecognitionTimer(m_fakeTimerFactory->createTimer(area));
66
area->setMinimumTouchPoints(1);
67
area->setMaximumTouchPoints(INT_MAX);
68
area->setRecognitionPeriod(50);
69
area->setReleaseRejectPeriod(100);
70
// start tests with area disabled (enable as desired)
71
area->setEnabled(false);
74
void tst_TouchGestureArea::init()
78
m_blueRect = m_view->rootObject()->findChild<QQuickItem*>("blueRect");
79
Q_ASSERT(m_blueRect != nullptr);
82
m_view->rootObject()->findChild<TouchGestureArea*>("touchGestureAreaBottom");
83
Q_ASSERT(m_gestureBottom != nullptr);
86
m_view->rootObject()->findChild<TouchGestureArea*>("touchGestureAreaMiddle");
87
Q_ASSERT(m_gestureMiddle != nullptr);
90
m_view->rootObject()->findChild<TouchGestureArea*>("touchGestureAreaTop");
91
Q_ASSERT(m_gestureTop != nullptr);
93
initGestureComponent(m_gestureBottom);
94
initGestureComponent(m_gestureMiddle);
95
initGestureComponent(m_gestureTop);
98
void tst_TouchGestureArea::minimumTouchPoints()
100
m_gestureBottom->setEnabled(true);
101
m_gestureBottom->setMinimumTouchPoints(4);
103
QPointF touchPoint = calculateInitialTouchPos(m_gestureBottom);
105
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::WaitingForTouch);
106
QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
107
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Undecided);
108
QTest::touchEvent(m_view, m_device).stationary(0)
109
.press(1, touchPoint.toPoint());
110
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Undecided);
111
QTest::touchEvent(m_view, m_device).stationary(0)
113
.press(2, touchPoint.toPoint());
114
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Undecided);
115
QTest::touchEvent(m_view, m_device).stationary(0)
118
.press(3, touchPoint.toPoint());
119
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Recognized);
120
// test minimum overflow
121
QTest::touchEvent(m_view, m_device).stationary(0)
125
.press(4, touchPoint.toPoint());
126
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Recognized);
129
void tst_TouchGestureArea::maximumTouchPoints()
131
m_gestureBottom->setEnabled(true);
132
m_gestureBottom->setMaximumTouchPoints(2);
134
QPointF touchPoint = calculateInitialTouchPos(m_gestureBottom);
136
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::WaitingForTouch);
137
QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
138
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Recognized);
139
QTest::touchEvent(m_view, m_device).stationary(0)
140
.press(1, touchPoint.toPoint());
141
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Recognized);
143
// test maximum overflow
144
QTest::touchEvent(m_view, m_device).stationary(0)
146
.press(2, touchPoint.toPoint());
147
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Rejected);
148
// test still rejected
149
QTest::touchEvent(m_view, m_device).stationary(0)
151
.press(3, touchPoint.toPoint());
152
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Rejected);
155
void tst_TouchGestureArea::minimumAndMaximumTouchPoints()
157
m_gestureBottom->setEnabled(true);
158
m_gestureBottom->setMinimumTouchPoints(2);
159
m_gestureBottom->setMaximumTouchPoints(2);
161
QPointF touchPoint = calculateInitialTouchPos(m_gestureBottom);
163
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::WaitingForTouch);
164
QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
165
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Undecided);
166
QTest::touchEvent(m_view, m_device).stationary(0)
167
.press(1, touchPoint.toPoint());
168
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Recognized);
170
// test maximum overflow
171
QTest::touchEvent(m_view, m_device).stationary(0)
173
.press(2, touchPoint.toPoint());
174
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Rejected);
177
void tst_TouchGestureArea::rejectGestureAfterRecognitionPeriod()
179
m_gestureBottom->setEnabled(true);
180
m_gestureBottom->setMinimumTouchPoints(2);
181
m_gestureBottom->setMaximumTouchPoints(2);
183
QPointF touchPoint = calculateInitialTouchPos(m_gestureBottom);
185
QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
186
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Undecided); // Recognition period is 50.
188
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Undecided);
190
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Rejected);
193
void tst_TouchGestureArea::releaseAndPressRecognisedGestureDoesNotRejectForPeriod()
195
m_gestureBottom->setEnabled(true);
196
m_gestureBottom->setMinimumTouchPoints(2);
197
m_gestureBottom->setMaximumTouchPoints(2);
199
bool wasRejected = false;
200
connect(m_gestureBottom, &TouchGestureArea::statusChanged,
201
this, [&wasRejected](int status) {
202
if (status == TouchGestureArea::Rejected) wasRejected = true;
205
QPointF touchPoint = calculateInitialTouchPos(m_gestureBottom);
207
QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint())
208
.press(1, touchPoint.toPoint());
209
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Recognized);
211
QTest::touchEvent(m_view, m_device).stationary(0)
212
.release(1, touchPoint.toPoint()); // Release period is 100.
213
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Recognized);
215
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Recognized);
216
QCOMPARE(wasRejected, false);
218
QCOMPARE(wasRejected, false);
219
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Recognized);
221
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::Rejected);
224
void tst_TouchGestureArea::topAreaReceivesOwnershipFirstWithEqualPoints()
226
m_gestureBottom->setEnabled(true);
227
m_gestureMiddle->setEnabled(true);
228
m_gestureTop->setEnabled(true);
230
m_gestureBottom->setMinimumTouchPoints(1);
231
m_gestureMiddle->setMinimumTouchPoints(1);
232
m_gestureTop->setMinimumTouchPoints(1);
234
QPointF touchPoint = calculateInitialTouchPos(m_gestureBottom);
236
QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
238
QCOMPARE((int)m_gestureTop->status(), (int)TouchGestureArea::Recognized);
239
// Lower items will not recieve the touch events
240
QCOMPARE((int)m_gestureMiddle->status(), (int)TouchGestureArea::WaitingForTouch);
241
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::WaitingForTouch);
244
void tst_TouchGestureArea::topAreaReceivesOwnershipFirstWithMorePoints()
246
m_gestureBottom->setEnabled(true);
247
m_gestureMiddle->setEnabled(true);
248
m_gestureTop->setEnabled(true);
250
m_gestureBottom->setMinimumTouchPoints(1);
251
m_gestureMiddle->setMinimumTouchPoints(1);
252
m_gestureTop->setMinimumTouchPoints(2);
254
QPointF touchPoint = calculateInitialTouchPos(m_gestureBottom);
256
QTest::touchEvent(m_view, m_device).press(0, touchPoint.toPoint());
257
QCOMPARE((int)m_gestureTop->status(), (int)TouchGestureArea::Undecided);
258
QCOMPARE((int)m_gestureMiddle->status(), (int)TouchGestureArea::Undecided);
259
// The middle item will accept the events; so the bottom item will not get a chance.
260
QCOMPARE((int)m_gestureBottom->status(), (int)TouchGestureArea::WaitingForTouch);
262
QTest::touchEvent(m_view, m_device).stationary(0)
263
.press(1, touchPoint.toPoint());
264
QCOMPARE((int)m_gestureTop->status(), (int)TouchGestureArea::Recognized);
265
QCOMPARE((int)m_gestureMiddle->status(), (int)TouchGestureArea::Rejected);
268
QTEST_MAIN(tst_TouchGestureArea)
270
#include "tst_TouchGestureArea.moc"