uifw/AvKon/src/akntabgrp.cpp
changeset 0 2f259fa3e83a
child 5 aabf2c525e0f
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002-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:  Implementation for tab navigation control.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // SYSTEM INCLUDE FILES
       
    20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    21 #include <uikon/eikdefmacros.h>
       
    22 #endif
       
    23 #include <w32std.h>
       
    24 #include <barsread.h>
       
    25 #include <eikbctrl.h>
       
    26 #include <eiklabel.h>
       
    27 #include <eikimage.h>
       
    28 #include <eikenv.h>
       
    29 #include <AknLayoutDef.h>
       
    30 #include <AknsUtils.h>
       
    31 #include <AknIconUtils.h>
       
    32 #include <AknDef.h>
       
    33 #include <e32std.h>
       
    34 #include <AknStatuspaneUtils.h>
       
    35 #include <layoutmetadata.cdl.h>
       
    36 #include <aknlayoutscalable_avkon.cdl.h>
       
    37 #include <akniconconfig.h>
       
    38 
       
    39 #include <AknTasHook.h>
       
    40 #include <touchfeedback.h>
       
    41 
       
    42 // USER INCLUDE FILES
       
    43 #include "aknappui.h"
       
    44 #include "avkon.hrh"
       
    45 #include "AknNaviObserver.h"
       
    46 #include "AknPanic.h"
       
    47 #include "akntabgrp.h"
       
    48 #include "AknTabObserver.h"
       
    49 #include "aknenv.h"
       
    50 #include "AknBitmapMirrorUtils.h"
       
    51 #include "AknTabGrpGraphics.h"
       
    52 #include "aknnavide.h"
       
    53 #include "AknNaviDecoratorObserver.h"
       
    54 
       
    55 // GLOBAL CONSTANTS
       
    56 
       
    57 const TInt KTabArrayGranularity             = 4;
       
    58 const TInt KAknTabGroupNoTabs               = KErrNotFound;
       
    59 const TInt KTabColorBitmapQueueGranularity  = 2;
       
    60 const TInt KTabColorBitmapActiveColorIndex  = 0;
       
    61 const TInt KTabColorBitmapPassiveColorIndex = 1;
       
    62 
       
    63 /** Maximum number of tabs that can be shown in the tab group at a time. */
       
    64 const TInt KMaxNumberOfVisibleTabs          = 4;
       
    65 
       
    66 /** Maximum number of frames in the tab group animations. */
       
    67 const TInt KMaxAmountOfAnimationEvents      = 80;
       
    68 
       
    69 /** Interval used between the frames in tab group animations. */
       
    70 const TInt KAnimationEventInterval          = 25000; // 40 events/s
       
    71 
       
    72 /** Speed value for the layout switch animation, smaller value is faster. */
       
    73 const TInt KLayoutSwitchAnimationSpeed      = 25;
       
    74 
       
    75 /** Minimum horizontal step size value for the tab cycle animation. */
       
    76 const TInt KMinimumCycleAnimationStepSize   = 3;
       
    77 
       
    78 /** Tolerance used for pointer event position's x-value in tab navigation. */
       
    79 const TInt KDragNavigationTolerance         = 5;
       
    80 
       
    81 //
       
    82 // Extension to CAknTab
       
    83 //
       
    84 
       
    85 NONSHARABLE_CLASS( CAknTabExtension ) : public CBase
       
    86     {
       
    87 public:
       
    88     static CAknTabExtension* NewL();
       
    89     ~CAknTabExtension();
       
    90 
       
    91 private:
       
    92     CAknTabExtension();
       
    93 
       
    94 public:
       
    95 
       
    96     /** Indicates whether or not the tab is shown in narrow tab group layout. */
       
    97     TBool iNarrowTabLayout;
       
    98 
       
    99     /** Total amount of tab in the tab group, needed to decide right layoutlines. */
       
   100     TInt  iNumberOfTabsInTabGroup;
       
   101 
       
   102     /** Indicates whether or not this tab is drawn using multi-color mode. */
       
   103     TBool iMultiColorMode;
       
   104 
       
   105     /** Indicates whether or not the tab is shown in long tab group layout. */
       
   106     TBool iLongTab;
       
   107     };
       
   108 
       
   109 CAknTabExtension* CAknTabExtension::NewL()
       
   110     {
       
   111     CAknTabExtension* self = new ( ELeave ) CAknTabExtension();
       
   112     return self;
       
   113     }
       
   114 
       
   115 
       
   116 CAknTabExtension::CAknTabExtension()
       
   117     {
       
   118     }
       
   119 
       
   120 CAknTabExtension::~CAknTabExtension()
       
   121     {
       
   122     }
       
   123 
       
   124 //
       
   125 // CAknTab
       
   126 //
       
   127 
       
   128 CAknTab::~CAknTab()
       
   129     {
       
   130     AKNTASHOOK_REMOVE();
       
   131     delete iLabel;
       
   132     delete iBitmap;
       
   133     delete iBitmapMask;
       
   134 
       
   135     if ( iColorBitmaps )
       
   136         {
       
   137         iColorBitmaps->ResetAndDestroy();
       
   138         delete iColorBitmaps;
       
   139         iColorBitmaps = NULL;
       
   140         }
       
   141 
       
   142     delete iExtension;
       
   143     }
       
   144 
       
   145 CAknTab* CAknTab::NewL( const CCoeControl& aParent, TResourceReader& aReader )
       
   146     {
       
   147     CAknTab* self = CAknTab::NewLC( aParent, aReader );
       
   148     CleanupStack::Pop( self );
       
   149     return self;
       
   150     }
       
   151 
       
   152 CAknTab* CAknTab::NewLC( const CCoeControl& aParent, TResourceReader& aReader )
       
   153     {
       
   154     CAknTab* self = new (ELeave) CAknTab( 0 ); // default tab id
       
   155     CleanupStack::PushL( self );
       
   156     self->SetContainerWindowL( aParent );
       
   157     self->ConstructFromResourceL( aReader );
       
   158     AKNTASHOOK_ADDL( self, "CAknTab" );
       
   159     return self;
       
   160     }
       
   161 
       
   162 CAknTab* CAknTab::NewL( TInt aId,
       
   163                         const CCoeControl& aParent,
       
   164                         const TDesC& aTabText )
       
   165     {
       
   166     CAknTab* self = CAknTab::NewLC( aId, aParent, aTabText );
       
   167     CleanupStack::Pop( self );
       
   168     return self;
       
   169     }
       
   170 
       
   171 CAknTab* CAknTab::NewLC( TInt aId,
       
   172                          const CCoeControl& aParent,
       
   173                          const TDesC& aTabText )
       
   174     {
       
   175     CAknTab* self = new (ELeave) CAknTab( aId );
       
   176     CleanupStack::PushL( self );
       
   177     self->SetContainerWindowL( aParent );
       
   178     self->ConstructL( aTabText );
       
   179     AKNTASHOOK_ADDL( self, "CAknTab" );
       
   180     return self;
       
   181     }
       
   182 
       
   183 CAknTab* CAknTab::NewL( TInt aId,
       
   184                         const CCoeControl& aParent,
       
   185                         const TDesC& aTabText,
       
   186                         const CFbsBitmap* aTabBitmap,
       
   187                         const CFbsBitmap* aMask )
       
   188     {
       
   189     CAknTab* self = CAknTab::NewLC( aId, aParent, aTabText, aTabBitmap, aMask );
       
   190     CleanupStack::Pop( self );
       
   191     return self;
       
   192     }
       
   193 
       
   194 CAknTab* CAknTab::NewLC( TInt aId,
       
   195                          const CCoeControl& aParent,
       
   196                          const TDesC& aTabText,
       
   197                          const CFbsBitmap* aTabBitmap,
       
   198                          const CFbsBitmap* aMask )
       
   199     {
       
   200     CAknTab* self = new (ELeave) CAknTab( aId );
       
   201     CleanupStack::PushL( self );
       
   202     self->SetContainerWindowL( aParent );
       
   203     self->ConstructL( aTabText );
       
   204     self->ConstructL( aTabBitmap, aMask );
       
   205     AKNTASHOOK_ADDL( self, "CAknTab" );
       
   206     return self;
       
   207     }
       
   208 
       
   209 CAknTab* CAknTab::NewL( TInt aId,
       
   210                         const CCoeControl& aParent,
       
   211                         const CFbsBitmap* aTabBitmap,
       
   212                         const CFbsBitmap* aMask )
       
   213     {
       
   214     CAknTab* self = CAknTab::NewLC( aId, aParent, aTabBitmap, aMask );
       
   215     CleanupStack::Pop( self );
       
   216     return self;
       
   217     }
       
   218 
       
   219 CAknTab* CAknTab::NewLC( TInt aId,
       
   220                          const CCoeControl& aParent,
       
   221                          const CFbsBitmap* aTabBitmap,
       
   222                          const CFbsBitmap* aMask )
       
   223     {
       
   224     CAknTab* self = new (ELeave) CAknTab( aId );
       
   225     CleanupStack::PushL( self );
       
   226     self->SetContainerWindowL( aParent );
       
   227     self->ConstructL( aTabBitmap, aMask );
       
   228     AKNTASHOOK_ADDL( self, "CAknTab" );
       
   229     return self;
       
   230     }
       
   231 
       
   232 CAknTab::CAknTab( TInt aId ) : iId( aId )
       
   233     {
       
   234     }
       
   235 
       
   236 void CAknTab::ConstructFromResourceL( TResourceReader& aReader )
       
   237     {
       
   238     if ( !iExtension )
       
   239         {
       
   240         iExtension = CAknTabExtension::NewL();
       
   241         }
       
   242 
       
   243     iId = aReader.ReadInt16(); // tab id
       
   244 
       
   245     HBufC* txt = aReader.ReadHBufCL(); // tab text
       
   246     if ( txt )
       
   247         {
       
   248         CleanupStack::PushL( txt );
       
   249         ConstructL( *txt );
       
   250         CleanupStack::PopAndDestroy( txt );
       
   251         }
       
   252 
       
   253     HBufC* bitmapFile = aReader.ReadHBufCL(); // bmp filename
       
   254     TInt bitmapId     = aReader.ReadInt16();  // bmp id
       
   255     TInt maskId       = aReader.ReadInt16();  // bmp mask id
       
   256 
       
   257     if ( bitmapFile )
       
   258         {
       
   259         CleanupStack::PushL( bitmapFile );
       
   260         TFileName fileName( *bitmapFile );
       
   261         CompleteWithAppPath( fileName );
       
   262         if ( bitmapId != KErrNotFound )
       
   263             {
       
   264             CFbsBitmap* bitmap;
       
   265             if ( maskId != KErrNotFound )
       
   266                 {
       
   267                 CFbsBitmap* mask;
       
   268                 AknIconUtils::CreateIconLC( bitmap,
       
   269                                             mask,
       
   270                                             fileName,
       
   271                                             bitmapId,
       
   272                                             maskId );
       
   273                 CleanupStack::Pop( mask );
       
   274                 CleanupStack::Pop( bitmap );
       
   275                 // moves ownership of bitmap and mask at beginning =>
       
   276                 // no need to have bitmap/mask in cleanupstack
       
   277                 ConstructL( bitmap, mask );
       
   278                 }
       
   279             else
       
   280                 {
       
   281                 bitmap = AknIconUtils::CreateIconL( fileName, bitmapId );
       
   282                 // moves ownership of bitmap and mask at beginning =>
       
   283                 // no need to have bitmap/mask in cleanupstack
       
   284                 ConstructL( bitmap );
       
   285                 }
       
   286             }
       
   287         CleanupStack::PopAndDestroy( bitmapFile );  // bitmapFile
       
   288         }
       
   289 
       
   290     LoadColorBitmapL();
       
   291     }
       
   292 
       
   293 void CAknTab::ConstructL( const TDesC& aTabText )
       
   294     {
       
   295     if ( !iExtension )
       
   296         {
       
   297         iExtension = CAknTabExtension::NewL();
       
   298         }
       
   299 
       
   300     iLabel = new (ELeave) CEikLabel;
       
   301     iLabel->SetContainerWindowL( *this );
       
   302     iLabel->SetTextL( aTabText );
       
   303     iLabel->SetAlignment( EHCenterVCenter );
       
   304     iLabel->SetAllMarginsTo( KNaviTabMargins );
       
   305 
       
   306     if ( AknLayoutUtils::Variant() == EEuropeanVariant )
       
   307         {
       
   308         iLabel->SetFont( LatinBold12() );
       
   309         }
       
   310     else    // APAC
       
   311         {
       
   312         iLabel->SetFont( ApacPlain12() );
       
   313         }
       
   314 
       
   315     LoadColorBitmapL();
       
   316     }
       
   317 
       
   318 void CAknTab::ConstructL( const CFbsBitmap* aTabBitmap,
       
   319                           const CFbsBitmap* aMask )
       
   320     {
       
   321     if ( !iExtension )
       
   322         {
       
   323         iExtension = CAknTabExtension::NewL();
       
   324         }
       
   325 
       
   326     iBitmap = aTabBitmap;
       
   327     iBitmapMask = aMask;
       
   328     LoadColorBitmapL();
       
   329     }
       
   330 
       
   331 void CAknTab::ReplaceTextL( const TDesC& aTabText )
       
   332     {
       
   333     if ( iLabel )
       
   334         {
       
   335         iLabel->SetTextL( aTabText );
       
   336         }
       
   337     }
       
   338 
       
   339 void CAknTab::SetActive( TBool aActive, TDrawNow aDrawNow )
       
   340     {
       
   341     iActive = aActive;
       
   342 
       
   343     if ( aDrawNow == EDrawNow )
       
   344         {
       
   345         DrawNow();
       
   346         }
       
   347     }
       
   348 
       
   349 TBool CAknTab::Active() const
       
   350     {
       
   351     return iActive;
       
   352     }
       
   353 
       
   354 
       
   355 TInt CAknTab::Id() const
       
   356     {
       
   357     return iId;
       
   358     }
       
   359 
       
   360 
       
   361 enum CAknTab::TAknTabDataType CAknTab::TabType() const
       
   362     {
       
   363     TAknTabDataType tabType( EAknTabNone );
       
   364 
       
   365     if ( iLabel && iBitmap )
       
   366         {
       
   367         tabType = EAknTabTextAndIcon;
       
   368         }
       
   369     else if ( iBitmap )
       
   370         {
       
   371         tabType = EAknTabIcon;
       
   372         }
       
   373     else if ( iLabel )
       
   374         {
       
   375         tabType = EAknTabText;
       
   376         }
       
   377 
       
   378     return tabType;
       
   379     }
       
   380 
       
   381 
       
   382 TSize CAknTab::MinimumSize()
       
   383     {
       
   384     TSize minSize;
       
   385 
       
   386     if ( iLabel )
       
   387         {
       
   388         minSize += iLabel->MinimumSize();
       
   389         }
       
   390     if ( iBitmap )
       
   391         {
       
   392         minSize += iBitmap->SizeInPixels();
       
   393         }
       
   394 
       
   395     return minSize;
       
   396     }
       
   397 
       
   398 
       
   399 void CAknTab::SetDimmed( TBool aDimmed )
       
   400     {
       
   401     CCoeControl::SetDimmed( aDimmed );
       
   402 
       
   403     if ( iLabel )
       
   404         {
       
   405         iLabel->SetDimmed( aDimmed );
       
   406         }
       
   407     }
       
   408 
       
   409 
       
   410 void CAknTab::GetColorUseListL( CArrayFix<TCoeColorUse>& aColorUseList ) const
       
   411     {
       
   412     TCoeColorUse colorUse;
       
   413     colorUse.SetLogicalColor( EColorDialogBackground );
       
   414     colorUse.SetUse( TCoeColorUse::EBack |
       
   415                      TCoeColorUse::ESurrounds |
       
   416                      TCoeColorUse::EActive |
       
   417                      TCoeColorUse::ENormal |
       
   418                      TCoeColorUse::ENeutral );
       
   419     aColorUseList.AppendL( colorUse );
       
   420     }
       
   421 
       
   422 
       
   423 void CAknTab::SizeChanged()
       
   424     {
       
   425     if ( AknStatuspaneUtils::FlatLayoutActive() &&
       
   426          !iExtension->iNarrowTabLayout )
       
   427         {
       
   428         SizeChangedInFlatLayout();
       
   429         }
       
   430     else if ( iExtension->iNarrowTabLayout )
       
   431         {
       
   432         SizeChangedInNarrowLayout();
       
   433         }
       
   434     else
       
   435         {
       
   436         SizeChangedInNormalLayout();
       
   437         }
       
   438     }
       
   439 
       
   440 
       
   441 void CAknTab::SizeChangedInNormalLayout()
       
   442     {
       
   443     if ( !iColorBitmaps )
       
   444         {
       
   445         TRAP_IGNORE( LoadColorBitmapL() );
       
   446         }
       
   447 
       
   448     TBool landscape( Layout_Meta_Data::IsLandscapeOrientation() );
       
   449     TBool staconPaneActive( AknStatuspaneUtils::StaconPaneActive() );
       
   450     TBool longTab( iExtension && iExtension->iLongTab );
       
   451     TRect rect( Rect() );
       
   452 
       
   453     if ( iLabel && iBitmap )
       
   454         {
       
   455         iBitmapRect.LayoutRect(
       
   456             rect,
       
   457             AknLayoutScalable_Avkon::navi_navi_icon_text_pane_g1() );
       
   458         AknIconUtils::SetSize( const_cast<CFbsBitmap*> ( iBitmap ),
       
   459                                iBitmapRect.Rect().Size() );
       
   460 
       
   461         AknLayoutUtils::LayoutLabel(
       
   462             iLabel,
       
   463             rect,
       
   464             AknLayoutScalable_Avkon::navi_navi_icon_text_pane_t1() );
       
   465 
       
   466         iLabel->CropText();
       
   467         }
       
   468     else
       
   469         {
       
   470         if ( iLabel )
       
   471             {
       
   472             TAknTextComponentLayout textLayout;
       
   473 
       
   474             switch ( iExtension->iNumberOfTabsInTabGroup )
       
   475                 {
       
   476                 case 1:
       
   477                     {
       
   478                     textLayout =
       
   479                         AknLayoutScalable_Avkon::tabs_2_long_active_pane_t1(
       
   480                             landscape );
       
   481                     break;
       
   482                     }
       
   483 
       
   484                 case 2:
       
   485                     {
       
   486                     if ( longTab )
       
   487                         {
       
   488                         textLayout =
       
   489                             AknLayoutScalable_Avkon::tabs_2_long_active_pane_t1(
       
   490                                 landscape );
       
   491                         }
       
   492                     else
       
   493                         {
       
   494                         if ( iActive )
       
   495                             {
       
   496                             textLayout =
       
   497                                 AknLayoutScalable_Avkon::tabs_2_active_pane_t1(
       
   498                                     landscape );
       
   499                             }
       
   500                         else
       
   501                             {
       
   502                             textLayout =
       
   503                                 AknLayoutScalable_Avkon::tabs_2_passive_pane_t1(
       
   504                                     landscape );
       
   505                             }
       
   506                         }
       
   507                     break;
       
   508                     }
       
   509 
       
   510                 case 3:
       
   511                     {
       
   512                     if ( longTab )
       
   513                         {
       
   514                         textLayout =
       
   515                             AknLayoutScalable_Avkon::tabs_3_long_active_pane_t1(
       
   516                                 landscape );
       
   517                         }
       
   518                     else
       
   519                         {
       
   520                         if ( iActive )
       
   521                             {
       
   522                             textLayout =
       
   523                                 AknLayoutScalable_Avkon::tabs_3_active_pane_t1(
       
   524                                     landscape );
       
   525                             }
       
   526                         else
       
   527                             {
       
   528                             textLayout =
       
   529                                 AknLayoutScalable_Avkon::tabs_3_passive_pane_t1(
       
   530                                     landscape );
       
   531                             }
       
   532                         }
       
   533                     break;
       
   534                     }
       
   535 
       
   536                 case 4:
       
   537                 default:
       
   538                     {
       
   539                     textLayout =
       
   540                         AknLayoutScalable_Avkon::tabs_4_active_pane_t1(
       
   541                             landscape );
       
   542                     break;
       
   543                     }
       
   544                 }
       
   545 
       
   546             AknLayoutUtils::LayoutLabel( iLabel, rect, textLayout );
       
   547 
       
   548             iLabel->CropText();
       
   549             }
       
   550 
       
   551         if ( iBitmap )
       
   552             {
       
   553             TAknWindowComponentLayout l1( TAknWindowComponentLayout::Compose(
       
   554                 AknLayoutScalable_Avkon::navi_tabs_2_pane(),
       
   555                 TAknWindowComponentLayout::Compose(
       
   556                     AknLayoutScalable_Avkon::tabs_2_active_pane( 0 ),
       
   557                     AknLayoutScalable_Avkon::tabs_2_active_pane_g1() ) ) );
       
   558 
       
   559             TAknWindowComponentLayout l2( TAknWindowComponentLayout::Compose(
       
   560                 AknLayoutScalable_Avkon::navi_tabs_3_pane(),
       
   561                 TAknWindowComponentLayout::Compose(
       
   562                     AknLayoutScalable_Avkon::tabs_3_active_pane( 0 ),
       
   563                     AknLayoutScalable_Avkon::tabs_3_active_pane_g1() ) ) );
       
   564 
       
   565             TAknWindowComponentLayout l3( TAknWindowComponentLayout::Compose(
       
   566                 AknLayoutScalable_Avkon::navi_tabs_4_pane(),
       
   567                 TAknWindowComponentLayout::Compose(
       
   568                     AknLayoutScalable_Avkon::tabs_4_active_pane( 0 ),
       
   569                     AknLayoutScalable_Avkon::tabs_4_active_pane_g1() ) ) );
       
   570 
       
   571             TAknLayoutRect layoutRect;
       
   572 
       
   573             layoutRect.LayoutRect( rect, l1 );
       
   574             TRect r1( layoutRect.Rect() );
       
   575             layoutRect.LayoutRect( rect, l2 );
       
   576             TRect r2( layoutRect.Rect() );
       
   577             layoutRect.LayoutRect( rect, l3 );
       
   578             TRect r3( layoutRect.Rect() );
       
   579 
       
   580             TInt w = rect.Size().iWidth;
       
   581             TSize size;
       
   582 
       
   583             if ( w < r2.Width() ) // smaller than 3 icon layout - use 4 icon layout
       
   584                 {
       
   585                 size.iWidth = r3.Width();
       
   586                 size.iHeight = r3.Height();
       
   587                 }
       
   588             else if ( w >= r2.Width() && w < r1.Width() )  // use 3 icon layout
       
   589                 {
       
   590                 size.iWidth = r2.Width();
       
   591                 size.iHeight = r2.Height();
       
   592                 }
       
   593             else // same or larger than 2 icon layout - use 2 icon layout
       
   594                 {
       
   595                 size.iWidth = r1.Width();
       
   596                 size.iHeight = r1.Height();
       
   597                 }
       
   598 
       
   599             AknIconUtils::SetSize( const_cast<CFbsBitmap*> (iBitmap), size );
       
   600 
       
   601             TInt imageWidth  = iBitmap->SizeInPixels().iWidth;
       
   602             TInt imageXPos   = rect.Width() - imageWidth;
       
   603             TInt imageHeight = iBitmap->SizeInPixels().iHeight;
       
   604             TInt imageYPos   = rect.Height() - imageHeight;
       
   605 
       
   606             TRect nRect( 0,0, rect.Width(), rect.Height() );
       
   607 
       
   608             if ( imageXPos < 0 || imageYPos < 0 )
       
   609                 {
       
   610                 iBitmapRect.LayoutRect( nRect,
       
   611                                         ELayoutEmpty,
       
   612                                         rect.iTl.iX,
       
   613                                         rect.iTl.iY,
       
   614                                         ELayoutEmpty,
       
   615                                         ELayoutEmpty,
       
   616                                         rect.Width(),
       
   617                                         rect.Height());
       
   618                 }
       
   619             else
       
   620                 {
       
   621                 // Center image.
       
   622                 imageXPos  = imageXPos >> 1;
       
   623                 imageXPos += rect.iTl.iX;
       
   624                 imageYPos  = imageYPos >> 1;
       
   625                 imageYPos += rect.iTl.iY;
       
   626 
       
   627                 iBitmapRect.LayoutRect( nRect,
       
   628                                         ELayoutEmpty,
       
   629                                         imageXPos,
       
   630                                         imageYPos,
       
   631                                         ELayoutEmpty,
       
   632                                         ELayoutEmpty,
       
   633                                         imageWidth,
       
   634                                         imageHeight );
       
   635                 }
       
   636             }
       
   637         }
       
   638     }
       
   639 
       
   640 
       
   641 void CAknTab::SizeChangedInNarrowLayout()
       
   642     {
       
   643     if ( !iColorBitmaps )
       
   644         {
       
   645         TRAP_IGNORE( LoadColorBitmapL() );
       
   646         }
       
   647 
       
   648     TBool isStaconPaneActive( AknStatuspaneUtils::StaconPaneActive() );
       
   649     TBool longTab( iExtension && iExtension->iLongTab );
       
   650 
       
   651     TRect rect( Rect() );
       
   652 
       
   653     if ( iLabel && iBitmap )
       
   654         {
       
   655         iBitmapRect.LayoutRect(
       
   656             rect,
       
   657             AknLayoutScalable_Avkon::navi_navi_icon_text_pane_srt_g1() );
       
   658         AknIconUtils::SetSize( const_cast<CFbsBitmap*> ( iBitmap ),
       
   659                                iBitmapRect.Rect().Size() );
       
   660         AknLayoutUtils::LayoutLabel(
       
   661             iLabel,
       
   662             rect,
       
   663             AknLayoutScalable_Avkon::navi_navi_icon_text_pane_srt_t1( 0 ) );
       
   664 
       
   665         iLabel->CropText();
       
   666         }
       
   667     else
       
   668         {
       
   669         if ( iLabel )
       
   670             {
       
   671             TAknTextComponentLayout textLayout;
       
   672 
       
   673             switch ( iExtension->iNumberOfTabsInTabGroup )
       
   674                 {
       
   675                 case 1:
       
   676                     {
       
   677                     textLayout =
       
   678                         AknLayoutScalable_Avkon::tabs_2_long_active_pane_t1(
       
   679                             isStaconPaneActive );
       
   680                     break;
       
   681                     }
       
   682 
       
   683                 case 2:
       
   684                     {
       
   685                     if ( longTab )
       
   686                         {
       
   687                         textLayout =
       
   688                             AknLayoutScalable_Avkon::tabs_2_long_active_pane_srt_t1(
       
   689                                 isStaconPaneActive );
       
   690                         }
       
   691                     else
       
   692                         {
       
   693                         textLayout =
       
   694                             AknLayoutScalable_Avkon::tabs_2_active_pane_srt_t1(
       
   695                                 isStaconPaneActive );
       
   696                         }
       
   697                     break;
       
   698                     }
       
   699 
       
   700                 case 3:
       
   701                     {
       
   702                     if ( longTab )
       
   703                         {
       
   704                         textLayout =
       
   705                             AknLayoutScalable_Avkon::tabs_3_long_active_pane_srt_t1(
       
   706                                 isStaconPaneActive );
       
   707                         }
       
   708                     else
       
   709                         {
       
   710                         textLayout =
       
   711                             AknLayoutScalable_Avkon::tabs_3_active_pane_srt_t1(
       
   712                                 isStaconPaneActive );
       
   713                         }
       
   714                     break;
       
   715                     }
       
   716 
       
   717                 case 4:
       
   718                 default:
       
   719                     {
       
   720                     textLayout =
       
   721                         AknLayoutScalable_Avkon::tabs_4_active_pane_srt_t1(
       
   722                             isStaconPaneActive );
       
   723                     break;
       
   724                     }
       
   725                 }
       
   726 
       
   727             AknLayoutUtils::LayoutLabel( iLabel, rect, textLayout );
       
   728 
       
   729             iLabel->CropText();
       
   730             }
       
   731 
       
   732         if ( iBitmap )
       
   733             {
       
   734             TAknWindowComponentLayout l1(
       
   735                 AknLayoutScalable_Avkon::tabs_2_active_pane_srt_g1() );
       
   736             TAknWindowComponentLayout l2(
       
   737                 AknLayoutScalable_Avkon::tabs_3_active_pane_srt_g1() );
       
   738             TAknWindowComponentLayout l3(
       
   739                 AknLayoutScalable_Avkon::tabs_4_active_pane_srt_g1() );
       
   740 
       
   741             TAknLayoutRect layoutRect;
       
   742 
       
   743             layoutRect.LayoutRect( rect, l1 );
       
   744             TRect r1 = layoutRect.Rect();
       
   745             layoutRect.LayoutRect( rect, l2 );
       
   746             TRect r2 = layoutRect.Rect();
       
   747             layoutRect.LayoutRect( rect, l3 );
       
   748             TRect r3 = layoutRect.Rect();
       
   749 
       
   750             TInt w = rect.Size().iWidth;
       
   751             TSize size;
       
   752 
       
   753             if ( w < r2.Width() )  // smaller than 3 icon layout - use 4 icon layout
       
   754                 {
       
   755                 size.iWidth = r3.Width();
       
   756                 size.iHeight = r3.Height();
       
   757                 }
       
   758             else if ( w >= r2.Width() && w < r1.Width() )  // use 3 icon layout
       
   759                 {
       
   760                 size.iWidth = r2.Width();
       
   761                 size.iHeight = r2.Height();
       
   762                 }
       
   763             else // same or larger than 2 icon layout - use 2 icon layout
       
   764                 {
       
   765                 size.iWidth = r1.Width();
       
   766                 size.iHeight = r1.Height();
       
   767                 }
       
   768 
       
   769             AknIconUtils::SetSize( const_cast<CFbsBitmap*> (iBitmap), size );
       
   770 
       
   771             TInt imageWidth  = iBitmap->SizeInPixels().iWidth;
       
   772             TInt imageXPos   = rect.Width() - imageWidth;
       
   773             TInt imageHeight =  iBitmap->SizeInPixels().iHeight;
       
   774             TInt imageYPos   = rect.Height() - imageHeight;
       
   775 
       
   776             TRect nRect( 0,0, rect.Width(), rect.Height() );
       
   777 
       
   778             if ( imageXPos < 0 || imageYPos < 0 )
       
   779                 {
       
   780                 iBitmapRect.LayoutRect( nRect,
       
   781                                         ELayoutEmpty,
       
   782                                         rect.iTl.iX,
       
   783                                         rect.iTl.iY,
       
   784                                         ELayoutEmpty,
       
   785                                         ELayoutEmpty,
       
   786                                         rect.Width(),
       
   787                                         rect.Height() );
       
   788                 }
       
   789             else
       
   790                 {
       
   791                 // Center image.
       
   792                 imageXPos  = imageXPos >> 1;
       
   793                 imageXPos += rect.iTl.iX;
       
   794                 imageYPos  = imageYPos >> 1;
       
   795                 imageYPos += rect.iTl.iY;
       
   796                 iBitmapRect.LayoutRect( nRect,
       
   797                                         ELayoutEmpty,
       
   798                                         imageXPos,
       
   799                                         imageYPos,
       
   800                                         ELayoutEmpty,
       
   801                                         ELayoutEmpty,
       
   802                                         imageWidth,
       
   803                                         imageHeight );
       
   804                 }
       
   805             }
       
   806         }
       
   807 
       
   808     }
       
   809 
       
   810 
       
   811 // ---------------------------------------------------------------------------
       
   812 // Handles size change events in flat status pane layouts.
       
   813 // ---------------------------------------------------------------------------
       
   814 //
       
   815 void CAknTab::SizeChangedInFlatLayout()
       
   816     {
       
   817     if ( !iColorBitmaps )
       
   818         {
       
   819         TRAP_IGNORE( LoadColorBitmapL() );
       
   820         }
       
   821 
       
   822     TBool longTab( iExtension && iExtension->iLongTab );
       
   823 
       
   824     TRect rect( Rect() );
       
   825 
       
   826     if ( iLabel && iBitmap )
       
   827         {
       
   828         iBitmapRect.LayoutRect( rect, AknLayoutScalable_Avkon::navi_navi_icon_text_pane_g1() );
       
   829 
       
   830         AknIconUtils::SetSize( const_cast<CFbsBitmap*> ( iBitmap ),
       
   831                                iBitmapRect.Rect().Size() );
       
   832 
       
   833         AknLayoutUtils::LayoutLabel(
       
   834             iLabel,
       
   835             rect,
       
   836             AknLayoutScalable_Avkon::navi_navi_icon_text_pane_t1() );
       
   837 
       
   838         iLabel->CropText();
       
   839         }
       
   840     else
       
   841         {
       
   842         if ( iLabel )
       
   843             {
       
   844             TAknTextComponentLayout textLayout;
       
   845 
       
   846             switch ( iExtension->iNumberOfTabsInTabGroup )
       
   847                 {
       
   848                 case 1:
       
   849                     {
       
   850                     textLayout =
       
   851                         AknLayoutScalable_Avkon::tabs_2_long_active_pane_t1( 0 );
       
   852                     break;
       
   853                     }
       
   854 
       
   855                 case 2:
       
   856                     {
       
   857                     if ( longTab )
       
   858                         {
       
   859                         textLayout =
       
   860                             AknLayoutScalable_Avkon::tabs_2_long_active_pane_t1( 0 );
       
   861                         }
       
   862                     else
       
   863                         {
       
   864                         if ( iActive )
       
   865                             {
       
   866                             textLayout =
       
   867                                 AknLayoutScalable_Avkon::tabs_2_active_pane_t1( 0 );
       
   868                             }
       
   869                         else
       
   870                             {
       
   871                             textLayout =
       
   872                                 AknLayoutScalable_Avkon::tabs_2_passive_pane_t1( 0 );
       
   873                             }
       
   874                         }
       
   875                     break;
       
   876                     }
       
   877 
       
   878                 case 3:
       
   879                     {
       
   880                     if ( longTab )
       
   881                         {
       
   882                         textLayout =
       
   883                             AknLayoutScalable_Avkon::tabs_3_long_active_pane_t1( 0 );
       
   884                         }
       
   885                     else
       
   886                         {
       
   887                         if ( iActive )
       
   888                             {
       
   889                             textLayout =
       
   890                                 AknLayoutScalable_Avkon::tabs_3_active_pane_t1( 0 );
       
   891                             }
       
   892                         else
       
   893                             {
       
   894                             textLayout =
       
   895                                 AknLayoutScalable_Avkon::tabs_3_passive_pane_t1( 0 );
       
   896                             }
       
   897                         }
       
   898                     break;
       
   899                     }
       
   900 
       
   901                 case 4:
       
   902                 default:
       
   903                     {
       
   904                     textLayout =
       
   905                         AknLayoutScalable_Avkon::tabs_4_active_pane_t1( 0 );
       
   906                     break;
       
   907                     }
       
   908                 }
       
   909 
       
   910             AknLayoutUtils::LayoutLabel( iLabel, rect, textLayout );
       
   911 
       
   912             iLabel->CropText();
       
   913             }
       
   914 
       
   915         if ( iBitmap )
       
   916             {
       
   917             TAknWindowComponentLayout l1(
       
   918                 AknLayoutScalable_Avkon::tabs_2_active_pane_g1() );
       
   919             TAknWindowComponentLayout l2(
       
   920                 AknLayoutScalable_Avkon::tabs_3_active_pane_g1() );
       
   921             TAknWindowComponentLayout l3(
       
   922                 AknLayoutScalable_Avkon::tabs_4_active_pane_g1() );
       
   923 
       
   924             TAknLayoutRect layoutRect;
       
   925 
       
   926             layoutRect.LayoutRect( rect, l1 );
       
   927             TRect r1 = layoutRect.Rect();
       
   928             layoutRect.LayoutRect( rect, l2 );
       
   929             TRect r2 = layoutRect.Rect();
       
   930             layoutRect.LayoutRect( rect, l3 );
       
   931             TRect r3 = layoutRect.Rect();
       
   932 
       
   933             TInt w = rect.Size().iWidth;
       
   934             TSize size;
       
   935 
       
   936             if ( w < r2.Width() )  // smaller than 3 icon layout - use 4 icon layout
       
   937                 {
       
   938                 size.iWidth = r3.Width();
       
   939                 size.iHeight = r3.Height();
       
   940                 }
       
   941             else if ( w >= r2.Width() && w < r1.Width() )  // use 3 icon layout
       
   942                 {
       
   943                 size.iWidth = r2.Width();
       
   944                 size.iHeight = r2.Height();
       
   945                 }
       
   946             else // same or larger than 2 icon layout - use 2 icon layout
       
   947                 {
       
   948                 size.iWidth = r1.Width();
       
   949                 size.iHeight = r1.Height();
       
   950                 }
       
   951 
       
   952             AknIconUtils::SetSize( const_cast<CFbsBitmap*> (iBitmap), size );
       
   953 
       
   954             TInt imageWidth  = iBitmap->SizeInPixels().iWidth;
       
   955             TInt imageXPos   = rect.Width() - imageWidth;
       
   956             TInt imageHeight =  iBitmap->SizeInPixels().iHeight;
       
   957             TInt imageYPos   = rect.Height() - imageHeight;
       
   958 
       
   959             TRect nRect( 0,0, rect.Width(), rect.Height() );
       
   960 
       
   961             if ( imageXPos < 0 || imageYPos < 0 )
       
   962                 {
       
   963                 iBitmapRect.LayoutRect( nRect,
       
   964                                         ELayoutEmpty,
       
   965                                         rect.iTl.iX,
       
   966                                         rect.iTl.iY,
       
   967                                         ELayoutEmpty,
       
   968                                         ELayoutEmpty,
       
   969                                         rect.Width(),
       
   970                                         rect.Height() );
       
   971                 }
       
   972             else
       
   973                 {
       
   974                 // Center image.
       
   975                 imageXPos  = imageXPos >> 1;
       
   976                 imageXPos += rect.iTl.iX;
       
   977                 imageYPos  = imageYPos >> 1;
       
   978                 imageYPos += rect.iTl.iY;
       
   979                 iBitmapRect.LayoutRect( nRect,
       
   980                                         ELayoutEmpty,
       
   981                                         imageXPos,
       
   982                                         imageYPos,
       
   983                                         ELayoutEmpty,
       
   984                                         ELayoutEmpty,
       
   985                                         imageWidth,
       
   986                                         imageHeight );
       
   987                 }
       
   988             }
       
   989         }
       
   990     }
       
   991 
       
   992 
       
   993 // ---------------------------------------------------------------------------
       
   994 // Returns the amount of component controls.
       
   995 // ---------------------------------------------------------------------------
       
   996 //
       
   997 TInt CAknTab::CountComponentControls() const
       
   998     {
       
   999     TInt count( 0 );
       
  1000 
       
  1001     if ( iLabel )
       
  1002         {
       
  1003         count++;
       
  1004         }
       
  1005 
       
  1006     return count;
       
  1007     }
       
  1008 
       
  1009 
       
  1010 CCoeControl* CAknTab::ComponentControl( TInt /*aIndex*/ ) const
       
  1011     {
       
  1012     return iLabel;
       
  1013     }
       
  1014 
       
  1015 void CAknTab::Draw( const TRect& /*aRect*/ ) const
       
  1016     {
       
  1017     if ( iLabel )
       
  1018         {
       
  1019         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1020         TRgb color;
       
  1021 
       
  1022 
       
  1023         if ( iExtension->iNumberOfTabsInTabGroup == 1 ) // >= EAknTabWidthWithOneTab
       
  1024             {
       
  1025             TInt error = AknsUtils::GetCachedColor( skin, color,
       
  1026                 KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG2 );
       
  1027             if ( !error )
       
  1028                 {
       
  1029                 // Ignore error
       
  1030                 TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( *iLabel,
       
  1031                     EColorLabelText, color ) );
       
  1032                 }
       
  1033             }
       
  1034         else
       
  1035             {
       
  1036             if ( iActive )
       
  1037                 {
       
  1038                 TInt error = AknsUtils::GetCachedColor( skin, color,
       
  1039                     KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG3 );
       
  1040                 if ( !error )
       
  1041                     {
       
  1042                     // Ignore error
       
  1043                     TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( *iLabel,
       
  1044                         EColorLabelText, color ) );
       
  1045                     }
       
  1046                 }
       
  1047             else
       
  1048                 {
       
  1049                 TInt error = AknsUtils::GetCachedColor( skin, color,
       
  1050                     KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG4 );
       
  1051                 if ( !error )
       
  1052                     {
       
  1053                     // Ignore error
       
  1054                     TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL( *iLabel,
       
  1055                         EColorLabelText, color ) );
       
  1056                     }
       
  1057                 }
       
  1058             }
       
  1059 
       
  1060         }
       
  1061 
       
  1062     if ( iBitmap )
       
  1063         {
       
  1064         TBool legacyDraw = EFalse;
       
  1065         CWindowGc& gc=SystemGc();
       
  1066         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1067         if ( skin && !iExtension->iMultiColorMode )
       
  1068             {
       
  1069             CFbsBitmap* colorBitmap = NULL;
       
  1070             if (iColorBitmaps &&
       
  1071                 iColorBitmaps->At(KTabColorBitmapActiveColorIndex) &&
       
  1072                 iColorBitmaps->At(KTabColorBitmapPassiveColorIndex) )
       
  1073                 {
       
  1074                 if( iActive )
       
  1075                     {
       
  1076                     colorBitmap = iColorBitmaps->At(KTabColorBitmapActiveColorIndex);
       
  1077                     }
       
  1078                 else
       
  1079                     {
       
  1080                     colorBitmap = iColorBitmaps->At(KTabColorBitmapPassiveColorIndex);
       
  1081                     }
       
  1082                 }
       
  1083 
       
  1084             if ( colorBitmap && iBitmapMask )
       
  1085                 {
       
  1086                 iBitmapRect.DrawImage( gc,
       
  1087                                        colorBitmap,
       
  1088                                        const_cast<CFbsBitmap*> ( iBitmapMask ) );
       
  1089                 }
       
  1090             else
       
  1091                 {
       
  1092                 legacyDraw = ETrue;
       
  1093                 }
       
  1094             }
       
  1095         else // No skin (legacy drawing) or multi-colored drawing.
       
  1096             {
       
  1097             legacyDraw = ETrue;
       
  1098             }
       
  1099         if ( legacyDraw )
       
  1100             {
       
  1101             iBitmapRect.DrawImage( gc,
       
  1102                                    const_cast<CFbsBitmap*>( iBitmap ),
       
  1103                                    const_cast<CFbsBitmap*>( iBitmapMask ) );
       
  1104             }
       
  1105         }
       
  1106     }
       
  1107 
       
  1108 void CAknTab::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
  1109     {
       
  1110     if ( aPointerEvent.iType==TPointerEvent::EButton1Down &&
       
  1111          !iActive &&
       
  1112          !IsDimmed() )
       
  1113         {
       
  1114         ReportEventL( MCoeControlObserver::EEventStateChanged );
       
  1115         }
       
  1116     }
       
  1117 
       
  1118 EXPORT_C void* CAknTab::ExtensionInterface( TUid /*aInterface*/ )
       
  1119     {
       
  1120     return NULL;
       
  1121     }
       
  1122 
       
  1123 // ---------------------------------------------------------------------------
       
  1124 // Loads the bitmap used in drawing the tab icon with correct color.
       
  1125 // ---------------------------------------------------------------------------
       
  1126 //
       
  1127 void CAknTab::LoadColorBitmapL()
       
  1128     {
       
  1129     if ( iColorBitmaps )
       
  1130         {
       
  1131         iColorBitmaps->ResetAndDestroy();
       
  1132         delete iColorBitmaps;
       
  1133         iColorBitmaps = NULL;
       
  1134         }
       
  1135 
       
  1136     TRect rect( Rect() );
       
  1137 
       
  1138     if ( rect.IsEmpty() )
       
  1139         {
       
  1140         // We cannot decide the right color.
       
  1141         // This method will be called again when the rect is set.
       
  1142         return;
       
  1143         }
       
  1144 
       
  1145     if ( !iColorBitmaps )
       
  1146         {
       
  1147         iColorBitmaps = new (ELeave) CAknTabColorBitmapArray(
       
  1148             KTabColorBitmapQueueGranularity );
       
  1149         CFbsBitmap* activeColorBitmap = new (ELeave) CFbsBitmap();
       
  1150         CleanupStack::PushL(activeColorBitmap);
       
  1151         CFbsBitmap* passiveColorBitmap = new (ELeave) CFbsBitmap();
       
  1152         CleanupStack::PushL( passiveColorBitmap );
       
  1153         iColorBitmaps->AppendL( activeColorBitmap );
       
  1154         iColorBitmaps->AppendL( passiveColorBitmap );
       
  1155         CleanupStack::Pop( 2, activeColorBitmap );
       
  1156         }
       
  1157 
       
  1158     TBool isStaconPaneActive( AknStatuspaneUtils::StaconPaneActive() );
       
  1159     TBool isFlatLayoutActive(
       
  1160         isStaconPaneActive ? EFalse : AknStatuspaneUtils::FlatLayoutActive() );
       
  1161 
       
  1162     TAknLayoutRect layoutRect;
       
  1163     // LAF does not contain line for EAknTabWidthWithOneTab
       
  1164     // so we use this instead.
       
  1165     layoutRect.LayoutRect( rect, AknLayoutScalable_Avkon::navi_tabs_2_pane() );
       
  1166     TRect tabRect = layoutRect.Rect();
       
  1167     if ( tabRect.Width() < 0 || tabRect.Height() < 0 )
       
  1168         {
       
  1169         tabRect.SetRect( 0, 0, 0, 0 );
       
  1170         }
       
  1171 
       
  1172     if ( !( iColorBitmaps &&
       
  1173             iColorBitmaps->At( KTabColorBitmapActiveColorIndex ) &&
       
  1174             iColorBitmaps->At( KTabColorBitmapPassiveColorIndex ) ) )
       
  1175         {
       
  1176         return;
       
  1177         }
       
  1178 
       
  1179     // Note 64K or 16M mode seems to have some issues with some HW possibly
       
  1180     // related to bitmap compression, so we use display's color mode
       
  1181     // here instead for now instead of the AknIconConfig's preferred
       
  1182     // display mode.
       
  1183     TDisplayMode screenDisplayMode( iEikonEnv->ScreenDevice()->DisplayMode() );
       
  1184     iColorBitmaps->At( KTabColorBitmapActiveColorIndex )->Create(
       
  1185         Size(), screenDisplayMode );
       
  1186     iColorBitmaps->At( KTabColorBitmapPassiveColorIndex )->Create(
       
  1187         Size(), screenDisplayMode );
       
  1188 
       
  1189     TRgb color( KRgbGray );
       
  1190     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1191 
       
  1192     // First active color...
       
  1193     TAknsQsnIconColorsIndex colorIndex;
       
  1194     if (iExtension->iNumberOfTabsInTabGroup == 1)
       
  1195         {
       
  1196         colorIndex = EAknsCIQsnIconColorsCG7;
       
  1197         }
       
  1198     else
       
  1199         {
       
  1200         colorIndex = EAknsCIQsnIconColorsCG8;
       
  1201         }
       
  1202     AknsUtils::GetCachedColor( skin,
       
  1203                                color,
       
  1204                                KAknsIIDQsnIconColors,
       
  1205                                colorIndex );
       
  1206 
       
  1207     CFbsBitmapDevice* destinationDevice =
       
  1208         CFbsBitmapDevice::NewL(
       
  1209             iColorBitmaps->At( KTabColorBitmapActiveColorIndex ) );
       
  1210     CleanupStack::PushL( destinationDevice );
       
  1211     CFbsBitGc* destinationGc;
       
  1212     User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) );
       
  1213     destinationGc->SetPenColor( color );
       
  1214     destinationGc->SetPenStyle( CGraphicsContext::ESolidPen );
       
  1215     destinationGc->SetBrushColor( color );
       
  1216     destinationGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
       
  1217     destinationGc->DrawRect(
       
  1218         TRect( iColorBitmaps->At( KTabColorBitmapActiveColorIndex )->SizeInPixels() ) );
       
  1219 
       
  1220     delete destinationGc;
       
  1221     CleanupStack::PopAndDestroy( destinationDevice );
       
  1222 
       
  1223     // ...then passive color.
       
  1224     AknsUtils::GetCachedColor( skin,
       
  1225                                color,
       
  1226                                KAknsIIDQsnIconColors,
       
  1227                                EAknsCIQsnIconColorsCG9 );
       
  1228 
       
  1229     destinationDevice =
       
  1230         CFbsBitmapDevice::NewL(
       
  1231             iColorBitmaps->At( KTabColorBitmapPassiveColorIndex ) );
       
  1232     CleanupStack::PushL(destinationDevice);
       
  1233     User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) );
       
  1234     destinationGc->SetPenColor( color );
       
  1235     destinationGc->SetPenStyle( CGraphicsContext::ESolidPen );
       
  1236     destinationGc->SetBrushColor( color );
       
  1237     destinationGc->SetBrushStyle( CGraphicsContext::ESolidBrush );
       
  1238     destinationGc->DrawRect(
       
  1239         TRect( iColorBitmaps->At( KTabColorBitmapPassiveColorIndex )->SizeInPixels() ) );
       
  1240 
       
  1241     delete destinationGc;
       
  1242     CleanupStack::PopAndDestroy( destinationDevice );
       
  1243     }
       
  1244 
       
  1245 
       
  1246 void CAknTab::HandleResourceChange( TInt aType )
       
  1247     {
       
  1248     CCoeControl::HandleResourceChange( aType );
       
  1249 
       
  1250     if ( aType == KEikDynamicLayoutVariantSwitch ||
       
  1251          aType == KEikColorResourceChange ||
       
  1252          aType == KAknsMessageSkinChange )
       
  1253         {
       
  1254         TRAP_IGNORE( LoadColorBitmapL() );
       
  1255         DrawDeferred();
       
  1256         }
       
  1257     }
       
  1258 
       
  1259 void CAknTab::SetTotalAmountOfTabs( TInt aAmount )
       
  1260     {
       
  1261     iExtension->iNumberOfTabsInTabGroup = aAmount;
       
  1262     
       
  1263     if ( !iColorBitmaps )
       
  1264     	{
       
  1265       LoadColorBitmapL();
       
  1266       }
       
  1267     }
       
  1268 
       
  1269 void CAknTab::SetNarrowTabLayout( TBool aNarrow )
       
  1270     {
       
  1271     iExtension->iNarrowTabLayout = aNarrow;
       
  1272     }
       
  1273 
       
  1274 
       
  1275 // ---------------------------------------------------------------------------
       
  1276 // CAknTab::SetMultiColorMode
       
  1277 // ---------------------------------------------------------------------------
       
  1278 //
       
  1279 void CAknTab::SetMultiColorMode( TBool aMultiColor )
       
  1280     {
       
  1281     if ( iExtension )
       
  1282         {
       
  1283         iExtension->iMultiColorMode = aMultiColor;
       
  1284         }
       
  1285     }
       
  1286 
       
  1287 
       
  1288 // ---------------------------------------------------------------------------
       
  1289 // CAknTab::MultiColorMode
       
  1290 // ---------------------------------------------------------------------------
       
  1291 //
       
  1292 TBool CAknTab::MultiColorMode() const
       
  1293     {
       
  1294     if ( iExtension )
       
  1295         {
       
  1296         return iExtension->iMultiColorMode;
       
  1297         }
       
  1298     else
       
  1299         {
       
  1300         return EFalse;
       
  1301         }
       
  1302     }
       
  1303 
       
  1304 
       
  1305 // ---------------------------------------------------------------------------
       
  1306 // CAknTab::SetLongTabLayout
       
  1307 // Sets this tab to use long layout.
       
  1308 // ---------------------------------------------------------------------------
       
  1309 //
       
  1310 void CAknTab::SetLongTabLayout( TBool aLongTab )
       
  1311     {
       
  1312     if ( iExtension )
       
  1313         {
       
  1314         iExtension->iLongTab = aLongTab;
       
  1315         }
       
  1316     }
       
  1317 
       
  1318 
       
  1319 // ================= PRIVATE CLASS =======================
       
  1320 
       
  1321 class CAknTabGroupExtension : public CBase
       
  1322     {
       
  1323 public:
       
  1324 
       
  1325     /** Types of supported tab group animations. */
       
  1326     enum TTabAnimationType
       
  1327         {
       
  1328         /**
       
  1329         * No animation is currently used.
       
  1330         */
       
  1331         ENoAnimation = 0,
       
  1332         /**
       
  1333         * Animation type used when switching between
       
  1334         * normal and flat tab group layout.
       
  1335         */
       
  1336         ELayoutSwitchAnimation,
       
  1337         /**
       
  1338         * Animation type used when cycling between tabs in three tab layout
       
  1339         * when there are more than three tabs in the tab group.
       
  1340         */
       
  1341         ETabCycleAnimation
       
  1342         };
       
  1343 
       
  1344     CAknTabGroupExtension();
       
  1345     ~CAknTabGroupExtension(){};
       
  1346 
       
  1347 public: // Member data.
       
  1348 
       
  1349     CFbsBitmap*           iStaconTabBitmaps[KTabNumberOfTabBitmaps];
       
  1350     CFbsBitmap*           iStaconTabMaskBitmaps[KTabNumberOfTabBitmaps];
       
  1351     CAknTabGroupGraphics* iTabSvgGraphics;
       
  1352 
       
  1353     /** Layout used for the tab background graphics. */
       
  1354     CAknTabGroupGraphics::SAknTabGroupBackgroundLayout iTabBackgroundLayout;
       
  1355 
       
  1356     /** Layout used for the tab background graphics during tab animation. */
       
  1357     CAknTabGroupGraphics::SAknTabGroupBackgroundLayout iNextTabBackgroundLayout;
       
  1358 
       
  1359     /** Timer used in tab animations. */
       
  1360     CPeriodic* iTabAnimationTimer;
       
  1361 
       
  1362     /** Type of the current tab animation. */
       
  1363     TTabAnimationType iTabAnimationType;
       
  1364 
       
  1365     /** Amount of completed tab animation steps. */
       
  1366     TInt iAmountOfDoneAnimationEvents;
       
  1367 
       
  1368     /** Direction of the current tab cycle animation (left or right). */
       
  1369     CAknTabGroup::TDirection iTabCycleAnimationDirection;
       
  1370 
       
  1371     /** Horizontal distance left in the tab cycle animation. */
       
  1372     TInt iTabCycleAnimationDistanceLeft;
       
  1373 
       
  1374     /** Is the tab cycle animation in process. */
       
  1375     TBool iTabCycleAnimationOngoing;
       
  1376 
       
  1377     /**
       
  1378     * Specifies on which side of the tab group there are tabs
       
  1379     * that don't fit in the set of currently displayed tabs.
       
  1380     */
       
  1381     CAknTabGroupGraphics::TTabsHidden iTabsHidden;
       
  1382 
       
  1383     TBool             iTabAnimationDoubleBufferNarrowTabLayout;
       
  1384     TBool             iTabAnimationDoubleBufferLongTabs;
       
  1385     TInt              iTabAnimationDoubleBufferNumberOfTabsShown;
       
  1386     TInt              iTabAnimationDoubleBufferpositionActive;
       
  1387 
       
  1388     TBool  iNarrowTabLayout;
       
  1389     TBool  iNarrowTabLayoutNext;
       
  1390 
       
  1391     /** Are navigation arrows shown in the current tab layout. */
       
  1392     TBool  iNaviArrowsUsed;
       
  1393 
       
  1394     /** Index of the tab where pointer down event happened. */
       
  1395     TInt   iPointerDownTab;
       
  1396 
       
  1397     /** X-value of the pointer down event position. */
       
  1398     TInt   iPointerDownXPosition;
       
  1399 
       
  1400     /** This is the tab width that is set by the application. */
       
  1401     TInt   iRequestedTabWidth;
       
  1402     };
       
  1403 
       
  1404 
       
  1405 CAknTabGroupExtension::CAknTabGroupExtension()
       
  1406     {
       
  1407     iPointerDownTab       = -1;
       
  1408     iPointerDownXPosition = -1;
       
  1409     }
       
  1410 
       
  1411 
       
  1412 //
       
  1413 // CAknTabGroup
       
  1414 //
       
  1415 
       
  1416 EXPORT_C CAknTabGroup::CAknTabGroup() : iActiveTab(KAknTabGroupNoTabs)
       
  1417     {
       
  1418     iTabFixedWidth     = -1;
       
  1419     iFirstShownTab     = 0;
       
  1420     iNumberOfTabsShown = 0;
       
  1421 
       
  1422     // Tab bitmaps and masks for every tab group layouts
       
  1423     iBitmapNames[0]  = EMbmAvkonQgn_graf_tab_21;
       
  1424     iBitmapNames[1]  = EMbmAvkonQgn_graf_tab_22;
       
  1425     iBitmapNames[2]  = EMbmAvkonQgn_graf_tab_long_21;
       
  1426     iBitmapNames[3]  = EMbmAvkonQgn_graf_tab_long_22;
       
  1427     iBitmapNames[4]  = EMbmAvkonQgn_graf_tab_long_31;
       
  1428     iBitmapNames[5]  = EMbmAvkonQgn_graf_tab_long_32;
       
  1429     iBitmapNames[6]  = EMbmAvkonQgn_graf_tab_long_33;
       
  1430     iBitmapNames[7]  = EMbmAvkonQgn_graf_tab_31;
       
  1431     iBitmapNames[8]  = EMbmAvkonQgn_graf_tab_32;
       
  1432     iBitmapNames[9]  = EMbmAvkonQgn_graf_tab_33;
       
  1433     iBitmapNames[10] = EMbmAvkonQgn_graf_tab_41;
       
  1434     iBitmapNames[11] = EMbmAvkonQgn_graf_tab_42;
       
  1435     iBitmapNames[12] = EMbmAvkonQgn_graf_tab_43;
       
  1436     iBitmapNames[13] = EMbmAvkonQgn_graf_tab_44;
       
  1437 
       
  1438     iBitmapMaskNames[0]  = EMbmAvkonQgn_graf_tab_21_mask;
       
  1439     iBitmapMaskNames[1]  = EMbmAvkonQgn_graf_tab_22_mask;
       
  1440     iBitmapMaskNames[2]  = EMbmAvkonQgn_graf_tab_long_21_mask;
       
  1441     iBitmapMaskNames[3]  = EMbmAvkonQgn_graf_tab_long_22_mask;
       
  1442     iBitmapMaskNames[4]  = EMbmAvkonQgn_graf_tab_long_31_mask;
       
  1443     iBitmapMaskNames[5]  = EMbmAvkonQgn_graf_tab_long_32_mask;
       
  1444     iBitmapMaskNames[6]  = EMbmAvkonQgn_graf_tab_long_33_mask;
       
  1445     iBitmapMaskNames[7]  = EMbmAvkonQgn_graf_tab_31_mask;
       
  1446     iBitmapMaskNames[8]  = EMbmAvkonQgn_graf_tab_32_mask;
       
  1447     iBitmapMaskNames[9]  = EMbmAvkonQgn_graf_tab_33_mask;
       
  1448     iBitmapMaskNames[10] = EMbmAvkonQgn_graf_tab_41_mask;
       
  1449     iBitmapMaskNames[11] = EMbmAvkonQgn_graf_tab_42_mask;
       
  1450     iBitmapMaskNames[12] = EMbmAvkonQgn_graf_tab_43_mask;
       
  1451     iBitmapMaskNames[13] = EMbmAvkonQgn_graf_tab_44_mask;
       
  1452 
       
  1453     iMirrored = AknLayoutUtils::LayoutMirrored();
       
  1454     }
       
  1455 
       
  1456 EXPORT_C CAknTabGroup::~CAknTabGroup()
       
  1457     {
       
  1458     AKNTASHOOK_REMOVE();
       
  1459     if ( iTabArray )
       
  1460         {
       
  1461         iTabArray->ResetAndDestroy();
       
  1462         }
       
  1463     delete iTabArray;
       
  1464 
       
  1465     for ( TInt i = 0; i < KTabNumberOfTabBitmaps; i++ )
       
  1466         {
       
  1467         delete( iTabBitmaps[i] );
       
  1468         delete( iTabMaskBitmaps[i] );
       
  1469         }
       
  1470 
       
  1471     if ( iExtension )
       
  1472         {
       
  1473         for ( TInt j = 0; j < KTabNumberOfTabBitmaps; j++ )
       
  1474             {
       
  1475             delete( iExtension->iStaconTabBitmaps[j] );
       
  1476             delete( iExtension->iStaconTabMaskBitmaps[j] );
       
  1477             }
       
  1478 
       
  1479         delete iExtension->iTabSvgGraphics;
       
  1480         if ( iExtension->iTabAnimationTimer )
       
  1481             {
       
  1482             iExtension->iTabAnimationTimer->Cancel();
       
  1483             delete iExtension->iTabAnimationTimer;
       
  1484             }
       
  1485         }
       
  1486 
       
  1487     delete iExtension;
       
  1488 
       
  1489     }
       
  1490 
       
  1491 EXPORT_C CAknTabGroup* CAknTabGroup::NewL( const CCoeControl& aParent )
       
  1492     {
       
  1493     CAknTabGroup* self = CAknTabGroup::NewLC( aParent );
       
  1494     CleanupStack::Pop( self );
       
  1495     return self;
       
  1496     }
       
  1497 
       
  1498 EXPORT_C CAknTabGroup* CAknTabGroup::NewLC( const CCoeControl& aParent )
       
  1499     {
       
  1500     CAknTabGroup* self = new (ELeave) CAknTabGroup;
       
  1501     CleanupStack::PushL( self );
       
  1502     self->SetContainerWindowL( aParent );
       
  1503     self->ConstructL();
       
  1504     AKNTASHOOK_ADDL( self, "CAknTabGroup" );
       
  1505     return self;
       
  1506     }
       
  1507 
       
  1508 EXPORT_C TInt CAknTabGroup::AddTabL( TResourceReader& aReader )
       
  1509     {
       
  1510     CAknTab* newTab = CAknTab::NewL( *this, aReader );
       
  1511     CommonAddTabL( newTab ); // Takes ownership of newTab safely.
       
  1512     return newTab->Id();
       
  1513     }
       
  1514 
       
  1515 EXPORT_C void CAknTabGroup::AddTabL( TInt aTabId, const TDesC& aTabText )
       
  1516     {
       
  1517     CAknTab* newTab = CAknTab::NewL( aTabId, *this, aTabText );
       
  1518     CommonAddTabL( newTab );  // Takes ownership of newTab safely.
       
  1519     }
       
  1520 
       
  1521 
       
  1522 EXPORT_C void CAknTabGroup::AddTabL( TInt aTabId,
       
  1523                                      const TDesC& aTabText,
       
  1524                                      const CFbsBitmap* aTabBitmap,
       
  1525                                      const CFbsBitmap* aMask)
       
  1526     {
       
  1527     CAknTab* newTab = CAknTab::NewL( aTabId, *this, aTabText, aTabBitmap, aMask );
       
  1528     CommonAddTabL( newTab );  // Takes ownership of newTab safely.
       
  1529     }
       
  1530 
       
  1531 
       
  1532 EXPORT_C void CAknTabGroup::AddTabL( TInt aTabId,
       
  1533                                      const CFbsBitmap* aTabBitmap,
       
  1534                                      const CFbsBitmap* aMask)
       
  1535     {
       
  1536     CAknTab* newTab = CAknTab::NewL( aTabId, *this, aTabBitmap, aMask );
       
  1537     CommonAddTabL( newTab );  // Takes ownership of newTab safely.
       
  1538     }
       
  1539 
       
  1540 void CAknTabGroup::CommonAddTabL( CAknTab* aTab )
       
  1541     {
       
  1542     CleanupStack::PushL( aTab );
       
  1543     aTab->SetObserver( this );
       
  1544     aTab->SetControlContext( this );
       
  1545 
       
  1546     if ( iMirrored && iTabObserver )
       
  1547         {
       
  1548         // If tab group is mirrored then tabs are inserted in
       
  1549         // reverse order.
       
  1550         iTabArray->InsertL( 0, aTab );
       
  1551         }
       
  1552     else
       
  1553         {
       
  1554         iTabArray->AppendL( aTab );
       
  1555         }
       
  1556 
       
  1557     CleanupStack::Pop( aTab );
       
  1558 
       
  1559     if ( iTabFixedWidth < 0 && TabCount() > 1 )
       
  1560         {
       
  1561         SetTabFixedWidthL( KTabWidthWithTwoTabs );
       
  1562         }
       
  1563     }
       
  1564 
       
  1565 EXPORT_C void CAknTabGroup::ReplaceTabL( TResourceReader& aReader )
       
  1566     {
       
  1567     CAknTab* newTab = CAknTab::NewL( *this, aReader );
       
  1568     CommonReplaceTabL( newTab ); // Takes ownership of the newTab safely
       
  1569     }
       
  1570 
       
  1571 EXPORT_C void CAknTabGroup::ReplaceTabL( TInt aTabId,const TDesC& aTabText )
       
  1572     {
       
  1573     CAknTab* newTab=CAknTab::NewL( aTabId, *this, aTabText );
       
  1574     CommonReplaceTabL( newTab ); // Takes ownership of the newTab safely
       
  1575     }
       
  1576 
       
  1577 EXPORT_C void CAknTabGroup::ReplaceTabL( TInt aTabId,
       
  1578                                          const TDesC& aTabText,
       
  1579                                          const CFbsBitmap* aTabBitmap,
       
  1580                                          const CFbsBitmap* aMask )
       
  1581     {
       
  1582     CAknTab* newTab = CAknTab::NewL( aTabId, *this, aTabText, aTabBitmap, aMask );
       
  1583     CommonReplaceTabL( newTab ); // Takes ownership of the newTab safely
       
  1584     }
       
  1585 
       
  1586 EXPORT_C void CAknTabGroup::ReplaceTabL( TInt aTabId,
       
  1587                                          const CFbsBitmap* aTabBitmap,
       
  1588                                          const CFbsBitmap* aMask )
       
  1589     {
       
  1590     CAknTab* newTab = CAknTab::NewL( aTabId, *this, aTabBitmap, aMask );
       
  1591     CommonReplaceTabL( newTab ); // Takes ownership of the newTab safely
       
  1592     }
       
  1593 
       
  1594 void CAknTabGroup::CommonReplaceTabL( CAknTab* aTab )
       
  1595     {
       
  1596     CleanupStack::PushL( aTab );
       
  1597     aTab->SetObserver( this );
       
  1598     TInt tabIndex = ConvertTabIndex( TabIndexFromId( aTab->Id() ) );
       
  1599     __ASSERT_ALWAYS( tabIndex >= 0, Panic( EAknPanicOutOfRange ) );
       
  1600 
       
  1601     // Is replaced tab active tab or not
       
  1602     TBool isActiveTab =  iTabArray->At( tabIndex )->Active();
       
  1603     TBool isMultiColor = iTabArray->At( tabIndex )->MultiColorMode();
       
  1604     delete iTabArray->At( tabIndex );
       
  1605     iTabArray->Delete( tabIndex );
       
  1606     iTabArray->InsertL( tabIndex, aTab );
       
  1607     CleanupStack::Pop( aTab );
       
  1608 
       
  1609     aTab->SetMultiColorMode( isMultiColor );
       
  1610     aTab->SetControlContext( this );
       
  1611     aTab->SetActive( isActiveTab, ENoDrawNow );
       
  1612     SizeChanged();
       
  1613     TInt event = MAknNavigationObserver::ENaviEventRedrawNeeded;
       
  1614     ReportEventL( static_cast<MCoeControlObserver::TCoeEvent>( event ) );
       
  1615     }
       
  1616 
       
  1617 EXPORT_C void CAknTabGroup::ReplaceTabTextL( TInt aTabId, const TDesC& aTabText )
       
  1618     {
       
  1619     TInt tabIndex = ConvertTabIndex( TabIndexFromId( aTabId ) );
       
  1620     __ASSERT_ALWAYS( tabIndex >= 0, Panic( EAknPanicOutOfRange ) );
       
  1621     iTabArray->At( tabIndex )->ReplaceTextL( aTabText );
       
  1622     SizeChanged();
       
  1623     TInt event = MAknNavigationObserver::ENaviEventRedrawNeeded;
       
  1624     ReportEventL( STATIC_CAST( MCoeControlObserver::TCoeEvent, event ) );
       
  1625     }
       
  1626 
       
  1627 EXPORT_C void CAknTabGroup::DeleteTabL( TInt aTabId )
       
  1628     {
       
  1629     TInt oldActiveTab = iActiveTab;
       
  1630     TInt tabIndex = ConvertTabIndex( TabIndexFromId( aTabId ) );
       
  1631     __ASSERT_ALWAYS( tabIndex >= 0, Panic( EAknPanicOutOfRange ) );
       
  1632     delete iTabArray->At( tabIndex );
       
  1633     iTabArray->Delete( tabIndex );
       
  1634     TInt tabCount = TabCount();
       
  1635     if ( tabCount == 0 )
       
  1636         {
       
  1637         iActiveTab = KAknTabGroupNoTabs;
       
  1638         }
       
  1639     if ( tabIndex < iActiveTab )
       
  1640         {
       
  1641         iActiveTab--;
       
  1642         }
       
  1643     else if ( tabIndex == iActiveTab && iActiveTab == tabCount )
       
  1644         {
       
  1645         iActiveTab--;
       
  1646         if ( iFirstShownTab > 0 )
       
  1647             {
       
  1648             iFirstShownTab--;
       
  1649             }
       
  1650         }
       
  1651 
       
  1652     SizeChanged();
       
  1653 
       
  1654     TInt event = MAknNavigationObserver::ENaviEventRedrawNeeded;
       
  1655     if ( tabCount <= 1 )
       
  1656         {
       
  1657         event = MAknNavigationObserver::ENaviEventOneItemExists;
       
  1658         }
       
  1659     else if ( iActiveTab == 0 && oldActiveTab != 0 )
       
  1660         {
       
  1661         event = MAknNavigationObserver::ENaviEventLeftMostItemReached;
       
  1662         }
       
  1663     else if ( iActiveTab == ( tabCount - 1 ) &&
       
  1664               oldActiveTab != tabCount )
       
  1665         {
       
  1666         event = MAknNavigationObserver::ENaviEventRightMostItemReached;
       
  1667         }
       
  1668 
       
  1669     ReportEventL( static_cast<MCoeControlObserver::TCoeEvent>( event ) );
       
  1670     }
       
  1671 
       
  1672 void CAknTabGroup::ConstructL()
       
  1673     {
       
  1674     iExtension = new (ELeave) CAknTabGroupExtension();
       
  1675     iExtension->iTabSvgGraphics = CAknTabGroupGraphics::NewL();
       
  1676     iExtension->iTabAnimationTimer = CPeriodic::NewL( CActive::EPriorityIdle );
       
  1677     iTabArray = new (ELeave) CArrayPtrFlat<CAknTab>( KTabArrayGranularity );
       
  1678     }
       
  1679 
       
  1680 EXPORT_C void CAknTabGroup::SetActiveTabById( TInt aTabId )
       
  1681     {
       
  1682     TInt tabIndex = Index( aTabId );
       
  1683     SetActiveTabByIndex( ConvertTabIndex( tabIndex ) );
       
  1684     }
       
  1685 
       
  1686 
       
  1687 // ---------------------------------------------------------------------------
       
  1688 // Sets the active tab by tab index.
       
  1689 // ---------------------------------------------------------------------------
       
  1690 //
       
  1691 EXPORT_C void CAknTabGroup::SetActiveTabByIndex( TInt aTabIndex )
       
  1692     {
       
  1693     const TInt numTabs = TabCount();
       
  1694 
       
  1695     TInt realIndex = ConvertTabIndex( aTabIndex );
       
  1696 
       
  1697     // When iActiveTab doesn't change, nothing need to do.
       
  1698     if ( realIndex == iActiveTab )
       
  1699         {
       
  1700         return;
       
  1701         }
       
  1702 
       
  1703     if ( realIndex >= 0 && realIndex < numTabs )
       
  1704         {
       
  1705         CArrayPtr<CAknTab>& tabArray = *iTabArray;
       
  1706         if ( iActiveTab >= 0 )
       
  1707             {
       
  1708             tabArray[iActiveTab]->SetFocus( EFalse, ENoDrawNow );
       
  1709             tabArray[iActiveTab]->SetActive( EFalse, ENoDrawNow );
       
  1710             }
       
  1711         iActiveTab = realIndex;
       
  1712         tabArray[iActiveTab]->SetFocus( ETrue, ENoDrawNow );
       
  1713         tabArray[iActiveTab]->SetActive( ETrue, ENoDrawNow );
       
  1714 
       
  1715         if ( AknLayoutUtils::PenEnabled() &&
       
  1716              iTabFixedWidth == KTabWidthWithThreeTabs )
       
  1717             {
       
  1718             if ( realIndex != RightMostTabIndex() &&
       
  1719                  realIndex != LeftMostTabIndex() )
       
  1720                 {
       
  1721                 iFirstShownTab = realIndex - 1;
       
  1722                 }
       
  1723             else if ( realIndex < iFirstShownTab )
       
  1724                 {
       
  1725                 iFirstShownTab = realIndex;
       
  1726                 }
       
  1727             else if ( realIndex >= ( iFirstShownTab + iNumberOfTabsShown ) )
       
  1728                 {
       
  1729                 iFirstShownTab = realIndex - iNumberOfTabsShown + 1;
       
  1730                 }
       
  1731             }
       
  1732         else
       
  1733             {
       
  1734             if ( realIndex < iFirstShownTab )
       
  1735                 {
       
  1736                 iFirstShownTab = realIndex;
       
  1737                 }
       
  1738 
       
  1739             if ( realIndex >= ( iFirstShownTab + iNumberOfTabsShown ) )
       
  1740                 {
       
  1741                 iFirstShownTab = realIndex - iNumberOfTabsShown + 1;
       
  1742                 }
       
  1743             }
       
  1744 
       
  1745         SizeChanged();
       
  1746 
       
  1747         if ( !AknStatuspaneUtils::FlatLayoutActive() &&
       
  1748              iExtension->iTabAnimationType ==
       
  1749                  CAknTabGroupExtension::ELayoutSwitchAnimation )
       
  1750             {
       
  1751             CancelTabAnimationEventTimer();
       
  1752             }
       
  1753 
       
  1754         SetDecoratorLayout( EFalse );
       
  1755         TRAP_IGNORE( InitTabAnimationL() );
       
  1756 
       
  1757         ReportNavigationEvent();
       
  1758         }
       
  1759     }
       
  1760 
       
  1761 EXPORT_C TInt CAknTabGroup::ActiveTabId() const
       
  1762     {
       
  1763     if ( iActiveTab >= 0 )
       
  1764         {
       
  1765         return iTabArray->At( iActiveTab )->Id();
       
  1766         }
       
  1767 
       
  1768     return KErrNotFound;
       
  1769     }
       
  1770 
       
  1771 EXPORT_C TInt CAknTabGroup::ActiveTabIndex() const
       
  1772     {
       
  1773     return ConvertTabIndex( iActiveTab );
       
  1774     }
       
  1775 
       
  1776 
       
  1777 // ---------------------------------------------------------------------------
       
  1778 // Sets the width (used layout) of the tabs.
       
  1779 // ---------------------------------------------------------------------------
       
  1780 //
       
  1781 EXPORT_C void CAknTabGroup::SetTabFixedWidthL( TInt aWidth )
       
  1782     {
       
  1783     if ( iExtension )
       
  1784         {
       
  1785         // Store the requested width in case it's mapped here to another
       
  1786         // width but usable in some other layout.
       
  1787         iExtension->iRequestedTabWidth = aWidth;
       
  1788         }
       
  1789 
       
  1790     TInt  numberOfTabsShown = iNumberOfTabsShown;
       
  1791     TInt  tabFixedWidth     = iTabFixedWidth;
       
  1792     TBool longTabs          = iLongTabs;
       
  1793 
       
  1794     iLongTabs = EFalse;
       
  1795 
       
  1796     if ( aWidth <= KTabWidthWithTwoTabs && aWidth > KTabWidthWithThreeTabs )
       
  1797         {
       
  1798         iNumberOfTabsShown = 2;
       
  1799         iTabFixedWidth = KTabWidthWithTwoTabs;
       
  1800         }
       
  1801     else if ( AknLayoutUtils::PenEnabled() )
       
  1802         {
       
  1803         if ( aWidth <= KTabWidthWithThreeTabs )
       
  1804             {
       
  1805             iNumberOfTabsShown = 3;
       
  1806             iTabFixedWidth = KTabWidthWithThreeTabs;
       
  1807             }
       
  1808         else
       
  1809             {
       
  1810             iNumberOfTabsShown = 1;
       
  1811             iTabFixedWidth = KTabWidthWithOneTab;
       
  1812             }
       
  1813         }
       
  1814     else
       
  1815         {
       
  1816         if ( aWidth <= KTabWidthWithThreeTabs &&
       
  1817              aWidth > KTabWidthWithFourTabs )
       
  1818             {
       
  1819             iNumberOfTabsShown = 3;
       
  1820             iTabFixedWidth = KTabWidthWithThreeTabs;
       
  1821             }
       
  1822         else if ( aWidth <= KTabWidthWithFourTabs )
       
  1823             {
       
  1824             iNumberOfTabsShown = 4;
       
  1825             iTabFixedWidth = KTabWidthWithFourTabs;
       
  1826             }
       
  1827         else if ( aWidth <= KTabWidthWithThreeLongTabs )
       
  1828             {
       
  1829             iNumberOfTabsShown = 3;
       
  1830             iTabFixedWidth = KTabWidthWithThreeLongTabs;
       
  1831             iLongTabs = ETrue;
       
  1832             }
       
  1833         else if ( aWidth <= KTabWidthWithTwoLongTabs )
       
  1834             {
       
  1835             iNumberOfTabsShown = 2;
       
  1836             iTabFixedWidth = KTabWidthWithTwoLongTabs;
       
  1837             iLongTabs = ETrue;
       
  1838             }
       
  1839         else
       
  1840             {
       
  1841             iNumberOfTabsShown = 1;
       
  1842             iTabFixedWidth = KTabWidthWithOneTab;
       
  1843             }
       
  1844         }
       
  1845 
       
  1846     // When iNumberOfTabsShown, iTabFixedWidth, iLongTabs don't change,
       
  1847     // there's no reason to do LoadTabBitmapsL(), etc.
       
  1848     if ( numberOfTabsShown == iNumberOfTabsShown &&
       
  1849          tabFixedWidth == iTabFixedWidth &&
       
  1850          longTabs == iLongTabs )
       
  1851         {
       
  1852         return;
       
  1853         }
       
  1854 
       
  1855     TInt tabCount = TabCount();
       
  1856 
       
  1857     for ( TInt ii = 0; ii < tabCount; ii++ )
       
  1858         {
       
  1859         // Tell the tabs about the long tab layout
       
  1860         // for them to be able to layout their content
       
  1861         // correctly.
       
  1862         CAknTab* tab = iTabArray->At( ii );
       
  1863         tab->SetLongTabLayout( iLongTabs );
       
  1864         }
       
  1865 
       
  1866     SizeChanged();
       
  1867 
       
  1868     if ( iExtension &&
       
  1869          iExtension->iTabSvgGraphics &&
       
  1870          iExtension->iTabSvgGraphics->TabGroupBackgroundAvailable() )
       
  1871         {
       
  1872         iExtension->iTabBackgroundLayout.iUse = EFalse;
       
  1873 
       
  1874         iExtension->iTabSvgGraphics->DrawTabGroupBackgroundL(
       
  1875             CAknTabGroupGraphics::ENoDraw,
       
  1876             iLongTabs,
       
  1877             iNumberOfTabsShown,
       
  1878             1,
       
  1879             NULL,
       
  1880             iExtension->iTabBackgroundLayout,
       
  1881             CAknTabGroupGraphics::ENone );
       
  1882 
       
  1883         iExtension->iTabBackgroundLayout.iUse = ETrue;
       
  1884         SetDecoratorLayout( EFalse );
       
  1885         }
       
  1886 
       
  1887     LoadTabBitmapsL( iNumberOfTabsShown, iLongTabs );
       
  1888     }
       
  1889 
       
  1890 
       
  1891 EXPORT_C void CAknTabGroup::DimTab( TInt aTabId, TBool aDimmed )
       
  1892     {
       
  1893     TInt index = Index( aTabId );
       
  1894     if ( index >= 0 )
       
  1895         {
       
  1896         CAknTab* tabToDim = iTabArray->At( index );
       
  1897         tabToDim->SetDimmed( aDimmed );
       
  1898         }
       
  1899     }
       
  1900 
       
  1901 EXPORT_C TBool CAknTabGroup::IsTabDimmed( TInt aTabId ) const
       
  1902     {
       
  1903     TInt index = Index( aTabId );
       
  1904     if ( index < 0 )
       
  1905         {
       
  1906         return EFalse;
       
  1907         }
       
  1908     CAknTab* tabToCheck = iTabArray->At( index );
       
  1909     return tabToCheck->IsDimmed();
       
  1910     }
       
  1911 
       
  1912 EXPORT_C TInt CAknTabGroup::TabIndexFromId( TInt aTabId ) const
       
  1913     {
       
  1914     const TInt numTabs = TabCount();
       
  1915 
       
  1916     for ( TInt ii = 0; ii < numTabs; ii++ )
       
  1917         {
       
  1918         if ( aTabId == iTabArray->At(ii)->Id() )
       
  1919             {
       
  1920             return ConvertTabIndex( ii );
       
  1921             }
       
  1922         }
       
  1923 
       
  1924     return KErrNotFound;
       
  1925     }
       
  1926 
       
  1927 EXPORT_C TInt CAknTabGroup::TabIdFromIndex( TInt aTabIndex ) const
       
  1928     {
       
  1929     TInt realIndex = ConvertTabIndex( aTabIndex );
       
  1930     const TInt numTabs = TabCount();
       
  1931     if( ( realIndex >= 0 ) && ( realIndex < numTabs ) )
       
  1932         {
       
  1933         return iTabArray->At( realIndex )->Id();
       
  1934         }
       
  1935 
       
  1936     return KErrNotFound;
       
  1937     }
       
  1938 
       
  1939 EXPORT_C TInt CAknTabGroup::TabCount() const
       
  1940     {
       
  1941     return iTabArray->Count();
       
  1942     }
       
  1943 
       
  1944 
       
  1945 EXPORT_C void CAknTabGroup::SetObserver( MAknTabObserver* aObserver )
       
  1946     {
       
  1947     if ( !iTabObserver && iTabArray && TabCount() > 0 && iMirrored )
       
  1948         {
       
  1949         //
       
  1950         // If there isn't observer set but there is tabs already in array
       
  1951         // then the order of tabs must be changed if layout is mirrored.
       
  1952         //
       
  1953         TRAP_IGNORE( ReverseTabOrderL() );
       
  1954         iTabObserver = aObserver;
       
  1955         iActiveTab = ConvertTabIndex( iActiveTab );
       
  1956         SetActiveTabByIndex( ConvertTabIndex( iActiveTab ) );
       
  1957         }
       
  1958     else
       
  1959         {
       
  1960         iTabObserver = aObserver;
       
  1961         }
       
  1962     }
       
  1963 
       
  1964 void CAknTabGroup::ReverseTabOrderL()
       
  1965     {
       
  1966     if ( !iTabArray )
       
  1967         {
       
  1968         return;
       
  1969         }
       
  1970 
       
  1971     CArrayPtr<CAknTab>* oldArray = iTabArray;
       
  1972     iTabArray = new(ELeave) CArrayPtrFlat<CAknTab>( KTabArrayGranularity );
       
  1973     CleanupStack::PushL( oldArray );
       
  1974     for ( TInt i = 0; i < oldArray->Count(); i++ )
       
  1975         {
       
  1976         iTabArray->InsertL( 0, oldArray->At(i) );
       
  1977         }
       
  1978 
       
  1979     oldArray->Reset();
       
  1980     CleanupStack::PopAndDestroy( oldArray );
       
  1981     SizeChanged();
       
  1982     }
       
  1983 
       
  1984 
       
  1985 EXPORT_C TSize CAknTabGroup::MinimumSize()
       
  1986     {
       
  1987     TAknWindowLineLayout layout;
       
  1988     CurrentLayout( layout );
       
  1989     TAknLayoutRect layoutRect;
       
  1990     layoutRect.LayoutRect( ParentRect( iExtension->iNaviArrowsUsed ), layout );
       
  1991     TRect rect( layoutRect.Rect() );
       
  1992 
       
  1993     return rect.Size();
       
  1994     }
       
  1995 
       
  1996 
       
  1997 EXPORT_C TKeyResponse CAknTabGroup::OfferKeyEventL( const TKeyEvent& aKeyEvent,
       
  1998                                                     TEventCode aType )
       
  1999     {
       
  2000     if ( aType != EEventKey )
       
  2001         {
       
  2002         return EKeyWasNotConsumed;
       
  2003         }
       
  2004 
       
  2005     TKeyResponse keyResponse = EKeyWasNotConsumed;
       
  2006 
       
  2007     switch ( aKeyEvent.iCode )
       
  2008         {
       
  2009         case EKeyLeftArrow:
       
  2010             if ( iActiveTab != LeftMostTabIndex() || aKeyEvent.iRepeats == 0 )
       
  2011                 {
       
  2012                 if ( CycleFocus( ELeft,EDrawNow ) )
       
  2013                     {
       
  2014                     keyResponse = EKeyWasConsumed;
       
  2015                     }
       
  2016                 }
       
  2017             break;
       
  2018 
       
  2019         case EKeyRightArrow:
       
  2020             if ( iActiveTab != RightMostTabIndex() || aKeyEvent.iRepeats == 0 )
       
  2021                 {
       
  2022                 if ( CycleFocus( ERight,EDrawNow ) )
       
  2023                     {
       
  2024                     keyResponse = EKeyWasConsumed;
       
  2025                     }
       
  2026                 }
       
  2027             break;
       
  2028 
       
  2029         default:
       
  2030             break;
       
  2031         }
       
  2032 
       
  2033     if ( iTabObserver && keyResponse != EKeyWasNotConsumed )
       
  2034         {
       
  2035         iTabObserver->TabChangedL( ConvertTabIndex( iActiveTab ) );
       
  2036         }
       
  2037 
       
  2038     return keyResponse;
       
  2039     }
       
  2040 
       
  2041 
       
  2042 EXPORT_C void CAknTabGroup::GetColorUseListL(
       
  2043     CArrayFix<TCoeColorUse>& aColorUseList ) const
       
  2044     {
       
  2045     TCoeColorUse colorUse;
       
  2046     colorUse.SetLogicalColor( EColorDialogBackground );
       
  2047     colorUse.SetUse( TCoeColorUse::EBack |
       
  2048                      TCoeColorUse::ESurrounds |
       
  2049                      TCoeColorUse::EActive |
       
  2050                      TCoeColorUse::ENormal |
       
  2051                      TCoeColorUse::ENeutral );
       
  2052     aColorUseList.AppendL( colorUse );
       
  2053     }
       
  2054 
       
  2055 
       
  2056 EXPORT_C void CAknTabGroup::HandleControlEventL( CCoeControl* aControl,
       
  2057                                                  TCoeEvent aEventType )
       
  2058     {
       
  2059     switch ( aEventType )
       
  2060         {
       
  2061         case EEventStateChanged:
       
  2062             HandleTabStateChanged( aControl );
       
  2063             break;
       
  2064         default:
       
  2065             break;
       
  2066         }
       
  2067     }
       
  2068 
       
  2069 
       
  2070 EXPORT_C void CAknTabGroup::PrepareContext( CWindowGc& /*aGc*/ ) const
       
  2071     {
       
  2072     }
       
  2073 
       
  2074 
       
  2075 EXPORT_C void CAknTabGroup::SizeChanged()
       
  2076     {
       
  2077     // In flat statuspane we do things differently because the layout may vary.
       
  2078     if ( AknStatuspaneUtils::FlatLayoutActive() && !NarrowTabLayout() )
       
  2079         {
       
  2080         SizeChangedInFlatLayout();
       
  2081         }
       
  2082     if ( NarrowTabLayout() )
       
  2083         {
       
  2084         SizeChangedInNarrowLayout();
       
  2085         }
       
  2086     else
       
  2087         {
       
  2088         SizeChangedInNormalLayout();
       
  2089         }
       
  2090     }
       
  2091 
       
  2092 
       
  2093 // ---------------------------------------------------------------------------
       
  2094 // Handles size change events in normal tab group layout.
       
  2095 // ---------------------------------------------------------------------------
       
  2096 //
       
  2097 void CAknTabGroup::SizeChangedInNormalLayout()
       
  2098     {
       
  2099     TRect rect( ParentRect( iExtension->iNaviArrowsUsed ) );
       
  2100 
       
  2101     TInt tabsDrawn = iNumberOfTabsShown;
       
  2102     TInt numTabs   = TabCount();
       
  2103 
       
  2104     if ( tabsDrawn > numTabs )
       
  2105         {
       
  2106         tabsDrawn = numTabs;
       
  2107         }
       
  2108 
       
  2109     if ( ( iFirstShownTab + iNumberOfTabsShown ) > numTabs )
       
  2110         {
       
  2111         iFirstShownTab = 0;
       
  2112         }
       
  2113 
       
  2114     // set bitmap sizes
       
  2115     TAknWindowLineLayout defaultLayout;
       
  2116     CurrentLayout( defaultLayout );
       
  2117     TAknLayoutRect r;
       
  2118     r.LayoutRect( rect, defaultLayout );
       
  2119     TRect tabPaneRect( r.Rect() );
       
  2120     TSize size( tabPaneRect.Size() );
       
  2121 
       
  2122     for ( TInt i = 0; i < iNumberOfTabsShown; i++ )
       
  2123         {
       
  2124         AknIconUtils::SetSize( iTabBitmaps[i], size );
       
  2125         }
       
  2126 
       
  2127     if ( iExtension->iTabCycleAnimationOngoing )
       
  2128         {
       
  2129         TRect emptyRect( 0, 0, 0, 0 );
       
  2130         for ( TInt j = 0; j < numTabs; j++)
       
  2131             {
       
  2132             CAknTab* thisTab = iTabArray->At( j );
       
  2133             thisTab->SetRect( emptyRect );
       
  2134             }
       
  2135 
       
  2136         for ( TInt ii = 0; ii < tabsDrawn + 1; ii++ )
       
  2137             {
       
  2138             TInt tabIndex =
       
  2139                 iExtension->iTabCycleAnimationDirection == ELeft ? iActiveTab - 1 + ii :
       
  2140                                                                    iActiveTab - 2 + ii;
       
  2141 
       
  2142             if ( tabIndex >= numTabs ||
       
  2143                  tabIndex < 0 )
       
  2144                 {
       
  2145                 break;
       
  2146                 }
       
  2147 
       
  2148             CAknTab* thisTab = iTabArray->At( tabIndex );
       
  2149             thisTab->SetNarrowTabLayout( EFalse ); // set to normal layout mode
       
  2150             thisTab->SetTotalAmountOfTabs( iNumberOfTabsShown );
       
  2151 
       
  2152             switch ( ii )
       
  2153                 {
       
  2154                 case 0:
       
  2155                     {
       
  2156                     if ( iExtension->iTabCycleAnimationDirection == ELeft )
       
  2157                         {
       
  2158                         TRect tabRect( iExtension->iTabSvgGraphics->TabRectFromLayout(
       
  2159                             iExtension->iNextTabBackgroundLayout.iHiddenTabLeft ) );
       
  2160                         thisTab->SetRect( tabRect );
       
  2161                         }
       
  2162                     else
       
  2163                         {
       
  2164                         TRect tabRect( iExtension->iTabSvgGraphics->TabRectFromLayout(
       
  2165                             iExtension->iNextTabBackgroundLayout.iFirstTab ) );
       
  2166                         thisTab->SetRect( tabRect );
       
  2167                         }
       
  2168                     break;
       
  2169                     }
       
  2170 
       
  2171                 case 1:
       
  2172                     {
       
  2173                     if ( iExtension->iTabCycleAnimationDirection == ELeft )
       
  2174                         {
       
  2175                         TRect tabRect( iExtension->iTabSvgGraphics->TabRectFromLayout(
       
  2176                             iExtension->iNextTabBackgroundLayout.iFirstTab ) );
       
  2177                         thisTab->SetRect( tabRect );
       
  2178                         }
       
  2179                     else
       
  2180                         {
       
  2181                         TRect tabRect( iExtension->iTabSvgGraphics->TabRectFromLayout(
       
  2182                             iExtension->iNextTabBackgroundLayout.iSecondTab ) );
       
  2183                         thisTab->SetRect( tabRect );
       
  2184                         }
       
  2185                     break;
       
  2186                     }
       
  2187 
       
  2188                 case 2:
       
  2189                     {
       
  2190                     if ( iExtension->iTabCycleAnimationDirection == ELeft )
       
  2191                         {
       
  2192                         TRect tabRect( iExtension->iTabSvgGraphics->TabRectFromLayout(
       
  2193                             iExtension->iNextTabBackgroundLayout.iSecondTab ) );
       
  2194                         thisTab->SetRect( tabRect );
       
  2195                         }
       
  2196                     else
       
  2197                         {
       
  2198                         TRect tabRect( iExtension->iTabSvgGraphics->TabRectFromLayout(
       
  2199                             iExtension->iNextTabBackgroundLayout.iThirdTab ) );
       
  2200                         thisTab->SetRect( tabRect );
       
  2201                         }
       
  2202                     break;
       
  2203                     }
       
  2204 
       
  2205                 case 3:
       
  2206                     {
       
  2207                     if ( iExtension->iTabCycleAnimationDirection == ELeft )
       
  2208                         {
       
  2209                         TRect tabRect( iExtension->iTabSvgGraphics->TabRectFromLayout(
       
  2210                             iExtension->iNextTabBackgroundLayout.iThirdTab ) );
       
  2211                         thisTab->SetRect( tabRect );
       
  2212                         }
       
  2213                     else
       
  2214                         {
       
  2215                         TRect tabRect( iExtension->iTabSvgGraphics->TabRectFromLayout(
       
  2216                             iExtension->iNextTabBackgroundLayout.iHiddenTabRight ) );
       
  2217                         thisTab->SetRect( tabRect );
       
  2218                         }
       
  2219                     break;
       
  2220                     }
       
  2221                 }
       
  2222             }
       
  2223         }
       
  2224     else
       
  2225         {
       
  2226         for ( TInt ii=0; ii < tabsDrawn; ii++ )
       
  2227             {
       
  2228             CAknTab* thisTab = iTabArray->At( ii + iFirstShownTab );
       
  2229             thisTab->SetNarrowTabLayout( EFalse ); // set to normal layout mode
       
  2230             thisTab->SetTotalAmountOfTabs( iNumberOfTabsShown );
       
  2231 
       
  2232             TAknLayoutRect tabLayoutRect;
       
  2233 
       
  2234             switch ( iNumberOfTabsShown )
       
  2235                 {
       
  2236                 case 1:
       
  2237                     {
       
  2238                     thisTab->SetRect( tabPaneRect );
       
  2239                     break;
       
  2240                     }
       
  2241 
       
  2242                 case 2:
       
  2243                     {
       
  2244                     if ( iLongTabs )
       
  2245                         {
       
  2246                         tabLayoutRect.LayoutRect(
       
  2247                             tabPaneRect,
       
  2248                             AknLayoutScalable_Avkon::tabs_2_long_active_pane( ii ) );
       
  2249                         thisTab->SetRect( tabLayoutRect.Rect() );
       
  2250                         }
       
  2251                     else
       
  2252                         {
       
  2253                         tabLayoutRect.LayoutRect(
       
  2254                             tabPaneRect,
       
  2255                             AknLayoutScalable_Avkon::tabs_2_active_pane( ii ) );
       
  2256                         thisTab->SetRect( tabLayoutRect.Rect() );
       
  2257                         }
       
  2258 
       
  2259                     break;
       
  2260                     }
       
  2261 
       
  2262                 case 3:
       
  2263                     {
       
  2264                     if ( iLongTabs )
       
  2265                         {
       
  2266                         tabLayoutRect.LayoutRect(
       
  2267                             tabPaneRect,
       
  2268                             AknLayoutScalable_Avkon::tabs_3_long_active_pane( ii ) );
       
  2269                         thisTab->SetRect( tabLayoutRect.Rect() );
       
  2270                         }
       
  2271                     else
       
  2272                         {
       
  2273                         tabLayoutRect.LayoutRect(
       
  2274                             tabPaneRect,
       
  2275                             AknLayoutScalable_Avkon::tabs_3_active_pane( ii ) );
       
  2276                         thisTab->SetRect( tabLayoutRect.Rect() );
       
  2277                         }
       
  2278 
       
  2279                     break;
       
  2280                     }
       
  2281 
       
  2282                 case 4:
       
  2283                     {
       
  2284                     tabLayoutRect.LayoutRect(
       
  2285                         tabPaneRect,
       
  2286                         AknLayoutScalable_Avkon::tabs_4_active_pane( ii ) );
       
  2287                     thisTab->SetRect( tabLayoutRect.Rect() );
       
  2288                     break;
       
  2289                     }
       
  2290                 }
       
  2291             }
       
  2292         }
       
  2293     }
       
  2294 
       
  2295 
       
  2296 // ---------------------------------------------------------------------------
       
  2297 // Handles size change events in narrow tab group layout.
       
  2298 // ---------------------------------------------------------------------------
       
  2299 //
       
  2300 void CAknTabGroup::SizeChangedInNarrowLayout()
       
  2301     {
       
  2302     TRect rect( ParentRect( iExtension->iNaviArrowsUsed ) );
       
  2303 
       
  2304     TRect containerNarrowRect(
       
  2305         CAknNavigationDecorator::DecoratedControlNarrowRect(
       
  2306             CAknNavigationDecorator::ETabGroup ) );
       
  2307 
       
  2308     TInt tabsDrawn = iNumberOfTabsShown;
       
  2309     TInt numTabs   = TabCount();
       
  2310 
       
  2311     if ( tabsDrawn > numTabs )
       
  2312         {
       
  2313         tabsDrawn = numTabs;
       
  2314         }
       
  2315 
       
  2316     if ( ( iFirstShownTab + iNumberOfTabsShown ) > numTabs )
       
  2317         {
       
  2318         iFirstShownTab = 0;
       
  2319         }
       
  2320 
       
  2321     // set bitmap sizes
       
  2322     TAknWindowLineLayout defaultLayout;
       
  2323     CurrentLayout( defaultLayout );
       
  2324     TAknLayoutRect r;
       
  2325     r.LayoutRect( rect, defaultLayout );
       
  2326     TRect tabPaneRect( r.Rect() );
       
  2327     TSize size( tabPaneRect.Size() );
       
  2328 
       
  2329     for ( TInt i = 0; i < iNumberOfTabsShown; i++ )
       
  2330         {
       
  2331         AknIconUtils::SetSize( iTabBitmaps[i], size );
       
  2332         }
       
  2333 
       
  2334     for ( TInt ii = 0; ii < tabsDrawn; ii++ )
       
  2335         {
       
  2336         CAknTab* thisTab = iTabArray->At( ii + iFirstShownTab );
       
  2337         CAknTab::TAknTabDataType type = thisTab->TabType();
       
  2338         thisTab->SetNarrowTabLayout( ETrue ); // set to narrow layout mode
       
  2339         thisTab->SetTotalAmountOfTabs( iNumberOfTabsShown );
       
  2340 
       
  2341         // In flat statuspane we do things differently because the layout may vary.
       
  2342         if ( AknStatuspaneUtils::FlatLayoutActive() && NarrowTabLayout() )
       
  2343             {
       
  2344             // only active tab shows content in narrow layout
       
  2345             if ( thisTab->Active() || iNumberOfTabsShown == 1 )
       
  2346                 {
       
  2347                 CAknTabGroupGraphics::SAknTabLayout activeTabLayout;
       
  2348                 TInt positionActive = iActiveTab - iFirstShownTab;
       
  2349 
       
  2350                 if ( positionActive == 0 )
       
  2351                     {
       
  2352                     activeTabLayout = iExtension->iTabBackgroundLayout.iFirstTab;
       
  2353                     }
       
  2354                 else if ( positionActive == 1 )
       
  2355                     {
       
  2356                     activeTabLayout = iExtension->iTabBackgroundLayout.iSecondTab;
       
  2357                     }
       
  2358                 else if ( positionActive == 2 )
       
  2359                     {
       
  2360                     activeTabLayout = iExtension->iTabBackgroundLayout.iThirdTab;
       
  2361                     }
       
  2362                 else if ( positionActive == 3 )
       
  2363                     {
       
  2364                     activeTabLayout = iExtension->iTabBackgroundLayout.iFourthTab;
       
  2365                     }
       
  2366 
       
  2367                 TRect parentRect( activeTabLayout.iLeft );
       
  2368                 parentRect.BoundingRect( activeTabLayout.iMiddle );
       
  2369                 parentRect.BoundingRect( activeTabLayout.iRight );
       
  2370 
       
  2371                 if ( iNumberOfTabsShown == 1 )
       
  2372                     {
       
  2373                     thisTab->SetRect( containerNarrowRect );
       
  2374                     }
       
  2375                 else
       
  2376                     {
       
  2377                     thisTab->SetRect( parentRect );
       
  2378                     }
       
  2379                 }
       
  2380             else
       
  2381                 {
       
  2382                 thisTab->SetSize( TSize( 0, 0 ) );
       
  2383                 }
       
  2384 
       
  2385             continue;
       
  2386             }
       
  2387         }
       
  2388     }
       
  2389 
       
  2390 
       
  2391 // ---------------------------------------------------------------------------
       
  2392 // Handles size change events in flat status pane layout.
       
  2393 // ---------------------------------------------------------------------------
       
  2394 //
       
  2395 void CAknTabGroup::SizeChangedInFlatLayout()
       
  2396     {
       
  2397     TRect rect( ParentRect( iExtension->iNaviArrowsUsed ) );
       
  2398 
       
  2399     TRect containerNarrowRect(
       
  2400         CAknNavigationDecorator::DecoratedControlRect(
       
  2401             CAknNavigationDecorator::ETabGroup,
       
  2402             iExtension->iNaviArrowsUsed ) );
       
  2403 
       
  2404     TInt tabsDrawn = iNumberOfTabsShown;
       
  2405     TInt numTabs   = TabCount();
       
  2406 
       
  2407     if ( tabsDrawn > numTabs )
       
  2408         {
       
  2409         tabsDrawn = numTabs;
       
  2410         }
       
  2411 
       
  2412     if ( ( iFirstShownTab + iNumberOfTabsShown ) > numTabs )
       
  2413         {
       
  2414         iFirstShownTab = 0;
       
  2415         }
       
  2416 
       
  2417     // set bitmap sizes
       
  2418     TAknWindowLineLayout defaultLayout;
       
  2419     CurrentLayout( defaultLayout );
       
  2420     TAknLayoutRect r;
       
  2421     r.LayoutRect( containerNarrowRect, defaultLayout );
       
  2422     TRect tabPaneRect( r.Rect() );
       
  2423     TSize size( tabPaneRect.Size() );
       
  2424 
       
  2425     for ( TInt i = 0; i < iNumberOfTabsShown; i++ )
       
  2426         {
       
  2427         AknIconUtils::SetSize( iTabBitmaps[i], size );
       
  2428         }
       
  2429 
       
  2430     for ( TInt ii = 0; ii < tabsDrawn; ii++ )
       
  2431         {
       
  2432         CAknTab* thisTab = iTabArray->At( ii + iFirstShownTab );
       
  2433         CAknTab::TAknTabDataType type = thisTab->TabType();
       
  2434         thisTab->SetNarrowTabLayout( ETrue ); // set to narrow layout mode
       
  2435         thisTab->SetTotalAmountOfTabs( iNumberOfTabsShown );
       
  2436 
       
  2437         if ( AknStatuspaneUtils::FlatLayoutActive() )
       
  2438             {
       
  2439             CAknTabGroupGraphics::SAknTabLayout activeTabLayout;
       
  2440             TInt positionActive = iActiveTab - iFirstShownTab;
       
  2441 
       
  2442             if ( positionActive == 0 )
       
  2443                 {
       
  2444                 activeTabLayout = iExtension->iTabBackgroundLayout.iFirstTab;
       
  2445                 }
       
  2446             else if ( positionActive == 1 )
       
  2447                 {
       
  2448                 activeTabLayout = iExtension->iTabBackgroundLayout.iSecondTab;
       
  2449                 }
       
  2450             else if ( positionActive == 2 )
       
  2451                 {
       
  2452                 activeTabLayout = iExtension->iTabBackgroundLayout.iThirdTab;
       
  2453                 }
       
  2454             else if ( positionActive == 3 )
       
  2455                 {
       
  2456                 activeTabLayout = iExtension->iTabBackgroundLayout.iFourthTab;
       
  2457                 }
       
  2458 
       
  2459             TRect parentRect( activeTabLayout.iLeft );
       
  2460             parentRect.BoundingRect( activeTabLayout.iMiddle );
       
  2461             parentRect.BoundingRect( activeTabLayout.iRight );
       
  2462 
       
  2463             if ( iNumberOfTabsShown == 1 )
       
  2464                 {
       
  2465                 thisTab->SetRect( containerNarrowRect );
       
  2466                 }
       
  2467             else
       
  2468                 {
       
  2469                 thisTab->SetRect( parentRect );
       
  2470                 }
       
  2471             }
       
  2472         }
       
  2473     }
       
  2474 
       
  2475 
       
  2476 // ---------------------------------------------------------------------------
       
  2477 // Returns the amount of component controls.
       
  2478 // ---------------------------------------------------------------------------
       
  2479 //
       
  2480 EXPORT_C TInt CAknTabGroup::CountComponentControls() const
       
  2481     {
       
  2482     TInt count( 0 );
       
  2483 
       
  2484     // Check if tabs are supposed to be visible in current layout.
       
  2485     if ( !TabsVisibleInCurrentLayout() ||
       
  2486          iActiveTab < 0 )
       
  2487         {
       
  2488         count = 0;
       
  2489         }
       
  2490     else
       
  2491         {
       
  2492         TInt numTabs = TabCount();
       
  2493         if ( iLongTabs && iActiveTab >= 0 )
       
  2494             {
       
  2495             // In long tab layout only one tab is drawn at a time.
       
  2496             count = 1;
       
  2497             }
       
  2498         else if ( numTabs < iNumberOfTabsShown ||
       
  2499                   iExtension->iTabCycleAnimationOngoing )
       
  2500             {
       
  2501             // It's required that all tabs can be drawn during
       
  2502             // the tab cycle animation, so return the
       
  2503             // entire amount of tabs.
       
  2504             count = numTabs;
       
  2505             }
       
  2506         else
       
  2507             {
       
  2508             // Else return amount of the displayed tabs.
       
  2509             count = iNumberOfTabsShown;
       
  2510             }
       
  2511         }
       
  2512 
       
  2513     return count;
       
  2514     }
       
  2515 
       
  2516 
       
  2517 // ---------------------------------------------------------------------------
       
  2518 // Gets a component control (tab control) by the control index.
       
  2519 // ---------------------------------------------------------------------------
       
  2520 //
       
  2521 EXPORT_C CCoeControl* CAknTabGroup::ComponentControl( TInt aIndex ) const
       
  2522     {
       
  2523     CCoeControl* control = NULL;
       
  2524 
       
  2525     if ( iLongTabs )
       
  2526         {
       
  2527         control = iTabArray->At( iActiveTab );
       
  2528         }
       
  2529     else
       
  2530         {
       
  2531         TInt index( aIndex );
       
  2532         if ( !iExtension->iTabCycleAnimationOngoing )
       
  2533             {
       
  2534             index += iFirstShownTab;
       
  2535             }
       
  2536         control = iTabArray->At( index );
       
  2537         }
       
  2538 
       
  2539     return control;
       
  2540     }
       
  2541 
       
  2542 EXPORT_C void CAknTabGroup::FocusChanged( TDrawNow aDrawNow )
       
  2543     {
       
  2544     if ( iActiveTab >= 0 )
       
  2545         {
       
  2546         iTabArray->At( iActiveTab )->SetFocus( IsFocused(), aDrawNow );
       
  2547         }
       
  2548     }
       
  2549 
       
  2550 
       
  2551 // ---------------------------------------------------------------------------
       
  2552 // Converts a mirrored tab index to it's non-mirrored index.
       
  2553 // ---------------------------------------------------------------------------
       
  2554 //
       
  2555 TInt CAknTabGroup::ConvertTabIndex( TInt aIndex ) const
       
  2556     {
       
  2557     if ( iMirrored && iTabObserver && aIndex >= 0 )
       
  2558         {
       
  2559         return TabCount() - 1 - aIndex;
       
  2560         }
       
  2561 
       
  2562     return aIndex;
       
  2563     }
       
  2564 
       
  2565 
       
  2566 // ---------------------------------------------------------------------------
       
  2567 // Draws the tab group background graphics.
       
  2568 // ---------------------------------------------------------------------------
       
  2569 //
       
  2570 EXPORT_C void CAknTabGroup::Draw( const TRect& /*aRect*/ ) const
       
  2571     {
       
  2572     TRect rect( ParentRect( iExtension->iNaviArrowsUsed ) );
       
  2573 
       
  2574     // Are tabs supposed to be visible in current layout.
       
  2575     if ( !TabsVisibleInCurrentLayout() )
       
  2576         {
       
  2577         return;  // No tabs shown
       
  2578         }
       
  2579 
       
  2580     if ( iActiveTab < 0 || iNumberOfTabsShown == 1 )
       
  2581         {
       
  2582         return;
       
  2583         }
       
  2584 
       
  2585     TInt bitmapNo = 0;
       
  2586     TInt positionActive = iActiveTab - iFirstShownTab;
       
  2587 
       
  2588     // Find out a correct background bitmap for tabs
       
  2589     if ( iNumberOfTabsShown == 2 )
       
  2590         if ( iLongTabs )
       
  2591             {
       
  2592             bitmapNo = positionActive + KTabIndexOfFirstTabBitmapInTwoLongTabsSet;
       
  2593             }
       
  2594         else
       
  2595             {
       
  2596             bitmapNo = positionActive + KTabIndexOfFirstTabBitmapInTwoTabsSet;
       
  2597             }
       
  2598     if ( iNumberOfTabsShown == 3 )
       
  2599         if ( iLongTabs )
       
  2600             {
       
  2601             bitmapNo = positionActive + KTabIndexOfFirstTabBitmapInThreeLongTabsSet;
       
  2602             }
       
  2603         else
       
  2604             {
       
  2605             bitmapNo = positionActive + KTabIndexOfFirstTabBitmapInThreeTabsSet;
       
  2606             }
       
  2607     if ( iNumberOfTabsShown == 4 )
       
  2608         {
       
  2609         bitmapNo = positionActive + KTabIndexOfFirstTabBitmapInFourTabsSet;
       
  2610         }
       
  2611 
       
  2612     CWindowGc& gc = SystemGc();
       
  2613 
       
  2614     if (iExtension && iExtension->iTabSvgGraphics
       
  2615             && iExtension->iTabSvgGraphics->TabGroupBackgroundAvailable())
       
  2616         {
       
  2617 
       
  2618         if (iExtension->iNarrowTabLayout)
       
  2619             {
       
  2620             iExtension->iTabSvgGraphics->DrawTabGroupNarrowBackgroundL(
       
  2621                     CAknTabGroupGraphics::ENormal, iLongTabs,
       
  2622                     iNumberOfTabsShown, positionActive + 1, &gc,
       
  2623                     iExtension->iTabBackgroundLayout);
       
  2624 
       
  2625             iExtension->iTabSvgGraphics->DrawTabGroupNarrowBackgroundL(
       
  2626                     CAknTabGroupGraphics::EMaskOnly, iLongTabs,
       
  2627                     iNumberOfTabsShown, positionActive + 1, &gc,
       
  2628                     iExtension->iTabBackgroundLayout);
       
  2629             }
       
  2630         else
       
  2631             {
       
  2632             CAknTabGroupGraphics::TTabAnimationType animation(
       
  2633                     CAknTabGroupGraphics::ENoAnimation);
       
  2634             TBool animationOngoing( iExtension->iTabCycleAnimationOngoing );
       
  2635             
       
  2636             if ( animationOngoing )
       
  2637                 {
       
  2638                 animation
       
  2639                         = iExtension->iTabCycleAnimationDirection == ELeft
       
  2640                                                                            ? CAknTabGroupGraphics::ECycleToLeft
       
  2641                                                                               : CAknTabGroupGraphics::ECycleToRight;
       
  2642                 }
       
  2643             iExtension->iTabSvgGraphics->DrawTabGroupBackgroundL(
       
  2644                     CAknTabGroupGraphics::ENormal, iLongTabs,
       
  2645                     iNumberOfTabsShown, positionActive + 1, &gc,
       
  2646                     animationOngoing ? iExtension->iNextTabBackgroundLayout
       
  2647                                        : iExtension->iTabBackgroundLayout,
       
  2648                     iExtension->iTabsHidden, animation);
       
  2649 
       
  2650             iExtension->iTabSvgGraphics->DrawTabGroupBackgroundL(
       
  2651                     CAknTabGroupGraphics::EMaskOnly,
       
  2652                     iLongTabs,
       
  2653                     iNumberOfTabsShown,
       
  2654                     positionActive + 1,
       
  2655                     &gc,
       
  2656                     animationOngoing ? iExtension->iNextTabBackgroundLayout
       
  2657                                        : iExtension->iTabBackgroundLayout,
       
  2658                     iExtension->iTabsHidden, animation);
       
  2659             }
       
  2660         }
       
  2661     else
       
  2662         {
       
  2663         // Old legacy draw code
       
  2664         if (iTabBitmaps[bitmapNo] && iTabMaskBitmaps[bitmapNo])
       
  2665             {
       
  2666             gc.BitBltMasked(rect.iTl, iTabBitmaps[bitmapNo], rect,
       
  2667                     iTabMaskBitmaps[bitmapNo], ETrue);
       
  2668             }
       
  2669         }
       
  2670     }
       
  2671 
       
  2672 
       
  2673 // ---------------------------------------------------------------------------
       
  2674 // Handles the pointer events that happen inside tab group control.
       
  2675 // ---------------------------------------------------------------------------
       
  2676 //
       
  2677 EXPORT_C void CAknTabGroup::HandlePointerEventL(
       
  2678     const TPointerEvent& aPointerEvent )
       
  2679     {
       
  2680     if ( AknLayoutUtils::PenEnabled() && iNumberOfTabsShown > 0 )
       
  2681         {
       
  2682         TInt newTab = -1;
       
  2683 
       
  2684         // If the tab background graphics are not drawn, then we can't
       
  2685         // use it to calculate tab rects and use only the x-value of
       
  2686         // the pointer event position.
       
  2687         TBool tabBackgroundUsed( iTabFixedWidth != KTabWidthWithOneTab );
       
  2688 
       
  2689         if ( tabBackgroundUsed )
       
  2690             {
       
  2691             CAknTabGroupGraphics::SAknTabGroupBackgroundLayout* layout =
       
  2692                 &iExtension->iTabBackgroundLayout;
       
  2693 
       
  2694             CAknTabGroupGraphics::SAknTabLayout* tabLayout[KMaxNumberOfVisibleTabs];
       
  2695             Mem::FillZ( tabLayout, sizeof( TUint ) * KMaxNumberOfVisibleTabs );
       
  2696 
       
  2697             // Sort the layout array into right order. Tabs need to be tested
       
  2698             // according to their "z-order" so that the currently active tab
       
  2699             // is tested last.
       
  2700 
       
  2701             TInt currentTab = iActiveTab - iFirstShownTab;
       
  2702 
       
  2703             switch ( iNumberOfTabsShown )
       
  2704                 {
       
  2705                 case 1:
       
  2706                     {
       
  2707                     tabLayout[0] = &layout->iFirstTab;
       
  2708                     break;
       
  2709                     }
       
  2710 
       
  2711                 case 2:
       
  2712                     {
       
  2713                     if ( currentTab == 0 )
       
  2714                         {
       
  2715                         tabLayout[0] = &layout->iSecondTab;
       
  2716                         tabLayout[1] = &layout->iFirstTab;
       
  2717                         }
       
  2718                     else
       
  2719                         {
       
  2720                         tabLayout[0] = &layout->iFirstTab;
       
  2721                         tabLayout[1] = &layout->iSecondTab;
       
  2722                         }
       
  2723                     break;
       
  2724                     }
       
  2725 
       
  2726                 case 3:
       
  2727                     {
       
  2728                     switch ( currentTab )
       
  2729                         {
       
  2730                         case 0:
       
  2731                             tabLayout[0] = &layout->iThirdTab;
       
  2732                             tabLayout[1] = &layout->iSecondTab;
       
  2733                             tabLayout[2] = &layout->iFirstTab;
       
  2734                             break;
       
  2735 
       
  2736                         case 1:
       
  2737                             tabLayout[0] = &layout->iThirdTab;
       
  2738                             tabLayout[1] = &layout->iFirstTab;
       
  2739                             tabLayout[2] = &layout->iSecondTab;
       
  2740                             break;
       
  2741 
       
  2742                         default:
       
  2743                             tabLayout[0] = &layout->iFirstTab;
       
  2744                             tabLayout[1] = &layout->iSecondTab;
       
  2745                             tabLayout[2] = &layout->iThirdTab;
       
  2746                         }
       
  2747                     break;
       
  2748                     }
       
  2749 
       
  2750                 case 4:
       
  2751                     {
       
  2752                     if ( NarrowTabLayout() )
       
  2753                         {
       
  2754                         switch ( currentTab )
       
  2755                             {
       
  2756                             case 0:
       
  2757                                 tabLayout[0] = &layout->iFourthTab;
       
  2758                                 tabLayout[1] = &layout->iThirdTab;
       
  2759                                 tabLayout[2] = &layout->iSecondTab;
       
  2760                                 tabLayout[3] = &layout->iFirstTab;
       
  2761                                 break;
       
  2762 
       
  2763                             case 1:
       
  2764                                 tabLayout[0] = &layout->iFourthTab;
       
  2765                                 tabLayout[1] = &layout->iThirdTab;
       
  2766                                 tabLayout[2] = &layout->iFirstTab;
       
  2767                                 tabLayout[3] = &layout->iSecondTab;
       
  2768                                 break;
       
  2769 
       
  2770                             case 2:
       
  2771                                 tabLayout[0] = &layout->iFourthTab;
       
  2772                                 tabLayout[1] = &layout->iFirstTab;
       
  2773                                 tabLayout[2] = &layout->iSecondTab;
       
  2774                                 tabLayout[3] = &layout->iThirdTab;
       
  2775                                 break;
       
  2776 
       
  2777                             default:
       
  2778                                 tabLayout[0] = &layout->iFirstTab;
       
  2779                                 tabLayout[1] = &layout->iSecondTab;
       
  2780                                 tabLayout[2] = &layout->iThirdTab;
       
  2781                                 tabLayout[3] = &layout->iFourthTab;
       
  2782                             }
       
  2783                         }
       
  2784                     else
       
  2785                         {
       
  2786                         switch ( currentTab )
       
  2787                             {
       
  2788                             case 0:
       
  2789                                 tabLayout[0] = &layout->iFourthTab;
       
  2790                                 tabLayout[1] = &layout->iThirdTab;
       
  2791                                 tabLayout[2] = &layout->iSecondTab;
       
  2792                                 tabLayout[3] = &layout->iFirstTab;
       
  2793                                 break;
       
  2794 
       
  2795                             case 1:
       
  2796                                 tabLayout[0] = &layout->iFourthTab;
       
  2797                                 tabLayout[1] = &layout->iThirdTab;
       
  2798                                 tabLayout[2] = &layout->iFirstTab;
       
  2799                                 tabLayout[3] = &layout->iSecondTab;
       
  2800                                 break;
       
  2801 
       
  2802                             case 2:
       
  2803                                 tabLayout[0] = &layout->iFourthTab;
       
  2804                                 tabLayout[1] = &layout->iSecondTab;
       
  2805                                 tabLayout[2] = &layout->iFirstTab;
       
  2806                                 tabLayout[3] = &layout->iThirdTab;
       
  2807                                 break;
       
  2808 
       
  2809                             default:
       
  2810                                 tabLayout[0] = &layout->iThirdTab;
       
  2811                                 tabLayout[1] = &layout->iSecondTab;
       
  2812                                 tabLayout[2] = &layout->iFirstTab;
       
  2813                                 tabLayout[3] = &layout->iFourthTab;
       
  2814                             }
       
  2815                         }
       
  2816                     break;
       
  2817                     }
       
  2818 
       
  2819                 default:
       
  2820                     {
       
  2821                     User::Leave( KErrArgument );
       
  2822                     }
       
  2823                 }
       
  2824 
       
  2825             // Loop through the layout array & pick the last suitable tab.
       
  2826             TRect* rect;
       
  2827 
       
  2828             for ( TInt tab = 0; tab < iNumberOfTabsShown; ++tab )
       
  2829                 {
       
  2830                 rect = &tabLayout[tab]->iLeft;
       
  2831 
       
  2832                 for ( TInt part = CAknTabGroupGraphics::ELeft;
       
  2833                       part <= CAknTabGroupGraphics::ERight;
       
  2834                       ++part )
       
  2835                     {
       
  2836                     if ( rect->Contains( aPointerEvent.iPosition ) )
       
  2837                         {
       
  2838                         if ( iExtension->iTabSvgGraphics->TabClickedL( 
       
  2839                                 part, *rect, aPointerEvent.iPosition,
       
  2840                                 tab == KMaxNumberOfVisibleTabs - 1 ) )
       
  2841                             {
       
  2842                             if ( tabLayout[tab] == &layout->iFirstTab )
       
  2843                                 {
       
  2844                                 newTab = iFirstShownTab;
       
  2845                                 }
       
  2846                             else if ( tabLayout[tab] == &layout->iSecondTab )
       
  2847                                 {
       
  2848                                 newTab = iFirstShownTab + 1;
       
  2849                                 }
       
  2850                             else if ( tabLayout[tab] == &layout->iThirdTab )
       
  2851                                 {
       
  2852                                 newTab = iFirstShownTab + 2;
       
  2853                                 }
       
  2854                             else
       
  2855                                 {
       
  2856                                 newTab = iFirstShownTab + 3;
       
  2857                                 }
       
  2858                             break;
       
  2859                             }
       
  2860                         }
       
  2861 
       
  2862                     // advance pointer to the next tab component
       
  2863                     if ( part < CAknTabGroupGraphics::ERight )
       
  2864                         {
       
  2865                         rect++;
       
  2866                         }
       
  2867                     }
       
  2868                 }
       
  2869             }
       
  2870 
       
  2871         if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  2872             {
       
  2873             if( newTab> -1 )
       
  2874                 {
       
  2875                 MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  2876 
       
  2877                 // Feedback is given only if new tab wasn't already active
       
  2878                 // Use two convertTabIndex to cancel the mirror effects, because the newTab is always the phsical index.
       
  2879                 TBool isActiveTab = iTabArray->At( ConvertTabIndex( ConvertTabIndex( newTab ) ) )->Active();
       
  2880                 TTouchFeedbackType type = static_cast<TTouchFeedbackType>(ETouchFeedbackAudio | ETouchFeedbackVibra);
       
  2881                 if ( feedback && !isActiveTab )
       
  2882                     {
       
  2883                     feedback->InstantFeedback( this,
       
  2884                         ETouchFeedbackTab, 
       
  2885                         type,
       
  2886                         aPointerEvent );
       
  2887                     }
       
  2888                 }
       
  2889             if ( !tabBackgroundUsed )
       
  2890                 {
       
  2891                 // In one tab layout handle the navigation always by
       
  2892                 // pointer position.
       
  2893                 newTab = iActiveTab;
       
  2894                 }
       
  2895             iExtension->iPointerDownTab       = newTab;
       
  2896             iExtension->iPointerDownXPosition = aPointerEvent.iPosition.iX;
       
  2897             return;
       
  2898             }
       
  2899         else if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
  2900             {
       
  2901             if( newTab> -1 )
       
  2902                 {
       
  2903                 MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  2904 
       
  2905                 // Feedback is given only if new tab wasn't already active
       
  2906                 // Use two convertTabIndex to cancel the mirror effects, because the newTab is always the phsical index.
       
  2907                 TBool isActiveTab = iTabArray->At( ConvertTabIndex( ConvertTabIndex( newTab ) ) )->Active();
       
  2908                 if ( feedback && !isActiveTab )
       
  2909                     {
       
  2910                     feedback->InstantFeedback( this,
       
  2911                         ETouchFeedbackTab, 
       
  2912                         ETouchFeedbackVibra,
       
  2913                         aPointerEvent );
       
  2914                     }
       
  2915                 }
       
  2916             if ( !tabBackgroundUsed )
       
  2917                 {
       
  2918                 // In one tab layout handle the navigation always by
       
  2919                 // pointer position.
       
  2920                 newTab = -1;
       
  2921                 }
       
  2922 
       
  2923             // if the button up event occurs ouside tabgroup, ignore it.
       
  2924             if ( !Rect().Contains( aPointerEvent.iPosition ) || iExtension->iPointerDownTab != newTab )
       
  2925                 {
       
  2926                 iExtension->iPointerDownTab       = -1;
       
  2927                 iExtension->iPointerDownXPosition = -1;
       
  2928                 return ;
       
  2929                 }
       
  2930 
       
  2931             if ( newTab != iActiveTab &&
       
  2932                  newTab > -1 &&
       
  2933                  newTab == iExtension->iPointerDownTab &&
       
  2934                  iNumberOfTabsShown > 1 )
       
  2935                 {
       
  2936                 if ( iTabObserver )
       
  2937                     {
       
  2938                     TDirection direction = newTab > iActiveTab ? ERight : ELeft;
       
  2939 
       
  2940                     CancelTabAnimationEventTimer();
       
  2941 
       
  2942                     StartCycleAnimationL( direction, newTab );
       
  2943 
       
  2944                     SetActiveTabByIndex( ConvertTabIndex( newTab ) );
       
  2945 
       
  2946                     iTabObserver->TabChangedL( ConvertTabIndex( newTab ) );
       
  2947                     }
       
  2948 
       
  2949                 else
       
  2950                     {
       
  2951                     // Kludge: if there is no tab observer, we need to
       
  2952                     // generate a keyevent to the application so it knows
       
  2953                     // to activate the correct view.
       
  2954                     //
       
  2955                     // The real fix would be to update applications to
       
  2956                     // implement MAknTabObserver::TabChangedL and to
       
  2957                     // activate the correct view there.
       
  2958                     TInt tabsToSkip = newTab - iActiveTab;
       
  2959                     TKeyEvent code;
       
  2960                     code.iCode = EKeyRightArrow;
       
  2961                     code.iModifiers = iEikonEnv->WsSession().GetModifierState();
       
  2962                     code.iRepeats = 0; // some applications are ignoring repeated events
       
  2963                     if ( tabsToSkip < 0 )
       
  2964                         {
       
  2965                         code.iCode = EKeyLeftArrow;
       
  2966                         tabsToSkip = -tabsToSkip;
       
  2967                         }
       
  2968 
       
  2969                     for ( TInt i = 0; i < tabsToSkip; i++ )
       
  2970                         {
       
  2971                         iEikonEnv->SimulateKeyEventL( code, EEventKey );
       
  2972                         }
       
  2973                     }
       
  2974                 }
       
  2975             else
       
  2976                 {
       
  2977                 if ( newTab != iExtension->iPointerDownTab && iExtension->iPointerDownTab > -1 )
       
  2978                     {
       
  2979                     if ( newTab == -1 )
       
  2980                         {
       
  2981                         if ( iExtension->iPointerDownXPosition + KDragNavigationTolerance <
       
  2982                                  aPointerEvent.iPosition.iX )
       
  2983                             {
       
  2984                             newTab = iExtension->iPointerDownTab + 1;
       
  2985                             }
       
  2986                         else if ( iExtension->iPointerDownXPosition - KDragNavigationTolerance >
       
  2987                                       aPointerEvent.iPosition.iX )
       
  2988                             {
       
  2989                             newTab = iExtension->iPointerDownTab - 1;
       
  2990                             }
       
  2991                         else
       
  2992                             {
       
  2993                             newTab = iExtension->iPointerDownTab;
       
  2994                             }
       
  2995                         }
       
  2996 
       
  2997                     if ( iExtension->iPointerDownTab < newTab &&
       
  2998                          iActiveTab > LeftMostTabIndex() )
       
  2999                         {
       
  3000                         if ( iTabObserver )
       
  3001                             {
       
  3002                             CycleFocus( ELeft, EDrawNow );
       
  3003                             iTabObserver->TabChangedL( ConvertTabIndex( iActiveTab ) );
       
  3004                             }
       
  3005                         else
       
  3006                             {
       
  3007                             // Kludge: if there is no tab observer generate a keyevent to
       
  3008                             // instruct the application to change the view.
       
  3009                             TKeyEvent code;
       
  3010                             code.iCode = EKeyLeftArrow;
       
  3011                             iEikonEnv->SimulateKeyEventL( code, EEventKey );
       
  3012                             }
       
  3013                         }
       
  3014                     else if ( iExtension->iPointerDownTab > newTab &&
       
  3015                               iActiveTab < RightMostTabIndex() )
       
  3016                         {
       
  3017                         if ( iTabObserver )
       
  3018                             {
       
  3019                             CycleFocus( ERight, EDrawNow );
       
  3020                             iTabObserver->TabChangedL( ConvertTabIndex( iActiveTab ) );
       
  3021                             }
       
  3022                         else
       
  3023                             {
       
  3024                             // Kludge: if there is no tab observer generate a keyevent to
       
  3025                             // instruct the application to change the view.
       
  3026                             TKeyEvent code;
       
  3027                             code.iCode = EKeyRightArrow;
       
  3028                             iEikonEnv->SimulateKeyEventL( code, EEventKey );
       
  3029                             }
       
  3030                         }
       
  3031                     }
       
  3032                 }
       
  3033 
       
  3034             iExtension->iPointerDownTab       = -1;
       
  3035             iExtension->iPointerDownXPosition = -1;
       
  3036             }
       
  3037         }
       
  3038     }
       
  3039 
       
  3040 
       
  3041 EXPORT_C void* CAknTabGroup::ExtensionInterface( TUid /*aInterface*/ )
       
  3042     {
       
  3043     return NULL;
       
  3044     }
       
  3045 
       
  3046 
       
  3047 // ---------------------------------------------------------------------------
       
  3048 // CAknTabGroup::SetTabMultiColorMode
       
  3049 // ---------------------------------------------------------------------------
       
  3050 //
       
  3051 EXPORT_C void CAknTabGroup::SetTabMultiColorMode( TInt aTabId,
       
  3052                                                   TBool aMultiColor )
       
  3053     {
       
  3054     TInt tabIndex = ConvertTabIndex( TabIndexFromId( aTabId ) );
       
  3055     if ( tabIndex >= 0 && tabIndex < TabCount() )
       
  3056         {
       
  3057         iTabArray->At( tabIndex )->SetMultiColorMode( aMultiColor );
       
  3058         }
       
  3059     }
       
  3060 
       
  3061 
       
  3062 TBool CAknTabGroup::CycleFocus( TDirection aDirection, TDrawNow /*aDrawNow*/ )
       
  3063     {
       
  3064     if ( iActiveTab < 0 )
       
  3065         {
       
  3066         return EFalse;
       
  3067         }
       
  3068 
       
  3069     if ( AknStatuspaneUtils::FlatLayoutActive() )
       
  3070         {
       
  3071         SetDecoratorLayout( EFalse );
       
  3072         }
       
  3073      else
       
  3074         {
       
  3075         CancelTabAnimationEventTimer();
       
  3076         }
       
  3077 
       
  3078     TInt numTabs = TabCount();
       
  3079 
       
  3080     if ( ( iActiveTab <= 0 ) && ( aDirection==ELeft ) )
       
  3081         {
       
  3082         TInt event = MAknNavigationObserver::ENaviEventAlreadyLeftmostItem;
       
  3083         TRAP_IGNORE( ReportEventL(
       
  3084                 static_cast<MCoeControlObserver::TCoeEvent>( event ) ) );
       
  3085         return EFalse;
       
  3086         }
       
  3087     else if ( ( iActiveTab >= ( numTabs - 1 ) ) && ( aDirection==ERight ) )
       
  3088         {
       
  3089         TInt event = MAknNavigationObserver::ENaviEventAlreadyRightmostItem;
       
  3090         TRAP_IGNORE( ReportEventL(
       
  3091                 static_cast<MCoeControlObserver::TCoeEvent>( event ) ) );
       
  3092         return EFalse;
       
  3093         }
       
  3094 
       
  3095     TInt tabIndex = ( aDirection == ERight ) ? iActiveTab + 1 : iActiveTab - 1;
       
  3096 
       
  3097     CAknTab* thisTab = (*iTabArray)[tabIndex];
       
  3098 
       
  3099     // This starts the animation only if required.
       
  3100     TRAP_IGNORE( StartCycleAnimationL( aDirection, tabIndex ) );
       
  3101 
       
  3102     (*iTabArray)[iActiveTab]->SetFocus( EFalse, ENoDrawNow );
       
  3103     thisTab->SetFocus( ETrue, ENoDrawNow );
       
  3104 
       
  3105     SetActiveTabByIndex( ConvertTabIndex( tabIndex ) );
       
  3106 
       
  3107     return ETrue;
       
  3108     }
       
  3109 
       
  3110 
       
  3111 void CAknTabGroup::HandleTabStateChanged( CCoeControl* aControl )
       
  3112     {
       
  3113     const TInt numTabs = TabCount();
       
  3114 
       
  3115     if ( numTabs > 1 )
       
  3116         {
       
  3117         CAknTab* newTab = static_cast<CAknTab*>( aControl );
       
  3118         CArrayPtr<CAknTab>& tabArray = *iTabArray;
       
  3119 
       
  3120         TInt ii = 0;
       
  3121         for( ; ii < numTabs; ii++ )
       
  3122             {
       
  3123             if( tabArray[ii] == newTab )
       
  3124                 {
       
  3125                 break;
       
  3126                 }
       
  3127             }
       
  3128 
       
  3129         tabArray[iActiveTab]->SetFocus( EFalse, EDrawNow );
       
  3130         SetActiveTabByIndex( ConvertTabIndex( ii ) );
       
  3131         }
       
  3132     else
       
  3133         {
       
  3134         ReportNavigationEvent();
       
  3135         }
       
  3136     }
       
  3137 
       
  3138 
       
  3139 TInt CAknTabGroup::Index( TInt aTabId ) const
       
  3140     {
       
  3141     const TInt numTabs = iTabArray->Count();
       
  3142 
       
  3143     for (TInt ii = 0; ii < numTabs; ii++ )
       
  3144         {
       
  3145         CAknTab* thisTab=iTabArray->At(ii);
       
  3146         if ( thisTab->Id() == aTabId )
       
  3147             {
       
  3148             return ii;
       
  3149             }
       
  3150         }
       
  3151     return KErrNotFound;
       
  3152     }
       
  3153 
       
  3154 
       
  3155 // --------------------------------------------------------------------------
       
  3156 // Returns the index of the leftmost tab in the tab group.
       
  3157 // --------------------------------------------------------------------------
       
  3158 //
       
  3159 TInt CAknTabGroup::LeftMostTabIndex() const
       
  3160     {
       
  3161     TInt index = 0;
       
  3162     const TInt numTabs = TabCount();
       
  3163 
       
  3164     while ( iTabArray->At( index )->IsDimmed() )
       
  3165         {
       
  3166         if ( ++index >= numTabs )
       
  3167             {
       
  3168             return KErrNotFound;
       
  3169             }
       
  3170         }
       
  3171 
       
  3172     return index;
       
  3173     }
       
  3174 
       
  3175 
       
  3176 // --------------------------------------------------------------------------
       
  3177 // Returns the index of the rightmost tab in the tab group.
       
  3178 // --------------------------------------------------------------------------
       
  3179 //
       
  3180 TInt CAknTabGroup::RightMostTabIndex() const
       
  3181     {
       
  3182     TInt index = TabCount() - 1;
       
  3183 
       
  3184     if ( index >= 0 )
       
  3185         {
       
  3186         while ( iTabArray->At( index )->IsDimmed() )
       
  3187             {
       
  3188             if ( --index < 0 )
       
  3189                 {
       
  3190                 return KErrNotFound;
       
  3191                 }
       
  3192             }
       
  3193         return index;
       
  3194         }
       
  3195     else
       
  3196         {
       
  3197         return KErrNotFound;
       
  3198         }
       
  3199     }
       
  3200 
       
  3201 
       
  3202 // ---------------------------------------------------------------------------
       
  3203 // Reports a navigation event to the navi pane decorator.
       
  3204 // ---------------------------------------------------------------------------
       
  3205 //
       
  3206 void CAknTabGroup::ReportNavigationEvent()
       
  3207     {
       
  3208     TInt active   = ConvertTabIndex( ActiveTabIndex() );
       
  3209     TInt tabCount = TabCount();
       
  3210 
       
  3211     TInt event = MAknNavigationObserver::ENaviEventHandleNavigation;
       
  3212 
       
  3213     if ( tabCount <= 1 )
       
  3214         {
       
  3215         event = MAknNavigationObserver::ENaviEventOneItemExists;
       
  3216         }
       
  3217     else if ( active == 0 )
       
  3218         {
       
  3219         event = MAknNavigationObserver::ENaviEventLeftMostItemReached;
       
  3220         }
       
  3221     else if ( active >= ( tabCount - 1 ) )
       
  3222         {
       
  3223         event = MAknNavigationObserver::ENaviEventRightMostItemReached;
       
  3224         }
       
  3225 
       
  3226     TRAP_IGNORE( ReportEventL(
       
  3227         static_cast<MCoeControlObserver::TCoeEvent>( event ) ) );
       
  3228     }
       
  3229 
       
  3230 
       
  3231 void CAknTabGroup::LoadTabBitmapsL( TInt aNumberOfTabsShown, TBool aLongTabs )
       
  3232     {
       
  3233     TInt i = 0;
       
  3234     for ( i = 0; i < KTabNumberOfTabBitmaps; i++ )
       
  3235         {
       
  3236         delete( iTabBitmaps[i] );
       
  3237         iTabBitmaps[i] = NULL;
       
  3238         delete( iTabMaskBitmaps[i] );
       
  3239         iTabMaskBitmaps[i] = NULL;
       
  3240         }
       
  3241 
       
  3242     TInt first = KErrNotFound;  // Bitmap indexes to bitmap name array
       
  3243     TInt last  = KErrNotFound;
       
  3244 
       
  3245     // Figures out what tab background bitmaps are needed.
       
  3246     if ( aNumberOfTabsShown == 1 )
       
  3247         {
       
  3248         return;
       
  3249         }
       
  3250     else if ( aNumberOfTabsShown == 2 )
       
  3251         {
       
  3252         if ( aLongTabs )
       
  3253             {
       
  3254             first = KTabIndexOfFirstTabBitmapInTwoLongTabsSet;
       
  3255             last = KTabIndexOfLastTabBitmapInTwoLongTabsSet;
       
  3256             }
       
  3257         else
       
  3258             {
       
  3259             first = KTabIndexOfFirstTabBitmapInTwoTabsSet;
       
  3260             last = KTabIndexOfLastTabBitmapInTwoTabsSet;
       
  3261             }
       
  3262         }
       
  3263     else if ( aNumberOfTabsShown == 3 )
       
  3264         {
       
  3265         if ( aLongTabs )
       
  3266             {
       
  3267             first = KTabIndexOfFirstTabBitmapInThreeLongTabsSet;
       
  3268             last = KTabIndexOfLastTabBitmapInThreeLongTabsSet;
       
  3269             }
       
  3270         else
       
  3271             {
       
  3272             first = KTabIndexOfFirstTabBitmapInThreeTabsSet;
       
  3273             last = KTabIndexOfLastTabBitmapInThreeTabsSet;
       
  3274             }
       
  3275         }
       
  3276     else if ( aNumberOfTabsShown == 4 )
       
  3277         {
       
  3278         first = KTabIndexOfFirstTabBitmapInFourTabsSet;
       
  3279         last = KTabIndexOfLastTabBitmapInFourTabsSet;
       
  3280         }
       
  3281 
       
  3282     if ( first < 0 )
       
  3283         {
       
  3284         return;
       
  3285         }
       
  3286 
       
  3287     TRect rect( ParentRect( iExtension->iNaviArrowsUsed ) );
       
  3288 
       
  3289     if ( iExtension &&
       
  3290          iExtension->iTabSvgGraphics &&
       
  3291          iExtension->iTabSvgGraphics->TabGroupBackgroundAvailable() )
       
  3292         {
       
  3293         // The background graphics are no more created in this case, instead
       
  3294         // backgrounds are drawn to a single double buffer
       
  3295         // (and other double buffer for stacon).
       
  3296         CAknTabGroupGraphics* tabgraphics = iExtension->iTabSvgGraphics;
       
  3297 
       
  3298         tabgraphics->SetTabGroupBackgroundParent(
       
  3299             ParentRect( iExtension->iNaviArrowsUsed ) );
       
  3300         }
       
  3301     else
       
  3302         {
       
  3303         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  3304 
       
  3305         TAknWindowLineLayout layout;
       
  3306         CurrentLayout( layout );
       
  3307         TAknLayoutRect layoutRect;
       
  3308         layoutRect.LayoutRect( rect, layout );
       
  3309         TSize size ( layoutRect.Rect().Size() );
       
  3310 
       
  3311         // This code is for legacy bitmaps, we should newer go here anymore.
       
  3312         if ( skin )
       
  3313             {
       
  3314             for ( i = first; i <= last; i++ )
       
  3315                 {
       
  3316                 TAknsItemID iid;
       
  3317                 iid.Set( EAknsMajorAvkon, iBitmapNames[i] );
       
  3318                 AknsUtils::CreateIconL( skin,
       
  3319                                         iid,
       
  3320                                         iTabBitmaps[i],
       
  3321                                         iTabMaskBitmaps[i],
       
  3322                                         KAvkonBitmapFile,
       
  3323                                         iBitmapNames[i],
       
  3324                                         iBitmapMaskNames[i] );
       
  3325 
       
  3326                 AknIconUtils::SetSize( iTabBitmaps[i],
       
  3327                                        size,
       
  3328                                        EAspectRatioNotPreserved );
       
  3329                 }
       
  3330             }
       
  3331         else
       
  3332             {
       
  3333             TAknLayoutRect layoutRect;
       
  3334             layoutRect.LayoutRect( rect,
       
  3335                 AknLayoutScalable_Avkon::navi_tabs_2_pane() );
       
  3336 
       
  3337             // Loads only those tab background bitmaps that are needed.
       
  3338             for ( i = first; i <= last; i++ )
       
  3339                 {
       
  3340                 // Delete (in case skin loading created some bitmaps)
       
  3341                 delete iTabBitmaps[i];
       
  3342                 iTabBitmaps[i] = NULL;
       
  3343                 delete iTabMaskBitmaps[i];
       
  3344                 iTabMaskBitmaps[i] = NULL;
       
  3345 
       
  3346                 AknIconUtils::CreateIconL( iTabBitmaps[i],
       
  3347                                            iTabMaskBitmaps[i],
       
  3348                                            KAvkonBitmapFile,
       
  3349                                            iBitmapNames[i],
       
  3350                                            iBitmapMaskNames[i] );
       
  3351 
       
  3352                 // Validate all loaded bitmaps by setting their sizes.
       
  3353                 AknIconUtils::SetSize( iTabBitmaps[i],
       
  3354                                        layoutRect.Rect().Size(),
       
  3355                                        EAspectRatioNotPreserved );
       
  3356                 }
       
  3357             }
       
  3358         }
       
  3359 
       
  3360     InitTabAnimationL();
       
  3361     }
       
  3362 
       
  3363 
       
  3364 void CAknTabGroup::HandleResourceChange( TInt aType )
       
  3365     {
       
  3366     // First forward event to child controls,
       
  3367     // skin change must be forwarded to ALL tabs...
       
  3368     if( aType == KAknsMessageSkinChange || aType == KEikColorResourceChange )
       
  3369         {
       
  3370         TInt numTabs = TabCount();
       
  3371         for ( TInt i = 0; i < numTabs; i++ )
       
  3372             {
       
  3373             iTabArray->At(i)->HandleResourceChange( aType );
       
  3374             }
       
  3375         }
       
  3376     else
       
  3377         {
       
  3378         CCoeControl::HandleResourceChange( aType );
       
  3379         }
       
  3380 
       
  3381     // ...now handle events
       
  3382     if ( aType == KAknsMessageSkinChange )
       
  3383         {
       
  3384         // If this fails, svg tab graphics are not available.
       
  3385         // Then defaults to bitmaps if possible.
       
  3386         TRAP_IGNORE( InitTabGroupGraphicsL() );
       
  3387         TRAP_IGNORE( LoadTabBitmapsL( iNumberOfTabsShown, iLongTabs ) );
       
  3388         }
       
  3389 
       
  3390     if ( aType == KEikDynamicLayoutVariantSwitch )
       
  3391         {
       
  3392         // If double buffers are used in this layout,
       
  3393         // then initialize its layouts at this point.
       
  3394         if ( iExtension &&
       
  3395              iExtension->iTabSvgGraphics &&
       
  3396              iExtension->iTabSvgGraphics->TabGroupBackgroundAvailable() )
       
  3397                 {
       
  3398                 TRAP_IGNORE( SwitchTabLayoutL() );
       
  3399 
       
  3400                 iExtension->iTabSvgGraphics->SetTabGroupBackgroundParent(
       
  3401                     ParentRect( iExtension->iNaviArrowsUsed ) );
       
  3402 
       
  3403                 iExtension->iTabBackgroundLayout.iUse = EFalse;
       
  3404                 TRAP_IGNORE( iExtension->iTabSvgGraphics->DrawTabGroupBackgroundL(
       
  3405                                 CAknTabGroupGraphics::ENoDraw,
       
  3406                                 iLongTabs,
       
  3407                                 iNumberOfTabsShown,
       
  3408                                 1,
       
  3409                                 NULL,
       
  3410                                 iExtension->iTabBackgroundLayout,
       
  3411                                 CAknTabGroupGraphics::ENone ) );
       
  3412                 iExtension->iTabBackgroundLayout.iUse = ETrue;
       
  3413                 SetDecoratorLayout( EFalse );
       
  3414                 }
       
  3415 
       
  3416         if ( iExtension )
       
  3417             {
       
  3418             iExtension->iNarrowTabLayout = EFalse;
       
  3419             }
       
  3420 
       
  3421         if ( !COMPARE_BOOLS( iMirrored, AknLayoutUtils::LayoutMirrored() ) )
       
  3422             {
       
  3423             TInt active = ActiveTabIndex();
       
  3424             TRAPD( err, ReverseTabOrderL() );
       
  3425             if ( err == KErrNone )
       
  3426                 {
       
  3427                 iMirrored = AknLayoutUtils::LayoutMirrored();
       
  3428                 SetActiveTabByIndex( active );
       
  3429                 }
       
  3430             }
       
  3431 
       
  3432         SizeChanged();
       
  3433         TRAP_IGNORE( LoadTabBitmapsL( iNumberOfTabsShown, iLongTabs ) );
       
  3434         }
       
  3435     }
       
  3436 
       
  3437 
       
  3438 TBool CAknTabGroup::TabsVisibleInCurrentLayout() const
       
  3439     {
       
  3440     TBool tabsVisible = ETrue;
       
  3441 
       
  3442     // Tabs are not shown in idle layouts and in portrait flat
       
  3443     // status pane layout because there's not enough space.
       
  3444     if ( AknStatuspaneUtils::IdleLayoutActive() ||
       
  3445          ( AknStatuspaneUtils::FlatLayoutActive() &&
       
  3446            !Layout_Meta_Data::IsLandscapeOrientation() ) )
       
  3447         {
       
  3448         tabsVisible = EFalse;  // No tabs shown
       
  3449         }
       
  3450 
       
  3451     return tabsVisible;
       
  3452     }
       
  3453 
       
  3454 
       
  3455 void CAknTabGroup::CurrentLayout( TAknWindowLineLayout& aLayout ) const
       
  3456     {
       
  3457     TAknWindowLineLayout layout( AknLayoutScalable_Avkon::navi_tabs_2_pane() );
       
  3458 
       
  3459     if ( iLongTabs )
       
  3460         {
       
  3461         switch ( iNumberOfTabsShown )
       
  3462             {
       
  3463             case 3:
       
  3464                 {
       
  3465                 layout = AknLayoutScalable_Avkon::navi_tabs_3_long_pane();
       
  3466                 break;
       
  3467                 }
       
  3468             default:
       
  3469                 {
       
  3470                 layout = AknLayoutScalable_Avkon::navi_tabs_2_long_pane();
       
  3471                 break;
       
  3472                 }
       
  3473             }
       
  3474         }
       
  3475     else
       
  3476         {
       
  3477         switch ( iNumberOfTabsShown )
       
  3478             {
       
  3479             case 4:
       
  3480                 {
       
  3481                 layout = AknLayoutScalable_Avkon::navi_tabs_4_pane();
       
  3482                 break;
       
  3483                 }
       
  3484             case 3:
       
  3485                 {
       
  3486                 layout = AknLayoutScalable_Avkon::navi_tabs_3_pane();
       
  3487                 break;
       
  3488                 }
       
  3489             default:
       
  3490                 {
       
  3491                 break;
       
  3492                 }
       
  3493             }
       
  3494         }
       
  3495 
       
  3496     aLayout = layout;
       
  3497     }
       
  3498 
       
  3499 
       
  3500 // ---------------------------------------------------------------------------
       
  3501 // Handles navication decorator events scrolling tabs to left/right
       
  3502 // Depending on event
       
  3503 // ---------------------------------------------------------------------------
       
  3504 //
       
  3505 EXPORT_C void CAknTabGroup::HandleNaviDecoratorEventL( TInt aEventID )
       
  3506     {
       
  3507     if ( AknLayoutUtils::PenEnabled() )
       
  3508         {
       
  3509         switch ( aEventID )
       
  3510             {
       
  3511             case MAknNaviDecoratorObserver::EAknNaviDecoratorEventLeftTabArrow:
       
  3512                 {
       
  3513                 if ( iTabObserver )
       
  3514                     {
       
  3515                     if ( iActiveTab != LeftMostTabIndex() )
       
  3516                         {
       
  3517                         CycleFocus( ELeft, EDrawNow );
       
  3518                         }
       
  3519                     iTabObserver->TabChangedL( ConvertTabIndex( iActiveTab ) );
       
  3520                     }
       
  3521                 else
       
  3522                     {
       
  3523                     // Kludge: if there is no tab observer generate a keyevent to
       
  3524                     // instruct the application to change the view.
       
  3525                     TKeyEvent code;
       
  3526                     code.iCode = EKeyLeftArrow;
       
  3527                     iEikonEnv->SimulateKeyEventL( code, EEventKey );
       
  3528                     }
       
  3529                 }
       
  3530                 break;
       
  3531 
       
  3532             case MAknNaviDecoratorObserver::EAknNaviDecoratorEventRightTabArrow:
       
  3533                 {
       
  3534                 if ( iTabObserver )
       
  3535                     {
       
  3536                     if ( iActiveTab != RightMostTabIndex() )
       
  3537                         {
       
  3538                         CycleFocus( ERight, EDrawNow );
       
  3539                         }
       
  3540                     iTabObserver->TabChangedL( ConvertTabIndex( iActiveTab ) );
       
  3541                     }
       
  3542                 else
       
  3543                     {
       
  3544                     // Kludge: if there is no tab observer generate a keyevent to
       
  3545                     // instruct the application to change the view.
       
  3546                     TKeyEvent code;
       
  3547                     code.iCode = EKeyRightArrow;
       
  3548                     iEikonEnv->SimulateKeyEventL( code, EEventKey );
       
  3549                     }
       
  3550                 }
       
  3551                 break;
       
  3552 
       
  3553             default:
       
  3554                 break;
       
  3555             }
       
  3556         }
       
  3557     }
       
  3558 
       
  3559 EXPORT_C void CAknTabGroup::Reserved1()
       
  3560     {
       
  3561     }
       
  3562 
       
  3563 EXPORT_C void CAknTabGroup::Reserved2()
       
  3564     {
       
  3565     }
       
  3566 
       
  3567 EXPORT_C void CAknTabGroup::Reserved3()
       
  3568     {
       
  3569     }
       
  3570 
       
  3571 void CAknTabGroup::InitTabGroupGraphicsL()
       
  3572     {
       
  3573     if ( iExtension && iExtension->iTabSvgGraphics )
       
  3574         {
       
  3575         delete iExtension->iTabSvgGraphics;
       
  3576         iExtension->iTabSvgGraphics = NULL;
       
  3577         iExtension->iTabSvgGraphics = CAknTabGroupGraphics::NewL();
       
  3578         }
       
  3579     }
       
  3580 
       
  3581 
       
  3582 // ---------------------------------------------------------------------------
       
  3583 // Starts the animation timer.
       
  3584 // ---------------------------------------------------------------------------
       
  3585 //
       
  3586 void CAknTabGroup::InitTabAnimationEventTimer()
       
  3587     {
       
  3588     TInt delay = 1;
       
  3589     iExtension->iTabAnimationTimer->Cancel();
       
  3590     iExtension->iTabAnimationTimer->Start(
       
  3591         TTimeIntervalMicroSeconds32( delay ),
       
  3592         TTimeIntervalMicroSeconds32( KAnimationEventInterval ),
       
  3593         TCallBack( CAknTabGroup::TabAnimationEvent, this ) );
       
  3594     }
       
  3595 
       
  3596 
       
  3597 // ---------------------------------------------------------------------------
       
  3598 // Cancels the animation timer.
       
  3599 // ---------------------------------------------------------------------------
       
  3600 //
       
  3601 void CAknTabGroup::CancelTabAnimationEventTimer()
       
  3602     {
       
  3603     if ( iExtension &&
       
  3604          iExtension->iTabAnimationTimer &&
       
  3605          iExtension->iTabAnimationTimer->IsActive() )
       
  3606         {
       
  3607         iExtension->iTabAnimationTimer->Cancel();
       
  3608         iExtension->iAmountOfDoneAnimationEvents = 0;
       
  3609 
       
  3610         if ( iExtension->iTabAnimationType ==
       
  3611                  CAknTabGroupExtension::ETabCycleAnimation )
       
  3612             {
       
  3613             iExtension->iTabCycleAnimationOngoing = EFalse;
       
  3614 
       
  3615             iExtension->iTabsHidden = CAknTabGroupGraphics::EOnBothSides;
       
  3616             if ( iFirstShownTab == 0 )
       
  3617                 {
       
  3618                 iExtension->iTabsHidden = CAknTabGroupGraphics::EOnRightSide;
       
  3619                 }
       
  3620             else if ( iFirstShownTab == TabCount() - iNumberOfTabsShown )
       
  3621                 {
       
  3622                 iExtension->iTabsHidden = CAknTabGroupGraphics::EOnLeftSide;
       
  3623                 }
       
  3624             }
       
  3625 
       
  3626         iExtension->iTabAnimationType =
       
  3627             CAknTabGroupExtension::ENoAnimation;
       
  3628         }
       
  3629     }
       
  3630 
       
  3631 TInt CAknTabGroup::TabAnimationEvent( TAny* aPtr )
       
  3632     {
       
  3633     static_cast<CAknTabGroup*>( aPtr )->DoTabAnimationEvent();
       
  3634     return ETrue;
       
  3635     }
       
  3636 
       
  3637 
       
  3638 // ---------------------------------------------------------------------------
       
  3639 // Animation timer callback.
       
  3640 // ---------------------------------------------------------------------------
       
  3641 //
       
  3642 void CAknTabGroup::DoTabAnimationEvent()
       
  3643     {
       
  3644     // In this method we calculate the new positions of tabs during
       
  3645     // the animation cycle.
       
  3646 
       
  3647     // We do this safety check because of possible problems with layout data.
       
  3648     iExtension->iAmountOfDoneAnimationEvents++;
       
  3649     if ( iExtension->iAmountOfDoneAnimationEvents > KMaxAmountOfAnimationEvents )
       
  3650         {
       
  3651         CancelTabAnimationEventTimer();
       
  3652         SizeChanged();
       
  3653         TRAP_IGNORE( InitTabAnimationL() );
       
  3654         DrawDeferred();
       
  3655         return;
       
  3656         }
       
  3657 
       
  3658     TBool firstDone  = EFalse;
       
  3659     TBool secondDone = EFalse;
       
  3660     TBool thirdDone  = EFalse;
       
  3661     TBool fourthDone = EFalse;
       
  3662 
       
  3663     if ( iExtension->iTabAnimationType ==
       
  3664              CAknTabGroupExtension::ETabCycleAnimation )
       
  3665         {
       
  3666         if ( iExtension->iAmountOfDoneAnimationEvents == 1 )
       
  3667             {
       
  3668             // Calculate the initial distance to go on the first event.
       
  3669             iExtension->iTabCycleAnimationDistanceLeft =
       
  3670                 iExtension->iTabBackgroundLayout.iSecondTab.iLeft.iTl.iX -
       
  3671                 iExtension->iTabBackgroundLayout.iFirstTab.iLeft.iTl.iX;
       
  3672             }
       
  3673 
       
  3674         // Calculate the step size used in this frame, currently
       
  3675         // using ease-out.
       
  3676         TInt stepSize = iExtension->iTabCycleAnimationDistanceLeft /
       
  3677                             KMinimumCycleAnimationStepSize;
       
  3678 
       
  3679         // Sanity check, ensure that animation doesn't move too slow.
       
  3680         if ( stepSize < KMinimumCycleAnimationStepSize )
       
  3681             {
       
  3682             stepSize = KMinimumCycleAnimationStepSize;
       
  3683             }
       
  3684 
       
  3685         if ( iExtension->iTabCycleAnimationDirection ==
       
  3686                  CAknTabGroup::ERight )
       
  3687             {
       
  3688             // Adjust the step size sign according to the direction
       
  3689             // we're moving to.
       
  3690             stepSize = -stepSize;
       
  3691             }
       
  3692 
       
  3693         // Decrease the distance left by the step size.
       
  3694         iExtension->iTabCycleAnimationDistanceLeft -= Abs( stepSize );
       
  3695 
       
  3696         // Move the tabs.
       
  3697         iExtension->iTabSvgGraphics->AdjustTabLayoutRect(
       
  3698             iExtension->iNextTabBackgroundLayout.iHiddenTabLeft, stepSize, 0 );
       
  3699         iExtension->iTabSvgGraphics->AdjustTabLayoutRect(
       
  3700             iExtension->iNextTabBackgroundLayout.iFirstTab, stepSize, 0 );
       
  3701         iExtension->iTabSvgGraphics->AdjustTabLayoutRect(
       
  3702             iExtension->iNextTabBackgroundLayout.iSecondTab, stepSize, 0 );
       
  3703         iExtension->iTabSvgGraphics->AdjustTabLayoutRect(
       
  3704             iExtension->iNextTabBackgroundLayout.iThirdTab, stepSize, 0 );
       
  3705         iExtension->iTabSvgGraphics->AdjustTabLayoutRect(
       
  3706             iExtension->iNextTabBackgroundLayout.iHiddenTabRight, stepSize, 0 );
       
  3707         }
       
  3708     else
       
  3709         {
       
  3710         // This seems to be quite ok speed for the animation.
       
  3711         TInt defaultStepSize = Rect().Width() / KLayoutSwitchAnimationSpeed;
       
  3712 
       
  3713         // Sanity check
       
  3714         if ( defaultStepSize == 0 )
       
  3715             {
       
  3716             defaultStepSize = 1;
       
  3717             }
       
  3718 
       
  3719         // First find out where we are moving, how far is the destination.
       
  3720         TInt firstTabHorizontalDistanceLeft  =
       
  3721         iExtension->iNextTabBackgroundLayout.iFirstTab.iLeft.iTl.iX -
       
  3722                 iExtension->iTabBackgroundLayout.iFirstTab.iLeft.iTl.iX;
       
  3723 
       
  3724         TInt secondTabHorizontalDistanceLeft =
       
  3725         iExtension->iNextTabBackgroundLayout.iSecondTab.iLeft.iTl.iX -
       
  3726                 iExtension->iTabBackgroundLayout.iSecondTab.iLeft.iTl.iX;
       
  3727 
       
  3728         TInt thirdTabHorizontalDistanceLeft  =
       
  3729         iExtension->iNextTabBackgroundLayout.iThirdTab.iLeft.iTl.iX -
       
  3730                 iExtension->iTabBackgroundLayout.iThirdTab.iLeft.iTl.iX;
       
  3731 
       
  3732         TInt fourthTabHorizontalDistanceLeft =
       
  3733         iExtension->iNextTabBackgroundLayout.iFourthTab.iLeft.iTl.iX -
       
  3734                 iExtension->iTabBackgroundLayout.iFourthTab.iLeft.iTl.iX;
       
  3735 
       
  3736         TInt firstTabHorizontalDistanceMiddle  =
       
  3737         iExtension->iNextTabBackgroundLayout.iFirstTab.iMiddle.iTl.iX -
       
  3738                 iExtension->iTabBackgroundLayout.iFirstTab.iMiddle.iTl.iX;
       
  3739 
       
  3740         TInt secondTabHorizontalDistanceMiddle =
       
  3741         iExtension->iNextTabBackgroundLayout.iSecondTab.iMiddle.iTl.iX -
       
  3742                 iExtension->iTabBackgroundLayout.iSecondTab.iMiddle.iTl.iX;
       
  3743 
       
  3744         TInt thirdTabHorizontalDistanceMiddle  =
       
  3745         iExtension->iNextTabBackgroundLayout.iThirdTab.iMiddle.iTl.iX -
       
  3746                 iExtension->iTabBackgroundLayout.iThirdTab.iMiddle.iTl.iX;
       
  3747 
       
  3748         TInt fourthTabHorizontalDistanceMiddle =
       
  3749         iExtension->iNextTabBackgroundLayout.iFourthTab.iMiddle.iTl.iX -
       
  3750                 iExtension->iTabBackgroundLayout.iFourthTab.iMiddle.iTl.iX;
       
  3751 
       
  3752         TInt firstTabHorizontalDistanceRight  =
       
  3753         iExtension->iNextTabBackgroundLayout.iFirstTab.iRight.iTl.iX -
       
  3754                 iExtension->iTabBackgroundLayout.iFirstTab.iRight.iTl.iX;
       
  3755 
       
  3756         TInt secondTabHorizontalDistanceRight =
       
  3757         iExtension->iNextTabBackgroundLayout.iSecondTab.iRight.iTl.iX -
       
  3758                 iExtension->iTabBackgroundLayout.iSecondTab.iRight.iTl.iX;
       
  3759 
       
  3760         TInt thirdTabHorizontalDistanceRight  =
       
  3761         iExtension->iNextTabBackgroundLayout.iThirdTab.iRight.iTl.iX -
       
  3762                 iExtension->iTabBackgroundLayout.iThirdTab.iRight.iTl.iX;
       
  3763 
       
  3764         TInt fourthTabHorizontalDistanceRight =
       
  3765         iExtension->iNextTabBackgroundLayout.iFourthTab.iRight.iTl.iX -
       
  3766                 iExtension->iTabBackgroundLayout.iFourthTab.iRight.iTl.iX;
       
  3767 
       
  3768         TInt usedStepSizeForFirstTabLeft  = defaultStepSize;
       
  3769         TInt usedStepSizeForSecondTabLeft = defaultStepSize;
       
  3770         TInt usedStepSizeForThirdTabLeft  = defaultStepSize;
       
  3771         TInt usedStepSizeForFourthTabLeft = defaultStepSize;
       
  3772 
       
  3773         TInt usedStepSizeForFirstTabMiddle  = defaultStepSize;
       
  3774         TInt usedStepSizeForSecondTabMiddle = defaultStepSize;
       
  3775         TInt usedStepSizeForThirdTabMiddle  = defaultStepSize;
       
  3776         TInt usedStepSizeForFourthTabMiddle = defaultStepSize;
       
  3777 
       
  3778         TInt usedStepSizeForFirstTabRight  = defaultStepSize;
       
  3779         TInt usedStepSizeForSecondTabRight = defaultStepSize;
       
  3780         TInt usedStepSizeForThirdTabRight  = defaultStepSize;
       
  3781         TInt usedStepSizeForFourthTabRight = defaultStepSize;
       
  3782 
       
  3783 
       
  3784         // If we are close to end, then adjust the step size. Also if we are moving to normal layout
       
  3785         // from narrow, do it with one big step.
       
  3786         if ( Abs( firstTabHorizontalDistanceLeft ) < Abs( usedStepSizeForFirstTabLeft ) ||
       
  3787              !NarrowTabLayoutNext() )
       
  3788             {
       
  3789             usedStepSizeForFirstTabLeft = Abs( firstTabHorizontalDistanceLeft );
       
  3790             }
       
  3791         if ( Abs( firstTabHorizontalDistanceMiddle ) < Abs( usedStepSizeForFirstTabMiddle ) ||
       
  3792              !NarrowTabLayoutNext() )
       
  3793             {
       
  3794             usedStepSizeForFirstTabMiddle = Abs( firstTabHorizontalDistanceMiddle );
       
  3795             }
       
  3796         if ( Abs( firstTabHorizontalDistanceRight ) < Abs( usedStepSizeForFirstTabRight ) ||
       
  3797              !NarrowTabLayoutNext() )
       
  3798             {
       
  3799             usedStepSizeForFirstTabRight = Abs( firstTabHorizontalDistanceRight );
       
  3800             }
       
  3801 
       
  3802         if ( Abs( secondTabHorizontalDistanceLeft ) < Abs( usedStepSizeForSecondTabLeft ) ||
       
  3803              !NarrowTabLayoutNext() )
       
  3804             {
       
  3805             usedStepSizeForSecondTabLeft = Abs( secondTabHorizontalDistanceLeft );
       
  3806             }
       
  3807         if ( Abs( secondTabHorizontalDistanceMiddle ) < Abs( usedStepSizeForSecondTabMiddle ) ||
       
  3808              !NarrowTabLayoutNext() )
       
  3809             {
       
  3810             usedStepSizeForSecondTabMiddle = Abs( secondTabHorizontalDistanceMiddle );
       
  3811             }
       
  3812         if ( Abs( secondTabHorizontalDistanceRight ) < Abs( usedStepSizeForSecondTabRight ) ||
       
  3813              !NarrowTabLayoutNext() )
       
  3814             {
       
  3815             usedStepSizeForSecondTabRight = Abs( secondTabHorizontalDistanceRight );
       
  3816             }
       
  3817 
       
  3818         if ( Abs( thirdTabHorizontalDistanceLeft ) < Abs( usedStepSizeForThirdTabLeft ) ||
       
  3819              !NarrowTabLayoutNext() )
       
  3820             {
       
  3821             usedStepSizeForThirdTabLeft = Abs(thirdTabHorizontalDistanceLeft);
       
  3822             }
       
  3823         if ( Abs( thirdTabHorizontalDistanceMiddle ) < Abs( usedStepSizeForThirdTabMiddle ) ||
       
  3824              !NarrowTabLayoutNext() )
       
  3825             {
       
  3826             usedStepSizeForThirdTabMiddle = Abs(thirdTabHorizontalDistanceMiddle);
       
  3827             }
       
  3828         if ( Abs( thirdTabHorizontalDistanceRight ) < Abs( usedStepSizeForThirdTabRight) ||
       
  3829              !NarrowTabLayoutNext() )
       
  3830             {
       
  3831             usedStepSizeForThirdTabRight = Abs(thirdTabHorizontalDistanceRight);
       
  3832             }
       
  3833 
       
  3834         if ( Abs( fourthTabHorizontalDistanceLeft ) < Abs( usedStepSizeForFourthTabLeft ) ||
       
  3835              !NarrowTabLayoutNext() )
       
  3836             {
       
  3837             usedStepSizeForFourthTabLeft = Abs(fourthTabHorizontalDistanceLeft);
       
  3838             }
       
  3839         if ( Abs( fourthTabHorizontalDistanceMiddle ) < Abs( usedStepSizeForFourthTabMiddle ) ||
       
  3840              !NarrowTabLayoutNext() )
       
  3841             {
       
  3842             usedStepSizeForFourthTabMiddle = Abs(fourthTabHorizontalDistanceMiddle);
       
  3843             }
       
  3844         if ( Abs( fourthTabHorizontalDistanceRight ) < Abs( usedStepSizeForFourthTabRight ) ||
       
  3845              !NarrowTabLayoutNext() )
       
  3846             {
       
  3847             usedStepSizeForFourthTabRight = Abs(fourthTabHorizontalDistanceRight);
       
  3848             }
       
  3849 
       
  3850 
       
  3851         // First tab
       
  3852         if ( firstTabHorizontalDistanceLeft < 0 )
       
  3853             {
       
  3854             usedStepSizeForFirstTabLeft = -usedStepSizeForFirstTabLeft;
       
  3855             }
       
  3856 
       
  3857         if ( firstTabHorizontalDistanceMiddle < 0 )
       
  3858             {
       
  3859             usedStepSizeForFirstTabMiddle = -usedStepSizeForFirstTabMiddle;
       
  3860             }
       
  3861 
       
  3862         if ( firstTabHorizontalDistanceRight < 0 )
       
  3863             {
       
  3864             usedStepSizeForFirstTabRight = -usedStepSizeForFirstTabRight;
       
  3865             }
       
  3866 
       
  3867     iExtension->iTabBackgroundLayout.iFirstTab.iLeft.Move( usedStepSizeForFirstTabLeft, 0 );
       
  3868     iExtension->iTabBackgroundLayout.iFirstTab.iRight.Move( usedStepSizeForFirstTabRight, 0 );
       
  3869 
       
  3870     iExtension->iTabBackgroundLayout.iFirstTab.iMiddle.iTl.iX =
       
  3871         iExtension->iTabBackgroundLayout.iFirstTab.iLeft.iBr.iX;
       
  3872 
       
  3873     iExtension->iTabBackgroundLayout.iFirstTab.iMiddle.iBr.iX =
       
  3874         iExtension->iTabBackgroundLayout.iFirstTab.iRight.iTl.iX;
       
  3875 
       
  3876         if ( ( iExtension->iNextTabBackgroundLayout.iFirstTab.iLeft.iTl.iX -
       
  3877                    iExtension->iTabBackgroundLayout.iFirstTab.iLeft.iTl.iX == 0 ) &&
       
  3878              ( iExtension->iNextTabBackgroundLayout.iFirstTab.iMiddle.iTl.iX -
       
  3879                    iExtension->iTabBackgroundLayout.iFirstTab.iMiddle.iTl.iX == 0 ) &&
       
  3880              ( iExtension->iNextTabBackgroundLayout.iFirstTab.iRight.iTl.iX -
       
  3881                    iExtension->iTabBackgroundLayout.iFirstTab.iRight.iTl.iX == 0 ) )
       
  3882             {
       
  3883             firstDone = ETrue;
       
  3884             }
       
  3885 
       
  3886         // Second tab
       
  3887         if ( secondTabHorizontalDistanceLeft < 0 )
       
  3888             {
       
  3889             usedStepSizeForSecondTabLeft = -usedStepSizeForSecondTabLeft;
       
  3890             }
       
  3891         if ( secondTabHorizontalDistanceMiddle < 0 )
       
  3892             {
       
  3893             usedStepSizeForSecondTabMiddle = -usedStepSizeForSecondTabMiddle;
       
  3894             }
       
  3895         if ( secondTabHorizontalDistanceRight < 0 )
       
  3896             {
       
  3897             usedStepSizeForSecondTabRight = -usedStepSizeForSecondTabRight;
       
  3898             }
       
  3899 
       
  3900     iExtension->iTabBackgroundLayout.iSecondTab.iLeft.Move(usedStepSizeForSecondTabLeft,0);
       
  3901     iExtension->iTabBackgroundLayout.iSecondTab.iRight.Move(usedStepSizeForSecondTabRight,0);
       
  3902 
       
  3903     iExtension->iTabBackgroundLayout.iSecondTab.iMiddle.iTl.iX =
       
  3904         iExtension->iTabBackgroundLayout.iSecondTab.iLeft.iBr.iX;
       
  3905 
       
  3906     iExtension->iTabBackgroundLayout.iSecondTab.iMiddle.iBr.iX =
       
  3907         iExtension->iTabBackgroundLayout.iSecondTab.iRight.iTl.iX;
       
  3908 
       
  3909         if ( ( iExtension->iNextTabBackgroundLayout.iSecondTab.iLeft.iTl.iX -
       
  3910                    iExtension->iTabBackgroundLayout.iSecondTab.iLeft.iTl.iX == 0 ) &&
       
  3911              ( iExtension->iNextTabBackgroundLayout.iSecondTab.iMiddle.iTl.iX -
       
  3912                    iExtension->iTabBackgroundLayout.iSecondTab.iMiddle.iTl.iX == 0 ) &&
       
  3913              ( iExtension->iNextTabBackgroundLayout.iSecondTab.iRight.iTl.iX -
       
  3914                    iExtension->iTabBackgroundLayout.iSecondTab.iRight.iTl.iX == 0 ) )
       
  3915             {
       
  3916             secondDone = ETrue;
       
  3917             }
       
  3918 
       
  3919         // Third tab
       
  3920         if ( thirdTabHorizontalDistanceLeft < 0 )
       
  3921             {
       
  3922             usedStepSizeForThirdTabLeft = -usedStepSizeForThirdTabLeft;
       
  3923             }
       
  3924         if ( thirdTabHorizontalDistanceMiddle < 0 )
       
  3925             {
       
  3926             usedStepSizeForThirdTabMiddle = -usedStepSizeForThirdTabMiddle;
       
  3927             }
       
  3928         if ( thirdTabHorizontalDistanceRight < 0 )
       
  3929             {
       
  3930             usedStepSizeForThirdTabRight = -usedStepSizeForThirdTabRight;
       
  3931             }
       
  3932 
       
  3933     iExtension->iTabBackgroundLayout.iThirdTab.iLeft.Move(usedStepSizeForThirdTabLeft,0);
       
  3934     iExtension->iTabBackgroundLayout.iThirdTab.iRight.Move(usedStepSizeForThirdTabRight,0);
       
  3935 
       
  3936     iExtension->iTabBackgroundLayout.iThirdTab.iMiddle.iTl.iX =
       
  3937         iExtension->iTabBackgroundLayout.iThirdTab.iLeft.iBr.iX;
       
  3938 
       
  3939     iExtension->iTabBackgroundLayout.iThirdTab.iMiddle.iBr.iX =
       
  3940         iExtension->iTabBackgroundLayout.iThirdTab.iRight.iTl.iX;
       
  3941 
       
  3942         if ( ( iExtension->iNextTabBackgroundLayout.iThirdTab.iLeft.iTl.iX -
       
  3943                    iExtension->iTabBackgroundLayout.iThirdTab.iLeft.iTl.iX == 0 ) &&
       
  3944              ( iExtension->iNextTabBackgroundLayout.iThirdTab.iMiddle.iTl.iX -
       
  3945                    iExtension->iTabBackgroundLayout.iThirdTab.iMiddle.iTl.iX == 0 ) &&
       
  3946              ( iExtension->iNextTabBackgroundLayout.iThirdTab.iRight.iTl.iX -
       
  3947                    iExtension->iTabBackgroundLayout.iThirdTab.iRight.iTl.iX == 0 ) )
       
  3948             {
       
  3949             thirdDone = ETrue;
       
  3950             }
       
  3951 
       
  3952         // Fourth tab
       
  3953         if ( fourthTabHorizontalDistanceLeft < 0 )
       
  3954             {
       
  3955             usedStepSizeForFourthTabLeft = -usedStepSizeForFourthTabLeft;
       
  3956             }
       
  3957         if ( fourthTabHorizontalDistanceMiddle < 0 )
       
  3958             {
       
  3959             usedStepSizeForFourthTabMiddle = -usedStepSizeForFourthTabMiddle;
       
  3960             }
       
  3961         if ( fourthTabHorizontalDistanceRight < 0 )
       
  3962             {
       
  3963             usedStepSizeForFourthTabRight = -usedStepSizeForFourthTabRight;
       
  3964             }
       
  3965 
       
  3966     iExtension->iTabBackgroundLayout.iFourthTab.iLeft.Move(
       
  3967         usedStepSizeForFourthTabLeft, 0 );
       
  3968     iExtension->iTabBackgroundLayout.iFourthTab.iRight.Move(
       
  3969         usedStepSizeForFourthTabRight, 0 );
       
  3970     iExtension->iTabBackgroundLayout.iFourthTab.iMiddle.iTl.iX =
       
  3971         iExtension->iTabBackgroundLayout.iFourthTab.iLeft.iBr.iX;
       
  3972     iExtension->iTabBackgroundLayout.iFourthTab.iMiddle.iBr.iX =
       
  3973         iExtension->iTabBackgroundLayout.iFourthTab.iRight.iTl.iX;
       
  3974 
       
  3975         if ( ( iExtension->iNextTabBackgroundLayout.iFourthTab.iLeft.iTl.iX -
       
  3976                 iExtension->iTabBackgroundLayout.iFourthTab.iLeft.iTl.iX == 0 ) &&
       
  3977              ( iExtension->iNextTabBackgroundLayout.iFourthTab.iMiddle.iTl.iX -
       
  3978                 iExtension->iTabBackgroundLayout.iFourthTab.iMiddle.iTl.iX == 0 ) &&
       
  3979              ( iExtension->iNextTabBackgroundLayout.iFourthTab.iRight.iTl.iX -
       
  3980                 iExtension->iTabBackgroundLayout.iFourthTab.iRight.iTl.iX == 0 ) )
       
  3981             {
       
  3982             fourthDone = ETrue;
       
  3983             }
       
  3984         }
       
  3985 
       
  3986    // Then lets adjust the tab content to right places.
       
  3987    if ( NarrowTabLayoutNext() )
       
  3988        {
       
  3989        TBool refreshTabs = iExtension->iNarrowTabLayout;
       
  3990        iExtension->iNarrowTabLayout = ETrue;
       
  3991        if ( refreshTabs )
       
  3992            {
       
  3993            SizeChanged();
       
  3994            }
       
  3995        }
       
  3996    else
       
  3997        {
       
  3998        TBool refreshTabs = !iExtension->iNarrowTabLayout;
       
  3999        iExtension->iNarrowTabLayout = EFalse;
       
  4000        if ( refreshTabs )
       
  4001            {
       
  4002            SizeChanged();
       
  4003            }
       
  4004        }
       
  4005 
       
  4006     // Check if we are done with the animation
       
  4007     if ( firstDone && secondDone && thirdDone && fourthDone ||
       
  4008          ( iExtension->iTabAnimationType == CAknTabGroupExtension::ETabCycleAnimation &&
       
  4009            iExtension->iTabCycleAnimationDistanceLeft <= 0 ) )
       
  4010         {
       
  4011         CancelTabAnimationEventTimer(); // done
       
  4012         SizeChanged();
       
  4013         }
       
  4014 
       
  4015     // Finally draw the tabs to their new places. Note that drawing must draw
       
  4016     // tabs little differently in this animated case. See Draw() method.
       
  4017     TRAP_IGNORE( InitTabAnimationL() );
       
  4018         
       
  4019     DrawDeferred();
       
  4020     }
       
  4021 
       
  4022 
       
  4023 // ---------------------------------------------------------------------------
       
  4024 // Sets the narrow/normal layout state of the tab group.
       
  4025 // ---------------------------------------------------------------------------
       
  4026 //
       
  4027 void CAknTabGroup::SetNarrowTabLayoutL( TBool aNarrow, TBool aUseAnimation )
       
  4028     {
       
  4029     if ( iExtension->iTabCycleAnimationOngoing )
       
  4030         {
       
  4031         // Narrow tab layout is not currently supported in touch layouts
       
  4032         // and this may should not be called during tab cycle animation.
       
  4033         return;
       
  4034         }
       
  4035 
       
  4036     if ( !aUseAnimation )
       
  4037         {
       
  4038         // Switch the layout directly without using the animation.
       
  4039         iExtension->iNarrowTabLayout = aNarrow;
       
  4040         iExtension->iTabAnimationType =
       
  4041             CAknTabGroupExtension::ENoAnimation;
       
  4042         }
       
  4043     else
       
  4044         {
       
  4045         iExtension->iTabAnimationType =
       
  4046             CAknTabGroupExtension::ELayoutSwitchAnimation;
       
  4047         }
       
  4048 
       
  4049     iExtension->iNarrowTabLayoutNext = aNarrow;
       
  4050 
       
  4051     iExtension->iTabSvgGraphics->SetTabGroupBackgroundParent(
       
  4052         ParentRect( iExtension->iNaviArrowsUsed ) );
       
  4053 
       
  4054     // Calculate new destination positions for animated tabs.
       
  4055     TInt positionActive = iActiveTab - iFirstShownTab;
       
  4056     if ( aNarrow )
       
  4057         {
       
  4058         iExtension->iNextTabBackgroundLayout.iUse = EFalse;
       
  4059         iExtension->iTabSvgGraphics->DrawTabGroupNarrowBackgroundL(
       
  4060             CAknTabGroupGraphics::ENoDraw,
       
  4061             iLongTabs,
       
  4062             iNumberOfTabsShown,
       
  4063             positionActive + 1,
       
  4064             NULL,
       
  4065             iExtension->iNextTabBackgroundLayout );
       
  4066         iExtension->iNextTabBackgroundLayout.iUse = ETrue;
       
  4067 
       
  4068         if ( !aUseAnimation )
       
  4069             {
       
  4070             iExtension->iTabBackgroundLayout.iUse = EFalse;
       
  4071             iExtension->iTabSvgGraphics->DrawTabGroupNarrowBackgroundL(
       
  4072                 CAknTabGroupGraphics::ENoDraw,
       
  4073                 iLongTabs,
       
  4074                 iNumberOfTabsShown,
       
  4075                 positionActive + 1,
       
  4076                 NULL,
       
  4077                 iExtension->iTabBackgroundLayout );
       
  4078             iExtension->iTabBackgroundLayout.iUse = ETrue;
       
  4079             }
       
  4080         }
       
  4081     else
       
  4082         {
       
  4083         iExtension->iNextTabBackgroundLayout.iUse = EFalse;
       
  4084         iExtension->iTabSvgGraphics->DrawTabGroupBackgroundL(
       
  4085             CAknTabGroupGraphics::ENoDraw,
       
  4086             iLongTabs,
       
  4087             iNumberOfTabsShown,
       
  4088             positionActive + 1,
       
  4089             NULL,
       
  4090             iExtension->iNextTabBackgroundLayout,
       
  4091             CAknTabGroupGraphics::ENone );
       
  4092         iExtension->iNextTabBackgroundLayout.iUse = ETrue;
       
  4093 
       
  4094         iExtension->iTabBackgroundLayout.iUse = EFalse;
       
  4095         iExtension->iTabSvgGraphics->DrawTabGroupBackgroundL(
       
  4096             CAknTabGroupGraphics::ENoDraw,
       
  4097             iLongTabs,
       
  4098             iNumberOfTabsShown,
       
  4099             positionActive + 1,
       
  4100             NULL,
       
  4101             iExtension->iTabBackgroundLayout,
       
  4102             CAknTabGroupGraphics::ENone );
       
  4103         iExtension->iTabBackgroundLayout.iUse = ETrue;
       
  4104         }
       
  4105 
       
  4106     InitTabAnimationL();
       
  4107 
       
  4108     if ( AknStatuspaneUtils::FlatLayoutActive() )
       
  4109         {
       
  4110         InitTabAnimationEventTimer();
       
  4111         }
       
  4112     else
       
  4113         {
       
  4114         CancelTabAnimationEventTimer();
       
  4115         }
       
  4116     }
       
  4117 
       
  4118 
       
  4119 // ---------------------------------------------------------------------------
       
  4120 // Sets the tab group internal state of the navi arrow visibility.
       
  4121 // ---------------------------------------------------------------------------
       
  4122 //
       
  4123 void CAknTabGroup::SetNaviArrowsVisible( TBool aVisible )
       
  4124     {
       
  4125     if ( iExtension )
       
  4126         {
       
  4127         iExtension->iNaviArrowsUsed = aVisible;
       
  4128         }
       
  4129     }
       
  4130 
       
  4131 
       
  4132 TBool CAknTabGroup::NarrowTabLayoutNext()
       
  4133     {
       
  4134     return iExtension && iExtension->iNarrowTabLayoutNext;
       
  4135     }
       
  4136 
       
  4137 TBool CAknTabGroup::NarrowTabLayout()
       
  4138     {
       
  4139     return iExtension && iExtension->iNarrowTabLayout;
       
  4140     }
       
  4141 
       
  4142 
       
  4143 // ---------------------------------------------------------------------------
       
  4144 // Sets the layout of the navi decorator to match the current
       
  4145 // tab group layout.
       
  4146 // ---------------------------------------------------------------------------
       
  4147 //
       
  4148 void CAknTabGroup::SetDecoratorLayout( TBool aNarrow )
       
  4149     {
       
  4150     CEikStatusPaneBase* statusPane           = CEikStatusPaneBase::Current();
       
  4151     CAknNavigationControlContainer* naviPane = NULL;
       
  4152     CAknNavigationDecorator* decorator       = NULL;
       
  4153 
       
  4154     if ( statusPane )
       
  4155         {
       
  4156         CCoeControl* control = NULL;
       
  4157         TRAPD( err, control = statusPane->ControlL(
       
  4158             TUid::Uid( EEikStatusPaneUidNavi ) ) );
       
  4159 
       
  4160         if ( !err && control )
       
  4161             {
       
  4162             // Control cannot be casted directly because someone may have
       
  4163             // swapped the control. Use this workaround instead.
       
  4164             control->MopGetObject( naviPane );
       
  4165             if ( naviPane )
       
  4166                 {
       
  4167                 decorator = naviPane->Top();
       
  4168                 if ( decorator && decorator->DecoratedControl() != this )
       
  4169                     {
       
  4170                     decorator = NULL;
       
  4171                     }
       
  4172                 }
       
  4173             }
       
  4174         }
       
  4175 
       
  4176     // Check first that application has not forced any layout mode.
       
  4177     if ( aNarrow )
       
  4178         {
       
  4179         if ( decorator &&
       
  4180              decorator->NaviControlLayoutMode() ==
       
  4181                 CAknNavigationDecorator::ENaviControlLayoutModeAutomatic )
       
  4182            {
       
  4183            decorator->SetNaviControlLayoutStyle(
       
  4184                CAknNavigationDecorator::ENaviControlLayoutNarrow );
       
  4185            }
       
  4186         }
       
  4187     else
       
  4188         {
       
  4189         if ( decorator &&
       
  4190              decorator->NaviControlLayoutMode() ==
       
  4191                 CAknNavigationDecorator::ENaviControlLayoutModeAutomatic )
       
  4192            {
       
  4193            decorator->SetNaviControlLayoutStyle(
       
  4194             CAknNavigationDecorator::ENaviControlLayoutNormal );
       
  4195            }
       
  4196         }
       
  4197 
       
  4198     // Only use tab arrows in non-touch layouts and in the one tab layout.
       
  4199     TBool naviArrowsShouldBeVisible( iTabFixedWidth == KTabWidthWithOneTab ||
       
  4200                                      !AknLayoutUtils::PenEnabled() );
       
  4201     if ( decorator &&
       
  4202          !COMPARE_BOOLS( decorator->ScrollButtonVisible(), naviArrowsShouldBeVisible ) )
       
  4203         {
       
  4204         decorator->MakeScrollButtonVisible( naviArrowsShouldBeVisible );
       
  4205         }
       
  4206     else
       
  4207         {
       
  4208         if ( iExtension )
       
  4209             {
       
  4210             // Ensure that the value here is correct if navi decorator
       
  4211             // already has it correct.
       
  4212             iExtension->iNaviArrowsUsed = naviArrowsShouldBeVisible;
       
  4213             }
       
  4214         }
       
  4215 
       
  4216     // After this method call decorator will set this class size right by
       
  4217     // calling us back at CAknTabGroup::SetNarrowTabLayoutL().
       
  4218     // If decorator does not exist we call ourself SetNarrowTabLayout.
       
  4219     if ( !decorator )
       
  4220         {
       
  4221         TRAP_IGNORE( SetNarrowTabLayoutL( aNarrow ) );
       
  4222         }
       
  4223     }
       
  4224 
       
  4225 
       
  4226 // ---------------------------------------------------------------------------
       
  4227 // Creates if necessary and draws the tab group background double buffer.
       
  4228 // ---------------------------------------------------------------------------
       
  4229 //
       
  4230 void CAknTabGroup::InitTabAnimationL()
       
  4231     {
       
  4232     TRect rect( ParentRect( iExtension->iNaviArrowsUsed ) );
       
  4233 
       
  4234     TSize size( rect.iBr.iX, rect.iBr.iY );
       
  4235 
       
  4236     if ( size.iHeight <= 0 || size.iWidth <= 0 )
       
  4237         {
       
  4238         size = rect.Size();
       
  4239         }
       
  4240 
       
  4241     TInt positionActive = iActiveTab - iFirstShownTab;
       
  4242 
       
  4243     TBool penEnabled( AknLayoutUtils::PenEnabled() );
       
  4244 
       
  4245     if ( penEnabled && iTabFixedWidth == KTabWidthWithThreeTabs )
       
  4246         {
       
  4247         // It's ensured here that the focused tab background graphic is drawn
       
  4248         // behind the middle tab in touch layouts when using three tab
       
  4249         // layout, if the currently active tab is not the leftmost or
       
  4250         // rightmost tab.
       
  4251         if ( iActiveTab != RightMostTabIndex() &&
       
  4252              iActiveTab != LeftMostTabIndex() )
       
  4253             {
       
  4254             positionActive = 1;
       
  4255             }
       
  4256         }
       
  4257 
       
  4258     if ( !iExtension->iNarrowTabLayout )
       
  4259         {
       
  4260         TInt tabCount = TabCount();
       
  4261         iExtension->iTabsHidden = CAknTabGroupGraphics::ENone;
       
  4262         TBool animationOngoing( iExtension->iTabCycleAnimationOngoing );
       
  4263         TBool firstAnimationUpdate( animationOngoing
       
  4264                 && iExtension->iAmountOfDoneAnimationEvents == 0 );
       
  4265 
       
  4266                 if ( tabCount > iNumberOfTabsShown && penEnabled )
       
  4267                     {
       
  4268                     iExtension->iTabsHidden = CAknTabGroupGraphics::ETwoOnBothSides;
       
  4269                     if ( animationOngoing &&
       
  4270                          ( ( iFirstShownTab == 0 &&
       
  4271                              iExtension->iTabCycleAnimationDirection == ELeft ) ||
       
  4272                            ( iFirstShownTab == tabCount - ( iNumberOfTabsShown ) &&
       
  4273                              iExtension->iTabCycleAnimationDirection == ERight ) ) )
       
  4274                         {
       
  4275                         iExtension->iTabsHidden = CAknTabGroupGraphics::EOnBothSides;
       
  4276                         }
       
  4277                     else if ( iActiveTab < iNumberOfTabsShown &&
       
  4278                          ( ( iFirstShownTab == 0 &&
       
  4279                              !animationOngoing ) ||
       
  4280                            firstAnimationUpdate &&
       
  4281                            iExtension->iTabCycleAnimationDirection == ERight ) )
       
  4282                         {
       
  4283                         iExtension->iTabsHidden = CAknTabGroupGraphics::EOnRightSide;
       
  4284                         }
       
  4285                     else if ( iActiveTab >= tabCount - ( iNumberOfTabsShown ) &&
       
  4286                               ( ( !animationOngoing &&
       
  4287                                   iFirstShownTab == tabCount - ( iNumberOfTabsShown ) ) ||
       
  4288                                 firstAnimationUpdate &&
       
  4289                                 iExtension->iTabCycleAnimationDirection == ELeft ) )
       
  4290                         {
       
  4291                         iExtension->iTabsHidden = CAknTabGroupGraphics::EOnLeftSide;
       
  4292                         }
       
  4293                     }
       
  4294 
       
  4295         if (firstAnimationUpdate)
       
  4296             {
       
  4297             iExtension->iNextTabBackgroundLayout.iUse = EFalse;
       
  4298             }
       
  4299         else
       
  4300             {
       
  4301             iExtension->iNextTabBackgroundLayout.iUse = ETrue;
       
  4302             }
       
  4303 
       
  4304         }
       
  4305 
       
  4306     iExtension->iTabAnimationDoubleBufferNarrowTabLayout
       
  4307             = iExtension->iNarrowTabLayout;
       
  4308     iExtension->iTabAnimationDoubleBufferNumberOfTabsShown
       
  4309             = iNumberOfTabsShown;
       
  4310     iExtension->iTabAnimationDoubleBufferpositionActive = positionActive;
       
  4311     iExtension->iTabAnimationDoubleBufferLongTabs = iLongTabs;
       
  4312 
       
  4313     iExtension->iTabBackgroundLayout.iUse = ETrue;
       
  4314     }
       
  4315 
       
  4316 
       
  4317 // ---------------------------------------------------------------------------
       
  4318 // Gets the tab group's parent rectangle.
       
  4319 // ---------------------------------------------------------------------------
       
  4320 //
       
  4321 TRect CAknTabGroup::ParentRect( TBool aArrowsUsed )
       
  4322     {
       
  4323     TBool scaled( ETrue );
       
  4324 
       
  4325     if ( !AknLayoutUtils::PenEnabled() )
       
  4326         {
       
  4327         CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
       
  4328 
       
  4329         if ( statusPane )
       
  4330             {
       
  4331             // In portrait mode the tab group needs to be adjacent
       
  4332             // the bottom of the navi pane.
       
  4333             TInt layoutResId = statusPane->CurrentLayoutResId();
       
  4334             if ( layoutResId == R_AVKON_STATUS_PANE_LAYOUT_USUAL_EXT ||
       
  4335                  layoutResId == R_AVKON_STATUS_PANE_LAYOUT_EMPTY )
       
  4336                 {
       
  4337                 scaled = EFalse;
       
  4338                 }
       
  4339             }
       
  4340         }
       
  4341 
       
  4342     TRect parentRect(
       
  4343         CAknNavigationDecorator::DecoratedTabControlRect( scaled,
       
  4344                                                           aArrowsUsed ) );
       
  4345 
       
  4346     return parentRect;
       
  4347     }
       
  4348 
       
  4349 
       
  4350 // ---------------------------------------------------------------------------
       
  4351 // Starts the tab group cycle animation.
       
  4352 // ---------------------------------------------------------------------------
       
  4353 //
       
  4354 void CAknTabGroup::StartCycleAnimationL( TDirection aDirection,
       
  4355                                          TInt aNewTab )
       
  4356     {
       
  4357     TInt tabCount( TabCount() );
       
  4358 
       
  4359     // First check if the animation should be used.
       
  4360     // The cycle animation is currently used only in following situation:
       
  4361     //  1) The three tab layout is active.
       
  4362     //  2) Touch layout is used.
       
  4363     //  3) Cycling the focus changes the first shown tab of the tab group.
       
  4364     //
       
  4365     if ( iTabFixedWidth == KTabWidthWithThreeTabs &&          // 1
       
  4366          AknLayoutUtils::PenEnabled() &&                      // 2
       
  4367          tabCount > iNumberOfTabsShown &&
       
  4368          ( ( iActiveTab > 0 && iActiveTab < tabCount - 2 &&   // 3
       
  4369              aDirection == ERight ) ||
       
  4370            ( iActiveTab > 1 && iActiveTab < tabCount - 1 &&   // 3
       
  4371              aDirection == ELeft ) ||
       
  4372            ( iActiveTab == 0 &&                               // 3
       
  4373              aNewTab == ( iNumberOfTabsShown - 1 ) ) ||
       
  4374            ( iActiveTab == tabCount - 1 &&                    // 3
       
  4375              aNewTab == tabCount - iNumberOfTabsShown ) ) )
       
  4376         {
       
  4377         iExtension->iTabAnimationType =
       
  4378             CAknTabGroupExtension::ETabCycleAnimation;
       
  4379 
       
  4380         iExtension->iTabCycleAnimationOngoing = ETrue;
       
  4381         iExtension->iTabCycleAnimationDirection = aDirection;
       
  4382 
       
  4383         iExtension->iTabSvgGraphics->SetTabGroupBackgroundParent(
       
  4384             ParentRect( iExtension->iNaviArrowsUsed ) );
       
  4385 
       
  4386         iExtension->iNextTabBackgroundLayout.iUse = EFalse;
       
  4387 
       
  4388         InitTabAnimationEventTimer();
       
  4389         }
       
  4390     }
       
  4391 
       
  4392 
       
  4393 // ---------------------------------------------------------------------------
       
  4394 // Switches the current tab layout to one that is usable in the current
       
  4395 // layout.
       
  4396 // ---------------------------------------------------------------------------
       
  4397 //
       
  4398 void CAknTabGroup::SwitchTabLayoutL()
       
  4399     {
       
  4400     TBool penEnabled( AknLayoutUtils::PenEnabled() );
       
  4401 
       
  4402     if ( penEnabled && ( iTabFixedWidth == KTabWidthWithTwoLongTabs ||
       
  4403                          iTabFixedWidth == KTabWidthWithThreeLongTabs ||
       
  4404                          iTabFixedWidth == KTabWidthWithFourTabs ) )
       
  4405         {
       
  4406         // If the current tab width is not supported in touch
       
  4407         // layout then switch it to a corresponding one.
       
  4408         SetTabFixedWidthL( iTabFixedWidth );
       
  4409         }
       
  4410     else if ( iExtension && iTabFixedWidth != iExtension->iRequestedTabWidth )
       
  4411         {
       
  4412         // Else try to set the requested width if it's supported in
       
  4413         // the new layout.
       
  4414         SetTabFixedWidthL( iExtension->iRequestedTabWidth );
       
  4415         }
       
  4416     else
       
  4417         {
       
  4418         // Nothing to do.
       
  4419         return;
       
  4420         }
       
  4421 
       
  4422     // Set the correct focus if tab width is changed in layout
       
  4423     // switch.
       
  4424     if ( iActiveTab >= 0 )
       
  4425         {
       
  4426         if ( penEnabled && iTabFixedWidth == KTabWidthWithThreeTabs )
       
  4427             {
       
  4428             if ( iActiveTab != RightMostTabIndex() &&
       
  4429                     iActiveTab != LeftMostTabIndex() )
       
  4430                 {
       
  4431                 iFirstShownTab = iActiveTab - 1;
       
  4432                 }
       
  4433             else if ( iActiveTab < iFirstShownTab )
       
  4434                 {
       
  4435                 iFirstShownTab = iActiveTab;
       
  4436                 }
       
  4437             else if ( iActiveTab >= ( iFirstShownTab + iNumberOfTabsShown ) )
       
  4438                 {
       
  4439                 iFirstShownTab = iActiveTab - iNumberOfTabsShown + 1;
       
  4440                 }
       
  4441             }
       
  4442         else
       
  4443             {
       
  4444             if ( iActiveTab < iFirstShownTab )
       
  4445                 {
       
  4446                 iFirstShownTab = iActiveTab;
       
  4447                 }
       
  4448 
       
  4449             if ( iActiveTab >= ( iFirstShownTab + iNumberOfTabsShown ) )
       
  4450                 {
       
  4451                 iFirstShownTab = iActiveTab - iNumberOfTabsShown + 1;
       
  4452                 }
       
  4453             }
       
  4454         SizeChanged();
       
  4455         }
       
  4456 
       
  4457     CancelTabAnimationEventTimer();
       
  4458     }
       
  4459 
       
  4460  //  End of File