uifw/AvKon/src/aknlongtapanimation.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of long tap animation feature.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <AknBitmapAnimation.h>
       
    20 #include <AknsConstants.h>
       
    21 #include <AknUtils.h>
       
    22 #include <apgwgnam.h>
       
    23 #include <aknlayoutscalable_avkon.cdl.h>
       
    24 
       
    25 #include <AknTasHook.h> // for testability hooks
       
    26 #include <touchfeedback.h>
       
    27 const TInt KStartIntensity = 1;
       
    28 const TInt KEndIntensity = 100;
       
    29 #include "aknlongtapanimation.h"
       
    30 
       
    31 enum TInternalFlags
       
    32 	{
       
    33 	EAnimationStarted			     =	0x0001,
       
    34 	EAnimationHasWindowGroup         =  0x0002
       
    35  	};
       
    36 
       
    37 const TInt KConversionFromMillisecondsToMicroseconds = 1000;
       
    38 
       
    39 /**  window group's priority */
       
    40 const TInt KAknLongTapWindowPosition = 11; // window group's priority
       
    41 
       
    42 /** Window`s Position when hiding the animation which  does not own Window Group */
       
    43 const TInt KAknAnimationNotOwnWindowGroupWindowPosition = -10; // never at front  
       
    44 
       
    45 /**  window group's name */
       
    46 _LIT( KAknLongTapWgName, "LongTapAnim" ); // window groups name
       
    47 
       
    48 
       
    49 // ============================ EXTENSION CLASS ===============================
       
    50 
       
    51 NONSHARABLE_CLASS(CAknLongTapAnimationExtension) : public CBase
       
    52     {
       
    53     public:
       
    54         CAknLongTapAnimationExtension();
       
    55         ~CAknLongTapAnimationExtension();
       
    56 
       
    57     public: // data 
       
    58         TBool iVisible;
       
    59         TInt iIndex;
       
    60         TInt iFlags;
       
    61 		CPeriodic* iTimer;
       
    62     };
       
    63 
       
    64 CAknLongTapAnimationExtension::CAknLongTapAnimationExtension() : iIndex(-1)
       
    65     {
       
    66     
       
    67     }
       
    68 CAknLongTapAnimationExtension::~CAknLongTapAnimationExtension()
       
    69     {
       
    70     
       
    71     }
       
    72 
       
    73 
       
    74 // ======== MEMBER FUNCTIONS ========
       
    75 
       
    76 // ---------------------------------------------------------------------------
       
    77 // Symbian two-phase constructor.
       
    78 // ---------------------------------------------------------------------------
       
    79 //
       
    80 EXPORT_C CAknLongTapAnimation* CAknLongTapAnimation::NewL()
       
    81     {
       
    82     CAknLongTapAnimation* self = CAknLongTapAnimation::NewLC();
       
    83     CleanupStack::Pop( self );
       
    84     return self;
       
    85     }
       
    86 
       
    87 
       
    88 // ---------------------------------------------------------------------------
       
    89 // Symbian two-phase constructor.
       
    90 // ---------------------------------------------------------------------------
       
    91 //
       
    92 EXPORT_C CAknLongTapAnimation* CAknLongTapAnimation::NewLC()
       
    93     {
       
    94     CAknLongTapAnimation* self = new( ELeave ) CAknLongTapAnimation;
       
    95     CleanupStack::PushL( self );
       
    96     self->ConstructL( ETrue );
       
    97     AKNTASHOOK_ADDL( self, "CAknLongTapAnimation" );
       
    98     return self;
       
    99     }
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // CAknLongTapAnimation::NewL()
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 EXPORT_C CAknLongTapAnimation* CAknLongTapAnimation::NewL( TBool aOwnWindowGroup )
       
   106     {
       
   107     if ( aOwnWindowGroup )
       
   108         {
       
   109         return CAknLongTapAnimation::NewL();
       
   110         }
       
   111     else
       
   112         {
       
   113         CAknLongTapAnimation* self = new( ELeave ) CAknLongTapAnimation;
       
   114         CleanupStack::PushL( self );
       
   115         self->ConstructL( EFalse );
       
   116         CleanupStack::Pop( self );
       
   117         AKNTASHOOK_ADDL( self, "CAknLongTapAnimation" );
       
   118         return self;    
       
   119         }    
       
   120     }
       
   121 
       
   122 
       
   123 // ---------------------------------------------------------------------------
       
   124 // Destructor.
       
   125 // ---------------------------------------------------------------------------
       
   126 //
       
   127 CAknLongTapAnimation::~CAknLongTapAnimation()
       
   128     {
       
   129     AKNTASHOOK_REMOVE();
       
   130     if( iExtension->iFlags & EAnimationHasWindowGroup )
       
   131         {
       
   132         iWindowGroup.Close();    
       
   133         }
       
   134 	CancelAnimation();
       
   135 	
       
   136     if (iExtension)
       
   137         {
       
   138 	    delete iExtension->iTimer;
       
   139         }
       
   140     delete iAnim;
       
   141     delete iExtension;
       
   142     }
       
   143     
       
   144 
       
   145 // ---------------------------------------------------------------------------
       
   146 // CAknLongTapAnimation::ShowAnimationL()
       
   147 // ---------------------------------------------------------------------------
       
   148 //
       
   149 EXPORT_C void CAknLongTapAnimation::ShowAnimationL( const TInt aX, 
       
   150                                                     const TInt aY )
       
   151     {
       
   152     TAknLayoutRect layoutRect;
       
   153     TRect rect;
       
   154     AknLayoutUtils::LayoutMetricsRect( 
       
   155             AknLayoutUtils::EApplicationWindow, rect );
       
   156     layoutRect.LayoutRect( rect, AknLayoutScalable_Avkon::misc_graphics() );
       
   157     layoutRect.LayoutRect( layoutRect.Rect(), 
       
   158         AknLayoutScalable_Avkon::misc_graphics() );
       
   159     layoutRect.LayoutRect( layoutRect.Rect(),
       
   160         AknLayoutScalable_Avkon::texts_graphics() );
       
   161     layoutRect.LayoutRect( layoutRect.Rect(),
       
   162         AknLayoutScalable_Avkon::cursor_press_pane() );
       
   163     layoutRect.LayoutRect( layoutRect.Rect(),
       
   164         AknLayoutScalable_Avkon::cursor_press_pane_g1() );
       
   165     
       
   166     SetRect( TRect( TPoint(aX, aY), layoutRect.Rect().Size() ));
       
   167     
       
   168     // Position window so that it will be directly on top of
       
   169     // the location that was clicked.
       
   170     TPoint point( aX - Rect().Width() / 2, aY - Rect().Height() / 2 );
       
   171     Window().SetPosition( point );
       
   172 
       
   173     iAnim->SetSize( layoutRect.Rect().Size() );
       
   174     
       
   175     iAnim->SetPosition( Rect().iTl );
       
   176     
       
   177     // finally, make window visible
       
   178     if( iExtension->iFlags & EAnimationHasWindowGroup )
       
   179         {
       
   180         iWindowGroup.SetOrdinalPosition( 0, KAknLongTapWindowPosition );
       
   181         }
       
   182     else
       
   183         {
       
   184         //bring this window to front
       
   185         Window().SetOrdinalPosition( 0 );
       
   186         }    
       
   187     SetVisibility(ETrue);
       
   188     ActivateL();
       
   189 
       
   190     MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   191     if ( feedback )
       
   192         {
       
   193         CBitmapAnimClientData* animData = iAnim->BitmapAnimData();	
       
   194 		TInt interval = animData->FrameIntervalInMilliSeconds()
       
   195 		             * KConversionFromMillisecondsToMicroseconds;
       
   196         TInt frameCount = animData->FrameArray().Count();
       
   197 
       
   198         // timeout should be greater than normal animation time 
       
   199         // so that timeout does not interfere into normal operation
       
   200         TInt timeout = interval * (frameCount+1); 
       
   201         feedback->StartFeedback( this, ETouchContinuousSmooth, NULL, KStartIntensity, timeout );
       
   202         }
       
   203 	StartAnimation();
       
   204     }
       
   205 
       
   206 
       
   207 // ---------------------------------------------------------
       
   208 // CAknLongTapAnimation::HideAnimation
       
   209 // ---------------------------------------------------------
       
   210 //
       
   211 EXPORT_C void CAknLongTapAnimation::HideAnimation()
       
   212     {
       
   213     if( iExtension->iFlags & EAnimationHasWindowGroup )
       
   214         {
       
   215         iWindowGroup.SetOrdinalPosition( 0, ECoeWinPriorityNeverAtFront );
       
   216         }
       
   217     else
       
   218         {
       
   219         //bring this window to back
       
   220         Window().SetOrdinalPosition( KAknAnimationNotOwnWindowGroupWindowPosition );
       
   221             
       
   222         }    
       
   223 
       
   224 	CancelAnimation();
       
   225     iExtension->iIndex = 0;
       
   226     DrawNow();
       
   227 		
       
   228     SetVisibility(EFalse);
       
   229     }
       
   230 
       
   231 
       
   232 // ---------------------------------------------------------------------------
       
   233 // CAknLongTapAnimation::CAknLongTapAnimation()
       
   234 // ---------------------------------------------------------------------------
       
   235 //
       
   236 CAknLongTapAnimation::CAknLongTapAnimation()
       
   237     {
       
   238     }
       
   239 
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // CAknLongTapAnimation::ConstructL
       
   243 // Symbian 2nd phase constructor can leave.
       
   244 // -----------------------------------------------------------------------------
       
   245 //
       
   246 void CAknLongTapAnimation::ConstructL( TBool aOwnWindowGroup )
       
   247     {
       
   248 	if (!iExtension)
       
   249         {
       
   250         iExtension = new( ELeave ) CAknLongTapAnimationExtension;
       
   251         }
       
   252 
       
   253     if ( aOwnWindowGroup )
       
   254         {
       
   255         //add flag
       
   256         iExtension->iFlags |= EAnimationHasWindowGroup; 
       
   257         
       
   258         // create a window group for volume popup
       
   259         // needed to prevent apps noticing this window
       
   260         RWsSession& wsSession = iCoeEnv->WsSession();
       
   261         iWindowGroup = RWindowGroup( wsSession );
       
   262         User::LeaveIfError( iWindowGroup.Construct( 
       
   263                                     (TUint32) &iWindowGroup, EFalse ) );
       
   264         iWindowGroup.AutoForeground(EFalse);
       
   265 
       
   266         CApaWindowGroupName* name = 
       
   267                 CApaWindowGroupName::NewLC( wsSession, (TUint32) &iWindowGroup );
       
   268         name->SetHidden( ETrue );
       
   269         name->SetCaptionL( KAknLongTapWgName );
       
   270         User::LeaveIfError( name->SetWindowGroupName( iWindowGroup ));
       
   271         CleanupStack::PopAndDestroy();  //name
       
   272 
       
   273         iWindowGroup.SetOrdinalPosition( 0, ECoeWinPriorityNeverAtFront );
       
   274         
       
   275         // create control's window to own window group
       
   276         CreateWindowL( &iWindowGroup );    
       
   277         Window().SetNonFading(ETrue);
       
   278         }
       
   279     else
       
   280         {
       
   281         //remove flag
       
   282         iExtension->iFlags &= ~EAnimationHasWindowGroup; 
       
   283         //create window
       
   284         CreateWindowL();
       
   285         Window().SetOrdinalPosition( KAknAnimationNotOwnWindowGroupWindowPosition );
       
   286         }    
       
   287 
       
   288     EnableWindowTransparency();
       
   289     Window().SetShadowDisabled(ETrue);
       
   290 
       
   291     iExtension->iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
       
   292    
       
   293     iAnim = CAknBitmapAnimation::NewL();
       
   294     iAnim->ConstructFromSkinL( KAknsIIDQgnGrafLongPressAnim );
       
   295 
       
   296     // set default behaviour
       
   297     SetVisibility(EFalse);
       
   298     }
       
   299   
       
   300 
       
   301 // ---------------------------------------------------------
       
   302 // CAknLongTapAnimation::SetVisibility
       
   303 // ---------------------------------------------------------
       
   304 //
       
   305 void CAknLongTapAnimation::SetVisibility(TBool aVisibility)
       
   306     {
       
   307     iExtension->iVisible = aVisibility;
       
   308     MakeVisible( aVisibility );
       
   309     }
       
   310 
       
   311 
       
   312 // ---------------------------------------------------------
       
   313 // CAknLongTapAnimation::Draw
       
   314 // ---------------------------------------------------------
       
   315 //
       
   316 void CAknLongTapAnimation::Draw(const TRect& /*aRect*/) const
       
   317  	{	
       
   318   	CWindowGc& gc = SystemGc();
       
   319     gc.Reset();	
       
   320     
       
   321  	if (!iExtension->iVisible || iExtension->iIndex < 0)
       
   322  		{
       
   323  		return;
       
   324  		}
       
   325  
       
   326     CBitmapAnimClientData* animData = iAnim->BitmapAnimData();	
       
   327     		
       
   328     CFbsBitmap* bit  = animData->FrameArray().At(iExtension->iIndex)->Bitmap();
       
   329     CFbsBitmap* mask = animData->FrameArray().At(iExtension->iIndex)->Mask();
       
   330 
       
   331 	TPoint pos = animData->FrameArray().At( iExtension->iIndex )->Position();
       
   332     
       
   333     if (mask)
       
   334     	{
       
   335     	gc.BitBltMasked(pos, bit, TRect(TPoint(0,0), bit->SizeInPixels()), mask, ETrue);
       
   336     	}
       
   337     else
       
   338     	{
       
   339     	gc.BitBlt(pos, bit, TRect(TPoint(0,0), bit->SizeInPixels()));
       
   340     	}
       
   341  	}
       
   342 
       
   343 
       
   344 // ---------------------------------------------------------
       
   345 // CAknLongTapAnimation::StartAnimation
       
   346 // ---------------------------------------------------------
       
   347 //
       
   348 void CAknLongTapAnimation::StartAnimation()
       
   349 	{
       
   350 	iExtension->iIndex = -1;
       
   351  	if (!(iExtension->iFlags & EAnimationStarted))
       
   352 		{
       
   353 		TCallBack callback(AnimationCallback, this);
       
   354 		
       
   355 		TInt interval = iAnim->BitmapAnimData()->FrameIntervalInMilliSeconds() *
       
   356 			KConversionFromMillisecondsToMicroseconds;
       
   357 		
       
   358 		iExtension->iTimer->Start(0, interval, callback);
       
   359 		iExtension->iFlags |= EAnimationStarted;
       
   360 		}		
       
   361 	}
       
   362 
       
   363 // ---------------------------------------------------------
       
   364 // CAknLongTapAnimation::CancelAnimation
       
   365 // ---------------------------------------------------------
       
   366 //
       
   367 void CAknLongTapAnimation::CancelAnimation()
       
   368 	{
       
   369     if (iExtension->iFlags & EAnimationStarted)
       
   370 		{
       
   371 		iExtension->iTimer->Cancel();
       
   372 		iExtension->iFlags &= ~EAnimationStarted;
       
   373         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   374         if ( feedback )
       
   375             {
       
   376             feedback->StopFeedback( this );
       
   377             }
       
   378 		}
       
   379 	}
       
   380 
       
   381 
       
   382 // ---------------------------------------------------------
       
   383 // CAknLongTapAnimation::NextFrame
       
   384 // ---------------------------------------------------------
       
   385 //
       
   386 void CAknLongTapAnimation::NextFrame()
       
   387 	{
       
   388 	CBitmapAnimClientData* animData = iAnim->BitmapAnimData();	
       
   389     TInt frameCount = animData->FrameArray().Count();
       
   390 		
       
   391 	iExtension->iIndex++;
       
   392 	if (iExtension->iIndex == frameCount)
       
   393 	{
       
   394 		iExtension->iIndex = frameCount - 1;
       
   395 	}
       
   396     MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   397     if ( feedback )
       
   398         {
       
   399         // intensity should go from 0 to 100
       
   400         TInt intensity = KEndIntensity
       
   401                        * (iExtension->iIndex+1) / frameCount;
       
   402         feedback->ModifyFeedback( this, intensity );
       
   403         }
       
   404 	DrawNow();
       
   405 	}
       
   406 
       
   407 
       
   408 // ---------------------------------------------------------
       
   409 // CAknLongTapAnimation::AnimationCallback
       
   410 // ---------------------------------------------------------
       
   411 //
       
   412 TInt CAknLongTapAnimation::AnimationCallback(TAny* aPtr)
       
   413 	{
       
   414 	CAknLongTapAnimation* ptr = (CAknLongTapAnimation*)aPtr;
       
   415 	ptr->NextFrame();
       
   416 	return KErrNone;
       
   417 	}
       
   418 	
       
   419 //  End of File