webengine/webkitutils/rt_gesturehelper/src/gesturehelperimpl.cpp
changeset 1 7c90e6132015
parent 0 dd21522fd290
--- a/webengine/webkitutils/rt_gesturehelper/src/gesturehelperimpl.cpp	Mon Mar 30 12:54:55 2009 +0300
+++ b/webengine/webkitutils/rt_gesturehelper/src/gesturehelperimpl.cpp	Fri May 08 08:25:06 2009 +0300
@@ -18,18 +18,15 @@
 
 #include "gesturehelperimpl.h"
 
-#include <alf/alfevent.h>
 #include <e32base.h>
 #include <w32std.h>
 
 #include "gesture.h"
 #include "gesturedefs.h"
 #include "utils.h"
-#include "pointercapturer.h"
 #include "gestureeventfilter.h"
 #include "gesturehelpereventsender.h"
 #include "flogger.h"
-#include "gestureevent.h"
 
 using namespace RT_GestureHelper;
 
@@ -128,7 +125,7 @@
     // and because the (Alfred) drag events are not local to visual even when
     // coming from the client
     
-    return aEvent.iParentPosition;
+    return aEvent.iPosition;
     }
 
 // ----------------------------------------------------------------------------
@@ -140,14 +137,14 @@
     CGestureHelperImpl* self = new ( ELeave ) CGestureHelperImpl( aObserver );
     CleanupStack::PushL( self );
     self->iEventSender = CGestureEventSender::NewL( aObserver );
-    self->iDoubleTapTimer = CCallbackTimer::NewL( *self, EmitFirstTapEventL, 
+    self->iDoubleTapTimer = CCallbackTimer::NewL( *self, EmitFirstTapEvent, 
             KMaxTapDuration, EFalse ); // double tap is disabled by default
     self->iHoldingTimer = CCallbackTimer::NewL( *self, StartHoldingL, 
         KHoldDuration, EFalse ); // holding is enabled by default
     
-    self->iLongTouchTimer = CCallbackTimer::NewL( *self, HandleLongTouchL, 
+    self->iLongTouchTimer = CCallbackTimer::NewL( *self, HandleLongTouch, 
             KLongTapDuration, ETrue ); // holding is enabled by default
-    self->iPointerCapturer = CPointerCapturer::NewL();    
+    
     self->iGesture = new ( ELeave ) CGesture();
     self->iUnusedGesture = new ( ELeave ) CGesture();
     TInt tapLimit = Mm2Pixels(KFingerSize_mm) / 2;
@@ -176,7 +173,6 @@
     delete iGesture;
     delete iPreviousTapGesture;
     delete iUnusedGesture;
-    delete iPointerCapturer;
     delete iLongTouchTimer;
     delete iEventFilter;
     delete iEventSender;
@@ -219,15 +215,7 @@
     return iDoubleTapTimer->IsEnabled();
     }
     
-// ----------------------------------------------------------------------------
-// InitAlfredPointerEventCaptureL
-// ----------------------------------------------------------------------------
-//
-void CGestureHelperImpl::InitAlfredPointerCaptureL( CAlfEnv& aEnv, 
-        CAlfDisplay& aDisplay, TInt aFreeControlGroupId )
-    {
-    iPointerCapturer->InitForAlfredL(*this, aEnv, aDisplay, aFreeControlGroupId );
-    }
+
 
 // ----------------------------------------------------------------------------
 // Reset state
@@ -238,7 +226,6 @@
     iHoldingTimer->Cancel();
     iLongTouchTimer->Cancel();
     iGesture->Reset();
-    iPointerCapturer->Stop();
     }
 
 /** 
@@ -259,7 +246,6 @@
     SetLastEventTime();
     if (!iEventFilter->FilterDrag(aEvent, iLastEventTime, filterReason))
         {
-        iGesture->SetVisual( NULL );
         return noneAlf_HandlePointerEventL( aEvent );
         }
     else
@@ -275,39 +261,13 @@
         }
     }
 
-// ----------------------------------------------------------------------------
-// OfferEventL
-// ----------------------------------------------------------------------------
-//
-TBool CGestureHelperImpl::OfferEventL( const TAlfEvent& aEvent )
-    {
-    if ( aEvent.IsPointerEvent() )
-        {
-        return HandlePointerEventL( aEvent.PointerEvent(), aEvent.Visual() );
-        }
-    return EFalse;
-    }
-
-
-
-
-
-
-// ----------------------------------------------------------------------------
-// Handle a pointer event
-// ----------------------------------------------------------------------------
-//
-
 
 TBool CGestureHelperImpl::noneAlf_HandlePointerEventL( const TPointerEvent& aEvent)
     {
-    
     switch ( aEvent.iType )
         {
         case TPointerEvent::EButton1Down:
             {
-            
-            iPointerCapturer->StartL();
             HandleTouchDownL(aEvent);
             break;
             }
@@ -318,16 +278,15 @@
             }
         case TPointerEvent::EButton1Up:
             {
-            CleanupStack::PushL( TCleanupItem( &ResetHelper, this ) );
             if (KErrNone == AddPoint( aEvent ))
                 {
-                HandleTouchUpL(aEvent);
+                HandleTouchUp(aEvent);
                 }
             else
                 {
-                EmitCancelEventL();
+                EmitCancelEvent();
                 }
-            CleanupStack::PopAndDestroy( this ); 
+            Reset();
             break;
             }
         default:
@@ -336,162 +295,19 @@
     return ETrue;
     }
 
-
-TBool CGestureHelperImpl::HandlePointerEventL( const TPointerEvent& aEvent,
-        CAlfVisual* aVisual )
-    {  
-    // filter out events that do not start with button down. It is a stray
-    // event from another visual
-    if ( IsIdle() && aEvent.iType != TPointerEvent::EButton1Down )
-        {
-        return EFalse; // don't consume
-        }
-    
-    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"
-                    CompleteAndEmitL( *iGesture );
-                    }
-                }
-            else
-                { // adding a point failed
-                EmitCancelEventL();
-                }
-            // reset state
-            CleanupStack::PopAndDestroy( this ); 
-            break;
-            
-        default:
-            break;
-        }
-    return ETrue; // consume
-    }
-
-
 TBool CGestureHelperImpl::IsMovementGesture(TGestureCode aCode)
     {
     return (aCode == EGestureDrag || aCode == EGestureFlick || aCode == EGestureSwipeUp ||
             aCode == EGestureSwipeDown || aCode == EGestureSwipeRight || aCode == EGestureSwipeLeft);
     }
 
-void CGestureHelperImpl::HandleLongTouchL()
+void CGestureHelperImpl::HandleLongTouch()
     {
     iDoubleTapTimer->Cancel();
     iGesture->SetLongTap(ETrue);
     iGesture->SetComplete();
     TPoint startPos = iGesture->StartPos();
-    EmitEventL(*iGesture);
+    EmitEvent(*iGesture);
     iGesture->Reset();
     iGesture->AddPoint( startPos, GetLastEventTime() );
     }
@@ -500,18 +316,25 @@
     {
     TGestureCode prevCode = iGesture->PreviousGestureCode();
     if (prevCode == EGestureStart) return;
+    if (prevCode == EGestureDrag) 
+        {
+        iGesture->Reset();
+        }
     AddPointL( aEvent );
     
+    if (!iLongTouchTimer->IsActive())
+        {
     iLongTouchTimer->Start();
+        }
     if (!iDoubleTapTimer->IsActive())
         {
-            EmitEventL( *iGesture );
+            EmitEvent( *iGesture );
         }
     }
 
 void CGestureHelperImpl::HandleMoveL(const TPointerEvent& aEvent)
     {
-    if (iGesture->IsLatestPoint( iGesture->Visual() ? Position ( aEvent ) : aEvent.iPosition)) return; // I'm not sure we need this
+    if (iGesture->IsLatestPoint( Position(aEvent))) return; // I'm not sure we need this
     //Cancel double tap time - it's neither tap nor double tap 
     iDoubleTapTimer->Cancel();
     iLongTouchTimer->Cancel();
@@ -527,11 +350,11 @@
     
     if (!isFirstPoint)
         {
-        EmitEventL( *iGesture );
+        EmitEvent( *iGesture );
         }
     }
 
-void CGestureHelperImpl::HandleTouchUpL(const TPointerEvent& /*aEvent*/)
+void CGestureHelperImpl::HandleTouchUp(const TPointerEvent& /*aEvent*/)
     {
     TGestureCode prevCode = iGesture->PreviousGestureCode();
     iLongTouchTimer->Cancel();
@@ -547,13 +370,13 @@
     */
     if ( prevCode == EGestureLongTap )
         {
-        EmitReleasedEventL();
+        EmitReleasedEvent();
         }
     else if (IsMovementGesture(prevCode) || 
              !iDoubleTapTimer->IsEnabled() /* || !iGesture->IsTap()*/ ) 
         {
         iGesture->SetComplete();
-        EmitEventL(*iGesture);
+        EmitEvent(*iGesture);
         }
     
     else 
@@ -566,7 +389,7 @@
             // it's a double tap
             iLastTouchUpTime = iLastEventTime;
             iLastDoubleTapTime = iLastEventTime;
-            EmitDoubleTapEventL();
+            EmitDoubleTapEvent();
             }
         else
             {
@@ -586,18 +409,18 @@
 
 
 
-void CGestureHelperImpl::EmitDoubleTapEventL()
+void CGestureHelperImpl::EmitDoubleTapEvent()
     {
     iPreviousTapGesture->SetDoubleTap();
-    EmitFirstTapEventL();
+    EmitFirstTapEvent();
     }
 
 
-void CGestureHelperImpl::EmitReleasedEventL()
+void CGestureHelperImpl::EmitReleasedEvent()
     {
     iGesture->SetComplete();
     iGesture->SetReleased();
-    EmitEventL(*iGesture);
+    EmitEvent(*iGesture);
     }
 
 
@@ -628,7 +451,7 @@
 //
 inline TInt CGestureHelperImpl::AddPoint( const TPointerEvent& aEvent )
     {
-    TPoint pos = iGesture->Visual() ? Position ( aEvent ) : aEvent.iPosition;
+    TPoint pos = Position ( aEvent );
     return iGesture->AddPoint( pos, GetLastEventTime() );
     }
 
@@ -679,7 +502,7 @@
     // otherwise, the holding gesture code will be sent twice
     CleanupStack::PushL( TCleanupItem( &ContinueHolding, iGesture ) );
     
-    EmitEventL( *iGesture );
+    EmitEvent( *iGesture );
     
     // set holding state to "post holding"
     CleanupStack::PopAndDestroy( iGesture );
@@ -699,21 +522,16 @@
 // Emit the remainder of the previous tap event (tap + released)
 // ----------------------------------------------------------------------------
 //
-void CGestureHelperImpl::EmitFirstTapEventL()
+void CGestureHelperImpl::EmitFirstTapEvent()
     {
     // 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 ) );
-    
-    CompleteAndEmitL( *iPreviousTapGesture );
-    
-    // recycle the emitted gesture 
-    CleanupStack::PopAndDestroy( this ); 
+    CompleteAndEmit( *iPreviousTapGesture );
+    RecycleGesture(iPreviousTapGesture);
+     
     }
 
 // ----------------------------------------------------------------------------
@@ -723,7 +541,7 @@
 void CGestureHelperImpl::EmitStartEventL( const CGesture& aGesture )    
     {
     CGesture* startGesture = aGesture.AsStartEventLC();
-    EmitEventL( *startGesture );
+    EmitEvent( *startGesture );
     CleanupStack::PopAndDestroy( startGesture );    
     }
     
@@ -731,7 +549,7 @@
 // EmitCompletionEventsL
 // ----------------------------------------------------------------------------
 //
-void CGestureHelperImpl::CompleteAndEmitL( CGesture& aGesture )
+void CGestureHelperImpl::CompleteAndEmit( CGesture& aGesture )
     {
     aGesture.SetComplete();
     // send gesture code if holding has not been started. If holding has 
@@ -741,48 +559,44 @@
         {
         // if client leaves, the state is automatically reset.
         // In this case the client will not get the released event
-        EmitEventL( aGesture ); 
+        EmitEvent( aGesture ); 
         }
     
     // send an event that stylus was lifted
     aGesture.SetReleased();
-    EmitEventL( aGesture ); 
+    EmitEvent( aGesture ); 
     }
     
 // ----------------------------------------------------------------------------
 // EmitCancelEventL
 // ----------------------------------------------------------------------------
 //
-void CGestureHelperImpl::EmitCancelEventL()
+void CGestureHelperImpl::EmitCancelEvent()
     {
     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 );
+    EmitEvent( gestureToCancel );
+    RecycleGesture(iPreviousTapGesture);
     
-    // recycle the emitted gesture 
-    CleanupStack::PopAndDestroy( this ); 
     }
 
 // ----------------------------------------------------------------------------
 // Notify observer
 // ----------------------------------------------------------------------------
 //
-void CGestureHelperImpl::EmitEventL( const CGesture& aGesture )
+void CGestureHelperImpl::EmitEvent( const CGesture& aGesture )
     {
     // deallocation of the event is happening in CGestureEventSender::RunL() 
-    CGestureEvent* event = new(ELeave) CGestureEvent();
-    event->iCode = const_cast<CGesture&>(aGesture).Code(MGestureEvent::EAxisBoth);
-    event->iCurrPos = aGesture.CurrentPos();
-    event->iDistance = aGesture.Distance();
-    event->iStartPos = aGesture.StartPos();
-    event->iIsHolding = aGesture.IsHolding();
-    event->iSpeed = aGesture.Speed();
-    event->iVisual = aGesture.Visual();
+    TGestureEvent event;
+    event.SetCode(const_cast<CGesture&>(aGesture).Code(EAxisBoth));
+    event.SetCurrentPos(aGesture.CurrentPos());
+    event.SetDistance(aGesture.Distance());
+    event.SetStartPos(aGesture.StartPos());
+    event.SetIsHolding(aGesture.IsHolding());
+    event.SetSpeed(aGesture.Speed());
     iEventSender->AddEvent(event);
     }