File indexing completed on 2024-05-19 04:21:33
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 "tapholdandmoving.h" 0022 0023 // Qt 0024 #include <QGraphicsWidget> 0025 #include <QTouchEvent> 0026 0027 // KF 0028 0029 // Local 0030 #include "gwenview_lib_debug.h" 0031 #include "lib/touch/touch_helper.h" 0032 0033 namespace Gwenview 0034 { 0035 struct TapHoldAndMovingRecognizerPrivate { 0036 TapHoldAndMovingRecognizer *q = nullptr; 0037 bool mTargetIsGrapicsWidget = false; 0038 qint64 mTouchBeginnTimestamp; 0039 bool mTouchPointStationary; 0040 bool mGestureTriggered; 0041 Qt::GestureState mLastGestureState = Qt::NoGesture; 0042 }; 0043 0044 TapHoldAndMovingRecognizer::TapHoldAndMovingRecognizer() 0045 : QGestureRecognizer() 0046 , d(new TapHoldAndMovingRecognizerPrivate) 0047 { 0048 d->q = this; 0049 } 0050 0051 TapHoldAndMovingRecognizer::~TapHoldAndMovingRecognizer() 0052 { 0053 delete d; 0054 } 0055 0056 QGesture *TapHoldAndMovingRecognizer::create(QObject *) 0057 { 0058 return static_cast<QGesture *>(new TapHoldAndMoving()); 0059 } 0060 0061 QGestureRecognizer::Result TapHoldAndMovingRecognizer::recognize(QGesture *state, QObject *watched, QEvent *event) 0062 { 0063 // Because of a bug in Qt in a gesture event in a graphicsview, all gestures are trigger twice 0064 // https://bugreports.qt.io/browse/QTBUG-13103 0065 if (qobject_cast<QGraphicsWidget *>(watched)) 0066 d->mTargetIsGrapicsWidget = true; 0067 if (d->mTargetIsGrapicsWidget && watched->isWidgetType()) 0068 return Ignore; 0069 0070 switch (event->type()) { 0071 case QEvent::TouchBegin: { 0072 auto touchEvent = static_cast<QTouchEvent *>(event); 0073 d->mTouchBeginnTimestamp = touchEvent->timestamp(); 0074 d->mGestureTriggered = false; 0075 d->mTouchPointStationary = true; 0076 state->setHotSpot(touchEvent->touchPoints().first().screenPos()); 0077 d->mLastGestureState = Qt::NoGesture; 0078 return MayBeGesture; 0079 } 0080 0081 case QEvent::TouchUpdate: { 0082 auto touchEvent = static_cast<QTouchEvent *>(event); 0083 const qint64 now = touchEvent->timestamp(); 0084 const QPoint pos = touchEvent->touchPoints().first().pos().toPoint(); 0085 state->setHotSpot(touchEvent->touchPoints().first().screenPos()); 0086 0087 if (touchEvent->touchPoints().size() >> 1) { 0088 d->mGestureTriggered = false; 0089 d->mLastGestureState = Qt::GestureCanceled; 0090 return CancelGesture; 0091 } 0092 0093 if (touchEvent->touchPoints().size() == 1 && d->mLastGestureState != Qt::GestureCanceled) { 0094 if (!d->mGestureTriggered && d->mTouchPointStationary && now - d->mTouchBeginnTimestamp >= Touch_Helper::Touch::durationForTapHold) { 0095 d->mGestureTriggered = true; 0096 } 0097 } 0098 d->mTouchPointStationary = Touch_Helper::touchStationary(event); 0099 0100 if (d->mGestureTriggered && d->mLastGestureState != Qt::GestureCanceled) { 0101 state->setProperty("pos", pos); 0102 d->mLastGestureState = Qt::GestureStarted; 0103 return TriggerGesture; 0104 } 0105 break; 0106 } 0107 0108 case QEvent::TouchEnd: { 0109 auto touchEvent = static_cast<QTouchEvent *>(event); 0110 state->setHotSpot(touchEvent->touchPoints().first().screenPos()); 0111 if (d->mGestureTriggered) { 0112 d->mLastGestureState = Qt::GestureFinished; 0113 return FinishGesture; 0114 } 0115 break; 0116 } 0117 default: 0118 return Ignore; 0119 } 0120 return Ignore; 0121 } 0122 0123 TapHoldAndMoving::TapHoldAndMoving(QObject *parent) 0124 : QGesture(parent) 0125 { 0126 } 0127 0128 } // namespace