taskswitcher/taskswitcherui/taskswitcherapp/src/tsfastswaparea.cpp
changeset 4 4d54b72983ae
child 5 c743ef5928ba
equal deleted inserted replaced
3:fb3763350a08 4:4d54b72983ae
       
     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 
       
    19 #include <gulicon.h>
       
    20 #include <eikenv.h>
       
    21 #include <AknUtils.h>
       
    22 #include <AknIconUtils.h>
       
    23 #include <AknIconArray.h>
       
    24 #include <aknstyluspopupmenu.h>
       
    25 #include <AknQueryDialog.h>
       
    26 #include <StringLoader.h>
       
    27 #include <tstaskswitcher.rsg>
       
    28 #include <aknlayoutscalable_apps.cdl.h>
       
    29 #include <layoutmetadata.cdl.h>
       
    30 #include <aknlists.h>
       
    31 #include <touchfeedback.h>
       
    32 #include <akntransitionutils.h>
       
    33 #include <akntranseffect.h>
       
    34 
       
    35 #include "tsfastswaparea.h"
       
    36 #include "tsapplogging.h"
       
    37 #include "tsfswclient.h"
       
    38 #include "tsappui.h"
       
    39 #include "tsdatachangeobserver.h"
       
    40 #include "tseventcontroler.h"
       
    41 
       
    42 /** command ids for the fsw popup */
       
    43 enum TPopupCommands
       
    44     {
       
    45     EFswCmdClose = 10000,
       
    46     EFswCmdCloseAll
       
    47     };
       
    48 
       
    49 /** Number of closable applications, to show "close all" option. */
       
    50 const TInt KTsMaxClosableApps = 2;
       
    51 
       
    52 /** Interval until which no change in the fsw content is rendered
       
    53     after starting the closing of an application. */
       
    54 const TInt KRefreshDelayAfterClose = 2; // seconds
       
    55 
       
    56 /** Uid of Active Idle application. 
       
    57     Used when movind Ai to specified position.*/
       
    58 const TUid KAiUid = TUid::Uid( 0x102750F0 );
       
    59     
       
    60 /** Position of Ai in fsw grid.*/
       
    61 const TInt KAiPosition = 0;
       
    62 
       
    63 /** Default grid item to highlight.*/
       
    64 const TInt KItemToHighlight = 3;
       
    65 
       
    66 const TInt KAppKeyTypeShort = 1;
       
    67 const TInt KAppKeyTypeLong = 2;
       
    68 
       
    69 const TInt KLayoutItemCount = 4;
       
    70 
       
    71 const TInt KRedrawTime = 250000; // 0.25 sec
       
    72 const TInt KHighlighActivationTime = 100000; // 100 ms
       
    73 const TInt KUpdateGridTime = 1000000; // 1 s
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // CTsFastSwapArea::NewL
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 CTsFastSwapArea* CTsFastSwapArea::NewL( const TRect& aRect,
       
    80     CCoeControl& aParent, CTsDeviceState& aDeviceState, 
       
    81     CTsEventControler& aEventHandler )
       
    82     {
       
    83     CTsFastSwapArea* self = CTsFastSwapArea::NewLC(aRect,
       
    84             aParent, aDeviceState, aEventHandler);
       
    85     CleanupStack::Pop( self );
       
    86     return self;
       
    87     }
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // CTsFastSwapArea::NewLC
       
    91 // -----------------------------------------------------------------------------
       
    92 //
       
    93 CTsFastSwapArea* CTsFastSwapArea::NewLC( const TRect& aRect,
       
    94     CCoeControl& aParent, CTsDeviceState& aDeviceState,
       
    95     CTsEventControler& aEventHandler)
       
    96     {
       
    97     CTsFastSwapArea* self = new (ELeave) CTsFastSwapArea(
       
    98             aParent, aDeviceState, aEventHandler);
       
    99     CleanupStack::PushL( self );
       
   100     self->ConstructL( aRect );
       
   101     return self;
       
   102     }
       
   103 
       
   104 // -----------------------------------------------------------------------------
       
   105 // CTsFastSwapArea::CTsFastSwapArea
       
   106 // -----------------------------------------------------------------------------
       
   107 //
       
   108 CTsFastSwapArea::CTsFastSwapArea(CCoeControl& aParent,
       
   109     CTsDeviceState& aDeviceState,
       
   110     CTsEventControler& aEventHandler) :
       
   111     iParent(aParent), iDeviceState(aDeviceState), iEvtHandler(aEventHandler),
       
   112     iPreviousNoOfItems(0)
       
   113     {
       
   114     // no implementation required
       
   115     }
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CTsFastSwapArea::~CTsFastSwapArea
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 CTsFastSwapArea::~CTsFastSwapArea()
       
   122     {
       
   123     iArray.ResetAndDestroy();
       
   124     delete iGrid;
       
   125     delete iFSClient;
       
   126     delete iPopup;
       
   127     delete iConfirmCloseQuery;
       
   128     delete iHighlightTimer;
       
   129     delete iRedrawTimer;
       
   130     delete iUpdateGridTimer;
       
   131     }
       
   132 
       
   133 // -----------------------------------------------------------------------------
       
   134 // CTsFastSwapArea::ConstructL
       
   135 // -----------------------------------------------------------------------------
       
   136 //
       
   137 void CTsFastSwapArea::ConstructL( const TRect& aRect )
       
   138     {
       
   139     SetContainerWindowL( iParent );
       
   140 
       
   141     SetRect( aRect );
       
   142 
       
   143     // setup ganes grid
       
   144     ReCreateGridL();
       
   145 
       
   146     // create stylus popup instance
       
   147     PreCreatePopupL();
       
   148 
       
   149     // connect to fsw server
       
   150     iFSClient = CTsFswClient::NewL();
       
   151     
       
   152     iEvtHandler.ReInitPhysicsL(GridWorldSize(), ViewSize(), ETrue);
       
   153     
       
   154     // add self to device state observer
       
   155     iDeviceState.AddObserverL( *this, EDeviceType );
       
   156     
       
   157     iHighlightTimer = new (ELeave) CTsFastSwapTimer( *this );
       
   158     iHighlightTimer->ConstructL();
       
   159     
       
   160     iRedrawTimer = new (ELeave) CTsFastSwapTimer( *this );
       
   161     iRedrawTimer->ConstructL();
       
   162 
       
   163     iUpdateGridTimer = new (ELeave) CTsFastSwapTimer( *this );
       
   164     iUpdateGridTimer->ConstructL();
       
   165     
       
   166     ActivateL();
       
   167     }
       
   168 
       
   169 // -----------------------------------------------------------------------------
       
   170 // CTsFastSwapArea::ReCreateGridL
       
   171 // -----------------------------------------------------------------------------
       
   172 //
       
   173 void CTsFastSwapArea::ReCreateGridL()
       
   174     {
       
   175     MCoeControlObserver* obs = NULL;
       
   176     TBool wasHighlight = iDeviceState.DeviceType() == 
       
   177                              CTsDeviceState::EHybrid ? ETrue : EFalse;
       
   178     if ( iGrid )
       
   179         {
       
   180         obs = iGrid->Observer();
       
   181         iDeviceState.RemoveObserver(*iGrid);
       
   182         wasHighlight = iGrid->IsHighlightVisible();
       
   183         delete iGrid;
       
   184         iGrid = NULL;
       
   185         }
       
   186     
       
   187     iGrid = new( ELeave ) CTsFastSwapGrid;
       
   188     iGrid->ConstructL( this );
       
   189     iDeviceState.AddObserverL(*iGrid, MTsDeviceStateObserver::ESkin);
       
   190     
       
   191     AknListBoxLayouts::SetupStandardGrid( *iGrid );
       
   192     
       
   193     RArray<TAknLayoutRect> rects;
       
   194     CleanupClosePushL(rects);
       
   195     rects.ReserveL(KLayoutItemCount);
       
   196     GetFastSwapAreaRects(rects);
       
   197     TAknLayoutRect gridAppPane = rects[0];
       
   198     TAknLayoutRect gridItem = rects[1];
       
   199     TAknLayoutRect gridImage = rects[2];
       
   200     TAknLayoutRect gridNextItem = rects[3];
       
   201     CleanupStack::PopAndDestroy(&rects);
       
   202     
       
   203     TInt variety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
       
   204     iGrid->SetRect(gridAppPane.Rect());
       
   205     iGrid->SetVisibleViewRect(gridAppPane.Rect());
       
   206     TAknLayoutScalableParameterLimits gridParams = 
       
   207         AknLayoutScalable_Apps::cell_tport_appsw_pane_ParamLimits( variety );
       
   208     TPoint empty( ELayoutEmpty, ELayoutEmpty );
       
   209     
       
   210     AknListBoxLayouts::SetupFormGfxCell( *iGrid, iGrid->ItemDrawer(), 0,
       
   211             AknLayoutScalable_Apps::cell_tport_appsw_pane_g1( variety ).LayoutLine(),
       
   212             empty, empty );
       
   213 
       
   214     // Setup text layout
       
   215     TRgb textColor;
       
   216     AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor,
       
   217             KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG9 );
       
   218     
       
   219     TAknLayoutText textLayout;
       
   220     textLayout.LayoutText(
       
   221             Rect(),
       
   222             AknLayoutScalable_Apps::cell_tport_appsw_pane_t1( variety ).LayoutLine() );
       
   223     
       
   224     // Because textLayout.BaselineOffset() does not work (missing lib entry),
       
   225     // we need to calculate offset ourselves
       
   226     TInt baselineOffset = textLayout.TextRect().iBr.iY - textLayout.TextRect().iTl.iY;
       
   227     AknListBoxLayouts::SetupFormTextCell( *iGrid, iGrid->ItemDrawer(), 1 /*Column index*/,
       
   228                                           textLayout.Font() /*Font type*/,
       
   229                                           textColor.Color16() /*color*/,
       
   230                                           textLayout.TextRect().iTl.iX /*Left margin*/, 0 /*unused*/,
       
   231                                           baselineOffset /*Baseline*/, 0 /*Text width*/,
       
   232                                           textLayout.Align() /*Text alignment*/,
       
   233                                           TPoint(0,0) /*Start pos*/,
       
   234                                           TPoint(0,0) /*End pos*/);
       
   235     
       
   236     // Setup grid observers
       
   237     if ( obs )
       
   238         {
       
   239         iGrid->SetObserver( obs );
       
   240         }
       
   241     iGrid->SetListBoxObserver(this);
       
   242     iGrid->SetFastSwapGridObserver(this);
       
   243     iGrid->SetContainerWindowL(*this);
       
   244     
       
   245     if ( AknLayoutUtils::LayoutMirrored() )
       
   246         {
       
   247         iGridItemGap = gridItem.Rect().iTl.iX - gridNextItem.Rect().iBr.iX;
       
   248         }
       
   249     else
       
   250         {
       
   251         iGridItemGap = gridNextItem.Rect().iTl.iX - gridItem.Rect().iBr.iX;
       
   252         }
       
   253     iMaxItemsOnScreen = Rect().Width() / gridItem.Rect().Width();
       
   254     if ( iMaxItemsOnScreen > 1 )
       
   255         {
       
   256         TInt widthWithGaps =
       
   257             (iMaxItemsOnScreen - 1) * iGridItemGap + iMaxItemsOnScreen * gridItem.Rect().Width();
       
   258         if ( widthWithGaps > Rect().Width() )
       
   259             {
       
   260             iMaxItemsOnScreen--;
       
   261             }
       
   262         }
       
   263     iGridItemWidth = gridItem.Rect().Width();
       
   264     
       
   265     iGrid->ItemDrawer()->ColumnData()->SetDrawBackground(EFalse);
       
   266     
       
   267     // Update state
       
   268     HandleDeviceStateChanged( EDeviceType );
       
   269     if( wasHighlight )
       
   270         {
       
   271         iGrid->ShowHighlight();
       
   272         }
       
   273     else
       
   274         {
       
   275         iGrid->HideHighlight();
       
   276         }
       
   277     
       
   278     // Make sure that there is an ActivateL call even when we are not
       
   279     // called from ConstructL. (in order to have the grid's parent ptr set properly)
       
   280     ActivateL();
       
   281     }
       
   282 
       
   283 
       
   284 // --------------------------------------------------------------------------
       
   285 // CTsFastSwapArea::GetFastSwapAreaRects
       
   286 // --------------------------------------------------------------------------
       
   287 //
       
   288 void CTsFastSwapArea::GetFastSwapAreaRects( RArray<TAknLayoutRect>& aRects )
       
   289     {
       
   290     TAknLayoutRect gridAppPane;
       
   291     TAknLayoutRect gridItem;
       
   292     TAknLayoutRect gridImage;
       
   293     TAknLayoutRect gridNextItem;
       
   294     
       
   295     TInt variety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
       
   296     
       
   297     gridAppPane.LayoutRect( Rect(), 
       
   298             AknLayoutScalable_Apps::tport_appsw_pane( variety ) );
       
   299     aRects.Append(gridAppPane);
       
   300     
       
   301     gridItem.LayoutRect( gridAppPane.Rect(),
       
   302             AknLayoutScalable_Apps::cell_tport_appsw_pane( variety, 0, 0 ) );
       
   303     aRects.Append(gridItem);
       
   304     
       
   305     gridImage.LayoutRect( gridItem.Rect(),
       
   306             AknLayoutScalable_Apps::cell_tport_appsw_pane_g1( variety ) ); 
       
   307     aRects.Append(gridImage);
       
   308     gridNextItem.LayoutRect( gridAppPane.Rect(),
       
   309             AknLayoutScalable_Apps::cell_tport_appsw_pane_cp03( variety ) );
       
   310     aRects.Append(gridNextItem);
       
   311     }
       
   312 
       
   313 
       
   314 // --------------------------------------------------------------------------
       
   315 // CTsFastSwapArea::Setup
       
   316 // --------------------------------------------------------------------------
       
   317 //
       
   318 void CTsFastSwapArea::Setup( MCoeControlObserver& aControlObserver )
       
   319     {
       
   320     iGrid->SetObserver( &aControlObserver );
       
   321     }
       
   322 
       
   323 // -----------------------------------------------------------------------------
       
   324 // CTsFastSwapArea::SizeChanged
       
   325 // -----------------------------------------------------------------------------
       
   326 //
       
   327 void CTsFastSwapArea::SizeChanged()
       
   328     {
       
   329     TSLOG_CONTEXT( CTsFastSwapArea::SizeChanged, TSLOG_LOCAL );
       
   330     TSLOG_IN();
       
   331     
       
   332     if ( iGrid )
       
   333         {
       
   334         // Grid needs to be recreated to proper reinitilize
       
   335         // data with new layout values
       
   336         TInt selIdx = SelectedIndex();
       
   337         TRAPD(err, 
       
   338               ReCreateGridL();
       
   339               iEvtHandler.ReInitPhysicsL(GridWorldSize(), ViewSize(), ETrue););
       
   340         if ( err != KErrNone )
       
   341             {
       
   342             TSLOG1( TSLOG_INFO, "ReCreateGridL leaves with %d", err );
       
   343             }
       
   344         HandleFswContentChanged();
       
   345         iGrid->SetCurrentDataIndex(selIdx);
       
   346         UpdateGrid(ETrue, EFalse);
       
   347         DrawDeferred();
       
   348         }
       
   349     TSLOG_OUT();
       
   350     }
       
   351 
       
   352 // -----------------------------------------------------------------------------
       
   353 // CTsFastSwapArea::Draw
       
   354 // -----------------------------------------------------------------------------
       
   355 //
       
   356 void CTsFastSwapArea::Draw( const TRect& /*aRect*/ ) const
       
   357     {
       
   358     CWindowGc& gc = SystemGc();
       
   359     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   360     MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
       
   361     AknsDrawUtils::Background( skin,
       
   362            cc,
       
   363            this,
       
   364            gc,
       
   365            Rect() );
       
   366     }
       
   367 
       
   368 // --------------------------------------------------------------------------
       
   369 // CTsFastSwapArea::SwitchToApp
       
   370 // --------------------------------------------------------------------------
       
   371 //
       
   372 void CTsFastSwapArea::SwitchToApp( TInt aIndex )
       
   373     {
       
   374     if ( aIndex >= 0 && aIndex < iArray.Count() )
       
   375         {
       
   376         TInt wgId = iArray[aIndex]->WgId();
       
   377         // Move other app to foreground and then move ourselves to background.
       
   378         // Order is important and cannot be reversed.
       
   379         iFSClient->SwitchToApp( wgId );
       
   380         // We do not want to come back to ts if the activated app is closed.
       
   381         // Therefore ts must be moved to background.
       
   382         CTsAppUi* appui =
       
   383             static_cast<CTsAppUi*>( iEikonEnv->AppUi() );
       
   384         appui->MoveAppToBackground( AknTransEffect::EApplicationStartRect );
       
   385         }
       
   386     }
       
   387 
       
   388 // --------------------------------------------------------------------------
       
   389 // CTsFastSwapArea::TryCloseAppL
       
   390 // --------------------------------------------------------------------------
       
   391 //
       
   392 void CTsFastSwapArea::TryCloseAppL( TInt aIndex,
       
   393         TBool aSuppressRendering )
       
   394     {
       
   395     TSLOG_CONTEXT( TryCloseAppL, TSLOG_LOCAL );
       
   396     TSLOG2_IN( "%d %d", aIndex, aSuppressRendering );
       
   397 
       
   398     if ( aIndex >= 0 && aIndex < iArray.Count() && CanClose( aIndex ) )
       
   399         {
       
   400         TInt wgId = iArray[aIndex]->WgId();
       
   401         iFSClient->CloseApp( wgId );
       
   402         // The fsw content will change sooner or later
       
   403         // but the updated content (without the closed app) will not
       
   404         // come very fast. It looks better to the user if the item
       
   405         // in the grid is removed right here, right now.
       
   406         // If the app does not close for some reason then this is
       
   407         // not fully correct but the app will then reappear on the next
       
   408         // content-changed notification anyway.
       
   409         delete iArray[aIndex];
       
   410         iArray.Remove( aIndex );
       
   411         NotifyChange();
       
   412         if ( !aSuppressRendering )
       
   413             {
       
   414             RenderContentL();
       
   415             }
       
   416         // Update item selection on the screen if last item was deleted
       
   417         TInt newItemCount = GridItemCount();
       
   418         if ( aIndex == newItemCount )
       
   419             {
       
   420             newItemCount--;
       
   421             iGrid->SetCurrentDataIndex(newItemCount);
       
   422             }
       
   423         iTimeOfLastClose.HomeTime();
       
   424         }
       
   425 
       
   426     TSLOG_OUT();
       
   427     }
       
   428 
       
   429 // --------------------------------------------------------------------------
       
   430 // CTsFastSwapArea::TryCloseAppWithQueryL
       
   431 // --------------------------------------------------------------------------
       
   432 //
       
   433 void CTsFastSwapArea::TryCloseAppWithQueryL( TInt aIndex )
       
   434     {
       
   435     if ( aIndex >= 0 && aIndex < iArray.Count()
       
   436             && CanClose( aIndex )
       
   437             && ConfirmCloseL( aIndex ) )
       
   438         {
       
   439         TryCloseAppL( aIndex );
       
   440         }
       
   441     }
       
   442 
       
   443 // --------------------------------------------------------------------------
       
   444 // CTsFastSwapArea::TryCloseAllL
       
   445 // --------------------------------------------------------------------------
       
   446 //
       
   447 void CTsFastSwapArea::TryCloseAllL()
       
   448     {
       
   449     // note the direction of the loop, this is needed because
       
   450     // TryCloseAppL may modify the array
       
   451     TBool changed = EFalse;
       
   452     for ( TInt i = iArray.Count() - 1; i >= 0; --i )
       
   453         {
       
   454         if ( CanClose( i ) )
       
   455             {
       
   456             TryCloseAppL( i, ETrue );
       
   457             changed = ETrue;
       
   458             }
       
   459         }
       
   460     if ( changed )
       
   461         {
       
   462         RenderContentL();
       
   463         RestoreSelectedIndex();
       
   464         iGrid->DrawNow();
       
   465         }
       
   466     }
       
   467 
       
   468 // --------------------------------------------------------------------------
       
   469 // CTsFastSwapArea::CanClose
       
   470 // --------------------------------------------------------------------------
       
   471 //
       
   472 TBool CTsFastSwapArea::CanClose( TInt aIndex ) const
       
   473     {
       
   474     CTsFswEntry* e = iArray[aIndex];
       
   475     return !e->AlwaysShown() && !e->SystemApp();
       
   476     }
       
   477 
       
   478 // --------------------------------------------------------------------------
       
   479 // CTsFastSwapArea::CanCloseOthers
       
   480 // --------------------------------------------------------------------------
       
   481 //
       
   482 TBool CTsFastSwapArea::CanCloseAll( TInt aSelectedItem ) const
       
   483     {
       
   484     TInt count( 0 );
       
   485 
       
   486     // Count number of closable applications and if number exceeds 2 finish
       
   487     // counting, because it is already enough to show the option.
       
   488     for ( TInt i = iArray.Count(); --i >= 0 && count < KTsMaxClosableApps; )
       
   489         {
       
   490         if ( CanClose( i ) )
       
   491             {
       
   492             count++;
       
   493             }
       
   494         }
       
   495     return ( count >= KTsMaxClosableApps ) ||
       
   496            ( count && !CanClose( aSelectedItem ) );
       
   497     }
       
   498 
       
   499 // --------------------------------------------------------------------------
       
   500 // CTsFastSwapArea::HandleFswContentChanged
       
   501 // From MTsFswObserver
       
   502 // --------------------------------------------------------------------------
       
   503 //
       
   504 void CTsFastSwapArea::HandleFswContentChanged()
       
   505     {
       
   506     TSLOG_CONTEXT( HandleFswContentChanged, TSLOG_LOCAL );
       
   507     TSLOG_IN();
       
   508 
       
   509     TRAPD( err, HandleFswContentChangedL() );
       
   510     if ( err != KErrNone )
       
   511         {
       
   512         TSLOG1( TSLOG_INFO, "leave occured: %d", err );
       
   513         }
       
   514 
       
   515     TSLOG_OUT();
       
   516     }
       
   517 
       
   518 // --------------------------------------------------------------------------
       
   519 // CTsFastSwapArea::HandleFswContentChangedL
       
   520 // --------------------------------------------------------------------------
       
   521 //
       
   522 void CTsFastSwapArea::HandleFswContentChangedL()
       
   523     {
       
   524     TSLOG_CONTEXT( HandleFswContentChangedL, TSLOG_LOCAL );
       
   525     TSLOG_IN();
       
   526 
       
   527     // If there was an app close operation started during the last
       
   528     // few seconds then stop, to prevent flickering.
       
   529     TTime now;
       
   530     now.HomeTime();
       
   531     TTimeIntervalSeconds iv;
       
   532     if ( now.SecondsFrom( iTimeOfLastClose, iv ) == KErrNone
       
   533             && iv.Int() <= KRefreshDelayAfterClose )
       
   534         {
       
   535         TSLOG1_OUT( "difference since last close is only %d sec, stop", iv.Int() );
       
   536         return;
       
   537         }
       
   538 
       
   539     // get current content from fastswap server
       
   540     iFSClient->GetContentL( iArray );
       
   541     SwapApplicationOrder( iArray );
       
   542 
       
   543 #ifdef _DEBUG
       
   544     for ( TInt i = 0, ie = iArray.Count(); i != ie; ++i )
       
   545         {
       
   546         CTsFswEntry* e = iArray[i];
       
   547         const TDesC& name( e->AppName() );
       
   548         TSLOG4( TSLOG_INFO, "[%d]: %d %d %S", i, e->WgId(), e->AppUid(), &name );
       
   549         }
       
   550 #endif
       
   551 
       
   552     // draw
       
   553     RenderContentL();
       
   554 
       
   555     // notify observer, if present
       
   556     NotifyChange();
       
   557 
       
   558     TSLOG_OUT();
       
   559     }
       
   560 
       
   561 // --------------------------------------------------------------------------
       
   562 // CTsFastSwapArea::RenderContentL
       
   563 // --------------------------------------------------------------------------
       
   564 //
       
   565 void CTsFastSwapArea::RenderContentL()
       
   566     {
       
   567     TSLOG_CONTEXT( RenderContentL, TSLOG_LOCAL );
       
   568     TSLOG_IN();
       
   569 
       
   570     _LIT(KSeparator, "\t");
       
   571     
       
   572     CArrayPtr<CGulIcon>* iconArray = new ( ELeave ) CAknIconArray( iArray.Count() );
       
   573     CleanupStack::PushL( iconArray );
       
   574     CDesCArrayFlat* textArray = new ( ELeave ) CDesCArrayFlat( iArray.Count() );
       
   575     CleanupStack::PushL( textArray );
       
   576     RArray<TInt> closeItemArray;
       
   577     CleanupClosePushL(closeItemArray);
       
   578     
       
   579     TInt variety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
       
   580     RArray<TAknLayoutRect> rects;
       
   581     CleanupClosePushL(rects);
       
   582     rects.ReserveL(KLayoutItemCount);
       
   583     GetFastSwapAreaRects(rects);
       
   584     TAknLayoutRect gridItem = rects[1];
       
   585     CleanupStack::PopAndDestroy(&rects);
       
   586     if ( AknLayoutUtils::LayoutMirrored() )
       
   587         {
       
   588         iGrid->SetLayoutL( EFalse, EFalse, ETrue, iArray.Count(), 1, gridItem.Rect().Size(), iGridItemGap );
       
   589         }
       
   590     else
       
   591         {
       
   592         iGrid->SetLayoutL( EFalse, ETrue, ETrue, iArray.Count(), 1, gridItem.Rect().Size(), iGridItemGap );
       
   593         }
       
   594     
       
   595     for ( TInt i = 0, ie = iArray.Count(); i != ie; ++i )
       
   596         {
       
   597         const TDesC& appName( iArray[i]->AppName() );
       
   598         const TInt formatLen = 3 + 2;
       
   599         RBuf formAppName;
       
   600         CleanupClosePushL(formAppName);
       
   601         formAppName.CreateL(appName.Length() + formatLen);
       
   602         formAppName.AppendNum(i);
       
   603         formAppName.Append(KSeparator);
       
   604         formAppName.Append(appName);
       
   605         textArray->AppendL(formAppName);
       
   606         CleanupStack::PopAndDestroy(&formAppName);
       
   607         TSize sz = PreferredImageSize();
       
   608 
       
   609         // take the screenshot or appicon+mask and make a copy and scale
       
   610         CFbsBitmap* bitmap = 0;
       
   611         TInt h = iArray[i]->ScreenshotHandle();
       
   612         TSLOG2( TSLOG_INFO, "'%S' screenshot handle %d", &appName, h );
       
   613         TInt maskh = 0;
       
   614         CFbsBitmap* mask = 0;
       
   615         if ( !h )
       
   616             {
       
   617             h = iArray[i]->AppIconBitmapHandle();
       
   618             maskh = iArray[i]->AppIconMaskHandle();
       
   619             TSLOG1( TSLOG_INFO, "using appicon, handle = %d", h );
       
   620             }
       
   621         __ASSERT_DEBUG( h, User::Invariant() );
       
   622         bitmap = CopyBitmapL( h, sz );
       
   623         CleanupStack::PushL( bitmap );
       
   624         if ( maskh )
       
   625             {
       
   626             mask = CopyBitmapL( maskh, sz );
       
   627             }
       
   628         CleanupStack::PushL( mask );
       
   629 
       
   630         CGulIcon* icon = CGulIcon::NewL( bitmap, mask );
       
   631         CleanupStack::PushL(icon);
       
   632         iconArray->AppendL(icon);
       
   633         CleanupStack::Pop( 3, bitmap ); // mask, bitmap, icon
       
   634         
       
   635         // Check if item can be closed
       
   636         if ( CanClose(i) && AknLayoutUtils::PenEnabled() )
       
   637             {
       
   638             closeItemArray.AppendL(i);
       
   639             }
       
   640         }
       
   641     // Setup grid
       
   642     iGrid->Model()->SetItemTextArray(textArray);
       
   643     CArrayPtr<CGulIcon>* oldIconArray =
       
   644         iGrid->ItemDrawer()->FormattedCellData()->IconArray();
       
   645     if(oldIconArray)
       
   646         {
       
   647         delete oldIconArray;
       
   648         oldIconArray = NULL;
       
   649         }
       
   650     iGrid->ItemDrawer()->FormattedCellData()->SetIconArrayL(iconArray);
       
   651     iGrid->SetCloseItemsL(closeItemArray);
       
   652     
       
   653     // Cleanup
       
   654     CleanupStack::PopAndDestroy(&closeItemArray);
       
   655     CleanupStack::Pop(textArray);
       
   656     CleanupStack::Pop(iconArray);
       
   657     
       
   658     iGrid->ScrollBarFrame()->SetScrollBarVisibilityL(
       
   659                 CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOff);
       
   660     
       
   661     // refresh the items in the grid
       
   662     if(iPreviousNoOfItems < iArray.Count())
       
   663         {
       
   664         iGrid->HandleItemAdditionL();
       
   665         }
       
   666     else if(iPreviousNoOfItems > iArray.Count())
       
   667         {
       
   668         iGrid->HandleItemRemovalL();
       
   669         }
       
   670     iPreviousNoOfItems = iArray.Count();
       
   671     iEvtHandler.ReInitPhysicsL( GridWorldSize(), ViewSize(), ETrue );
       
   672     UpdateGrid( ETrue );
       
   673     
       
   674     TSLOG_OUT();
       
   675     }
       
   676 
       
   677 // --------------------------------------------------------------------------
       
   678 // CTsFastSwapArea::CopyBitmapL
       
   679 // Copy and scale.
       
   680 // --------------------------------------------------------------------------
       
   681 //
       
   682 CFbsBitmap* CTsFastSwapArea::CopyBitmapL( TInt aFbsHandle, TSize aSize )
       
   683     {
       
   684     CFbsBitmap* ret = new (ELeave) CFbsBitmap();
       
   685     CleanupStack::PushL( ret );
       
   686 
       
   687     CFbsBitmap* bmp = new (ELeave) CFbsBitmap();
       
   688     CleanupStack::PushL( bmp );
       
   689     User::LeaveIfError( bmp->Duplicate( aFbsHandle ) );
       
   690 
       
   691     // do not always use aSize, preserving the aspect ratio is quite
       
   692     // important when showing app icons instead of screenshots
       
   693     TSize sz = CalculateSizePreserveRatio( aSize, bmp->SizeInPixels() );
       
   694 
       
   695     User::LeaveIfError( ret->Create( sz, bmp->DisplayMode() ) );
       
   696 
       
   697     AknIconUtils::ScaleBitmapL( sz, ret, bmp );
       
   698 
       
   699     CleanupStack::PopAndDestroy( bmp );
       
   700     CleanupStack::Pop( ret );
       
   701 
       
   702     return ret;
       
   703     }
       
   704 
       
   705 // --------------------------------------------------------------------------
       
   706 // CTsFastSwapArea::CountComponentControls
       
   707 // --------------------------------------------------------------------------
       
   708 //
       
   709 TInt CTsFastSwapArea::CountComponentControls() const
       
   710     {
       
   711     return 1;
       
   712     }
       
   713 
       
   714 // --------------------------------------------------------------------------
       
   715 // CTsFastSwapArea::ComponentControl
       
   716 // --------------------------------------------------------------------------
       
   717 //
       
   718 CCoeControl* CTsFastSwapArea::ComponentControl( TInt aIndex ) const
       
   719     {
       
   720     if ( aIndex == 0 )
       
   721         {
       
   722         return iGrid;
       
   723         }
       
   724     return NULL;
       
   725     }
       
   726 
       
   727 // -----------------------------------------------------------------------------
       
   728 // CTsFastSwapArea::HandleSwitchToBackgroundEvent
       
   729 // -----------------------------------------------------------------------------
       
   730 //
       
   731 void CTsFastSwapArea::HandleSwitchToBackgroundEvent()
       
   732     {
       
   733     // stop listening for changes in fsw content
       
   734     iFSClient->CancelSubscribe();
       
   735     // get rid of the close confirmation query if shown
       
   736     delete iConfirmCloseQuery; // this will cause ExecuteLD to return with 0
       
   737     iConfirmCloseQuery = 0;
       
   738     }
       
   739 
       
   740 // -----------------------------------------------------------------------------
       
   741 // CTsFastSwapArea::HandleSwitchToForegroundEvent
       
   742 // -----------------------------------------------------------------------------
       
   743 //
       
   744 void CTsFastSwapArea::HandleSwitchToForegroundEvent()
       
   745     {
       
   746     TSLOG_CONTEXT( CTsFastSwapArea::HandleSwitchToForegroundEvent, TSLOG_LOCAL );
       
   747     TSLOG_IN();
       
   748     
       
   749     // get the current task list
       
   750     HandleFswContentChanged();
       
   751     // and then start listening for changes
       
   752     iFSClient->Subscribe( *this );
       
   753     
       
   754     if ( iDeviceState.DeviceType() == CTsDeviceState::EFullTouch )
       
   755         {
       
   756         iGrid->HideHighlight();
       
   757         }
       
   758     else
       
   759         {
       
   760         iGrid->ShowHighlight();
       
   761         }
       
   762     
       
   763     RestoreSelectedIndex();
       
   764     UpdateGrid(ETrue, EFalse);
       
   765     
       
   766     iRedrawTimer->Cancel();
       
   767     iRedrawTimer->After(KRedrawTime);
       
   768     
       
   769     // give feedback
       
   770     LaunchPopupFeedback();
       
   771 
       
   772     TSLOG_OUT();
       
   773     }
       
   774 
       
   775 // -----------------------------------------------------------------------------
       
   776 // CTsFastSwapArea::FocusChanged
       
   777 // -----------------------------------------------------------------------------
       
   778 //
       
   779 void CTsFastSwapArea::FocusChanged( TDrawNow /*aDrawNow*/ )
       
   780     {
       
   781     if ( IsFocused() )
       
   782         {
       
   783         // if in non-touch mode then select (highlight) some item
       
   784         if ( !AknLayoutUtils::PenEnabled()
       
   785             && SelectedIndex() == KErrNotFound
       
   786             && GridItemCount() )
       
   787             {
       
   788             RestoreSelectedIndex();
       
   789             }
       
   790         }
       
   791     else
       
   792         {
       
   793         // store the currently selected index if there is one
       
   794         SaveSelectedIndex();
       
   795         }
       
   796     iGrid->DrawDeferred();
       
   797     }
       
   798 
       
   799 // -----------------------------------------------------------------------------
       
   800 // CTsFastSwapArea::OfferKeyEventL
       
   801 // -----------------------------------------------------------------------------
       
   802 //
       
   803 TKeyResponse CTsFastSwapArea::OfferKeyEventL(
       
   804         const TKeyEvent& aKeyEvent,
       
   805         TEventCode aType )
       
   806     {
       
   807     iKeyEvent = ETrue;
       
   808     iGrid->SetTactileFeedbackSupport(EFalse);
       
   809     // handle the 'clear' key
       
   810     if ( aType == EEventKey && aKeyEvent.iCode == EKeyBackspace )
       
   811         {
       
   812         TInt idx = SelectedIndex();
       
   813         if ( idx >= 0 )
       
   814             {
       
   815             TryCloseAppWithQueryL( idx );
       
   816             }
       
   817         return EKeyWasConsumed;
       
   818         }
       
   819     
       
   820     //do not forward the event until item is higlighted
       
   821     if( aKeyEvent.iScanCode == EStdKeyLeftArrow ||
       
   822         aKeyEvent.iScanCode == EStdKeyRightArrow )
       
   823         {
       
   824         if ( !iGrid->IsHighlightVisible() )
       
   825             {
       
   826             if ( aType == EEventKey )
       
   827                 {
       
   828                 ShowHighlight();
       
   829                 iConsumeEvent = ETrue;
       
   830                 }
       
   831             return EKeyWasConsumed;
       
   832             }
       
   833         else if(iConsumeEvent)
       
   834             {
       
   835             if (aType == EEventKeyUp)
       
   836                 {
       
   837                 return EKeyWasConsumed;
       
   838                 }
       
   839             iConsumeEvent = EFalse;
       
   840             }
       
   841         }
       
   842     
       
   843     // pass the event to grid
       
   844     // do not pass down and up arrow key events
       
   845     if ( aKeyEvent.iScanCode != EStdKeyUpArrow &&
       
   846          aKeyEvent.iScanCode != EStdKeyDownArrow )
       
   847         {
       
   848         TBool animate(ETrue);
       
   849         TBool redraw(EFalse);
       
   850         TInt prevItem = SelectedIndex();
       
   851         TKeyResponse response = iGrid->OfferKeyEventL( aKeyEvent, aType );
       
   852         if ( prevItem != SelectedIndex() && // item changed
       
   853              ( ( prevItem == 0 &&
       
   854                  SelectedIndex() == GridItemCount() - 1 &&
       
   855                  GridItemCount() > iMaxItemsOnScreen + 1 ) || // loop from first to last item
       
   856                ( prevItem == GridItemCount() - 1 &&
       
   857                  SelectedIndex() == 0 &&
       
   858                  GridItemCount() > iMaxItemsOnScreen + 1) // loop from last to first item
       
   859               ) // loop
       
   860             )
       
   861             {
       
   862             // Loop occured
       
   863             animate = EFalse;
       
   864             }
       
   865         if ( prevItem != SelectedIndex() )
       
   866             {
       
   867             redraw = ETrue;
       
   868             iGrid->ShowHighlight();
       
   869             }
       
   870         UpdateGrid( redraw, animate );
       
   871         return response;
       
   872         }
       
   873     
       
   874     return EKeyWasNotConsumed;
       
   875     }
       
   876 
       
   877 // -----------------------------------------------------------------------------
       
   878 // CTsFastSwapArea::HandlePointerEventL
       
   879 // -----------------------------------------------------------------------------
       
   880 //
       
   881 void CTsFastSwapArea::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
   882     {
       
   883     iKeyEvent = EFalse;
       
   884     iGrid->SetTactileFeedbackSupport(ETrue);
       
   885     if(aPointerEvent.iType == TPointerEvent::EButton1Down)
       
   886         {
       
   887         iTapEvent = aPointerEvent;
       
   888         }
       
   889     }
       
   890 
       
   891 // -----------------------------------------------------------------------------
       
   892 // CTsFastSwapArea::ConfirmCloseL
       
   893 // -----------------------------------------------------------------------------
       
   894 //
       
   895 TBool CTsFastSwapArea::ConfirmCloseL( TInt aIndex )
       
   896     {
       
   897     HBufC* msg = StringLoader::LoadLC( R_TS_FSW_CONFIRM_CLOSE,
       
   898         iArray[aIndex]->AppName() );
       
   899     iConfirmCloseQuery = CAknQueryDialog::NewL(
       
   900         CAknQueryDialog::EConfirmationTone );
       
   901     iConfirmCloseQuery->SetPromptL( *msg );
       
   902     CleanupStack::PopAndDestroy( msg );
       
   903     TBool ok = iConfirmCloseQuery->ExecuteLD(
       
   904         R_TS_FSW_CONFIRM_CLOSE_QUERY );
       
   905     iConfirmCloseQuery = 0;
       
   906     return ok;
       
   907     }
       
   908 
       
   909 // -----------------------------------------------------------------------------
       
   910 // CTsFastSwapArea::SelectedIndex
       
   911 // -----------------------------------------------------------------------------
       
   912 //
       
   913 TInt CTsFastSwapArea::SelectedIndex() const
       
   914     {
       
   915     return iGrid->CurrentDataIndex();
       
   916     }
       
   917 
       
   918 // -----------------------------------------------------------------------------
       
   919 // CTsFastSwapArea::SaveSelectedIndex
       
   920 // -----------------------------------------------------------------------------
       
   921 //
       
   922 void CTsFastSwapArea::SaveSelectedIndex()
       
   923     {
       
   924     iSavedSelectedIndex = SelectedIndex();
       
   925     }
       
   926 
       
   927 // -----------------------------------------------------------------------------
       
   928 // CTsFastSwapArea::RestoreSelectedIndex
       
   929 // -----------------------------------------------------------------------------
       
   930 //
       
   931 void CTsFastSwapArea::RestoreSelectedIndex()
       
   932     {
       
   933     iSavedSelectedIndex = KErrNotFound;
       
   934     if ( GridItemCount() )
       
   935         {
       
   936         // highlight second recent item (that has index 2) if possible
       
   937         TInt highlightItem = 0;
       
   938         TInt count = GridItemCount();
       
   939         while( highlightItem < count 
       
   940             && highlightItem < KItemToHighlight )
       
   941             {
       
   942             ++highlightItem;
       
   943             }
       
   944         iSavedSelectedIndex = highlightItem - 1;//count from 0
       
   945         iGrid->SetCurrentDataIndex( iSavedSelectedIndex );
       
   946         TBool forceRedraw(ETrue);
       
   947         UpdateGrid(forceRedraw);
       
   948         }
       
   949     }
       
   950 
       
   951 // -----------------------------------------------------------------------------
       
   952 // CTsFastSwapArea::ProcessCommandL
       
   953 // Handle fsw popup commands
       
   954 // -----------------------------------------------------------------------------
       
   955 //
       
   956 void CTsFastSwapArea::ProcessCommandL( TInt aCommandId )
       
   957     {
       
   958     switch ( aCommandId )
       
   959         {
       
   960         case EFswCmdClose:
       
   961             TryCloseAppL( iAppIndexForPopup );
       
   962             break;
       
   963 
       
   964         case EFswCmdCloseAll:
       
   965             TryCloseAllL();
       
   966             break;
       
   967 
       
   968         case KErrCancel:
       
   969             // popup dismisses automatically when tapping outside or when switching to other app
       
   970             break;
       
   971         }
       
   972     }
       
   973 
       
   974 
       
   975 // -----------------------------------------------------------------------------
       
   976 // CTsFastSwapArea::HandleCloseEventL
       
   977 // -----------------------------------------------------------------------------
       
   978 //
       
   979 void CTsFastSwapArea::HandleCloseEventL(TInt aItemIdx)
       
   980     {
       
   981     TryCloseAppWithQueryL( aItemIdx );
       
   982     }
       
   983 
       
   984 
       
   985 // -----------------------------------------------------------------------------
       
   986 // CTsFastSwapArea::HandleDeviceStateChanged
       
   987 // -----------------------------------------------------------------------------
       
   988 //
       
   989 void CTsFastSwapArea::HandleDeviceStateChanged( TChangeType aChangeType )
       
   990     {
       
   991     if ( aChangeType == EDeviceType )
       
   992         {
       
   993         CTsDeviceState::TDeviceType state = iDeviceState.DeviceType();
       
   994         switch ( state )
       
   995             {
       
   996             case CTsDeviceState::EHybrid:
       
   997                 {
       
   998                 iGrid->SetGridBehaviour( CTsFastSwapGrid::EHybrid );
       
   999                 }
       
  1000                 break;
       
  1001             case CTsDeviceState::EFullTouch:
       
  1002                 {
       
  1003                 iGrid->SetGridBehaviour( CTsFastSwapGrid::ETouchOnly );
       
  1004                 }
       
  1005                 break;
       
  1006             default:
       
  1007                 break;
       
  1008             }
       
  1009         }
       
  1010     }
       
  1011 
       
  1012 
       
  1013 // -----------------------------------------------------------------------------
       
  1014 // CTsFastSwapArea::TimerCompletedL
       
  1015 // -----------------------------------------------------------------------------
       
  1016 //
       
  1017 void CTsFastSwapArea::TimerCompletedL( CTsFastSwapTimer* aSource )
       
  1018     {
       
  1019     if(aSource == iHighlightTimer)
       
  1020         {
       
  1021         iTapEvent.iType = TPointerEvent::EButton1Up;
       
  1022         iGrid->HandlePointerEventL(iTapEvent);
       
  1023         }
       
  1024     else if(aSource == iRedrawTimer)
       
  1025         {
       
  1026         DrawNow();
       
  1027         }
       
  1028     else if( aSource == iUpdateGridTimer )
       
  1029         {
       
  1030         UpdateGrid(ETrue, ETrue);
       
  1031         }
       
  1032     }
       
  1033 
       
  1034 
       
  1035 // -----------------------------------------------------------------------------
       
  1036 // CTsFastSwapArea::PreCreatePopupL
       
  1037 // -----------------------------------------------------------------------------
       
  1038 //
       
  1039 void CTsFastSwapArea::PreCreatePopupL()
       
  1040     {
       
  1041     if ( !iPopup )
       
  1042         {
       
  1043         iPopup = CAknStylusPopUpMenu::NewL( this, Rect().iTl );
       
  1044         HBufC* text = StringLoader::LoadLC( R_TS_FSW_CLOSE );
       
  1045         iPopup->AddMenuItemL( *text, EFswCmdClose );
       
  1046         CleanupStack::PopAndDestroy( text );
       
  1047         text = StringLoader::LoadLC( R_TS_FSW_CLOSE_ALL );
       
  1048         iPopup->AddMenuItemL( *text, EFswCmdCloseAll );
       
  1049         CleanupStack::PopAndDestroy( text );
       
  1050         }
       
  1051     }
       
  1052 
       
  1053 // -----------------------------------------------------------------------------
       
  1054 // CTsFastSwapArea::ShowPopupL
       
  1055 // -----------------------------------------------------------------------------
       
  1056 //
       
  1057 TBool CTsFastSwapArea::ShowPopupL( TInt aIndex, const TPoint& aPoint )
       
  1058     {
       
  1059     TBool showPopUp(EFalse);
       
  1060     TBool showPopupItem;
       
  1061     // hide 'close' if app cannot be closed
       
  1062     showPopupItem = CanClose( aIndex );
       
  1063     iPopup->SetItemDimmed( EFswCmdClose, !showPopupItem );
       
  1064     showPopUp = showPopUp || showPopupItem;
       
  1065     // hide 'close all' if there are no applications to close.
       
  1066     showPopupItem = CanCloseAll( aIndex );
       
  1067     iPopup->SetItemDimmed( EFswCmdCloseAll, !showPopupItem );
       
  1068     showPopUp = showPopUp || showPopupItem;
       
  1069 
       
  1070     if(showPopUp)
       
  1071         {
       
  1072         // give feedback
       
  1073         LaunchPopupFeedback();
       
  1074         // save index for later use & show popup
       
  1075         iAppIndexForPopup = aIndex;
       
  1076         iPopup->SetPosition( aPoint, CAknStylusPopUpMenu::EPositionTypeLeftBottom );
       
  1077         iPopup->ShowMenu();
       
  1078         }
       
  1079     return showPopUp;
       
  1080     }
       
  1081 
       
  1082 
       
  1083 // -----------------------------------------------------------------------------
       
  1084 // CTsFastSwapArea::Count
       
  1085 // -----------------------------------------------------------------------------
       
  1086 //
       
  1087 TInt CTsFastSwapArea::Count() const
       
  1088     {
       
  1089     return iArray.Count();
       
  1090     }
       
  1091 
       
  1092 // -----------------------------------------------------------------------------
       
  1093 // CTsFastSwapArea::SetDataChangeObserver
       
  1094 // -----------------------------------------------------------------------------
       
  1095 //
       
  1096 void CTsFastSwapArea::SetDataChangeObserver(
       
  1097         MTsDataChangeObserver* aDcObserver )
       
  1098     {
       
  1099     iDcObserver = aDcObserver;
       
  1100     }
       
  1101 
       
  1102 // -----------------------------------------------------------------------------
       
  1103 // CTsFastSwapArea::NotifyChange
       
  1104 // -----------------------------------------------------------------------------
       
  1105 //
       
  1106 void CTsFastSwapArea::NotifyChange()
       
  1107     {
       
  1108     if ( iDcObserver )
       
  1109         {
       
  1110         iDcObserver->DataChanged( this, Count() );
       
  1111         }
       
  1112     }
       
  1113     
       
  1114 // -----------------------------------------------------------------------------
       
  1115 // CTsFastSwapArea::SwapApplicationOrder
       
  1116 // -----------------------------------------------------------------------------
       
  1117 //
       
  1118 void CTsFastSwapArea::SwapApplicationOrder( 
       
  1119     RPointerArray<CTsFswEntry>& aArray )
       
  1120     {
       
  1121     for ( TInt i = 0; i < aArray.Count(); ++i )
       
  1122         {
       
  1123         if( aArray[i]->AppUid() == KAiUid )
       
  1124             {
       
  1125             CTsFswEntry* homescreenEntry(0);
       
  1126             homescreenEntry = aArray[i];
       
  1127             aArray.Remove(i);
       
  1128             aArray.Insert(homescreenEntry, KAiPosition);
       
  1129             break;
       
  1130             }
       
  1131         }
       
  1132     }
       
  1133     
       
  1134 // -----------------------------------------------------------------------------
       
  1135 // CTsFastSwapArea::PreferredImageSize
       
  1136 // -----------------------------------------------------------------------------
       
  1137 //
       
  1138 TSize CTsFastSwapArea::PreferredImageSize()
       
  1139     {
       
  1140     TAknLayoutRect gridImage;
       
  1141     TRAP_IGNORE(
       
  1142         RArray<TAknLayoutRect> rects;
       
  1143         CleanupClosePushL(rects);
       
  1144         rects.ReserveL(KLayoutItemCount);
       
  1145         GetFastSwapAreaRects(rects);
       
  1146         gridImage = rects[2];
       
  1147         CleanupStack::PopAndDestroy(&rects);
       
  1148         );
       
  1149     return gridImage.Rect().Size();
       
  1150     }
       
  1151     
       
  1152 // -----------------------------------------------------------------------------
       
  1153 // CTsFastSwapArea::GridItemCount
       
  1154 // -----------------------------------------------------------------------------
       
  1155 //
       
  1156 TInt CTsFastSwapArea::GridItemCount()
       
  1157     {
       
  1158     return iGrid->Model()->ItemTextArray()->MdcaCount();
       
  1159     }
       
  1160 
       
  1161 // -----------------------------------------------------------------------------
       
  1162 // CTsFastSwapArea::HandleListBoxEventL
       
  1163 // -----------------------------------------------------------------------------
       
  1164 //
       
  1165 void CTsFastSwapArea::HandleListBoxEventL(CEikListBox* aListBox, TListBoxEvent aEventType)
       
  1166     {
       
  1167     if ( aListBox == iGrid )
       
  1168         {
       
  1169         switch ( aEventType )
       
  1170             {
       
  1171             case EEventEnterKeyPressed:
       
  1172             case EEventItemClicked:
       
  1173                 {
       
  1174                 SwitchToApp(SelectedIndex());
       
  1175                 }
       
  1176                 break;
       
  1177             case EEventPenDownOnItem:
       
  1178                 {
       
  1179                 iGrid->ShowHighlight();
       
  1180                 }
       
  1181                 break;
       
  1182             default:
       
  1183                 break;
       
  1184             }
       
  1185         }
       
  1186     }
       
  1187 
       
  1188 // --------------------------------------------------------------------------
       
  1189 // CTsFastSwapArea::CalculateSizePreserveRatio
       
  1190 // --------------------------------------------------------------------------
       
  1191 //
       
  1192 TSize CTsFastSwapArea::CalculateSizePreserveRatio(
       
  1193         const TSize& aTargetAreaSize,
       
  1194         const TSize& aSourceSize )
       
  1195     {
       
  1196     TSize sz;
       
  1197     if ( aSourceSize.iWidth > aSourceSize.iHeight )
       
  1198         {
       
  1199         sz.iWidth = aTargetAreaSize.iWidth;
       
  1200         TReal ratio = aSourceSize.iWidth / (TReal) aSourceSize.iHeight;
       
  1201         sz.iHeight = sz.iWidth / ratio;
       
  1202         }
       
  1203     else
       
  1204         {
       
  1205         sz.iHeight = aTargetAreaSize.iHeight;
       
  1206         TReal ratio = aSourceSize.iHeight / (TReal) aSourceSize.iWidth;
       
  1207         sz.iWidth = sz.iHeight / ratio;
       
  1208         }
       
  1209     return sz;
       
  1210     }
       
  1211 
       
  1212 // --------------------------------------------------------------------------
       
  1213 // CTsFastSwapArea::SelectNextItem
       
  1214 // --------------------------------------------------------------------------
       
  1215 //
       
  1216 void CTsFastSwapArea::SelectNextItem()
       
  1217     {
       
  1218     iKeyEvent = ETrue;
       
  1219     iGrid->SetTactileFeedbackSupport(EFalse);
       
  1220     TBool forceRedraw(ETrue);
       
  1221     TBool animate(ETrue);
       
  1222     TInt selectedItem = SelectedIndex();
       
  1223     selectedItem++;
       
  1224     if ( selectedItem == GridItemCount() )
       
  1225         {
       
  1226         // Last item is selected, move to first one
       
  1227         selectedItem = 0;
       
  1228         animate = EFalse;
       
  1229         }
       
  1230     iGrid->SetCurrentDataIndex(selectedItem);
       
  1231     UpdateGrid(forceRedraw, animate);
       
  1232     }
       
  1233 
       
  1234 // --------------------------------------------------------------------------
       
  1235 // CTsFastSwapArea::ShowHiglight
       
  1236 // --------------------------------------------------------------------------
       
  1237 //
       
  1238 void CTsFastSwapArea::ShowHighlight()
       
  1239     {
       
  1240     iGrid->ShowHighlight();
       
  1241     UpdateGrid(ETrue, EFalse);
       
  1242     }
       
  1243 
       
  1244 // --------------------------------------------------------------------------
       
  1245 // CTsFastSwapArea::CenterItem
       
  1246 // --------------------------------------------------------------------------
       
  1247 //
       
  1248 void CTsFastSwapArea::CenterItem(TInt aRedrawDelay)
       
  1249     {
       
  1250     if( iMaxItemsOnScreen < GridItemCount() )
       
  1251         {
       
  1252         TInt visibleItem = ViewToVisibleItem( ViewPos() );
       
  1253         if(iKeyEvent)
       
  1254             {
       
  1255             visibleItem = SelectedIndex();
       
  1256             }
       
  1257         if(visibleItem != SelectedIndex())
       
  1258             {
       
  1259             iGrid->SetCurrentDataIndex( visibleItem );
       
  1260             DrawNow();
       
  1261             }
       
  1262         }
       
  1263 
       
  1264     iUpdateGridTimer->Cancel();
       
  1265     iUpdateGridTimer->After(aRedrawDelay);
       
  1266     }
       
  1267 
       
  1268 // --------------------------------------------------------------------------
       
  1269 // CTsFastSwapArea::GridWorldSize
       
  1270 // --------------------------------------------------------------------------
       
  1271 //
       
  1272 TSize CTsFastSwapArea::GridWorldSize()
       
  1273     {
       
  1274     return TSize( GridItemCount() * iGridItemWidth + (GridItemCount() - 1) * iGridItemGap, Rect().Height() );
       
  1275     }
       
  1276 
       
  1277 // --------------------------------------------------------------------------
       
  1278 // CTsFastSwapArea::UpdateGrid
       
  1279 // --------------------------------------------------------------------------
       
  1280 //
       
  1281 void CTsFastSwapArea::UpdateGrid( TBool aForceRedraw, TBool aAnimate )
       
  1282     {
       
  1283     TPoint targetPoint = ItemViewPosition( SelectedIndex() );
       
  1284     if ( aForceRedraw || targetPoint.iX != ViewPos().iX )
       
  1285         {
       
  1286         if ( aAnimate )
       
  1287             {
       
  1288             iEvtHandler.Animate( targetPoint );
       
  1289             }
       
  1290         else
       
  1291             {
       
  1292             MoveOffset(targetPoint);
       
  1293             iEvtHandler.StopAnimation();
       
  1294             }
       
  1295         if ( aForceRedraw )
       
  1296             {
       
  1297             iGrid->DrawNow();
       
  1298             }
       
  1299         }
       
  1300     }
       
  1301 
       
  1302 // --------------------------------------------------------------------------
       
  1303 // CTsFastSwapArea::HandleAppKey
       
  1304 // --------------------------------------------------------------------------
       
  1305 //
       
  1306 void CTsFastSwapArea::HandleAppKey(TInt aType)
       
  1307     {
       
  1308     if( aType == KAppKeyTypeShort )
       
  1309         {
       
  1310         if(iGrid->IsHighlightVisible())
       
  1311             {
       
  1312             SelectNextItem();
       
  1313             }
       
  1314         else
       
  1315             {
       
  1316             ShowHighlight();
       
  1317             }
       
  1318         }
       
  1319     else if( aType == KAppKeyTypeLong )
       
  1320         {
       
  1321         SwitchToApp( SelectedIndex() );
       
  1322         }
       
  1323     }
       
  1324 
       
  1325 // --------------------------------------------------------------------------
       
  1326 // CTsFastSwapArea::MoveOffset
       
  1327 // --------------------------------------------------------------------------
       
  1328 //
       
  1329 void CTsFastSwapArea::MoveOffset(const TPoint& aPoint)
       
  1330     {
       
  1331     TSLOG_CONTEXT( CTsFastSwapArea::MoveOffset, TSLOG_LOCAL );
       
  1332     TSLOG2_IN("Old position x: %d, y:%d", ViewPos().iX, ViewPos().iY);
       
  1333     TSLOG2_IN("New position x: %d, y:%d", aPoint.iX, aPoint.iY);
       
  1334     TSLOG_OUT();
       
  1335     
       
  1336     TInt currentXPos = aPoint.iX;
       
  1337     currentXPos -= Rect().Width() / 2;
       
  1338     TRect gridViewRect = Rect();
       
  1339     gridViewRect.iTl.iX = -currentXPos;
       
  1340     // Take edge offset into account
       
  1341     gridViewRect.iTl.iX += Rect().iTl.iX;
       
  1342     if(GridItemCount() <= iMaxItemsOnScreen)
       
  1343         {
       
  1344         // Center view
       
  1345         gridViewRect.iTl.iX += ( Rect().Width() - GridItemCount() * iGridItemWidth ) / 2;
       
  1346         }
       
  1347     iGrid->SetRect( gridViewRect );
       
  1348     DrawNow();
       
  1349     }
       
  1350 
       
  1351 // --------------------------------------------------------------------------
       
  1352 // CTsFastSwapArea::Tap
       
  1353 // --------------------------------------------------------------------------
       
  1354 //
       
  1355 void CTsFastSwapArea::TapL(const TPoint& aPoint)
       
  1356     {
       
  1357     if(iGrid->Rect().Contains(aPoint))
       
  1358         {
       
  1359         //provide tap pointer event to grid
       
  1360         iGrid->HandlePointerEventL(iTapEvent);
       
  1361         iHighlightTimer->Cancel();
       
  1362         iHighlightTimer->After(KHighlighActivationTime);
       
  1363         }
       
  1364     else
       
  1365         {
       
  1366         //move task switcher to background
       
  1367         iEikonEnv->EikAppUi()->HandleCommandL(EAknSoftkeyExit);
       
  1368         }
       
  1369     }
       
  1370 
       
  1371 // --------------------------------------------------------------------------
       
  1372 // CTsFastSwapArea::LongTap
       
  1373 // --------------------------------------------------------------------------
       
  1374 //
       
  1375 void CTsFastSwapArea::LongTapL(const TPoint& aPoint)
       
  1376     {
       
  1377     TInt index(KErrNotFound);
       
  1378     if( iGrid->GridView()->XYPosToItemIndex(aPoint,index) )
       
  1379         {
       
  1380         iGrid->SetCurrentItemIndex(index);
       
  1381         SaveSelectedIndex();
       
  1382         if ( !ShowPopupL(iSavedSelectedIndex, aPoint) )
       
  1383             {
       
  1384             TapL(aPoint);
       
  1385             }
       
  1386         else
       
  1387             {
       
  1388             iGrid->ShowHighlight();
       
  1389             DrawNow();
       
  1390             }
       
  1391         }
       
  1392     else
       
  1393         {
       
  1394         TapL(aPoint);
       
  1395         }
       
  1396     }
       
  1397 
       
  1398 // --------------------------------------------------------------------------
       
  1399 // CTsFastSwapArea::Drag
       
  1400 // --------------------------------------------------------------------------
       
  1401 //
       
  1402 void CTsFastSwapArea::Drag(
       
  1403     const MAknTouchGestureFwDragEvent& /*aEvent*/)
       
  1404     {
       
  1405     iGrid->SetTactileFeedbackSupport(ETrue);
       
  1406     iGrid->HideHighlight();
       
  1407     CenterItem( KUpdateGridTime );
       
  1408     DrawNow();
       
  1409     }
       
  1410 
       
  1411 // -----------------------------------------------------------------------------
       
  1412 // CTsFastSwapArea::ViewSize
       
  1413 // -----------------------------------------------------------------------------
       
  1414 //
       
  1415 TSize CTsFastSwapArea::ViewSize()
       
  1416     {
       
  1417     return TSize(Rect().Width(), Rect().Height());  
       
  1418     }
       
  1419 
       
  1420 // -----------------------------------------------------------------------------
       
  1421 // CTsFastSwapArea::Stop
       
  1422 // -----------------------------------------------------------------------------
       
  1423 //
       
  1424 void CTsFastSwapArea::Stop()
       
  1425     {    
       
  1426     CenterItem( KUpdateGridTime );
       
  1427     DrawNow();
       
  1428     }
       
  1429 
       
  1430 // -----------------------------------------------------------------------------
       
  1431 // CTsFastSwapArea::ViewSize
       
  1432 // -----------------------------------------------------------------------------
       
  1433 //
       
  1434 TPoint CTsFastSwapArea::ViewPos() const
       
  1435     {
       
  1436     TPoint retVal;
       
  1437     retVal.iY = iGrid->Rect().iTl.iY + Rect().Height() / 2;
       
  1438     retVal.iX = - (iGrid->Rect().iTl.iX - Rect().iTl.iX) + Rect().Width() / 2 ;
       
  1439     TInt gridItemCount = iGrid->Model()->ItemTextArray()->MdcaCount();
       
  1440     if( gridItemCount <= iMaxItemsOnScreen)
       
  1441         {
       
  1442         // View centered
       
  1443         retVal.iX += ( Rect().Width() - gridItemCount * iGridItemWidth ) / 2;
       
  1444         }
       
  1445     return retVal;
       
  1446     }
       
  1447 
       
  1448 // -----------------------------------------------------------------------------
       
  1449 // CTsFastSwapArea::ItemPosition
       
  1450 // -----------------------------------------------------------------------------
       
  1451 //
       
  1452 TPoint CTsFastSwapArea::ItemViewPosition( TInt aItemIdx )
       
  1453     {
       
  1454     TPoint retVal = Rect().iTl;
       
  1455     if ( aItemIdx == 0 )
       
  1456         {
       
  1457         // First item
       
  1458         if( AknLayoutUtils::LayoutMirrored() )
       
  1459             {
       
  1460             if ( GridItemCount() > iMaxItemsOnScreen )
       
  1461                 {
       
  1462                 retVal.iX = GridWorldSize().iWidth - Rect().Width();
       
  1463                 }
       
  1464             else
       
  1465                 {
       
  1466                 retVal.iX = 0;
       
  1467                 }
       
  1468             }
       
  1469         else // normal layout
       
  1470             {
       
  1471             retVal.iX = 0;
       
  1472             }
       
  1473         }
       
  1474     else if ( aItemIdx == GridItemCount() - 1 )
       
  1475         {
       
  1476         // Last item selected
       
  1477         if( AknLayoutUtils::LayoutMirrored() )
       
  1478             {
       
  1479             retVal.iX = 0;
       
  1480             }
       
  1481         else // normal layout
       
  1482             {
       
  1483             if ( GridItemCount() > iMaxItemsOnScreen )
       
  1484                 {
       
  1485                 retVal.iX = GridWorldSize().iWidth - Rect().Width();
       
  1486                 }
       
  1487             else
       
  1488                 {
       
  1489                 retVal.iX = 0;
       
  1490                 }
       
  1491             }
       
  1492         }
       
  1493     else
       
  1494         {
       
  1495         // Middle item
       
  1496         TInt screenMiddleItemOffset = ( Rect().Width() - iGridItemWidth ) / 2;
       
  1497         if( AknLayoutUtils::LayoutMirrored() )
       
  1498             {
       
  1499             retVal.iX = iGridItemWidth * ( GridItemCount() - 1 - aItemIdx ) - screenMiddleItemOffset;
       
  1500             retVal.iX += ( GridItemCount() - 1 - aItemIdx ) * iGridItemGap;
       
  1501             }
       
  1502         else // normal layout
       
  1503             {
       
  1504             retVal.iX = iGridItemWidth * aItemIdx - screenMiddleItemOffset;
       
  1505             retVal.iX += iGridItemGap * aItemIdx;
       
  1506             }
       
  1507         if ( retVal.iX < 0 )
       
  1508             {
       
  1509             retVal.iX = 0;
       
  1510             }
       
  1511         else if ( retVal.iX + Rect().Width() > GridWorldSize().iWidth )
       
  1512             {
       
  1513             retVal.iX = GridWorldSize().iWidth - Rect().Width();
       
  1514             }
       
  1515         }
       
  1516     
       
  1517     // Return middle of the view rectangle
       
  1518     retVal.iX += Rect().Width() / 2;
       
  1519     
       
  1520     return retVal;
       
  1521     }
       
  1522 
       
  1523 // -----------------------------------------------------------------------------
       
  1524 // CTsFastSwapArea::ViewToVisibleItem
       
  1525 // -----------------------------------------------------------------------------
       
  1526 //
       
  1527 TInt CTsFastSwapArea::ViewToVisibleItem( const TPoint aViewPos )
       
  1528     {
       
  1529     TInt retVal(0);
       
  1530     TPoint absViewPos = aViewPos;
       
  1531     absViewPos.iX -= Rect().Width() / 2;
       
  1532     if ( absViewPos.iX < 0 )
       
  1533         {
       
  1534         if ( AknLayoutUtils::LayoutMirrored() )
       
  1535             {
       
  1536             // View crossed left border of grid world rect, last item selected
       
  1537             retVal = GridItemCount() - 1;
       
  1538             }
       
  1539         else // normal layout
       
  1540             {
       
  1541             // View crossed left border of grid world rect, first item selected
       
  1542             retVal = 0;
       
  1543             }
       
  1544         }
       
  1545     else if ( absViewPos.iX + Rect().Width() > GridWorldSize().iWidth )
       
  1546         {
       
  1547         if ( AknLayoutUtils::LayoutMirrored() )
       
  1548             {
       
  1549             // View crossed right border of grid world rect, first item selected
       
  1550             retVal = 0;
       
  1551             }
       
  1552         else // normal layout
       
  1553             {
       
  1554             // View crossed right border of grid world rect, last item selected
       
  1555             retVal = GridItemCount() - 1;
       
  1556             }
       
  1557         }
       
  1558     else
       
  1559         {
       
  1560         TInt offsetCheck = GridWorldSize().iWidth;
       
  1561         // View inside of grid world rect
       
  1562         for ( TInt i = 0 ; i < GridItemCount(); i++ )
       
  1563             {
       
  1564             TInt offset = aViewPos.iX - ItemViewPosition( i ).iX;
       
  1565             if ( Abs( offset ) <= offsetCheck )
       
  1566                 {
       
  1567                 offsetCheck = Abs( offset );
       
  1568                 retVal = i;
       
  1569                 }
       
  1570             else
       
  1571                 {
       
  1572                 break;
       
  1573                 }
       
  1574             }
       
  1575         }
       
  1576     return retVal;
       
  1577     }
       
  1578 
       
  1579 
       
  1580 // -----------------------------------------------------------------------------
       
  1581 // CTsFastSwapArea::LaunchPopupFeedback
       
  1582 // -----------------------------------------------------------------------------
       
  1583 //
       
  1584 void CTsFastSwapArea::LaunchPopupFeedback()
       
  1585     {
       
  1586     if ( AknLayoutUtils::PenEnabled() )
       
  1587         {
       
  1588         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1589         if ( feedback )
       
  1590             {
       
  1591             TTouchLogicalFeedback fbLogicalType = ETouchFeedbackPopUp;
       
  1592             if ( CAknTransitionUtils::TransitionsEnabled(
       
  1593                  AknTransEffect::EComponentTransitionsOff ) )
       
  1594                 {
       
  1595                 fbLogicalType = ETouchFeedbackIncreasingPopUp;
       
  1596                 }
       
  1597             feedback->InstantFeedback( this,
       
  1598                                        fbLogicalType,
       
  1599                                        ETouchFeedbackVibra,
       
  1600                                        TPointerEvent() );
       
  1601             }
       
  1602         }
       
  1603     }
       
  1604 
       
  1605 // End of file