File indexing completed on 2025-01-19 05:01:06
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2017 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #pragma once 0010 0011 #include "effect/globals.h" 0012 #include <kwin_export.h> 0013 0014 #include <QList> 0015 #include <QMap> 0016 #include <QObject> 0017 #include <QPointF> 0018 0019 namespace KWin 0020 { 0021 /* 0022 * Everytime the scale of the gesture changes by this much, the callback changes by 1. 0023 * This is the amount of change for 1 unit of change, like switch by 1 desktop. 0024 * */ 0025 static const qreal DEFAULT_UNIT_SCALE_DELTA = .2; // 20% 0026 0027 class Gesture : public QObject 0028 { 0029 Q_OBJECT 0030 public: 0031 ~Gesture() override; 0032 0033 protected: 0034 explicit Gesture(QObject *parent); 0035 0036 Q_SIGNALS: 0037 /** 0038 * Matching of a gesture started and this Gesture might match. 0039 * On further evaluation either the signal @ref triggered or 0040 * @ref cancelled will get emitted. 0041 */ 0042 void started(); 0043 /** 0044 * Gesture matching ended and this Gesture matched. 0045 */ 0046 void triggered(); 0047 /** 0048 * This Gesture no longer matches. 0049 */ 0050 void cancelled(); 0051 }; 0052 0053 class SwipeGesture : public Gesture 0054 { 0055 Q_OBJECT 0056 public: 0057 explicit SwipeGesture(QObject *parent = nullptr); 0058 ~SwipeGesture() override; 0059 0060 bool minimumFingerCountIsRelevant() const; 0061 void setMinimumFingerCount(uint count); 0062 uint minimumFingerCount() const; 0063 0064 bool maximumFingerCountIsRelevant() const; 0065 void setMaximumFingerCount(uint count); 0066 uint maximumFingerCount() const; 0067 0068 SwipeDirection direction() const; 0069 void setDirection(SwipeDirection direction); 0070 0071 void setMinimumX(int x); 0072 int minimumX() const; 0073 bool minimumXIsRelevant() const; 0074 void setMinimumY(int y); 0075 int minimumY() const; 0076 bool minimumYIsRelevant() const; 0077 0078 void setMaximumX(int x); 0079 int maximumX() const; 0080 bool maximumXIsRelevant() const; 0081 void setMaximumY(int y); 0082 int maximumY() const; 0083 bool maximumYIsRelevant() const; 0084 void setStartGeometry(const QRect &geometry); 0085 0086 QPointF minimumDelta() const; 0087 void setMinimumDelta(const QPointF &delta); 0088 bool isMinimumDeltaRelevant() const; 0089 0090 qreal deltaToProgress(const QPointF &delta) const; 0091 bool minimumDeltaReached(const QPointF &delta) const; 0092 0093 Q_SIGNALS: 0094 /** 0095 * The progress of the gesture if a minimumDelta is set. 0096 * The progress is reported in [0.0,1.0] 0097 */ 0098 void progress(qreal); 0099 0100 /** 0101 * The progress in actual pixel distance traveled by the fingers 0102 */ 0103 void deltaProgress(const QPointF &delta); 0104 0105 private: 0106 bool m_minimumFingerCountRelevant = false; 0107 uint m_minimumFingerCount = 0; 0108 bool m_maximumFingerCountRelevant = false; 0109 uint m_maximumFingerCount = 0; 0110 SwipeDirection m_direction = SwipeDirection::Down; 0111 bool m_minimumXRelevant = false; 0112 int m_minimumX = 0; 0113 bool m_minimumYRelevant = false; 0114 int m_minimumY = 0; 0115 bool m_maximumXRelevant = false; 0116 int m_maximumX = 0; 0117 bool m_maximumYRelevant = false; 0118 int m_maximumY = 0; 0119 bool m_minimumDeltaRelevant = false; 0120 QPointF m_minimumDelta; 0121 }; 0122 0123 class PinchGesture : public Gesture 0124 { 0125 Q_OBJECT 0126 public: 0127 explicit PinchGesture(QObject *parent = nullptr); 0128 ~PinchGesture() override; 0129 0130 bool minimumFingerCountIsRelevant() const; 0131 void setMinimumFingerCount(uint count); 0132 uint minimumFingerCount() const; 0133 0134 bool maximumFingerCountIsRelevant() const; 0135 void setMaximumFingerCount(uint count); 0136 uint maximumFingerCount() const; 0137 0138 PinchDirection direction() const; 0139 void setDirection(PinchDirection direction); 0140 0141 qreal minimumScaleDelta() const; 0142 0143 /** 0144 * scaleDelta is the % scale difference needed to trigger 0145 * 0.25 will trigger when scale reaches 0.75 or 1.25 0146 */ 0147 void setMinimumScaleDelta(const qreal &scaleDelta); 0148 bool isMinimumScaleDeltaRelevant() const; 0149 0150 qreal scaleDeltaToProgress(const qreal &scaleDelta) const; 0151 bool minimumScaleDeltaReached(const qreal &scaleDelta) const; 0152 0153 Q_SIGNALS: 0154 /** 0155 * The progress of the gesture if a minimumDelta is set. 0156 * The progress is reported in [0.0,1.0] 0157 */ 0158 void progress(qreal); 0159 0160 private: 0161 bool m_minimumFingerCountRelevant = false; 0162 uint m_minimumFingerCount = 0; 0163 bool m_maximumFingerCountRelevant = false; 0164 uint m_maximumFingerCount = 0; 0165 PinchDirection m_direction = PinchDirection::Expanding; 0166 bool m_minimumScaleDeltaRelevant = false; 0167 qreal m_minimumScaleDelta = DEFAULT_UNIT_SCALE_DELTA; 0168 }; 0169 0170 class KWIN_EXPORT GestureRecognizer : public QObject 0171 { 0172 Q_OBJECT 0173 public: 0174 GestureRecognizer(QObject *parent = nullptr); 0175 ~GestureRecognizer() override; 0176 0177 void registerSwipeGesture(SwipeGesture *gesture); 0178 void unregisterSwipeGesture(SwipeGesture *gesture); 0179 void registerPinchGesture(PinchGesture *gesture); 0180 void unregisterPinchGesture(PinchGesture *gesture); 0181 0182 int startSwipeGesture(uint fingerCount); 0183 int startSwipeGesture(const QPointF &startPos); 0184 0185 void updateSwipeGesture(const QPointF &delta); 0186 void cancelSwipeGesture(); 0187 void endSwipeGesture(); 0188 0189 int startPinchGesture(uint fingerCount); 0190 void updatePinchGesture(qreal scale, qreal angleDelta, const QPointF &posDelta); 0191 void cancelPinchGesture(); 0192 void endPinchGesture(); 0193 0194 private: 0195 void cancelActiveGestures(); 0196 enum class StartPositionBehavior { 0197 Relevant, 0198 Irrelevant, 0199 }; 0200 enum class Axis { 0201 Horizontal, 0202 Vertical, 0203 None, 0204 }; 0205 int startSwipeGesture(uint fingerCount, const QPointF &startPos, StartPositionBehavior startPosBehavior); 0206 QList<SwipeGesture *> m_swipeGestures; 0207 QList<PinchGesture *> m_pinchGestures; 0208 QList<SwipeGesture *> m_activeSwipeGestures; 0209 QList<PinchGesture *> m_activePinchGestures; 0210 QMap<Gesture *, QMetaObject::Connection> m_destroyConnections; 0211 0212 QPointF m_currentDelta = QPointF(0, 0); 0213 qreal m_currentScale = 1; // For Pinch Gesture recognition 0214 uint m_currentFingerCount = 0; 0215 Axis m_currentSwipeAxis = Axis::None; 0216 }; 0217 0218 }