diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-11-04 18:26:40 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-11-05 11:54:51 (GMT) |
commit | 6777135b2cacd3a72a60ff372749837b67762fbe (patch) | |
tree | 5caf0678a75d45bc927cf284c543d06b28a32828 | |
parent | f4450efb6fbc9fd0e592d5bc3bce37d5bf272984 (diff) | |
download | Qt-6777135b2cacd3a72a60ff372749837b67762fbe.zip Qt-6777135b2cacd3a72a60ff372749837b67762fbe.tar.gz Qt-6777135b2cacd3a72a60ff372749837b67762fbe.tar.bz2 |
Implemented Tap and TapAndHold gestures.
Added QGesture objects and gesture recognizers based on touch events.
Reviewed-by: Bradley T. Hughes
-rw-r--r-- | src/gui/kernel/qgesture.cpp | 66 | ||||
-rw-r--r-- | src/gui/kernel/qgesture.h | 34 | ||||
-rw-r--r-- | src/gui/kernel/qgesture_p.h | 26 | ||||
-rw-r--r-- | src/gui/kernel/qgesturemanager.cpp | 5 | ||||
-rw-r--r-- | src/gui/kernel/qstandardgestures.cpp | 153 | ||||
-rw-r--r-- | src/gui/kernel/qstandardgestures_p.h | 20 |
6 files changed, 303 insertions, 1 deletions
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 4edf8a9..88c04e2 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -667,4 +667,70 @@ void QSwipeGesture::setSwipeAngle(qreal value) d_func()->swipeAngle = value; } +/*! + \class QTapGesture + \since 4.6 + \brief The QTapGesture class describes a tap gesture made by the user. + \ingroup gestures + + \sa {Gestures Programming}, QPanGesture, QPinchGesture +*/ + +/*! + \property QTapGesture::position + \brief the position of the tap +*/ + +/*! + \internal +*/ +QTapGesture::QTapGesture(QObject *parent) + : QGesture(*new QTapGesturePrivate, parent) +{ + d_func()->gestureType = Qt::TapGesture; +} + +QPointF QTapGesture::position() const +{ + return d_func()->position; +} + +void QTapGesture::setPosition(const QPointF &value) +{ + d_func()->position = value; +} +/*! + \class QTapAndHoldGesture + \since 4.6 + \brief The QTapAndHoldGesture class describes a tap-and-hold (aka LongTap) + gesture made by the user. + \ingroup gestures + + \sa {Gestures Programming}, QPanGesture, QPinchGesture +*/ + +/*! + \property QTapAndHoldGesture::position + \brief the position of the tap +*/ + +/*! + \internal +*/ +QTapAndHoldGesture::QTapAndHoldGesture(QObject *parent) + : QGesture(*new QTapAndHoldGesturePrivate, parent) +{ + d_func()->gestureType = Qt::TapAndHoldGesture; +} + +QPointF QTapAndHoldGesture::position() const +{ + return d_func()->position; +} + +void QTapAndHoldGesture::setPosition(const QPointF &value) +{ + d_func()->position = value; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index dd322ad..f995d7b 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -219,6 +219,40 @@ public: friend class QSwipeGestureRecognizer; }; +class QTapGesturePrivate; +class Q_GUI_EXPORT QTapGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QTapGesture) + + Q_PROPERTY(QPointF position READ position WRITE setPosition) + +public: + QTapGesture(QObject *parent = 0); + + QPointF position() const; + void setPosition(const QPointF &pos); + + friend class QTapGestureRecognizer; +}; + +class QTapAndHoldGesturePrivate; +class Q_GUI_EXPORT QTapAndHoldGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QTapAndHoldGesture) + + Q_PROPERTY(QPointF position READ position WRITE setPosition) + +public: + QTapAndHoldGesture(QObject *parent = 0); + + QPointF position() const; + void setPosition(const QPointF &pos); + + friend class QTapAndHoldGestureRecognizer; +}; + QT_END_NAMESPACE Q_DECLARE_METATYPE(QGesture::GestureCancelPolicy) diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index a571bdb..2537f47 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -151,6 +151,32 @@ public: QTime time; }; +class QTapGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QTapGesture) + +public: + QTapGesturePrivate() + { + } + + QPointF position; +}; + +class QTapAndHoldGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QTapAndHoldGesture) + +public: + QTapAndHoldGesturePrivate() + : timerId(0) + { + } + + QPointF position; + int timerId; +}; + QT_END_NAMESPACE #endif // QGESTURE_P_H diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 662a64b..375116f 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -91,9 +91,12 @@ QGestureManager::QGestureManager(QObject *parent) registerGestureRecognizer(new QPanGestureRecognizer); registerGestureRecognizer(new QPinchGestureRecognizer); registerGestureRecognizer(new QSwipeGestureRecognizer); + registerGestureRecognizer(new QTapGestureRecognizer); +#endif #if defined(Q_OS_WIN) registerGestureRecognizer(new QWinNativePanGestureRecognizer); -#endif +#else + registerGestureRecognizer(new QTapAndHoldGestureRecognizer); #endif } diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index a0055a1..3cc1b4b 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -407,4 +407,157 @@ void QSwipeGestureRecognizer::reset(QGesture *state) QGestureRecognizer::reset(state); } +// +// QTapGestureRecognizer +// + +QTapGestureRecognizer::QTapGestureRecognizer() +{ +} + +QGesture *QTapGestureRecognizer::create(QObject *target) +{ + if (target && target->isWidgetType()) { + static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents); + } + return new QTapGesture; +} + +QGestureRecognizer::Result QTapGestureRecognizer::recognize(QGesture *state, + QObject *, + QEvent *event) +{ + QTapGesture *q = static_cast<QTapGesture *>(state); + QTapGesturePrivate *d = q->d_func(); + + const QTouchEvent *ev = static_cast<const QTouchEvent *>(event); + + QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture; + + switch (event->type()) { + case QEvent::TouchBegin: { + d->position = ev->touchPoints().at(0).pos(); + result = QGestureRecognizer::TriggerGesture; + break; + } + case QEvent::TouchUpdate: + case QEvent::TouchEnd: { + if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + QPoint delta = p.pos().toPoint() - p.startPos().toPoint(); + enum { TapRadius = 40 }; + if (delta.manhattanLength() <= TapRadius) { + if (event->type() == QEvent::TouchEnd) + result = QGestureRecognizer::FinishGesture; + else + result = QGestureRecognizer::TriggerGesture; + } + } + break; + } + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + result = QGestureRecognizer::Ignore; + break; + default: + result = QGestureRecognizer::Ignore; + break; + } + return result; +} + +void QTapGestureRecognizer::reset(QGesture *state) +{ + QTapGesture *q = static_cast<QTapGesture *>(state); + QTapGesturePrivate *d = q->d_func(); + + d->position = QPointF(); + + QGestureRecognizer::reset(state); +} + +// +// QTapAndHoldGestureRecognizer +// + +QTapAndHoldGestureRecognizer::QTapAndHoldGestureRecognizer() +{ +} + +QGesture *QTapAndHoldGestureRecognizer::create(QObject *target) +{ + if (target && target->isWidgetType()) { + static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents); + } + return new QTapAndHoldGesture; +} + +QGestureRecognizer::Result +QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object, + QEvent *event) +{ + QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state); + QTapAndHoldGesturePrivate *d = q->d_func(); + + if (object == state && event->type() == QEvent::Timer) { + q->killTimer(d->timerId); + d->timerId = 0; + return QGestureRecognizer::Ignore | QGestureRecognizer::ConsumeEventHint; + } + + const QTouchEvent *ev = static_cast<const QTouchEvent *>(event); + + QGestureRecognizer::Result result = QGestureRecognizer::CancelGesture; + + enum { TimerInterval = 2000 }; + enum { TapRadius = 40 }; + + switch (event->type()) { + case QEvent::TouchBegin: + d->position = ev->touchPoints().at(0).pos(); + if (d->timerId) + q->killTimer(d->timerId); + d->timerId = q->startTimer(TimerInterval); + result = QGestureRecognizer::TriggerGesture; + break; + case QEvent::TouchEnd: + if (d->timerId) + result = QGestureRecognizer::CancelGesture; + else + result = QGestureRecognizer::FinishGesture; + break; + case QEvent::TouchUpdate: + if (q->state() != Qt::NoGesture && ev->touchPoints().size() == 1) { + QTouchEvent::TouchPoint p = ev->touchPoints().at(0); + QPoint delta = p.pos().toPoint() - p.startPos().toPoint(); + if (delta.manhattanLength() <= TapRadius) + result = QGestureRecognizer::TriggerGesture; + } + break; + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + result = QGestureRecognizer::Ignore; + break; + default: + result = QGestureRecognizer::Ignore; + break; + } + return result; +} + +void QTapAndHoldGestureRecognizer::reset(QGesture *state) +{ + QTapAndHoldGesture *q = static_cast<QTapAndHoldGesture *>(state); + QTapAndHoldGesturePrivate *d = q->d_func(); + + d->position = QPointF(); + if (d->timerId) + q->killTimer(d->timerId); + d->timerId = 0; + + QGestureRecognizer::reset(state); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 90f995d..8fea2bc 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -88,6 +88,26 @@ public: void reset(QGesture *state); }; +class QTapGestureRecognizer : public QGestureRecognizer +{ +public: + QTapGestureRecognizer(); + + QGesture *create(QObject *target); + QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; + +class QTapAndHoldGestureRecognizer : public QGestureRecognizer +{ +public: + QTapAndHoldGestureRecognizer(); + + QGesture *create(QObject *target); + QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; + QT_END_NAMESPACE #endif // QSTANDARDGESTURES_P_H |