File indexing completed on 2024-05-12 04:19:51
0001 /* 0002 Gwenview: an image viewer 0003 Copyright 2019 Steffen Hartleib <steffenhartleib@t-online.de> 0004 0005 This program is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU General Public License 0007 as published by the Free Software Foundation; either version 2 0008 of the License, or (at your option) any later version. 0009 0010 This program is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 GNU General Public License for more details. 0014 0015 You should have received a copy of the GNU General Public License 0016 along with this program; if not, write to the Free Software 0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. 0018 0019 */ 0020 // Self 0021 #include "oneandtwofingerswipe.h" 0022 0023 // STL 0024 #include <cmath> 0025 0026 // Qt 0027 #include <QGraphicsWidget> 0028 #include <QTouchEvent> 0029 0030 // KF 0031 0032 // Local 0033 #include "gwenview_lib_debug.h" 0034 #include "lib/touch/touch_helper.h" 0035 0036 namespace Gwenview 0037 { 0038 struct OneAndTwoFingerSwipeRecognizerPrivate { 0039 OneAndTwoFingerSwipeRecognizer *q = nullptr; 0040 bool mTargetIsGrapicsWidget = false; 0041 qint64 mTouchBeginnTimestamp; 0042 bool mGestureAlreadyTriggered; 0043 }; 0044 0045 OneAndTwoFingerSwipeRecognizer::OneAndTwoFingerSwipeRecognizer() 0046 : QGestureRecognizer() 0047 , d(new OneAndTwoFingerSwipeRecognizerPrivate) 0048 { 0049 d->q = this; 0050 } 0051 0052 OneAndTwoFingerSwipeRecognizer::~OneAndTwoFingerSwipeRecognizer() 0053 { 0054 delete d; 0055 } 0056 0057 QGesture *OneAndTwoFingerSwipeRecognizer::create(QObject *) 0058 { 0059 return static_cast<QGesture *>(new OneAndTwoFingerSwipe()); 0060 } 0061 0062 QGestureRecognizer::Result OneAndTwoFingerSwipeRecognizer::recognize(QGesture *state, QObject *watched, QEvent *event) 0063 { 0064 // Because of a bug in Qt in a gesture event in a graphicsview, all gestures are trigger twice 0065 // https://bugreports.qt.io/browse/QTBUG-13103 0066 if (qobject_cast<QGraphicsWidget *>(watched)) 0067 d->mTargetIsGrapicsWidget = true; 0068 if (d->mTargetIsGrapicsWidget && watched->isWidgetType()) 0069 return Ignore; 0070 0071 switch (event->type()) { 0072 case QEvent::TouchBegin: { 0073 auto touchEvent = static_cast<QTouchEvent *>(event); 0074 d->mTouchBeginnTimestamp = touchEvent->timestamp(); 0075 d->mGestureAlreadyTriggered = false; 0076 state->setHotSpot(touchEvent->touchPoints().first().screenPos()); 0077 return MayBeGesture; 0078 } 0079 0080 case QEvent::TouchUpdate: { 0081 auto touchEvent = static_cast<QTouchEvent *>(event); 0082 const qint64 now = touchEvent->timestamp(); 0083 const QPointF distance = touchEvent->touchPoints().first().startPos() - touchEvent->touchPoints().first().pos(); 0084 state->setHotSpot(touchEvent->touchPoints().first().screenPos()); 0085 0086 if (touchEvent->touchPoints().size() >> 2) { 0087 d->mGestureAlreadyTriggered = false; 0088 return CancelGesture; 0089 } 0090 0091 if (distance.manhattanLength() >= Touch_Helper::Touch::minDistanceForSwipe 0092 && (now - d->mTouchBeginnTimestamp) <= Touch_Helper::Touch::maxTimeFrameForSwipe && !d->mGestureAlreadyTriggered) { 0093 if (distance.x() < 0 && abs(distance.x()) >= abs(distance.y()) * 2) { 0094 state->setProperty("right", true); 0095 state->setProperty("left", false); 0096 d->mGestureAlreadyTriggered = true; 0097 return FinishGesture; 0098 } 0099 if (distance.x() > 0 && abs(distance.x()) >= abs(distance.y()) * 2) { 0100 state->setProperty("right", false); 0101 state->setProperty("left", true); 0102 d->mGestureAlreadyTriggered = true; 0103 return FinishGesture; 0104 } 0105 if ((now - d->mTouchBeginnTimestamp) <= Touch_Helper::Touch::maxTimeFrameForSwipe && !d->mGestureAlreadyTriggered) { 0106 return MayBeGesture; 0107 } else { 0108 d->mGestureAlreadyTriggered = false; 0109 return CancelGesture; 0110 } 0111 } 0112 break; 0113 } 0114 0115 default: 0116 return Ignore; 0117 } 0118 return Ignore; 0119 } 0120 0121 OneAndTwoFingerSwipe::OneAndTwoFingerSwipe(QObject *parent) 0122 : QGesture(parent) 0123 { 0124 } 0125 0126 } // namespace