src/hbcore/gestures/hbpangesturelogic_p.cpp
changeset 28 b7da29130b0e
parent 23 e6ad4ef83b23
child 30 80e4d18b72f5
equal deleted inserted replaced
23:e6ad4ef83b23 28:b7da29130b0e
    34 #include "hbpangesture.h"
    34 #include "hbpangesture.h"
    35 #include "hbpangesture_p.h"
    35 #include "hbpangesture_p.h"
    36 #include "hbpangesturelogic_p.h"
    36 #include "hbpangesturelogic_p.h"
    37 #include "hbnamespace_p.h"
    37 #include "hbnamespace_p.h"
    38 
    38 
       
    39 #define followedTouchPoint(te, gesture) te->touchPoints().at(followedTouchPointIndex(te, gesture))
       
    40 
    39 /*!
    41 /*!
    40    @hbcore
    42    @hbcore
    41    \internal
    43    \internal
    42    \class HbPanGestureLogic
    44    \class HbPanGestureLogic
    43 
    45 
    66 
    68 
    67 */
    69 */
    68 bool HbPanGestureLogic::isMouseEvent(QEvent::Type eventType)
    70 bool HbPanGestureLogic::isMouseEvent(QEvent::Type eventType)
    69 {
    71 {
    70     return eventType == QEvent::MouseButtonPress ||
    72     return eventType == QEvent::MouseButtonPress ||
    71            eventType == QEvent::MouseMove ||
    73             eventType == QEvent::MouseMove ||
    72            eventType == QEvent::MouseButtonDblClick ||
    74             eventType == QEvent::MouseButtonDblClick ||
    73            eventType == QEvent::MouseButtonRelease;
    75             eventType == QEvent::MouseButtonRelease;
       
    76 }
       
    77 
       
    78 /*!
       
    79     \internal
       
    80     \brief
       
    81     \return
       
    82 
       
    83 */
       
    84 bool HbPanGestureLogic::isTouchEvent(QEvent::Type eventType)
       
    85 {
       
    86     return eventType == QEvent::TouchBegin ||
       
    87             eventType == QEvent::TouchEnd ||
       
    88             eventType == QEvent::TouchUpdate;
    74 }
    89 }
    75 
    90 
    76 /*!
    91 /*!
    77     \internal
    92     \internal
    78     \brief
    93     \brief
    94 
   109 
    95     gesture->setLastOffset(QPointF());
   110     gesture->setLastOffset(QPointF());
    96     gesture->setOffset(QPointF(0,0));
   111     gesture->setOffset(QPointF(0,0));
    97     gesture->setAcceleration(0);
   112     gesture->setAcceleration(0);
    98     gesture->setStartPos(QPointF());
   113     gesture->setStartPos(QPointF());
       
   114 
       
   115     gesture->d_ptr->mIgnoreMouseEvents = false;
       
   116     gesture->d_ptr->mFollowedTouchPointId = 0;
    99 }
   117 }
   100 
   118 
   101 /*!
   119 /*!
   102     \internal
   120     \internal
   103     \brief
   121     \brief
   113     // Just ignore situations that are not interesting at all.
   131     // Just ignore situations that are not interesting at all.
   114     if ( !( gestureState == Qt::NoGesture && me->button() == Qt::LeftButton ) )
   132     if ( !( gestureState == Qt::NoGesture && me->button() == Qt::LeftButton ) )
   115     {
   133     {
   116         return QGestureRecognizer::Ignore;
   134         return QGestureRecognizer::Ignore;
   117     }
   135     }
   118     
   136 
   119     gesture->setHotSpot( me->globalPos() );
   137     gesture->setHotSpot( me->globalPos() );
   120     gesture->setStartPos( me->globalPos() );
   138     gesture->setStartPos( me->globalPos() );
   121     gesture->setOffset( QPointF( 0,0 ) );
   139     gesture->setOffset( QPointF( 0,0 ) );
   122     gesture->setLastOffset( QPointF( 0,0 ) );
   140     gesture->setLastOffset( QPointF( 0,0 ) );
   123     QPointF scenePos = HbGestureUtils::mapToScene(watched, me->globalPos());
   141     QPointF scenePos = HbGestureUtils::mapToScene(watched, me->globalPos());
   124     gesture->d_ptr->mSceneStartPos       = scenePos;
   142     gesture->d_ptr->mSceneStartPos       = scenePos;
   125     gesture->d_ptr->mSceneOffset         = HbGestureUtils::mapToScene(watched, QPointF(0,0));
   143     gesture->d_ptr->mSceneOffset         = HbGestureUtils::mapToScene(watched, QPointF(0,0));
   126     gesture->d_ptr->mSceneLastOffset     = HbGestureUtils::mapToScene(watched, QPointF(0,0));
   144     gesture->d_ptr->mSceneLastOffset     = HbGestureUtils::mapToScene(watched, QPointF(0,0));
   127     gesture->d_ptr->mLastTimeStamp = mCurrentTime;
   145     gesture->d_ptr->mLastTimeStamp = mCurrentTime;
   128           
   146 
   129 
   147 
   130     gesture->d_ptr->mThresholdSquare = HbDefaultPanThreshold * HbDeviceProfile::current().ppmValue();
   148     gesture->d_ptr->mThresholdSquare = HbDefaultPanThreshold * HbDeviceProfile::current().ppmValue();
   131     gesture->d_ptr->mThresholdSquare = gesture->d_ptr->mThresholdSquare * gesture->d_ptr->mThresholdSquare;
   149     gesture->d_ptr->mThresholdSquare = gesture->d_ptr->mThresholdSquare * gesture->d_ptr->mThresholdSquare;
   132 
   150 
   133     qreal velocityThreshold = HbPanVelocityUpdateThreshold * HbDeviceProfile::current().ppmValue();
   151     qreal velocityThreshold = HbPanVelocityUpdateThreshold * HbDeviceProfile::current().ppmValue();
   154         Qt::GestureState gestureState,
   172         Qt::GestureState gestureState,
   155         HbPanGesture *gesture,
   173         HbPanGesture *gesture,
   156         QObject *watched,
   174         QObject *watched,
   157         QMouseEvent *me )
   175         QMouseEvent *me )
   158 {
   176 {
   159     if ( !me->buttons().testFlag(Qt::LeftButton) )
   177     if ( !me->buttons().testFlag(Qt::LeftButton))
   160     {
   178     {
   161         return QGestureRecognizer::Ignore;
   179         return QGestureRecognizer::Ignore;
   162     }
   180     }
   163 
   181 
   164     QPointF offset = me->globalPos() - gesture->startPos().toPoint();
   182     QPointF offset = me->globalPos() - gesture->startPos().toPoint();
   208 QGestureRecognizer::Result HbPanGestureLogic::handleMouseRelease(
   226 QGestureRecognizer::Result HbPanGestureLogic::handleMouseRelease(
   209         Qt::GestureState gestureState,
   227         Qt::GestureState gestureState,
   210         HbPanGesture *gesture,
   228         HbPanGesture *gesture,
   211         QObject *watched,
   229         QObject *watched,
   212         QMouseEvent *me )
   230         QMouseEvent *me )
   213 {   
   231 {
   214     Q_UNUSED(me->globalPos());
   232     Q_UNUSED(me);
   215     Q_UNUSED(gesture);
   233     Q_UNUSED(gesture);
   216     Q_UNUSED(watched);
   234     Q_UNUSED(watched);
   217     
   235 
   218     gesture->d_ptr->mLastTimeStamp = mCurrentTime;
   236     gesture->d_ptr->mLastTimeStamp = mCurrentTime;
   219         
   237 
   220     if ( gestureState == Qt::GestureStarted || gestureState == Qt::GestureUpdated )
   238     if ( gestureState == Qt::GestureStarted || gestureState == Qt::GestureUpdated )
   221     {
   239     {
   222         return QGestureRecognizer::FinishGesture;
   240         return QGestureRecognizer::FinishGesture;
   223     }
   241     }
   224     else
   242     else
   245     \internal
   263     \internal
   246     \brief
   264     \brief
   247     \return
   265     \return
   248 
   266 
   249 */
   267 */
       
   268 QGestureRecognizer::Result HbPanGestureLogic::handleTouchBegin(
       
   269         Qt::GestureState gestureState,
       
   270         HbPanGesture *gesture,
       
   271         QObject *watched,
       
   272         QTouchEvent *te )
       
   273 {
       
   274     gesture->d_ptr->mFollowedTouchPointId = getNextId(te);
       
   275 
       
   276     if(gesture->d_ptr->mFollowedTouchPointId == -1 && gestureState != Qt::NoGesture) {
       
   277         return QGestureRecognizer::FinishGesture; // if all touchpoints are released
       
   278     }
       
   279 
       
   280     QTouchEvent::TouchPoint tp = followedTouchPoint(te, gesture);
       
   281     QPointF scenePos = HbGestureUtils::mapToScene(watched, tp.screenPos());
       
   282 
       
   283     gesture->setHotSpot(tp.screenPos()) ;
       
   284     gesture->setStartPos(tp.screenPos());
       
   285     gesture->setOffset( QPointF( 0,0 ) );
       
   286     gesture->setLastOffset( QPointF( 0,0 ) );
       
   287 
       
   288     gesture->d_ptr->mSceneStartPos       = scenePos;
       
   289     gesture->d_ptr->mSceneOffset         = QPointF(0,0);
       
   290     gesture->d_ptr->mSceneLastOffset     = QPointF(0,0);
       
   291     gesture->d_ptr->mLastTimeStamp = mCurrentTime;
       
   292 
       
   293     qreal defaultThreshold = HbDefaultPanThreshold * HbDeviceProfile::current().ppmValue();
       
   294     gesture->d_ptr->mThresholdSquare = defaultThreshold * defaultThreshold;
       
   295 
       
   296     gesture->d_ptr->mAxisX.resetRecorder(defaultThreshold);
       
   297     gesture->d_ptr->mAxisY.resetRecorder(defaultThreshold);
       
   298     gesture->d_ptr->mSceneAxisX.resetRecorder(defaultThreshold);
       
   299     gesture->d_ptr->mSceneAxisY.resetRecorder(defaultThreshold);
       
   300     gesture->d_ptr->mAxisY.record( tp.screenPos().y(), mCurrentTime );
       
   301     gesture->d_ptr->mAxisX.record( tp.screenPos().x(), mCurrentTime );    
       
   302     gesture->d_ptr->mSceneAxisX.record( scenePos.x(), mCurrentTime );
       
   303     gesture->d_ptr->mSceneAxisY.record( scenePos.y(), mCurrentTime );
       
   304 
       
   305     if (gestureState != Qt::NoGesture) {
       
   306         return QGestureRecognizer::Ignore;
       
   307     } else {
       
   308         return QGestureRecognizer::MayBeGesture;
       
   309     }
       
   310 }
       
   311 
       
   312 /*!
       
   313     \internal
       
   314     \brief
       
   315     \return
       
   316 
       
   317 */
       
   318 QGestureRecognizer::Result HbPanGestureLogic::handleTouchMove(
       
   319         Qt::GestureState gestureState,
       
   320         HbPanGesture *gesture,
       
   321         QObject *watched,
       
   322         QTouchEvent *te)
       
   323 {
       
   324     QTouchEvent::TouchPoint tp = followedTouchPoint(te, gesture);
       
   325 
       
   326     // touch event handling has already started
       
   327     // need to update position and offset
       
   328     QPointF offset = tp.screenPos() - gesture->startPos();
       
   329     if (tp.lastScreenPos() == tp.screenPos()) {
       
   330         return QGestureRecognizer::Ignore;
       
   331     }
       
   332     if (gestureState == Qt::NoGesture && (offset.x() * offset.x() + offset.y() * offset.y()) <= gesture->d_ptr->mThresholdSquare) {
       
   333 
       
   334         return QGestureRecognizer::MayBeGesture;
       
   335     }
       
   336 
       
   337     // Hotspot is updated on the press and on events after the gesture started.
       
   338     // Here we are checking the previously set gestureState.
       
   339     if (gestureState == Qt::GestureStarted || gestureState == Qt::GestureUpdated) {
       
   340         gesture->setHotSpot( tp.screenPos() );
       
   341     }
       
   342 
       
   343     gesture->setLastOffset( gesture->offset().toPoint() );
       
   344     gesture->setOffset( offset );
       
   345     gesture->d_ptr->mSceneLastOffset = gesture->d_ptr->mSceneOffset;
       
   346     gesture->d_ptr->mSceneOffset =
       
   347             HbGestureUtils::mapToScene(watched, tp.screenPos()) - gesture->d_ptr->mSceneStartPos;
       
   348     gesture->d_ptr->mLastTimeStamp = mCurrentTime;
       
   349 
       
   350     gesture->d_ptr->mAxisX.record( tp.screenPos().x(), mCurrentTime );
       
   351     gesture->d_ptr->mAxisY.record( tp.screenPos().y(), mCurrentTime );
       
   352     QPointF scenePos = HbGestureUtils::mapToScene(watched, tp.screenPos());
       
   353     gesture->d_ptr->mSceneAxisX.record( scenePos.x(), mCurrentTime );
       
   354     gesture->d_ptr->mSceneAxisY.record( scenePos.y(), mCurrentTime );
       
   355 
       
   356     QGraphicsView* view = qobject_cast<QGraphicsView*>(watched->parent());
       
   357     if (view) {
       
   358         QGraphicsScene* scene = view->scene();
       
   359         if (scene && scene->property(HbPrivate::OverridingGesture.latin1()).isValid() &&
       
   360             scene->property(HbPrivate::OverridingGesture.latin1()).toInt() != Qt::PanGesture) {
       
   361             return QGestureRecognizer::MayBeGesture;
       
   362         }
       
   363     }
       
   364 
       
   365     return QGestureRecognizer::TriggerGesture;
       
   366 }
       
   367 
       
   368 /*!
       
   369     \internal
       
   370     \brief
       
   371     \return
       
   372 
       
   373 */
       
   374 QGestureRecognizer::Result HbPanGestureLogic::handleTouchEnd(
       
   375         Qt::GestureState gestureState,
       
   376         HbPanGesture *gesture,
       
   377         QObject *watched,
       
   378         QTouchEvent *te )
       
   379 {
       
   380     Q_UNUSED(te);
       
   381     Q_UNUSED(gesture);
       
   382     Q_UNUSED(watched);
       
   383 
       
   384     gesture->d_ptr->mLastTimeStamp = mCurrentTime;
       
   385 
       
   386     if ( gestureState == Qt::GestureStarted || gestureState == Qt::GestureUpdated )
       
   387     {
       
   388         return QGestureRecognizer::FinishGesture;
       
   389     }
       
   390     else
       
   391     {
       
   392         return QGestureRecognizer::CancelGesture;
       
   393     }
       
   394 }
       
   395 
       
   396 
       
   397 /*!
       
   398     \internal
       
   399     \brief
       
   400     \return
       
   401 
       
   402 */
   250 QGestureRecognizer::Result HbPanGestureLogic::recognize(
   403 QGestureRecognizer::Result HbPanGestureLogic::recognize(
   251         Qt::GestureState gestureState,
   404         Qt::GestureState gestureState,
   252         HbPanGesture *gesture,
   405         HbPanGesture *gesture,
   253         QObject *watched,
   406         QObject *watched,
   254         QEvent *event,
   407         QEvent *event,
   255         QTime currentTime)
   408         QTime currentTime)
   256 {
   409 {
   257     // Record the time right away.
   410     // Record the time right away.
   258     mCurrentTime = currentTime;
   411     mCurrentTime = currentTime;
   259     
   412 
   260     if ( isMouseEvent(event->type()) )
   413     if ( isMouseEvent(event->type()) )
   261     {
   414     {
       
   415         if (gesture->d_ptr->mIgnoreMouseEvents) {
       
   416             return QGestureRecognizer::Ignore;
       
   417         }
   262         QMouseEvent* me = static_cast<QMouseEvent*>(event);
   418         QMouseEvent* me = static_cast<QMouseEvent*>(event);
   263         switch(event->type())
   419         switch(event->type())
   264         {
   420         {
   265         case QEvent::MouseButtonDblClick:
   421         case QEvent::MouseButtonDblClick:
   266         case QEvent::MouseButtonPress:
   422         case QEvent::MouseButtonPress:
   267             return handleMousePress(gestureState, gesture, watched, me);
   423             return handleMousePress(gestureState, gesture, watched, me);
   268 
       
   269         case QEvent::MouseMove:
   424         case QEvent::MouseMove:
   270             return handleMouseMove(gestureState, gesture, watched, me);
   425             return handleMouseMove(gestureState, gesture, watched, me);
   271 
       
   272         case QEvent::MouseButtonRelease:
   426         case QEvent::MouseButtonRelease:
   273             return handleMouseRelease(gestureState, gesture, watched, me);
   427             return handleMouseRelease(gestureState, gesture, watched, me);
   274 
       
   275         default: break;
   428         default: break;
   276         }
   429         }
   277     }
   430     }
       
   431     if (isTouchEvent(event->type()) && watched->isWidgetType() ) {
       
   432 
       
   433         QTouchEvent *te = static_cast<QTouchEvent *>(event);
       
   434 
       
   435         switch(event->type())
       
   436         {
       
   437         case QEvent::TouchBegin:
       
   438             return handleTouchBegin(gestureState, gesture, watched, te);
       
   439             break;
       
   440         case QEvent::TouchUpdate: {
       
   441                 gesture->d_ptr->mIgnoreMouseEvents = true;
       
   442 
       
   443                 if (followedTouchPoint(te, gesture).state() == Qt::TouchPointReleased) {
       
   444                     //qDebug() << "---- Finger changed ----";
       
   445                     return handleTouchBegin(gestureState, gesture, watched, te);
       
   446                 }
       
   447                 if (followedTouchPoint(te, gesture).state() == Qt::TouchPointMoved) {
       
   448                     return handleTouchMove(gestureState, gesture, watched, te);
       
   449                 }
       
   450                 break;
       
   451             }
       
   452         case QEvent::TouchEnd:
       
   453             //qDebug() << "===== TOUCHEND ======" ;
       
   454             gesture->d_ptr->mIgnoreMouseEvents = false;
       
   455             return handleTouchEnd(gestureState, gesture, watched, te);
       
   456         default:
       
   457             break;
       
   458         }
       
   459     }
   278     return QGestureRecognizer::Ignore;
   460     return QGestureRecognizer::Ignore;
   279 }
   461 }
       
   462 
       
   463 /*!
       
   464     \internal
       
   465     \brief
       
   466     \return
       
   467 
       
   468 */
       
   469 int HbPanGestureLogic::followedTouchPointIndex(QTouchEvent *te, HbPanGesture *gesture)
       
   470 {
       
   471     for(int index(0); index < te->touchPoints().count(); index++) {
       
   472         if (te->touchPoints().at(index).id() == gesture->d_ptr->mFollowedTouchPointId) {
       
   473             return index;
       
   474         }
       
   475     }
       
   476     Q_ASSERT(false);
       
   477     return -1;
       
   478 }
       
   479 
       
   480 /*!
       
   481     \internal
       
   482     \brief
       
   483     \return
       
   484 
       
   485 */
       
   486 int HbPanGestureLogic::getNextId(QTouchEvent *te)
       
   487 {
       
   488     for (int i(0); i < te->touchPoints().count(); i++) {
       
   489         if (te->touchPoints().at(i).state() != Qt::TouchPointReleased) {
       
   490             return te->touchPoints().at(i).id();
       
   491         }
       
   492     }
       
   493     return -1;
       
   494 }