--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/aknlongtapanimation.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,419 @@
+/*
+* Copyright (c) 2006 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: Implementation of long tap animation feature.
+*
+*/
+
+
+#include <AknBitmapAnimation.h>
+#include <AknsConstants.h>
+#include <AknUtils.h>
+#include <apgwgnam.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+
+#include <AknTasHook.h> // for testability hooks
+#include <touchfeedback.h>
+const TInt KStartIntensity = 1;
+const TInt KEndIntensity = 100;
+#include "aknlongtapanimation.h"
+
+enum TInternalFlags
+ {
+ EAnimationStarted = 0x0001,
+ EAnimationHasWindowGroup = 0x0002
+ };
+
+const TInt KConversionFromMillisecondsToMicroseconds = 1000;
+
+/** window group's priority */
+const TInt KAknLongTapWindowPosition = 11; // window group's priority
+
+/** Window`s Position when hiding the animation which does not own Window Group */
+const TInt KAknAnimationNotOwnWindowGroupWindowPosition = -10; // never at front
+
+/** window group's name */
+_LIT( KAknLongTapWgName, "LongTapAnim" ); // window groups name
+
+
+// ============================ EXTENSION CLASS ===============================
+
+NONSHARABLE_CLASS(CAknLongTapAnimationExtension) : public CBase
+ {
+ public:
+ CAknLongTapAnimationExtension();
+ ~CAknLongTapAnimationExtension();
+
+ public: // data
+ TBool iVisible;
+ TInt iIndex;
+ TInt iFlags;
+ CPeriodic* iTimer;
+ };
+
+CAknLongTapAnimationExtension::CAknLongTapAnimationExtension() : iIndex(-1)
+ {
+
+ }
+CAknLongTapAnimationExtension::~CAknLongTapAnimationExtension()
+ {
+
+ }
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Symbian two-phase constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAknLongTapAnimation* CAknLongTapAnimation::NewL()
+ {
+ CAknLongTapAnimation* self = CAknLongTapAnimation::NewLC();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Symbian two-phase constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAknLongTapAnimation* CAknLongTapAnimation::NewLC()
+ {
+ CAknLongTapAnimation* self = new( ELeave ) CAknLongTapAnimation;
+ CleanupStack::PushL( self );
+ self->ConstructL( ETrue );
+ AKNTASHOOK_ADDL( self, "CAknLongTapAnimation" );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CAknLongTapAnimation::NewL()
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CAknLongTapAnimation* CAknLongTapAnimation::NewL( TBool aOwnWindowGroup )
+ {
+ if ( aOwnWindowGroup )
+ {
+ return CAknLongTapAnimation::NewL();
+ }
+ else
+ {
+ CAknLongTapAnimation* self = new( ELeave ) CAknLongTapAnimation;
+ CleanupStack::PushL( self );
+ self->ConstructL( EFalse );
+ CleanupStack::Pop( self );
+ AKNTASHOOK_ADDL( self, "CAknLongTapAnimation" );
+ return self;
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CAknLongTapAnimation::~CAknLongTapAnimation()
+ {
+ AKNTASHOOK_REMOVE();
+ if( iExtension->iFlags & EAnimationHasWindowGroup )
+ {
+ iWindowGroup.Close();
+ }
+ CancelAnimation();
+
+ if (iExtension)
+ {
+ delete iExtension->iTimer;
+ }
+ delete iAnim;
+ delete iExtension;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapAnimation::ShowAnimationL()
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CAknLongTapAnimation::ShowAnimationL( const TInt aX,
+ const TInt aY )
+ {
+ TAknLayoutRect layoutRect;
+ TRect rect;
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EApplicationWindow, rect );
+ layoutRect.LayoutRect( rect, AknLayoutScalable_Avkon::misc_graphics() );
+ layoutRect.LayoutRect( layoutRect.Rect(),
+ AknLayoutScalable_Avkon::misc_graphics() );
+ layoutRect.LayoutRect( layoutRect.Rect(),
+ AknLayoutScalable_Avkon::texts_graphics() );
+ layoutRect.LayoutRect( layoutRect.Rect(),
+ AknLayoutScalable_Avkon::cursor_press_pane() );
+ layoutRect.LayoutRect( layoutRect.Rect(),
+ AknLayoutScalable_Avkon::cursor_press_pane_g1() );
+
+ SetRect( TRect( TPoint(aX, aY), layoutRect.Rect().Size() ));
+
+ // Position window so that it will be directly on top of
+ // the location that was clicked.
+ TPoint point( aX - Rect().Width() / 2, aY - Rect().Height() / 2 );
+ Window().SetPosition( point );
+
+ iAnim->SetSize( layoutRect.Rect().Size() );
+
+ iAnim->SetPosition( Rect().iTl );
+
+ // finally, make window visible
+ if( iExtension->iFlags & EAnimationHasWindowGroup )
+ {
+ iWindowGroup.SetOrdinalPosition( 0, KAknLongTapWindowPosition );
+ }
+ else
+ {
+ //bring this window to front
+ Window().SetOrdinalPosition( 0 );
+ }
+ SetVisibility(ETrue);
+ ActivateL();
+
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ CBitmapAnimClientData* animData = iAnim->BitmapAnimData();
+ TInt interval = animData->FrameIntervalInMilliSeconds()
+ * KConversionFromMillisecondsToMicroseconds;
+ TInt frameCount = animData->FrameArray().Count();
+
+ // timeout should be greater than normal animation time
+ // so that timeout does not interfere into normal operation
+ TInt timeout = interval * (frameCount+1);
+ feedback->StartFeedback( this, ETouchContinuousSmooth, NULL, KStartIntensity, timeout );
+ }
+ StartAnimation();
+ }
+
+
+// ---------------------------------------------------------
+// CAknLongTapAnimation::HideAnimation
+// ---------------------------------------------------------
+//
+EXPORT_C void CAknLongTapAnimation::HideAnimation()
+ {
+ if( iExtension->iFlags & EAnimationHasWindowGroup )
+ {
+ iWindowGroup.SetOrdinalPosition( 0, ECoeWinPriorityNeverAtFront );
+ }
+ else
+ {
+ //bring this window to back
+ Window().SetOrdinalPosition( KAknAnimationNotOwnWindowGroupWindowPosition );
+
+ }
+
+ CancelAnimation();
+ iExtension->iIndex = 0;
+ DrawNow();
+
+ SetVisibility(EFalse);
+ }
+
+
+// ---------------------------------------------------------------------------
+// CAknLongTapAnimation::CAknLongTapAnimation()
+// ---------------------------------------------------------------------------
+//
+CAknLongTapAnimation::CAknLongTapAnimation()
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+// CAknLongTapAnimation::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CAknLongTapAnimation::ConstructL( TBool aOwnWindowGroup )
+ {
+ if (!iExtension)
+ {
+ iExtension = new( ELeave ) CAknLongTapAnimationExtension;
+ }
+
+ if ( aOwnWindowGroup )
+ {
+ //add flag
+ iExtension->iFlags |= EAnimationHasWindowGroup;
+
+ // create a window group for volume popup
+ // needed to prevent apps noticing this window
+ RWsSession& wsSession = iCoeEnv->WsSession();
+ iWindowGroup = RWindowGroup( wsSession );
+ User::LeaveIfError( iWindowGroup.Construct(
+ (TUint32) &iWindowGroup, EFalse ) );
+ iWindowGroup.AutoForeground(EFalse);
+
+ CApaWindowGroupName* name =
+ CApaWindowGroupName::NewLC( wsSession, (TUint32) &iWindowGroup );
+ name->SetHidden( ETrue );
+ name->SetCaptionL( KAknLongTapWgName );
+ User::LeaveIfError( name->SetWindowGroupName( iWindowGroup ));
+ CleanupStack::PopAndDestroy(); //name
+
+ iWindowGroup.SetOrdinalPosition( 0, ECoeWinPriorityNeverAtFront );
+
+ // create control's window to own window group
+ CreateWindowL( &iWindowGroup );
+ Window().SetNonFading(ETrue);
+ }
+ else
+ {
+ //remove flag
+ iExtension->iFlags &= ~EAnimationHasWindowGroup;
+ //create window
+ CreateWindowL();
+ Window().SetOrdinalPosition( KAknAnimationNotOwnWindowGroupWindowPosition );
+ }
+
+ EnableWindowTransparency();
+ Window().SetShadowDisabled(ETrue);
+
+ iExtension->iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
+
+ iAnim = CAknBitmapAnimation::NewL();
+ iAnim->ConstructFromSkinL( KAknsIIDQgnGrafLongPressAnim );
+
+ // set default behaviour
+ SetVisibility(EFalse);
+ }
+
+
+// ---------------------------------------------------------
+// CAknLongTapAnimation::SetVisibility
+// ---------------------------------------------------------
+//
+void CAknLongTapAnimation::SetVisibility(TBool aVisibility)
+ {
+ iExtension->iVisible = aVisibility;
+ MakeVisible( aVisibility );
+ }
+
+
+// ---------------------------------------------------------
+// CAknLongTapAnimation::Draw
+// ---------------------------------------------------------
+//
+void CAknLongTapAnimation::Draw(const TRect& /*aRect*/) const
+ {
+ CWindowGc& gc = SystemGc();
+ gc.Reset();
+
+ if (!iExtension->iVisible || iExtension->iIndex < 0)
+ {
+ return;
+ }
+
+ CBitmapAnimClientData* animData = iAnim->BitmapAnimData();
+
+ CFbsBitmap* bit = animData->FrameArray().At(iExtension->iIndex)->Bitmap();
+ CFbsBitmap* mask = animData->FrameArray().At(iExtension->iIndex)->Mask();
+
+ TPoint pos = animData->FrameArray().At( iExtension->iIndex )->Position();
+
+ if (mask)
+ {
+ gc.BitBltMasked(pos, bit, TRect(TPoint(0,0), bit->SizeInPixels()), mask, ETrue);
+ }
+ else
+ {
+ gc.BitBlt(pos, bit, TRect(TPoint(0,0), bit->SizeInPixels()));
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CAknLongTapAnimation::StartAnimation
+// ---------------------------------------------------------
+//
+void CAknLongTapAnimation::StartAnimation()
+ {
+ iExtension->iIndex = -1;
+ if (!(iExtension->iFlags & EAnimationStarted))
+ {
+ TCallBack callback(AnimationCallback, this);
+
+ TInt interval = iAnim->BitmapAnimData()->FrameIntervalInMilliSeconds() *
+ KConversionFromMillisecondsToMicroseconds;
+
+ iExtension->iTimer->Start(0, interval, callback);
+ iExtension->iFlags |= EAnimationStarted;
+ }
+ }
+
+// ---------------------------------------------------------
+// CAknLongTapAnimation::CancelAnimation
+// ---------------------------------------------------------
+//
+void CAknLongTapAnimation::CancelAnimation()
+ {
+ if (iExtension->iFlags & EAnimationStarted)
+ {
+ iExtension->iTimer->Cancel();
+ iExtension->iFlags &= ~EAnimationStarted;
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ feedback->StopFeedback( this );
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CAknLongTapAnimation::NextFrame
+// ---------------------------------------------------------
+//
+void CAknLongTapAnimation::NextFrame()
+ {
+ CBitmapAnimClientData* animData = iAnim->BitmapAnimData();
+ TInt frameCount = animData->FrameArray().Count();
+
+ iExtension->iIndex++;
+ if (iExtension->iIndex == frameCount)
+ {
+ iExtension->iIndex = frameCount - 1;
+ }
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ // intensity should go from 0 to 100
+ TInt intensity = KEndIntensity
+ * (iExtension->iIndex+1) / frameCount;
+ feedback->ModifyFeedback( this, intensity );
+ }
+ DrawNow();
+ }
+
+
+// ---------------------------------------------------------
+// CAknLongTapAnimation::AnimationCallback
+// ---------------------------------------------------------
+//
+TInt CAknLongTapAnimation::AnimationCallback(TAny* aPtr)
+ {
+ CAknLongTapAnimation* ptr = (CAknLongTapAnimation*)aPtr;
+ ptr->NextFrame();
+ return KErrNone;
+ }
+
+// End of File