diff -r 000000000000 -r 2f259fa3e83a akntouchgesturefw/src/akntouchgesturefwpointerstate.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/akntouchgesturefw/src/akntouchgesturefwpointerstate.cpp Tue Feb 02 01:00:49 2010 +0200 @@ -0,0 +1,332 @@ +/* +* 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: Touch gesture framework pointer state. +* +*/ + +#include "akntouchgesturefwdefs.h" +#include "akntouchgesturefwpointerstate.h" + +using namespace AknTouchGestureFw; + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CAknTouchGestureFwPointerState* CAknTouchGestureFwPointerState::NewL() + { + CAknTouchGestureFwPointerState* self = + CAknTouchGestureFwPointerState::NewLC(); + CleanupStack::Pop( self ); + return self; + } + + +// --------------------------------------------------------------------------- +// Two-phased constructor. +// --------------------------------------------------------------------------- +// +CAknTouchGestureFwPointerState* CAknTouchGestureFwPointerState::NewLC() + { + CAknTouchGestureFwPointerState* self + = new ( ELeave ) CAknTouchGestureFwPointerState(); + CleanupStack::PushL( self ); + return self; + } + + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CAknTouchGestureFwPointerState::~CAknTouchGestureFwPointerState() + { + } + + +// --------------------------------------------------------------------------- +// Resets the pointer state. +// --------------------------------------------------------------------------- +// +void CAknTouchGestureFwPointerState::Reset() + { + iPointerCount = 0; + iPointerData[0].iIsPressedDown = EFalse; + iPointerData[1].iIsPressedDown = EFalse; + iFirstPointerNumber = KInvalidPointerNumber; + iSecondPointerNumber = KInvalidPointerNumber; + } + + +// --------------------------------------------------------------------------- +// Updates the pointer state. +// --------------------------------------------------------------------------- +// +TBool CAknTouchGestureFwPointerState::Update( + const TPointerEventData& aPointerData ) + { + // Invalid events (e.g. several down events without corresponding + // up-event) are ignored. + iSuccessiveDownEvents = EFalse; + + TBool isValid( IsValidEvent( aPointerData.iPointerEvent.iType, + aPointerData.iPointerNumber ) ); + TBool targetedToControl( aPointerData.iTargetedToControl ); + + if ( isValid ) + { + // Updates pointer-related data + UpdatePointerOrder( aPointerData.iPointerEvent.iType, + aPointerData.iPointerNumber ); + + TPointerData& data( iPointerData[ aPointerData.iPointerNumber ] ); + + switch ( aPointerData.iPointerEvent.iType ) + { + case TPointerEvent::EButton1Down: + // One pointer is already down outside gesture control. + // No gesture recognition in such cases + if ( targetedToControl + && PointersDownOutsideControlArea() ) + { + targetedToControl = EFalse; + } + data.iPosition = aPointerData.iPointerEvent.iPosition; + data.iStartPosition = aPointerData.iPointerEvent.iPosition; + data.iIsPressedDown = ETrue; + data.iTargetedToControl = targetedToControl; + + iPointerCount++; + break; + + case TPointerEvent::EDrag: + data.iPosition = aPointerData.iPointerEvent.iPosition; + break; + + case TPointerEvent::EButton1Up: + data.iIsPressedDown = EFalse; + iPointerCount--; + break; + default: + break; + } + + targetedToControl = data.iTargetedToControl; + } + else + { + iSuccessiveDownEvents = + aPointerData.iPointerEvent.iType == TPointerEvent::EButton1Down; + } + + return isValid && targetedToControl; + } + + +// --------------------------------------------------------------------------- +// Returns the position of the first pointer. +// --------------------------------------------------------------------------- +// +TPoint* CAknTouchGestureFwPointerState::FirstPointerPosition() + { + __ASSERT_ALWAYS( iFirstPointerNumber != KInvalidPointerNumber, + User::Invariant() ); + return &iPointerData[ iFirstPointerNumber ].iPosition; + } + + +// --------------------------------------------------------------------------- +// Returns the position of the second pointer. +// --------------------------------------------------------------------------- +// +TPoint* CAknTouchGestureFwPointerState::SecondPointerPosition() + { + __ASSERT_ALWAYS( iSecondPointerNumber != KInvalidPointerNumber, + User::Invariant() ); + return &iPointerData[ iSecondPointerNumber ].iPosition; + } + + +// --------------------------------------------------------------------------- +// Checks whether or not two pointers are currently detected. +// --------------------------------------------------------------------------- +// +TBool CAknTouchGestureFwPointerState::IsDoubleTouch() const + { + return iPointerCount == 2; + } + + +// --------------------------------------------------------------------------- +// Checks whether or not only one pointer is currently detected. +// --------------------------------------------------------------------------- +// +TBool CAknTouchGestureFwPointerState::IsSingleTouch() const + { + return iPointerCount == 1; + } + + +// --------------------------------------------------------------------------- +// Checks whether or not there are currently any pointers detected. +// --------------------------------------------------------------------------- +// +TBool CAknTouchGestureFwPointerState::IsNoTouch() const + { + return !iPointerCount; + } + + +// --------------------------------------------------------------------------- +// Checks if successive down events have been received. +// --------------------------------------------------------------------------- +// +TBool CAknTouchGestureFwPointerState::SuccessiveDownEventsReceived() + { + return iSuccessiveDownEvents; + } + + +// --------------------------------------------------------------------------- +// Default C++ constructor. +// --------------------------------------------------------------------------- +// +CAknTouchGestureFwPointerState::CAknTouchGestureFwPointerState() + { + Reset(); + } + + +// --------------------------------------------------------------------------- +// Updates the order in which the pointers were detected. +// --------------------------------------------------------------------------- +// +void CAknTouchGestureFwPointerState::UpdatePointerOrder( + TPointerEvent::TType aPointerType, + TInt aPointerNumber ) + { + // Updates iFirstPointerNumber and iSecondPointerNumber to hold numbers + // (=ids) of pointers that were pressed down first and secondly. + // Possible values are 0 or 1 (or KInvalidPointerNumber if no pointers + // are down) + + // for double touch + __ASSERT_ALWAYS( aPointerNumber >= 0, User::Invariant() ); + __ASSERT_ALWAYS( aPointerNumber <= 1, User::Invariant() ); + + switch ( aPointerType ) + { + case TPointerEvent::EButton1Down: + { + if ( iPointerCount == 0 ) + { + iFirstPointerNumber = aPointerNumber; + } + else if ( iPointerCount == 1 ) + { + iSecondPointerNumber = aPointerNumber; + } + break; + } + + case TPointerEvent::EButton1Up: + { + if ( iPointerCount == 1 ) + { + iFirstPointerNumber = KInvalidPointerNumber; + } + else if ( iPointerCount == 2 ) + { + if ( aPointerNumber == 0 ) + { + iFirstPointerNumber = 1; + iSecondPointerNumber = KInvalidPointerNumber; + } + else if ( aPointerNumber == 1 ) + { + iFirstPointerNumber = 0; + iSecondPointerNumber = KInvalidPointerNumber; + } + } + break; + } + + default: + { + break; + } + } + } + + +// --------------------------------------------------------------------------- +// Checks if the received event is valid or not. +// --------------------------------------------------------------------------- +// +TBool CAknTouchGestureFwPointerState::IsValidEvent( + TPointerEvent::TType aPointerType, + TInt aPointerNumber ) + { + // In practice, event is NOT valid in the following situations: + // + // 1. Pointer down event is received for pointer which is already down. + // 2. Pointer up event is received for pointer which is already up. + // 3. Pointer drag event is received for pointer which is not down. + // + // In these situations this function returns EFalse, + // corresponding event is ignored and recognition continues as earlier. + // + TBool isValid( ETrue ); + if ( aPointerType == TPointerEvent::EButton1Down ) + { + if ( iPointerData[ aPointerNumber ].iIsPressedDown ) + { + isValid = EFalse; + } + } + else if ( aPointerType == TPointerEvent::EButton1Up + || aPointerType == TPointerEvent::EDrag ) + { + if ( !iPointerData[ aPointerNumber ].iIsPressedDown ) + { + isValid = EFalse; + } + } + + return isValid; + } + + +// --------------------------------------------------------------------------- +// Checks if pointers are down outside the control area. +// --------------------------------------------------------------------------- +// +TBool CAknTouchGestureFwPointerState::PointersDownOutsideControlArea() const + { + TBool outsideFound( EFalse ); + for ( TInt i = 0; i < KMaxPointerCount; i++ ) + { + if ( !iPointerData[ i ].iTargetedToControl && + iPointerData[ i ].iIsPressedDown ) + { + outsideFound = ETrue; + break; + } + } + return outsideFound; + } + +// End of File