src/hbcore/gestures/hbpangesturelogic_p.cpp
changeset 28 b7da29130b0e
parent 23 e6ad4ef83b23
child 30 80e4d18b72f5
--- a/src/hbcore/gestures/hbpangesturelogic_p.cpp	Thu Sep 02 20:44:51 2010 +0300
+++ b/src/hbcore/gestures/hbpangesturelogic_p.cpp	Fri Sep 17 08:32:10 2010 +0300
@@ -36,6 +36,8 @@
 #include "hbpangesturelogic_p.h"
 #include "hbnamespace_p.h"
 
+#define followedTouchPoint(te, gesture) te->touchPoints().at(followedTouchPointIndex(te, gesture))
+
 /*!
    @hbcore
    \internal
@@ -68,9 +70,22 @@
 bool HbPanGestureLogic::isMouseEvent(QEvent::Type eventType)
 {
     return eventType == QEvent::MouseButtonPress ||
-           eventType == QEvent::MouseMove ||
-           eventType == QEvent::MouseButtonDblClick ||
-           eventType == QEvent::MouseButtonRelease;
+            eventType == QEvent::MouseMove ||
+            eventType == QEvent::MouseButtonDblClick ||
+            eventType == QEvent::MouseButtonRelease;
+}
+
+/*!
+    \internal
+    \brief
+    \return
+
+*/
+bool HbPanGestureLogic::isTouchEvent(QEvent::Type eventType)
+{
+    return eventType == QEvent::TouchBegin ||
+            eventType == QEvent::TouchEnd ||
+            eventType == QEvent::TouchUpdate;
 }
 
 /*!
@@ -96,6 +111,9 @@
     gesture->setOffset(QPointF(0,0));
     gesture->setAcceleration(0);
     gesture->setStartPos(QPointF());
+
+    gesture->d_ptr->mIgnoreMouseEvents = false;
+    gesture->d_ptr->mFollowedTouchPointId = 0;
 }
 
 /*!
@@ -115,7 +133,7 @@
     {
         return QGestureRecognizer::Ignore;
     }
-    
+
     gesture->setHotSpot( me->globalPos() );
     gesture->setStartPos( me->globalPos() );
     gesture->setOffset( QPointF( 0,0 ) );
@@ -125,7 +143,7 @@
     gesture->d_ptr->mSceneOffset         = HbGestureUtils::mapToScene(watched, QPointF(0,0));
     gesture->d_ptr->mSceneLastOffset     = HbGestureUtils::mapToScene(watched, QPointF(0,0));
     gesture->d_ptr->mLastTimeStamp = mCurrentTime;
-          
+
 
     gesture->d_ptr->mThresholdSquare = HbDefaultPanThreshold * HbDeviceProfile::current().ppmValue();
     gesture->d_ptr->mThresholdSquare = gesture->d_ptr->mThresholdSquare * gesture->d_ptr->mThresholdSquare;
@@ -156,7 +174,7 @@
         QObject *watched,
         QMouseEvent *me )
 {
-    if ( !me->buttons().testFlag(Qt::LeftButton) )
+    if ( !me->buttons().testFlag(Qt::LeftButton))
     {
         return QGestureRecognizer::Ignore;
     }
@@ -210,13 +228,13 @@
         HbPanGesture *gesture,
         QObject *watched,
         QMouseEvent *me )
-{   
-    Q_UNUSED(me->globalPos());
+{
+    Q_UNUSED(me);
     Q_UNUSED(gesture);
     Q_UNUSED(watched);
-    
+
     gesture->d_ptr->mLastTimeStamp = mCurrentTime;
-        
+
     if ( gestureState == Qt::GestureStarted || gestureState == Qt::GestureUpdated )
     {
         return QGestureRecognizer::FinishGesture;
@@ -247,6 +265,141 @@
     \return
 
 */
+QGestureRecognizer::Result HbPanGestureLogic::handleTouchBegin(
+        Qt::GestureState gestureState,
+        HbPanGesture *gesture,
+        QObject *watched,
+        QTouchEvent *te )
+{
+    gesture->d_ptr->mFollowedTouchPointId = getNextId(te);
+
+    if(gesture->d_ptr->mFollowedTouchPointId == -1 && gestureState != Qt::NoGesture) {
+        return QGestureRecognizer::FinishGesture; // if all touchpoints are released
+    }
+
+    QTouchEvent::TouchPoint tp = followedTouchPoint(te, gesture);
+    QPointF scenePos = HbGestureUtils::mapToScene(watched, tp.screenPos());
+
+    gesture->setHotSpot(tp.screenPos()) ;
+    gesture->setStartPos(tp.screenPos());
+    gesture->setOffset( QPointF( 0,0 ) );
+    gesture->setLastOffset( QPointF( 0,0 ) );
+
+    gesture->d_ptr->mSceneStartPos       = scenePos;
+    gesture->d_ptr->mSceneOffset         = QPointF(0,0);
+    gesture->d_ptr->mSceneLastOffset     = QPointF(0,0);
+    gesture->d_ptr->mLastTimeStamp = mCurrentTime;
+
+    qreal defaultThreshold = HbDefaultPanThreshold * HbDeviceProfile::current().ppmValue();
+    gesture->d_ptr->mThresholdSquare = defaultThreshold * defaultThreshold;
+
+    gesture->d_ptr->mAxisX.resetRecorder(defaultThreshold);
+    gesture->d_ptr->mAxisY.resetRecorder(defaultThreshold);
+    gesture->d_ptr->mSceneAxisX.resetRecorder(defaultThreshold);
+    gesture->d_ptr->mSceneAxisY.resetRecorder(defaultThreshold);
+    gesture->d_ptr->mAxisY.record( tp.screenPos().y(), mCurrentTime );
+    gesture->d_ptr->mAxisX.record( tp.screenPos().x(), mCurrentTime );    
+    gesture->d_ptr->mSceneAxisX.record( scenePos.x(), mCurrentTime );
+    gesture->d_ptr->mSceneAxisY.record( scenePos.y(), mCurrentTime );
+
+    if (gestureState != Qt::NoGesture) {
+        return QGestureRecognizer::Ignore;
+    } else {
+        return QGestureRecognizer::MayBeGesture;
+    }
+}
+
+/*!
+    \internal
+    \brief
+    \return
+
+*/
+QGestureRecognizer::Result HbPanGestureLogic::handleTouchMove(
+        Qt::GestureState gestureState,
+        HbPanGesture *gesture,
+        QObject *watched,
+        QTouchEvent *te)
+{
+    QTouchEvent::TouchPoint tp = followedTouchPoint(te, gesture);
+
+    // touch event handling has already started
+    // need to update position and offset
+    QPointF offset = tp.screenPos() - gesture->startPos();
+    if (tp.lastScreenPos() == tp.screenPos()) {
+        return QGestureRecognizer::Ignore;
+    }
+    if (gestureState == Qt::NoGesture && (offset.x() * offset.x() + offset.y() * offset.y()) <= gesture->d_ptr->mThresholdSquare) {
+
+        return QGestureRecognizer::MayBeGesture;
+    }
+
+    // Hotspot is updated on the press and on events after the gesture started.
+    // Here we are checking the previously set gestureState.
+    if (gestureState == Qt::GestureStarted || gestureState == Qt::GestureUpdated) {
+        gesture->setHotSpot( tp.screenPos() );
+    }
+
+    gesture->setLastOffset( gesture->offset().toPoint() );
+    gesture->setOffset( offset );
+    gesture->d_ptr->mSceneLastOffset = gesture->d_ptr->mSceneOffset;
+    gesture->d_ptr->mSceneOffset =
+            HbGestureUtils::mapToScene(watched, tp.screenPos()) - gesture->d_ptr->mSceneStartPos;
+    gesture->d_ptr->mLastTimeStamp = mCurrentTime;
+
+    gesture->d_ptr->mAxisX.record( tp.screenPos().x(), mCurrentTime );
+    gesture->d_ptr->mAxisY.record( tp.screenPos().y(), mCurrentTime );
+    QPointF scenePos = HbGestureUtils::mapToScene(watched, tp.screenPos());
+    gesture->d_ptr->mSceneAxisX.record( scenePos.x(), mCurrentTime );
+    gesture->d_ptr->mSceneAxisY.record( scenePos.y(), mCurrentTime );
+
+    QGraphicsView* view = qobject_cast<QGraphicsView*>(watched->parent());
+    if (view) {
+        QGraphicsScene* scene = view->scene();
+        if (scene && scene->property(HbPrivate::OverridingGesture.latin1()).isValid() &&
+            scene->property(HbPrivate::OverridingGesture.latin1()).toInt() != Qt::PanGesture) {
+            return QGestureRecognizer::MayBeGesture;
+        }
+    }
+
+    return QGestureRecognizer::TriggerGesture;
+}
+
+/*!
+    \internal
+    \brief
+    \return
+
+*/
+QGestureRecognizer::Result HbPanGestureLogic::handleTouchEnd(
+        Qt::GestureState gestureState,
+        HbPanGesture *gesture,
+        QObject *watched,
+        QTouchEvent *te )
+{
+    Q_UNUSED(te);
+    Q_UNUSED(gesture);
+    Q_UNUSED(watched);
+
+    gesture->d_ptr->mLastTimeStamp = mCurrentTime;
+
+    if ( gestureState == Qt::GestureStarted || gestureState == Qt::GestureUpdated )
+    {
+        return QGestureRecognizer::FinishGesture;
+    }
+    else
+    {
+        return QGestureRecognizer::CancelGesture;
+    }
+}
+
+
+/*!
+    \internal
+    \brief
+    \return
+
+*/
 QGestureRecognizer::Result HbPanGestureLogic::recognize(
         Qt::GestureState gestureState,
         HbPanGesture *gesture,
@@ -256,24 +409,86 @@
 {
     // Record the time right away.
     mCurrentTime = currentTime;
-    
+
     if ( isMouseEvent(event->type()) )
     {
+        if (gesture->d_ptr->mIgnoreMouseEvents) {
+            return QGestureRecognizer::Ignore;
+        }
         QMouseEvent* me = static_cast<QMouseEvent*>(event);
         switch(event->type())
         {
         case QEvent::MouseButtonDblClick:
         case QEvent::MouseButtonPress:
             return handleMousePress(gestureState, gesture, watched, me);
-
         case QEvent::MouseMove:
             return handleMouseMove(gestureState, gesture, watched, me);
-
         case QEvent::MouseButtonRelease:
             return handleMouseRelease(gestureState, gesture, watched, me);
+        default: break;
+        }
+    }
+    if (isTouchEvent(event->type()) && watched->isWidgetType() ) {
 
-        default: break;
+        QTouchEvent *te = static_cast<QTouchEvent *>(event);
+
+        switch(event->type())
+        {
+        case QEvent::TouchBegin:
+            return handleTouchBegin(gestureState, gesture, watched, te);
+            break;
+        case QEvent::TouchUpdate: {
+                gesture->d_ptr->mIgnoreMouseEvents = true;
+
+                if (followedTouchPoint(te, gesture).state() == Qt::TouchPointReleased) {
+                    //qDebug() << "---- Finger changed ----";
+                    return handleTouchBegin(gestureState, gesture, watched, te);
+                }
+                if (followedTouchPoint(te, gesture).state() == Qt::TouchPointMoved) {
+                    return handleTouchMove(gestureState, gesture, watched, te);
+                }
+                break;
+            }
+        case QEvent::TouchEnd:
+            //qDebug() << "===== TOUCHEND ======" ;
+            gesture->d_ptr->mIgnoreMouseEvents = false;
+            return handleTouchEnd(gestureState, gesture, watched, te);
+        default:
+            break;
         }
     }
     return QGestureRecognizer::Ignore;
 }
+
+/*!
+    \internal
+    \brief
+    \return
+
+*/
+int HbPanGestureLogic::followedTouchPointIndex(QTouchEvent *te, HbPanGesture *gesture)
+{
+    for(int index(0); index < te->touchPoints().count(); index++) {
+        if (te->touchPoints().at(index).id() == gesture->d_ptr->mFollowedTouchPointId) {
+            return index;
+        }
+    }
+    Q_ASSERT(false);
+    return -1;
+}
+
+/*!
+    \internal
+    \brief
+    \return
+
+*/
+int HbPanGestureLogic::getNextId(QTouchEvent *te)
+{
+    for (int i(0); i < te->touchPoints().count(); i++) {
+        if (te->touchPoints().at(i).state() != Qt::TouchPointReleased) {
+            return te->touchPoints().at(i).id();
+        }
+    }
+    return -1;
+}