taskswitcher/taskswitcherui/taskswitcherapp/src/tsfastswapareautils.cpp
branchRCL_3
changeset 35 3321d3e205b6
equal deleted inserted replaced
34:5456b4e8b3a8 35:3321d3e205b6
       
     1 /*
       
     2 * Copyright (c) 2008 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:  Taskswitcher Fast Swap area UI
       
    15  *
       
    16 */
       
    17 
       
    18 #include <w32std.h>
       
    19 #include <eikenv.h>
       
    20 #include <layoutmetadata.cdl.h>
       
    21 #include <touchfeedback.h>
       
    22 #include <akntransitionutils.h>
       
    23 #include <akntranseffect.h>
       
    24 #include <aknlayoutscalable_apps.cdl.h>
       
    25 #include <bitmaptransforms.h>
       
    26 
       
    27 
       
    28 #include "tsfastswapareautils.h"
       
    29 #include "tsfastswaparea.h"
       
    30 #include "tsappui.h"
       
    31 #include "tsfswentry.h"
       
    32 
       
    33 
       
    34 const TInt KLayoutItemCount = 4;
       
    35 
       
    36  /* ================================================================================
       
    37   * CTsFastSwapTimer
       
    38   * ================================================================================
       
    39   */
       
    40 
       
    41 // -----------------------------------------------------------------------------
       
    42 // CTsFastSwapTimer::CTsFastSwapTimer
       
    43 // -----------------------------------------------------------------------------
       
    44 //
       
    45 CTsFastSwapTimer::CTsFastSwapTimer( MTsFastSwapTimerObserver& aObserver )
       
    46 : CTimer( EPriorityStandard ),
       
    47   iObserver( &aObserver )
       
    48     {
       
    49     }
       
    50 
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // CTsFastSwapTimer::CTsGridHighlightTimer
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 CTsFastSwapTimer::~CTsFastSwapTimer()
       
    57     {
       
    58     Cancel();
       
    59     }
       
    60 
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CTsFastSwapTimer::ConstructL
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 void CTsFastSwapTimer::ConstructL()
       
    67     {
       
    68     CTimer::ConstructL();
       
    69     CActiveScheduler::Add( this );
       
    70     }
       
    71 
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CTsFastSwapTimer::CTsGridHighlightTimer
       
    75 // -----------------------------------------------------------------------------
       
    76 //
       
    77 void CTsFastSwapTimer::RunL()
       
    78     {
       
    79     iObserver->TimerCompletedL(this);
       
    80     }
       
    81  
       
    82 
       
    83 
       
    84 /* ================================================================================
       
    85  * CTsBitmapScaleTask
       
    86  * ================================================================================
       
    87  */
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // CTsBitmapScaleTask::
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 CTsBitmapScaleTask::CTsBitmapScaleTask( CTsFastSwapAreaExtension& aObserver )
       
    94 : CActive(EPriorityStandard),
       
    95   iObserver( aObserver )
       
    96     {
       
    97     CActiveScheduler::Add( this );
       
    98     }
       
    99 
       
   100 
       
   101 // -----------------------------------------------------------------------------
       
   102 // CTsBitmapScaleTask::
       
   103 // -----------------------------------------------------------------------------
       
   104 //
       
   105 CTsBitmapScaleTask::~CTsBitmapScaleTask()
       
   106     {
       
   107     Cancel();
       
   108     delete iScaler;
       
   109     delete iSourceBmp;
       
   110     }
       
   111 
       
   112 
       
   113 // -----------------------------------------------------------------------------
       
   114 // CTsBitmapScaleTask::
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 void CTsBitmapScaleTask::StartLD( CFbsBitmap* aSourceBitmap,
       
   118                                   CFbsBitmap* aTargetBitmap )
       
   119     {
       
   120     if ( !iScaler )
       
   121         {
       
   122         iSourceBmp = aSourceBitmap;
       
   123         iScaler = CBitmapScaler::NewL();
       
   124         iScaler->Scale( &iStatus, *aSourceBitmap, *aTargetBitmap );
       
   125         SetActive();
       
   126         }
       
   127     }
       
   128 
       
   129 
       
   130 // -----------------------------------------------------------------------------
       
   131 // CTsBitmapScaleTask::
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 void CTsBitmapScaleTask::RunL()
       
   135     {
       
   136     iObserver.ScaleFinished( this );
       
   137     delete this;
       
   138     }
       
   139 
       
   140 
       
   141 // -----------------------------------------------------------------------------
       
   142 // CTsBitmapScaleTask::
       
   143 // -----------------------------------------------------------------------------
       
   144 //
       
   145 void CTsBitmapScaleTask::DoCancel()
       
   146     {
       
   147     iScaler->Cancel();
       
   148     }
       
   149 
       
   150 
       
   151 /* ================================================================================
       
   152  * CTsFastSwapAreaExtension
       
   153  * ================================================================================
       
   154  */
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // CTsFastSwapAreaExtension::NewL
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 CTsFastSwapAreaExtension* CTsFastSwapAreaExtension::NewL( CTsFastSwapArea& aFastSwapArea,
       
   161                                                   CEikonEnv& aEnv )
       
   162     {
       
   163     CTsFastSwapAreaExtension* self = CTsFastSwapAreaExtension::NewLC(
       
   164             aFastSwapArea, aEnv );
       
   165     CleanupStack::Pop( self );
       
   166     return self;
       
   167     }
       
   168 
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // CTsFastSwapAreaExtension::NewLC
       
   172 // -----------------------------------------------------------------------------
       
   173 //
       
   174 CTsFastSwapAreaExtension* CTsFastSwapAreaExtension::NewLC( CTsFastSwapArea& aFastSwapArea,
       
   175                                                    CEikonEnv& aEnv )
       
   176     {
       
   177     CTsFastSwapAreaExtension* self = new (ELeave) CTsFastSwapAreaExtension(
       
   178             aFastSwapArea, aEnv );
       
   179     CleanupStack::PushL( self );
       
   180     self->ConstructL();
       
   181     return self;
       
   182     }
       
   183 
       
   184 
       
   185 // -----------------------------------------------------------------------------
       
   186 // CTsFastSwapAreaExtension::~CTsFastSwapAreaExtension
       
   187 // -----------------------------------------------------------------------------
       
   188 //
       
   189 CTsFastSwapAreaExtension::~CTsFastSwapAreaExtension()
       
   190     {
       
   191     iScaleTasks.ResetAndDestroy();
       
   192     }
       
   193 
       
   194 
       
   195 // -----------------------------------------------------------------------------
       
   196 // CTsFastSwapAreaExtension::ConstructL
       
   197 // -----------------------------------------------------------------------------
       
   198 //
       
   199 void CTsFastSwapAreaExtension::ConstructL()
       
   200     {
       
   201     }
       
   202 
       
   203 
       
   204 // -----------------------------------------------------------------------------
       
   205 // CTsFastSwapAreaExtension::CTsFastSwapAreaExtension
       
   206 // -----------------------------------------------------------------------------
       
   207 //
       
   208 CTsFastSwapAreaExtension::CTsFastSwapAreaExtension( CTsFastSwapArea& aFastSwapArea,
       
   209                                             CEikonEnv& aEnv )
       
   210 : iFastSwapArea( aFastSwapArea ),
       
   211   iEnv( aEnv )
       
   212     {
       
   213     }
       
   214 
       
   215 // -----------------------------------------------------------------------------
       
   216 // CTsFastSwapAreaExtension::GetCurrentScreenOrientation
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 TInt CTsFastSwapAreaExtension::GetCurrentScreenOrientation()
       
   220     {
       
   221     TPixelsAndRotation availableRect;
       
   222     iEnv.ScreenDevice()->GetDefaultScreenSizeAndRotation(availableRect);
       
   223     return availableRect.iPixelSize.iWidth > availableRect.iPixelSize.iHeight;
       
   224     }
       
   225 
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // CTsFastSwapAreaExtension::GetVariety
       
   229 // -----------------------------------------------------------------------------
       
   230 //
       
   231 TBool CTsFastSwapAreaExtension::GetVariety( TInt& aVariety )
       
   232     {
       
   233     aVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
       
   234     TBool foreground = static_cast<CTsAppUi*>(iEnv.AppUi())->IsForeground();
       
   235     if ( foreground )
       
   236         {
       
   237         TInt screenOrientation = GetCurrentScreenOrientation();
       
   238         if ( aVariety != screenOrientation )
       
   239             {
       
   240             aVariety = screenOrientation;
       
   241             return ETrue;
       
   242             }
       
   243         }
       
   244     return EFalse;
       
   245     }
       
   246 
       
   247 
       
   248 // --------------------------------------------------------------------------
       
   249 // CTsFastSwapAreaExtension::GetFastSwapAreaRects
       
   250 // --------------------------------------------------------------------------
       
   251 //
       
   252 void CTsFastSwapAreaExtension::GetFastSwapAreaRects( RArray<TAknLayoutRect>& aRects )
       
   253     {
       
   254     TAknLayoutRect gridAppPane;
       
   255     TAknLayoutRect gridItem;
       
   256     TAknLayoutRect gridImage;
       
   257     TInt variety;
       
   258     TBool disable = GetVariety(variety);
       
   259     if ( disable )
       
   260         {
       
   261         TRAP_IGNORE(static_cast<CTsAppUi*>(iEnv.AppUi())->RequestPopUpL());
       
   262         }
       
   263     variety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0; // double check to avoid layout panic
       
   264     gridAppPane.LayoutRect( iFastSwapArea.Rect(), 
       
   265             AknLayoutScalable_Apps::tport_appsw_pane_g1( variety ) );
       
   266     aRects.Append(gridAppPane);
       
   267     
       
   268     gridItem.LayoutRect( gridAppPane.Rect(),
       
   269             AknLayoutScalable_Apps::cell_tport_appsw_pane( variety, 0, 0 ) );
       
   270     aRects.Append(gridItem);
       
   271     
       
   272     gridImage.LayoutRect( gridItem.Rect(),
       
   273             AknLayoutScalable_Apps::cell_tport_appsw_pane_g1( variety ) ); 
       
   274     aRects.Append(gridImage);
       
   275     
       
   276     if ( disable )
       
   277         {
       
   278         TRAP_IGNORE(static_cast<CTsAppUi*>(iEnv.AppUi())->DisablePopUpL());
       
   279         }
       
   280     }
       
   281 
       
   282 
       
   283 // -----------------------------------------------------------------------------
       
   284 // CTsFastSwapAreaExtension::ItemPosition
       
   285 // -----------------------------------------------------------------------------
       
   286 //
       
   287 TPoint CTsFastSwapAreaExtension::ItemViewPosition( TInt aItemIdx )
       
   288     {
       
   289     TPoint retVal = iFastSwapArea.Rect().iTl;
       
   290     TInt maxItemsOnScreen = iFastSwapArea.GetGridItemData( CTsFastSwapArea::EMaxItemsOnScreen );
       
   291     TInt gridItemWidth = iFastSwapArea.GetGridItemData( CTsFastSwapArea::EGridItemWidth );
       
   292     TInt gridItemGap = iFastSwapArea.GetGridItemData( CTsFastSwapArea::EGridItemGap );
       
   293     
       
   294     if ( aItemIdx < 0 )
       
   295         {
       
   296         // No items
       
   297         retVal.iX = 0;
       
   298         }
       
   299     else if ( aItemIdx == 0 )
       
   300         {
       
   301         // First item
       
   302         if( AknLayoutUtils::LayoutMirrored() )
       
   303             {
       
   304             if ( iFastSwapArea.GridItemCount() > maxItemsOnScreen )
       
   305                 {
       
   306                 retVal.iX = iFastSwapArea.GridWorldSize().iWidth - iFastSwapArea.Rect().Width();
       
   307                 }
       
   308             else
       
   309                 {
       
   310                 retVal.iX = 0;
       
   311                 }
       
   312             }
       
   313         else // normal layout
       
   314             {
       
   315             retVal.iX = 0;
       
   316             }
       
   317         }
       
   318     else if ( aItemIdx == iFastSwapArea.GridItemCount() - 1 )
       
   319         {
       
   320         // Last item selected
       
   321         if( AknLayoutUtils::LayoutMirrored() )
       
   322             {
       
   323             retVal.iX = 0;
       
   324             }
       
   325         else // normal layout
       
   326             {
       
   327             if ( iFastSwapArea.GridItemCount() > maxItemsOnScreen )
       
   328                 {
       
   329                 retVal.iX = iFastSwapArea.GridWorldSize().iWidth - iFastSwapArea.Rect().Width();
       
   330                 }
       
   331             else
       
   332                 {
       
   333                 retVal.iX = 0;
       
   334                 }
       
   335             }
       
   336         }
       
   337     else
       
   338         {
       
   339         // Middle item
       
   340         TInt screenMiddleItemOffset = ( iFastSwapArea.Rect().Width() - gridItemWidth ) / 2;
       
   341         if( AknLayoutUtils::LayoutMirrored() )
       
   342             {
       
   343             retVal.iX = gridItemWidth * ( iFastSwapArea.GridItemCount() - 1 - aItemIdx ) - screenMiddleItemOffset;
       
   344             retVal.iX += ( iFastSwapArea.GridItemCount() - 1 - aItemIdx ) * gridItemGap;
       
   345             }
       
   346         else // normal layout
       
   347             {
       
   348             retVal.iX = gridItemWidth * aItemIdx - screenMiddleItemOffset;
       
   349             retVal.iX += gridItemGap * aItemIdx;
       
   350             }
       
   351         if ( retVal.iX < 0 )
       
   352             {
       
   353             retVal.iX = 0;
       
   354             }
       
   355         // aligin to grid end edge in case
       
   356         // (item's position + draw area) extends over grid area and
       
   357         // (all items cover more than grid area or penultimate item)
       
   358         else if ( retVal.iX + iFastSwapArea.Rect().Width() > iFastSwapArea.GridWorldSize().iWidth &&
       
   359               (iFastSwapArea.GridWorldSize().iWidth > gridItemWidth * iFastSwapArea.GridItemCount() ||
       
   360                (aItemIdx > 1 &&   aItemIdx == iFastSwapArea.GridItemCount() - 2 )) )
       
   361             {
       
   362             retVal.iX = iFastSwapArea.GridWorldSize().iWidth - iFastSwapArea.Rect().Width();
       
   363             }
       
   364         }
       
   365     
       
   366     // Return middle of the view rectangle
       
   367     retVal.iX += iFastSwapArea.Rect().Width() / 2;
       
   368     
       
   369     return retVal;
       
   370     }
       
   371 
       
   372 
       
   373 // -----------------------------------------------------------------------------
       
   374 // CTsFastSwapAreaExtension::ViewToVisibleItem
       
   375 // -----------------------------------------------------------------------------
       
   376 //
       
   377 TInt CTsFastSwapAreaExtension::ViewToVisibleItem( const TPoint aViewPos )
       
   378     {
       
   379     TInt retVal(0);
       
   380     TPoint absViewPos = aViewPos;
       
   381     absViewPos.iX -= iFastSwapArea.Rect().Width() / 2;
       
   382     if ( absViewPos.iX < 0 )
       
   383         {
       
   384         if ( AknLayoutUtils::LayoutMirrored() )
       
   385             {
       
   386             // View crossed left border of grid world rect, last item selected
       
   387             retVal = iFastSwapArea.GridItemCount() - 1;
       
   388             }
       
   389         else // normal layout
       
   390             {
       
   391             // View crossed left border of grid world rect, first item selected
       
   392             retVal = 0;
       
   393             }
       
   394         }
       
   395     else if ( absViewPos.iX + iFastSwapArea.Rect().Width() > iFastSwapArea.GridWorldSize().iWidth )
       
   396         {
       
   397         if ( AknLayoutUtils::LayoutMirrored() )
       
   398             {
       
   399             // View crossed right border of grid world rect, first item selected
       
   400             retVal = 0;
       
   401             }
       
   402         else // normal layout
       
   403             {
       
   404             // View crossed right border of grid world rect, last item selected
       
   405             retVal = iFastSwapArea.GridItemCount() - 1;
       
   406             }
       
   407         }
       
   408     else
       
   409         {
       
   410         TInt retItemPosX(0);
       
   411         TInt offsetCheck = iFastSwapArea.GridWorldSize().iWidth;
       
   412         // View inside of grid world rect
       
   413         for ( TInt i = 0 ; i < iFastSwapArea.GridItemCount(); i++ )
       
   414             {
       
   415             TInt itemPosX = ItemViewPosition( i ).iX;
       
   416             TInt offset = aViewPos.iX - itemPosX;
       
   417             if ( Abs( offset ) <= offsetCheck )
       
   418                 {
       
   419                 offsetCheck = Abs( offset );
       
   420                 retVal = i;
       
   421                 retItemPosX = itemPosX;
       
   422                 }
       
   423             else
       
   424                 {
       
   425                 break;
       
   426                 }
       
   427             }
       
   428         // Check if item is fully visible. If not
       
   429         // return next one if possible
       
   430         TInt gridItemWidth = iFastSwapArea.GetGridItemData( CTsFastSwapArea::EGridItemWidth );
       
   431         if ( retItemPosX - gridItemWidth / 2 < absViewPos.iX &&
       
   432              retVal + 1 < iFastSwapArea.GridItemCount() )
       
   433             {
       
   434             retVal++;
       
   435             }
       
   436         }
       
   437     
       
   438     return retVal;
       
   439     }
       
   440 
       
   441 
       
   442 // -----------------------------------------------------------------------------
       
   443 // CTsFastSwapAreaExtension::LaunchPopupFeedback
       
   444 // -----------------------------------------------------------------------------
       
   445 //
       
   446 void CTsFastSwapAreaExtension::LaunchPopupFeedback()
       
   447     {
       
   448     if ( AknLayoutUtils::PenEnabled() )
       
   449         {
       
   450         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   451         if ( feedback )
       
   452             {
       
   453             TTouchLogicalFeedback fbLogicalType = ETouchFeedbackPopUp;
       
   454             if ( CAknTransitionUtils::TransitionsEnabled(
       
   455                  AknTransEffect::EComponentTransitionsOff ) )
       
   456                 {
       
   457                 fbLogicalType = ETouchFeedbackIncreasingPopUp;
       
   458                 }
       
   459             feedback->InstantFeedback( &iFastSwapArea,
       
   460                                        fbLogicalType,
       
   461                                        ETouchFeedbackVibra,
       
   462                                        TPointerEvent() );
       
   463             }
       
   464         }
       
   465     }
       
   466 
       
   467 
       
   468 // -----------------------------------------------------------------------------
       
   469 // CTsFastSwapAreaExtension::PreferredImageSize
       
   470 // -----------------------------------------------------------------------------
       
   471 //
       
   472 TSize CTsFastSwapAreaExtension::PreferredImageSize()
       
   473     {
       
   474     TAknLayoutRect gridImage;
       
   475     TRAP_IGNORE(
       
   476         RArray<TAknLayoutRect> rects;
       
   477         CleanupClosePushL(rects);
       
   478         rects.ReserveL(KLayoutItemCount);
       
   479         GetFastSwapAreaRects(rects);
       
   480         gridImage = rects[2];
       
   481         CleanupStack::PopAndDestroy(&rects);
       
   482         );
       
   483     return gridImage.Rect().Size();
       
   484     }
       
   485 
       
   486 // --------------------------------------------------------------------------
       
   487 // CTsFastSwapAreaExtension::CalculateSizePreserveRatio
       
   488 // --------------------------------------------------------------------------
       
   489 //
       
   490 TSize CTsFastSwapAreaExtension::CalculateSizePreserveRatio(
       
   491         const TSize& aTargetAreaSize,
       
   492         const TSize& aSourceSize )
       
   493     {
       
   494     const TReal 
       
   495       resizedAspectRatio(aTargetAreaSize.iWidth/(TReal)aTargetAreaSize.iHeight);
       
   496     const TReal 
       
   497       orginalAspectRatio(aSourceSize.iWidth/(TReal)aSourceSize.iHeight);
       
   498     //this condition avoid empty margins ( bigger output ). to realy fit area change it
       
   499     const TReal scaleFactor = 
       
   500         ( orginalAspectRatio > resizedAspectRatio ) ? 
       
   501         (aTargetAreaSize.iHeight /(TReal)aSourceSize.iHeight) ://scale by height
       
   502         (aTargetAreaSize.iWidth /(TReal)aSourceSize.iWidth) ;//scale by width
       
   503     return TSize(aSourceSize.iWidth * scaleFactor, aSourceSize.iHeight * scaleFactor);
       
   504     }
       
   505 
       
   506 
       
   507 // --------------------------------------------------------------------------
       
   508 // CTsFastSwapAreaExtension::CopyBitmapL
       
   509 // Copy and scale.
       
   510 // --------------------------------------------------------------------------
       
   511 //
       
   512 CFbsBitmap* CTsFastSwapAreaExtension::CopyBitmapL( TInt aFbsHandle, TSize aSize, TBool aIsScreenshot  )
       
   513     {
       
   514     CFbsBitmap* ret = new (ELeave) CFbsBitmap();
       
   515     CleanupStack::PushL( ret );
       
   516 
       
   517     CFbsBitmap* bmp = new (ELeave) CFbsBitmap();
       
   518     CleanupStack::PushL( bmp );
       
   519     User::LeaveIfError( bmp->Duplicate( aFbsHandle ) );
       
   520     
       
   521     // First scale using normal method, to show "draft" screenshots.
       
   522     // Do not always use aSize, preserving the aspect ratio is quite
       
   523     // important when showing app icons instead of screenshots
       
   524     TSize sz = CalculateSizePreserveRatio( aSize, bmp->SizeInPixels() );
       
   525     User::LeaveIfError( ret->Create( sz, bmp->DisplayMode() ) );
       
   526     AknIconUtils::ScaleBitmapL( sz, ret, bmp );
       
   527     
       
   528     // Second, if it is screenshot, perform quality improvement scaling
       
   529     if ( aIsScreenshot )
       
   530         {
       
   531         CTsBitmapScaleTask* rotaTask = new (ELeave) CTsBitmapScaleTask( *this );
       
   532         CleanupStack::PushL( rotaTask );
       
   533         iScaleTasks.AppendL( rotaTask );
       
   534         rotaTask->StartLD( bmp, ret ); // ownership of bmp transferred
       
   535         CleanupStack::Pop( rotaTask );
       
   536         CleanupStack::Pop( bmp );
       
   537         }
       
   538     else
       
   539         {
       
   540         CleanupStack::PopAndDestroy( bmp );
       
   541         }
       
   542     
       
   543     CleanupStack::Pop( ret );
       
   544     return ret;
       
   545     }
       
   546 
       
   547 
       
   548 // --------------------------------------------------------------------------
       
   549 // CTsFastSwapAreaExtension::CancelScaleTasks
       
   550 // --------------------------------------------------------------------------
       
   551 //
       
   552 void CTsFastSwapAreaExtension::CancelScaleTasks()
       
   553     {
       
   554     iScaleTasks.ResetAndDestroy();
       
   555     }
       
   556 
       
   557 
       
   558 // --------------------------------------------------------------------------
       
   559 // CTsFastSwapAreaExtension::ScaleFinished
       
   560 // --------------------------------------------------------------------------
       
   561 //
       
   562 void CTsFastSwapAreaExtension::ScaleFinished( CTsBitmapScaleTask* iFinishedTask )
       
   563     {
       
   564     TInt task = iScaleTasks.Find( iFinishedTask );
       
   565     if ( task != KErrNotFound )
       
   566         {
       
   567         iScaleTasks.Remove( task );
       
   568         }
       
   569     iFastSwapArea.DrawDeferred();
       
   570     }
       
   571 
       
   572  // End of file