File indexing completed on 2025-02-02 14:20:12
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 // Self 0009 #include "ktwofingerswipe.h" 0010 0011 // Qt 0012 #include <QGraphicsWidget> 0013 #include <QLineF> 0014 #include <QTouchEvent> 0015 #include <QDebug> 0016 class KTwoFingerSwipeRecognizerPrivate 0017 { 0018 public: 0019 KTwoFingerSwipeRecognizerPrivate(KTwoFingerSwipeRecognizer *parent) 0020 : q(parent) 0021 { 0022 } 0023 KTwoFingerSwipeRecognizer *const q; 0024 qint64 mTouchBeginnTimestamp = 0; 0025 bool mGestureAlreadyFinished = false; 0026 int mMaxSwipeTime = 90; 0027 int mMinSwipeDistance = 30; 0028 }; 0029 0030 KTwoFingerSwipeRecognizer::KTwoFingerSwipeRecognizer() 0031 : QGestureRecognizer() 0032 , d(new KTwoFingerSwipeRecognizerPrivate(this)) 0033 { 0034 } 0035 0036 KTwoFingerSwipeRecognizer::~KTwoFingerSwipeRecognizer() 0037 { 0038 } 0039 0040 QGesture* KTwoFingerSwipeRecognizer::create(QObject *target) 0041 { 0042 Q_UNUSED(target); 0043 return static_cast<QGesture *>(new KTwoFingerSwipe()); 0044 } 0045 0046 QGestureRecognizer::Result KTwoFingerSwipeRecognizer::recognize(QGesture *gesture, QObject *watched, QEvent *event) 0047 { 0048 Q_UNUSED(watched) 0049 0050 KTwoFingerSwipe *kTwoFingerSwipe = static_cast<KTwoFingerSwipe *>(gesture); 0051 const QTouchEvent *touchEvent = static_cast<const QTouchEvent *>(event); 0052 0053 switch (event->type()) { 0054 case QEvent::TouchBegin: { 0055 d->mTouchBeginnTimestamp = touchEvent->timestamp(); 0056 d->mGestureAlreadyFinished = false; 0057 const QTouchEvent::TouchPoint tp = touchEvent->touchPoints().first(); 0058 kTwoFingerSwipe->setHotSpot(tp.startScreenPos()); 0059 kTwoFingerSwipe->setPos(tp.startPos()); 0060 kTwoFingerSwipe->setScreenPos(tp.startScreenPos()); 0061 kTwoFingerSwipe->setScenePos(tp.startScenePos()); 0062 kTwoFingerSwipe->setSwipeAngle(0.0); 0063 return MayBeGesture; 0064 } 0065 0066 case QEvent::TouchUpdate: { 0067 // The gesture was already canceled or finished, so we will ignore this event. 0068 if (d->mGestureAlreadyFinished) { 0069 return Ignore; 0070 } 0071 0072 const qint64 now = touchEvent->timestamp(); 0073 const qint64 elapsedTime = now - d->mTouchBeginnTimestamp; 0074 const QLineF ql = QLineF(touchEvent->touchPoints().first().startPos(), touchEvent->touchPoints().first().pos()); 0075 const qreal length = ql.length(); 0076 const int touchPointSize = touchEvent->touchPoints().size(); 0077 0078 kTwoFingerSwipe->setSwipeAngle(ql.angle()); 0079 0080 if (touchPointSize > 2) { 0081 d->mGestureAlreadyFinished = true; 0082 return CancelGesture; 0083 } 0084 0085 if (touchPointSize == 2) { 0086 if (elapsedTime > d->mMaxSwipeTime) { 0087 d->mGestureAlreadyFinished = true; 0088 return CancelGesture; 0089 } 0090 if (length >= d->mMinSwipeDistance && elapsedTime <= d->mMaxSwipeTime && !d->mGestureAlreadyFinished) { 0091 d->mGestureAlreadyFinished = true; 0092 return FinishGesture; 0093 } else if (elapsedTime <= d->mMaxSwipeTime && !d->mGestureAlreadyFinished) { 0094 return TriggerGesture; 0095 } 0096 } 0097 break; 0098 } 0099 0100 case QEvent::TouchEnd: { 0101 if (gesture->state() == Qt::GestureUpdated || gesture->state() == Qt::GestureStarted) { 0102 if (!d->mGestureAlreadyFinished) { 0103 return CancelGesture; 0104 } 0105 } 0106 break; 0107 } 0108 0109 default: 0110 return Ignore; 0111 } 0112 return Ignore; 0113 } 0114 0115 int KTwoFingerSwipeRecognizer::maxSwipeTime() const 0116 { 0117 return d->mMaxSwipeTime; 0118 } 0119 0120 void KTwoFingerSwipeRecognizer::setMaxSwipeTime(int i) 0121 { 0122 if (i < 0) { 0123 i = 0; 0124 } 0125 0126 d->mMaxSwipeTime = i; 0127 } 0128 0129 int KTwoFingerSwipeRecognizer::minSswipeDistance() const 0130 { 0131 return d->mMinSwipeDistance; 0132 } 0133 0134 void KTwoFingerSwipeRecognizer::setSwipeDistance(int i) 0135 { 0136 if (i < 0) { 0137 i = 0; 0138 } 0139 0140 d->mMinSwipeDistance = i; 0141 } 0142 0143 0144 0145 class KTwoFingerSwipePrivate 0146 { 0147 public: 0148 KTwoFingerSwipePrivate(KTwoFingerSwipe *parent) 0149 : q(parent) 0150 { 0151 } 0152 KTwoFingerSwipe *const q; 0153 QPointF mPos = QPointF(-1, -1); 0154 QPointF mScreenPos = QPointF(-1, -1); 0155 QPointF mScenePos = QPointF(-1, -1); 0156 qreal mSwipeAngle = 0.0; 0157 }; 0158 0159 KTwoFingerSwipe::KTwoFingerSwipe(QObject *parent) 0160 : QGesture(parent) 0161 , d(new KTwoFingerSwipePrivate(this)) 0162 { 0163 } 0164 0165 KTwoFingerSwipe::~KTwoFingerSwipe() 0166 { 0167 } 0168 0169 QPointF KTwoFingerSwipe::pos() const 0170 { 0171 return d->mPos; 0172 } 0173 0174 void KTwoFingerSwipe::setPos(QPointF _pos) 0175 { 0176 d->mPos = _pos; 0177 } 0178 0179 QPointF KTwoFingerSwipe::screenPos() const 0180 { 0181 return d->mScreenPos; 0182 } 0183 0184 void KTwoFingerSwipe::setScreenPos(QPointF _screenPos) 0185 { 0186 d->mScreenPos = _screenPos; 0187 } 0188 0189 QPointF KTwoFingerSwipe::scenePos() const 0190 { 0191 return d->mScenePos; 0192 } 0193 0194 void KTwoFingerSwipe::setScenePos(QPointF _scenePos) 0195 { 0196 d->mScenePos = _scenePos; 0197 } 0198 0199 qreal KTwoFingerSwipe::swipeAngle() const 0200 { 0201 return d->mSwipeAngle; 0202 } 0203 void KTwoFingerSwipe::setSwipeAngle(qreal _swipeAngle) 0204 { 0205 d->mSwipeAngle = _swipeAngle; 0206 } 0207 0208 #include "moc_ktwofingerswipe.cpp"