1/*
2 This file is part of the KDE libraries
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 "ktwofingertap.h"
10
11// Qt
12#include <QApplication>
13#include <QGraphicsWidget>
14#include <QTouchEvent>
15
16class KTwoFingerTapRecognizerPrivate
17{
18public:
19 KTwoFingerTapRecognizerPrivate(KTwoFingerTapRecognizer *parent)
20 : q(parent)
21 {
22 }
23 KTwoFingerTapRecognizer *const q;
24 bool mGestureTriggered = false;
25 int mTapRadius = 40; // same as Qt::TapGesture
26 Qt::GestureState mLastState = Qt::NoGesture;
27};
28
29KTwoFingerTapRecognizer::KTwoFingerTapRecognizer()
30 : QGestureRecognizer()
31 , d(new KTwoFingerTapRecognizerPrivate(this))
32{
33}
34
35KTwoFingerTapRecognizer::~KTwoFingerTapRecognizer()
36{
37}
38
39QGesture* KTwoFingerTapRecognizer::create(QObject *target)
40{
41 Q_UNUSED(target)
42 return static_cast<QGesture *>(new KTwoFingerTap());
43}
44
45QGestureRecognizer::Result KTwoFingerTapRecognizer::recognize(QGesture *gesture, QObject *watched, QEvent *event)
46{
47 Q_UNUSED(watched)
48
49 KTwoFingerTap *ktwoFingerTap = static_cast<KTwoFingerTap *>(gesture);
50 const QTouchEvent *touchEvent = static_cast<const QTouchEvent *>(event);
51
52 switch (event->type()) {
53 case QEvent::TouchBegin: {
54 const QTouchEvent::TouchPoint tp = touchEvent->points().first();
55 ktwoFingerTap->setHotSpot(tp.globalPressPosition());
56 ktwoFingerTap->setPos(tp.pressPosition());
57 ktwoFingerTap->setScreenPos(tp.globalPressPosition());
58 ktwoFingerTap->setScenePos(tp.scenePressPosition());
59 d->mLastState = Qt::NoGesture;
60 return MayBeGesture;
61 }
62
63 case QEvent::TouchUpdate: {
64 // The gesture was already canceled or finished, so we will ignore this event.
65 if (d->mLastState == Qt::GestureCanceled || d->mLastState == Qt::GestureFinished) {
66 return Ignore;
67 }
68
69 const int touchPointSize = touchEvent->points().size();
70
71 if (touchPointSize > 2) {
72 d->mLastState = Qt::GestureCanceled;
73 return CancelGesture;
74 }
75
76 if (touchPointSize == 2) {
77 if ((touchEvent->points().first().pressPosition() - touchEvent->points().first().position()).manhattanLength() > d->mTapRadius) {
78 d->mLastState = Qt::GestureCanceled;
79 return CancelGesture;
80 }
81 if ((touchEvent->points().at(i: 1).pressPosition() - touchEvent->points().at(i: 1).position()).manhattanLength() > d->mTapRadius) {
82 d->mLastState = Qt::GestureCanceled;
83 return CancelGesture;
84 }
85 if (touchEvent->touchPointStates() & Qt::TouchPointPressed) {
86 d->mLastState = gesture->state() == Qt::NoGesture ? Qt::GestureStarted : Qt::GestureUpdated;
87 return TriggerGesture;
88 }
89 if (touchEvent->touchPointStates() & Qt::TouchPointMoved) {
90 d->mLastState = gesture->state() == Qt::NoGesture ? Qt::GestureStarted : Qt::GestureUpdated;
91 return TriggerGesture;
92 }
93 if (touchEvent->touchPointStates() & Qt::TouchPointReleased) {
94 d->mLastState = Qt::GestureFinished;
95 return FinishGesture;
96 }
97 }
98 break;
99 }
100
101 case QEvent::TouchEnd: {
102 if (d->mLastState == Qt::GestureStarted || d->mLastState == Qt::GestureUpdated) {
103 return FinishGesture;
104 }
105 break;
106 }
107
108 default:
109 return Ignore;
110 }
111 return Ignore;
112}
113
114void KTwoFingerTapRecognizer::setTapRadius(int i)
115{
116 if (i < 0) {
117 i = 0;
118 }
119
120 d->mTapRadius = i;
121}
122
123int KTwoFingerTapRecognizer::tapRadius() const
124{
125 return d->mTapRadius;
126}
127
128class KTwoFingerTapPrivate
129{
130public:
131 KTwoFingerTapPrivate(KTwoFingerTap *parent)
132 : q(parent)
133 {
134 }
135 KTwoFingerTap *const q;
136 QPointF mPos = QPointF(-1, -1);
137 QPointF mScreenPos = QPointF(-1, -1);
138 QPointF mScenePos = QPointF(-1, -1);
139};
140
141KTwoFingerTap::KTwoFingerTap(QObject *parent)
142 : QGesture(parent)
143 , d(new KTwoFingerTapPrivate(this))
144{
145}
146
147KTwoFingerTap::~KTwoFingerTap()
148{
149}
150
151QPointF KTwoFingerTap::pos() const
152{
153 return d->mPos;
154}
155
156void KTwoFingerTap::setPos(QPointF _pos)
157{
158 d->mPos = _pos;
159}
160
161QPointF KTwoFingerTap::screenPos() const
162{
163 return d->mScreenPos;
164}
165
166void KTwoFingerTap::setScreenPos(QPointF _screenPos)
167{
168 d->mScreenPos = _screenPos;
169}
170
171QPointF KTwoFingerTap::scenePos() const
172{
173 return d->mScenePos;
174}
175
176void KTwoFingerTap::setScenePos(QPointF _scenePos)
177{
178 d->mScenePos = _scenePos;
179}
180
181#include "moc_ktwofingertap.cpp"
182

source code of kwidgetsaddons/src/ktwofingertap.cpp