diff -r dd21522fd290 -r 7c90e6132015 webengine/webkitutils/rt_gesturehelper/src/gesturehelperimpl.cpp --- 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 #include #include #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(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(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); }