1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2021 Steffen Hartleib <steffenhartleib@t-online.de>
4
5 SPDX-License-Identifier: LGPL-2.1-or-later
6*/
7
8// Self
9#include "ktwofingerswipe.h"
10
11// Qt
12#include <QGraphicsWidget>
13#include <QLineF>
14#include <QTouchEvent>
15#include <QDebug>
16class KTwoFingerSwipeRecognizerPrivate
17{
18public:
19 KTwoFingerSwipeRecognizerPrivate(KTwoFingerSwipeRecognizer *parent)
20 : q(parent)
21 {
22 }
23 KTwoFingerSwipeRecognizer *const q;
24 qint64 mTouchBeginnTimestamp = 0;
25 bool mGestureAlreadyFinished = false;
26 int mMaxSwipeTime = 90;
27 int mMinSwipeDistance = 30;
28};
29
30KTwoFingerSwipeRecognizer::KTwoFingerSwipeRecognizer()
31 : QGestureRecognizer()
32 , d(new KTwoFingerSwipeRecognizerPrivate(this))
33{
34}
35
36KTwoFingerSwipeRecognizer::~KTwoFingerSwipeRecognizer()
37{
38}
39
40QGesture* KTwoFingerSwipeRecognizer::create(QObject *target)
41{
42 Q_UNUSED(target);
43 return static_cast<QGesture *>(new KTwoFingerSwipe());
44}
45
46QGestureRecognizer::Result KTwoFingerSwipeRecognizer::recognize(QGesture *gesture, QObject *watched, QEvent *event)
47{
48 Q_UNUSED(watched)
49
50 KTwoFingerSwipe *kTwoFingerSwipe = static_cast<KTwoFingerSwipe *>(gesture);
51 const QTouchEvent *touchEvent = static_cast<const QTouchEvent *>(event);
52
53 switch (event->type()) {
54 case QEvent::TouchBegin: {
55 d->mTouchBeginnTimestamp = touchEvent->timestamp();
56 d->mGestureAlreadyFinished = false;
57 const QTouchEvent::TouchPoint tp = touchEvent->points().first();
58 kTwoFingerSwipe->setHotSpot(tp.globalPressPosition());
59 kTwoFingerSwipe->setPos(tp.pressPosition());
60 kTwoFingerSwipe->setScreenPos(tp.globalPressPosition());
61 kTwoFingerSwipe->setScenePos(tp.scenePressPosition());
62 kTwoFingerSwipe->setSwipeAngle(0.0);
63 return MayBeGesture;
64 }
65
66 case QEvent::TouchUpdate: {
67 // The gesture was already canceled or finished, so we will ignore this event.
68 if (d->mGestureAlreadyFinished) {
69 return Ignore;
70 }
71
72 const qint64 now = touchEvent->timestamp();
73 const qint64 elapsedTime = now - d->mTouchBeginnTimestamp;
74 const QLineF ql = QLineF(touchEvent->points().first().pressPosition(), touchEvent->points().first().position());
75 const qreal length = ql.length();
76 const int touchPointSize = touchEvent->points().size();
77
78 kTwoFingerSwipe->setSwipeAngle(ql.angle());
79
80 if (touchPointSize > 2) {
81 d->mGestureAlreadyFinished = true;
82 return CancelGesture;
83 }
84
85 if (touchPointSize == 2) {
86 if (elapsedTime > d->mMaxSwipeTime) {
87 d->mGestureAlreadyFinished = true;
88 return CancelGesture;
89 }
90 if (length >= d->mMinSwipeDistance && elapsedTime <= d->mMaxSwipeTime && !d->mGestureAlreadyFinished) {
91 d->mGestureAlreadyFinished = true;
92 return FinishGesture;
93 } else if (elapsedTime <= d->mMaxSwipeTime && !d->mGestureAlreadyFinished) {
94 return TriggerGesture;
95 }
96 }
97 break;
98 }
99
100 case QEvent::TouchEnd: {
101 if (gesture->state() == Qt::GestureUpdated || gesture->state() == Qt::GestureStarted) {
102 if (!d->mGestureAlreadyFinished) {
103 return CancelGesture;
104 }
105 }
106 break;
107 }
108
109 default:
110 return Ignore;
111 }
112 return Ignore;
113}
114
115int KTwoFingerSwipeRecognizer::maxSwipeTime() const
116{
117 return d->mMaxSwipeTime;
118}
119
120void KTwoFingerSwipeRecognizer::setMaxSwipeTime(int i)
121{
122 if (i < 0) {
123 i = 0;
124 }
125
126 d->mMaxSwipeTime = i;
127}
128
129int KTwoFingerSwipeRecognizer::minSswipeDistance() const
130{
131 return d->mMinSwipeDistance;
132}
133
134void KTwoFingerSwipeRecognizer::setSwipeDistance(int i)
135{
136 if (i < 0) {
137 i = 0;
138 }
139
140 d->mMinSwipeDistance = i;
141}
142
143
144
145class KTwoFingerSwipePrivate
146{
147public:
148 KTwoFingerSwipePrivate(KTwoFingerSwipe *parent)
149 : q(parent)
150 {
151 }
152 KTwoFingerSwipe *const q;
153 QPointF mPos = QPointF(-1, -1);
154 QPointF mScreenPos = QPointF(-1, -1);
155 QPointF mScenePos = QPointF(-1, -1);
156 qreal mSwipeAngle = 0.0;
157};
158
159KTwoFingerSwipe::KTwoFingerSwipe(QObject *parent)
160 : QGesture(parent)
161 , d(new KTwoFingerSwipePrivate(this))
162{
163}
164
165KTwoFingerSwipe::~KTwoFingerSwipe()
166{
167}
168
169QPointF KTwoFingerSwipe::pos() const
170{
171 return d->mPos;
172}
173
174void KTwoFingerSwipe::setPos(QPointF _pos)
175{
176 d->mPos = _pos;
177}
178
179QPointF KTwoFingerSwipe::screenPos() const
180{
181 return d->mScreenPos;
182}
183
184void KTwoFingerSwipe::setScreenPos(QPointF _screenPos)
185{
186 d->mScreenPos = _screenPos;
187}
188
189QPointF KTwoFingerSwipe::scenePos() const
190{
191 return d->mScenePos;
192}
193
194void KTwoFingerSwipe::setScenePos(QPointF _scenePos)
195{
196 d->mScenePos = _scenePos;
197}
198
199qreal KTwoFingerSwipe::swipeAngle() const
200{
201 return d->mSwipeAngle;
202}
203 void KTwoFingerSwipe::setSwipeAngle(qreal _swipeAngle)
204{
205 d->mSwipeAngle = _swipeAngle;
206}
207
208#include "moc_ktwofingerswipe.cpp"
209

source code of kwidgetsaddons/src/ktwofingerswipe.cpp