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