File indexing completed on 2024-04-28 15:31:54
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2021 Steffen Hartleib <steffenhartleib@t-online.de> 0004 0005 SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include <ktwofingerswipe.h> 0009 0010 #include <QTest> 0011 #include <QSignalSpy> 0012 #include <QWidget> 0013 #include <QMainWindow> 0014 0015 class KTwoFingerSwipeTest : public QObject 0016 { 0017 Q_OBJECT 0018 0019 QTouchDevice *mDev = nullptr; 0020 0021 QMainWindow mMainWindow; 0022 QWidget mWidget; 0023 KTwoFingerSwipeRecognizer *mTwoFingerRec = nullptr; 0024 Qt::GestureType mKTwoFingerSwipeGesture; 0025 QPoint mTouchPointPos = QPoint(200, 200); 0026 QSignalSpy *mSpySwipeFinished = nullptr; 0027 QSignalSpy *mSpySwipeStarted = nullptr; 0028 QSignalSpy *mSpySwipeUpdated = nullptr; 0029 QSignalSpy *mSpySwipeCanceled = nullptr; 0030 qreal mAngel = 0.0; 0031 0032 Q_SIGNALS: 0033 void swipeStarted(KTwoFingerSwipe *); 0034 void swipeFinished(KTwoFingerSwipe *); 0035 void swipeUpdated(KTwoFingerSwipe *); 0036 void swipeCanceled(KTwoFingerSwipe *); 0037 0038 protected: 0039 bool eventFilter(QObject *watched, QEvent *e) override 0040 { 0041 if (e->type() == QEvent::Gesture) { 0042 QGestureEvent *gEvent = static_cast<QGestureEvent *>(e); 0043 KTwoFingerSwipe *swipe = static_cast<KTwoFingerSwipe *>(gEvent->gesture(mKTwoFingerSwipeGesture)); 0044 if (swipe) { 0045 const Qt::GestureState state = swipe->state(); 0046 if (state == Qt::GestureFinished) { 0047 Q_EMIT swipeFinished(swipe); 0048 } else if (state == Qt::GestureStarted) { 0049 Q_EMIT swipeStarted(swipe); 0050 } else if (state == Qt::GestureUpdated) { 0051 Q_EMIT swipeUpdated(swipe); 0052 } else if (state == Qt::GestureCanceled) { 0053 Q_EMIT swipeCanceled(swipe); 0054 } 0055 } 0056 e->accept(); 0057 return true; 0058 } 0059 return QObject::eventFilter(watched, e); 0060 } 0061 0062 protected Q_SLOTS: 0063 void slotSwipeFinished (KTwoFingerSwipe *swipe) 0064 { 0065 compareGesturePositions(swipe); 0066 } 0067 void slotSwipeStarted (KTwoFingerSwipe *swipe) 0068 { 0069 compareGesturePositions(swipe); 0070 } 0071 void slotSwipeUpdated (KTwoFingerSwipe *swipe) 0072 { 0073 compareGesturePositions(swipe); 0074 } 0075 void slotSwipeCanceled (KTwoFingerSwipe *swipe) 0076 { 0077 compareGesturePositions(swipe); 0078 } 0079 private: 0080 void compareGesturePositions(KTwoFingerSwipe *swipe) 0081 { 0082 QCOMPARE(swipe->pos(), mTouchPointPos); 0083 QCOMPARE(swipe->screenPos(), mWidget.mapToGlobal(mTouchPointPos)); 0084 QCOMPARE(swipe->hotSpot(), mWidget.mapToGlobal(mTouchPointPos)); 0085 QCOMPARE(swipe->scenePos(), mWidget.mapToGlobal(mTouchPointPos)); 0086 QVERIFY(swipe->hasHotSpot()); 0087 mAngel = swipe->swipeAngle(); 0088 } 0089 0090 void clearSignalSpys() 0091 { 0092 mSpySwipeFinished->clear(); 0093 mSpySwipeCanceled->clear(); 0094 mSpySwipeUpdated->clear(); 0095 mSpySwipeStarted->clear(); 0096 } 0097 0098 private Q_SLOTS: 0099 void initTestCase() 0100 { 0101 mDev = QTest::createTouchDevice(); 0102 0103 mMainWindow.setGeometry(0, 0, 500, 500); 0104 mMainWindow.setCentralWidget(&mWidget); 0105 mMainWindow.show(); 0106 0107 mWidget.installEventFilter(this); 0108 mWidget.setAttribute(Qt::WA_AcceptTouchEvents); 0109 0110 QVERIFY(QTest::qWaitForWindowActive(&mMainWindow)); 0111 QVERIFY(QTest::qWaitForWindowActive(&mWidget)); 0112 0113 mTwoFingerRec = new KTwoFingerSwipeRecognizer(); 0114 QVERIFY(mTwoFingerRec); 0115 0116 mKTwoFingerSwipeGesture = QGestureRecognizer::registerRecognizer(mTwoFingerRec); 0117 QVERIFY(mKTwoFingerSwipeGesture & Qt::CustomGesture); 0118 0119 mWidget.grabGesture(mKTwoFingerSwipeGesture); 0120 0121 connect(this, &KTwoFingerSwipeTest::swipeFinished, this, &KTwoFingerSwipeTest::slotSwipeFinished); 0122 connect(this, &KTwoFingerSwipeTest::swipeStarted, this, &KTwoFingerSwipeTest::slotSwipeStarted); 0123 connect(this, &KTwoFingerSwipeTest::swipeUpdated, this, &KTwoFingerSwipeTest::slotSwipeUpdated); 0124 connect(this, &KTwoFingerSwipeTest::swipeCanceled, this, &KTwoFingerSwipeTest::slotSwipeCanceled); 0125 0126 mSpySwipeFinished = new QSignalSpy(this, &KTwoFingerSwipeTest::swipeFinished); 0127 QVERIFY(mSpySwipeFinished->isValid()); 0128 0129 mSpySwipeStarted = new QSignalSpy(this, &KTwoFingerSwipeTest::swipeStarted); 0130 QVERIFY(mSpySwipeStarted->isValid()); 0131 0132 mSpySwipeUpdated = new QSignalSpy(this, &KTwoFingerSwipeTest::swipeUpdated); 0133 QVERIFY(mSpySwipeUpdated->isValid()); 0134 0135 mSpySwipeCanceled = new QSignalSpy(this, &KTwoFingerSwipeTest::swipeCanceled); 0136 QVERIFY(mSpySwipeCanceled->isValid()); 0137 0138 QTest::qWait(1000); 0139 } 0140 0141 void testChangeTimeAndDistance() 0142 { 0143 QVERIFY(mTwoFingerRec->maxSwipeTime() >= 0); 0144 mTwoFingerRec->setMaxSwipeTime(10); 0145 QCOMPARE(mTwoFingerRec->maxSwipeTime(), 10); 0146 mTwoFingerRec->setMaxSwipeTime(-10); 0147 QCOMPARE(mTwoFingerRec->maxSwipeTime(), 0); 0148 mTwoFingerRec->setMaxSwipeTime(90); 0149 QCOMPARE(mTwoFingerRec->maxSwipeTime(), 90); 0150 0151 QVERIFY(mTwoFingerRec->minSswipeDistance() >= 0); 0152 mTwoFingerRec->setSwipeDistance(10); 0153 QCOMPARE(mTwoFingerRec->minSswipeDistance(), 10); 0154 mTwoFingerRec->setSwipeDistance(-10); 0155 QCOMPARE(mTwoFingerRec->minSswipeDistance(), 0); 0156 mTwoFingerRec->setSwipeDistance(30); 0157 QCOMPARE(mTwoFingerRec->minSswipeDistance(), 30); 0158 } 0159 0160 void testSuccessfulGesture_right() 0161 { 0162 clearSignalSpys(); 0163 0164 const int length = mTwoFingerRec->minSswipeDistance(); 0165 const QPoint swipeDistance = QPoint(length, 0); 0166 0167 QTest::touchEvent(&mWidget, mDev) 0168 .press(0, mTouchPointPos, (QWidget *) nullptr) 0169 .press(1, mTouchPointPos, (QWidget *) nullptr); 0170 0171 QTest::touchEvent(&mWidget, mDev) 0172 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0173 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0174 0175 0176 QTest::touchEvent(&mWidget, mDev) 0177 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0178 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0179 0180 QTest::touchEvent(&mWidget, mDev) 0181 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0182 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0183 0184 QTest::touchEvent(&mWidget, mDev) 0185 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0186 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0187 0188 if (mSpySwipeStarted->count() == 0) { 0189 QVERIFY(mSpySwipeStarted->wait(1000)); 0190 } 0191 0192 QCOMPARE(mSpySwipeStarted->count(), 1); 0193 QCOMPARE(mSpySwipeFinished->count(), 1); 0194 QCOMPARE(mSpySwipeCanceled->count(), 0); 0195 QVERIFY(mSpySwipeUpdated->count() > 0); 0196 QCOMPARE(mAngel, 0); 0197 } 0198 0199 void testSuccessfulGesture_left() 0200 { 0201 clearSignalSpys(); 0202 0203 const int length = mTwoFingerRec->minSswipeDistance(); 0204 const QPoint swipeDistance = QPoint(-length, 0); 0205 0206 QTest::touchEvent(&mWidget, mDev) 0207 .press(0, mTouchPointPos, (QWidget *) nullptr) 0208 .press(1, mTouchPointPos, (QWidget *) nullptr); 0209 0210 QTest::touchEvent(&mWidget, mDev) 0211 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0212 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0213 0214 0215 QTest::touchEvent(&mWidget, mDev) 0216 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0217 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0218 0219 QTest::touchEvent(&mWidget, mDev) 0220 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0221 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0222 0223 QTest::touchEvent(&mWidget, mDev) 0224 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0225 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0226 0227 if (mSpySwipeStarted->count() == 0) { 0228 QVERIFY(mSpySwipeStarted->wait(1000)); 0229 } 0230 0231 QCOMPARE(mSpySwipeStarted->count(), 1); 0232 QCOMPARE(mSpySwipeFinished->count(), 1); 0233 QCOMPARE(mSpySwipeCanceled->count(), 0); 0234 QVERIFY(mSpySwipeUpdated->count() > 0); 0235 QCOMPARE(mAngel, 180); 0236 } 0237 0238 void testSuccessfulGesture_up() 0239 { 0240 clearSignalSpys(); 0241 0242 const int length = mTwoFingerRec->minSswipeDistance(); 0243 const QPoint swipeDistance = QPoint(0, -length); 0244 0245 QTest::touchEvent(&mWidget, mDev) 0246 .press(0, mTouchPointPos, (QWidget *) nullptr) 0247 .press(1, mTouchPointPos, (QWidget *) nullptr); 0248 0249 QTest::touchEvent(&mWidget, mDev) 0250 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0251 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0252 0253 0254 QTest::touchEvent(&mWidget, mDev) 0255 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0256 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0257 0258 QTest::touchEvent(&mWidget, mDev) 0259 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0260 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0261 0262 QTest::touchEvent(&mWidget, mDev) 0263 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0264 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0265 0266 if (mSpySwipeStarted->count() == 0) { 0267 QVERIFY(mSpySwipeStarted->wait(1000)); 0268 } 0269 0270 QCOMPARE(mSpySwipeStarted->count(), 1); 0271 QCOMPARE(mSpySwipeFinished->count(), 1); 0272 QCOMPARE(mSpySwipeCanceled->count(), 0); 0273 QVERIFY(mSpySwipeUpdated->count() > 0); 0274 QCOMPARE(mAngel, 90); 0275 } 0276 0277 void testSuccessfulGesture_down() 0278 { 0279 clearSignalSpys(); 0280 0281 const int length = mTwoFingerRec->minSswipeDistance(); 0282 const QPoint swipeDistance = QPoint(0, length); 0283 0284 QTest::touchEvent(&mWidget, mDev) 0285 .press(0, mTouchPointPos, (QWidget *) nullptr) 0286 .press(1, mTouchPointPos, (QWidget *) nullptr); 0287 0288 QTest::touchEvent(&mWidget, mDev) 0289 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0290 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0291 0292 0293 QTest::touchEvent(&mWidget, mDev) 0294 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0295 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0296 0297 QTest::touchEvent(&mWidget, mDev) 0298 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0299 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0300 0301 QTest::touchEvent(&mWidget, mDev) 0302 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0303 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0304 0305 if (mSpySwipeStarted->count() == 0) { 0306 QVERIFY(mSpySwipeStarted->wait(1000)); 0307 } 0308 0309 QCOMPARE(mSpySwipeStarted->count(), 1); 0310 QCOMPARE(mSpySwipeFinished->count(), 1); 0311 QCOMPARE(mSpySwipeCanceled->count(), 0); 0312 QVERIFY(mSpySwipeUpdated->count() > 0); 0313 QCOMPARE(mAngel, 270); 0314 } 0315 0316 void testFailingGesture_toSlow() 0317 { 0318 clearSignalSpys(); 0319 0320 const int length = mTwoFingerRec->minSswipeDistance() / 3; 0321 const QPoint swipeDistance = QPoint(length, 0); 0322 0323 QTest::touchEvent(&mWidget, mDev) 0324 .press(0, mTouchPointPos, (QWidget *) nullptr) 0325 .press(1, mTouchPointPos, (QWidget *) nullptr); 0326 0327 QTest::touchEvent(&mWidget, mDev) 0328 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0329 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0330 0331 0332 QTest::touchEvent(&mWidget, mDev) 0333 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0334 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0335 0336 QTest::touchEvent(&mWidget, mDev) 0337 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0338 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0339 0340 QTest::touchEvent(&mWidget, mDev) 0341 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0342 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0343 0344 if (mSpySwipeStarted->count() == 0) { 0345 QVERIFY(mSpySwipeStarted->wait(1000)); 0346 } 0347 0348 QCOMPARE(mSpySwipeStarted->count(), 1); 0349 QCOMPARE(mSpySwipeFinished->count(), 0); 0350 QCOMPARE(mSpySwipeCanceled->count(), 1); 0351 QVERIFY(mSpySwipeUpdated->count() > 0); 0352 QCOMPARE(mAngel, 0); 0353 } 0354 0355 0356 void testFailingGesture_threeFingers() 0357 { 0358 clearSignalSpys(); 0359 0360 const int length = mTwoFingerRec->minSswipeDistance(); 0361 const QPoint swipeDistance = QPoint(length, 0); 0362 0363 QTest::touchEvent(&mWidget, mDev) 0364 .press(0, mTouchPointPos, (QWidget *) nullptr) 0365 .press(1, mTouchPointPos, (QWidget *) nullptr); 0366 0367 QTest::touchEvent(&mWidget, mDev) 0368 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr) 0369 .move(1, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0370 0371 QTest::touchEvent(&mWidget, mDev) 0372 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0373 .move(1, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr) 0374 .press(2, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0375 0376 QTest::touchEvent(&mWidget, mDev) 0377 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0378 .move(1, mTouchPointPos + swipeDistance, (QWidget *) nullptr) 0379 .move(2, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0380 0381 QTest::touchEvent(&mWidget, mDev) 0382 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0383 .release(1, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr) 0384 .release(2, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0385 0386 if (mSpySwipeCanceled->count() == 0) { 0387 QVERIFY(mSpySwipeCanceled->wait(1000)); 0388 } 0389 0390 QCOMPARE(mSpySwipeStarted->count(), 1); 0391 QCOMPARE(mSpySwipeFinished->count(), 0); 0392 QCOMPARE(mSpySwipeCanceled->count(), 1); 0393 QVERIFY(mSpySwipeUpdated->count() >= 0); 0394 QCOMPARE(mAngel, 0); 0395 } 0396 0397 void testFailingGesture_oneFinger() 0398 { 0399 clearSignalSpys(); 0400 0401 const int length = mTwoFingerRec->minSswipeDistance(); 0402 const QPoint swipeDistance = QPoint(length, 0); 0403 0404 QTest::touchEvent(&mWidget, mDev) 0405 .press(0, mTouchPointPos, (QWidget *) nullptr); 0406 0407 QTest::touchEvent(&mWidget, mDev) 0408 .move(0, mTouchPointPos + swipeDistance / 3, (QWidget *) nullptr); 0409 0410 QTest::touchEvent(&mWidget, mDev) 0411 .move(0, mTouchPointPos + swipeDistance / 2, (QWidget *) nullptr); 0412 0413 QTest::touchEvent(&mWidget, mDev) 0414 .move(0, mTouchPointPos + swipeDistance, (QWidget *) nullptr); 0415 0416 QTest::touchEvent(&mWidget, mDev) 0417 .release(0, mTouchPointPos + swipeDistance * 1.5, (QWidget *) nullptr); 0418 0419 QCOMPARE(mSpySwipeStarted->count(), 0); 0420 QCOMPARE(mSpySwipeFinished->count(), 0); 0421 QCOMPARE(mSpySwipeCanceled->count(), 0); 0422 QVERIFY(mSpySwipeUpdated->count() == 0); 0423 } 0424 0425 void testSomeRandomSwipes() 0426 { 0427 for (int i = 0; i < 50; ++i) { 0428 const int x = rand() % 200 + 150; 0429 const int y = rand() % 200 + 150; 0430 mTouchPointPos = QPoint(x, y); 0431 testSuccessfulGesture_right(); 0432 testSuccessfulGesture_up(); 0433 } 0434 } 0435 }; 0436 0437 QTEST_MAIN(KTwoFingerSwipeTest) 0438 0439 #include "ktwofingerswipetest.moc"