akntouchgesturefw/src/akntouchgesturefwpointerstate.cpp
changeset 0 2f259fa3e83a
child 21 978afdc0236f
--- /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