uifw/AvKon/src/aknlongtapdetector.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
child 14 3320e4e6e8bb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/aknlongtapdetector.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,328 @@
+/*
+* Copyright (c) 2005 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:  Long Tap Detector with animation informing of long tap functionality
+*
+*/
+
+
+#include <e32base.h>
+#include <e32cmn.h>
+#include <w32std.h>
+#include <AknUtils.h>
+#include <AknCapServerClient.h> // RAknUiServer
+#include <AknSgcc.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <aknlongtapanimation.h>
+#include <EIKSRVS.H>
+#include "AknPanic.h"
+#include "aknlongtapdetector.h"
+
+// CONSTANTS
+const TInt KTimeDelayBeforeAnimation = 150000;  // 0,15 seconds
+const TInt KLongTapDelay = 600000;              // 0,6 seconds
+
+// ======== MEMBER FUNCTIONS ========
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::CAknLongTapDetector
+// ---------------------------------------------------------------------------
+//
+CAknLongTapDetector::CAknLongTapDetector( MAknLongTapDetectorCallBack* aOwner )
+    : CTimer( 0 ),
+    iState( EWaiting ),
+    iOwner( aOwner ),
+    iTimeDelayBeforeAnimation( KTimeDelayBeforeAnimation ),
+    iLongTapDelay( KLongTapDelay ),
+    iPointerEvent(),
+    iShowAnimation( ETrue )
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CAknLongTapDetector::ConstructL()
+    {
+    CTimer::ConstructL();
+    CActiveScheduler::Add( this );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAknLongTapDetector* CAknLongTapDetector::NewL( MAknLongTapDetectorCallBack* aOwner )
+    {
+    CAknLongTapDetector* self = CAknLongTapDetector::NewLC( aOwner );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::NewLC
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAknLongTapDetector* CAknLongTapDetector::NewLC( MAknLongTapDetectorCallBack* aOwner )
+    {
+    CAknLongTapDetector* self = new ( ELeave ) CAknLongTapDetector( aOwner );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::~CAknLongTapDetector
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAknLongTapDetector::~CAknLongTapDetector()
+    {
+    Cancel(); // CTimer
+    delete iAnimation;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::PointerEventL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknLongTapDetector::PointerEventL( const TPointerEvent& aEvent )
+    {
+    // offset is now 2 layout units, if the pointer is dragged just a few 
+    // pixels from the original point, long tap is not cancelled. 
+    TInt offset = AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine().iW * 2 / 5;
+    if ( ( iState == EShowingAnimation || iState == EWaitingForAnimation ) 
+            && aEvent.iType == TPointerEvent::EDrag 
+    )
+        {
+        TPoint aCenter = iPointerEvent.iPosition; 
+        TRect rect( aCenter.iX - offset, aCenter.iY - offset, 
+            aCenter.iX + offset, aCenter.iY + offset ); 
+        if ( rect.Contains( aEvent.iPosition ) )
+            {
+            return; 
+            }
+        }
+
+    Cancel();
+
+    iPointerEvent = aEvent;
+    
+    const TWsEvent& lastEvent = CCoeEnv::Static()->LastEvent();
+        
+    CCoeControl* windowControl = 
+        reinterpret_cast<CCoeControl*>( lastEvent.Handle() );
+        
+    if ( windowControl && windowControl->DrawableWindow() && 
+        lastEvent.Type() == EEventPointer )
+        {
+        iPointerEvent.iParentPosition = iPointerEvent.iPosition +
+            windowControl->DrawableWindow()->AbsPosition();
+        }
+
+    if ( iShowAnimation && iState == EWaiting 
+            && aEvent.iType == TPointerEvent::EButton1Down )
+        {
+        iState = EWaitingForAnimation;
+        After( TTimeIntervalMicroSeconds32( iTimeDelayBeforeAnimation ) );
+        }
+    else
+        {
+        iState = EWaiting;
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::SetTimeDelayBeforeAnimation
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknLongTapDetector::SetTimeDelayBeforeAnimation( 
+        const TInt aMicroSeconds )
+    {
+    if ( aMicroSeconds >= 0 )
+        {
+        iTimeDelayBeforeAnimation = aMicroSeconds;
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::SetLongTapDelay
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknLongTapDetector::SetLongTapDelay( const TInt aMicroSeconds )
+    {
+    // update longtap delay time only if it is reasonable
+    if ( ( aMicroSeconds >= 0 ) && 
+            ( aMicroSeconds > iTimeDelayBeforeAnimation ) )
+        {
+        iLongTapDelay = aMicroSeconds;
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::IsAnimationRunning
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknLongTapDetector::IsAnimationRunning() const
+    {
+    return iState == EShowingAnimation;
+    }
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::CancelAnimationL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknLongTapDetector::CancelAnimationL()
+    {
+    Cancel();
+    }
+    
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::EnableLongTapAnimation
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknLongTapDetector::EnableLongTapAnimation( 
+        const TBool aAnimation )
+    {
+    iShowAnimation = aAnimation;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapDetector::RunL
+// ---------------------------------------------------------------------------
+//
+void CAknLongTapDetector::RunL()
+    {
+    switch ( iState )
+        {
+        case EWaitingForAnimation:
+            {
+            iState = EShowingAnimation;
+            StartAnimationL();
+
+            After( TTimeIntervalMicroSeconds32( iLongTapDelay - iTimeDelayBeforeAnimation ) );
+            break;
+            }
+        case EShowingAnimation:
+            {
+            iState = EWaiting;
+            StopAnimation();
+
+            // Report long tap to owner with locations related to both owner rect and screen rect.
+            iOwner->HandleLongTapEventL( iPointerEvent.iPosition, iPointerEvent.iParentPosition );
+            break;
+            }
+        default:
+            {
+            // we should never end up here.
+            User::Panic( _L( "LongTapDetector" ), EAknPanicSelfCheckFailure );
+            break;
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknLongTapDetector::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CAknLongTapDetector::DoCancel()
+    {
+    CTimer::DoCancel();
+    
+    if ( iState == EShowingAnimation )
+        {
+        StopAnimation();
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknLongTapDetector::StartAnimationL
+// -----------------------------------------------------------------------------
+//
+void CAknLongTapDetector::StartAnimationL()
+    {
+    if ( iAnimation )
+        {
+        CCoeEnv::Static()->AddMessageMonitorObserverL( *this );
+        iAnimation->ShowAnimationL( iPointerEvent.iParentPosition.iX, 
+                iPointerEvent.iParentPosition.iY );
+        }
+    else
+        {
+        CCoeEnv::Static()->AddMessageMonitorObserverL( *this );
+        RAknUiServer* uiServer = CAknSgcClient::AknSrv();
+        
+        TInt error = uiServer->ShowLongTapAnimation( iPointerEvent );
+        
+        if ( error == KErrCouldNotConnect )
+            {
+            iAnimation = CAknLongTapAnimation::NewL();
+            iAnimation->ShowAnimationL( iPointerEvent.iParentPosition.iX, 
+                    iPointerEvent.iParentPosition.iY );
+            }
+        else if ( error != KErrNone )
+            {
+            User::Leave( error );
+            }
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknLongTapDetector::StopAnimation
+// -----------------------------------------------------------------------------
+//
+void CAknLongTapDetector::StopAnimation()
+    {
+    if ( iAnimation )
+        {
+        CCoeEnv::Static()->RemoveMessageMonitorObserver( *this );
+        iAnimation->HideAnimation();
+        }
+    else
+        {
+        CCoeEnv::Static()->RemoveMessageMonitorObserver( *this );
+        RAknUiServer* uiServer = CAknSgcClient::AknSrv();
+        uiServer->HideLongTapAnimation();
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknLongTapDetector::MonitorWsMessage
+// -----------------------------------------------------------------------------
+//
+void CAknLongTapDetector::MonitorWsMessage(const TWsEvent& aEvent)
+    {
+    if ( aEvent.Type() == EEventKey || aEvent.Type() == EEventKeyUp 
+            || aEvent.Type() == EEventKeyDown || (aEvent.Type() == EEventPointer
+            && aEvent.Pointer()->iType == TPointerEvent::EButton1Up ) )
+		{
+        Cancel();
+        iState = EWaiting;		
+	    }
+    }
+
+//  End of File