akntouchgesturefw/src/akntouchgesturefwrecognitionengine.cpp
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/akntouchgesturefw/src/akntouchgesturefwrecognitionengine.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,542 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Gesture recognition engine.
+*
+*/
+
+#include <akntouchgesturefwobserver.h>
+
+#include "akntouchgesturefwdefs.h"
+#include "akntouchgesturefwbaserecognizer.h"
+#include "akntouchgesturefwdragrecognizer.h"
+#include "akntouchgesturefwevent.h"
+#include "akntouchgesturefwflickrecognizer.h"
+#include "akntouchgesturefwpinchrecognizer.h"
+#include "akntouchgesturefwpointerstate.h"
+#include "akntouchgesturefwrecognitionengine.h"
+#include "akntouchgesturefwsettings.h"
+#include "akntouchgesturefwtaprecognizer.h"
+
+using namespace AknTouchGestureFw;
+
+// Array of gesture groups
+const TAknTouchGestureFwGroup KGestureGroup[] =
+    {
+    EAknTouchGestureFwGroupTap,
+    EAknTouchGestureFwGroupDrag,
+    EAknTouchGestureFwGroupFlick,
+    EAknTouchGestureFwGroupPinch
+    };
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CAknTouchGestureFwRecognitionEngine* CAknTouchGestureFwRecognitionEngine::NewL(
+        MAknTouchGestureFwObserver& aObserver, CCoeControl* aControl )
+    {
+    CAknTouchGestureFwRecognitionEngine* self =
+        CAknTouchGestureFwRecognitionEngine::NewLC( aObserver, aControl );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CAknTouchGestureFwRecognitionEngine*
+    CAknTouchGestureFwRecognitionEngine::NewLC(
+            MAknTouchGestureFwObserver& aObserver, CCoeControl* aControl )
+    {
+    CAknTouchGestureFwRecognitionEngine* self
+        = new ( ELeave ) CAknTouchGestureFwRecognitionEngine( aObserver,
+            aControl );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CAknTouchGestureFwRecognitionEngine::~CAknTouchGestureFwRecognitionEngine()
+    {
+    delete iPointerState;
+    delete iSettings;
+    iRecognizers.ResetAndDestroy();
+    iRecognizers.Close();
+    }
+
+
+// ---------------------------------------------------------------------------
+// Notifies the observer about a gesture event.
+// ---------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::NotifyObserverL(
+        MAknTouchGestureFwEvent& aEvent )
+    {
+#ifdef GFW_DEBUG_TRACE_INPUTOUTPUT
+    AknTouchGestureFwUtils::DumpGestureEvent( aEvent );
+#endif  // GFW_DEBUG_TRACE_INPUTOUTPUT
+
+    iObserver.HandleTouchGestureL( aEvent );
+    }
+
+
+// ---------------------------------------------------------------------------
+// Sets the gesture interest.
+// ---------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::SetGestureInterestL(
+    TUint aGestureGroups )
+    {
+    TUint newGestureInterest( aGestureGroups );
+
+    // Create recognizers on demand.
+    if ( newGestureInterest & EAknTouchGestureFwGroupPinch )
+        {
+        CreateRecognizerL( EAknTouchGestureFwGroupPinch );
+        }
+
+    if ( newGestureInterest & EAknTouchGestureFwGroupDrag )
+        {
+        CreateRecognizerL( EAknTouchGestureFwGroupDrag );
+        }
+
+    if ( newGestureInterest & EAknTouchGestureFwGroupFlick )
+        {
+        CreateRecognizerL( EAknTouchGestureFwGroupFlick );
+        }
+
+    if ( newGestureInterest & EAknTouchGestureFwGroupTap )
+        {
+        CreateRecognizerL( EAknTouchGestureFwGroupTap );
+        }
+
+    iGestureInterest = newGestureInterest;
+
+    // Enable/disable recognizers.
+    UpdateRecognizersForInterest( newGestureInterest );
+    }
+
+
+// ---------------------------------------------------------------------------
+// Returns the current gesture interest.
+// ---------------------------------------------------------------------------
+//
+TUint CAknTouchGestureFwRecognitionEngine::GestureInterest() const
+    {
+    return iGestureInterest;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Cancels the gesture recognition.
+// ---------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::CancelRecognizing()
+    {
+    if ( iSingleRecognizing || iMultiRecognizing )
+        {
+        iSingleRecognizing = EFalse;
+        iMultiRecognizing = EFalse;
+
+        iPointerState->Reset();
+
+        for ( TInt i = 0; i < iRecognizers.Count(); i++ )
+            {
+            iRecognizers[ i ]->CancelRecognizing();
+            }
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// Handles pointer events.
+// ---------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::HandlePointerEventL(
+    const TPointerEventData& aPointerData )
+    {
+    // Note: term pointer means physical pointer, e.g. finger
+    // in the following comments. So first pointer down
+    // means that single finger has been pressed down and
+    // second pointer down means that also another finger has
+    // been pressed down
+
+    // Update pointer state
+    if ( !iPointerState->Update( aPointerData ) )
+        {
+        // Send unknown event if successive down events were received
+        // to same pointer
+        if ( iTestingEnabled && iPointerState->SuccessiveDownEventsReceived() )
+            {
+            TAknTouchGestureFwUnknownEvent unknown;
+            NotifyObserverL( unknown );
+            }
+        return;
+        }
+
+    TBool multiTouchEvent( iMultiRecognizing );
+
+    if ( aPointerData.iPointerEvent.iType == TPointerEvent::EButton1Down )
+        {
+        // Single recognizing with first button down
+        if ( !iSingleRecognizing )
+            {
+            iMultiRecognizing = EFalse;
+            iSingleRecognizing = ETrue;
+            multiTouchEvent = EFalse;
+            }
+        else
+            {
+            // Second pointer down starts multi recognizing
+            iSingleRecognizing = EFalse;
+            iMultiRecognizing = ETrue;
+            multiTouchEvent = ETrue;
+            }
+        }
+    else if ( aPointerData.iPointerEvent.iType == TPointerEvent::EButton1Up )
+        {
+        if ( iMultiRecognizing && iPointerState->IsSingleTouch() )
+            {
+            iSingleRecognizing = ETrue;
+            iMultiRecognizing = EFalse;
+            multiTouchEvent = ETrue;
+            }
+        else if ( iSingleRecognizing && iPointerState->IsNoTouch() )
+            {
+            // Single recognizing ongoing, pointer goes up.
+            iSingleRecognizing = EFalse;
+            iMultiRecognizing = EFalse;
+            multiTouchEvent = EFalse;
+            }
+        }
+
+    SendPointerEventToRecognizersL( multiTouchEvent, aPointerData );
+    }
+
+
+// ---------------------------------------------------------------------------
+// Returns the framework settings provider.
+// ---------------------------------------------------------------------------
+//
+CAknTouchGestureFwSettings& CAknTouchGestureFwRecognitionEngine::Settings() const
+    {
+    return *iSettings;
+    }
+
+
+// ---------------------------------------------------------------------------
+// EnableTestingFeatures
+// ---------------------------------------------------------------------------
+//    
+void CAknTouchGestureFwRecognitionEngine::EnableTestingFeatures()
+    {
+    iTestingEnabled = ETrue;
+    }
+
+
+// ---------------------------------------------------------------------------
+// C++ constructor.
+// ---------------------------------------------------------------------------
+//
+CAknTouchGestureFwRecognitionEngine::CAknTouchGestureFwRecognitionEngine(
+        MAknTouchGestureFwObserver& aObserver, CCoeControl* aControl )
+    :
+    iObserver( aObserver ),
+    iPointerState( NULL ),
+    iSettings( NULL ),
+    iGestureInterest( EAknTouchGestureFwNoGroup ),
+    iSingleRecognizing( EFalse ),
+    iMultiRecognizing( EFalse ),
+    iControl( aControl ),
+    iFeedBack( MTouchFeedback::Instance() )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// Second-phase constructor.
+// ---------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::ConstructL()
+    {
+    iPointerState = CAknTouchGestureFwPointerState::NewL();
+    iSettings = CAknTouchGestureFwSettings::NewL();
+    }
+
+
+// ---------------------------------------------------------------------------
+// Enables/disables the necessary recognizers based on the gesture interest.
+// ---------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::UpdateRecognizersForInterest(
+    TUint aGestureInterest )
+    {
+    for ( TInt i = 0; i < iRecognizers.Count(); i++ )
+        {
+        if ( iRecognizers[i]->GestureGroup() & aGestureInterest )
+            {
+            iRecognizers[i]->SetEnabled( ETrue );
+            }
+        else
+            {
+            iRecognizers[i]->SetEnabled( EFalse );
+            }
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// Creates the recognizer for the specified gesture group.
+// ---------------------------------------------------------------------------
+//
+CAknTouchGestureFwBaseRecognizer*
+    CAknTouchGestureFwRecognitionEngine::CreateRecognizerL(
+        TAknTouchGestureFwGroup aGroup )
+    {
+    // Check first that the recognizer doesn't already exist.
+    CAknTouchGestureFwBaseRecognizer* newRecognizer( Recognizer( aGroup ) );
+    if ( newRecognizer )
+        {
+        return newRecognizer;
+        }
+    
+    switch ( aGroup )
+        {
+        case ( EAknTouchGestureFwGroupTap ):
+            {
+            newRecognizer = CAknTouchGestureFwTapRecognizer::NewLC( *this );
+            break;
+            }
+        case ( EAknTouchGestureFwGroupFlick ):
+            {
+            newRecognizer = CAknTouchGestureFwFlickRecognizer::NewLC( *this );
+            break;
+            }
+        case ( EAknTouchGestureFwGroupDrag ):
+            {
+            newRecognizer = CAknTouchGestureFwDragRecognizer::NewLC( *this );
+            break;
+            }
+        case ( EAknTouchGestureFwGroupPinch ):
+            {
+            newRecognizer = CAknTouchGestureFwPinchRecognizer::NewLC( *this );
+            break;
+            }
+            
+        default:
+            {
+            break;
+            }
+        }
+
+    if ( newRecognizer )
+        {
+        iRecognizers.AppendL( newRecognizer );
+        CleanupStack::Pop( newRecognizer );
+        }
+
+    return newRecognizer;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Gets recognizer for the specified gesture group.
+// ---------------------------------------------------------------------------
+//
+CAknTouchGestureFwBaseRecognizer*
+    CAknTouchGestureFwRecognitionEngine::Recognizer(
+        TAknTouchGestureFwGroup aGroup )
+    {
+    for ( TInt i = 0; i < iRecognizers.Count(); i++ )
+        {
+        if ( iRecognizers[i]->GestureGroup() == aGroup )
+            {
+            return iRecognizers[i];
+            }
+        }
+    return NULL;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Sends a pointer event to all enabled recognizers.
+// ---------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::SendPointerEventToRecognizersL(
+    TBool aMultiPointer,
+    const TPointerEventData& aPointerData )
+    {    
+    // Inform recognizers of pointer event
+    for ( TInt i = 0; i < iRecognizers.Count(); i++ )
+        {
+        if ( iRecognizers[ i ]->Enabled() )
+            {
+            // Multi pointer event
+            if ( aMultiPointer )
+                {
+                // Both pointers in use
+                if ( iPointerState->IsDoubleTouch() )
+                    {
+                    iRecognizers[ i ]->HandleMultiPointerEventL(
+                            aPointerData,
+                            *iPointerState->FirstPointerPosition(),
+                            *iPointerState->SecondPointerPosition() );
+                    }
+                // One pointer up
+                else
+                    {
+                    iRecognizers[ i ]->HandleMultiPointerEventL(
+                            aPointerData,
+                            *iPointerState->FirstPointerPosition(),
+                            TPoint() );
+                    }
+                }
+            // Single pointer event
+            else
+                {
+                iRecognizers[ i ]->HandleSinglePointerEventL( 
+                        aPointerData );
+                }
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknTouchGestureFwRecognitionEngine::ImmediateFeedback
+// -----------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::ImmediateFeedback(
+    TTouchLogicalFeedback aLogicalFeedback,
+    TTouchFeedbackType aFeedbackType )
+    {
+    if ( iFeedBack )
+        {
+        // dummy pointer event is needed
+        TPointerEvent pointerEvent;
+        iFeedBack->InstantFeedback( iControl, aLogicalFeedback, aFeedbackType,
+            pointerEvent );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknTouchGestureFwRecognitionEngine::StartContinuousFeedback
+// -----------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::StartContinuousFeedback(
+    TTouchContinuousFeedback aType,
+    TInt aIntensity,
+    TTimeIntervalMicroSeconds32 aTimeout )
+    {
+    if ( iFeedBack )
+        {
+        iFeedBack->StartFeedback( iControl, aType, NULL,
+            aIntensity, aTimeout );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknTouchGestureFwRecognitionEngine::ModifyContinuousFeedback
+// -----------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::ModifyContinuousFeedback(
+    TInt aIntensity )
+    {
+    iFeedBack->ModifyFeedback( iControl, aIntensity );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknTouchGestureFwRecognitionEngine::StopContinuousFeedback
+// -----------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::StopContinuousFeedback()
+    {
+    if ( iFeedBack )
+        {
+        iFeedBack->StopFeedback( iControl );
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// Defines gesture groups, which trigger tactile feedback automatically.
+// ---------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::SetFeedbackForGroupsL( TUint aGestureGroups )
+    {
+    CAknTouchGestureFwBaseRecognizer* recognizer;
+    
+    TInt count = sizeof( KGestureGroup )/sizeof( TAknTouchGestureFwGroup );
+    for ( TInt i = 0; i < count; i++ )
+        {
+        if ( aGestureGroups & KGestureGroup[ i ] )
+            {
+            recognizer = Recognizer( KGestureGroup[ i ] );
+            if ( recognizer )
+                {
+                recognizer->SetFeedbackForTypesL(
+                    KAknTouchGestureFwAllGestureTypes,
+                    KAknTouchGestureFwAllGestureTypes );
+                }
+            }
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// Defines gesture types, which trigger tactile feedback automatically.
+// ---------------------------------------------------------------------------
+//
+void CAknTouchGestureFwRecognitionEngine::SetFeedbackForTypesL(
+    TAknTouchGestureFwGroup aGestureGroup,
+    TUint aGestureTypesForTactile,
+    TUint aGestureTypesForAudio )
+    {
+    if ( aGestureGroup == EAknTouchGestureFwNoGroup )
+        {
+        return;
+        }
+    if ( aGestureGroup == EAknTouchGestureFwAll )
+        {
+        for ( TInt i = 0; i < iRecognizers.Count(); i++ )
+            {
+            iRecognizers[ i ]->SetFeedbackForTypesL( aGestureTypesForTactile,
+                aGestureTypesForAudio );        
+            }
+        return;
+        }
+    
+    CAknTouchGestureFwBaseRecognizer* recognizer =
+        Recognizer( aGestureGroup );
+           
+    if ( recognizer )
+        {
+        recognizer->SetFeedbackForTypesL( aGestureTypesForTactile,
+            aGestureTypesForAudio );
+        }
+    }
+
+// End of File