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 "doubletap.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 DoubleTapRecognizerPrivate { 0036 DoubleTapRecognizer *q = nullptr; 0037 bool mTargetIsGrapicsWidget = false; 0038 qint64 mTouchBeginnTimestamp; 0039 bool mIsOnlyTap; 0040 qint64 mLastTapTimestamp = 0; 0041 qint64 mLastDoupleTapTimestamp = 0; 0042 }; 0043 0044 DoubleTapRecognizer::DoubleTapRecognizer() 0045 : QGestureRecognizer() 0046 , d(new DoubleTapRecognizerPrivate) 0047 { 0048 d->q = this; 0049 } 0050 0051 DoubleTapRecognizer::~DoubleTapRecognizer() 0052 { 0053 delete d; 0054 } 0055 0056 QGesture *DoubleTapRecognizer::create(QObject *) 0057 { 0058 return static_cast<QGesture *>(new DoubleTap()); 0059 } 0060 0061 QGestureRecognizer::Result DoubleTapRecognizer::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->mIsOnlyTap = true; 0075 if (d->mLastDoupleTapTimestamp == 0) 0076 d->mLastDoupleTapTimestamp = touchEvent->timestamp() - Touch_Helper::Touch::doubleTapInterval; 0077 state->setHotSpot(touchEvent->touchPoints().first().screenPos()); 0078 return MayBeGesture; 0079 } 0080 0081 case QEvent::TouchUpdate: { 0082 auto touchEvent = static_cast<QTouchEvent *>(event); 0083 const qint64 now = touchEvent->timestamp(); 0084 state->setHotSpot(touchEvent->touchPoints().first().screenPos()); 0085 0086 if (d->mIsOnlyTap && now - d->mTouchBeginnTimestamp < Touch_Helper::Touch::maxTimeForTap && Touch_Helper::touchStationary(event)) { 0087 d->mIsOnlyTap = true; 0088 return MayBeGesture; 0089 } else { 0090 d->mIsOnlyTap = false; 0091 return CancelGesture; 0092 } 0093 break; 0094 } 0095 0096 case QEvent::TouchEnd: { 0097 auto touchEvent = static_cast<QTouchEvent *>(event); 0098 const qint64 now = touchEvent->timestamp(); 0099 0100 if (now - d->mLastTapTimestamp <= Touch_Helper::Touch::doubleTapInterval && d->mIsOnlyTap) { 0101 // Interval between two double tap gesture need to be bigger than Touch_Helper::Touch::doupleTapIntervall, 0102 // to suppress fast successively double tap gestures 0103 if (now - d->mLastDoupleTapTimestamp > Touch_Helper::Touch::doubleTapInterval) { 0104 d->mLastTapTimestamp = 0; 0105 state->setHotSpot(touchEvent->touchPoints().first().screenPos()); 0106 d->mLastDoupleTapTimestamp = now; 0107 return FinishGesture; 0108 } 0109 } 0110 0111 if (d->mIsOnlyTap) 0112 d->mLastTapTimestamp = now; 0113 0114 break; 0115 } 0116 0117 default: 0118 return Ignore; 0119 } 0120 return Ignore; 0121 } 0122 0123 DoubleTap::DoubleTap(QObject *parent) 0124 : QGesture(parent) 0125 { 0126 } 0127 0128 } // namespace