Implement native gestures on OS X.
Add QWindowSystemInterface::GestureEvent and QNativeGestureEvent to QtGui. These events are copies of Qt4's QNativeGestureEvent, where it was an implementation detail of QGestureManager. Add gesture message handlers to QNSView and bring back the Mac gesture recognizers for QGestureManager. Task-number: QTBUG-28126 Change-Id: I1304e09e776fa7c44d133d54ca8b895ca2f544c5 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
This commit is contained in:
parent
73e3d2f6cb
commit
fbfc8ffbf3
@ -1557,6 +1557,18 @@ public:
|
||||
IgnoredGesturesPropagateToParent = 0x04
|
||||
};
|
||||
Q_DECLARE_FLAGS(GestureFlags, GestureFlag)
|
||||
|
||||
enum NativeGestureType
|
||||
{
|
||||
BeginNativeGesture,
|
||||
EndNativeGesture,
|
||||
PanNativeGesture,
|
||||
ZoomNativeGesture,
|
||||
SmartZoomNativeGesture,
|
||||
RotateNativeGesture,
|
||||
SwipeNativeGesture
|
||||
};
|
||||
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
enum NavigationMode
|
||||
|
@ -249,7 +249,7 @@ public:
|
||||
TouchEnd = 196,
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
NativeGesture = 197, // Internal for platform gesture support
|
||||
NativeGesture = 197, // QtGui native gesture
|
||||
#endif
|
||||
RequestSoftwareInputPanel = 199,
|
||||
CloseSoftwareInputPanel = 200,
|
||||
|
@ -2263,6 +2263,121 @@ QTabletEvent::~QTabletEvent()
|
||||
|
||||
#endif // QT_NO_TABLETEVENT
|
||||
|
||||
/*!
|
||||
\class QNativeGestureEvent
|
||||
\since 5.2
|
||||
\brief The QNativeGestureEvent class contains parameters that describe a gesture event.
|
||||
\inmodule QtGui
|
||||
\ingroup events
|
||||
|
||||
Native gesture events are generated by the operating system, typically by
|
||||
interpreting touch events. Gesture events are high-level events such
|
||||
as zoom or rotate.
|
||||
|
||||
\table
|
||||
\header
|
||||
\li Event Type
|
||||
\li Description
|
||||
\li Touch equence
|
||||
\row
|
||||
\li Qt::ZoomNativeGesture
|
||||
\li Magnification delta in percent.
|
||||
\li OS X: Two-finger pinch.
|
||||
\row
|
||||
\li Qt::SmartZoomNativeGesture
|
||||
\li Boolean magnification state.
|
||||
\li OS X: Two-finger douple tap (trackpad) / One-finger douple tap (magic mouse).
|
||||
\row
|
||||
\li Qt::RotateNativeGesture
|
||||
\li Rotation delta in degrees.
|
||||
\li OS X: Two-finger rotate.
|
||||
\endtable
|
||||
|
||||
|
||||
In addition, BeginNativeGesture and EndNativeGesture are sent before and after
|
||||
gesture event streams:
|
||||
|
||||
BeginNativeGesture
|
||||
ZoomNativeGesture
|
||||
ZoomNativeGesture
|
||||
ZoomNativeGesture
|
||||
EndNativeGesture
|
||||
|
||||
\sa Qt::NativeGestureType, QGestureEvent
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs a native gesture event of type \a type.
|
||||
|
||||
The points \a localPos, \a windowPos and \a screenPos specify the
|
||||
gesture position relative to the receiving widget or item,
|
||||
window, and screen, respectively.
|
||||
|
||||
\a realValue is the OS X event parameter, \a sequenceId and \a intValue are the Windows event parameters.
|
||||
*/
|
||||
QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos,
|
||||
const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue)
|
||||
: QInputEvent(QEvent::NativeGesture), mGestureType(type),
|
||||
mLocalPos(localPos), mWindowPos(windowPos), mScreenPos(screenPos), mRealValue(realValue),
|
||||
mSequenceId(sequenceId), mIntValue(intValue)
|
||||
{ }
|
||||
|
||||
/*!
|
||||
\fn QNativeGestureEvent::gestureType() const
|
||||
\since 5.2
|
||||
|
||||
Returns the gesture type.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QNativeGestureEvent::value() const
|
||||
\since 5.2
|
||||
|
||||
Returns the gesture value. The value should be interpreted based on the
|
||||
gesture type. For example, a Zoom gesture provides a scale factor while a Rotate
|
||||
gesture provides a rotation delta.
|
||||
|
||||
\sa QNativeGestureEvent, gestureType()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QPoint QNativeGestureEvent::globalPos() const
|
||||
\since 5.2
|
||||
|
||||
Returns the position of the gesture as a QPointF in screen coordinates
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QPoint QNativeGestureEvent::pos() const
|
||||
\since 5.2
|
||||
|
||||
Returns the position of the mouse cursor, relative to the widget
|
||||
or item that received the event.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QPointF QNativeGestureEvent::localPos() const
|
||||
\since 5.2
|
||||
|
||||
Returns the position of the gesture as a QPointF, relative to the
|
||||
widget or item that received the event.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QPointF QNativeGestureEvent::screenPos() const
|
||||
\since 5.2
|
||||
|
||||
Returns the position of the gesture as a QPointF in screen coordinates.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QPointF QNativeGestureEvent::windowPos() const
|
||||
\since 5.2
|
||||
|
||||
Returns the position of the gesture as a QPointF, relative to the
|
||||
window that received the event.
|
||||
*/
|
||||
|
||||
#ifndef QT_NO_DRAGANDDROP
|
||||
/*!
|
||||
Creates a QDragMoveEvent of the required \a type indicating
|
||||
|
@ -268,6 +268,34 @@ protected:
|
||||
};
|
||||
#endif // QT_NO_TABLETEVENT
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
class Q_GUI_EXPORT QNativeGestureEvent : public QInputEvent
|
||||
{
|
||||
public:
|
||||
QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos,
|
||||
const QPointF &screenPos, qreal value, ulong sequenceId, quint64 intArgument);
|
||||
Qt::NativeGestureType gestureType() const { return mGestureType; }
|
||||
qreal value() const { return mRealValue; }
|
||||
|
||||
#ifndef QT_NO_INTEGER_EVENT_COORDINATES
|
||||
inline const QPoint pos() const { return mLocalPos.toPoint(); }
|
||||
inline const QPoint globalPos() const { return mScreenPos.toPoint(); }
|
||||
#endif
|
||||
const QPointF &localPos() const { return mLocalPos; }
|
||||
const QPointF &windowPos() const { return mWindowPos; }
|
||||
const QPointF &screenPos() const { return mScreenPos; }
|
||||
|
||||
protected:
|
||||
Qt::NativeGestureType mGestureType;
|
||||
QPointF mLocalPos;
|
||||
QPointF mWindowPos;
|
||||
QPointF mScreenPos;
|
||||
qreal mRealValue;
|
||||
ulong mSequenceId;
|
||||
quint64 mIntValue;
|
||||
};
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
class Q_GUI_EXPORT QKeyEvent : public QInputEvent
|
||||
{
|
||||
public:
|
||||
|
@ -1473,6 +1473,10 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
|
||||
QGuiApplicationPrivate::processTabletLeaveProximityEvent(
|
||||
static_cast<QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *>(e));
|
||||
break;
|
||||
case QWindowSystemInterfacePrivate::Gesture:
|
||||
QGuiApplicationPrivate::processGestureEvent(
|
||||
static_cast<QWindowSystemInterfacePrivate::GestureEvent *>(e));
|
||||
break;
|
||||
case QWindowSystemInterfacePrivate::PlatformPanel:
|
||||
QGuiApplicationPrivate::processPlatformPanelEvent(
|
||||
static_cast<QWindowSystemInterfacePrivate::PlatformPanelEvent *>(e));
|
||||
@ -1958,6 +1962,15 @@ void QGuiApplicationPrivate::processTabletLeaveProximityEvent(QWindowSystemInter
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
void QGuiApplicationPrivate::processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e)
|
||||
{
|
||||
QNativeGestureEvent ev(e->type, e->pos, e->pos, e->globalPos, e->realValue, e->sequenceId, e->intValue);
|
||||
ev.setTimestamp(e->timestamp);
|
||||
QGuiApplication::sendSpontaneousEvent(e->window, &ev);
|
||||
}
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
void QGuiApplicationPrivate::processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e)
|
||||
{
|
||||
if (!e->window)
|
||||
|
@ -148,6 +148,7 @@ public:
|
||||
static void processTabletEvent(QWindowSystemInterfacePrivate::TabletEvent *e);
|
||||
static void processTabletEnterProximityEvent(QWindowSystemInterfacePrivate::TabletEnterProximityEvent *e);
|
||||
static void processTabletLeaveProximityEvent(QWindowSystemInterfacePrivate::TabletLeaveProximityEvent *e);
|
||||
static void processGestureEvent(QWindowSystemInterfacePrivate::GestureEvent *e);
|
||||
|
||||
static void processPlatformPanelEvent(QWindowSystemInterfacePrivate::PlatformPanelEvent *e);
|
||||
#ifndef QT_NO_CONTEXTMENU
|
||||
|
@ -669,6 +669,35 @@ void QWindowSystemInterface::handleTabletLeaveProximityEvent(int device, int poi
|
||||
handleTabletLeaveProximityEvent(time, device, pointerType, uid);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
void QWindowSystemInterface::handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
|
||||
QPointF &local, QPointF &global)
|
||||
{
|
||||
QWindowSystemInterfacePrivate::GestureEvent *e =
|
||||
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
|
||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
||||
}
|
||||
|
||||
void QWindowSystemInterface::handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
|
||||
qreal value, QPointF &local, QPointF &global)
|
||||
{
|
||||
QWindowSystemInterfacePrivate::GestureEvent *e =
|
||||
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
|
||||
e->realValue = value;
|
||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
||||
}
|
||||
|
||||
void QWindowSystemInterface::handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
|
||||
ulong sequenceId, quint64 value, QPointF &local, QPointF &global)
|
||||
{
|
||||
QWindowSystemInterfacePrivate::GestureEvent *e =
|
||||
new QWindowSystemInterfacePrivate::GestureEvent(window, timestamp, type, local, global);
|
||||
e->sequenceId = sequenceId;
|
||||
e->intValue = value;
|
||||
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
|
||||
}
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
void QWindowSystemInterface::handlePlatformPanelEvent(QWindow *w)
|
||||
{
|
||||
QWindowSystemInterfacePrivate::PlatformPanelEvent *e =
|
||||
|
@ -177,6 +177,15 @@ public:
|
||||
static void handleTabletLeaveProximityEvent(ulong timestamp, int device, int pointerType, qint64 uid);
|
||||
static void handleTabletLeaveProximityEvent(int device, int pointerType, qint64 uid);
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
static void handleGestureEvent(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
|
||||
QPointF &local, QPointF &global);
|
||||
static void handleGestureEventWithRealValue(QWindow *window, ulong timestamp, Qt::NativeGestureType type,
|
||||
qreal value, QPointF &local, QPointF &global);
|
||||
static void handleGestureEventWithSequenceIdAndValue(QWindow *window, ulong timestamp,Qt::NativeGestureType type,
|
||||
ulong sequenceId, quint64 value, QPointF &local, QPointF &global);
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
static void handlePlatformPanelEvent(QWindow *w);
|
||||
#ifndef QT_NO_CONTEXTMENU
|
||||
static void handleContextMenuEvent(QWindow *w, bool mouseTriggered,
|
||||
|
@ -91,6 +91,7 @@ public:
|
||||
PlatformPanel = UserInputEvent | 0x17,
|
||||
ContextMenu = UserInputEvent | 0x18,
|
||||
EnterWhatsThisMode = UserInputEvent | 0x19,
|
||||
Gesture = UserInputEvent | 0x1a,
|
||||
ApplicationStateChanged = 0x19,
|
||||
FlushEvents = 0x20,
|
||||
WindowScreenChanged = 0x21
|
||||
@ -398,6 +399,21 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
class GestureEvent : public InputEvent {
|
||||
public:
|
||||
GestureEvent(QWindow *window, ulong time, Qt::NativeGestureType type, QPointF pos, QPointF globalPos)
|
||||
: InputEvent(window, time, Gesture, Qt::NoModifier), type(type), pos(pos), globalPos(globalPos),
|
||||
realValue(0), sequenceId(0), intValue(0) { }
|
||||
Qt::NativeGestureType type;
|
||||
QPointF pos;
|
||||
QPointF globalPos;
|
||||
// Mac
|
||||
qreal realValue;
|
||||
// Windows
|
||||
ulong sequenceId;
|
||||
quint64 intValue;
|
||||
};
|
||||
|
||||
class WindowSystemEventList {
|
||||
QList<WindowSystemEvent *> impl;
|
||||
mutable QMutex mutex;
|
||||
|
@ -975,6 +975,102 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
|
||||
QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, touchDevice, points);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
//#define QT_COCOA_ENABLE_GESTURE_DEBUG
|
||||
- (void)magnifyWithEvent:(NSEvent *)event
|
||||
{
|
||||
#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
|
||||
qDebug() << "magnifyWithEvent" << [event magnification];
|
||||
#endif
|
||||
const NSTimeInterval timestamp = [event timestamp];
|
||||
QPointF windowPoint;
|
||||
QPointF screenPoint;
|
||||
[self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
|
||||
QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::ZoomNativeGesture,
|
||||
[event magnification], windowPoint, screenPoint);
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
|
||||
- (void)smartMagnifyWithEvent:(NSEvent *)event
|
||||
{
|
||||
static bool zoomIn = true;
|
||||
#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
|
||||
qDebug() << "smartMagnifyWithEvent" << zoomIn;
|
||||
#endif
|
||||
const NSTimeInterval timestamp = [event timestamp];
|
||||
QPointF windowPoint;
|
||||
QPointF screenPoint;
|
||||
[self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
|
||||
QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SmartZoomNativeGesture,
|
||||
zoomIn ? 1.0f : 0.0f, windowPoint, screenPoint);
|
||||
zoomIn = !zoomIn;
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)rotateWithEvent:(NSEvent *)event
|
||||
{
|
||||
#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
|
||||
qDebug() << "rotateWithEvent" << [event rotation];
|
||||
#endif
|
||||
const NSTimeInterval timestamp = [event timestamp];
|
||||
QPointF windowPoint;
|
||||
QPointF screenPoint;
|
||||
[self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
|
||||
QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::RotateNativeGesture,
|
||||
-[event rotation], windowPoint, screenPoint);
|
||||
}
|
||||
|
||||
- (void)swipeWithEvent:(NSEvent *)event
|
||||
{
|
||||
#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
|
||||
qDebug() << "swipeWithEvent" << [event deltaX] << [event deltaY];
|
||||
#endif
|
||||
const NSTimeInterval timestamp = [event timestamp];
|
||||
QPointF windowPoint;
|
||||
QPointF screenPoint;
|
||||
[self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
|
||||
|
||||
qreal angle = 0.0f;
|
||||
if ([event deltaX] == 1)
|
||||
angle = 180.0f;
|
||||
else if ([event deltaX] == -1)
|
||||
angle = 0.0f;
|
||||
else if ([event deltaY] == 1)
|
||||
angle = 90.0f;
|
||||
else if ([event deltaY] == -1)
|
||||
angle = 270.0f;
|
||||
|
||||
QWindowSystemInterface::handleGestureEventWithRealValue(m_window, timestamp, Qt::SwipeNativeGesture,
|
||||
angle, windowPoint, screenPoint);
|
||||
}
|
||||
|
||||
- (void)beginGestureWithEvent:(NSEvent *)event
|
||||
{
|
||||
#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
|
||||
qDebug() << "beginGestureWithEvent";
|
||||
#endif
|
||||
const NSTimeInterval timestamp = [event timestamp];
|
||||
QPointF windowPoint;
|
||||
QPointF screenPoint;
|
||||
[self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
|
||||
QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::BeginNativeGesture,
|
||||
windowPoint, screenPoint);
|
||||
}
|
||||
|
||||
- (void)endGestureWithEvent:(NSEvent *)event
|
||||
{
|
||||
#ifdef QT_COCOA_ENABLE_GESTURE_DEBUG
|
||||
qDebug() << "endGestureWithEvent";
|
||||
#endif
|
||||
const NSTimeInterval timestamp = [event timestamp];
|
||||
QPointF windowPoint;
|
||||
QPointF screenPoint;
|
||||
[self convertFromEvent:event toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
|
||||
QWindowSystemInterface::handleGestureEvent(m_window, timestamp, Qt::EndNativeGesture,
|
||||
windowPoint, screenPoint);
|
||||
}
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
- (void)scrollWheel:(NSEvent *)theEvent
|
||||
{
|
||||
|
@ -66,59 +66,9 @@ SOURCES += \
|
||||
kernel/qwidgetwindow.cpp \
|
||||
kernel/qwindowcontainer.cpp
|
||||
|
||||
|
||||
# TODO
|
||||
false:!x11:mac {
|
||||
SOURCES += \
|
||||
kernel/qclipboard_mac.cpp \
|
||||
kernel/qmime_mac.cpp \
|
||||
kernel/qt_mac.cpp \
|
||||
kernel/qkeymapper_mac.cpp
|
||||
|
||||
OBJECTIVE_HEADERS += \
|
||||
qcocoawindow_mac_p.h \
|
||||
qcocoapanel_mac_p.h \
|
||||
qcocoawindowdelegate_mac_p.h \
|
||||
qcocoaview_mac_p.h \
|
||||
qcocoaapplication_mac_p.h \
|
||||
qcocoaapplicationdelegate_mac_p.h \
|
||||
qmacgesturerecognizer_mac_p.h \
|
||||
qmultitouch_mac_p.h \
|
||||
qcocoasharedwindowmethods_mac_p.h \
|
||||
qcocoaintrospection_p.h
|
||||
|
||||
OBJECTIVE_SOURCES += \
|
||||
kernel/qcursor_mac.mm \
|
||||
kernel/qdnd_mac.mm \
|
||||
kernel/qapplication_mac.mm \
|
||||
kernel/qwidget_mac.mm \
|
||||
kernel/qcocoapanel_mac.mm \
|
||||
kernel/qcocoaview_mac.mm \
|
||||
kernel/qcocoawindow_mac.mm \
|
||||
kernel/qcocoawindowdelegate_mac.mm \
|
||||
kernel/qcocoaapplication_mac.mm \
|
||||
kernel/qcocoaapplicationdelegate_mac.mm \
|
||||
kernel/qt_cocoa_helpers_mac.mm \
|
||||
kernel/qdesktopwidget_mac.mm \
|
||||
kernel/qeventdispatcher_mac.mm \
|
||||
kernel/qcocoawindowcustomthemeframe_mac.mm \
|
||||
kernel/qmacgesturerecognizer_mac.mm \
|
||||
kernel/qmultitouch_mac.mm \
|
||||
kernel/qcocoaintrospection_mac.mm
|
||||
|
||||
HEADERS += \
|
||||
kernel/qt_cocoa_helpers_mac_p.h \
|
||||
kernel/qcocoaapplication_mac_p.h \
|
||||
kernel/qcocoaapplicationdelegate_mac_p.h \
|
||||
kernel/qeventdispatcher_mac_p.h
|
||||
|
||||
MENU_NIB.files = mac/qt_menu.nib
|
||||
MENU_NIB.path = Resources
|
||||
MENU_NIB.version = Versions
|
||||
QMAKE_BUNDLE_DATA += MENU_NIB
|
||||
RESOURCES += mac/macresources.qrc
|
||||
|
||||
LIBS_PRIVATE += -framework AppKit
|
||||
macx: {
|
||||
HEADERS += kernel/qmacgesturerecognizer_p.h
|
||||
SOURCES += kernel/qmacgesturerecognizer.cpp
|
||||
}
|
||||
|
||||
wince*: {
|
||||
|
@ -190,41 +190,6 @@ public:
|
||||
static int Timeout;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
class QNativeGestureEvent : public QEvent
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
None,
|
||||
GestureBegin,
|
||||
GestureEnd,
|
||||
Pan,
|
||||
Zoom,
|
||||
Rotate,
|
||||
Swipe
|
||||
};
|
||||
|
||||
QNativeGestureEvent()
|
||||
: QEvent(QEvent::NativeGesture), gestureType(None), percentage(0)
|
||||
#ifdef Q_WS_WIN
|
||||
, sequenceId(0), argument(0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
Type gestureType;
|
||||
float percentage;
|
||||
QPoint position;
|
||||
float angle;
|
||||
#ifdef Q_WS_WIN
|
||||
ulong sequenceId;
|
||||
quint64 argument;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_GESTURES
|
||||
|
@ -51,8 +51,8 @@
|
||||
#include "qevent.h"
|
||||
#include "qgraphicsitem.h"
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
#include "qmacgesturerecognizer_mac_p.h"
|
||||
#ifdef Q_OS_MAC
|
||||
#include "qmacgesturerecognizer_p.h"
|
||||
#endif
|
||||
#if defined(Q_WS_WIN) && !defined(QT_NO_NATIVE_GESTURES)
|
||||
#include "qwinnativepangesturerecognizer_win_p.h"
|
||||
@ -76,7 +76,7 @@ QGestureManager::QGestureManager(QObject *parent)
|
||||
{
|
||||
qRegisterMetaType<Qt::GestureState>();
|
||||
|
||||
#if defined(Q_WS_MAC)
|
||||
#if defined(Q_OS_MAC)
|
||||
registerGestureRecognizer(new QMacSwipeGestureRecognizer);
|
||||
registerGestureRecognizer(new QMacPinchGestureRecognizer);
|
||||
registerGestureRecognizer(new QMacPanGestureRecognizer);
|
||||
|
275
src/widgets/kernel/qmacgesturerecognizer.cpp
Normal file
275
src/widgets/kernel/qmacgesturerecognizer.cpp
Normal file
@ -0,0 +1,275 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.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<QNativeGestureEvent*>(event);
|
||||
switch (ev->gestureType()) {
|
||||
case Qt::SwipeNativeGesture: {
|
||||
QSwipeGesture *g = static_cast<QSwipeGesture *>(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<QSwipeGesture *>(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<QPinchGesture *>(gesture);
|
||||
QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event);
|
||||
switch (ev->gestureType()) {
|
||||
case Qt::BeginNativeGesture:
|
||||
reset(gesture);
|
||||
g->setStartCenterPoint(static_cast<QWidget*>(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(g->scaleFactor() * (1 + ev->value()));
|
||||
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<QPinchGesture *>(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<QWidget *>(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<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();
|
||||
_panTimer.start(panBeginDelay, target);
|
||||
_panCanceled = false;
|
||||
return QGestureRecognizer::MayBeGesture;
|
||||
}
|
||||
break;}
|
||||
case QEvent::TouchEnd: {
|
||||
if (_panCanceled)
|
||||
break;
|
||||
|
||||
const QTouchEvent *ev = static_cast<const QTouchEvent*>(event);
|
||||
if (ev->touchPoints().size() == 1)
|
||||
return QGestureRecognizer::FinishGesture;
|
||||
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::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<QTimerEvent *>(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<QPanGesture *>(gesture);
|
||||
_startPos = QPointF();
|
||||
_panCanceled = true;
|
||||
g->setOffset(QPointF(0, 0));
|
||||
g->setLastOffset(QPointF(0, 0));
|
||||
g->setAcceleration(qreal(1));
|
||||
QGestureRecognizer::reset(gesture);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_GESTURES
|
102
src/widgets/kernel/qmacgesturerecognizer_p.h
Normal file
102
src/widgets/kernel/qmacgesturerecognizer_p.h
Normal file
@ -0,0 +1,102 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** 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 Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3.0 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU General Public License version 3.0 requirements will be
|
||||
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
**
|
||||
** $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"
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QMacSwipeGestureRecognizer : public QGestureRecognizer
|
||||
{
|
||||
public:
|
||||
QMacSwipeGestureRecognizer();
|
||||
|
||||
QGesture *create(QObject *target);
|
||||
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
|
||||
void reset(QGesture *gesture);
|
||||
};
|
||||
|
||||
class QMacPinchGestureRecognizer : public QGestureRecognizer
|
||||
{
|
||||
public:
|
||||
QMacPinchGestureRecognizer();
|
||||
|
||||
QGesture *create(QObject *target);
|
||||
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
|
||||
void reset(QGesture *gesture);
|
||||
};
|
||||
|
||||
class QMacPanGestureRecognizer : public QObject, public QGestureRecognizer
|
||||
{
|
||||
public:
|
||||
QMacPanGestureRecognizer();
|
||||
|
||||
QGesture *create(QObject *target);
|
||||
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
|
||||
void reset(QGesture *gesture);
|
||||
private:
|
||||
QPointF _startPos;
|
||||
QBasicTimer _panTimer;
|
||||
bool _panCanceled;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
#endif // QMACSWIPEGESTURERECOGNIZER_MAC_P_H
|
@ -49,6 +49,7 @@
|
||||
#endif
|
||||
#include <private/qwidgetbackingstore_p.h>
|
||||
#include <qpa/qwindowsysteminterface_p.h>
|
||||
#include <private/qgesturemanager_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -220,6 +221,13 @@ bool QWidgetWindow::event(QEvent *event)
|
||||
handleTabletEvent(static_cast<QTabletEvent *>(event));
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
case QEvent::NativeGesture:
|
||||
handleGestureEvent(static_cast<QNativeGestureEvent *>(event));
|
||||
return true;
|
||||
#endif
|
||||
|
||||
#ifndef QT_NO_CONTEXTMENU
|
||||
case QEvent::ContextMenu:
|
||||
handleContextMenuEvent(static_cast<QContextMenuEvent *>(event));
|
||||
@ -732,6 +740,25 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
|
||||
}
|
||||
#endif // QT_NO_TABLETEVENT
|
||||
|
||||
#ifndef QT_NO_GESTURES
|
||||
void QWidgetWindow::handleGestureEvent(QNativeGestureEvent *e)
|
||||
{
|
||||
// copy-pasted code to find correct widget follows:
|
||||
QObject *receiver = 0;
|
||||
if (QApplicationPrivate::inPopupMode()) {
|
||||
QWidget *popup = QApplication::activePopupWidget();
|
||||
QWidget *popupFocusWidget = popup->focusWidget();
|
||||
receiver = popupFocusWidget ? popupFocusWidget : popup;
|
||||
}
|
||||
if (!receiver)
|
||||
receiver = QApplication::widgetAt(e->globalPos());
|
||||
if (!receiver)
|
||||
receiver = m_widget; // last resort
|
||||
|
||||
QApplication::sendSpontaneousEvent(receiver, e);
|
||||
}
|
||||
#endif // QT_NO_GESTURES
|
||||
|
||||
#ifndef QT_NO_CONTEXTMENU
|
||||
void QWidgetWindow::handleContextMenuEvent(QContextMenuEvent *e)
|
||||
{
|
||||
|
@ -91,6 +91,9 @@ protected:
|
||||
#ifndef QT_NO_TABLETEVENT
|
||||
void handleTabletEvent(QTabletEvent *);
|
||||
#endif
|
||||
#ifndef QT_NO_GESTURES
|
||||
void handleGestureEvent(QNativeGestureEvent *);
|
||||
#endif
|
||||
#ifndef QT_NO_CONTEXTMENU
|
||||
void handleContextMenuEvent(QContextMenuEvent *);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user