uifw/AvKon/src/aknnavide.cpp
changeset 0 2f259fa3e83a
child 29 a8834a2e9a96
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 of the decorator class for navigation
       
    15 *                pane controls.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // SYSTEM INCLUDE FILES
       
    21 #include <AknsUtils.h>
       
    22 #include <AknsDrawUtils.h>
       
    23 #include <aknlayoutscalable_avkon.cdl.h>
       
    24 #include <layoutmetadata.cdl.h>
       
    25 #include <touchfeedback.h>
       
    26 
       
    27 #include <AknTasHook.h>
       
    28 // USER INCLUDE FILES
       
    29 #include "aknappui.h"
       
    30 #include "aknconsts.h"
       
    31 #include "aknnavilabel.h"
       
    32 #include "aknnavide.h"
       
    33 #include "AknNaviObserver.h"
       
    34 #include "AknUtils.h"
       
    35 #include "AknStatuspaneUtils.h"
       
    36 #include "AknNaviDecoratorObserver.h"
       
    37 #include "akntabgrp.h"
       
    38 #include "akntitle.h"
       
    39 #include "AknTitlePaneLabel.h"
       
    40 
       
    41 
       
    42 const TInt KEikNavidePointerRepeatInterval = 500000;  // in micro seconds
       
    43 
       
    44 
       
    45 // ============================= LOCAL FUNCTIONS ===============================
       
    46 
       
    47 NONSHARABLE_CLASS( CAknNavigationDecoratorExtension ) : public CBase
       
    48     {
       
    49 public:
       
    50     enum
       
    51         {
       
    52         ENaviDecoratorNoSide = 0,
       
    53         ENaviDecoratorLeftSide,
       
    54         ENaviDecoratorRightSide
       
    55         };
       
    56     
       
    57 public:
       
    58     static CAknNavigationDecoratorExtension* NewL();
       
    59     ~CAknNavigationDecoratorExtension();
       
    60     
       
    61 private:
       
    62     CAknNavigationDecoratorExtension();
       
    63     CAknNavigationDecoratorExtension( const CAknNavigationDecoratorExtension* aExtension );
       
    64     
       
    65 public:
       
    66     CPeriodic* iTimer;
       
    67     TInt iEffectTimerCount;
       
    68     TInt iOutermostRepeats;
       
    69     TInt iBlinkingSide;
       
    70     };
       
    71 
       
    72 CAknNavigationDecoratorExtension* CAknNavigationDecoratorExtension::NewL()
       
    73     {
       
    74     CAknNavigationDecoratorExtension* naviExtension = 
       
    75         new (ELeave) CAknNavigationDecoratorExtension();
       
    76     return naviExtension;
       
    77     }
       
    78 
       
    79 CAknNavigationDecoratorExtension::CAknNavigationDecoratorExtension() : 
       
    80     iTimer(NULL), iEffectTimerCount(0), iOutermostRepeats(0), iBlinkingSide(0)
       
    81     {
       
    82     }
       
    83 
       
    84 CAknNavigationDecoratorExtension::~CAknNavigationDecoratorExtension()
       
    85     {
       
    86     }
       
    87     
       
    88 // -----------------------------------------------------------------------------
       
    89 // IsMaskAllBlack
       
    90 //
       
    91 // Checks whether the given bitmap is all black (first row ignored).
       
    92 // The width of the bitmap is assumed to be 8 or less (sufficient for arrows).
       
    93 //
       
    94 // Returns: Boolean value.
       
    95 // -----------------------------------------------------------------------------
       
    96 //
       
    97 static TBool IsMaskAllBlack( CFbsBitmap* bitmap )
       
    98     {
       
    99     if ( !bitmap )
       
   100         {
       
   101         return EFalse;
       
   102         }
       
   103 
       
   104     TSize size( bitmap->SizeInPixels() );
       
   105 
       
   106     if ( size.iWidth > 8 )
       
   107         {
       
   108         return EFalse;
       
   109         }
       
   110         
       
   111     TBuf8<8> scanLineBuf;
       
   112 
       
   113     for ( TInt y = 1; y < size.iHeight; y++ )
       
   114         {
       
   115         bitmap->GetScanLine( scanLineBuf,
       
   116                              TPoint( 0, y ),
       
   117                              size.iWidth,
       
   118                              EGray256 );
       
   119         for ( TInt x = 0; x < size.iWidth; x++ )
       
   120             {
       
   121             if ( scanLineBuf[x] != 0 )
       
   122                 {
       
   123                 return EFalse;
       
   124                 }
       
   125             }
       
   126         }
       
   127 
       
   128     return ETrue;
       
   129     }
       
   130 
       
   131 // ============================ MEMBER FUNCTIONS ===============================
       
   132 
       
   133 EXPORT_C CAknNavigationDecorator* CAknNavigationDecorator::NewL(
       
   134     CAknNavigationControlContainer* /*aNavigationControlContainer*/,
       
   135     CCoeControl* aDecoratedControl,
       
   136     TControlType aType )
       
   137     {
       
   138     CleanupStack::PushL( aDecoratedControl );
       
   139     CAknNavigationDecorator* self = new (ELeave) CAknNavigationDecorator;
       
   140 
       
   141     self->iDecoratedControl = aDecoratedControl;
       
   142 
       
   143     CleanupStack::Pop( aDecoratedControl );
       
   144     
       
   145     // Control type must be set before calling constructor.
       
   146     self->iControlType = aType;
       
   147     
       
   148     CleanupStack::PushL( self );
       
   149     self->ConstructL();
       
   150     CleanupStack::Pop( self ); // self
       
   151     AKNTASHOOK_ADDL( self, "CAknNavigationDecorator" );
       
   152     return self;
       
   153     }
       
   154 
       
   155 EXPORT_C CAknNavigationDecorator::~CAknNavigationDecorator()
       
   156     {
       
   157     AKNTASHOOK_REMOVE();
       
   158     if ( iContainer )
       
   159         {
       
   160         iContainer->Pop( this );
       
   161         }
       
   162 
       
   163     if ( iLayoutStyleTimer )
       
   164         {
       
   165         iLayoutStyleTimer->Cancel();
       
   166         delete iLayoutStyleTimer;
       
   167         }
       
   168         
       
   169     if( iExtension && iExtension->iTimer )
       
   170         {
       
   171         if ( iExtension->iTimer->IsActive() )
       
   172             {
       
   173             CancelTimer();
       
   174             }
       
   175 
       
   176         delete iExtension->iTimer;
       
   177         }
       
   178     
       
   179     delete iExtension;    
       
   180     delete iDecoratedControl;
       
   181     }
       
   182 
       
   183 
       
   184 EXPORT_C void CAknNavigationDecorator::ConstructL()
       
   185     {
       
   186     iDecoratedControl->SetObserver( this );
       
   187 
       
   188     iNaviArrowsVisible    = EFalse;
       
   189     iNaviArrowLeftDimmed  = ETrue;
       
   190     iNaviArrowRightDimmed = ETrue;
       
   191     
       
   192     TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
       
   193     
       
   194     iLayoutStyleTimer = CPeriodic::NewL( CActive::EPriorityIdle );
       
   195     if ( AknStatuspaneUtils::FlatLayoutActive() &&
       
   196          !isLandscape )
       
   197         {
       
   198         iLayoutFlags |= ENaviControlLayoutNarrow;
       
   199         iLayoutFlags |= ENaviControlLayoutModeForced;
       
   200         }
       
   201 
       
   202     // Wide layout is used in usual portrait mode,
       
   203     // except for tabs in non-touch layouts.
       
   204     else if ( AknStatuspaneUtils::UsualLayoutActive() &&
       
   205               !isLandscape &&
       
   206               ( iControlType != ETabGroup ||
       
   207                 AknLayoutUtils::PenEnabled() ) )
       
   208         {
       
   209         iLayoutFlags |= ENaviControlLayoutWide;
       
   210         iLayoutFlags |= ENaviControlLayoutModeForced;
       
   211         }
       
   212     else
       
   213         {        
       
   214         iLayoutFlags |= ENaviControlLayoutNormal;
       
   215         iLayoutFlags |= ENaviControlLayoutModeAutomatic;
       
   216         }
       
   217     
       
   218     iExtension = CAknNavigationDecoratorExtension::NewL();
       
   219     
       
   220     ActivateL();
       
   221     }
       
   222 
       
   223 EXPORT_C CCoeControl* CAknNavigationDecorator::DecoratedControl()
       
   224     {
       
   225     // In case the decorated control is of the ENaviVolume type, this
       
   226     // function returns the CAknVolumeControl object which is a component
       
   227     // control of the volume popup, instead of the volume popup control itself.
       
   228     // This is in order to maintain BC.
       
   229     if ( iControlType == ENaviVolume )
       
   230         {
       
   231         CCoeControl* volumeControl = iDecoratedControl->ComponentControl( 5 );
       
   232         
       
   233         if ( volumeControl )
       
   234             {
       
   235             return volumeControl;
       
   236             }
       
   237         }
       
   238 
       
   239     return iDecoratedControl;
       
   240     }
       
   241 
       
   242 EXPORT_C void CAknNavigationDecorator::MakeScrollButtonVisible( TBool aVisible )
       
   243     {
       
   244     TBool differ = ( iNaviArrowsVisible != aVisible );
       
   245     
       
   246     iNaviArrowsVisible = aVisible;
       
   247     
       
   248     if ( iControlType == ENaviLabel )
       
   249         {
       
   250         if ( iNaviArrowsVisible )
       
   251             {
       
   252             STATIC_CAST( CAknNaviLabel*, iDecoratedControl )->
       
   253                 SetNaviLabelType( CAknNaviLabel::ENavigationLabel );
       
   254             }
       
   255         else
       
   256             {
       
   257             STATIC_CAST( CAknNaviLabel*, iDecoratedControl )->
       
   258                 SetNaviLabelType( CAknNaviLabel::EAdditionalInfoLabel );
       
   259             }
       
   260         }
       
   261     else if ( iControlType == ETabGroup )
       
   262         {
       
   263         static_cast<CAknTabGroup*>(
       
   264             iDecoratedControl )->SetNaviArrowsVisible( aVisible );
       
   265         }
       
   266 
       
   267     if ( differ )
       
   268         {
       
   269         SizeChanged();
       
   270         }
       
   271     }
       
   272 
       
   273 EXPORT_C TBool CAknNavigationDecorator::ScrollButtonVisible() const
       
   274     {
       
   275     return iNaviArrowsVisible;
       
   276     }
       
   277 
       
   278 EXPORT_C void CAknNavigationDecorator::SetScrollButtonDimmed(
       
   279     TScrollButton aButton,
       
   280     TBool aDimmed )
       
   281     {
       
   282     if ( aButton == ELeftButton )
       
   283         {
       
   284         iNaviArrowLeftDimmed = aDimmed;
       
   285 
       
   286         if ( aDimmed )
       
   287             {
       
   288             iExtension->iBlinkingSide = 
       
   289                 CAknNavigationDecoratorExtension::ENaviDecoratorRightSide;
       
   290             }
       
   291         }
       
   292     if ( aButton == ERightButton )
       
   293         {
       
   294         iNaviArrowRightDimmed = aDimmed;
       
   295 
       
   296         if ( aDimmed )
       
   297             {
       
   298             iExtension->iBlinkingSide = 
       
   299                 CAknNavigationDecoratorExtension::ENaviDecoratorLeftSide;
       
   300             }
       
   301         }
       
   302     }
       
   303 
       
   304 EXPORT_C TBool CAknNavigationDecorator::IsScrollButtonDimmed(
       
   305     TScrollButton aButton ) const
       
   306     {
       
   307     if ( aButton == ELeftButton )
       
   308         {
       
   309         return iNaviArrowLeftDimmed;
       
   310         }
       
   311     if ( aButton == ERightButton )
       
   312         {
       
   313         return iNaviArrowRightDimmed;
       
   314         }
       
   315     return ETrue;
       
   316     }
       
   317 
       
   318 EXPORT_C void CAknNavigationDecorator::SetControlType( TControlType aType )
       
   319     {
       
   320     iControlType = aType;
       
   321     }
       
   322 
       
   323 EXPORT_C CAknNavigationDecorator::TControlType CAknNavigationDecorator::ControlType() const
       
   324     {
       
   325     return iControlType;
       
   326     }
       
   327 
       
   328 EXPORT_C void CAknNavigationDecorator::SizeChanged()
       
   329     {
       
   330     if ( iControlType == ENaviVolume )
       
   331         {
       
   332         // The control for ENaviVolume type does not reside in the navi pane
       
   333         // anymore, so the control size doesn't need to be adjusted if navi pane
       
   334         // size changes.
       
   335         return;
       
   336         }
       
   337     
       
   338     TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
       
   339     TBool flatLayout( AknStatuspaneUtils::FlatLayoutActive() );
       
   340     
       
   341     if ( isLandscape &&
       
   342          flatLayout &&
       
   343          !AknLayoutUtils::PenEnabled() &&
       
   344          NaviControlLayoutMode() == ENaviControlLayoutModeAutomatic &&
       
   345          NaviControlLayoutStyle() == ENaviControlLayoutNormal )
       
   346         {
       
   347         if ( iLayoutStyleTimer && !iLayoutStyleTimer->IsActive() )
       
   348             {
       
   349             InitLayoutStyleTimer();
       
   350             }            
       
   351         }
       
   352     else
       
   353         {
       
   354         CancelLayoutStyleTimer();
       
   355         }    
       
   356     
       
   357     TBool wideInUseInLsc( EFalse );
       
   358     
       
   359     if ( NaviControlLayoutStyle() != ENaviControlLayoutNarrow &&
       
   360          flatLayout &&
       
   361          !isLandscape )
       
   362         {
       
   363         iLayoutFlags &= ~ENaviControlLayoutNormal;
       
   364         iLayoutFlags &= ~ENaviControlLayoutWide;
       
   365         iLayoutFlags |= ENaviControlLayoutNarrow;
       
   366         }
       
   367 
       
   368     // Only flat layout supports narrow mode for now.
       
   369     if ( NaviControlLayoutStyle() == ENaviControlLayoutNarrow )
       
   370         {
       
   371         if ( !flatLayout ||
       
   372              ( isLandscape && AknLayoutUtils::PenEnabled() ) )
       
   373             {
       
   374             iLayoutFlags &= ~ENaviControlLayoutNarrow;           
       
   375             iLayoutFlags |= ENaviControlLayoutNormal; 
       
   376             }
       
   377         }
       
   378     // Wide layout is supported only in portrait mode.
       
   379     else if ( NaviControlLayoutStyle() == ENaviControlLayoutWide )
       
   380         {
       
   381         if ( Layout_Meta_Data::IsLandscapeOrientation() )
       
   382             {
       
   383             wideInUseInLsc = ETrue;
       
   384             }
       
   385         }
       
   386     
       
   387     if ( NaviControlLayoutStyle() == ENaviControlLayoutNarrow &&
       
   388          NaviControlLayoutStyleSupported( ENaviControlLayoutNarrow ) )
       
   389         {
       
   390         SizeChangedInNarrowLayout();
       
   391         }
       
   392     else if ( NaviControlLayoutStyle() == ENaviControlLayoutWide &&
       
   393               !wideInUseInLsc )
       
   394         {
       
   395         SizeChangedInWideLayout();
       
   396         }
       
   397     else // Normal layout
       
   398         {
       
   399         SizeChangedInNormalLayout();
       
   400         }
       
   401 
       
   402     // Finally call the navi arrow bitmap getter, as it will
       
   403     // resize the navi arrows to correct size.
       
   404     if ( iContainer )
       
   405         {
       
   406         iContainer->NaviArrowBitmap( 0 );
       
   407         iContainer->NaviArrowBitmap( 1 );
       
   408         }
       
   409     }
       
   410 
       
   411 void CAknNavigationDecorator::SizeChangedInNormalLayout()
       
   412     {
       
   413     TRect rect;
       
   414     TRect leftArrowRect;
       
   415     TRect rightArrowRect;
       
   416     
       
   417     CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
       
   418     if ( statusPane && 
       
   419          statusPane->CurrentLayoutResId() == R_AVKON_STATUS_PANE_LAYOUT_USUAL_EXT &&
       
   420          iControlType == ETabGroup )
       
   421         {
       
   422         // At the moment this special handling is required for tab group
       
   423         // in portrait mode, because tabs don't support wide navi pane layout yet.
       
   424         TAknLayoutRect layoutRect;
       
   425             
       
   426         TRect screenRect;
       
   427         AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
       
   428         
       
   429         TBool isHDLayoutActive( AknStatuspaneUtils::HDLayoutActive() );
       
   430                     
       
   431         TAknWindowComponentLayout topArea( 
       
   432             AknLayoutScalable_Avkon::area_top_pane( isHDLayoutActive ? 8 : 0 ) );
       
   433         TAknWindowComponentLayout spLayout(
       
   434             AknLayoutScalable_Avkon::status_pane( isHDLayoutActive ? 1 : 0 ) );
       
   435             
       
   436         TAknWindowComponentLayout layout(
       
   437                 TAknWindowComponentLayout::Compose( topArea, spLayout ) );
       
   438                 
       
   439         layoutRect.LayoutRect( screenRect, layout );
       
   440         TRect spRect( layoutRect.Rect() );
       
   441                 
       
   442         layoutRect.LayoutRect(
       
   443             spRect,
       
   444             AknLayoutScalable_Avkon::navi_pane( isHDLayoutActive ? 8 : 5 ) );
       
   445         rect = layoutRect.Rect();
       
   446         rect.Move( -rect.iTl.iX, -rect.iTl.iY );
       
   447         leftArrowRect  = NaviArrowRect( ELeftButton,  EFalse, rect );
       
   448         rightArrowRect = NaviArrowRect( ERightButton, EFalse, rect );
       
   449         }
       
   450     else
       
   451         {
       
   452         rect = ParentRect();
       
   453         
       
   454         if ( iControlType == ENaviVolume &&
       
   455              !Layout_Meta_Data::IsLandscapeOrientation() &&
       
   456              AknStatuspaneUtils::SmallLayoutActive() )
       
   457             {
       
   458             // Small status pane volume control has it's own positions for
       
   459             // navi arrows, but in landscape the data doesn't exist
       
   460             // so normal navi arrow positions are used.
       
   461             
       
   462             // These layout data items aren't mirrored.
       
   463             TBool layoutMirrored( AknLayoutUtils::LayoutMirrored() );
       
   464             
       
   465             TRect naviPaneRect;
       
   466             AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::ENaviPane,
       
   467                                                naviPaneRect );
       
   468                                                
       
   469             naviPaneRect.Move( -naviPaneRect.iTl.iX,
       
   470                                -naviPaneRect.iTl.iY );
       
   471             
       
   472             TAknLayoutRect layoutRect;
       
   473             layoutRect.LayoutRect(
       
   474                 naviPaneRect,
       
   475                 layoutMirrored ?
       
   476                     AknLayoutScalable_Avkon::status_small_pane_g6( 0 ) :
       
   477                     AknLayoutScalable_Avkon::status_small_pane_g5( 0 ) );
       
   478             leftArrowRect = layoutRect.Rect();
       
   479 
       
   480             layoutRect.LayoutRect(
       
   481                 naviPaneRect,
       
   482                 layoutMirrored ?
       
   483                     AknLayoutScalable_Avkon::status_small_pane_g5( 0 ) :
       
   484                     AknLayoutScalable_Avkon::status_small_pane_g6( 0 ) );
       
   485             rightArrowRect = layoutRect.Rect();   
       
   486             }
       
   487         else
       
   488             {
       
   489             leftArrowRect = NaviArrowRect( ELeftButton );
       
   490             rightArrowRect = NaviArrowRect( ERightButton );
       
   491             }
       
   492         }
       
   493 
       
   494     if ( iControlType == ETabGroup )
       
   495         {
       
   496         rect = DecoratedTabControlRect( AknLayoutUtils::PenEnabled(),
       
   497                                         ETrue );
       
   498         }
       
   499 
       
   500     iArrowRightSize = rightArrowRect.Size();
       
   501     iArrowLeftSize  = leftArrowRect.Size();
       
   502     
       
   503     iArrowRightPos = TPoint( rightArrowRect.iTl.iX, rect.iTl.iY );
       
   504     iArrowLeftPos  = TPoint( leftArrowRect.iTl.iX, rect.iTl.iY );
       
   505     
       
   506     TSize rectSize( rect.Size() );
       
   507     
       
   508     // In case the decorated control is tab group, the tab layout mode
       
   509     // must be set before it's size is set.
       
   510     if ( iControlType == ETabGroup )
       
   511         {
       
   512         CAknTabGroup* tabGroup = static_cast <CAknTabGroup*> (iDecoratedControl);
       
   513         TRAP_IGNORE( tabGroup->SetNarrowTabLayoutL( EFalse ) );
       
   514         }
       
   515     
       
   516     if ( ScrollButtonVisible() )
       
   517         {
       
   518         iDecoratedControl->SetRect( rect );
       
   519         }
       
   520     else
       
   521         {
       
   522         iDecoratedControl->SetRect( Rect() );
       
   523         }
       
   524     }
       
   525 
       
   526 
       
   527 void CAknNavigationDecorator::SizeChangedInNarrowLayout()
       
   528     {
       
   529     TRect rect( DecoratedControlNarrowRect( this->ControlType() ) );
       
   530     
       
   531     TRect leftArrowRect( NaviArrowRect( ELeftButton, ETrue ) );
       
   532     TRect rightArrowRect( NaviArrowRect( ERightButton, ETrue ) );
       
   533 
       
   534     iArrowRightSize = rightArrowRect.Size();
       
   535     iArrowRightPos  = rightArrowRect.iTl;
       
   536     
       
   537     iArrowLeftSize  = leftArrowRect.Size();
       
   538     iArrowLeftPos   = leftArrowRect.iTl;
       
   539 
       
   540     // Tab group is handled specificly... 
       
   541     if ( iControlType == ETabGroup )
       
   542         {
       
   543         // Note. Size is set bigger than normally. 
       
   544         // Tabs take this into account in layout calculations (akntabgrp.cpp).
       
   545         iDecoratedControl->SetRect( Rect() ); 
       
   546         CAknTabGroup* tabGroup = static_cast <CAknTabGroup*> (iDecoratedControl);
       
   547         // This sets tab size using animation.
       
   548         TBool useAnimation( Layout_Meta_Data::IsLandscapeOrientation() );
       
   549         TRAP_IGNORE( tabGroup->SetNarrowTabLayoutL( ETrue, useAnimation ) );
       
   550         }
       
   551     else
       
   552         {
       
   553         if ( ScrollButtonVisible() )
       
   554             {
       
   555             iDecoratedControl->SetRect( TRect( iArrowLeftPos.iX + iArrowLeftSize.iWidth,
       
   556                                                rect.iTl.iY,
       
   557                                                iArrowRightPos.iX,
       
   558                                                rect.iBr.iY ) );
       
   559             }
       
   560         else
       
   561             {
       
   562             iDecoratedControl->SetRect( rect );
       
   563             }
       
   564         }                 
       
   565     }
       
   566 
       
   567 
       
   568 void CAknNavigationDecorator::SizeChangedInWideLayout()
       
   569     {
       
   570     TRect rect( Rect() );
       
   571     TRect parentRect;
       
   572 
       
   573     if ( iControlType == ETabGroup &&
       
   574          !AknLayoutUtils::PenEnabled() )
       
   575         {
       
   576         parentRect = DecoratedTabControlRect( EFalse, ETrue );
       
   577         }
       
   578     else
       
   579         {
       
   580         parentRect = ParentRect();
       
   581         }
       
   582 
       
   583     if ( rect.Width()  < parentRect.Width() ||
       
   584          rect.Height() < parentRect.Height() )
       
   585         {
       
   586         rect = parentRect;
       
   587         }
       
   588 
       
   589     TRect leftArrowRect( NaviArrowRect( ELeftButton ) );
       
   590     TRect rightArrowRect( NaviArrowRect( ERightButton ) );
       
   591 
       
   592     iArrowRightSize = rightArrowRect.Size();
       
   593     iArrowLeftSize  = leftArrowRect.Size();
       
   594 
       
   595     if ( ScrollButtonVisible() )
       
   596         {
       
   597         rect.iTl.iX += iArrowRightSize.iWidth;
       
   598         rect.iBr.iX -= iArrowLeftSize.iWidth;
       
   599         }
       
   600     
       
   601     if ( parentRect.Height() < rect.Height() )
       
   602         {
       
   603         iArrowRightPos = TPoint( rect.iBr.iX, parentRect.iTl.iY );
       
   604         iArrowLeftPos = TPoint( rect.iTl.iX - iArrowLeftSize.iWidth, parentRect.iTl.iY );
       
   605         }
       
   606     else
       
   607         {
       
   608         iArrowRightPos = TPoint( rect.iBr.iX, rightArrowRect.iTl.iY );
       
   609         iArrowLeftPos = TPoint( rect.iTl.iX - iArrowLeftSize.iWidth, iArrowRightPos.iY );
       
   610         }
       
   611 
       
   612     // In case the decorated control is tab group, the tab layout mode
       
   613     // must be set before it's size is set.
       
   614     if ( iControlType == ETabGroup )
       
   615         {
       
   616         CAknTabGroup* tabGroup = static_cast <CAknTabGroup*> ( iDecoratedControl );
       
   617         TRAP_IGNORE( tabGroup->SetNarrowTabLayoutL( EFalse) );
       
   618         }
       
   619 
       
   620     iDecoratedControl->SetRect( rect );
       
   621     }
       
   622 
       
   623 EXPORT_C TInt CAknNavigationDecorator::CountComponentControls() const
       
   624     {
       
   625     if ( iContainer && iDecoratedControl )
       
   626         {
       
   627         return 1;
       
   628         }
       
   629 
       
   630     return 0;
       
   631     }
       
   632 
       
   633 
       
   634 EXPORT_C CCoeControl* CAknNavigationDecorator::ComponentControl(TInt /*aIndex*/) const
       
   635     {
       
   636     // DecoratedControl() isn't declared as const but doesn't actually
       
   637     // change anything.
       
   638     return ( const_cast<CAknNavigationDecorator*>(this)->DecoratedControl() );
       
   639     }
       
   640 
       
   641 
       
   642 EXPORT_C void* CAknNavigationDecorator::ExtensionInterface( TUid /*aInterface*/ ) 
       
   643     { 
       
   644     return NULL;
       
   645     }
       
   646 
       
   647    
       
   648 // ---------------------------------------------------------------------------
       
   649 // CAknNavigationDecorator::HandlePointerEventL
       
   650 // Handles pointer events by checking first if the pointer event was
       
   651 // in the arrow areas and sending the arrow event to observer,
       
   652 // and if not sending the pointer event to all child components.
       
   653 // ---------------------------------------------------------------------------
       
   654 //
       
   655 EXPORT_C void CAknNavigationDecorator::HandlePointerEventL(
       
   656     const TPointerEvent& aPointerEvent )
       
   657     {
       
   658     if ( AknLayoutUtils::PenEnabled() )
       
   659         {
       
   660         TRect naviPaneRect( ParentRect() );
       
   661         TRect parentRect = naviPaneRect;
       
   662         
       
   663         TRect statusPaneRect;
       
   664         AknLayoutUtils::LayoutMetricsRect(
       
   665             AknLayoutUtils::EStatusPane, statusPaneRect );
       
   666         
       
   667         // In certain status pane layouts the navi pane has extended
       
   668         // touch responsive area in the layout data which is larger
       
   669         // than the actual decorator size.
       
   670         CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
       
   671         if ( statusPane )
       
   672             {
       
   673             TInt currentLayoutResId( statusPane->CurrentLayoutResId() );
       
   674             
       
   675             if ( currentLayoutResId == R_AVKON_WIDESCREEN_PANE_LAYOUT_USUAL ||
       
   676                  currentLayoutResId == R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE )
       
   677                 {
       
   678                 TAknLayoutRect layoutRect;
       
   679                 layoutRect.LayoutRect(
       
   680                     statusPaneRect,
       
   681                     AknLayoutScalable_Avkon::aid_touch_navi_pane() );
       
   682                 parentRect = layoutRect.Rect();
       
   683                 
       
   684                 // Make the parent rect navi pane relative and move it so
       
   685                 // that the bottom sides of the real navi pane area and the
       
   686                 // touch pane responsive area are aligned. This means
       
   687                 // that the iTl.iY will become negative, which is required
       
   688                 // for pointer events in which the down event happens
       
   689                 // inside the decorator rect, but the up event in the
       
   690                 // extended area above the decorator rect.
       
   691                 parentRect.Move( -parentRect.iTl.iX,
       
   692                                  -( parentRect.iTl.iY +
       
   693                                     ( parentRect.Height() -
       
   694                                       naviPaneRect.Height() ) ) );
       
   695                 }
       
   696             }
       
   697 
       
   698         TRect rightArrowTabRect( iArrowRightPos, iArrowRightSize );
       
   699         TRect leftArrowTabRect( iArrowLeftPos, iArrowLeftSize );
       
   700         
       
   701         // Get tab arrow touch aid rects from layout data, they extend the
       
   702         // arrow areas bit to the decorated control's area to make the arrows
       
   703         // more "finger usable".
       
   704         TAknLayoutRect arrowAidLayout;
       
   705         arrowAidLayout.LayoutRect(
       
   706             statusPaneRect,
       
   707             AknLayoutScalable_Avkon::aid_touch_tab_arrow_left(
       
   708                 Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 0 ) );
       
   709         
       
   710         // The arrows are the same size so use only the other's width.
       
   711         TInt aidWidth( arrowAidLayout.Rect().Width() );
       
   712         
       
   713         rightArrowTabRect.iTl.iX -= aidWidth;
       
   714         leftArrowTabRect.iBr.iX  += aidWidth;
       
   715                 
       
   716         TBool rightArrowTapped(
       
   717             iNaviArrowsVisible &&
       
   718             !iNaviArrowRightDimmed &&
       
   719             rightArrowTabRect.Contains( aPointerEvent.iPosition ) );
       
   720             
       
   721         TBool leftArrowTapped(
       
   722             iNaviArrowsVisible &&
       
   723             !iNaviArrowLeftDimmed &&
       
   724             leftArrowTabRect.Contains( aPointerEvent.iPosition ) );
       
   725         
       
   726         // Inform controls if tapped to arrows.
       
   727         if ( aPointerEvent.iType == TPointerEvent::EButton1Down ||
       
   728              aPointerEvent.iType == TPointerEvent::EButtonRepeat )
       
   729             {
       
   730             // Detects whether tap hits left arrow.
       
   731             if ( leftArrowTapped && iNaviDecoratorObserver )
       
   732                 {
       
   733                 MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   734                 if ( feedback &&
       
   735                      ( iDecoratedControl && !iDecoratedControl->IsDimmed() ) )
       
   736                     {
       
   737                     TTouchLogicalFeedback feedbackType =
       
   738                         ( aPointerEvent.iType == TPointerEvent::EButtonRepeat ?
       
   739                               ETouchFeedbackSensitiveButton :
       
   740                               ETouchFeedbackBasicButton );
       
   741                     feedback->InstantFeedback( this, feedbackType, aPointerEvent );
       
   742                     }
       
   743 
       
   744                 iNaviDecoratorObserver->HandleNaviDecoratorEventL(
       
   745                     MAknNaviDecoratorObserver::EAknNaviDecoratorEventLeftTabArrow );
       
   746 
       
   747                 // Request pointer repeat to implement longtapping
       
   748                 Window().RequestPointerRepeatEvent(
       
   749                     KEikNavidePointerRepeatInterval, leftArrowTabRect );
       
   750 
       
   751                 // Don't pass the event to children as the tap point
       
   752                 // may be in the decorated control's area and it's
       
   753                 // already handled here.
       
   754                 }
       
   755             // Detects whether tap hits right arrow.
       
   756             else if ( rightArrowTapped && iNaviDecoratorObserver )
       
   757                 {
       
   758                 MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   759                 if ( feedback &&
       
   760                      ( iDecoratedControl && !iDecoratedControl->IsDimmed() ) )
       
   761                     {
       
   762                     TTouchLogicalFeedback feedbackType =
       
   763                         ( aPointerEvent.iType == TPointerEvent::EButtonRepeat ?
       
   764                               ETouchFeedbackSensitiveButton :
       
   765                               ETouchFeedbackBasicButton );
       
   766                     feedback->InstantFeedback( this, feedbackType, aPointerEvent );
       
   767                     }
       
   768 
       
   769                 iNaviDecoratorObserver->HandleNaviDecoratorEventL(
       
   770                     MAknNaviDecoratorObserver::EAknNaviDecoratorEventRightTabArrow );
       
   771 
       
   772                 // Request pointer repeat to implement longtapping
       
   773                 Window().RequestPointerRepeatEvent(
       
   774                     KEikNavidePointerRepeatInterval, rightArrowTabRect );
       
   775 
       
   776                 // Don't pass the event to children as the tap point
       
   777                 // may be in the decorated control's area and it's
       
   778                 // already handled here.
       
   779                 }
       
   780             else
       
   781                 {
       
   782                 // Pass the pointer events to children.
       
   783                 CCoeControl::HandlePointerEventL( aPointerEvent );
       
   784                 }
       
   785 
       
   786             // check if navi label was hit
       
   787             }
       
   788         else if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
   789             {
       
   790             if ( iControlType == ENaviLabel )
       
   791                 {
       
   792                 if ( parentRect.Contains( aPointerEvent.iPosition ) &&
       
   793                      iNaviDecoratorObserver )
       
   794                     {
       
   795                     iNaviDecoratorObserver->HandleNaviDecoratorEventL(
       
   796                         MAknNaviDecoratorObserver::EAknNaviDecoratorEventNaviLabel );
       
   797                     }
       
   798                 }
       
   799             else if( !rightArrowTapped && !leftArrowTapped )
       
   800                 {
       
   801                 CCoeControl::HandlePointerEventL( aPointerEvent );
       
   802                 }
       
   803             
       
   804             // feedback is also given on up event from arrows
       
   805             if ( rightArrowTapped || leftArrowTapped )
       
   806                 {
       
   807                 MTouchFeedback* feedback = MTouchFeedback::Instance();
       
   808                 if ( feedback &&
       
   809                      ( iDecoratedControl && !iDecoratedControl->IsDimmed() ) )
       
   810                     {
       
   811                     feedback->InstantFeedback( this, 
       
   812                                                ETouchFeedbackBasicButton,
       
   813                                                ETouchFeedbackVibra,
       
   814                                                aPointerEvent );
       
   815                     }
       
   816                 }
       
   817             }
       
   818         else
       
   819             {
       
   820             if ( !rightArrowTapped && !leftArrowTapped )
       
   821                 {
       
   822                 // Pass other pointer events to children if it
       
   823                 // happened outside the arrow areas.
       
   824                 CCoeControl::HandlePointerEventL( aPointerEvent );
       
   825                 }
       
   826             }
       
   827         }
       
   828     }
       
   829 
       
   830 
       
   831 EXPORT_C void CAknNavigationDecorator::HandleControlEventL(
       
   832     CCoeControl* /*aControl*/, TCoeEvent aEventType )
       
   833     {
       
   834     TInt event = aEventType;
       
   835     switch ( event )
       
   836         {
       
   837         case MAknNavigationObserver::ENaviEventHandleNavigation:
       
   838             {
       
   839             iNaviArrowRightDimmed = EFalse;
       
   840             iNaviArrowLeftDimmed  = EFalse;
       
   841             break;
       
   842             }
       
   843         case MAknNavigationObserver::ENaviEventRightMostItemReached:
       
   844             {
       
   845             iNaviArrowRightDimmed = ETrue;
       
   846             iNaviArrowLeftDimmed  = EFalse;
       
   847             break;
       
   848             }
       
   849         case MAknNavigationObserver::ENaviEventLeftMostItemReached:
       
   850             {
       
   851             iNaviArrowRightDimmed = EFalse;
       
   852             iNaviArrowLeftDimmed  = ETrue;
       
   853             break;
       
   854             }
       
   855         case MAknNavigationObserver::ENaviEventOneItemExists:
       
   856             {
       
   857             iNaviArrowRightDimmed = ETrue;
       
   858             iNaviArrowLeftDimmed  = ETrue;
       
   859             break;
       
   860             }
       
   861         case MAknNavigationObserver::ENaviEventAlreadyLeftmostItem:
       
   862             {
       
   863 #ifdef RD_ANIMATION_EFFECTS 
       
   864             iExtension->iBlinkingSide = 
       
   865                     CAknNavigationDecoratorExtension::ENaviDecoratorRightSide;           
       
   866             StartTimerL();
       
   867             return;
       
   868 #else
       
   869             break;
       
   870 #endif // RD_ANIMATION_EFFECTS
       
   871             }
       
   872         case MAknNavigationObserver::ENaviEventAlreadyRightmostItem:
       
   873             {
       
   874 #ifdef RD_ANIMATION_EFFECTS
       
   875             iExtension->iBlinkingSide = 
       
   876                     CAknNavigationDecoratorExtension::ENaviDecoratorLeftSide;
       
   877             StartTimerL();
       
   878             return;
       
   879 #else // RD_ANIMATION_EFFECTS
       
   880             break;
       
   881 #endif
       
   882             }
       
   883         case MAknNavigationObserver::ENaviEventRedrawNeeded:
       
   884             break;
       
   885         default:
       
   886             break;
       
   887         }
       
   888     
       
   889     ReportEventL( MCoeControlObserver::EEventStateChanged );
       
   890     
       
   891     MCoeControlObserver* observer = Observer();
       
   892     // If event was not sent yet to the navigation control container, send it now
       
   893     if ( iContainer && observer != iContainer )
       
   894         {
       
   895         SetObserver( iContainer );
       
   896         ReportEventL( MCoeControlObserver::EEventStateChanged );
       
   897         SetObserver( observer );
       
   898         }
       
   899     }
       
   900 
       
   901 
       
   902 EXPORT_C void CAknNavigationDecorator::Draw( const TRect& /*aRect*/ ) const
       
   903     {
       
   904     // Draw navigation pane scroll indicator arrows if visible
       
   905     if ( iNaviArrowsVisible && iContainer )
       
   906         {
       
   907         CWindowGc& gc = SystemGc();
       
   908         
       
   909         CFbsBitmap* colorbmp = iContainer->NaviColorBitmap();
       
   910 
       
   911         if ( !iNaviArrowLeftDimmed )
       
   912             {
       
   913             CFbsBitmap* arrowBmp = &( iContainer->NaviArrowBitmap( 0 ) );
       
   914             CFbsBitmap* arrowMask = &( iContainer->NaviArrowBitmap( 1 ) );
       
   915             
       
   916             TPoint arrowPos( iArrowLeftPos );
       
   917             
       
   918             if ( arrowBmp )
       
   919                 {
       
   920                 TInt arrowHeight( arrowBmp->SizeInPixels().iHeight );
       
   921                 if ( arrowHeight < Size().iHeight )
       
   922                     {
       
   923                     arrowPos.iY = ( Size().iHeight - arrowHeight ) / 2;
       
   924                     }
       
   925                 }
       
   926                     
       
   927             if( colorbmp && !IsMaskAllBlack( arrowMask ) )
       
   928                 {
       
   929                 gc.BitBltMasked(
       
   930                     arrowPos,
       
   931                     colorbmp, 
       
   932                     TRect( iArrowLeftSize ),
       
   933                     arrowMask,
       
   934                     ETrue );
       
   935                 }
       
   936             else
       
   937                 {
       
   938                 gc.BitBltMasked(
       
   939                     arrowPos,
       
   940                     arrowBmp, 
       
   941                     TRect( iArrowLeftSize ),
       
   942                     arrowMask,
       
   943                     ETrue );
       
   944                 }
       
   945             }
       
   946         
       
   947         if ( !iNaviArrowRightDimmed )
       
   948             {
       
   949             CFbsBitmap* arrowBmp = &( iContainer->NaviArrowBitmap( 2 ) );
       
   950             CFbsBitmap* arrowMask = &( iContainer->NaviArrowBitmap( 3 ) );
       
   951             
       
   952             TPoint arrowPos( iArrowRightPos );
       
   953             
       
   954             if ( arrowBmp )
       
   955                 {
       
   956                 TInt arrowHeight( arrowBmp->SizeInPixels().iHeight );
       
   957                 if ( arrowHeight < Size().iHeight )
       
   958                     {
       
   959                     arrowPos.iY = ( Size().iHeight - arrowHeight ) / 2;
       
   960                     }
       
   961                 }
       
   962             
       
   963             if( colorbmp && !IsMaskAllBlack( arrowMask ) )
       
   964                 {
       
   965                 gc.BitBltMasked(
       
   966                     arrowPos,
       
   967                     colorbmp, 
       
   968                     TRect( iArrowRightSize ),
       
   969                     arrowMask,
       
   970                     ETrue );
       
   971                 }
       
   972             else
       
   973                 {
       
   974                 gc.BitBltMasked(
       
   975                     arrowPos,
       
   976                     arrowBmp,
       
   977                     TRect( iArrowRightSize ),
       
   978                     arrowMask,
       
   979                     ETrue );
       
   980                 }
       
   981             }
       
   982         }
       
   983     }
       
   984 
       
   985 void CAknNavigationDecorator::SetNaviStack(
       
   986     CAknNavigationControlContainer* aContainer )
       
   987     {
       
   988     iContainer = aContainer;
       
   989 
       
   990     if ( iContainer &&
       
   991          iControlType == ETabGroup )
       
   992         {
       
   993         CAknTabGroup* tabGroup =
       
   994             static_cast <CAknTabGroup*> ( iDecoratedControl );
       
   995         tabGroup->SetDecoratorLayout( iLayoutFlags & ENaviControlLayoutNarrow );
       
   996         }
       
   997     }
       
   998 
       
   999 // ---------------------------------------------------------------------------
       
  1000 // CAknNavigationDecorator::SetNaviDecoratorObserver
       
  1001 // Sets observer for navidecorator.
       
  1002 // ---------------------------------------------------------------------------
       
  1003 //  
       
  1004 EXPORT_C void CAknNavigationDecorator::SetNaviDecoratorObserver(
       
  1005     MAknNaviDecoratorObserver* aObserver )
       
  1006     {
       
  1007     if ( AknLayoutUtils::PenEnabled() )
       
  1008         {
       
  1009         iNaviDecoratorObserver = aObserver;
       
  1010         }
       
  1011     }
       
  1012 
       
  1013 
       
  1014 // ---------------------------------------------------------------------------
       
  1015 // CAknNavigationDecorator::ParentRect
       
  1016 // Returns the navigation decorator rectangle.
       
  1017 // ---------------------------------------------------------------------------
       
  1018 //
       
  1019 TRect CAknNavigationDecorator::ParentRect()
       
  1020     {
       
  1021     return DecoratedControlRect( iControlType, iNaviArrowsVisible );
       
  1022     }
       
  1023 
       
  1024 
       
  1025 // ---------------------------------------------------------------------------
       
  1026 // CAknNavigationDecorator::DecoratedControlNarrowRect
       
  1027 // Returns the navigation decorator rectangle used in the narrow layout.
       
  1028 // ---------------------------------------------------------------------------
       
  1029 //
       
  1030 TRect CAknNavigationDecorator::DecoratedControlNarrowRect(
       
  1031     TInt /*aControlType*/ )
       
  1032     {
       
  1033     TBool landscape( Layout_Meta_Data::IsLandscapeOrientation() );
       
  1034 
       
  1035     // Status pane area
       
  1036     TRect statusPaneRect;
       
  1037     AknLayoutUtils::LayoutMetricsRect(
       
  1038         AknLayoutUtils::EStatusPane, statusPaneRect );
       
  1039         
       
  1040     // Navi pane area
       
  1041     TRect naviPaneRect;
       
  1042     AknLayoutUtils::LayoutMetricsRect(
       
  1043         AknLayoutUtils::ENaviPane, naviPaneRect );
       
  1044 
       
  1045     // Short navi pane
       
  1046     TAknLayoutRect naviSrtRect;        
       
  1047     naviSrtRect.LayoutRect(
       
  1048         statusPaneRect,
       
  1049         AknLayoutScalable_Avkon::navi_pane_srt( 0 ) );        
       
  1050 
       
  1051     TRect rect( naviSrtRect.Rect() );
       
  1052         
       
  1053     // Set relative to navipane coordinates
       
  1054     rect.Move( -naviPaneRect.iTl.iX, 0 );
       
  1055     rect.iTl.iY = 0;
       
  1056     rect.SetHeight( naviSrtRect.Rect().Height() );
       
  1057 
       
  1058     return rect;
       
  1059     }
       
  1060 
       
  1061 
       
  1062 // ---------------------------------------------------------------------------
       
  1063 // CAknNavigationDecorator::DecoratedControlRect
       
  1064 // Returns the rectangle of the navigation decorator in relation to the
       
  1065 // navi pane.
       
  1066 // ---------------------------------------------------------------------------
       
  1067 //
       
  1068 TRect CAknNavigationDecorator::DecoratedControlRect( TInt aControlType,
       
  1069                                                      TBool aArrowsUsed )
       
  1070     {
       
  1071     TRect rect;
       
  1072 
       
  1073     switch ( aControlType )
       
  1074         {
       
  1075         case ETabGroup:
       
  1076             {
       
  1077             rect = DecoratedTabControlRect( ETrue, aArrowsUsed );
       
  1078             break;
       
  1079             }
       
  1080         case ENaviVolume:
       
  1081             {
       
  1082             rect = DecoratedVolumeControlRect();
       
  1083             break;
       
  1084             }
       
  1085         default:
       
  1086             {
       
  1087             rect = DecoratedDefaultControlRect();
       
  1088             break;
       
  1089             }
       
  1090         }
       
  1091 
       
  1092     return rect;
       
  1093     }
       
  1094 
       
  1095 
       
  1096 // ---------------------------------------------------------------------------
       
  1097 // CAknNavigationDecorator::DecoratedControlRect
       
  1098 // Returns the default rectangle of the navigation decorator.
       
  1099 // ---------------------------------------------------------------------------
       
  1100 //
       
  1101 TRect CAknNavigationDecorator::DecoratedDefaultControlRect()
       
  1102     {
       
  1103     TRect rect;
       
  1104     
       
  1105     TRect naviPaneRect;
       
  1106     AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::ENaviPane, naviPaneRect );
       
  1107 
       
  1108     if ( AknStatuspaneUtils::SmallLayoutActive() )
       
  1109         {
       
  1110         // screen
       
  1111         TRect screenRect;
       
  1112         AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
       
  1113     
       
  1114         // top area
       
  1115         TAknLayoutRect topAreaLayoutRect;        
       
  1116         topAreaLayoutRect.LayoutRect(
       
  1117             screenRect,
       
  1118             AknLayoutScalable_Avkon::area_top_pane( 1 ) );
       
  1119         
       
  1120         // small statuspane      
       
  1121         TAknLayoutRect statusPaneLayoutRect;
       
  1122         statusPaneLayoutRect.LayoutRect(
       
  1123             topAreaLayoutRect.Rect(),
       
  1124             AknLayoutScalable_Avkon::status_small_pane() );
       
  1125         TRect statusPaneRect( statusPaneLayoutRect.Rect() );
       
  1126         
       
  1127         TAknWindowComponentLayout signalPaneLayout(
       
  1128             AknLayoutScalable_Avkon::status_small_pane_g2( 0 ) );
       
  1129         TAknLayoutRect signalPaneLayoutRect;
       
  1130         signalPaneLayoutRect.LayoutRect( statusPaneRect, signalPaneLayout );
       
  1131 
       
  1132         rect = statusPaneRect; 
       
  1133 
       
  1134         CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
       
  1135         if ( statusPane &&
       
  1136              statusPane->PaneCapabilities(TUid::Uid(EEikStatusPaneUidSignal)).IsInCurrentLayout() )
       
  1137             {
       
  1138             TSize size( rect.Size() );
       
  1139             size.iWidth -= signalPaneLayoutRect.Rect().Width();            
       
  1140             rect.SetSize( size );
       
  1141             }
       
  1142         
       
  1143         // Adjust the size for the navi pane content so that there's space for
       
  1144         // the possible navi arrows.
       
  1145         TInt arrowWidth = NaviArrowRect( ELeftButton ).Width();
       
  1146         rect.iTl.iX += arrowWidth;
       
  1147         rect.iBr.iX -= arrowWidth;
       
  1148         }
       
  1149     else if ( AknStatuspaneUtils::StaconPaneActive() )
       
  1150         {
       
  1151         // navi navi pane
       
  1152         TAknLayoutRect naviNaviLayoutRect;        
       
  1153         naviNaviLayoutRect.LayoutRect(
       
  1154             naviPaneRect,
       
  1155             AknLayoutScalable_Avkon::navi_navi_pane() );        
       
  1156         
       
  1157         // pane for text and graphics
       
  1158         TAknLayoutRect naviControlLayoutRect;        
       
  1159         naviControlLayoutRect.LayoutRect(
       
  1160             naviNaviLayoutRect.Rect(),
       
  1161             AknLayoutScalable_Avkon::navi_navi_icon_text_pane() );
       
  1162         
       
  1163         rect = naviControlLayoutRect.Rect();
       
  1164         
       
  1165         // Set relative to stacon navipane coordinates
       
  1166         rect.Move( -naviPaneRect.iTl.iX,
       
  1167                    -naviControlLayoutRect.Rect().iTl.iY ); 
       
  1168         }       
       
  1169     else
       
  1170         {
       
  1171         // navi navi pane
       
  1172         TAknLayoutRect naviNaviLayoutRect;        
       
  1173         naviNaviLayoutRect.LayoutRect(
       
  1174             naviPaneRect,
       
  1175             AknLayoutScalable_Avkon::navi_navi_pane() );        
       
  1176         
       
  1177         // pane for text and graphics
       
  1178         TAknLayoutRect naviControlLayoutRect;        
       
  1179         naviControlLayoutRect.LayoutRect(
       
  1180             naviNaviLayoutRect.Rect(),
       
  1181             AknLayoutScalable_Avkon::navi_navi_icon_text_pane() );         
       
  1182         TRect naviControlRect( naviControlLayoutRect.Rect() );
       
  1183         
       
  1184         rect = naviControlRect;
       
  1185         rect.Move( -naviNaviLayoutRect.Rect().iTl.iX,
       
  1186                    -naviControlRect.iTl.iY );
       
  1187         }
       
  1188 
       
  1189     return rect;
       
  1190     }
       
  1191 
       
  1192 
       
  1193 // ---------------------------------------------------------------------------
       
  1194 // CAknNavigationDecorator::DecoratedTabControlRect
       
  1195 // Returns the tab group rectangle in relation to the navi pane.
       
  1196 // ---------------------------------------------------------------------------
       
  1197 //
       
  1198 TRect CAknNavigationDecorator::DecoratedTabControlRect( TBool aTopAdjacent,
       
  1199                                                         TBool aArrowsUsed )
       
  1200     {
       
  1201     TRect rect;
       
  1202 
       
  1203     // "Stacon" statuspane
       
  1204     if ( AknStatuspaneUtils::StaconPaneActive() )
       
  1205         {
       
  1206         TRect naviPaneRect;
       
  1207         AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::ENaviPane,
       
  1208                                            naviPaneRect );
       
  1209 
       
  1210         TInt variety = AknStatuspaneUtils::ExtendedStaconPaneActive() ? 1 : 0;
       
  1211 
       
  1212         TAknLayoutRect staconNaviTabRect;
       
  1213         staconNaviTabRect.LayoutRect(
       
  1214             naviPaneRect,
       
  1215             AknLayoutScalable_Avkon::navi_navi_pane_stacon( variety ) );
       
  1216 
       
  1217         // tab pane
       
  1218         TAknLayoutRect tabsPaneLayoutRect;
       
  1219         tabsPaneLayoutRect.LayoutRect(
       
  1220             staconNaviTabRect.Rect(),
       
  1221             AknLayoutScalable_Avkon::navi_navi_tabs_pane() );
       
  1222         TRect tabsRect( tabsPaneLayoutRect.Rect() );
       
  1223 
       
  1224         rect = tabsRect;
       
  1225 
       
  1226         // Set relative to stacon navipane coordinates
       
  1227         rect.Move( -staconNaviTabRect.Rect().iTl.iX, -tabsRect.iTl.iY );
       
  1228         }
       
  1229     else
       
  1230         {
       
  1231         TBool penEnabled( AknLayoutUtils::PenEnabled() );
       
  1232         TRect naviPaneRect;
       
  1233         AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::ENaviPane,
       
  1234                                            naviPaneRect );
       
  1235 
       
  1236         if ( !penEnabled )
       
  1237             {
       
  1238             // Tab pane is the only control which doesn't use the wide navi pane
       
  1239             // layout in non-touch portrait mode, so we can't get the navi
       
  1240             // pane rect directly from AknLayoutUtils.
       
  1241             TRect statusPaneRect;
       
  1242             AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EStatusPane,
       
  1243                                                statusPaneRect );
       
  1244 
       
  1245             TAknLayoutRect naviPaneLayoutRect;
       
  1246             naviPaneLayoutRect.LayoutRect(
       
  1247                 statusPaneRect,
       
  1248                 AknLayoutScalable_Avkon::navi_pane( 5 ) );
       
  1249             naviPaneRect = naviPaneLayoutRect.Rect();
       
  1250             }
       
  1251         
       
  1252         if ( aArrowsUsed )
       
  1253             {
       
  1254             // navi navi pane
       
  1255             TAknLayoutRect naviNaviPaneLayoutRect;
       
  1256             naviNaviPaneLayoutRect.LayoutRect(
       
  1257                 naviPaneRect,
       
  1258                 AknLayoutScalable_Avkon::navi_navi_pane() );
       
  1259     
       
  1260             // tab pane
       
  1261             TAknLayoutRect tabsPaneLayoutRect;
       
  1262             tabsPaneLayoutRect.LayoutRect(
       
  1263                 naviNaviPaneLayoutRect.Rect(),
       
  1264                 AknLayoutScalable_Avkon::navi_navi_tabs_pane() );
       
  1265             TRect tabsRect( tabsPaneLayoutRect.Rect() );
       
  1266             
       
  1267             rect = tabsRect;
       
  1268             
       
  1269             if ( aTopAdjacent )
       
  1270                 {
       
  1271                 rect.Move( -naviNaviPaneLayoutRect.Rect().iTl.iX,
       
  1272                            -tabsRect.iTl.iY );
       
  1273                 }
       
  1274             else
       
  1275                 {
       
  1276                 rect.Move( -naviNaviPaneLayoutRect.Rect().iTl.iX,
       
  1277                            -( tabsRect.iTl.iY - ( naviPaneRect.Height() -
       
  1278                                                   tabsRect.Height() ) ) );
       
  1279                 }
       
  1280             }
       
  1281         else
       
  1282             {
       
  1283             rect = naviPaneRect;
       
  1284             rect.Move( -naviPaneRect.iTl.iX,
       
  1285                        -naviPaneRect.iTl.iY );
       
  1286             }
       
  1287         }
       
  1288 
       
  1289     return rect;
       
  1290     }
       
  1291 
       
  1292 
       
  1293 TRect CAknNavigationDecorator::DecoratedVolumeControlRect()
       
  1294     {
       
  1295     TRect rect;
       
  1296     
       
  1297     // screen
       
  1298     TRect screenRect;
       
  1299     AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
       
  1300     
       
  1301     if ( AknStatuspaneUtils::SmallLayoutActive() )
       
  1302         {
       
  1303         // top area
       
  1304         TAknLayoutRect topAreaLayoutRect;        
       
  1305         topAreaLayoutRect.LayoutRect(
       
  1306             screenRect,
       
  1307             AknLayoutScalable_Avkon::area_top_pane( 1 ) );
       
  1308         
       
  1309         // small statuspane      
       
  1310         TAknLayoutRect statusPaneLayoutRect;
       
  1311         statusPaneLayoutRect.LayoutRect(
       
  1312             topAreaLayoutRect.Rect(),
       
  1313             AknLayoutScalable_Avkon::status_small_pane() );
       
  1314         TRect statusPaneRect( statusPaneLayoutRect.Rect() );
       
  1315         
       
  1316         rect = statusPaneRect; 
       
  1317         
       
  1318         statusPaneLayoutRect.LayoutRect(
       
  1319             rect,
       
  1320             AknLayoutScalable_Avkon::status_small_volume_pane() );
       
  1321         rect = statusPaneLayoutRect.Rect();
       
  1322         }
       
  1323         
       
  1324     else if ( AknStatuspaneUtils::StaconPaneActive() )
       
  1325         {
       
  1326         // bottom area
       
  1327         TAknLayoutRect bottomAreaLayoutRect;        
       
  1328         bottomAreaLayoutRect.LayoutRect(
       
  1329             screenRect,
       
  1330             AknLayoutScalable_Avkon::area_bottom_pane( 2 ) );        
       
  1331             
       
  1332         // stacon bottom
       
  1333         TAknLayoutRect staconBottomLayoutRect;
       
  1334         staconBottomLayoutRect.LayoutRect(
       
  1335             bottomAreaLayoutRect.Rect(),
       
  1336             AknLayoutScalable_Avkon::stacon_bottom_pane() );
       
  1337             
       
  1338         TInt naviPaneVariety = AknStatuspaneUtils::StaconSoftKeysRight() ? 2 : 3;
       
  1339         TAknLayoutRect staconNaviRect;        
       
  1340         staconNaviRect.LayoutRect(
       
  1341             staconBottomLayoutRect.Rect(),
       
  1342             AknLayoutScalable_Avkon::navi_pane_stacon( naviPaneVariety ) );        
       
  1343 
       
  1344         TAknLayoutRect staconNaviControlRect;        
       
  1345         staconNaviControlRect.LayoutRect(
       
  1346             staconNaviRect.Rect(),
       
  1347             AknLayoutScalable_Avkon::navi_navi_pane() );
       
  1348         
       
  1349         TAknLayoutRect volumeControlRect;
       
  1350         volumeControlRect.LayoutRect(
       
  1351             staconNaviControlRect.Rect(),
       
  1352             AknLayoutScalable_Avkon::navi_navi_volume_pane() );
       
  1353 
       
  1354         rect = volumeControlRect.Rect();
       
  1355         
       
  1356         // Set relative to stacon navipane coordinates
       
  1357         rect.Move( -staconNaviRect.Rect().iTl.iX, 0 ); 
       
  1358         rect.iTl.iY = 0;
       
  1359         rect.SetHeight( volumeControlRect.Rect().Height() );
       
  1360         }
       
  1361         
       
  1362     // "Flat" statuspane
       
  1363     else if ( AknStatuspaneUtils::FlatLayoutActive() )
       
  1364         {
       
  1365         TAknLayoutRect naviRect;        
       
  1366         naviRect.LayoutRect(
       
  1367             screenRect,
       
  1368             AknLayoutScalable_Avkon::navi_pane( 2 ) );
       
  1369         
       
  1370         TAknLayoutRect naviNaviLayoutRect;        
       
  1371         naviNaviLayoutRect.LayoutRect(
       
  1372             naviRect.Rect(),
       
  1373             AknLayoutScalable_Avkon::navi_navi_pane() );
       
  1374         
       
  1375         TAknLayoutRect volumeControlRect;
       
  1376         volumeControlRect.LayoutRect(
       
  1377             naviNaviLayoutRect.Rect(),
       
  1378             AknLayoutScalable_Avkon::navi_navi_volume_pane() );
       
  1379             
       
  1380         rect = volumeControlRect.Rect();
       
  1381         
       
  1382         rect.Move( -naviNaviLayoutRect.Rect().iTl.iX, 0 ); 
       
  1383         rect.iTl.iY = 0;
       
  1384         rect.SetHeight( volumeControlRect.Rect().Height() );
       
  1385         }
       
  1386         
       
  1387     else
       
  1388         {        
       
  1389         // Is battery pane visible in current layout
       
  1390         TInt battery = AknStatuspaneUtils::ExtendedLayoutActive() ? 5 : 0; // classic or extended
       
  1391         
       
  1392         if ( AknStatuspaneUtils::IdleLayoutActive() )
       
  1393             {
       
  1394             battery = AknStatuspaneUtils::ExtendedLayoutActive() ? 6 : 1; // classic or extended
       
  1395             }
       
  1396         else if ( AknStatuspaneUtils::UsualLayoutActive() &&
       
  1397                   !Layout_Meta_Data::IsLandscapeOrientation() )
       
  1398             {
       
  1399             battery = 7;
       
  1400             }
       
  1401 
       
  1402         if ( AknStatuspaneUtils::HDLayoutActive() && battery == 5 )
       
  1403             {
       
  1404             battery = 8;
       
  1405             }
       
  1406 
       
  1407         // app window
       
  1408         TAknLayoutRect applicationWindowLayoutRect;
       
  1409         applicationWindowLayoutRect.LayoutRect(
       
  1410             screenRect,
       
  1411             AknLayoutScalable_Avkon::application_window( 0 ) );
       
  1412         
       
  1413         // statuspane
       
  1414         TAknLayoutRect statusPaneLayoutRect;
       
  1415         statusPaneLayoutRect.LayoutRect(
       
  1416             applicationWindowLayoutRect.Rect(),
       
  1417             AknLayoutScalable_Avkon::status_pane( 0 ) );
       
  1418         
       
  1419         // navi pane
       
  1420         TAknLayoutRect naviPaneLayoutRect;
       
  1421         naviPaneLayoutRect.LayoutRect(
       
  1422             statusPaneLayoutRect.Rect(),
       
  1423             AknLayoutScalable_Avkon::navi_pane( battery ) );
       
  1424         
       
  1425         TAknLayoutRect naviNaviLayoutRect;        
       
  1426         naviNaviLayoutRect.LayoutRect(
       
  1427             naviPaneLayoutRect.Rect(),
       
  1428             AknLayoutScalable_Avkon::navi_navi_pane() );
       
  1429         
       
  1430         TAknLayoutRect volumeControlRect;
       
  1431         volumeControlRect.LayoutRect(
       
  1432             naviNaviLayoutRect.Rect(),
       
  1433             AknLayoutScalable_Avkon::navi_navi_volume_pane() );
       
  1434         TRect volumeRect( volumeControlRect.Rect() );
       
  1435         
       
  1436         rect = volumeRect;
       
  1437         
       
  1438         rect.Move( -naviNaviLayoutRect.Rect().iTl.iX, -volumeRect.iTl.iY );
       
  1439         }
       
  1440 
       
  1441     return rect;
       
  1442     }
       
  1443 
       
  1444 EXPORT_C void CAknNavigationDecorator::SetNaviControlLayoutStyle(
       
  1445     TAknNaviControlLayoutStyle aStyle )
       
  1446     {
       
  1447     if ( AknStatuspaneUtils::FlatLayoutActive() &&
       
  1448          !Layout_Meta_Data::IsLandscapeOrientation() )
       
  1449         {
       
  1450         // In portrait flat sp mode only narrow mode is allowed.
       
  1451         iLayoutFlags &= ~ENaviControlLayoutNarrow;
       
  1452         iLayoutFlags &= ~ENaviControlLayoutNormal;
       
  1453         iLayoutFlags |= ENaviControlLayoutNarrow;
       
  1454         }
       
  1455     else if ( NaviControlLayoutStyleSupported( aStyle ) )
       
  1456         {
       
  1457         iLayoutFlags &= ~ENaviControlLayoutNarrow;
       
  1458         iLayoutFlags &= ~ENaviControlLayoutNormal;
       
  1459         iLayoutFlags &= ~ENaviControlLayoutWide;
       
  1460         iLayoutFlags |= aStyle;        
       
  1461         }
       
  1462         
       
  1463     if ( NaviControlLayoutMode() == ENaviControlLayoutModeAutomatic &&
       
  1464          NaviControlLayoutStyle() == ENaviControlLayoutNormal )
       
  1465         {
       
  1466         InitLayoutStyleTimer();
       
  1467         }
       
  1468     else
       
  1469         {
       
  1470         CancelLayoutStyleTimer();
       
  1471         }
       
  1472 
       
  1473     if ( iContainer )
       
  1474         {
       
  1475         iContainer->SetSize( iContainer->Size() );
       
  1476         }
       
  1477     else
       
  1478         {
       
  1479         SizeChanged();
       
  1480         }
       
  1481     }
       
  1482 
       
  1483 
       
  1484 EXPORT_C CAknNavigationDecorator::TAknNaviControlLayoutStyle CAknNavigationDecorator::NaviControlLayoutStyle()
       
  1485     {
       
  1486     if ( iLayoutFlags & ENaviControlLayoutNarrow )
       
  1487         {
       
  1488         return ENaviControlLayoutNarrow;
       
  1489         }
       
  1490     else if ( iLayoutFlags & ENaviControlLayoutWide )
       
  1491         {
       
  1492         return ENaviControlLayoutWide;
       
  1493         }
       
  1494     else
       
  1495         {
       
  1496         return ENaviControlLayoutNormal;
       
  1497         }
       
  1498     }
       
  1499 
       
  1500 
       
  1501 EXPORT_C void CAknNavigationDecorator::SetNaviControlLayoutMode(
       
  1502     TAknNaviControlLayoutMode aMode )
       
  1503     {
       
  1504     iLayoutFlags &= ~ENaviControlLayoutModeAutomatic;                
       
  1505     iLayoutFlags &= ~ENaviControlLayoutModeForced;                
       
  1506     iLayoutFlags |= aMode;
       
  1507 
       
  1508     if ( NaviControlLayoutMode() == ENaviControlLayoutModeForced )
       
  1509         {
       
  1510         CancelLayoutStyleTimer();
       
  1511         }
       
  1512     else 
       
  1513         {
       
  1514         if ( NaviControlLayoutMode()  == ENaviControlLayoutModeAutomatic &&
       
  1515              NaviControlLayoutStyle() == ENaviControlLayoutNormal )
       
  1516             {
       
  1517             InitLayoutStyleTimer();
       
  1518             }        
       
  1519         }          
       
  1520     }
       
  1521 
       
  1522 
       
  1523 EXPORT_C CAknNavigationDecorator::TAknNaviControlLayoutMode CAknNavigationDecorator::NaviControlLayoutMode()
       
  1524     {
       
  1525     if ( iLayoutFlags & ENaviControlLayoutModeForced )
       
  1526         {
       
  1527         return ENaviControlLayoutModeForced;
       
  1528         }
       
  1529     else
       
  1530         {
       
  1531         return ENaviControlLayoutModeAutomatic;
       
  1532         }
       
  1533     }
       
  1534 
       
  1535 
       
  1536 EXPORT_C TBool CAknNavigationDecorator::NaviControlLayoutStyleSupported(
       
  1537     TAknNaviControlLayoutStyle aStyle )
       
  1538     {
       
  1539     TBool retVal( EFalse );
       
  1540     TBool penEnabled( AknLayoutUtils::PenEnabled() );
       
  1541 
       
  1542     if ( aStyle == ENaviControlLayoutNormal )
       
  1543         {
       
  1544         retVal = ETrue;
       
  1545         }
       
  1546     else if ( aStyle == ENaviControlLayoutNarrow )
       
  1547         {
       
  1548         if ( ( iControlType == ETabGroup && !penEnabled ) ||
       
  1549              iControlType == ENaviLabel ||
       
  1550              iControlType == ENaviImage ||
       
  1551              iControlType == EHintText ||
       
  1552              iControlType == EEditorIndicator )
       
  1553             {
       
  1554             retVal = ETrue;
       
  1555             }
       
  1556         }
       
  1557     else if ( aStyle == ENaviControlLayoutWide )
       
  1558         {
       
  1559         // Wide layout is not currently supported for tabs in non-touch
       
  1560         // layouts.
       
  1561         if ( iControlType == ETabGroup && !penEnabled )
       
  1562             {
       
  1563             retVal = EFalse;
       
  1564             }
       
  1565         else
       
  1566             {
       
  1567             retVal = ETrue;
       
  1568             }
       
  1569         }
       
  1570 
       
  1571     return retVal;
       
  1572     }
       
  1573 
       
  1574 
       
  1575 void CAknNavigationDecorator::InitLayoutStyleTimer()
       
  1576     {
       
  1577     if ( IsVisible() )
       
  1578         {
       
  1579         const TInt KIdleDelay = 5000000; // 5 s
       
  1580         iLayoutStyleTimer->Cancel();    
       
  1581         iLayoutStyleTimer->Start(TTimeIntervalMicroSeconds32(KIdleDelay),
       
  1582             TTimeIntervalMicroSeconds32(KIdleDelay), 
       
  1583             TCallBack(CAknNavigationDecorator::LayoutStyleEvent, this));
       
  1584         }
       
  1585     }
       
  1586 
       
  1587 void CAknNavigationDecorator::CancelLayoutStyleTimer()
       
  1588     {
       
  1589     if (iLayoutStyleTimer && iLayoutStyleTimer->IsActive())
       
  1590         {
       
  1591         iLayoutStyleTimer->Cancel();
       
  1592         }    
       
  1593     }
       
  1594 
       
  1595 TInt CAknNavigationDecorator::LayoutStyleEvent( TAny* aPtr )
       
  1596     {
       
  1597     ( ( CAknNavigationDecorator*) aPtr )->DoLayoutStyleEvent();
       
  1598     return ETrue;
       
  1599     }
       
  1600 
       
  1601 void CAknNavigationDecorator::DoLayoutStyleEvent()
       
  1602     {
       
  1603     // First check that status pane layout or layout mode
       
  1604     // has not been changed during timeout time.
       
  1605     if ( !iContainer ||
       
  1606          ( iContainer && iContainer->Top() != this ) ||
       
  1607          !AknStatuspaneUtils::FlatLayoutActive() ||
       
  1608          NaviControlLayoutMode() != ENaviControlLayoutModeAutomatic ||
       
  1609          !IsVisible() )
       
  1610         {
       
  1611         CancelLayoutStyleTimer();
       
  1612         return; 
       
  1613         }
       
  1614     
       
  1615     // Only if automatic mode is active and control supports narrow layout style 
       
  1616     // and titlepane text does not fit completely in normal mode
       
  1617     // we change the layout style...
       
  1618     CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
       
  1619     CCoeControl* navipanecontrol = NULL;
       
  1620     CCoeControl* titlepaneControl = NULL;
       
  1621     TBool textDoesFitVisibleTitlePaneArea = EFalse;
       
  1622     
       
  1623     if ( statusPane )
       
  1624         {
       
  1625         TRAP_IGNORE( navipanecontrol =
       
  1626             statusPane->ControlL(TUid::Uid( EEikStatusPaneUidNavi ) ) );
       
  1627         CAknTitlePane* titlePane =
       
  1628             dynamic_cast <CAknTitlePane*> ( titlepaneControl );
       
  1629             
       
  1630         TRAP_IGNORE( titlepaneControl =
       
  1631             statusPane->ControlL(TUid::Uid( EEikStatusPaneUidTitle ) ) );
       
  1632     
       
  1633         if ( navipanecontrol && titlePane )
       
  1634             {        
       
  1635             CAknTitlePaneLabel* titleLabel =
       
  1636                 static_cast <CAknTitlePaneLabel*> ( titlePane->TextLabel() );
       
  1637                 
       
  1638             if ( titleLabel )
       
  1639                 {
       
  1640                 // check it text fits, add some safety margin (15%)
       
  1641                 TInt textlength = titleLabel->TextLength();
       
  1642                 TInt visibleAreaForText =
       
  1643                     titlepaneControl->Size().iWidth - navipanecontrol->Size().iWidth;
       
  1644                 if ( textlength < ( visibleAreaForText * 85 / 100) )
       
  1645                     {
       
  1646                     textDoesFitVisibleTitlePaneArea = ETrue;
       
  1647                     }
       
  1648                 }            
       
  1649             }
       
  1650         }
       
  1651     
       
  1652     if ( NaviControlLayoutMode() == ENaviControlLayoutModeAutomatic &&
       
  1653          NaviControlLayoutStyleSupported( ENaviControlLayoutNarrow ) &&
       
  1654          !textDoesFitVisibleTitlePaneArea )
       
  1655         {
       
  1656         SetNaviControlLayoutStyle( ENaviControlLayoutNarrow );         
       
  1657         SizeChanged();
       
  1658         DrawDeferred();
       
  1659         }    
       
  1660     
       
  1661     CancelLayoutStyleTimer();
       
  1662     }
       
  1663 
       
  1664 TInt CAknNavigationDecorator::IndicationDrawCallbackL( TAny* aThis )
       
  1665     {
       
  1666     CAknNavigationDecorator* decorator = 
       
  1667         static_cast<CAknNavigationDecorator*>(aThis);
       
  1668     
       
  1669     decorator->SmallDirectionIndicationL();
       
  1670     
       
  1671     return KErrNone;
       
  1672     }
       
  1673 
       
  1674 void CAknNavigationDecorator::SmallDirectionIndicationL()
       
  1675     {
       
  1676     TRect rect;
       
  1677     
       
  1678     // Cancel blinking if moved from the min or max position,
       
  1679     // unless the area is blank. Then redraw and cancel after redraw
       
  1680     if ( !iNaviArrowLeftDimmed &&
       
  1681          !iNaviArrowRightDimmed && 
       
  1682          ( iExtension->iEffectTimerCount % 2 == 0 ) )
       
  1683         {
       
  1684         CancelTimer();
       
  1685         return;
       
  1686         }
       
  1687     
       
  1688     // Stop timer if done normal-inverted-normal-inverted-normal sequence
       
  1689     // or the user has changed the value from the min or max
       
  1690     if ( iExtension->iEffectTimerCount >= 3 || 
       
  1691          ( !iNaviArrowLeftDimmed &&
       
  1692            !iNaviArrowRightDimmed ) )
       
  1693         {
       
  1694         CancelTimer();
       
  1695         }
       
  1696     
       
  1697     Window().Invalidate( rect );
       
  1698     ActivateGc();
       
  1699             
       
  1700     rect = TRect( iArrowLeftSize );
       
  1701     
       
  1702     // Draw navigation pane scroll indicator arrows if visible
       
  1703     if ( iNaviArrowsVisible && iContainer )
       
  1704         {
       
  1705         CWindowGc& gc = SystemGc();
       
  1706         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1707         MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
       
  1708         
       
  1709         CFbsBitmap* colorbmp = iContainer->NaviColorBitmap();
       
  1710 
       
  1711         if ( iExtension->iBlinkingSide == 
       
  1712              CAknNavigationDecoratorExtension::ENaviDecoratorLeftSide ) 
       
  1713             {
       
  1714             if( iExtension->iEffectTimerCount % 2 == 1 &&
       
  1715                 !iNaviArrowLeftDimmed )
       
  1716                 {
       
  1717                 CFbsBitmap* arrowBmp = &(iContainer->NaviArrowBitmap(0));
       
  1718                 CFbsBitmap* arrowMask = &(iContainer->NaviArrowBitmap(1));
       
  1719                 if( colorbmp && !IsMaskAllBlack( arrowMask ) )
       
  1720                     {
       
  1721                     gc.BitBltMasked( iArrowLeftPos,
       
  1722                                      colorbmp,
       
  1723                                      rect, 
       
  1724                                      arrowMask,
       
  1725                                      ETrue );
       
  1726                     }
       
  1727                 else
       
  1728                     {
       
  1729                     gc.BitBltMasked( iArrowLeftPos,
       
  1730                                      arrowBmp,
       
  1731                                      rect,
       
  1732                                      arrowMask,
       
  1733                                      ETrue );
       
  1734                     }
       
  1735                 }
       
  1736             else
       
  1737                 {
       
  1738                 // draw empty
       
  1739                 AknsDrawUtils::Background(
       
  1740                     skin,
       
  1741                     cc,
       
  1742                     this,
       
  1743                     gc, 
       
  1744                     TRect( iArrowLeftPos, rect.Size() ),
       
  1745                     KAknsDrawParamDefault );
       
  1746                 }
       
  1747             }
       
  1748         rect = TRect( iArrowRightSize );
       
  1749         
       
  1750         if ( iExtension->iBlinkingSide == 
       
  1751              CAknNavigationDecoratorExtension::ENaviDecoratorRightSide ) 
       
  1752             {
       
  1753             if ( iExtension->iEffectTimerCount % 2 == 1 &&
       
  1754                  !iNaviArrowRightDimmed )
       
  1755                 {
       
  1756                 CFbsBitmap* arrowBmp = &(iContainer->NaviArrowBitmap(2));
       
  1757                 CFbsBitmap* arrowMask = &(iContainer->NaviArrowBitmap(3));
       
  1758                 if( colorbmp && !IsMaskAllBlack( arrowMask ) )
       
  1759                     {
       
  1760                     gc.BitBltMasked( iArrowRightPos,
       
  1761                                      colorbmp,
       
  1762                                      rect,
       
  1763                                      arrowMask,
       
  1764                                      ETrue );
       
  1765                     }
       
  1766                 else
       
  1767                     {
       
  1768                     gc.BitBltMasked( iArrowRightPos,
       
  1769                                      arrowBmp,
       
  1770                                      rect,
       
  1771                                      arrowMask,
       
  1772                                      ETrue );
       
  1773                     }
       
  1774                 }
       
  1775             else
       
  1776                 {
       
  1777                 // draw empty
       
  1778                 AknsDrawUtils::Background(
       
  1779                     skin,
       
  1780                     cc,
       
  1781                     this,
       
  1782                     gc, 
       
  1783                     TRect( iArrowRightPos, rect.Size() ),
       
  1784                     KAknsDrawParamDefault );
       
  1785                 }
       
  1786             }
       
  1787         }
       
  1788 
       
  1789     DeactivateGc();
       
  1790     
       
  1791     iExtension->iEffectTimerCount++;
       
  1792     }
       
  1793 
       
  1794 
       
  1795 void CAknNavigationDecorator::StartTimerL()
       
  1796     {
       
  1797     if ( !iExtension->iTimer )
       
  1798         {
       
  1799         iExtension->iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
  1800         }
       
  1801     else if ( iExtension->iTimer->IsActive() )
       
  1802         {
       
  1803         return; // do not re-start as we have the feedback ongoing
       
  1804         }
       
  1805     
       
  1806     iExtension->iEffectTimerCount = 0;
       
  1807 
       
  1808     const TTimeIntervalMicroSeconds32 KArrowFeedbackActionTime = 160 * 1000;
       
  1809     
       
  1810     TCallBack callback( IndicationDrawCallbackL, this );
       
  1811     iExtension->iTimer->Start( KArrowFeedbackActionTime,
       
  1812                                KArrowFeedbackActionTime,
       
  1813                                callback );
       
  1814     }
       
  1815     
       
  1816 void CAknNavigationDecorator::CancelTimer()
       
  1817     {
       
  1818     if ( iExtension && iExtension->iTimer )
       
  1819         {
       
  1820         if ( iExtension->iTimer->IsActive() )
       
  1821             {
       
  1822             iExtension->iTimer->Cancel();
       
  1823             }
       
  1824         }
       
  1825     }
       
  1826 
       
  1827 EXPORT_C void CAknNavigationDecorator::HandleResourceChange( TInt aType )
       
  1828     {
       
  1829     if ( iControlType == ENaviVolume )
       
  1830         {
       
  1831         // We must forward the event to the volume popup instead
       
  1832         // of the old style volume control.
       
  1833         iDecoratedControl->HandleResourceChange( aType );
       
  1834         }
       
  1835     else
       
  1836         {
       
  1837         CCoeControl::HandleResourceChange( aType );
       
  1838         }
       
  1839 
       
  1840     if ( aType == KEikDynamicLayoutVariantSwitch )
       
  1841         {
       
  1842         TAknNaviControlLayoutStyle layoutStyle = NaviControlLayoutStyle();
       
  1843         TAknNaviControlLayoutMode  layoutMode  = NaviControlLayoutMode();
       
  1844         TBool sizeChangedCalled( EFalse );
       
  1845         
       
  1846         if ( layoutMode  == ENaviControlLayoutModeAutomatic &&
       
  1847              layoutStyle == ENaviControlLayoutNarrow )
       
  1848             {
       
  1849             SetNaviControlLayoutStyle( ENaviControlLayoutNormal );
       
  1850             sizeChangedCalled = ETrue;
       
  1851             }
       
  1852         else if ( iControlType == ETabGroup &&
       
  1853                   AknStatuspaneUtils::UsualLayoutActive() &&
       
  1854                   !Layout_Meta_Data::IsLandscapeOrientation() )
       
  1855             {
       
  1856             // Need special handling for tab group in portrait mode usual
       
  1857             // layout if switching from touch layout to a non-touch layout
       
  1858             // or vice versa since the wide layout is not supported in
       
  1859             // non-touch layout but is always used for tab groups in
       
  1860             // portrait touch layouts.
       
  1861             if ( AknLayoutUtils::PenEnabled() )
       
  1862                 {
       
  1863                 if ( layoutStyle != ENaviControlLayoutWide )
       
  1864                     {
       
  1865                     SetNaviControlLayoutMode( ENaviControlLayoutModeForced );
       
  1866                     SetNaviControlLayoutStyle( ENaviControlLayoutWide );
       
  1867                     sizeChangedCalled = ETrue;
       
  1868                     }
       
  1869                 }
       
  1870             else
       
  1871                 {
       
  1872                 if ( layoutStyle == ENaviControlLayoutWide )
       
  1873                     {
       
  1874                     SetNaviControlLayoutMode( ENaviControlLayoutModeAutomatic );
       
  1875                     SetNaviControlLayoutStyle( ENaviControlLayoutNormal );
       
  1876                     sizeChangedCalled = ETrue;
       
  1877                     }
       
  1878                 }
       
  1879             }
       
  1880 
       
  1881         if ( !sizeChangedCalled )
       
  1882             {
       
  1883             SizeChanged();
       
  1884             }
       
  1885         }
       
  1886     }
       
  1887 
       
  1888 
       
  1889 TRect CAknNavigationDecorator::NaviArrowRect( TScrollButton aScrollButton,
       
  1890                                               TBool aNarrowLayout,
       
  1891                                               TRect aNaviRect )
       
  1892     {
       
  1893     TAknLayoutRect layoutRect;
       
  1894     TRect arrowRect;
       
  1895 
       
  1896     TAknWindowComponentLayout arrowLayout;
       
  1897     if ( aNarrowLayout )
       
  1898         {
       
  1899         arrowLayout = aScrollButton == ELeftButton ?
       
  1900             AknLayoutScalable_Avkon::navi_navi_pane_srt_g1( 0 ) :
       
  1901             AknLayoutScalable_Avkon::navi_navi_pane_srt_g2( 0 );
       
  1902         }
       
  1903     else
       
  1904         {
       
  1905         arrowLayout = aScrollButton == ELeftButton ?
       
  1906             AknLayoutScalable_Avkon::navi_navi_pane_g1( 0 ) :
       
  1907             AknLayoutScalable_Avkon::navi_navi_pane_g2( 0 );
       
  1908         }
       
  1909 
       
  1910     // aNaviRect is empty by default
       
  1911     if ( !aNaviRect.IsEmpty() )
       
  1912         {
       
  1913         layoutRect.LayoutRect( aNaviRect, arrowLayout );
       
  1914         arrowRect = layoutRect.Rect();
       
  1915         }
       
  1916     else
       
  1917         {
       
  1918         if ( aNarrowLayout )
       
  1919             {
       
  1920             TRect naviPaneRect( DecoratedControlNarrowRect( 0 ) ); // parameter not used
       
  1921             layoutRect.LayoutRect( naviPaneRect, arrowLayout );
       
  1922             arrowRect = layoutRect.Rect();
       
  1923             }
       
  1924         else
       
  1925             {
       
  1926             TRect naviPaneRect;
       
  1927             AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::ENaviPane,
       
  1928                                                naviPaneRect );
       
  1929 
       
  1930             naviPaneRect.Move( -naviPaneRect.iTl.iX,
       
  1931                                -naviPaneRect.iTl.iY );
       
  1932 
       
  1933             layoutRect.LayoutRect(
       
  1934                 naviPaneRect,
       
  1935                 AknLayoutScalable_Avkon::navi_navi_pane() );
       
  1936             TRect naviNaviRect( layoutRect.Rect() );
       
  1937 
       
  1938             layoutRect.LayoutRect( naviNaviRect, arrowLayout );
       
  1939             arrowRect = layoutRect.Rect();
       
  1940             }
       
  1941         }
       
  1942 
       
  1943     return arrowRect;
       
  1944     }
       
  1945 
       
  1946 //  End of File