/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtWidgets module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qmacgesturerecognizer_p.h" #include "qgesture.h" #include "qgesture_p.h" #include "qevent.h" #include "qwidget.h" #include "qdebug.h" #ifndef QT_NO_GESTURES QT_BEGIN_NAMESPACE QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer() { } QGesture *QMacSwipeGestureRecognizer::create(QObject * /*target*/) { return new QSwipeGesture; } QGestureRecognizer::Result QMacSwipeGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event) { if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) { QNativeGestureEvent *ev = static_cast(event); switch (ev->gestureType()) { case Qt::SwipeNativeGesture: { QSwipeGesture *g = static_cast(gesture); g->setSwipeAngle(ev->value()); g->setHotSpot(ev->screenPos()); return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint; break; } default: break; } } return QGestureRecognizer::Ignore; } void QMacSwipeGestureRecognizer::reset(QGesture *gesture) { QSwipeGesture *g = static_cast(gesture); g->setSwipeAngle(0); QGestureRecognizer::reset(gesture); } //////////////////////////////////////////////////////////////////////// QMacPinchGestureRecognizer::QMacPinchGestureRecognizer() { } QGesture *QMacPinchGestureRecognizer::create(QObject * /*target*/) { return new QPinchGesture; } QGestureRecognizer::Result QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *event) { if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) { QPinchGesture *g = static_cast(gesture); QNativeGestureEvent *ev = static_cast(event); switch (ev->gestureType()) { case Qt::BeginNativeGesture: reset(gesture); g->setStartCenterPoint(static_cast(obj)->mapFromGlobal(ev->screenPos().toPoint())); g->setCenterPoint(g->startCenterPoint()); g->setChangeFlags(QPinchGesture::CenterPointChanged); g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); g->setHotSpot(ev->screenPos()); return QGestureRecognizer::MayBeGesture | QGestureRecognizer::ConsumeEventHint; case Qt::RotateNativeGesture: g->setLastScaleFactor(g->scaleFactor()); g->setLastRotationAngle(g->rotationAngle()); g->setRotationAngle(g->rotationAngle() + ev->value()); g->setChangeFlags(QPinchGesture::RotationAngleChanged); g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); g->setHotSpot(ev->screenPos()); return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; case Qt::ZoomNativeGesture: g->setLastScaleFactor(g->scaleFactor()); g->setLastRotationAngle(g->rotationAngle()); g->setScaleFactor(1 + ev->value()); g->setTotalScaleFactor(g->totalScaleFactor() * g->scaleFactor()); g->setChangeFlags(QPinchGesture::ScaleFactorChanged); g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); g->setHotSpot(ev->screenPos()); return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; case Qt::SmartZoomNativeGesture: g->setLastScaleFactor(g->scaleFactor()); g->setLastRotationAngle(g->rotationAngle()); g->setScaleFactor(ev->value() ? 1.7f : 1.0f); g->setChangeFlags(QPinchGesture::ScaleFactorChanged); g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags()); g->setHotSpot(ev->screenPos()); return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; case Qt::EndNativeGesture: return QGestureRecognizer::FinishGesture | QGestureRecognizer::ConsumeEventHint; default: break; } } return QGestureRecognizer::Ignore; } void QMacPinchGestureRecognizer::reset(QGesture *gesture) { QPinchGesture *g = static_cast(gesture); g->setChangeFlags(0); g->setTotalChangeFlags(0); g->setScaleFactor(1.0f); g->setTotalScaleFactor(1.0f); g->setLastScaleFactor(1.0f); g->setRotationAngle(0.0f); g->setTotalRotationAngle(0.0f); g->setLastRotationAngle(0.0f); g->setCenterPoint(QPointF()); g->setStartCenterPoint(QPointF()); g->setLastCenterPoint(QPointF()); QGestureRecognizer::reset(gesture); } //////////////////////////////////////////////////////////////////////// QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true) { } QGesture *QMacPanGestureRecognizer::create(QObject *target) { if (!target) return new QPanGesture; if (QWidget *w = qobject_cast(target)) { w->setAttribute(Qt::WA_AcceptTouchEvents); w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); return new QPanGesture; } return 0; } QGestureRecognizer::Result QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event) { const int panBeginDelay = 300; const int panBeginRadius = 3; QPanGesture *g = static_cast(gesture); switch (event->type()) { case QEvent::TouchBegin: { const QTouchEvent *ev = static_cast(event); if (ev->touchPoints().size() == 1) { reset(gesture); _startPos = QCursor::pos(); _panTimer.start(panBeginDelay, target); _panCanceled = false; return QGestureRecognizer::MayBeGesture; } break;} case QEvent::TouchEnd: { if (_panCanceled) break; const QTouchEvent *ev = static_cast(event); if (ev->touchPoints().size() == 1) return QGestureRecognizer::FinishGesture; break;} case QEvent::TouchUpdate: { if (_panCanceled) break; const QTouchEvent *ev = static_cast(event); if (ev->touchPoints().size() == 1) { if (_panTimer.isActive()) { // INVARIANT: Still in maybeGesture. Check if the user // moved his finger so much that it makes sense to cancel the pan: const QPointF p = QCursor::pos(); if ((p - _startPos).manhattanLength() > panBeginRadius) { _panCanceled = true; _panTimer.stop(); return QGestureRecognizer::CancelGesture; } } else { const QPointF p = QCursor::pos(); const QPointF posOffset = p - _startPos; g->setLastOffset(g->offset()); g->setOffset(QPointF(posOffset.x(), posOffset.y())); g->setHotSpot(_startPos); return QGestureRecognizer::TriggerGesture; } } else if (_panTimer.isActive()) { // I only want to cancel the pan if the user is pressing // more than one finger, and the pan hasn't started yet: _panCanceled = true; _panTimer.stop(); return QGestureRecognizer::CancelGesture; } break;} case QEvent::Timer: { QTimerEvent *ev = static_cast(event); if (ev->timerId() == _panTimer.timerId()) { _panTimer.stop(); if (_panCanceled) break; // Begin new pan session! _startPos = QCursor::pos(); g->setHotSpot(_startPos); return QGestureRecognizer::TriggerGesture | QGestureRecognizer::ConsumeEventHint; } break; } default: break; } return QGestureRecognizer::Ignore; } void QMacPanGestureRecognizer::reset(QGesture *gesture) { QPanGesture *g = static_cast(gesture); _startPos = QPointF(); _panCanceled = true; _panTimer.stop(); g->setOffset(QPointF(0, 0)); g->setLastOffset(QPointF(0, 0)); g->setAcceleration(qreal(1)); QGestureRecognizer::reset(gesture); } QT_END_NAMESPACE #endif // QT_NO_GESTURES