From f13908359f08d856c2825988e65651dbf744c0e4 Mon Sep 17 00:00:00 2001
From: Denis Dzyubenko <denis.dzyubenko@nokia.com>
Date: Fri, 21 Aug 2009 13:57:18 +0200
Subject: Improved a QGesture api a little bit.

Changed the constructor of the QGesture to separate the gesture target (the
object/widget that the gesture filters events for), and the parent object.

Reviewed-by: Richard Moe Gustavsen
---
 src/gui/kernel/qgesture.cpp          | 37 ++++++++++++---
 src/gui/kernel/qgesture.h            |  8 +++-
 src/gui/kernel/qgesture_p.h          |  5 +-
 src/gui/kernel/qstandardgestures.cpp | 92 ++++++++++++++++--------------------
 src/gui/kernel/qstandardgestures.h   |  4 +-
 src/gui/kernel/qstandardgestures_p.h |  5 ++
 6 files changed, 88 insertions(+), 63 deletions(-)

diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index 79dcae1..eeb6528 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -149,20 +149,18 @@ private:
 
     \sa setGraphicsItem()
 */
-QGesture::QGesture(QObject *parent)
+QGesture::QGesture(QObject *gestureTarget, QObject *parent)
     : QObject(*new QGesturePrivate, parent)
 {
-    if (parent)
-        parent->installEventFilter(this);
+    setGestureTarget(gestureTarget);
 }
 
 /*! \internal
  */
-QGesture::QGesture(QGesturePrivate &dd, QObject *parent)
+QGesture::QGesture(QGesturePrivate &dd, QObject *gestureTarget, QObject *parent)
     : QObject(dd, parent)
 {
-    if (parent)
-        parent->installEventFilter(this);
+    setGestureTarget(gestureTarget);
 }
 
 /*!
@@ -172,6 +170,33 @@ QGesture::~QGesture()
 {
 }
 
+/*!
+    \property QGesture::gestureTarget
+
+    Gesture target is the object that the gesture will observe for events.
+    Typically this means that the gesture installs an event filter on the
+    target object.
+*/
+void QGesture::setGestureTarget(QObject *object)
+{
+    d_func()->setupGestureTarget(object);
+}
+
+QObject* QGesture::gestureTarget() const
+{
+    return d_func()->gestureTarget;
+}
+
+void QGesturePrivate::setupGestureTarget(QObject *object)
+{
+    Q_Q(QGesture);
+    if (gestureTarget)
+        gestureTarget->removeEventFilter(q);
+    if (object)
+        object->installEventFilter(q);
+    gestureTarget = object;
+}
+
 /*! \internal
  */
 bool QGesture::eventFilter(QObject *receiver, QEvent *event)
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
index ee28ea4..1d2fa6d 100644
--- a/src/gui/kernel/qgesture.h
+++ b/src/gui/kernel/qgesture.h
@@ -63,20 +63,24 @@ class Q_GUI_EXPORT QGesture : public QObject
     Q_DECLARE_PRIVATE(QGesture)
 
     Q_PROPERTY(Qt::GestureState state READ state)
+    Q_PROPERTY(QObject* gestureTarget READ gestureTarget WRITE setGestureTarget)
 
 public:
-    explicit QGesture(QObject *parent = 0);
+    explicit QGesture(QObject *gestureTarget = 0, QObject *parent = 0);
     ~QGesture();
 
     virtual bool filterEvent(QEvent *event) = 0;
 
+    void setGestureTarget(QObject *object);
+    QObject* gestureTarget() const;
+
     void setGraphicsItem(QGraphicsItem *);
     QGraphicsItem *graphicsItem() const;
 
     Qt::GestureState state() const;
 
 protected:
-    QGesture(QGesturePrivate &dd, QObject *parent);
+    QGesture(QGesturePrivate &dd, QObject *gestureTarget, QObject *parent);
     bool eventFilter(QObject*, QEvent*);
 
     virtual void reset();
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index 37f3146..f584713 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -69,11 +69,14 @@ class QGesturePrivate : public QObjectPrivate
 
 public:
     QGesturePrivate()
-        : graphicsItem(0), eventFilterProxyGraphicsItem(0), state(Qt::NoGesture)
+        : gestureTarget(0), graphicsItem(0), eventFilterProxyGraphicsItem(0),
+          state(Qt::NoGesture)
     {
     }
 
+    virtual void setupGestureTarget(QObject *o);
 
+    QPointer<QObject> gestureTarget;
     QGraphicsItem *graphicsItem;
     QGraphicsItem *eventFilterProxyGraphicsItem;
 
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index 8c50c78..d798d32 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -69,42 +69,35 @@ QWidgetPrivate *qt_widget_private(QWidget *widget);
     On some platform like Windows it's necessary to provide a non-null widget
     as \a parent to get native gesture support.
 */
-QPanGesture::QPanGesture(QWidget *parent)
-    : QGesture(*new QPanGesturePrivate, parent)
+QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent)
+    : QGesture(*new QPanGesturePrivate, gestureTarget, parent)
 {
-    if (parent) {
-        QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
-        qAppPriv->widgetGestures[parent].pan = this;
-#ifdef Q_WS_WIN
-        qt_widget_private(parent)->winSetupGestures();
-#endif
-    }
 }
 
-/*! \internal */
-bool QPanGesture::event(QEvent *event)
+void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget)
 {
-    switch (event->type()) {
-    case QEvent::ParentAboutToChange:
-        if (QWidget *w = qobject_cast<QWidget*>(parent())) {
-            QApplicationPrivate::instance()->widgetGestures[w].pan = 0;
+    Q_Q(QPanGesture);
+    if (gestureTarget && gestureTarget->isWidgetType()) {
+        QWidget *w = static_cast<QWidget*>(gestureTarget.data());
+        QApplicationPrivate::instance()->widgetGestures[w].pan = 0;
 #ifdef Q_WS_WIN
-            qt_widget_private(w)->winSetupGestures();
+        qt_widget_private(w)->winSetupGestures();
 #endif
-        }
-        break;
-    case QEvent::ParentChange:
-        if (QWidget *w = qobject_cast<QWidget*>(parent())) {
-            QApplicationPrivate::instance()->widgetGestures[w].pan = this;
+    }
+
+    if (newGestureTarget && newGestureTarget->isWidgetType()) {
+        QWidget *w = static_cast<QWidget*>(newGestureTarget);
+        QApplicationPrivate::instance()->widgetGestures[w].pan = q;
 #ifdef Q_WS_WIN
-            qt_widget_private(w)->winSetupGestures();
+        qt_widget_private(w)->winSetupGestures();
 #endif
-        }
-        break;
-    default:
-        break;
     }
+    QGesturePrivate::setupGestureTarget(newGestureTarget);
+}
 
+/*! \internal */
+bool QPanGesture::event(QEvent *event)
+{
 #if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA)
     Q_D(QPanGesture);
     if (event->type() == QEvent::Timer) {
@@ -289,41 +282,35 @@ QSize QPanGesture::lastOffset() const
     On some platform like Windows it's necessary to provide a non-null widget
     as \a parent to get native gesture support.
 */
-QPinchGesture::QPinchGesture(QWidget *parent)
-    : QGesture(*new QPinchGesturePrivate, parent)
+QPinchGesture::QPinchGesture(QWidget *gestureTarget, QObject *parent)
+    : QGesture(*new QPinchGesturePrivate, gestureTarget, parent)
 {
-    if (parent) {
-        QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
-        qAppPriv->widgetGestures[parent].pinch = this;
-#ifdef Q_WS_WIN
-        qt_widget_private(parent)->winSetupGestures();
-#endif
-    }
 }
 
-/*! \internal */
-bool QPinchGesture::event(QEvent *event)
+void QPinchGesturePrivate::setupGestureTarget(QObject *newGestureTarget)
 {
-    switch (event->type()) {
-    case QEvent::ParentAboutToChange:
-        if (QWidget *w = qobject_cast<QWidget*>(parent())) {
-            QApplicationPrivate::instance()->widgetGestures[w].pinch = 0;
+    Q_Q(QPinchGesture);
+    if (gestureTarget && gestureTarget->isWidgetType()) {
+        QWidget *w = static_cast<QWidget*>(gestureTarget.data());
+        QApplicationPrivate::instance()->widgetGestures[w].pinch = 0;
 #ifdef Q_WS_WIN
-            qt_widget_private(w)->winSetupGestures();
+        qt_widget_private(w)->winSetupGestures();
 #endif
-        }
-        break;
-    case QEvent::ParentChange:
-        if (QWidget *w = qobject_cast<QWidget*>(parent())) {
-            QApplicationPrivate::instance()->widgetGestures[w].pinch = this;
+    }
+
+    if (newGestureTarget && newGestureTarget->isWidgetType()) {
+        QWidget *w = static_cast<QWidget*>(newGestureTarget);
+        QApplicationPrivate::instance()->widgetGestures[w].pinch = q;
 #ifdef Q_WS_WIN
-            qt_widget_private(w)->winSetupGestures();
+        qt_widget_private(w)->winSetupGestures();
 #endif
-        }
-        break;
-    default:
-        break;
     }
+    QGesturePrivate::setupGestureTarget(newGestureTarget);
+}
+
+/*! \internal */
+bool QPinchGesture::event(QEvent *event)
+{
     return QObject::event(event);
 }
 
@@ -401,6 +388,7 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
     return QGesture::eventFilter(receiver, event);
 }
 
+
 /*! \internal */
 bool QPinchGesture::filterEvent(QEvent *event)
 {
diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h
index 8b5421b..0eb9d92 100644
--- a/src/gui/kernel/qstandardgestures.h
+++ b/src/gui/kernel/qstandardgestures.h
@@ -63,7 +63,7 @@ class Q_GUI_EXPORT QPanGesture : public QGesture
     Q_PROPERTY(QSize lastOffset READ lastOffset)
 
 public:
-    QPanGesture(QWidget *parent);
+    QPanGesture(QWidget *gestureTarget, QObject *parent = 0);
 
     bool filterEvent(QEvent *event);
 
@@ -97,7 +97,7 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture
     Q_PROPERTY(QPoint centerPoint READ centerPoint)
 
 public:
-    QPinchGesture(QWidget *parent);
+    QPinchGesture(QWidget *gestureTarget, QObject *parent = 0);
 
     bool filterEvent(QEvent *event);
     void reset();
diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h
index c52d16b..5fbcc5d 100644
--- a/src/gui/kernel/qstandardgestures_p.h
+++ b/src/gui/kernel/qstandardgestures_p.h
@@ -76,6 +76,8 @@ public:
 #endif
     }
 
+    void setupGestureTarget(QObject *o);
+
     QSize totalOffset;
     QSize lastOffset;
     QPoint lastPosition;
@@ -98,6 +100,9 @@ public:
 #endif
     {
     }
+
+    void setupGestureTarget(QObject *o);
+
     qreal scaleFactor;
     qreal lastScaleFactor;
     qreal rotationAngle;
-- 
cgit v0.12