summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@nokia.com>2009-10-12 12:11:44 (GMT)
committerRichard Moe Gustavsen <richard.gustavsen@nokia.com>2009-10-13 12:15:35 (GMT)
commitb6b6da647132f7fdf78d0601cbf7b411fda474f0 (patch)
tree42c6eddc023420111a4c080ad94d77172e24567a
parent8d9acba3ecac466fa86201e4eb760af1ccea68e3 (diff)
downloadQt-b6b6da647132f7fdf78d0601cbf7b411fda474f0.zip
Qt-b6b6da647132f7fdf78d0601cbf7b411fda474f0.tar.gz
Qt-b6b6da647132f7fdf78d0601cbf7b411fda474f0.tar.bz2
Mac: implement gestures conforming to the new API
-rw-r--r--examples/gestures/imageviewer/imagewidget.cpp8
-rw-r--r--src/gui/kernel/kernel.pri4
-rw-r--r--src/gui/kernel/qgesture.cpp26
-rw-r--r--src/gui/kernel/qgesture.h6
-rw-r--r--src/gui/kernel/qgesturemanager.cpp12
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac.mm258
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac_p.h103
7 files changed, 396 insertions, 21 deletions
diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp
index b8bb7b5..f3fd8e4 100644
--- a/examples/gestures/imageviewer/imagewidget.cpp
+++ b/examples/gestures/imageviewer/imagewidget.cpp
@@ -104,10 +104,10 @@ bool ImageWidget::gestureEvent(QGestureEvent *event)
panTriggered(static_cast<QPanGesture*>(pan));
return true;
} else if (QGesture *pinch = event->gesture(Qt::PinchGesture)) {
- pinchTriggered(static_cast<QPinchGesture*>(pan));
+ pinchTriggered(static_cast<QPinchGesture*>(pinch));
return true;
} else if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {
- swipeTriggered(static_cast<QSwipeGesture*>(pan));
+ swipeTriggered(static_cast<QSwipeGesture*>(swipe));
return true;
}
return false;
@@ -125,7 +125,7 @@ void ImageWidget::panTriggered(QPanGesture *gesture)
setCursor(Qt::ArrowCursor);
}
#endif
- QSizeF lastOffset = gesture->property("lastOffset").toSizeF();
+ QSizeF lastOffset = gesture->offset();
horizontalOffset += lastOffset.width();
verticalOffset += lastOffset.height();
update();
@@ -133,7 +133,7 @@ void ImageWidget::panTriggered(QPanGesture *gesture)
void ImageWidget::pinchTriggered(QPinchGesture *gesture)
{
- QPinchGesture::WhatChanged whatChanged = gesture->property("whatChanged").value<QPinchGesture::WhatChanged>();
+ QPinchGesture::WhatChanged whatChanged = gesture->whatChanged();
if (whatChanged & QPinchGesture::RotationAngleChanged) {
qreal value = gesture->property("rotationAngle").toReal();
qreal lastValue = gesture->property("lastRotationAngle").toReal();
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 88c1f73..53c2611 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -205,6 +205,7 @@ embedded {
qcocoaview_mac_p.h \
qcocoaapplication_mac_p.h \
qcocoaapplicationdelegate_mac_p.h \
+ qmacgesturerecognizer_mac_p.h \
qmultitouch_mac_p.h
OBJECTIVE_SOURCES += \
@@ -224,7 +225,8 @@ embedded {
kernel/qdesktopwidget_mac.mm \
kernel/qeventdispatcher_mac.mm \
kernel/qcocoawindowcustomthemeframe_mac.mm \
- kernel/qmultitouch_mac.mm \
+ kernel/qmacgesturerecognizer_mac.mm \
+ kernel/qmultitouch_mac.mm
HEADERS += \
kernel/qt_cocoa_helpers_mac_p.h \
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index 7b2cd6d..3639a45 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -335,22 +335,24 @@ QSwipeGesture::QSwipeGesture(QObject *parent)
QSwipeGesture::SwipeDirection QSwipeGesture::horizontalDirection() const
{
- return d_func()->horizontalDirection;
+ Q_D(const QSwipeGesture);
+ if (d->swipeAngle < 0 || d->swipeAngle == 90 || d->swipeAngle == 270)
+ return QSwipeGesture::NoDirection;
+ else if (d->swipeAngle < 90 || d->swipeAngle > 270)
+ return QSwipeGesture::Right;
+ else
+ return QSwipeGesture::Left;
}
QSwipeGesture::SwipeDirection QSwipeGesture::verticalDirection() const
{
- return d_func()->verticalDirection;
-}
-
-void QSwipeGesture::setHorizontalDirection(QSwipeGesture::SwipeDirection value)
-{
- d_func()->horizontalDirection = value;
-}
-
-void QSwipeGesture::setVerticalDirection(QSwipeGesture::SwipeDirection value)
-{
- d_func()->verticalDirection = value;
+ Q_D(const QSwipeGesture);
+ if (d->swipeAngle <= 0 || d->swipeAngle == 180)
+ return QSwipeGesture::NoDirection;
+ else if (d->swipeAngle < 180)
+ return QSwipeGesture::Up;
+ else
+ return QSwipeGesture::Down;
}
qreal QSwipeGesture::swipeAngle() const
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
index bf72759..0034819 100644
--- a/src/gui/kernel/qgesture.h
+++ b/src/gui/kernel/qgesture.h
@@ -189,8 +189,8 @@ class Q_GUI_EXPORT QSwipeGesture : public QGesture
Q_DECLARE_PRIVATE(QSwipeGesture)
Q_ENUMS(SwipeDirection)
- Q_PROPERTY(SwipeDirection horizontalDirection READ horizontalDirection WRITE setHorizontalDirection)
- Q_PROPERTY(SwipeDirection verticalDirection READ verticalDirection WRITE setVerticalDirection)
+ Q_PROPERTY(SwipeDirection horizontalDirection READ horizontalDirection STORED false)
+ Q_PROPERTY(SwipeDirection verticalDirection READ verticalDirection STORED false)
Q_PROPERTY(qreal swipeAngle READ swipeAngle WRITE setSwipeAngle)
public:
@@ -199,8 +199,6 @@ public:
SwipeDirection horizontalDirection() const;
SwipeDirection verticalDirection() const;
- void setHorizontalDirection(SwipeDirection value);
- void setVerticalDirection(SwipeDirection value);
qreal swipeAngle() const;
void setSwipeAngle(qreal value);
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index b0ef703..0f0aef2 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -48,6 +48,10 @@
#include "qevent.h"
#include "qgraphicsitem.h"
+#ifdef Q_WS_MAC
+#include "qmacgesturerecognizer_mac_p.h"
+#endif
+
#include "qdebug.h"
// #define GESTURE_DEBUG
@@ -64,7 +68,15 @@ QGestureManager::QGestureManager(QObject *parent)
{
qRegisterMetaType<Qt::GestureState>();
+#if defined(Q_WS_MAC)
+ registerGestureRecognizer(new QMacSwipeGestureRecognizer);
+ registerGestureRecognizer(new QMacPinchGestureRecognizer);
+ #if defined(QT_MAC_USE_COCOA)
+ registerGestureRecognizer(new QMacPanGestureRecognizer);
+ #endif
+#else
registerGestureRecognizer(new QPanGestureRecognizer);
+#endif
}
QGestureManager::~QGestureManager()
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac.mm b/src/gui/kernel/qmacgesturerecognizer_mac.mm
new file mode 100644
index 0000000..583fc93
--- /dev/null
+++ b/src/gui/kernel/qmacgesturerecognizer_mac.mm
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmacgesturerecognizer_mac_p.h"
+#include "qgesture.h"
+#include "qgesture_p.h"
+#include "qevent.h"
+#include "qevent_p.h"
+#include "qwidget.h"
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer()
+{
+}
+
+QGesture *QMacSwipeGestureRecognizer::createGesture(QObject * /*target*/)
+{
+ return new QSwipeGesture;
+}
+
+QGestureRecognizer::Result
+QMacSwipeGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
+ QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+ switch (ev->gestureType) {
+ case QNativeGestureEvent::Swipe: {
+ QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
+ g->setSwipeAngle(ev->angle);
+ return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ break; }
+ default:
+ break;
+ }
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacSwipeGestureRecognizer::reset(QGesture *gesture)
+{
+ QSwipeGesture *g = static_cast<QSwipeGesture *>(gesture);
+ g->setSwipeAngle(0);
+ QGestureRecognizer::reset(gesture);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+QMacPinchGestureRecognizer::QMacPinchGestureRecognizer()
+{
+}
+
+QGesture *QMacPinchGestureRecognizer::createGesture(QObject * /*target*/)
+{
+ return new QPinchGesture;
+}
+
+QGestureRecognizer::Result
+QMacPinchGestureRecognizer::filterEvent(QGesture *gesture, QObject *obj, QEvent *event)
+{
+ if (event->type() == QEvent::NativeGesture && obj->isWidgetType()) {
+ QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
+ QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
+ switch(ev->gestureType) {
+ case QNativeGestureEvent::GestureBegin:
+ reset(gesture);
+ g->setStartCenterPoint(static_cast<QWidget*>(obj)->mapFromGlobal(ev->position));
+ g->setCenterPoint(g->startCenterPoint());
+ g->setWhatChanged(QPinchGesture::CenterPointChanged);
+ return QGestureRecognizer::MaybeGesture | QGestureRecognizer::ConsumeEventHint;
+ case QNativeGestureEvent::Rotate: {
+ g->setLastScaleFactor(g->scaleFactor());
+ g->setLastRotationAngle(g->rotationAngle());
+ g->setRotationAngle(g->rotationAngle() + ev->percentage);
+ g->setWhatChanged(QPinchGesture::RotationAngleChanged);
+ return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ break;
+ }
+ case QNativeGestureEvent::Zoom:
+ g->setLastScaleFactor(g->scaleFactor());
+ g->setLastRotationAngle(g->rotationAngle());
+ g->setScaleFactor(g->scaleFactor() + ev->percentage);
+ g->setWhatChanged(QPinchGesture::ScaleFactorChanged);
+ return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ break;
+ case QNativeGestureEvent::GestureEnd:
+ return QGestureRecognizer::GestureFinished | QGestureRecognizer::ConsumeEventHint;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacPinchGestureRecognizer::reset(QGesture *gesture)
+{
+ QPinchGesture *g = static_cast<QPinchGesture *>(gesture);
+ g->setWhatChanged(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);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+#if defined(QT_MAC_USE_COCOA)
+
+QMacPanGestureRecognizer::QMacPanGestureRecognizer() : _panCanceled(true)
+{
+}
+
+QGesture *QMacPanGestureRecognizer::createGesture(QObject *target)
+{
+ if (!target)
+ return new QPanGesture;
+
+ if (QWidget *w = qobject_cast<QWidget *>(target)) {
+ w->setAttribute(Qt::WA_AcceptTouchEvents);
+ w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents);
+ return new QPanGesture;
+ }
+ return 0;
+}
+
+QGestureRecognizer::Result
+QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent *event)
+{
+ const int panBeginDelay = 300;
+ const int panBeginRadius = 3;
+
+ QPanGesture *g = static_cast<QPanGesture *>(gesture);
+
+ switch (event->type()) {
+ case QEvent::TouchBegin: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (ev->touchPoints().size() == 1) {
+ reset(gesture);
+ _startPos = QCursor::pos();
+ _lastPos = _startPos;
+ _panTimer.start(panBeginDelay, target);
+ _panCanceled = false;
+ return QGestureRecognizer::MaybeGesture;
+ }
+ break;}
+ case QEvent::TouchEnd: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
+ if (!_panCanceled && ev->touchPoints().size() == 1)
+ return QGestureRecognizer::GestureFinished;
+ break;}
+ case QEvent::TouchUpdate: {
+ if (_panCanceled)
+ break;
+
+ const QTouchEvent *ev = static_cast<const QTouchEvent*>(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::NotGesture;
+ }
+ } else {
+ const QPointF p = QCursor::pos();
+ const QPointF posOffset = p - _lastPos;
+ g->setLastOffset(g->offset());
+ g->setOffset(QSizeF(posOffset.x(), posOffset.y()));
+ g->setTotalOffset(g->lastOffset() + g->offset());
+ _lastPos = p;
+ return QGestureRecognizer::GestureTriggered;
+ }
+ }
+ break;}
+ case QEvent::Timer: {
+ QTimerEvent *ev = static_cast<QTimerEvent *>(event);
+ if (ev->timerId() == _panTimer.timerId()) {
+ _panTimer.stop();
+ if (_panCanceled)
+ break;
+ // Begin new pan session!
+ _startPos = QCursor::pos();
+ _lastPos = _startPos;
+ return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint;
+ }
+ break; }
+ default:
+ break;
+ }
+
+ return QGestureRecognizer::Ignore;
+}
+
+void QMacPanGestureRecognizer::reset(QGesture *gesture)
+{
+ QPanGesture *g = static_cast<QPanGesture *>(gesture);
+ _startPos = QPointF();
+ _lastPos = QPointF();
+ _panCanceled = true;
+ g->setOffset(QSizeF(0, 0));
+ g->setLastOffset(QSizeF(0, 0));
+ g->setTotalOffset(QSizeF(0, 0));
+ g->setAcceleration(qreal(1));
+ QGestureRecognizer::reset(gesture);
+}
+#endif // QT_MAC_USE_COCOA
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac_p.h b/src/gui/kernel/qmacgesturerecognizer_mac_p.h
new file mode 100644
index 0000000..bdc2e08
--- /dev/null
+++ b/src/gui/kernel/qmacgesturerecognizer_mac_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMACSWIPEGESTURERECOGNIZER_MAC_P_H
+#define QMACSWIPEGESTURERECOGNIZER_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qtimer.h"
+#include "qpoint.h"
+#include "qgesturerecognizer.h"
+
+QT_BEGIN_NAMESPACE
+
+class QMacSwipeGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QMacSwipeGestureRecognizer();
+
+ QGesture *createGesture(QObject *target);
+ QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+};
+
+class QMacPinchGestureRecognizer : public QGestureRecognizer
+{
+public:
+ QMacPinchGestureRecognizer();
+
+ QGesture *createGesture(QObject *target);
+ QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+};
+
+#if defined(QT_MAC_USE_COCOA)
+
+class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
+{
+public:
+ QMacPanGestureRecognizer();
+
+ QGesture *createGesture(QObject *target);
+ QGestureRecognizer::Result filterEvent(QGesture *gesture, QObject *watched, QEvent *event);
+ void reset(QGesture *gesture);
+private:
+ QPointF _startPos;
+ QPointF _lastPos;
+ QBasicTimer _panTimer;
+ bool _panCanceled;
+};
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QMACSWIPEGESTURERECOGNIZER_MAC_P_H