From 5ee1f48c2d1039ec51e7907659797233113f0d29 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@digia.com>
Date: Fri, 28 Mar 2014 09:37:16 +0100
Subject: [PATCH] WIP: Try to improve multiple gesture handling in image
 gestures example.

Try to prevent swipe from interfering with pan by introducing
fuzzy comparison.

Task-number: QTBUG-37759
Change-Id: I6182afa7282da75daf94bcf2f347dfbaaf99fe07
---
 .../widgets/gestures/imagegestures/imagewidget.cpp |   54 ++++++++++++++------
 .../widgets/gestures/imagegestures/imagewidget.h   |    4 +-
 2 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/examples/widgets/gestures/imagegestures/imagewidget.cpp b/examples/widgets/gestures/imagegestures/imagewidget.cpp
index 57c2af4..a87baa9 100644
--- a/examples/widgets/gestures/imagegestures/imagewidget.cpp
+++ b/examples/widgets/gestures/imagegestures/imagewidget.cpp
@@ -109,17 +109,21 @@ void ImageWidget::mouseDoubleClickEvent(QMouseEvent *)
 bool ImageWidget::gestureEvent(QGestureEvent *event)
 {
     qCDebug(lcExample) << "gestureEvent():" << event->gestures().size();
-    if (QGesture *swipe = event->gesture(Qt::SwipeGesture))
+    if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) {
         swipeTriggered(static_cast<QSwipeGesture *>(swipe));
-    else if (QGesture *pan = event->gesture(Qt::PanGesture))
+        return true;
+    }
+    if (QGesture *pinch = event->gesture(Qt::PinchGesture)) {
+        if (pinchTriggered(static_cast<QPinchGesture *>(pinch)))
+            return true;
+    }
+    if (QGesture *pan = event->gesture(Qt::PanGesture))
         panTriggered(static_cast<QPanGesture *>(pan));
-    if (QGesture *pinch = event->gesture(Qt::PinchGesture))
-        pinchTriggered(static_cast<QPinchGesture *>(pinch));
     return true;
 }
 //! [gesture event handler]
 
-void ImageWidget::panTriggered(QPanGesture *gesture)
+bool ImageWidget::panTriggered(QPanGesture *gesture)
 {
 #ifndef QT_NO_CURSOR
     switch (gesture->state()) {
@@ -133,31 +137,51 @@ void ImageWidget::panTriggered(QPanGesture *gesture)
 #endif
     QPointF delta = gesture->delta();
     qCDebug(lcExample) << "panTriggered():" << delta;
-    horizontalOffset += delta.x();
-    verticalOffset += delta.y();
-    update();
+    if (!qFuzzyCompare(delta.manhattanLength(), 0)) {
+        horizontalOffset += delta.x();
+        verticalOffset += delta.y();
+        update();
+        return true;
+    }
+    return false;
 }
 
-void ImageWidget::pinchTriggered(QPinchGesture *gesture)
+bool ImageWidget::pinchTriggered(QPinchGesture *gesture)
 {
     QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags();
+    qreal rotationAngleDelta = 0;
     if (changeFlags & QPinchGesture::RotationAngleChanged) {
         const qreal value = gesture->property("rotationAngle").toReal();
         const qreal lastValue = gesture->property("lastRotationAngle").toReal();
-        const qreal rotationAngleDelta = value - lastValue;
-        rotationAngle += rotationAngleDelta;
+        rotationAngleDelta = value - lastValue;
         qCDebug(lcExample) << "pinchTriggered(): rotation by" << rotationAngleDelta << rotationAngle;
     }
+    qreal newCurrentStepScaleFactor = 1;
     if (changeFlags & QPinchGesture::ScaleFactorChanged) {
-        qreal value = gesture->property("scaleFactor").toReal();
-        currentStepScaleFactor = value;
-        qCDebug(lcExample) << "pinchTriggered(): " << currentStepScaleFactor;
+        newCurrentStepScaleFactor = gesture->property("scaleFactor").toReal();
+        qCDebug(lcExample) << "pinchTriggered(): scale factor" << newCurrentStepScaleFactor;
+    }
+    const bool hasRotation = qAbs(rotationAngleDelta) > 1;
+    const bool hasScaling = !qFuzzyCompare(newCurrentStepScaleFactor, 1.0);
+    if (hasRotation) {
+        rotationAngle += rotationAngleDelta;
+        qCDebug(lcExample) << "pinchTriggered(): applied rotation by" << rotationAngleDelta << rotationAngle;
+    }
+    if (hasScaling) {
+        currentStepScaleFactor = newCurrentStepScaleFactor;
+        qCDebug(lcExample) << "pinchTriggered(): applied scaling" << currentStepScaleFactor;
     }
     if (gesture->state() == Qt::GestureFinished) {
         scaleFactor *= currentStepScaleFactor;
         currentStepScaleFactor = 1;
+        update();
+        qCDebug(lcExample) << "pinchTriggered(): finished, scaling" << scaleFactor;
+        return true;
+    } else if (hasRotation) {
+        update();
+        return true;
     }
-    update();
+    return false;
 }
 
 //! [swipe function]
diff --git a/examples/widgets/gestures/imagegestures/imagewidget.h b/examples/widgets/gestures/imagegestures/imagewidget.h
index d061935..071f7eb 100644
--- a/examples/widgets/gestures/imagegestures/imagewidget.h
+++ b/examples/widgets/gestures/imagegestures/imagewidget.h
@@ -72,8 +72,8 @@ protected:
 
 private:
     bool gestureEvent(QGestureEvent *event);
-    void panTriggered(QPanGesture*);
-    void pinchTriggered(QPinchGesture*);
+    bool panTriggered(QPanGesture*);
+    bool pinchTriggered(QPinchGesture*);
     void swipeTriggered(QSwipeGesture*);
 //! [class definition begin]
 
-- 
1.7.9.5

