diff options
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_win.cpp | 12 | ||||
-rw-r--r-- | src/gui/kernel/qevent.cpp | 1 | ||||
-rw-r--r-- | src/gui/kernel/qevent_p.h | 14 | ||||
-rw-r--r-- | src/gui/kernel/qgesture.cpp | 45 | ||||
-rw-r--r-- | src/gui/kernel/qgesture.h | 14 | ||||
-rw-r--r-- | src/gui/kernel/qgesture_p.h | 11 | ||||
-rw-r--r-- | src/gui/kernel/qstandardgestures.cpp | 243 | ||||
-rw-r--r-- | src/gui/kernel/qstandardgestures.h | 20 | ||||
-rw-r--r-- | src/gui/kernel/qstandardgestures_p.h | 29 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 60 |
11 files changed, 180 insertions, 271 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 7aeab39..5d1ef8c 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -4129,7 +4129,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) res = d->notify_helper(receiver, e); break; - case QEvent::WinGesture: + case QEvent::NativeGesture: { // only propagate the first gesture event (after the GID_BEGIN) QWidget *w = static_cast<QWidget *>(receiver); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 8eeac65..0a38870 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3735,22 +3735,22 @@ bool QETWidget::translateGestureEvent(const MSG &msg) alienWidget = 0; QWidget *widget = alienWidget ? alienWidget : this; - QWinGestureEvent event; + QNativeGestureEvent event; event.sequenceId = gi.dwSequenceID; event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); if (bResult) { switch (gi.dwID) { case GID_BEGIN: - // we are not interested in this type of event. + event.gestureType = QNativeGestureEvent::GestureBegin; break; case GID_END: - event.gestureType = QWinGestureEvent::GestureEnd; + event.gestureType = QNativeGestureEvent::GestureEnd; break; case GID_ZOOM: - event.gestureType = QWinGestureEvent::Pinch; + event.gestureType = QNativeGestureEvent::Pinch; break; case GID_PAN: - event.gestureType = QWinGestureEvent::Pan; + event.gestureType = QNativeGestureEvent::Pan; break; case GID_ROTATE: case GID_TWOFINGERTAP: @@ -3758,7 +3758,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) default: break; } - if (event.gestureType != QWinGestureEvent::None) + if (event.gestureType != QNativeGestureEvent::None) qt_sendSpontaneousEvent(widget, &event); } else { DWORD dwErr = GetLastError(); diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 2a91181..0e5d5b9 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -49,7 +49,6 @@ #include "qmime.h" #include "qdnd_p.h" #include "qevent_p.h" -#include "qgesture.h" QT_BEGIN_NAMESPACE diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 67441ea..92c4fc1 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -119,20 +119,30 @@ public: qreal pressure; }; -class QWinGestureEvent : public QEvent +class QNativeGestureEvent : public QEvent { public: enum Type { None, + GestureBegin, GestureEnd, Pan, Pinch }; - QWinGestureEvent() : QEvent(QEvent::WinGesture), gestureType(None), sequenceId(0) { } + QNativeGestureEvent() + : QEvent(QEvent::NativeGesture), gestureType(None) +#ifdef Q_WS_WIN + , sequenceId(0) +#endif + { + } + Type gestureType; +#ifdef Q_WS_WIN QPoint position; ulong sequenceId; +#endif }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 1f98013..32ac4f8 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -205,51 +205,6 @@ void QGesture::setState(Qt::GestureState state) } /*! - \property QGesture::startPos - - \brief The start position of the gesture (if relevant). -*/ -QPoint QGesture::startPos() const -{ - return d_func()->startPos; -} - -void QGesture::setStartPos(const QPoint &point) -{ - d_func()->startPos = point; -} - -/*! - \property QGesture::lastPos - - \brief The last recorded position of the gesture (if relevant). -*/ -QPoint QGesture::lastPos() const -{ - return d_func()->lastPos; -} - -void QGesture::setLastPos(const QPoint &point) -{ - d_func()->lastPos = point; -} - -/*! - \property QGesture::pos - - \brief The current position of the gesture (if relevant). -*/ -QPoint QGesture::pos() const -{ - return d_func()->pos; -} - -void QGesture::setPos(const QPoint &point) -{ - d_func()->pos = point; -} - -/*! Sets the \a graphicsItem the gesture is filtering events for. The gesture will install an event filter to the \a graphicsItem and diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index 8390d11..a4bd2c2 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -64,10 +64,6 @@ class Q_GUI_EXPORT QGesture : public QObject Q_PROPERTY(Qt::GestureState state READ state) - Q_PROPERTY(QPoint startPos READ startPos WRITE setStartPos) - Q_PROPERTY(QPoint lastPos READ lastPos WRITE setLastPos) - Q_PROPERTY(QPoint pos READ pos WRITE setPos) - public: explicit QGesture(QObject *parent = 0); ~QGesture(); @@ -80,19 +76,13 @@ public: virtual void reset(); Qt::GestureState state() const; - void setState(Qt::GestureState state); - - QPoint startPos() const; - void setStartPos(const QPoint &point); - QPoint lastPos() const; - void setLastPos(const QPoint &point); - QPoint pos() const; - void setPos(const QPoint &point); protected: QGesture(QGesturePrivate &dd, QObject *parent); bool eventFilter(QObject*, QEvent*); + void setState(Qt::GestureState state); + Q_SIGNALS: void started(); void triggered(); diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index 99f572f..56eaee7 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -73,22 +73,11 @@ public: { } - void init(const QPoint &startPos, const QPoint &lastPos, - const QPoint &pos) - { - this->startPos = startPos; - this->lastPos = lastPos; - this->pos = pos; - } QGraphicsItem *graphicsItem; QGraphicsItem *eventFilterProxyGraphicsItem; Qt::GestureState state; - - QPoint startPos; - QPoint lastPos; - QPoint pos; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index c8b11c5..4753416 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -45,9 +45,14 @@ #include <qabstractscrollarea.h> #include <qscrollbar.h> #include <private/qapplication_p.h> +#include <private/qevent_p.h> QT_BEGIN_NAMESPACE +#ifdef Q_WS_WIN +QApplicationPrivate* getQApplicationPrivateInternal(); +#endif + /*! \class QPanGesture \since 4.6 @@ -68,7 +73,6 @@ QPanGesture::QPanGesture(QWidget *parent) { #ifdef Q_WS_WIN if (parent) { - QApplicationPrivate* getQApplicationPrivateInternal(); QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); qAppPriv->widgetGestures[parent].pan = this; } @@ -93,9 +97,81 @@ bool QPanGesture::event(QEvent *event) break; } #endif + +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + Q_D(QPanGesture); + if (event->type() == QEvent::Timer) { + const QTimerEvent *te = static_cast<QTimerEvent *>(event); + if (te->timerId() == d->panFinishedTimer) { + killTimer(d->panFinishedTimer); + d->panFinishedTimer = 0; + d->lastOffset = QSize(0, 0); + setState(Qt::GestureFinished); + emit triggered(); + setState(Qt::NoGesture); + } + } +#endif + return QObject::event(event); } +bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) +{ +#ifdef Q_WS_WIN + if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { + QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); + QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); + QApplicationPrivate::WidgetStandardGesturesMap::iterator it; + it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver)); + if (it == qAppPriv->widgetGestures.end()) + return false; + QPanGesture *gesture = it.value().pan; + if (!gesture) + return false; + Qt::GestureState nextState = state(); + switch(ev->gestureType) { + case QNativeGestureEvent::GestureBegin: + // next we might receive the first gesture update event, so we + // prepare for it. + setState(Qt::GestureStarted); + return false; + case QNativeGestureEvent::Pan: + nextState = Qt::GestureUpdated; + break; + case QNativeGestureEvent::GestureEnd: + if (state() != QNativeGestureEvent::Pan) + return false; // some other gesture has ended + setState(Qt::GestureFinished); + nextState = Qt::GestureFinished; + break; + default: + return false; + } + QPanGesturePrivate *d = gesture->d_func(); + if (state() == Qt::GestureStarted) { + d->lastPosition = ev->position; + d->lastOffset = d->totalOffset = QSize(); + } else { + d->lastOffset = QSize(ev->position.x() - d->lastPosition.x(), + ev->position.y() - d->lastPosition.y()); + d->totalOffset += d->lastOffset; + } + d->lastPosition = ev->position; + + if (state() == Qt::GestureStarted) + emit gesture->started(); + emit gesture->triggered(); + if (state() == Qt::GestureFinished) + emit gesture->finished(); + event->accept(); + gesture->setState(nextState); + return true; + } +#endif + return QGesture::eventFilter(receiver, event); +} + /*! \internal */ bool QPanGesture::filterEvent(QEvent *event) { @@ -104,28 +180,34 @@ bool QPanGesture::filterEvent(QEvent *event) return false; const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); if (event->type() == QEvent::TouchBegin) { - d->touchPoints = ev->touchPoints(); - const QPoint p = ev->touchPoints().at(0).pos().toPoint(); - setStartPos(p); - setLastPos(p); - setPos(p); - return false; + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + d->lastPosition = p.pos().toPoint(); + d->lastOffset = d->totalOffset = QSize(); } else if (event->type() == QEvent::TouchEnd) { if (state() != Qt::NoGesture) { setState(Qt::GestureFinished); - setLastPos(pos()); - setPos(ev->touchPoints().at(0).pos().toPoint()); + if (!ev->touchPoints().isEmpty()) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + const QPoint pos = p.pos().toPoint(); + const QPoint lastPos = p.lastPos().toPoint(); + const QPoint startPos = p.startPos().toPoint(); + d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y()); + d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y()); + } emit triggered(); emit finished(); } setState(Qt::NoGesture); reset(); } else if (event->type() == QEvent::TouchUpdate) { - d->touchPoints = ev->touchPoints(); - QPointF pt = d->touchPoints.at(0).pos() - d->touchPoints.at(0).startPos(); - setLastPos(pos()); - setPos(ev->touchPoints().at(0).pos().toPoint()); - if (pt.x() > 10 || pt.y() > 10 || pt.x() < -10 || pt.y() < -10) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + const QPoint pos = p.pos().toPoint(); + const QPoint lastPos = p.lastPos().toPoint(); + const QPoint startPos = p.startPos().toPoint(); + d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y()); + d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y()); + if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 || + d->totalOffset.width() < -10 || d->totalOffset.height() < -10) { if (state() == Qt::NoGesture) setState(Qt::GestureStarted); else @@ -133,6 +215,36 @@ bool QPanGesture::filterEvent(QEvent *event) emit triggered(); } } +#ifdef Q_OS_MAC + else if (event->type() == QEvent::Wheel) { + // On Mac, there is really no native panning gesture. Instead, a two + // finger pan is delivered as mouse wheel events. Otoh, on Windows, you + // either get mouse wheel events or pan events. We have decided to make this + // the Qt behaviour as well, meaning that on Mac, wheel + // events will be masked away when listening for pan events. +#ifndef QT_MAC_USE_COCOA + // In Carbon we receive neither touch-, nor pan gesture events. + // So we create pan gestures by converting wheel events. After all, this + // is how things are supposed to work on mac in the first place. + const QWheelEvent *wev = static_cast<const QWheelEvent*>(event); + int offset = wev->delta() / -120; + d->lastOffset = wev->orientation() == Qt::Horizontal ? QSize(offset, 0) : QSize(0, offset); + + if (state() == Qt::NoGesture) { + setState(Qt::GestureStarted); + d->totalOffset = d->lastOffset; + } else { + setState(Qt::GestureUpdated); + d->totalOffset += d->lastOffset; + } + + killTimer(d->panFinishedTimer); + d->panFinishedTimer = startTimer(200); + emit triggered(); +#endif + return true; + } +#endif return false; } @@ -140,7 +252,14 @@ bool QPanGesture::filterEvent(QEvent *event) void QPanGesture::reset() { Q_D(QPanGesture); - d->touchPoints.clear(); + d->lastOffset = d->totalOffset = QSize(); + d->lastPosition = QPoint(); +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + if (d->panFinishedTimer) { + killTimer(d->panFinishedTimer); + d->panFinishedTimer = 0; + } +#endif } /*! @@ -150,8 +269,8 @@ void QPanGesture::reset() */ QSize QPanGesture::totalOffset() const { - QPoint pt = pos() - startPos(); - return QSize(pt.x(), pt.y()); + Q_D(const QPanGesture); + return d->totalOffset; } /*! @@ -162,93 +281,11 @@ QSize QPanGesture::totalOffset() const */ QSize QPanGesture::lastOffset() const { - QPoint pt = pos() - lastPos(); - return QSize(pt.x(), pt.y()); -} - -/*! - \class QTapAndHoldGesture - \since 4.6 - - \brief The QTapAndHoldGesture class represents a Tap-and-Hold gesture, - providing additional information. -*/ - -const int QTapAndHoldGesturePrivate::iterationCount = 40; -const int QTapAndHoldGesturePrivate::iterationTimeout = 50; - -/*! - Creates a new Tap and Hold gesture handler object and marks it as a child - of \a parent. - - On some platforms like Windows there is a system-wide tap and hold gesture - that cannot be overriden, hence the gesture might never trigger and default - context menu will be shown instead. -*/ -QTapAndHoldGesture::QTapAndHoldGesture(QWidget *parent) - : QGesture(*new QTapAndHoldGesturePrivate, parent) -{ -} - -/*! \internal */ -bool QTapAndHoldGesture::filterEvent(QEvent *event) -{ - Q_D(QTapAndHoldGesture); - if (!event->spontaneous()) - return false; - const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); - switch (event->type()) { - case QEvent::TouchBegin: { - if (d->timer.isActive()) - d->timer.stop(); - d->timer.start(QTapAndHoldGesturePrivate::iterationTimeout, this); - const QPoint p = ev->touchPoints().at(0).pos().toPoint(); - setStartPos(p); - setLastPos(p); - setPos(p); - break; - } - case QEvent::TouchUpdate: - if (ev->touchPoints().size() != 1) - reset(); - else if ((startPos() - ev->touchPoints().at(0).pos().toPoint()).manhattanLength() > 15) - reset(); - break; - case QEvent::TouchEnd: - reset(); - break; - default: - break; - } - return false; + Q_D(const QPanGesture); + return d->lastOffset; } -/*! \internal */ -void QTapAndHoldGesture::timerEvent(QTimerEvent *event) -{ - Q_D(QTapAndHoldGesture); - if (event->timerId() != d->timer.timerId()) - return; - if (d->iteration == QTapAndHoldGesturePrivate::iterationCount) { - d->timer.stop(); - setState(Qt::GestureFinished); - emit triggered(); - } else { - setState(Qt::GestureStarted); - emit triggered(); - } - ++d->iteration; -} +QT_END_NAMESPACE -/*! \internal */ -void QTapAndHoldGesture::reset() -{ - Q_D(QTapAndHoldGesture); - if (state() != Qt::NoGesture) - emit cancelled(); - setState(Qt::NoGesture); - d->timer.stop(); - d->iteration = 0; -} +#include "moc_qstandardgestures.cpp" -QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index a777253..fc7cb00 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -71,29 +71,13 @@ public: QSize totalOffset() const; QSize lastOffset() const; -protected: +private: bool event(QEvent *event); + bool eventFilter(QObject *receiver, QEvent *event); -private: friend class QWidget; }; -class QTapAndHoldGesturePrivate; -class Q_GUI_EXPORT QTapAndHoldGesture : public QGesture -{ - Q_OBJECT - Q_DECLARE_SCOPED_PRIVATE(QTapAndHoldGesture) - -public: - QTapAndHoldGesture(QWidget *parent); - - bool filterEvent(QEvent *event); - void reset(); - -protected: - void timerEvent(QTimerEvent *event); -}; - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index bb11c9f..0fe24ee 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -60,6 +60,8 @@ #include "qgesture.h" #include "qgesture_p.h" +#include "qstandardgestures.h" + QT_BEGIN_NAMESPACE class QPanGesturePrivate : public QGesturePrivate @@ -67,23 +69,20 @@ class QPanGesturePrivate : public QGesturePrivate Q_DECLARE_PUBLIC(QPanGesture) public: - QPanGesturePrivate() { } - - QList<QTouchEvent::TouchPoint> touchPoints; -}; + QPanGesturePrivate() + { +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + panFinishedTimer = 0; +#endif + } -class QTapAndHoldGesturePrivate : public QGesturePrivate -{ - Q_DECLARE_PUBLIC(QTapAndHoldGesture) - -public: - QTapAndHoldGesturePrivate() - : iteration(0) { } + QSize totalOffset; + QSize lastOffset; + QPoint lastPosition; - QBasicTimer timer; - int iteration; - static const int iterationCount; - static const int iterationTimeout; +#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA) + int panFinishedTimer; +#endif }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e990358..a8157d5 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1454,10 +1454,9 @@ QWidget::~QWidget() // set all QPointers for this object to zero QObjectPrivate::clearGuards(this); - if(d->declarativeData) { - QDeclarativeData *dd = d->declarativeData; - d->declarativeData = 0; - dd->destroyed(this); + if (d->declarativeData) { + d->declarativeData->destroyed(this); + d->declarativeData = 0; // don't activate again in ~QObject } if (!d->children.isEmpty()) @@ -8070,59 +8069,6 @@ bool QWidget::event(QEvent *event) #endif break; } -#ifdef Q_WS_WIN - case QEvent::WinGesture: { - QWinGestureEvent *ev = static_cast<QWinGestureEvent*>(event); - QApplicationPrivate *qAppPriv = qApp->d_func(); - QApplicationPrivate::WidgetStandardGesturesMap::iterator it; - it = qAppPriv->widgetGestures.find(this); - if (it != qAppPriv->widgetGestures.end()) { - Qt::GestureState state = Qt::GestureUpdated; - if (qAppPriv->lastGestureId == 0) - state = Qt::GestureStarted; - QWinGestureEvent::Type type = ev->gestureType; - if (ev->gestureType == QWinGestureEvent::GestureEnd) { - type = (QWinGestureEvent::Type)qAppPriv->lastGestureId; - state = Qt::GestureFinished; - } - - QGesture *gesture = 0; - switch (type) { - case QWinGestureEvent::Pan: { - QPanGesture *pan = it.value().pan; - gesture = pan; - if (state == Qt::GestureStarted) { - gesture->setStartPos(ev->position); - gesture->setLastPos(ev->position); - } else { - gesture->setLastPos(gesture->pos()); - } - gesture->setPos(ev->position); - break; - } - case QWinGestureEvent::Pinch: - break; - default: - break; - } - if (gesture) { - gesture->setState(state); - if (state == Qt::GestureStarted) - emit gesture->started(); - emit gesture->triggered(); - if (state == Qt::GestureFinished) - emit gesture->finished(); - event->accept(); - } - if (ev->gestureType == QWinGestureEvent::GestureEnd) { - qAppPriv->lastGestureId = 0; - } else { - qAppPriv->lastGestureId = type; - } - } - break; - } -#endif #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName(); |