diff -r 000000000000 -r 2f259fa3e83a akntouchgesturefw/src/akntouchgesturefwrecognitionengine.cpp --- /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 + +#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