mulwidgets/gesturehelper/src/gesturehelperimpl.cpp
changeset 17 3eca7e70b1b8
parent 3 4526337fb576
--- a/mulwidgets/gesturehelper/src/gesturehelperimpl.cpp	Tue Feb 02 00:28:09 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,912 +0,0 @@
-/*
-* Copyright (c) 2008 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 helper implementation
-*
-*/
-
-#include "gesturehelperimpl.h"
-
-#include <alf/alfevent.h>
-#include <e32base.h>
-#include <w32std.h>
-
-#include "gesture.h"
-#include "gesturedefs.h"
-
-#include "pointercapturer.h"
-
-using namespace GestureHelper;
-
-namespace GestureHelper
-{
-
-/// type of function in gesture helper to be called by the timer
-/// when timer triggers
-typedef void (CGestureHelperImpl::*CallbackFunctionL)();
-
-NONSHARABLE_CLASS( CCallbackTimer ) : public CTimer
-    {
-public:
-    /** Two-phase constructor */
-    static CCallbackTimer* NewL( CGestureHelperImpl& aHelper, 
-            CallbackFunctionL aCallbackFunctionL, TInt aDelay, TBool aIsEnabled )
-        {
-        CCallbackTimer* self = new ( ELeave ) CCallbackTimer( aHelper, 
-            aCallbackFunctionL, aDelay, aIsEnabled );
-        CleanupStack::PushL( self );
-        self->ConstructL(); // construct base class
-        CActiveScheduler::Add( self );
-        CleanupStack::Pop( self );
-        return self;
-        }
-        
-    /** Destructor */
-    ~CCallbackTimer()
-        {
-        Cancel();
-        }
-        
-    /** Set whether sending holding events is currently enabled */
-    void SetEnabled( TBool aEnabled )
-        {
-        iIsEnabled = aEnabled;
-        // cancel in case hold timer is already running
-        Cancel();
-        }
-        
-    /** @return whether sending holding events is currently enabled */
-    TBool IsEnabled() const
-        {
-        return iIsEnabled;
-        }
-        
-    /** Start the timer. Calls CGestureHelperImpl::StartHoldingL upon completion */
-    void Start()
-        {
-        // if sending hold events is disabled, do not ever start the hold timer, and 
-        // hence hold events will never be triggered
-        if ( iIsEnabled ) 
-            {
-            Cancel();
-            After( iDelay );
-            }
-        }    
-    
-private:    
-    /** Constructor */
-    CCallbackTimer( CGestureHelperImpl& aHelper,
-        CallbackFunctionL aCallbackFunctionL, TInt aDelay, TBool aIsEnabled )
-            : CTimer( EPriorityUserInput - 1 ), // give higher priority to new pointer events with - 1
-                iHelper( aHelper ), iCallbackFunctionL( aCallbackFunctionL ), 
-                    iDelay( aDelay ), iIsEnabled( aIsEnabled ) 
-        {
-        }
-        
-    void RunL() // From CActive
-        {
-        (iHelper.*iCallbackFunctionL)();
-        }
-
-private:
-    /// helper object that will be called back when timer is triggered
-    CGestureHelperImpl& iHelper;
-    /// Function in the iHelper object call 
-    CallbackFunctionL iCallbackFunctionL;
-    /// How long a time to wait befor calling back after Start()
-    TInt iDelay;
-    /// whether sending holding events is currently enabled
-    TBool iIsEnabled;
-    };
-
-} // namespace GestureHelper
-
-/** 
- * @return position from event. Use this instead of using aEvent direction to
- *         avoid accidentally using TPointerEvent::iPosition
- */
-inline TPoint Position( const TPointerEvent& aEvent )
-    {
-    // use parent position, since the capturer is using full screen area,
-    // and because the (Alfred) drag events are not local to visual even when
-    // coming from the client
-    return aEvent.iParentPosition;
-    }
-
-// ----------------------------------------------------------------------------
-// Two-phase constructor
-// ----------------------------------------------------------------------------
-//
-CGestureHelperImpl* CGestureHelperImpl::NewL( MGestureObserver& aObserver )
-    {
-    CGestureHelperImpl* self = new ( ELeave ) CGestureHelperImpl( );
-    CleanupStack::PushL( self );
-    self->iDoubleTapTimer = CCallbackTimer::NewL( *self, EmitFirstTapEventL, 
-        KMaxDoubleTapDuration, EFalse ); // double tap is disabled by default
-    self->iHoldingTimer = CCallbackTimer::NewL( *self, StartHoldingL, 
-        KHoldDuration, ETrue ); // holding is enabled by default
-    self->iGesture = new ( ELeave ) CGesture();
-    self->iUnusedGesture = new ( ELeave ) CGesture();
-    self->iPointerCapturer = CPointerCapturer::NewL();
-    self->iPointerCount = 0;
-    self->iObserver = &aObserver;
-    CleanupStack::Pop( self );
-    return self;
-    }
-
-// ----------------------------------------------------------------------------
-// Destructor
-// ----------------------------------------------------------------------------
-//
-CGestureHelperImpl::~CGestureHelperImpl()
-    {
-    delete iDoubleTapTimer;
-    delete iHoldingTimer;
-    delete iGesture;
-    delete iPreviousTapGesture;
-    delete iUnusedGesture;
-    delete iPointerCapturer;
-    }
-    
-// ----------------------------------------------------------------------------
-// SetHoldingEnabled
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::SetHoldingEnabled( TBool aEnabled )
-    {
-    iHoldingTimer->SetEnabled( aEnabled );
-    }
-
-// ----------------------------------------------------------------------------
-// IsHoldingEnabled
-// ----------------------------------------------------------------------------
-//
-TBool CGestureHelperImpl::IsHoldingEnabled() const
-    {
-    return iHoldingTimer->IsEnabled();
-    }
-
-// ----------------------------------------------------------------------------
-// SetHoldingEnabled
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::SetDoubleTapEnabled( TBool aEnabled )
-    {
-    iDoubleTapTimer->SetEnabled( aEnabled );
-    }
-
-// ----------------------------------------------------------------------------
-// IsHoldingEnabled
-// ----------------------------------------------------------------------------
-//
-TBool CGestureHelperImpl::IsDoubleTapEnabled() const
-    {
-    return iDoubleTapTimer->IsEnabled();
-    }
-    
-// ----------------------------------------------------------------------------
-// InitAlfredPointerEventCaptureL
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::InitAlfredPointerCaptureL( CAlfEnv& aEnv, 
-        CAlfDisplay& aDisplay, TInt aFreeControlGroupId )
-    {
-    iPointerCapturer->InitForAlfredL(*this, aEnv, aDisplay, aFreeControlGroupId );
-    }
-
-// ----------------------------------------------------------------------------
-// Reset state
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::Reset()
-    {
-    iHoldingTimer->Cancel();
-    iGesture->Reset();
-    iPointerCapturer->Stop();
-    iPointerCount=0;
-    iCurrentPointer = -1;
-    }
-
-/** 
- * Helper function that calls Reset on the pointer to CGestureHelperImpl
- */
-static void ResetHelper( TAny* aHelper )
-    {
-    static_cast< CGestureHelperImpl* >( aHelper )->Reset();
-    }
-
-// ----------------------------------------------------------------------------
-// Handle a pointer event
-// ----------------------------------------------------------------------------
-//
-TBool CGestureHelperImpl::HandlePointerEventL( const TPointerEvent& aEvent )
-    {     
-    return HandlePointerEventL( aEvent, NULL );
-    }
-
-// ----------------------------------------------------------------------------
-// OfferEventL
-// ----------------------------------------------------------------------------
-//
-TBool CGestureHelperImpl::OfferEventL( const TAlfEvent& aEvent )
-    {
-    if ( aEvent.IsPointerEvent() )
-        {
-        return HandlePointerEventL( aEvent.PointerEvent(), aEvent.Visual() );
-        }
-    return EFalse;
-    }
-
-// ----------------------------------------------------------------------------
-// Handle a pointer event
-// ----------------------------------------------------------------------------
-//
-TBool CGestureHelperImpl::HandlePointerEventL( const TPointerEvent& aEvent,
-        CAlfVisual* aVisual )
-    {  
-    TInt pointerNumber = GestureHelper::TGestureRecogniser().PointerNumber( aEvent );
-
-    if( !ValidatePointer( aEvent, pointerNumber ) )
-        {
-        return EFalse; // don't consume
-        }
-
-    switch ( aEvent.iType )
-        {
-        case TPointerEvent::EButton1Down:            
-		    // Error handling for recieveing a button down on the pointer which
-            // is already touched down
-            // Here the pointer number shouldnot be considered for validtaing.
-            // We should consider which pointer is currently touched down
-            // It can so happen that user has touched was doing pinch and then released his
-            // 1st finger. and starts to do panning with the second finger still touched down.
-            // Then again when he touches the first finger, in that case you should be validating these pointers w.r.t
-            // the pointer numbers of the last touched finger
-             
-            // we shouldnot consider pointer number here. If pointer 1 is
-            // already touched and dragging and we recieve a down of pointer 0     
-                    
-            if( iPointerCount == 1 )
-                {
-                if(iCurrentPointer == pointerNumber )
-                    {
-                    TRAP_IGNORE( EmitCancelEventL() );
-                    Reset();
-                    }
-                }
-            else if( iPointerCount == 2 )
-                {
-                // This case is similar to reciving a pointer up on the pointer
-                // on which the second down is recieved. We reset all the earlier points
-                // recieved on this pointer because we assume that some pointer up got
-                // missed in between.
-            
-                // if pointer count is already 2, then reset the array of pointer for 
-                // which a down event is recieved, and continue handling in normal way
-                // Fix for error crash in photos fullscreen
-                // Like above if you reset the pointer array for which the down event
-                // is recieved the second time then in thecase of, 0 down, 1 down, 0 down
-                // iPoints will be null.
-                // Here whenever reseting it to single pointer havndling, always iPoints should have
-                // the data. Hence the first parameter should always be true.
-                // Fix is iGesture->ResetToLastPoint(pointerNumber != 0,pointerNumber != 0);
-                // is changed to iGesture->ResetToLastPoint( ETrue,pointerNumber != 0);
-                iPointerCount = 1; 
-                iCurrentPointer = pointerNumber == 0 ? 1 : 0;
-                iGesture->ResetToLastPoint( ETrue,pointerNumber != 0);
-                iGesture->SetSingleTouchActive();
-                }
-
-            if(iPointerCount == 0)
-                {
-                iPointerCount = 1;
-                iCurrentPointer = pointerNumber;
-                // single touch gesture start
-                iGesture->SetSingleTouchActive();
-                HandleSinglePointerEventL( aEvent, aVisual );
-                }
-            else if(iPointerCount == 1)
-                {              
-                iPointerCount = 2;
-                iCurrentPointer = -1;
-                // add the last point of the single touch event
-                // to first array of gesture
-                iGesture->ResetToLastPoint(pointerNumber != 0,ETrue);
-                iGesture->SetMultiTouchActive();
-                // multi touch gesture start
-                HandleMultiplePointerEventL( aEvent, pointerNumber );
-                }
-            else
-                {
-                
-                }
-            break;
-            
-        case TPointerEvent::EDrag:
-            if(iPointerCount == 1)
-                {
-                HandleSinglePointerEventL( aEvent, aVisual );
-                }
-            else if(iPointerCount == 2)
-                {
-                HandleMultiplePointerEventL( aEvent, pointerNumber );
-                }
-            else
-                {
-                // nothing to be done
-                }
-            break;
-            
-        case TPointerEvent::EButton1Up:
-            if(iPointerCount == 2)
-                { 
-                // multi touch gesture complete
-                HandleMultiplePointerEventL( aEvent, pointerNumber );
-                // should the pointer count decrese first n then
-                // handling of event or otherwise
-                iPointerCount = 1;    
-                iCurrentPointer = pointerNumber == 0 ? 1 : 0;
-                iGesture->ResetToLastPoint(ETrue,pointerNumber != 0);
-                iGesture->SetSingleTouchActive();
-                }
-            else if( iPointerCount == 1 )
-                {
-                iPointerCount = 0;
-                iCurrentPointer = -1;
-                // single touch gesture complete
-                HandleSinglePointerEventL( aEvent, aVisual ); 
-                }
-            else
-                {
-                // nothing to be done
-                }
-            break;
-            
-        default:
-            break;
-        }
-    return ETrue; // consume
-    }
-// ----------------------------------------------------------------------------
-// Handle a pointer event
-// ----------------------------------------------------------------------------
-//
-TBool CGestureHelperImpl::HandleSinglePointerEventL( const TPointerEvent& aEvent,
-        CAlfVisual* aVisual )
-    {  
-    switch ( aEvent.iType )
-        {
-        case TPointerEvent::EButton1Down:
-            // If no up event was received during previous gesture, cancel 
-            // previous event and reset state
-            if ( !IsIdle() )
-                {
-                // ambiguous what is the right thing when "cancel" event leaves
-                // and "start" does not. Leaving for cancel *after* "start" could 
-                // be unexpected to client, as client would have handled start 
-                // event successfully. Assume that leaving upon cancellation 
-                // can be ignored.
-                TRAP_IGNORE( EmitCancelEventL() );
-                Reset();  
-                }
-            // as long as down event of a double tap comes within the double 
-            // tap timeout, it does not matter how long the user keeps the finger
-            // pressed for the gesture to be a double tap. Therefore, cancel
-            // the timeout, as it is no longer relevant. (Of course, this call
-            // will only do something if the timer is actually running, which
-            // is only if received a tap event very recently.)
-            iDoubleTapTimer->Cancel();
-            // adding the first point implicitly makes the state "not idle"
-            AddPointL( aEvent );
-            iGesture->SetVisual( aVisual );
-            // if pointer capturer leaves, the remaining pointer events will
-            // not be captured if stylus is dragged outside the capturing visual
-            // an error note will be shown, so the potential problem is irrelevant,
-            // assuming client does not (incorrectly) block the leave from reaching 
-            // the framework
-            iPointerCapturer->StartL();
-            // Delay emitting a down event _until_ it is known that this beginning 
-            // gesture is _not_ the second tap of a double tap event.
-            // iPreviousTapGesture is only non-null if very recently received 
-            // a tap event and double tap is enabled. 
-            if ( !iPreviousTapGesture )
-                {
-                EmitEventL( *iGesture );
-                }
-            // else delay emitting an event, as it might be a double tap 
-            // (allow the second tap of a double tap to be anywhere, so don't check
-            // for start pos here)
-            break;
-            
-        case TPointerEvent::EDrag:
-            // While stylus down, the same event is received repeatedly
-            // even if stylus does not move. Filter out by checking if point 
-            // is the same as the latest point
-            if ( !iGesture->IsLatestPoint( Position( aEvent ) ) )
-                {
-                AddPointL( aEvent );
-
-                // as long as the starting gesture is seen as a tap, do not emit any
-                // drag events
-                if ( !iGesture->IsTap() )
-                    {
-                    // if there is a previous tap gesture, getting drag events means that
-                    // the previous gesture is not a double tap. So emit the previous gesture.
-                    if ( iPreviousTapGesture )
-                        {
-                        // this is a second gesture after a tap (double tap is enabled)
-                        EmitFirstTapEventL();
-                        // emit down event for the current gesture (since its down was delayed, until
-                        // it was to be known if the event is a tap. That is known now.)
-                        EmitStartEventL( *iGesture );
-                        }
-                    // restart holding timer every time the current stylus pos changes
-                    StartHoldingTimer( aEvent );
-                    // emit the drag event to client
-                    EmitEventL( *iGesture );
-                    }
-                // else: do not emit drag events until it is known that the gesture is not a tap
-                // (or the second tap of double tap)
-                }
-            break;
-
-        case TPointerEvent::EButton1Up:
-            // reset in case the down event for next gesture is not received for a reason 
-            // in client, and instead drag or up events are received. 
-            // reset via cleanup stack to ensure Reset is run even if
-            // observer leaves
-            CleanupStack::PushL( TCleanupItem( &ResetHelper, this ) );
-            // if adding of the point fails, notify client with a 
-            // cancelled event. It would be wrong to send another
-            // gesture code when the up point is not known
-            if ( KErrNone == AddPoint( aEvent ) )
-                {
-                // if the gesture is a tap, the gesture is either the first tap of a _potential_
-                // double tap, or the second tap of a double tap
-                if ( iDoubleTapTimer->IsEnabled() && iGesture->IsTap() )
-                    {
-                    __ASSERT_DEBUG( !iGesture->IsHolding(), Panic( EGesturePanicIllegalLogic ) );
-                    if ( !iPreviousTapGesture )
-                        {
-                        // First tap. Delay emitting its code evemt and released events until it is known
-                        // whether the tap is a double tap
-                        iPreviousTapGesture = iGesture;
-                        iGesture = NewGesture();
-                        iDoubleTapTimer->Start(); 
-                        }
-                    else
-                        {
-                        // This is a second tap of a double tap. Do not emit anything for the second
-                        // tap. Only down event has been emitted for the first tap. Emit the code 
-                        // event (double tap) and released for the first tap.
-                        iPreviousTapGesture->SetDoubleTap();
-                        EmitFirstTapEventL();
-                        }
-                    }
-                else 
-                    {
-                    // modified iGesture to be "released"
-                    CompleteAndEmitSingleTouchL( *iGesture );
-                    }
-                }
-            else
-                { // adding a point failed
-                EmitCancelEventL();
-                }
-            // reset state
-            CleanupStack::PopAndDestroy( this ); 
-            break;
-            
-        default:
-            break;
-        }
-    return ETrue; // consume
-    }
-
-// ----------------------------------------------------------------------------
-// Handle multiple pointer events
-// ----------------------------------------------------------------------------
-//
-TBool CGestureHelperImpl::HandleMultiplePointerEventL( const TPointerEvent& aEvent,
-       const TInt aPointerNumber )
-    { 
-    switch ( aEvent.iType )
-        {
-        case TPointerEvent::EButton1Down:
-            // adding the first point implicitly makes the state "not idle"
-            AddMultiTouchPointsL( aEvent, aPointerNumber);
-            EmitEventL( *iGesture );
-            break;
-            
-        case TPointerEvent::EDrag:
-            // While stylus down, the same event is received repeatedly
-            // even if stylus does not move. Filter out by checking if point 
-            // is the same as the latest point
-            if( AddMultiTouchPointsL(aEvent, aPointerNumber ))
-                {
-                // as long as the starting gesture is seen as a tap, do not emit any
-                // drag events
-                if ( iGesture->IsPinch() )
-                    {
-                    // emit the pinch event to client
-                    EmitEventL( *iGesture );
-                    }
-                // else: do not emit any events to the client               
-                }
-
-            
-            break;
-
-        case TPointerEvent::EButton1Up:
-                        
-            // if adding of the point fails, notify client with a 
-            // cancelled event. It would be wrong to send another
-            // gesture code when the up point is not known
-            AddMultiTouchPointsL(aEvent, aPointerNumber );
-            CompleteAndEmitDoubleTouchL( *iGesture );
-
-            break;
-            
-        default:
-            break;
-        }   
-    return ETrue; // consume
-    }
-
-// ----------------------------------------------------------------------------
-// Validate AddMultiTouchPointsL events
-// Check if the point recieved is the repeavt event of previous point or a new point 
-// inline ok in cpp file for a private member function
-// ----------------------------------------------------------------------------
-//
-inline TBool CGestureHelperImpl::AddMultiTouchPointsL( const TPointerEvent& aEvent, const TInt aPointerNumber)
-    {
-    TBool pointAdded = EFalse;
-    if ( aPointerNumber > 0 )
-        {
-        if ( !iGesture->IsLatestSecondaryPoint( Position( aEvent ) ) )
-            {
-            AddSecondaryPointL( aEvent );
-            pointAdded = ETrue;
-            }                 
-        }
-    else
-        {
-        if ( !iGesture->IsLatestPoint( Position( aEvent ) ) )
-            {
-            AddPointL( aEvent );
-            pointAdded = ETrue;
-            }                
-        }
-    return pointAdded;
-    }
-
-// ----------------------------------------------------------------------------
-// Check for Stray evnet
-// ----------------------------------------------------------------------------
-//
-TBool CGestureHelperImpl::StrayEvent( const TPointerEvent& aEvent ) const
-    {
-     //If we are recieving a button down on pointer 0 in pointer capturer then its a stray event
-    // Dont consume it
-    if ( aEvent.iType == TPointerEvent::EButton1Down && IsIdle( 0) )
-        {
-        return ETrue; // don't consume
-        }  
-	return EFalse;  
-    }
-// ----------------------------------------------------------------------------
-// Validate the events
-// is it a valid event or a stray pointer form some other visuals
-// inline ok in cpp file for a private member function
-// ----------------------------------------------------------------------------
-//
-inline TBool CGestureHelperImpl::ValidatePointer( const TPointerEvent& aEvent, const TInt aPointerNumber) const
-    {
-    // Check if received event is valid or not.
-    // 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.
-    // 4. Pointer numbers other than 0 and 1. We are handling only 2 pointers.
-    //
-    // In these situations this function returns EFalse,
-    // corresponding event is ignored and recognition continues as earlier.
-    //
-    
-    // filter all the events for which the pointer number is less than 0
-    // or greater than 1. we will handle only 2 pointer events.  
-    if( aPointerNumber >= 2 || aPointerNumber < 0 )
-        {
-        return EFalse;
-        }
-        
-    // filter out events that do not start with button down. It is a stray
-    // event from another visual    
-    TInt pointerTovalidate = aPointerNumber ;
-    if( iPointerCount == 1 && aPointerNumber == 1)
-	    {
-	    pointerTovalidate = 0;
-	    }
-    if ( aEvent.iType != TPointerEvent::EButton1Down && IsIdle( pointerTovalidate ) )
-        {
-        return EFalse; // don't consume
-        }
-
-    
-    return ETrue;
-    }
-
-// ----------------------------------------------------------------------------
-// Is the helper idle?
-// Checks whether any points are already added in the array corresponding
-// to the pointer number 
-// inline ok in cpp file for a private member function
-// ----------------------------------------------------------------------------
-//
-inline TBool CGestureHelperImpl::IsIdle( TBool aPointerNumber ) const
-    {
-    if( aPointerNumber == 0 )
-        {
-        return iGesture->IsEmpty();
-        }
-    else if( aPointerNumber == 1 )
-        {
-        return iGesture->IsMultiTouch();
-        }
-    return ETrue;
-    }
-
-// ----------------------------------------------------------------------------
-// Add a point to the sequence of points that together make up the gesture
-// inline ok in cpp file for a private member function
-// ----------------------------------------------------------------------------
-//
-inline void CGestureHelperImpl::AddPointL( const TPointerEvent& aEvent )
-    {
-    User::LeaveIfError( AddPoint( aEvent ) );
-    }
-
-// ----------------------------------------------------------------------------
-// Add a point to the sequence of points that together make up the gesture
-// inline ok in cpp file for a private member function
-// ----------------------------------------------------------------------------
-//
-inline TInt CGestureHelperImpl::AddPoint( const TPointerEvent& aEvent )
-    {
-    return iGesture->AddPoint( Position ( aEvent ) );
-    }
-
-// ----------------------------------------------------------------------------
-// Add a point to the sequence of points that together make up the gesture
-// inline ok in cpp file for a private member function
-// ----------------------------------------------------------------------------
-//
-inline void CGestureHelperImpl::AddSecondaryPointL( const TPointerEvent& aEvent )
-    {
-    User::LeaveIfError( AddSecondaryPoint( aEvent ) );
-    }
-
-// ----------------------------------------------------------------------------
-// Add a point to the sequence of points that together make up the gesture
-// inline ok in cpp file for a private member function
-// ----------------------------------------------------------------------------
-//
-inline TInt CGestureHelperImpl::AddSecondaryPoint( const TPointerEvent& aEvent )
-    {
-    return iGesture->AddSecondaryPoint( Position ( aEvent ) );
-    }
-
-// ----------------------------------------------------------------------------
-// StartHoldingTimer
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::StartHoldingTimer( const TPointerEvent& aNewEvent )
-    {
-    if ( !( iGesture->IsHolding() ||
-            iGesture->IsNearHoldingPoint( Position( aNewEvent ) ) ) )
-        {
-        // restart hold timer, since pointer has moved
-        iHoldingTimer->Start();
-        // Remember the point in which holding was started
-        iGesture->SetHoldingPoint();
-        }
-    }
-
-/** 
- * Helper function that calls ContinueHolding on the pointer to TGesture
- */
-static void ContinueHolding( TAny* aGesture )
-    {
-    static_cast< CGesture* >( aGesture )->ContinueHolding();
-    }
-
-// ----------------------------------------------------------------------------
-// Add a point to the sequence of points that together make up the gesture
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::StartHoldingL()
-    {
-    // hold & tap event is specifically filtered out. Use case: in list fast 
-    // scrolling activation (e.g. enhanced coverflow), tap & hold should not
-    // start fast scroll. In addition, after long tap on start position,
-    // drag and drag & hold swiping should emit normal swipe and swipe&hold
-    // events. Therefore, tap & hold is not supported.
-    __ASSERT_DEBUG( !iGesture->IsTap() && !iPreviousTapGesture, Panic( EGesturePanicIllegalLogic ) );
-    
-    // holding has just started, and gesture code should be provided to client.
-    // set gesture state so that it produces a gesture code (other than drag)
-    iGesture->StartHolding();
-    
-    // create an item in the cleanup stack that will set the gesture state
-    // to holding-was-started-earlier state. NotifyL may leave, but the
-    // holding-was-started-earlier state must still be successfully set,
-    // otherwise, the holding gesture code will be sent twice
-    CleanupStack::PushL( TCleanupItem( &ContinueHolding, iGesture ) );
-    
-    EmitEventL( *iGesture );
-    
-    // set holding state to "post holding"
-    CleanupStack::PopAndDestroy( iGesture );
-    }
-
-// ----------------------------------------------------------------------------
-// RecyclePreviousTapGesture
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::RecyclePreviousTapGesture( TAny* aSelf )
-    {
-    CGestureHelperImpl& self = *reinterpret_cast<CGestureHelperImpl*>( aSelf );
-    self.RecycleGesture( self.iPreviousTapGesture );
-    }
-
-// ----------------------------------------------------------------------------
-// Emit the remainder of the previous tap event (tap + released)
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::EmitFirstTapEventL()
-    {
-    // when this function is called, a tap has turned out to _not_ be a double tap
-    __ASSERT_DEBUG( IsDoubleTapEnabled(), Panic( EGesturePanicIllegalLogic ) );
-    __ASSERT_DEBUG( iPreviousTapGesture, Panic( EGesturePanicIllegalLogic ) );
-    
-    iDoubleTapTimer->Cancel();
-    
-    // ensure previous tap gesture is reset even if client leaves
-    CleanupStack::PushL( TCleanupItem( &RecyclePreviousTapGesture, this ) );
-    
-    CompleteAndEmitSingleTouchL( *iPreviousTapGesture );
-    
-    // recycle the emitted gesture 
-    CleanupStack::PopAndDestroy( this ); 
-    }
-
-// ----------------------------------------------------------------------------
-// EmitStartEventL
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::EmitStartEventL( const CGesture& aGesture )    
-    {
-    CGesture* startGesture = aGesture.AsStartEventLC();
-    EmitEventL( *startGesture );
-    CleanupStack::PopAndDestroy( startGesture );    
-    }
-    
-// ----------------------------------------------------------------------------
-// EmitCompletionEvents for single touch
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::CompleteAndEmitSingleTouchL( CGesture& aGesture )
-    {
-    aGesture.SetSingleTouchComplete();
-    // send gesture code if holding has not been started. If holding has 
-    // been started, client has already received a "hold swipe left" e.g. event, in which
-    // case don't another "swipe left" event
-    if ( !aGesture.IsHolding() )
-        {
-        // if client leaves, the state is automatically reset.
-        // In this case the client will not get the released event
-        EmitEventL( aGesture ); 
-        }
-    // send an event that stylus was lifted
-    aGesture.SetSingleTouchReleased();
-    EmitEventL( aGesture ); 
-    }
- 
-// ----------------------------------------------------------------------------
-// EmitCompletionEvents for double touch
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::CompleteAndEmitDoubleTouchL( CGesture& aGesture )
-    {
-    aGesture.SetMultiTouchComplete();
-    if ( aGesture.IsPinch() )
-        {
-        // emit the pinch event to client
-        EmitEventL( aGesture );
-        }
-    // send an event that stylus was lifted
-    aGesture.SetMultiTouchReleased();
-    EmitEventL( aGesture ); 
-    }
-
-// ----------------------------------------------------------------------------
-// EmitCancelEventL
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::EmitCancelEventL()
-    {
-    iDoubleTapTimer->Cancel();
-
-    // ensure previous tap gesture is reset even if client leaves
-    CleanupStack::PushL( TCleanupItem( &RecyclePreviousTapGesture, this ) );
-
-    CGesture& gestureToCancel = iPreviousTapGesture ? *iPreviousTapGesture : *iGesture;
-    gestureToCancel.SetCancelled();
-    EmitEventL( gestureToCancel );
-    
-    // recycle the emitted gesture 
-    CleanupStack::PopAndDestroy( this ); 
-    }
-
-// ----------------------------------------------------------------------------
-// Notify observer
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::EmitEventL( const CGesture& aGesture )
-    {
-    // iPoints array must have content when this function is called
-    iObserver->HandleGestureL( aGesture );
-    }
-
-// ----------------------------------------------------------------------------
-// Return a fresh gesture from the gesture pool (pool of one gesture)
-// ----------------------------------------------------------------------------
-//
-CGesture* CGestureHelperImpl::NewGesture()
-    {
-    __ASSERT_DEBUG( iUnusedGesture, Panic( EGesturePanicIllegalLogic ) ); // pool should no be empty
-    iUnusedGesture->Reset();
-    CGesture* freshGesture = iUnusedGesture;
-    iUnusedGesture = NULL;
-    return freshGesture;
-    }
-
-// ----------------------------------------------------------------------------
-// Return a fresh gesture from the gesture pool (pool of one gesture)
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::RecycleGesture( CGesture*& aGesturePointer )
-    {
-    // only one object fits into the pool, and that should currently be enough
-    // one pointer must be null, one non-null
-    __ASSERT_DEBUG( !iUnusedGesture != !aGesturePointer, Panic( EGesturePanicIllegalLogic ) );
-    if ( aGesturePointer )
-        {
-        iUnusedGesture = aGesturePointer;
-        aGesturePointer = NULL;
-        }
-    }
-
-// ----------------------------------------------------------------------------
-// AddObserver
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::AddObserver(MGestureObserver* aObserver)
-    {
-    iObserver = aObserver;
-    }
-	
-// end of file
-