uifw/EikStd/coctlsrc/AknButton.cpp
changeset 0 2f259fa3e83a
child 5 aabf2c525e0f
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2005-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:  Button component
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <aknbutton.h>
       
    21 
       
    22 #include <gulicon.h>        // CGulIcon
       
    23 #include <barsread.h>       // TResourceReader
       
    24 #include <avkon.hrh>
       
    25 #include <StringLoader.h>   // StringLoader
       
    26 #include <AknsDrawUtils.h>
       
    27 #include <AknsControlContext.h>
       
    28 #include <AknBidiTextUtils.h>
       
    29 #include <aknlayout.cdl.h>
       
    30 #include <aknlayoutscalable_avkon.cdl.h>
       
    31 #include <AknInfoPopupNoteController.h>
       
    32 #include <AknPictographInterface.h>
       
    33 #include <AknPictographDrawerInterface.h>
       
    34 #include <AknsFrameBackgroundControlContext.h>
       
    35 #include <aknconsts.h>
       
    36 #include <layoutmetadata.cdl.h>
       
    37 #include <AknPriv.hrh>
       
    38 #include <AknLayoutFont.h>
       
    39 #include <akniconconfig.h>
       
    40 
       
    41 #include <AknTasHook.h> // for testability hooks
       
    42 #include "aknresourceprovider.h"
       
    43 #include "aknbitmapresourceitem.h"
       
    44 #include "akncommandbuttonstate.h"
       
    45 
       
    46 #include <touchfeedback.h>
       
    47 const TUint KPointerFlag = 3; // second bit
       
    48  
       
    49 
       
    50 // CONSTANTS
       
    51 enum TSkinItemIdIndex
       
    52     {
       
    53     KFrameId = 0,
       
    54     KCenterId,
       
    55     KLatchedFrameId,
       
    56     KLatchedCenterId,
       
    57     KDimmedFrameId,
       
    58     KDimmedCenterId,
       
    59     KPressedFrameId,
       
    60     KPressedCenterId,
       
    61     KLatchedDimmedFrameId,
       
    62     KLatchedDimmedCenterId
       
    63     };
       
    64 
       
    65 // ATTENTION, if the values bellow are changed, make the changes in AknButton.h
       
    66 const TInt KTimeoutBeforeHelpNote = 150; // in milliseconds
       
    67 const TInt KTimeoutInViewHelpNote = 3000; // in milliseconds
       
    68 
       
    69 const TInt KKeyRepeatDelay = 500000;   // 0,5 seconds
       
    70 const TInt KKeyRepeatInterval = 500000; // 0,5 seconds
       
    71 const TInt KLongPressInterval = 800000; // 0,8 seconds
       
    72 
       
    73 const TInt KDragEventSensitivity = 1;
       
    74 
       
    75 // Value table for 70% Transparency 
       
    76 const TInt KTransparency[256] =
       
    77     { 
       
    78     0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7,
       
    79     8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13,
       
    80     14, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 19,
       
    81     19, 19, 20, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 23, 24, 24,
       
    82     24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29,
       
    83     30, 30, 30, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35,
       
    84     35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 40, 40, 40,
       
    85     41, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 46,
       
    86     46, 46, 47, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 50, 51, 51,
       
    87     51, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 56,
       
    88     57, 57, 57, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62,
       
    89     62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67,
       
    90     68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 73,
       
    91     73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77 
       
    92     };
       
    93 
       
    94 // -----------------------------------------------------------------------------
       
    95 // ResizeIcon
       
    96 // Tries to resize the given icon. If the operation fails the icon is deleted.
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 static TInt ResizeIcon( CGulIcon*& aIcon, 
       
   100                         const TSize& aSize, 
       
   101                         TScaleMode aScaleMode )
       
   102     {
       
   103     TInt retval = KErrNotFound;
       
   104     
       
   105     if ( aIcon )
       
   106         {
       
   107         CFbsBitmap* bmp = aIcon->Bitmap();
       
   108         
       
   109         if ( bmp )
       
   110             {
       
   111             retval = !( aSize == bmp->SizeInPixels() );
       
   112             }
       
   113             
       
   114         if ( retval != KErrNone )
       
   115             {
       
   116             retval = AknIconUtils::SetSize( bmp, aSize, aScaleMode );
       
   117             }
       
   118 
       
   119         // Retval is checked outside of the "if ( bmp )" scope above in order
       
   120         // to detect if the given icon's bitmap is NULL. This is required since
       
   121         // AknIconUtils::SetSize returns KErrNone for NULL bitmaps and we want
       
   122         // to delete icons that couldn't be resized.
       
   123         if ( retval != KErrNone )
       
   124             {
       
   125             delete aIcon;
       
   126             aIcon = NULL;
       
   127             }
       
   128         }
       
   129         
       
   130     return retval;        
       
   131     }
       
   132     
       
   133 static void ReplaceIconStatic( CGulIcon*& aIcon, CGulIcon* aNewIcon, 
       
   134                                TScaleMode aScaleMode )
       
   135     {
       
   136     TSize iconSize( 0, 0 );
       
   137     
       
   138     if ( aIcon && aIcon->Bitmap() )
       
   139         {
       
   140         iconSize = aIcon->Bitmap()->SizeInPixels();
       
   141         }
       
   142         
       
   143     delete aIcon;
       
   144     aIcon = aNewIcon;
       
   145     
       
   146     if ( iconSize != TSize( 0, 0 ) )
       
   147         {
       
   148         ResizeIcon( aIcon, iconSize, aScaleMode );
       
   149         }
       
   150     }
       
   151     
       
   152 // -----------------------------------------------------------------------------
       
   153 // CreateAndSetDimmedIconL
       
   154 // Creates and sets a dimmed icon from the normal icon 
       
   155 // by making a partially transparent version of it.
       
   156 //
       
   157 // @param aIcon The original icon
       
   158 // @param aDimmedIcon The dimmed icon
       
   159 // @param aScaleMode The preferred ScaleMode
       
   160 // -----------------------------------------------------------------------------
       
   161 static void CreateAndSetDimmedIconL( CGulIcon*& aDimmedIcon, 
       
   162                                      const CGulIcon* aIcon, 
       
   163                                      TScaleMode aScaleMode )
       
   164     {
       
   165     if ( aIcon )
       
   166         {
       
   167         CFbsBitmap* mask = aIcon->Mask();
       
   168         
       
   169         if ( mask && mask->DisplayMode() == EGray256 )
       
   170             {
       
   171             CGulIcon* newIcon = CGulIcon::NewLC();
       
   172             CFbsBitmap* newPic = new ( ELeave ) CFbsBitmap;
       
   173             CleanupStack::PushL( newPic );
       
   174             
       
   175             newPic->Duplicate( aIcon->Bitmap()->Handle() );
       
   176             newIcon->SetBitmap( newPic );
       
   177 
       
   178             CFbsBitmap* newMask = new ( ELeave ) CFbsBitmap;
       
   179             
       
   180             User::LeaveIfError( newMask->Create( 
       
   181                 newIcon->Bitmap()->SizeInPixels(), EGray256 ) );
       
   182             CleanupStack::PushL( newMask );
       
   183                
       
   184             CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL( newMask );
       
   185             CleanupStack::PushL( bitmapDevice );
       
   186             
       
   187             CFbsBitGc* bitGc( NULL );
       
   188             User::LeaveIfError( bitmapDevice->CreateContext( bitGc ) );
       
   189             CleanupStack::PushL( bitGc );
       
   190     
       
   191             bitGc->SetPenStyle( CGraphicsContext::ESolidPen );
       
   192             bitGc->BitBlt( TPoint( 0, 0 ), mask );
       
   193            
       
   194             newMask->LockHeap();
       
   195             TInt w = mask->SizeInPixels().iWidth; 
       
   196             TInt h = mask->SizeInPixels().iHeight;
       
   197             TInt dataStride = mask->DataStride() - w; 
       
   198             unsigned char* address = (unsigned char *)newMask->DataAddress();  
       
   199             
       
   200             for ( TInt i = 0; i < h; ++i )
       
   201                 {
       
   202                 for ( TInt j = 0; j < w; ++j )
       
   203                     {
       
   204                     *address = KTransparency[*address];
       
   205                     ++address;
       
   206                     }
       
   207                 address += dataStride;         
       
   208                 }
       
   209 
       
   210             newMask->UnlockHeap();
       
   211             newIcon->SetMask( newMask );
       
   212             ReplaceIconStatic( aDimmedIcon, newIcon, aScaleMode );
       
   213                                
       
   214             CleanupStack::PopAndDestroy( 2 ); // bitmapDevice, bitGc
       
   215             CleanupStack::Pop( 3 ); // newIcon, newPic, newMask
       
   216             }
       
   217         }
       
   218     }
       
   219 // ============================ EXTENSION CLASS ================================
       
   220 
       
   221 NONSHARABLE_CLASS( CAknButtonExtension ) : public CBase, MCoeControlHitTest
       
   222     {
       
   223     friend class CAknButton;    
       
   224 
       
   225 public:
       
   226     // bitflags used to keep track of several button's internal features
       
   227     enum TFlags
       
   228         {
       
   229         EUseAdditionalMask,
       
   230         ECheckHitArea,
       
   231         EDimmed,
       
   232         ELongPressReported,
       
   233         EUseDefaultIconSize,
       
   234         EKeyRepeatEventReported,
       
   235         EUseDefaultMargins
       
   236         };
       
   237         
       
   238     static CAknButtonExtension* NewL( CAknButton& aButton );
       
   239     ~CAknButtonExtension();
       
   240 
       
   241     // Starts the long press timer.
       
   242     void StartLongPressTimerL();
       
   243     
       
   244     TBool HitRegionContains( const TPoint &aPoint, 
       
   245                              const CCoeControl &aControl ) const;
       
   246 
       
   247     void HandleFeedbackAreaChange();
       
   248 private:
       
   249 
       
   250     CAknButtonExtension( CAknButton& aButton );
       
   251     void ConstructL();
       
   252 
       
   253     // Callback method for long press timer.
       
   254     static TInt ReportLongPressL( TAny* aThis );
       
   255 
       
   256     // Handles long press.
       
   257     void DoReportLongPressL();
       
   258 
       
   259     // Deletes pressed down bitmaps
       
   260     void DeletePressedBmps();
       
   261 
       
   262     // Fetches bitmaps from resource provider (if one exists)
       
   263     TBool FetchProviderPressedBmpsL();
       
   264 
       
   265     // Sets bitmaps to resource provider (if one exists)
       
   266     void SetProviderPressedBmpsL();
       
   267 
       
   268 private: // Data
       
   269 
       
   270     CAknButton& iButton;
       
   271     CAknButton::TTooltipPosition iTooltipPosition;
       
   272     CAknPictographInterface* iPictographInterface; // not owned
       
   273     CPeriodic* iLongPressTimer;
       
   274     TInt iLongPressInterval;
       
   275     TFontUnderline iUnderlineStyle;
       
   276     RArray<TAknsItemID> iFrameAndCenterIds;
       
   277     CAknButton::TAlignment iVerticalIconAlignment; 
       
   278     CAknButton::TAlignment iHorizontalIconAlignment;
       
   279     TMargins8 iMargins;
       
   280     TSize iIconSize;
       
   281     CAknButton::TTextAndIconAlignment iTextAndIconAlignment;
       
   282     TBitFlags iFlags;
       
   283     MTouchFeedback* iFeedback;
       
   284     CFbsBitmap* iPressedDownBmp;
       
   285     CFbsBitmap* iPressedDownBmpMask;
       
   286     CAknResourceProvider* iResourceProvider;
       
   287     };
       
   288 
       
   289 // ============================ MEMBER FUNCTIONS ===============================
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // CAknButtonExtension::CAknButtonExtension
       
   293 // C++ default constructor.
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 CAknButtonExtension::CAknButtonExtension( CAknButton& aButton )
       
   297     : iButton( aButton ),
       
   298       iTooltipPosition( CAknButton::EPositionTop ),
       
   299       iLongPressTimer( NULL ),
       
   300       iLongPressInterval( KLongPressInterval ),
       
   301       iUnderlineStyle( EUnderlineOff ),
       
   302       iFrameAndCenterIds( 2 ),
       
   303       iVerticalIconAlignment( CAknButton::ECenter ),
       
   304       iHorizontalIconAlignment( CAknButton::ECenter ),
       
   305       iTextAndIconAlignment( CAknButton::EIconBeforeText ),
       
   306       iResourceProvider( 0 )
       
   307     {
       
   308     // default margins, these are applied to both text and icon
       
   309     iMargins.SetAllValuesTo( 
       
   310         AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine().iW / 10 );
       
   311         
       
   312     // default icon size
       
   313     TRect rect( TSize( 100, 100 ) );
       
   314     TAknLayoutRect layoutRect;
       
   315     layoutRect.LayoutRect( rect, 
       
   316         AknLayoutScalable_Avkon::toolbar_button_pane_g10().LayoutLine() );
       
   317     iIconSize = layoutRect.Rect().Size();
       
   318     iFlags.Set( EUseDefaultIconSize );
       
   319     iFlags.Set( EUseDefaultMargins );
       
   320     }
       
   321 
       
   322 // -----------------------------------------------------------------------------
       
   323 // CAknButtonExtension::~CAknButtonExtension
       
   324 // Destructor.
       
   325 // -----------------------------------------------------------------------------
       
   326 //
       
   327 CAknButtonExtension::~CAknButtonExtension()
       
   328     {
       
   329     delete iLongPressTimer;
       
   330     iPictographInterface = NULL; // not owned
       
   331     iFrameAndCenterIds.Close();
       
   332     DeletePressedBmps();
       
   333     }
       
   334 
       
   335 // -----------------------------------------------------------------------------
       
   336 // CAknButtonExtension::NewL
       
   337 // Symbian two-phased constructor.
       
   338 // -----------------------------------------------------------------------------
       
   339 //
       
   340 CAknButtonExtension* CAknButtonExtension::NewL( CAknButton& aButton )
       
   341     {
       
   342     CAknButtonExtension* ext = new ( ELeave ) CAknButtonExtension( aButton );
       
   343     CleanupStack::PushL( ext );
       
   344     ext->ConstructL();
       
   345     CleanupStack::Pop( ext );
       
   346     return ext;
       
   347     }
       
   348 
       
   349 // -----------------------------------------------------------------------------
       
   350 // CAknButtonExtension::ConstructL
       
   351 // Symbian 2nd stage constructor.
       
   352 // -----------------------------------------------------------------------------
       
   353 //
       
   354 void CAknButtonExtension::ConstructL()
       
   355     {
       
   356     // Normal frame and center
       
   357     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonNormal );
       
   358     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterNormal );
       
   359     // Latched frame and center
       
   360     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonPressed );
       
   361     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterPressed );
       
   362     // Dimmed frame and center
       
   363     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonInactive );
       
   364     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterInactive );
       
   365     // Pressed frame and center
       
   366     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonPressed );
       
   367     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterPressed );
       
   368     // Latched dimmed frame and center
       
   369     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonInactive );
       
   370     iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterInactive );
       
   371     }
       
   372 
       
   373 // -----------------------------------------------------------------------------
       
   374 // CAknButtonExtension::StartLongPressTimerL
       
   375 // Starts the long press timer. The timer is constructed when used for the
       
   376 // first time.
       
   377 // -----------------------------------------------------------------------------
       
   378 //
       
   379 void CAknButtonExtension::StartLongPressTimerL()
       
   380     {
       
   381     if ( !iLongPressTimer )
       
   382         {
       
   383         iLongPressTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
   384         }
       
   385     else if ( iLongPressTimer->IsActive() )
       
   386         {
       
   387         iLongPressTimer->Cancel();
       
   388         }
       
   389 
       
   390     if ( iLongPressInterval > 0 )
       
   391         {
       
   392         iLongPressTimer->Start( iLongPressInterval, iLongPressInterval,
       
   393             TCallBack( ReportLongPressL, this ) );
       
   394         }
       
   395     }
       
   396 
       
   397 // -----------------------------------------------------------------------------
       
   398 // CAknButtonExtension::ReportLongPressL
       
   399 // -----------------------------------------------------------------------------
       
   400 //
       
   401 TInt CAknButtonExtension::ReportLongPressL( TAny* aThis )
       
   402     {
       
   403     static_cast<CAknButtonExtension*>( aThis )->DoReportLongPressL();
       
   404     return 0;
       
   405     }
       
   406 
       
   407 // -----------------------------------------------------------------------------
       
   408 // CAknButtonExtension::DoReportLongPressL
       
   409 // -----------------------------------------------------------------------------
       
   410 //
       
   411 void CAknButtonExtension::DoReportLongPressL()
       
   412     {
       
   413     if ( iLongPressTimer && iLongPressTimer->IsActive() )
       
   414         {
       
   415         iLongPressTimer->Cancel();
       
   416         }
       
   417 
       
   418     if ( iButton.Observer() )
       
   419         {
       
   420         iButton.Observer()->HandleControlEventL( &iButton,
       
   421             static_cast<MCoeControlObserver::TCoeEvent>(
       
   422                  CAknButton::ELongPressEvent ) );
       
   423 
       
   424         iFlags.Set( ELongPressReported );
       
   425         }
       
   426     }
       
   427 
       
   428 
       
   429 // -----------------------------------------------------------------------------
       
   430 // CAknButtonExtension::DeletePressedBmps
       
   431 // Deletes pressed down bitmaps
       
   432 // -----------------------------------------------------------------------------
       
   433 //
       
   434 void CAknButtonExtension::DeletePressedBmps()
       
   435     {
       
   436     delete iPressedDownBmp;
       
   437     delete iPressedDownBmpMask;
       
   438     iPressedDownBmp = 0;
       
   439     iPressedDownBmpMask = 0;
       
   440     }
       
   441 
       
   442 
       
   443 // -----------------------------------------------------------------------------
       
   444 // CAknButtonExtension::FetchProviderPressedBmpsL
       
   445 // Fetches bitmaps from provider (if one exists). Returns ETrue if bitmaps were
       
   446 // found.
       
   447 // -----------------------------------------------------------------------------
       
   448 //
       
   449 TBool CAknButtonExtension::FetchProviderPressedBmpsL()
       
   450     {
       
   451     TBool bmpsFetched = EFalse;
       
   452     if ( iResourceProvider )
       
   453         {
       
   454         MAknResourceItem* resourceItem = 0;
       
   455 
       
   456         // Check if resource provider has item for KPressedFrameId
       
   457         if ( iResourceProvider->GetResourceL( 
       
   458                 KPressedFrameId, resourceItem ) != KErrNotFound 
       
   459             && resourceItem )
       
   460             {
       
   461             DeletePressedBmps();
       
   462             static_cast<CAknBitmapResourceItem*>( resourceItem )->GetBitmaps( 
       
   463                 iPressedDownBmp, iPressedDownBmpMask );
       
   464             delete resourceItem;
       
   465             
       
   466             // Check if found bitmap size matches with button size
       
   467             if ( iPressedDownBmp 
       
   468                 && iPressedDownBmpMask
       
   469                 && iPressedDownBmp->SizeInPixels() == iButton.Size() )
       
   470                 {
       
   471                 bmpsFetched = ETrue;
       
   472                 }
       
   473             // If not, delete the fetched bitmaps
       
   474             else
       
   475                 {
       
   476                 DeletePressedBmps();
       
   477                 }
       
   478             }
       
   479         }
       
   480     return bmpsFetched;
       
   481     }
       
   482 
       
   483 
       
   484 // -----------------------------------------------------------------------------
       
   485 // CAknButtonExtension::SetProviderPressedBmpsL
       
   486 // Sets bitmaps to provider (if one exists).
       
   487 // -----------------------------------------------------------------------------
       
   488 //
       
   489 void CAknButtonExtension::SetProviderPressedBmpsL()
       
   490     {
       
   491     if ( iResourceProvider )
       
   492         {
       
   493         CAknBitmapResourceItem* resourceItem = 
       
   494             CAknBitmapResourceItem::NewL( KPressedFrameId );
       
   495         resourceItem->SetBitmapsL( iPressedDownBmp, iPressedDownBmpMask );
       
   496         iResourceProvider->SetResourceL( 
       
   497             KPressedFrameId, 
       
   498             static_cast<MAknResourceItem*>( resourceItem ) );
       
   499         }
       
   500     }
       
   501     
       
   502     
       
   503 
       
   504 //
       
   505 TBool CAknButtonExtension::HitRegionContains( const TPoint &aPoint, 
       
   506     const CCoeControl& /*aControl*/ ) const
       
   507     {
       
   508     TBool retval = EFalse;
       
   509     
       
   510     TRAP_IGNORE( retval = iButton.HitAreaContainsL( aPoint, iFlags.IsSet( ECheckHitArea ) ) );
       
   511 
       
   512     return retval;
       
   513     }
       
   514 
       
   515 void CAknButtonExtension::HandleFeedbackAreaChange()
       
   516     {
       
   517     // it is possible that feedback does not exist, eg. while booting.
       
   518     // try getting one, and give up if that fails.
       
   519     if ( !iFeedback )
       
   520         {
       
   521         iFeedback = MTouchFeedback::Instance();
       
   522         }
       
   523     if ( !iFeedback )
       
   524         {
       
   525         return;
       
   526         }
       
   527             
       
   528     if ( iButton.ButtonFlags() & KAknButtonHitTest )
       
   529         {
       
   530         // no registry feedback if shaped buttons are used
       
   531         iFeedback->RemoveFeedbackArea( &iButton, 0 );
       
   532         }
       
   533     else
       
   534         {
       
   535         CFeedbackSpec* spec = CFeedbackSpec::New();
       
   536         if (spec)
       
   537             {
       
   538             spec->AddFeedback( ETouchEventStylusDown, 
       
   539                                ETouchFeedbackBasicButton );
       
   540             spec->AddFeedback( ETouchEventStylusUp, 
       
   541                                ETouchFeedbackBasicButton,
       
   542                                ETouchFeedbackVibra );
       
   543             iFeedback->SetFeedbackArea( &iButton, 0, iButton.Rect(), spec );
       
   544             delete spec;
       
   545             }
       
   546         }
       
   547     }
       
   548 
       
   549 // ============================ EXTENSION CLASS ================================
       
   550 
       
   551 NONSHARABLE_CLASS( CAknButtonStateExtension ) : public CBase
       
   552     {
       
   553     friend class CAknButtonState;
       
   554 
       
   555 public:
       
   556     static CAknButtonStateExtension* NewL();
       
   557     ~CAknButtonStateExtension();
       
   558     
       
   559     void ConfigureExtensionFromResourceL( const TInt aResourceId );
       
   560     void ConfigureExtensionFromResourceL( TResourceReader& aReader );
       
   561     
       
   562 private:
       
   563     CAknButtonStateExtension();
       
   564     void ConstructL();
       
   565 
       
   566 private: // Data
       
   567     TBool iGeneratedDimmedIcon;
       
   568     HBufC* iFilePath;
       
   569     TInt iBmpId;
       
   570     TInt iMaskId;
       
   571     TInt iDimmedBmpId;
       
   572     TInt iDimmedMaskId;
       
   573     TInt iPressedBmpId;
       
   574     TInt iPressedMaskId;
       
   575     TInt iHoverBmpId;
       
   576     TInt iHoverMaskId;
       
   577     TAknsItemID iId;
       
   578     TAknsItemID iDimmedId;
       
   579     TAknsItemID iPressedId;
       
   580     TAknsItemID iHoverId;
       
   581     TScaleMode iScaleMode;
       
   582     };
       
   583 
       
   584 // ============================ MEMBER FUNCTIONS ===============================
       
   585 
       
   586 // -----------------------------------------------------------------------------
       
   587 // CAknButtonStateExtension::CAknButtonStateExtension
       
   588 // C++ default constructor.
       
   589 // -----------------------------------------------------------------------------
       
   590 //
       
   591 CAknButtonStateExtension::CAknButtonStateExtension()    
       
   592     : iGeneratedDimmedIcon ( EFalse ), iBmpId( -1 ), iMaskId( -1 ),
       
   593       iDimmedBmpId( -1 ), iDimmedMaskId( -1 ), iPressedBmpId( -1 ),
       
   594       iPressedMaskId( -1 ), iHoverBmpId( -1 ), iHoverMaskId( -1 ),
       
   595       iId( KAknsIIDNone ), iDimmedId( KAknsIIDNone ), 
       
   596       iPressedId( KAknsIIDNone ), iHoverId( KAknsIIDNone ), 
       
   597       iScaleMode( EAspectRatioNotPreserved )
       
   598     {
       
   599     }
       
   600 
       
   601 // -----------------------------------------------------------------------------
       
   602 // CAknButtonStateExtension::~CAknButtonStateExtension
       
   603 // Destructor.
       
   604 // -----------------------------------------------------------------------------
       
   605 //
       
   606 CAknButtonStateExtension::~CAknButtonStateExtension()
       
   607     {
       
   608     delete iFilePath;
       
   609     }
       
   610 
       
   611 // -----------------------------------------------------------------------------
       
   612 // CAknButtonStateExtension::NewL
       
   613 // Symbian two-phased constructor.
       
   614 // -----------------------------------------------------------------------------
       
   615 //
       
   616 CAknButtonStateExtension* CAknButtonStateExtension::NewL()
       
   617     {
       
   618     CAknButtonStateExtension* ext = new ( ELeave ) CAknButtonStateExtension;
       
   619     CleanupStack::PushL( ext );
       
   620     ext->ConstructL();
       
   621     CleanupStack::Pop( ext );
       
   622     return ext;
       
   623     }
       
   624 
       
   625 // -----------------------------------------------------------------------------
       
   626 // CAknButtonStateExtension::ConstructL
       
   627 // Symbian 2nd stage constructor.
       
   628 // -----------------------------------------------------------------------------
       
   629 //
       
   630 void CAknButtonStateExtension::ConstructL()
       
   631     {
       
   632     } //lint !e1762 function cannot be made const
       
   633 
       
   634 // -----------------------------------------------------------------------------
       
   635 // CAknButtonStateExtension::ConfigureExtensionFromResourceL
       
   636 // -----------------------------------------------------------------------------
       
   637 //    
       
   638 void CAknButtonStateExtension::ConfigureExtensionFromResourceL( 
       
   639     const TInt aResourceId )    
       
   640     {
       
   641     
       
   642     if ( aResourceId )
       
   643         {
       
   644         TResourceReader reader;
       
   645         CCoeEnv::Static()->CreateResourceReaderLC( reader, aResourceId );
       
   646         ConfigureExtensionFromResourceL( reader );
       
   647         CleanupStack::PopAndDestroy();
       
   648         }    
       
   649     }
       
   650 
       
   651 // -----------------------------------------------------------------------------
       
   652 // CAknButtonStateExtension::ConfigureExtensionFromResourceL
       
   653 // -----------------------------------------------------------------------------
       
   654 //        
       
   655 void CAknButtonStateExtension::ConfigureExtensionFromResourceL( 
       
   656     TResourceReader& aReader )
       
   657     {
       
   658     TInt version = aReader.ReadInt8();
       
   659 
       
   660     // bmp ids 
       
   661     TInt major = aReader.ReadInt32();
       
   662     TInt minor = aReader.ReadInt32();
       
   663     
       
   664     if ( major != 0 && minor != 0 )
       
   665         {
       
   666         iId.Set( major, minor );    
       
   667         }
       
   668 
       
   669     // dimmed ids
       
   670     major = aReader.ReadInt32();
       
   671     minor = aReader.ReadInt32();
       
   672     
       
   673     if ( major != 0 && minor != 0 )
       
   674         {
       
   675         iDimmedId.Set( major, minor );    
       
   676         }
       
   677 
       
   678     // pressed ids
       
   679     major = aReader.ReadInt32();
       
   680     minor = aReader.ReadInt32();
       
   681     
       
   682     if ( major != 0 && minor != 0 )
       
   683         {
       
   684         iPressedId.Set( major, minor );    
       
   685         }
       
   686 
       
   687     // hover ids
       
   688     major = aReader.ReadInt32();
       
   689     minor = aReader.ReadInt32();
       
   690     
       
   691     if ( major != 0 && minor != 0 )
       
   692         {
       
   693         iHoverId.Set( major, minor );    
       
   694         }
       
   695     }
       
   696     
       
   697 // ============================ MEMBER FUNCTIONS ===============================
       
   698 
       
   699 // -----------------------------------------------------------------------------
       
   700 // CAknButtonState::CAknButtonState
       
   701 // Constructor
       
   702 // -----------------------------------------------------------------------------
       
   703 //
       
   704 EXPORT_C CAknButtonState::CAknButtonState( const TInt aFlags ) :
       
   705                                            iFlags( aFlags )
       
   706     {
       
   707     }
       
   708 
       
   709 // -----------------------------------------------------------------------------
       
   710 // CAknButtonState::~CAknButtonState
       
   711 // Destructor
       
   712 // -----------------------------------------------------------------------------
       
   713 //
       
   714 EXPORT_C CAknButtonState::~CAknButtonState()
       
   715     {
       
   716     delete iIcon;
       
   717     delete iDimmedIcon;
       
   718     delete iPressedIcon;
       
   719     delete iHoverIcon;
       
   720     delete iText;
       
   721     delete iHelpText;
       
   722     delete iExtension;
       
   723     }
       
   724 
       
   725 // -----------------------------------------------------------------------------
       
   726 // CAknButtonState::ConstructFromResourceL
       
   727 // Constructs the button state from the resources
       
   728 // -----------------------------------------------------------------------------
       
   729 //
       
   730 EXPORT_C void CAknButtonState::ConstructFromResourceL( TResourceReader& aReader )
       
   731     {
       
   732     if ( !iExtension )
       
   733         {
       
   734         iExtension = CAknButtonStateExtension::NewL();
       
   735         }
       
   736 
       
   737     // flags
       
   738     iFlags = aReader.ReadInt16();
       
   739 
       
   740     // txt
       
   741     TPtrC txt = aReader.ReadTPtrC();
       
   742     SetTextL( txt );
       
   743 
       
   744     // helptxt
       
   745     TPtrC helpTxt = aReader.ReadTPtrC();
       
   746     SetHelpTextL( helpTxt );
       
   747 
       
   748     if ( iExtension->iFilePath )
       
   749         {
       
   750         delete iExtension->iFilePath;
       
   751         iExtension->iFilePath = NULL;
       
   752         }
       
   753 
       
   754     // bmpfile
       
   755     iExtension->iFilePath = aReader.ReadTPtrC().AllocL();
       
   756 
       
   757     // bmpid & bmpmask
       
   758     iExtension->iBmpId = aReader.ReadInt16();
       
   759     iExtension->iMaskId = aReader.ReadInt16();
       
   760 
       
   761     // dim_bmpid & dim_bmpmask
       
   762     iExtension->iDimmedBmpId = aReader.ReadInt16();
       
   763     iExtension->iDimmedMaskId = aReader.ReadInt16();
       
   764 
       
   765     // press_bmpid & press_bmpmask
       
   766     iExtension->iPressedBmpId = aReader.ReadInt16();
       
   767     iExtension->iPressedMaskId = aReader.ReadInt16();
       
   768 
       
   769     // hover_bmpid & hover_bmpmask
       
   770     iExtension->iHoverBmpId = aReader.ReadInt16();
       
   771     iExtension->iHoverMaskId = aReader.ReadInt16();
       
   772 
       
   773     // extension
       
   774     TInt extensionLink = aReader.ReadInt32();
       
   775     
       
   776     if ( extensionLink != 0 )
       
   777         {
       
   778         iExtension->ConfigureExtensionFromResourceL( extensionLink );
       
   779         }
       
   780         
       
   781     LoadButtonIcon( iIcon );
       
   782     LoadButtonIcon( iDimmedIcon );
       
   783     LoadButtonIcon( iPressedIcon );
       
   784     LoadButtonIcon( iHoverIcon );
       
   785     }
       
   786 
       
   787 // -----------------------------------------------------------------------------
       
   788 // CAknButtonState::ConstructL
       
   789 //
       
   790 // -----------------------------------------------------------------------------
       
   791 //
       
   792 EXPORT_C void CAknButtonState::ConstructL( CGulIcon* aIcon,
       
   793                                            CGulIcon* aDimmedIcon,
       
   794                                            CGulIcon* aPressedIcon,
       
   795                                            CGulIcon* aHoverIcon,
       
   796                                            const TDesC& aText,
       
   797                                            const TDesC& aHelpText )
       
   798     {
       
   799     if ( !iExtension )
       
   800         {
       
   801         iExtension = CAknButtonStateExtension::NewL();
       
   802         }
       
   803 
       
   804     SetIcon( aIcon );
       
   805     SetDimmedIcon( aDimmedIcon );
       
   806     SetPressedIcon( aPressedIcon );
       
   807     SetHoverIcon( aHoverIcon );
       
   808     SetTextL( aText );
       
   809     SetHelpTextL( aHelpText );
       
   810     }
       
   811 
       
   812 // -----------------------------------------------------------------------------
       
   813 // CAknButtonState::
       
   814 // Symbian 2nd phase constructor.
       
   815 // -----------------------------------------------------------------------------
       
   816 //
       
   817 EXPORT_C void CAknButtonState::ConstructL( const TDesC& aFilePath,
       
   818                                            const TInt aBmpId,
       
   819                                            const TInt aMaskId,
       
   820                                            const TInt aDimmedBmpId,
       
   821                                            const TInt aDimmedMaskId,
       
   822                                            const TInt aPressedBmpId,
       
   823                                            const TInt aPressedMaskId,
       
   824                                            const TInt aHoverBmpId,
       
   825                                            const TInt aHoverMaskId,
       
   826                                            const TDesC& aText,
       
   827                                            const TDesC& aHelpText,
       
   828                                            const TAknsItemID& aId,
       
   829                                            const TAknsItemID& aDimmedId,
       
   830                                            const TAknsItemID& aPressedId,
       
   831                                            const TAknsItemID& aHoverId )
       
   832     {
       
   833     UpdateIconL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId, 
       
   834         aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId, aId, aDimmedId, 
       
   835         aPressedId, aHoverId ); 
       
   836 
       
   837     SetTextL( aText );
       
   838     SetHelpTextL( aHelpText );
       
   839     }
       
   840 
       
   841 // -----------------------------------------------------------------------------
       
   842 // CAknButtonState::Icon
       
   843 // Returns the icon for the normal state.
       
   844 // -----------------------------------------------------------------------------
       
   845 //
       
   846 EXPORT_C const CGulIcon* CAknButtonState::Icon() const
       
   847     {
       
   848     return iIcon;
       
   849     }
       
   850 
       
   851 // -----------------------------------------------------------------------------
       
   852 // CAknButtonState::DimmedIcon
       
   853 // Returns the icon for the dimmed state
       
   854 // -----------------------------------------------------------------------------
       
   855 //
       
   856 EXPORT_C const CGulIcon* CAknButtonState::DimmedIcon() const
       
   857     {
       
   858     return iDimmedIcon;
       
   859     }
       
   860 
       
   861 // -----------------------------------------------------------------------------
       
   862 // CAknButtonState::PressedIcon
       
   863 // Returns the icon for the pressed but not released state.
       
   864 // -----------------------------------------------------------------------------
       
   865 //
       
   866 EXPORT_C const CGulIcon* CAknButtonState::PressedIcon() const
       
   867     {
       
   868     return iPressedIcon;
       
   869     }
       
   870 
       
   871 // -----------------------------------------------------------------------------
       
   872 // CAknButtonState::HoverIcon
       
   873 // Returns the icon for the hover state.
       
   874 // -----------------------------------------------------------------------------
       
   875 //
       
   876 EXPORT_C const CGulIcon* CAknButtonState::HoverIcon() const
       
   877     {
       
   878     return iHoverIcon;
       
   879     }
       
   880 
       
   881 // -----------------------------------------------------------------------------
       
   882 // CAknButtonState::Text
       
   883 // Returns the text inside the button.
       
   884 // -----------------------------------------------------------------------------
       
   885 //
       
   886 EXPORT_C const TDesC& CAknButtonState::Text() const
       
   887     {
       
   888     if ( iText )
       
   889         {
       
   890         return *iText;
       
   891         }
       
   892     else
       
   893         {
       
   894         return KNullDesC();
       
   895         }
       
   896     }
       
   897 
       
   898 // -----------------------------------------------------------------------------
       
   899 // CAknButtonState::HelpText
       
   900 // Returns the text inside the help note.
       
   901 // -----------------------------------------------------------------------------
       
   902 //
       
   903 EXPORT_C const TDesC& CAknButtonState::HelpText() const
       
   904     {
       
   905     if ( iHelpText )
       
   906         {
       
   907         return *iHelpText;
       
   908         }
       
   909     else
       
   910         {
       
   911         return KNullDesC();
       
   912         }
       
   913     }
       
   914 
       
   915 // -----------------------------------------------------------------------------
       
   916 // CAknButtonState::Flags
       
   917 // Returns the state flags.
       
   918 // -----------------------------------------------------------------------------
       
   919 //
       
   920 EXPORT_C TInt CAknButtonState::Flags() const
       
   921     {
       
   922     return iFlags;
       
   923     }
       
   924 
       
   925 // -----------------------------------------------------------------------------
       
   926 // CAknButtonState::SetIcon
       
   927 // Sets the icon for the normal state.
       
   928 // -----------------------------------------------------------------------------
       
   929 //
       
   930 EXPORT_C void CAknButtonState::SetIcon( CGulIcon* aIcon )
       
   931     {
       
   932     ReplaceIcon( iIcon, aIcon );
       
   933     
       
   934     if ( iExtension->iGeneratedDimmedIcon )
       
   935         {
       
   936         TRAP_IGNORE( CreateAndSetDimmedIconL( iDimmedIcon, iIcon, 
       
   937             iExtension->iScaleMode ) );   
       
   938         }
       
   939     }
       
   940 
       
   941 // -----------------------------------------------------------------------------
       
   942 // CAknButtonState::SetDimmedIcon
       
   943 // Sets the icon for the dimmed state.
       
   944 // -----------------------------------------------------------------------------
       
   945 //
       
   946 EXPORT_C void CAknButtonState::SetDimmedIcon( CGulIcon* aDimmedIcon )
       
   947     {
       
   948     ReplaceIcon( iDimmedIcon, aDimmedIcon );
       
   949     }
       
   950 
       
   951 // -----------------------------------------------------------------------------
       
   952 // CAknButtonState::SetPressedIcon
       
   953 // Sets the icon for the pressed but not released state.
       
   954 // -----------------------------------------------------------------------------
       
   955 //
       
   956 EXPORT_C void CAknButtonState::SetPressedIcon( CGulIcon* aPressedIcon )
       
   957     {
       
   958     ReplaceIcon( iPressedIcon, aPressedIcon );
       
   959     }
       
   960 
       
   961 // -----------------------------------------------------------------------------
       
   962 // CAknButtonState::SetHoverIcon
       
   963 // Sets the icon for the hover state.
       
   964 // -----------------------------------------------------------------------------
       
   965 //
       
   966 EXPORT_C void CAknButtonState::SetHoverIcon( CGulIcon* aHoverIcon )
       
   967     {
       
   968     ReplaceIcon( iHoverIcon, aHoverIcon );
       
   969     }
       
   970 
       
   971 // -----------------------------------------------------------------------------
       
   972 // CAknButtonState::ReplaceIcon
       
   973 // Replaces the given icon with a new one. If the original icon had its size set
       
   974 // then the new icon is scaled to that size.
       
   975 // -----------------------------------------------------------------------------
       
   976 //
       
   977 void CAknButtonState::ReplaceIcon( CGulIcon*& aIcon, CGulIcon* aNewIcon )
       
   978     {
       
   979         ReplaceIconStatic( aIcon, aNewIcon, iExtension->iScaleMode );
       
   980     }
       
   981 
       
   982     
       
   983 // -----------------------------------------------------------------------------
       
   984 // CAknButtonState::SetTextL
       
   985 // Sets the text inside the button
       
   986 // -----------------------------------------------------------------------------
       
   987 //
       
   988 EXPORT_C void CAknButtonState::SetTextL( const TDesC& aText )
       
   989     {
       
   990     delete iText;
       
   991     iText = NULL;
       
   992 
       
   993     iText = aText.AllocL();
       
   994     }
       
   995 
       
   996 // -----------------------------------------------------------------------------
       
   997 // CAknButtonState::SetHelpTextL
       
   998 // Sets the text inside the help note
       
   999 // -----------------------------------------------------------------------------
       
  1000 //
       
  1001 EXPORT_C void CAknButtonState::SetHelpTextL( const TDesC& aHelpText )
       
  1002     {
       
  1003     delete iHelpText;
       
  1004     iHelpText = NULL;
       
  1005 
       
  1006     iHelpText = aHelpText.AllocL();
       
  1007     }
       
  1008 
       
  1009 // -----------------------------------------------------------------------------
       
  1010 // CAknButtonState::
       
  1011 // Sets state flags.
       
  1012 // -----------------------------------------------------------------------------
       
  1013 //
       
  1014 EXPORT_C void CAknButtonState::SetFlags( const TInt aFlags )
       
  1015     {
       
  1016     iFlags = aFlags;
       
  1017     }
       
  1018 
       
  1019 // -----------------------------------------------------------------------------
       
  1020 // CAknButtonState::UpdateIconL
       
  1021 // Updates button icons. 
       
  1022 // -----------------------------------------------------------------------------
       
  1023 void CAknButtonState::UpdateIconL( const TDesC& aFilePath, 
       
  1024                                    const TInt aBmpId, 
       
  1025                                    const TInt aMaskId,
       
  1026                                    const TInt aDimmedBmpId,
       
  1027                                    const TInt aDimmedMaskId,
       
  1028                                    const TInt aPressedBmpId,
       
  1029                                    const TInt aPressedMaskId,
       
  1030                                    const TInt aHoverBmpId,
       
  1031                                    const TInt aHoverMaskId,
       
  1032                                    const TAknsItemID& aId,
       
  1033                                    const TAknsItemID& aDimmedId,
       
  1034                                    const TAknsItemID& aPressedId,
       
  1035                                    const TAknsItemID& aHoverId )
       
  1036 
       
  1037     {
       
  1038     if ( !iExtension )
       
  1039         {
       
  1040         iExtension = CAknButtonStateExtension::NewL();
       
  1041         }
       
  1042 
       
  1043     if ( iExtension->iFilePath )
       
  1044         {        
       
  1045         delete iExtension->iFilePath;
       
  1046         iExtension->iFilePath = NULL;
       
  1047         }
       
  1048 
       
  1049     // try to save some ram by defaulting to avkon bitmap file
       
  1050     if ( aFilePath != KAvkonBitmapFile )
       
  1051         {
       
  1052         iExtension->iFilePath = aFilePath.AllocL();    
       
  1053         }
       
  1054     
       
  1055     iExtension->iBmpId = aBmpId;
       
  1056     iExtension->iMaskId = aMaskId;
       
  1057     iExtension->iDimmedBmpId = aDimmedBmpId;
       
  1058     iExtension->iDimmedMaskId = aDimmedMaskId;
       
  1059     iExtension->iPressedBmpId = aPressedBmpId;
       
  1060     iExtension->iPressedMaskId = aPressedMaskId;
       
  1061     iExtension->iHoverBmpId = aHoverBmpId;
       
  1062     iExtension->iHoverMaskId = aHoverMaskId;
       
  1063     iExtension->iId = aId;
       
  1064     iExtension->iDimmedId = aDimmedId;
       
  1065     iExtension->iPressedId = aPressedId;
       
  1066     iExtension->iHoverId = aHoverId;
       
  1067 
       
  1068     LoadButtonIcon( iIcon );
       
  1069     LoadButtonIcon( iDimmedIcon );
       
  1070     LoadButtonIcon( iPressedIcon );
       
  1071     LoadButtonIcon( iHoverIcon );
       
  1072     }
       
  1073 
       
  1074 // -----------------------------------------------------------------------------
       
  1075 // CAknButtonState::SizeChanged
       
  1076 // Scales function graphics to the given size
       
  1077 // -----------------------------------------------------------------------------
       
  1078 //
       
  1079 EXPORT_C void CAknButtonState::SizeChanged( const TRect& aRect,
       
  1080                                             TScaleMode aScaleMode )
       
  1081     {
       
  1082     ScaleIcons( aRect.Size(), aScaleMode );
       
  1083     }
       
  1084 
       
  1085 // -----------------------------------------------------------------------------
       
  1086 // CAknButtonState::HasText
       
  1087 // Returns ETrue if the text inside button is not empty or space.
       
  1088 // -----------------------------------------------------------------------------
       
  1089 //
       
  1090 EXPORT_C TBool CAknButtonState::HasText() const
       
  1091     {
       
  1092     if ( !iText )
       
  1093         return EFalse;
       
  1094 
       
  1095     TBool ret = EFalse;
       
  1096     for ( TInt i = 0; i < iText->Des().Length(); i++ )
       
  1097         {
       
  1098         TChar c ( (iText->Des())[i]);
       
  1099 
       
  1100 //        TChar::TCategory cat = c.GetCategory();
       
  1101         if ( !c.IsSpace() /*&& cat != TChar::ECoCategory*/ )
       
  1102             {
       
  1103             // not space and not private use char
       
  1104             ret = ETrue;
       
  1105             break;
       
  1106             }
       
  1107         }
       
  1108 
       
  1109     return ret;
       
  1110     }
       
  1111 
       
  1112 // -----------------------------------------------------------------------------
       
  1113 // CAknButtonState::HasHelp
       
  1114 // Returns ETrue if the text inside the help note is not empty or space.
       
  1115 // -----------------------------------------------------------------------------
       
  1116 //
       
  1117 EXPORT_C TBool CAknButtonState::HasHelp() const
       
  1118     {
       
  1119     if ( !iHelpText )
       
  1120         return EFalse;
       
  1121 
       
  1122     TBool ret = EFalse;
       
  1123     for ( TInt i = 0; i < iHelpText->Des().Length(); i++ )
       
  1124         {
       
  1125         TChar c( ( *iHelpText )[i] );
       
  1126 
       
  1127 //        TChar::TCategory cat = c.GetCategory();
       
  1128         if ( !c.IsSpace() /*&& cat != TChar::ECoCategory*/ )
       
  1129             {
       
  1130             // not space and not private use char
       
  1131             ret = ETrue;
       
  1132             break;
       
  1133             }
       
  1134         }
       
  1135 
       
  1136     return ret;
       
  1137     }
       
  1138 
       
  1139 // -----------------------------------------------------------------------------
       
  1140 // CAknButtonState::HandleResourceChange
       
  1141 // Handles changes in state's environment.
       
  1142 // -----------------------------------------------------------------------------
       
  1143 //
       
  1144 void CAknButtonState::HandleResourceChange( TInt aType )
       
  1145     {
       
  1146     // Update icons if skin is changed. KEikDynamicLayoutVariantSwitch event is
       
  1147     // handled via SizeChanged.
       
  1148     if ( aType == KAknsMessageSkinChange )
       
  1149         {
       
  1150         LoadButtonIcon( iIcon );
       
  1151         LoadButtonIcon( iDimmedIcon );
       
  1152         LoadButtonIcon( iPressedIcon );
       
  1153         LoadButtonIcon( iHoverIcon );
       
  1154 
       
  1155         // generated dimmed state icon has to be regenerated
       
  1156         if ( iExtension->iGeneratedDimmedIcon )
       
  1157             {
       
  1158             TRAP_IGNORE( CreateAndSetDimmedIconL( iDimmedIcon, iIcon, 
       
  1159                 iExtension->iScaleMode ) );
       
  1160             }
       
  1161         }
       
  1162     }
       
  1163 
       
  1164 // -----------------------------------------------------------------------------
       
  1165 // CAknButtonState::SetIconScaleMode
       
  1166 // Sets default scaling mode.
       
  1167 // -----------------------------------------------------------------------------
       
  1168 //
       
  1169 void CAknButtonState::SetIconScaleMode( const TScaleMode aScaleMode )
       
  1170     {
       
  1171     iExtension->iScaleMode = aScaleMode;
       
  1172     }
       
  1173     
       
  1174 // -----------------------------------------------------------------------------
       
  1175 // CAknButtonState::CreateButtonIconL
       
  1176 // Creates one of the icons
       
  1177 // -----------------------------------------------------------------------------
       
  1178 //
       
  1179 void CAknButtonState::CreateButtonIconL( CGulIcon*& aIcon,
       
  1180                                          const TDesC& aFilePath,
       
  1181                                          TInt aBmpId,
       
  1182                                          TInt aMaskId,
       
  1183                                          const TAknsItemID& aId ) const
       
  1184     {
       
  1185     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1186 
       
  1187     if ( aIcon )
       
  1188         {
       
  1189         if ( ( aId != KAknsIIDNone && skin ) || aBmpId != -1 )
       
  1190             {
       
  1191             delete aIcon;
       
  1192             aIcon = NULL;
       
  1193             }
       
  1194         }
       
  1195 
       
  1196     if ( aFilePath == KNullDesC || aBmpId == -1 )
       
  1197         {
       
  1198         if ( aId != KAknsIIDNone && skin )
       
  1199             {
       
  1200             aIcon = AknsUtils::CreateGulIconL( skin, aId, EFalse );
       
  1201             }
       
  1202         }
       
  1203     else
       
  1204         {
       
  1205         if ( aId != KAknsIIDNone && skin )
       
  1206             {
       
  1207             aIcon = AknsUtils::CreateGulIconL( skin, aId, aFilePath, aBmpId,
       
  1208                                                aMaskId);
       
  1209             }
       
  1210         else
       
  1211             {
       
  1212             CFbsBitmap* bmp;
       
  1213             CFbsBitmap* mask;
       
  1214             AknIconUtils::CreateIconLC( bmp, mask, aFilePath, aBmpId, aMaskId);
       
  1215             aIcon = CGulIcon::NewL( bmp, mask ); // ownership passed
       
  1216             CleanupStack::Pop( 2 );
       
  1217             }
       
  1218         }
       
  1219     }
       
  1220 
       
  1221 // -----------------------------------------------------------------------------
       
  1222 // CAknButtonState::LoadButtonIcon
       
  1223 // Reloads one button icon.
       
  1224 // -----------------------------------------------------------------------------
       
  1225 //
       
  1226 void CAknButtonState::LoadButtonIcon( CGulIcon*& aIcon ) const
       
  1227     {
       
  1228     TSize iconSize( 0, 0 );
       
  1229     
       
  1230     if ( aIcon && aIcon->Bitmap() )
       
  1231         {
       
  1232         iconSize = aIcon->Bitmap()->SizeInPixels();
       
  1233         }
       
  1234 
       
  1235     TInt bmpId = -1;
       
  1236     TInt maskId = -1;
       
  1237     TAknsItemID skinId = KAknsIIDNone;
       
  1238 
       
  1239     if ( &aIcon == &iIcon )
       
  1240         {
       
  1241         bmpId = iExtension->iBmpId;
       
  1242         maskId = iExtension->iMaskId;
       
  1243         skinId = iExtension->iId;
       
  1244         }
       
  1245     else if ( &aIcon == &iPressedIcon )
       
  1246         {
       
  1247         bmpId = iExtension->iPressedBmpId;
       
  1248         maskId = iExtension->iPressedMaskId;
       
  1249         skinId = iExtension->iPressedId;
       
  1250         }
       
  1251     else if ( &aIcon == &iDimmedIcon )
       
  1252         {
       
  1253         bmpId = iExtension->iDimmedBmpId;
       
  1254         maskId = iExtension->iDimmedMaskId;
       
  1255         skinId = iExtension->iDimmedId;
       
  1256         }
       
  1257     else if ( &aIcon == &iHoverIcon )
       
  1258         {
       
  1259         bmpId = iExtension->iHoverBmpId;
       
  1260         maskId = iExtension->iHoverMaskId;
       
  1261         skinId = iExtension->iHoverId;
       
  1262         }
       
  1263 
       
  1264     TPtrC16 bitmapFile;
       
  1265     
       
  1266     if ( iExtension->iFilePath )
       
  1267         {
       
  1268         bitmapFile.Set( *iExtension->iFilePath );
       
  1269         }
       
  1270     else
       
  1271         {
       
  1272         bitmapFile.Set( KAvkonBitmapFile );
       
  1273         }
       
  1274 
       
  1275     // aIcon is set to NULL if the next call fails
       
  1276     TRAP_IGNORE( CreateButtonIconL( aIcon, bitmapFile, bmpId, maskId, skinId ) );
       
  1277             
       
  1278     if ( aIcon && iconSize != TSize( 0, 0 ) )
       
  1279         {
       
  1280         ResizeIcon( aIcon, iconSize, iExtension->iScaleMode );
       
  1281         }
       
  1282     }                                          
       
  1283 
       
  1284 // -----------------------------------------------------------------------------
       
  1285 // CAknButtonState::ScaleIcons
       
  1286 // Sets the size for bitmap and mask
       
  1287 // -----------------------------------------------------------------------------
       
  1288 //
       
  1289 TInt CAknButtonState::ScaleIcons( const TSize& aSize, TScaleMode aScaleMode )
       
  1290     {
       
  1291     TInt retval = ResizeIcon( iIcon, aSize, aScaleMode );
       
  1292     retval = Min( retval, ResizeIcon( iPressedIcon, aSize, aScaleMode ) );
       
  1293     
       
  1294     // Generated dimmed state icon has to be regenerated
       
  1295     if ( iExtension->iGeneratedDimmedIcon )
       
  1296         {
       
  1297         TRAP_IGNORE ( CreateAndSetDimmedIconL( iDimmedIcon, iIcon, aScaleMode ) );
       
  1298         }
       
  1299     else
       
  1300         {
       
  1301         retval = Min( retval, ResizeIcon( iDimmedIcon, aSize, aScaleMode ) );
       
  1302         }
       
  1303         
       
  1304     return retval;        
       
  1305     }
       
  1306 
       
  1307 // -----------------------------------------------------------------------------
       
  1308 // CAknButtonState::ScaleMode
       
  1309 // Getter for the current scalemode of the state
       
  1310 // -----------------------------------------------------------------------------
       
  1311 TScaleMode CAknButtonState::ScaleMode() const
       
  1312     {
       
  1313     return iExtension->iScaleMode;
       
  1314     }
       
  1315 
       
  1316 // -----------------------------------------------------------------------------
       
  1317 // CAknButtonState::SetGeneratedDimmedIcon
       
  1318 // Whether the dimmed icon of the state is created by owning Button
       
  1319 // -----------------------------------------------------------------------------    
       
  1320 void CAknButtonState::SetGeneratedDimmedIcon( TBool aDimmedIconCreatedByButton )
       
  1321     {
       
  1322     iExtension->iGeneratedDimmedIcon = aDimmedIconCreatedByButton;
       
  1323     }
       
  1324 
       
  1325 // -----------------------------------------------------------------------------
       
  1326 // CAknButtonState::Extension
       
  1327 // -----------------------------------------------------------------------------
       
  1328 //
       
  1329 CAknButtonStateExtension* CAknButtonState::Extension() const
       
  1330     {
       
  1331     return iExtension;
       
  1332     }
       
  1333 
       
  1334 // ============================ MEMBER FUNCTIONS ===============================
       
  1335 
       
  1336 // -----------------------------------------------------------------------------
       
  1337 // CAknButton::NewL
       
  1338 // Two-phased constructor.
       
  1339 // Constructs an empty button
       
  1340 // -----------------------------------------------------------------------------
       
  1341 //
       
  1342 EXPORT_C CAknButton* CAknButton::NewL()
       
  1343     {
       
  1344     CAknButton* self = NewLC();
       
  1345     CleanupStack::Pop( self );
       
  1346     return self;
       
  1347     }
       
  1348 
       
  1349 // -----------------------------------------------------------------------------
       
  1350 // CAknButton::NewLC
       
  1351 // Two-phased constructor.
       
  1352 // Constructs an empty button
       
  1353 // -----------------------------------------------------------------------------
       
  1354 //
       
  1355 EXPORT_C CAknButton* CAknButton::NewLC()
       
  1356     {
       
  1357     CAknButton* self = new (ELeave) CAknButton( 0 );
       
  1358     CleanupStack::PushL( self );
       
  1359     self->ConstructL();
       
  1360     AKNTASHOOK_ADDL( self, "CAknButton" );
       
  1361     return self;
       
  1362     }
       
  1363 
       
  1364 // -----------------------------------------------------------------------------
       
  1365 // CAknButton::NewL
       
  1366 // Two-phased constructor.
       
  1367 // Constructs the button from resources.
       
  1368 // -----------------------------------------------------------------------------
       
  1369 //
       
  1370 EXPORT_C CAknButton* CAknButton::NewL( TResourceReader& aReader )
       
  1371     {
       
  1372     CAknButton* self = NewLC( aReader );
       
  1373     CleanupStack::Pop( self );
       
  1374     return self;
       
  1375     }
       
  1376 
       
  1377 // -----------------------------------------------------------------------------
       
  1378 // CAknButton::NewLC
       
  1379 // Two-phased constructor.
       
  1380 // Constructs the button from resources.
       
  1381 // -----------------------------------------------------------------------------
       
  1382 //
       
  1383 EXPORT_C CAknButton* CAknButton::NewLC( TResourceReader& aReader )
       
  1384     {
       
  1385     CAknButton* self = new( ELeave ) CAknButton( 0 );
       
  1386     CleanupStack::PushL( self );
       
  1387     self->ConstructL();
       
  1388     self->ConstructFromResourceL( aReader );
       
  1389     AKNTASHOOK_ADDL( self, "CAknButton" );
       
  1390     return self;
       
  1391     }
       
  1392 
       
  1393 // -----------------------------------------------------------------------------
       
  1394 // CAknButton::NewL
       
  1395 // Two-phased constructor.
       
  1396 // Constructs the button from resources.
       
  1397 // -----------------------------------------------------------------------------
       
  1398 //
       
  1399 EXPORT_C CAknButton* CAknButton::NewL( const TInt aResourceId )
       
  1400     {
       
  1401     CAknButton* self = NewLC( aResourceId );
       
  1402     CleanupStack::Pop( self );
       
  1403     return self;
       
  1404     }
       
  1405 
       
  1406 // -----------------------------------------------------------------------------
       
  1407 // CAknButton::NewLC
       
  1408 // Two-phased constructor.
       
  1409 // Constructs the button from resources.
       
  1410 // -----------------------------------------------------------------------------
       
  1411 //
       
  1412 EXPORT_C CAknButton* CAknButton::NewLC( const TInt aResourceId )
       
  1413     {
       
  1414     CAknButton* self = new (ELeave) CAknButton( 0 );
       
  1415     CleanupStack::PushL( self );
       
  1416     self->ConstructL();
       
  1417     self->ConstructFromResourceL( aResourceId );
       
  1418     AKNTASHOOK_ADDL( self, "CAknButton" );
       
  1419     return self;
       
  1420     }
       
  1421 
       
  1422 // -----------------------------------------------------------------------------
       
  1423 // CAknButton::NewL
       
  1424 // Two-phased constructor.
       
  1425 // Constructs one state button.
       
  1426 // -----------------------------------------------------------------------------
       
  1427 //
       
  1428 EXPORT_C CAknButton* CAknButton::NewL( CGulIcon* aIcon,
       
  1429                                        CGulIcon* aDimmedIcon,
       
  1430                                        CGulIcon* aPressedIcon,
       
  1431                                        CGulIcon* aHoverIcon,
       
  1432                                        const TDesC& aText,
       
  1433                                        const TDesC& aHelpText,
       
  1434                                        const TInt aButtonFlags,
       
  1435                                        const TInt aStateFlags )
       
  1436     {
       
  1437     CAknButton* self = NewLC( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon,
       
  1438         aText, aHelpText, aButtonFlags, aStateFlags );
       
  1439     CleanupStack::Pop( self );
       
  1440     return self;
       
  1441     }
       
  1442 
       
  1443 // -----------------------------------------------------------------------------
       
  1444 // CAknButton::NewLC
       
  1445 // Two-phased constructor.
       
  1446 // Constructs one state button.
       
  1447 // -----------------------------------------------------------------------------
       
  1448 //
       
  1449 EXPORT_C CAknButton* CAknButton::NewLC( CGulIcon* aIcon,
       
  1450                                         CGulIcon* aDimmedIcon,
       
  1451                                         CGulIcon* aPressedIcon,
       
  1452                                         CGulIcon* aHoverIcon,
       
  1453                                         const TDesC& aText,
       
  1454                                         const TDesC& aHelpText,
       
  1455                                         const TInt aButtonFlags,
       
  1456                                         const TInt aStateFlags )
       
  1457     {
       
  1458     CAknButton* self = new (ELeave) CAknButton( aButtonFlags );
       
  1459     CleanupStack::PushL( self );
       
  1460     self->ConstructL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText,
       
  1461                       aHelpText, aStateFlags );
       
  1462     AKNTASHOOK_ADDL( self, "CAknButton" );
       
  1463     return self;
       
  1464     }
       
  1465 
       
  1466 // -----------------------------------------------------------------------------
       
  1467 // CAknButton::NewL
       
  1468 // Two-phased constructor.
       
  1469 // Constructs one state button.
       
  1470 // -----------------------------------------------------------------------------
       
  1471 //
       
  1472 EXPORT_C CAknButton* CAknButton::NewL( const TDesC& aFilePath,
       
  1473                                        const TInt aBmpId,
       
  1474                                        const TInt aMaskId,
       
  1475                                        const TInt aDimmedBmpId,
       
  1476                                        const TInt aDimmedMaskId,
       
  1477                                        const TInt aPressedBmpId,
       
  1478                                        const TInt aPressedMaskId,
       
  1479                                        const TInt aHoverBmpId,
       
  1480                                        const TInt aHoverMaskId,
       
  1481                                        const TDesC& aText,
       
  1482                                        const TDesC& aHelpText,
       
  1483                                        const TInt aButtonFlags,
       
  1484                                        const TInt aStateFlags,
       
  1485                                        const TAknsItemID& aId,
       
  1486                                        const TAknsItemID& aDimmedId,
       
  1487                                        const TAknsItemID& aPressedId,
       
  1488                                        const TAknsItemID& aHoverId )
       
  1489     {
       
  1490     CAknButton* self = NewLC( aFilePath, aBmpId, aMaskId, aDimmedBmpId,
       
  1491         aDimmedMaskId, aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId,
       
  1492         aText, aHelpText, aButtonFlags, aStateFlags, aId, aDimmedId, aPressedId,
       
  1493         aHoverId );
       
  1494     CleanupStack::Pop( self );
       
  1495     return self;
       
  1496     }
       
  1497 
       
  1498 // -----------------------------------------------------------------------------
       
  1499 // CAknButton::NewLC
       
  1500 // Two-phased constructor.
       
  1501 // Constructs one state button.
       
  1502 // -----------------------------------------------------------------------------
       
  1503 //
       
  1504 EXPORT_C CAknButton* CAknButton::NewLC( const TDesC& aFilePath,
       
  1505                                         const TInt aBmpId,
       
  1506                                         const TInt aMaskId,
       
  1507                                         const TInt aDimmedBmpId,
       
  1508                                         const TInt aDimmedMaskId,
       
  1509                                         const TInt aPressedBmpId,
       
  1510                                         const TInt aPressedMaskId,
       
  1511                                         const TInt aHoverBmpId,
       
  1512                                         const TInt aHoverMaskId,
       
  1513                                         const TDesC& aText,
       
  1514                                         const TDesC& aHelpText,
       
  1515                                         const TInt aButtonFlags,
       
  1516                                         const TInt aStateFlags,
       
  1517                                         const TAknsItemID& aId,
       
  1518                                         const TAknsItemID& aDimmedId,
       
  1519                                         const TAknsItemID& aPressedId,
       
  1520                                         const TAknsItemID& aHoverId )
       
  1521     {
       
  1522     CAknButton* self = new (ELeave) CAknButton( aButtonFlags );
       
  1523     CleanupStack::PushL( self );
       
  1524     self->ConstructL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId,
       
  1525         aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId,
       
  1526         aText, aHelpText, aStateFlags, aId, aDimmedId, aPressedId, aHoverId );
       
  1527     AKNTASHOOK_ADDL( self, "CAknButton" );
       
  1528     return self;
       
  1529     }
       
  1530 
       
  1531 // -----------------------------------------------------------------------------
       
  1532 // CAknButton::CAknButton
       
  1533 // C++ constructor.
       
  1534 // -----------------------------------------------------------------------------
       
  1535 //
       
  1536 EXPORT_C CAknButton::CAknButton( const TInt aFlags )
       
  1537     : iFlags( aFlags ),
       
  1538       iVerticalAlignment( ECenter ),
       
  1539       iHorizontalAlignment( CGraphicsContext::ECenter ),
       
  1540       iTextColorTableId( KAknsIIDQsnTextColors ), // TODO
       
  1541       iTextColorIndex( EAknsCIQsnTextColorsCG80 ), // TODO
       
  1542       iScaleMode( EAspectRatioNotPreserved ),
       
  1543       iHelpNoteWaitInterval( KTimeoutBeforeHelpNote ),
       
  1544       iHelpNoteInViewInterval( KTimeoutInViewHelpNote ),
       
  1545       iKeyRepeatDelay( KKeyRepeatDelay ),
       
  1546       iKeyRepeatInterval( KKeyRepeatInterval )
       
  1547     {
       
  1548     }
       
  1549 
       
  1550 // -----------------------------------------------------------------------------
       
  1551 // CAknButton::ConstructL
       
  1552 // Symbian 2nd phase constructor.
       
  1553 // Constructor for the empty button.
       
  1554 // -----------------------------------------------------------------------------
       
  1555 //
       
  1556 EXPORT_C void CAknButton::ConstructL()
       
  1557     {
       
  1558     TRgb textColor;
       
  1559     
       
  1560     if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor, 
       
  1561         iTextColorTableId, iTextColorIndex ) == KErrNone )
       
  1562         {
       
  1563         OverrideColorL( EColorButtonText, textColor );
       
  1564         }
       
  1565 
       
  1566     if ( !iStates )
       
  1567         {
       
  1568         iStates = new ( ELeave ) CArrayPtrFlat<CAknButtonState>( 2 );
       
  1569         }
       
  1570 
       
  1571     if ( !iBgContext )
       
  1572         {
       
  1573         iBgContext = CAknsFrameBackgroundControlContext::NewL(
       
  1574             KAknsIIDNone, TRect(), TRect(), EFalse );
       
  1575         }
       
  1576   
       
  1577     if ( !iExtension )
       
  1578         {
       
  1579         iExtension = CAknButtonExtension::NewL( *this );
       
  1580         }
       
  1581 
       
  1582     if ( iFlags & KAknButtonHitTest )
       
  1583         {
       
  1584         SetHitTest( iExtension );
       
  1585         }        
       
  1586 
       
  1587     if ( iFlags & KAknButtonNoFrame )
       
  1588         {
       
  1589         iExtension->iMargins.SetAllValuesTo( 0 );
       
  1590         }
       
  1591     
       
  1592     if ( iFlags & KAknButtonTextLeft )
       
  1593         {
       
  1594         iHorizontalAlignment = CGraphicsContext::ELeft;
       
  1595         }
       
  1596     iExtension->HandleFeedbackAreaChange();
       
  1597     }
       
  1598 
       
  1599 // -----------------------------------------------------------------------------
       
  1600 // CAknButton::ConstructL
       
  1601 // Symbian 2nd phase constructor for 1 state button.
       
  1602 // -----------------------------------------------------------------------------
       
  1603 //
       
  1604 EXPORT_C void CAknButton::ConstructL( CGulIcon* aIcon,
       
  1605                                       CGulIcon* aDimmedIcon,
       
  1606                                       CGulIcon* aPressedIcon,
       
  1607                                       CGulIcon* aHoverIcon,
       
  1608                                       const TDesC& aText,
       
  1609                                       const TDesC& aHelpText,
       
  1610                                       const TInt aStateFlags )
       
  1611     {
       
  1612     ConstructL();
       
  1613     AddStateL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText, aHelpText,
       
  1614                aStateFlags);
       
  1615     }
       
  1616 
       
  1617 // -----------------------------------------------------------------------------
       
  1618 // CAknButton::ConstructL
       
  1619 // Symbian 2nd phase constructor for 1 state button
       
  1620 // -----------------------------------------------------------------------------
       
  1621 //
       
  1622 EXPORT_C void CAknButton::ConstructL( const TDesC& aFilePath,
       
  1623                                       const TInt aBmpId,
       
  1624                                       const TInt aMaskId,
       
  1625                                       const TInt aDimmedBmpId,
       
  1626                                       const TInt aDimmedMaskId,
       
  1627                                       const TInt aPressedBmpId,
       
  1628                                       const TInt aPressedMaskId,
       
  1629                                       const TInt aHoverBmpId,
       
  1630                                       const TInt aHoverMaskId,
       
  1631                                       const TDesC& aText,
       
  1632                                       const TDesC& aHelpText,
       
  1633                                       const TInt aStateFlags,
       
  1634                                       const TAknsItemID& aId,
       
  1635                                       const TAknsItemID& aDimmedId,
       
  1636                                       const TAknsItemID& aPressedId,
       
  1637                                       const TAknsItemID& aHoverId )
       
  1638     {
       
  1639     ConstructL();
       
  1640     AddStateL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId,
       
  1641         aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId,
       
  1642         aText, aHelpText, aStateFlags, aId, aDimmedId, aPressedId, aHoverId );
       
  1643     }
       
  1644 
       
  1645 // -----------------------------------------------------------------------------
       
  1646 // Destructor
       
  1647 // -----------------------------------------------------------------------------
       
  1648 //
       
  1649 EXPORT_C CAknButton::~CAknButton()
       
  1650     {
       
  1651     AKNTASHOOK_REMOVE();
       
  1652     if ( iStates )
       
  1653         {
       
  1654         iStates->ResetAndDestroy();
       
  1655         delete iStates;
       
  1656         }
       
  1657 
       
  1658     // MTouchFeedback instance lives in AknAppUi. AppUi might be
       
  1659     // destroyed when this destructor is running. If there is no
       
  1660     // MTouchFeedback instance there is no need to remove any areas
       
  1661     // either, as these are ( naturally ) destroyed with
       
  1662     // MTouchFeedback instance.
       
  1663     MTouchFeedback* fb = MTouchFeedback::Instance();
       
  1664     if ( fb )
       
  1665         {
       
  1666         fb->RemoveFeedbackForControl( this );
       
  1667         }
       
  1668 
       
  1669     delete iBgContext;
       
  1670     delete iDimmedHelpText;
       
  1671     delete iHelpNote;
       
  1672     delete iKeyRepeatTimer;
       
  1673     delete iExtension;
       
  1674     iFont = NULL;
       
  1675     }
       
  1676 
       
  1677 // -----------------------------------------------------------------------------
       
  1678 // CAknButton::ActivateL
       
  1679 // Sets control as ready to be drawn.
       
  1680 // -----------------------------------------------------------------------------
       
  1681 //
       
  1682 EXPORT_C void CAknButton::ActivateL()
       
  1683     {
       
  1684     // request for drag events outside the button
       
  1685     SetAllowStrayPointers();
       
  1686     // Requesting pointer drag events
       
  1687     EnableDragEvents();
       
  1688     
       
  1689     CAknControl::ActivateL();
       
  1690     }
       
  1691 
       
  1692 // -----------------------------------------------------------------------------
       
  1693 // CAknButton::ConstructFromResourceL
       
  1694 // Constructs controls from a resource file.
       
  1695 // -----------------------------------------------------------------------------
       
  1696 //
       
  1697 EXPORT_C void CAknButton::ConstructFromResourceL( TResourceReader& aReader )
       
  1698     {
       
  1699     if ( !iExtension )
       
  1700         {
       
  1701         iExtension = CAknButtonExtension::NewL( *this );
       
  1702         }
       
  1703 
       
  1704     // flags
       
  1705     iFlags = aReader.ReadInt16();
       
  1706 
       
  1707     // state index
       
  1708     SetStateIndexL( aReader.ReadInt16() );
       
  1709 
       
  1710     // read states
       
  1711     const TInt stateCount = aReader.ReadInt16();
       
  1712     for ( TInt ii = 0; ii < stateCount; ii++ )
       
  1713         {
       
  1714         CAknButtonState* state = new (ELeave) CAknButtonState( 0 );
       
  1715         CleanupStack::PushL( state );
       
  1716         state->ConstructFromResourceL( aReader );
       
  1717         iStates->AppendL( state );
       
  1718         CleanupStack::Pop( state );
       
  1719         }
       
  1720 
       
  1721     aReader.ReadInt32(); // extension link, not used currently
       
  1722 
       
  1723     if ( iFlags & KAknButtonHitTest )
       
  1724         {
       
  1725         SetHitTest( iExtension );
       
  1726         }        
       
  1727 
       
  1728     if ( iFlags & KAknButtonNoFrame )
       
  1729         {
       
  1730         iExtension->iMargins.SetAllValuesTo( 0 );
       
  1731         }
       
  1732 
       
  1733     if ( iFlags & KAknButtonTextLeft )
       
  1734         {
       
  1735         iHorizontalAlignment = CGraphicsContext::ELeft;
       
  1736         }
       
  1737     iExtension->HandleFeedbackAreaChange();
       
  1738     }
       
  1739 
       
  1740 // -----------------------------------------------------------------------------
       
  1741 // CAknButton::HandleResourceChange
       
  1742 // Handles a change to the control's resources.
       
  1743 // -----------------------------------------------------------------------------
       
  1744 //
       
  1745 EXPORT_C void CAknButton::HandleResourceChange( TInt aType )
       
  1746     {
       
  1747     // No need to call base class implementation since CountComponentControls
       
  1748     // is always zero.
       
  1749         
       
  1750     if ( aType == KAknsMessageSkinChange || aType == KEikDynamicLayoutVariantSwitch )
       
  1751         {
       
  1752         if ( iButtonPressed )
       
  1753             {
       
  1754             ResetState();
       
  1755             DrawDeferred();
       
  1756             }
       
  1757         }
       
  1758         
       
  1759     // UIFW informs control about lost focus when moved to background.
       
  1760     // Rest of pointer events are no longer forvarded to control.    
       
  1761     if ( aType == KAknMessageFocusLost || aType == KEikMessageFadeAllWindows )
       
  1762         {
       
  1763         if (iHelpNote)
       
  1764             {
       
  1765             iHelpNote->HideInfoPopupNote();
       
  1766             }
       
  1767         
       
  1768         if (iButtonPressed)
       
  1769             {
       
  1770             ResetState();
       
  1771             DrawDeferred();
       
  1772             }
       
  1773         return;
       
  1774         }
       
  1775     
       
  1776     if ( iStates )
       
  1777         {
       
  1778         for ( TInt i = 0; i < iStates->Count(); ++i )
       
  1779             {
       
  1780             CAknButtonState* state = iStates->At( i );
       
  1781             
       
  1782             if ( state )
       
  1783                 {
       
  1784                 state->HandleResourceChange( aType );
       
  1785                 }
       
  1786             }
       
  1787         }
       
  1788 
       
  1789     if ( aType == KAknsMessageSkinChange )
       
  1790         {
       
  1791         TRgb textColor;
       
  1792         
       
  1793         if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor, 
       
  1794                 iTextColorTableId, iTextColorIndex ) == KErrNone )
       
  1795             {
       
  1796             TRAP_IGNORE( OverrideColorL( EColorButtonText, textColor ) );
       
  1797             }
       
  1798     
       
  1799         // generated pressed frame has to be regenerated
       
  1800         if ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame )
       
  1801             {
       
  1802             iExtension->DeletePressedBmps();
       
  1803             TRAP_IGNORE( CreatePressedDownFrameL() );
       
  1804             }
       
  1805         }
       
  1806     }
       
  1807 
       
  1808 // -----------------------------------------------------------------------------
       
  1809 // CAknButton::MinimumSize
       
  1810 // Returns the control's minimum required size. This doesn't include highlight
       
  1811 // area.
       
  1812 // -----------------------------------------------------------------------------
       
  1813 //
       
  1814 EXPORT_C TSize CAknButton::MinimumSize()
       
  1815     {
       
  1816     // by default, margins decide the absolute minimum size...
       
  1817     TInt width = iExtension->iMargins.iLeft + iExtension->iMargins.iRight;
       
  1818     TInt height = iExtension->iMargins.iTop + iExtension->iMargins.iBottom;
       
  1819     
       
  1820     // ...but possible frames may enlarge the required area...
       
  1821     if ( !( iFlags & KAknButtonNoFrame ) )
       
  1822         {
       
  1823         TAknLayoutRect tl;
       
  1824         tl.LayoutRect( Rect(), 
       
  1825             AknLayoutScalable_Avkon::toolbar_button_pane_g2().LayoutLine() );
       
  1826 
       
  1827         TAknLayoutRect br;
       
  1828         br.LayoutRect( Rect(),
       
  1829             AknLayoutScalable_Avkon::toolbar_button_pane_g5().LayoutLine() );
       
  1830 
       
  1831         TInt frameWidth = tl.Rect().Width() + br.Rect().Width();
       
  1832         TInt frameHeight = tl.Rect().Height() + br.Rect().Height();
       
  1833         
       
  1834         if ( !( iFlags & KAknButtonTextInsideFrame ) )
       
  1835             {
       
  1836             width = Max( width, frameWidth );
       
  1837             height = Max( height, frameHeight );
       
  1838             }
       
  1839         else
       
  1840             {
       
  1841             width = frameWidth;
       
  1842             height = frameHeight;
       
  1843             }
       
  1844         }
       
  1845     
       
  1846     // ...as well as evil flags
       
  1847     if ( iStates && ( iFlags & KAknButtonSizeFitText ) )
       
  1848         {
       
  1849         if ( !iFont )
       
  1850             {
       
  1851             iFont = iCoeEnv->NormalFont();
       
  1852             }
       
  1853 
       
  1854         height += iFont->FontMaxHeight();
       
  1855 
       
  1856         TInt textWidth = 0;
       
  1857         
       
  1858         // choose the longest one
       
  1859         for ( TInt ii = 0; ii < iStates->Count(); ii++ )
       
  1860             {
       
  1861             CAknButtonState* state = iStates->At( ii );
       
  1862             if ( state && state->HasText() )
       
  1863                 {
       
  1864                 TInt tempWidth = iFont->TextWidthInPixels( state->Text() );
       
  1865                 textWidth = Max( textWidth, tempWidth );
       
  1866                 }
       
  1867             }
       
  1868             
       
  1869         width += textWidth;
       
  1870         }
       
  1871     
       
  1872     return TSize( width, height );
       
  1873     }
       
  1874 
       
  1875 // -----------------------------------------------------------------------------
       
  1876 // CAknButton::SetDimmed
       
  1877 // Sets button dimmed. Doesn't redraw.
       
  1878 // Button needs to get pointer events even if it is dimmed to be able to show
       
  1879 // help text in dimmed state. So, the CCoeControl::SetDimmed(TBool) cannot be
       
  1880 // used to set button dimmed if the help text is used.
       
  1881 // -----------------------------------------------------------------------------
       
  1882 //
       
  1883 EXPORT_C void CAknButton::SetDimmed( TBool aDimmed )
       
  1884     {
       
  1885     if ( aDimmed )
       
  1886         {
       
  1887         StopKeyRepeatTimer();
       
  1888         StopLongPressTimer();
       
  1889         HideHelp();
       
  1890         iButtonPressed = EFalse;
       
  1891         }
       
  1892     
       
  1893     if ( aDimmed )
       
  1894         {
       
  1895         iExtension->iFlags.Set( CAknButtonExtension::EDimmed );
       
  1896         }
       
  1897     else
       
  1898         {
       
  1899         iExtension->iFlags.Clear( CAknButtonExtension::EDimmed );
       
  1900         }
       
  1901     if ( iExtension->iFeedback )
       
  1902         {
       
  1903         if ( aDimmed )
       
  1904             {
       
  1905             iExtension->iFeedback->MoveFeedbackAreaToFirstPriority( this, 0 );
       
  1906             }        
       
  1907         iExtension->iFeedback->EnableFeedbackForControl( this, !aDimmed && IsVisible() );
       
  1908         }
       
  1909 
       
  1910     TBool hasHelp ( EFalse );
       
  1911     
       
  1912     for ( TInt i = 0; i < iStates->Count(); ++i )
       
  1913         {
       
  1914         CAknButtonState* state = iStates->At( i );
       
  1915         
       
  1916         if ( state )
       
  1917             {
       
  1918             if ( !state->iDimmedIcon )
       
  1919                 {
       
  1920                 TRAP_IGNORE ( CreateAndSetDimmedIconL( state->iDimmedIcon, 
       
  1921                     state->iIcon, state->ScaleMode() ) );
       
  1922                 state->SetGeneratedDimmedIcon( ETrue );
       
  1923                 }
       
  1924             
       
  1925             if ( state->HasHelp() )
       
  1926                 {
       
  1927                 hasHelp = ETrue;
       
  1928                 }
       
  1929             }
       
  1930         }
       
  1931     // None of states has help text, CCoeControl::SetDimmed can be used        
       
  1932     if ( !hasHelp )
       
  1933         {
       
  1934         CCoeControl::SetDimmed( aDimmed );
       
  1935         }
       
  1936     }
       
  1937 
       
  1938 // -----------------------------------------------------------------------------
       
  1939 // CAknButton::OfferKeyEventL
       
  1940 // Handles key events.
       
  1941 // -----------------------------------------------------------------------------
       
  1942 //
       
  1943 EXPORT_C TKeyResponse CAknButton::OfferKeyEventL( const TKeyEvent& aKeyEvent,
       
  1944                                                   TEventCode aType )
       
  1945     {
       
  1946     if ( IsDimmed() )
       
  1947         return EKeyWasNotConsumed;
       
  1948 
       
  1949     if ( aType == EEventKeyDown && IsVisible() )
       
  1950         {
       
  1951         HideHelp(); // hides help text as soon as the first key event comes.
       
  1952         }
       
  1953 
       
  1954     if ( aKeyEvent.iScanCode == EStdKeyDevice3 ||
       
  1955          aKeyEvent.iScanCode == EStdKeyEnter )
       
  1956         {
       
  1957         if ( aType == EEventKeyDown )
       
  1958             {
       
  1959             iKeyDownReported = ETrue;
       
  1960 
       
  1961             if ( !iButtonPressed )
       
  1962                 {
       
  1963                 // show press changes
       
  1964                 iButtonPressed = ETrue;
       
  1965                 if ( NeedsRedrawWhenPressed() )
       
  1966                     {
       
  1967                     DrawNow();
       
  1968                     }
       
  1969                 }
       
  1970 
       
  1971             if ( iFlags & KAknButtonReportOnKeyDown )
       
  1972                 {
       
  1973                 ChangeState( ETrue );
       
  1974                 if ( Observer() )
       
  1975                     {
       
  1976                     Observer()->HandleControlEventL( this,
       
  1977                         MCoeControlObserver::EEventStateChanged );
       
  1978                     }
       
  1979                 }
       
  1980 
       
  1981             if ( iFlags & KAknButtonKeyRepeat )
       
  1982                 {
       
  1983                 iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
       
  1984                 StartKeyRepeatTimerL();
       
  1985                 }
       
  1986 
       
  1987             if ( iFlags & KAknButtonReportOnLongPress )
       
  1988                 {
       
  1989                 iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
       
  1990                 iExtension->StartLongPressTimerL();
       
  1991                 }
       
  1992             }
       
  1993 
       
  1994         else if ( aType == EEventKeyUp )
       
  1995             {
       
  1996             if ( iButtonPressed )
       
  1997                 {
       
  1998                 iButtonPressed = EFalse;
       
  1999 
       
  2000                 if ( NeedsRedrawWhenPressed() )
       
  2001                     {
       
  2002                     DrawNow();
       
  2003                     }
       
  2004                 }
       
  2005 
       
  2006             StopKeyRepeatTimer();
       
  2007             StopLongPressTimer();
       
  2008 
       
  2009             // The state is not changed, if it is already changed on key
       
  2010             // down event, or if a long press or a key repeat event is
       
  2011             // already reported to the observer.
       
  2012             if ( !( iFlags & KAknButtonReportOnKeyDown ) &&
       
  2013                  !( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) &&
       
  2014                  !( iExtension->iFlags.IsSet( CAknButtonExtension::EKeyRepeatEventReported ) ) &&
       
  2015                  iKeyDownReported )
       
  2016                 {
       
  2017                 ChangeState( ETrue );
       
  2018                 if ( Observer() )
       
  2019                     {
       
  2020                     Observer()->HandleControlEventL( this,
       
  2021                         MCoeControlObserver::EEventStateChanged );
       
  2022                     }
       
  2023                 }
       
  2024             else
       
  2025                 {
       
  2026                 if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && iKeyDownReported )
       
  2027                     {
       
  2028                     Observer()->HandleControlEventL( this, 
       
  2029                         static_cast<MCoeControlObserver::TCoeEvent>( 
       
  2030                         CAknButton::ELongPressEndedEvent ) );
       
  2031                     }
       
  2032                 iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
       
  2033                 iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
       
  2034                 }
       
  2035 
       
  2036             if ( iKeyDownReported && RequestExit() && Observer() )
       
  2037                 {
       
  2038                 Observer()->HandleControlEventL( this,
       
  2039                     MCoeControlObserver::EEventRequestExit );
       
  2040                 }
       
  2041 
       
  2042             iKeyDownReported = EFalse;
       
  2043             }
       
  2044         // we don't want aKeyEvent to go somewhere else :)
       
  2045         return EKeyWasConsumed;
       
  2046         }
       
  2047 
       
  2048     return EKeyWasNotConsumed;
       
  2049     }
       
  2050 
       
  2051 // -----------------------------------------------------------------------------
       
  2052 // CAknButton::MakeVisible
       
  2053 // Sets this control as visible or invisible.
       
  2054 // -----------------------------------------------------------------------------
       
  2055 //
       
  2056 EXPORT_C void CAknButton::MakeVisible( TBool aVisible )
       
  2057     {
       
  2058     if ( aVisible != IsVisible() )
       
  2059         {
       
  2060         CAknControl::MakeVisible( aVisible );
       
  2061         if ( iExtension->iFeedback )
       
  2062             {
       
  2063             if ( aVisible )
       
  2064                 {
       
  2065                 iExtension->iFeedback->MoveFeedbackAreaToFirstPriority( this, 
       
  2066                                                                         0 );
       
  2067                 }
       
  2068             iExtension->iFeedback->EnableFeedbackForControl( 
       
  2069                     this, 
       
  2070                     aVisible && !IsDimmed() );
       
  2071             }
       
  2072 
       
  2073         CAknButtonState* state = State();
       
  2074         if ( !aVisible && state && state->HasHelp() )
       
  2075             {
       
  2076             HideHelp();
       
  2077             }
       
  2078         }
       
  2079     }
       
  2080 
       
  2081 // -----------------------------------------------------------------------------
       
  2082 // CAknButton::PrepareForFocusLossL
       
  2083 // This function is called by the dialog framework immediately before it removes
       
  2084 // keyboard focus from a control within a dialog.
       
  2085 // Currently has empty implementation.
       
  2086 // -----------------------------------------------------------------------------
       
  2087 //
       
  2088 EXPORT_C void CAknButton::PrepareForFocusLossL()
       
  2089     {
       
  2090     CAknControl::PrepareForFocusLossL(); // empty but it can be changed... :)
       
  2091     }
       
  2092 
       
  2093 // -----------------------------------------------------------------------------
       
  2094 // CAknButton::PrepareForFocusGainL
       
  2095 // Prepares the control for gaining focus.
       
  2096 // Must be used before calling SetFocus() function in case when help note
       
  2097 // should be shown.
       
  2098 // -----------------------------------------------------------------------------
       
  2099 //
       
  2100 EXPORT_C void CAknButton::PrepareForFocusGainL()
       
  2101     {
       
  2102     CAknControl::PrepareForFocusGainL(); // empty but it can be changed... :)
       
  2103 
       
  2104     CAknButtonState* state = State();
       
  2105     if ( state && state->HasHelp() && IsVisible() && !IsFocused() )
       
  2106         {
       
  2107         iShowHelp = ETrue;
       
  2108         }
       
  2109     else
       
  2110         {
       
  2111         iShowHelp = EFalse;
       
  2112         }
       
  2113     }
       
  2114 
       
  2115 // -----------------------------------------------------------------------------
       
  2116 // CAknButton::SizeChanged
       
  2117 // Responds to size changes to sets the size and position of the contents of
       
  2118 // this control.
       
  2119 // -----------------------------------------------------------------------------
       
  2120 //
       
  2121 EXPORT_C void CAknButton::SizeChanged()
       
  2122     {
       
  2123     // If default icon size from LAF is used re-request that, otherwise trust
       
  2124     // that size will be updated by the utilising application.
       
  2125     if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultIconSize ) )
       
  2126         {
       
  2127         if ( iFlags & KAknButtonNoFrame && !State()->HasText() )
       
  2128             {
       
  2129             iExtension->iIconSize = Size();
       
  2130             }
       
  2131         else
       
  2132             {
       
  2133             TAknLayoutRect layoutRect;
       
  2134             layoutRect.LayoutRect( Rect(), 
       
  2135                 AknLayoutScalable_Avkon::toolbar_button_pane_g10().LayoutLine() );
       
  2136             iExtension->iIconSize = layoutRect.Rect().Size();
       
  2137             }
       
  2138         }
       
  2139 
       
  2140     // Update margins from LAF if default values are used. This also refreshes
       
  2141     // icon size in case it overlaps margins.
       
  2142     CalculateDefaultMargins();
       
  2143         
       
  2144     // scale all icons
       
  2145     ScaleIcons();
       
  2146 
       
  2147     // Pressed down frame has to be regenerated
       
  2148     if ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame ) 
       
  2149        {
       
  2150         TRAP_IGNORE( CreatePressedDownFrameL() );
       
  2151         }
       
  2152 
       
  2153     iExtension->HandleFeedbackAreaChange();
       
  2154     }
       
  2155 
       
  2156 // -----------------------------------------------------------------------------
       
  2157 // CAknButton::HandlePointerEventL
       
  2158 // Handles pointer events.
       
  2159 // @param aPointerEvent is the pointer event.
       
  2160 // -----------------------------------------------------------------------------
       
  2161 //
       
  2162 EXPORT_C void CAknButton::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
  2163     {
       
  2164     if ( AknLayoutUtils::PenEnabled() )
       
  2165         {
       
  2166         if ( !IsVisible() )
       
  2167             {
       
  2168             if ( iButtonPressed )
       
  2169                 {
       
  2170                 ResetState();               
       
  2171                 }
       
  2172             return;
       
  2173             }
       
  2174         TBool buttonEvent( TouchArea().Contains( aPointerEvent.iPosition ) );
       
  2175         CAknButtonState* state = State();
       
  2176         if ( !state )
       
  2177             {
       
  2178             return;
       
  2179             }            
       
  2180         
       
  2181         if ( ( iFlags & KAknButtonHitTest ) && 
       
  2182              !HitAreaContainsL( aPointerEvent.iPosition, EFalse ) )
       
  2183             {
       
  2184             buttonEvent = EFalse;
       
  2185             }
       
  2186         
       
  2187         TBool redrawNeeded(EFalse);
       
  2188         switch ( aPointerEvent.iType )
       
  2189             {
       
  2190             case TPointerEvent::EButton1Down:
       
  2191                 {
       
  2192                 if ( buttonEvent && IsDimmed() )
       
  2193                     {
       
  2194                     ShowHelpL();
       
  2195                     }
       
  2196                 else if ( buttonEvent )
       
  2197                     {
       
  2198                     if ( !iButtonPressed )
       
  2199                         {
       
  2200                         iButtonPressed = ETrue;
       
  2201                         // feedback/basic on down event, if hit test is
       
  2202                         // used. Area registry is used for rectangular
       
  2203                         // buttons
       
  2204                         if ( ( iFlags & KAknButtonHitTest ) 
       
  2205                            && !IsDimmed() 
       
  2206                            && iExtension->iFeedback )
       
  2207                             {
       
  2208                             iExtension->iFeedback->InstantFeedback(
       
  2209                                                     this,
       
  2210                                                     ETouchFeedbackBasicButton,
       
  2211                                                     aPointerEvent );
       
  2212                             }
       
  2213 
       
  2214                         // make a mark so that we can later test that the button press comes from pointer event
       
  2215                         iButtonPressed |= KPointerFlag;
       
  2216 
       
  2217                         // Redraw button, if needed
       
  2218                         if ( NeedsRedrawWhenPressed() )
       
  2219                             {
       
  2220                             redrawNeeded = ETrue;
       
  2221                             }
       
  2222 
       
  2223                         ShowHelpL();
       
  2224                         }
       
  2225 
       
  2226                     if ( iFlags & KAknButtonReportOnKeyDown )
       
  2227                         {
       
  2228                         // State is changed on button down event
       
  2229                         ChangeState( EFalse );
       
  2230                         redrawNeeded = EFalse;
       
  2231                         DrawNow();  //Redraw before noticing the observer for observer might open dialog                        
       
  2232                         if ( Observer() )
       
  2233                             {
       
  2234                             Observer()->HandleControlEventL( this,
       
  2235                                 MCoeControlObserver::EEventStateChanged );
       
  2236                             }
       
  2237                         }
       
  2238 
       
  2239                     if ( iFlags & KAknButtonKeyRepeat )
       
  2240                         {
       
  2241                         // Key repeat
       
  2242                         iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
       
  2243                         StartKeyRepeatTimerL();
       
  2244                         }
       
  2245 
       
  2246                     if ( iFlags & KAknButtonReportOnLongPress )
       
  2247                         {
       
  2248                         iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
       
  2249                         iExtension->StartLongPressTimerL();
       
  2250                         }
       
  2251                     }
       
  2252                 break;
       
  2253                 }
       
  2254 
       
  2255             case TPointerEvent::EDrag:
       
  2256                 {
       
  2257                 iNumberOfDragEvents++;
       
  2258                 if ( iNumberOfDragEvents >= KDragEventSensitivity  )
       
  2259                     {
       
  2260                     iNumberOfDragEvents = 0;
       
  2261 
       
  2262                     // Pointer is dragged out of the button area
       
  2263                     if ( !buttonEvent && iButtonPressed )
       
  2264                         {
       
  2265                         // Redraw button, if needed
       
  2266                         if ( NeedsRedrawWhenPressed() )
       
  2267                             {
       
  2268                             iButtonPressed = EFalse;
       
  2269                             redrawNeeded = ETrue;
       
  2270                             }
       
  2271                         iButtonPressed = EFalse;
       
  2272 
       
  2273                         StopKeyRepeatTimer();
       
  2274                         StopLongPressTimer();
       
  2275 
       
  2276                         if ( !IsFocused() )
       
  2277                             {
       
  2278                             HideHelp();
       
  2279                             }
       
  2280                         if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() )
       
  2281                             {
       
  2282                             Observer()->HandleControlEventL( this, 
       
  2283                                 static_cast<MCoeControlObserver::TCoeEvent>( 
       
  2284                                 CAknButton::ELongPressEndedEvent ) );
       
  2285                             }
       
  2286                         iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
       
  2287                         }
       
  2288 
       
  2289                     // Pointer is dragged back into button area
       
  2290                     else if ( buttonEvent && !iButtonPressed && !IsDimmed() )
       
  2291                         {
       
  2292                         iButtonPressed = ETrue;
       
  2293 
       
  2294                         // Redraw button, if needed
       
  2295                         if ( NeedsRedrawWhenPressed() )
       
  2296                             {
       
  2297                             redrawNeeded = ETrue;
       
  2298                             }
       
  2299 
       
  2300                         if ( iFlags & KAknButtonKeyRepeat )
       
  2301                             {
       
  2302                             // Continue key repeat
       
  2303                             StartKeyRepeatTimerL();
       
  2304                             }
       
  2305 
       
  2306                         if ( ( iFlags & KAknButtonReportOnLongPress ) &&
       
  2307                              !( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) )
       
  2308                             {
       
  2309                             // Restart long press timer
       
  2310                             StartLongPressTimerL();
       
  2311                             }
       
  2312                         }
       
  2313                     }
       
  2314                 break;
       
  2315                 }
       
  2316 
       
  2317             case TPointerEvent::EButton1Up:
       
  2318                 {
       
  2319                 iNumberOfDragEvents = 0;
       
  2320                 HideHelp();
       
  2321 
       
  2322                 StopKeyRepeatTimer();
       
  2323                 StopLongPressTimer();
       
  2324 
       
  2325                 if ( iButtonPressed )
       
  2326                     {
       
  2327                     // Redraw button, if needed
       
  2328                     if ( NeedsRedrawWhenPressed() )
       
  2329                         {
       
  2330                         iButtonPressed = EFalse;
       
  2331                         if ( ! ( buttonEvent && iStates->Count() > 1 ) ) 
       
  2332                             {
       
  2333                             redrawNeeded = ETrue;
       
  2334                             }
       
  2335                         }
       
  2336                     iButtonPressed = EFalse;
       
  2337                     }
       
  2338 
       
  2339                 TBool hasDrawn( EFalse );
       
  2340                 if ( buttonEvent && !IsDimmed() )
       
  2341                     {
       
  2342                         // feedback/BasicButton on up event, if hit test is
       
  2343                         // used. Area registry is used for rectangular
       
  2344                         // buttons
       
  2345                         if ( ( iFlags & KAknButtonHitTest ) 
       
  2346                            && iExtension->iFeedback )
       
  2347                             {
       
  2348                             iExtension->iFeedback->InstantFeedback(
       
  2349                                                     this,
       
  2350                                                     ETouchFeedbackBasicButton,
       
  2351                                                     ETouchFeedbackVibra,
       
  2352                                                     aPointerEvent );
       
  2353                             }
       
  2354                     // The state is not changed, if it is already changed on key
       
  2355                     // down event, or if a long press or a key repeat event is
       
  2356                     // already reported to the observer.
       
  2357                     if ( !( iFlags & KAknButtonReportOnKeyDown ) &&
       
  2358                          !( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) &&
       
  2359                          !( iExtension->iFlags.IsSet( CAknButtonExtension::EKeyRepeatEventReported ) ) )
       
  2360                         {
       
  2361                         ChangeState( EFalse );
       
  2362                         if ( !hasDrawn )
       
  2363                         	{
       
  2364 	                        DrawNow();
       
  2365 	                        hasDrawn = ETrue;
       
  2366                         	}
       
  2367                         
       
  2368                         if ( Observer() )
       
  2369                             {
       
  2370                             Observer()->HandleControlEventL( this,
       
  2371                                 MCoeControlObserver::EEventStateChanged );
       
  2372                             }
       
  2373                         }
       
  2374                    else
       
  2375                         {
       
  2376                         if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() )
       
  2377                             {
       
  2378                             if ( redrawNeeded && !hasDrawn )
       
  2379                             	{
       
  2380                             	DrawNow();
       
  2381                             	hasDrawn = ETrue;
       
  2382                             	}
       
  2383                             Observer()->HandleControlEventL( this, 
       
  2384                                 static_cast<MCoeControlObserver::TCoeEvent>( 
       
  2385                                 CAknButton::ELongPressEndedEvent ) );
       
  2386                             }
       
  2387                         iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
       
  2388                         iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
       
  2389                         }
       
  2390 
       
  2391                     if ( RequestExit() && Observer() )
       
  2392                         {
       
  2393                         if ( redrawNeeded && !hasDrawn )
       
  2394                         	{
       
  2395                         	DrawNow();
       
  2396                         	hasDrawn = ETrue;
       
  2397                         	}
       
  2398                         Observer()->HandleControlEventL( this,
       
  2399                             MCoeControlObserver::EEventRequestExit );
       
  2400                         }
       
  2401                     }
       
  2402                         
       
  2403                 if ( !buttonEvent && !IsDimmed() && Observer() )
       
  2404                    {
       
  2405                    if ( redrawNeeded && !hasDrawn )
       
  2406                 	   {
       
  2407                 	   DrawNow();
       
  2408                 	   hasDrawn = ETrue;
       
  2409                 	   }
       
  2410                    Observer()->HandleControlEventL( this,
       
  2411                         MCoeControlObserver::EEventRequestCancel );
       
  2412                         
       
  2413                     if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) )
       
  2414                         {
       
  2415                         Observer()->HandleControlEventL( this, 
       
  2416                             static_cast<MCoeControlObserver::TCoeEvent>( 
       
  2417                             CAknButton::ELongPressEndedEvent ) );
       
  2418                         iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
       
  2419                         iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
       
  2420                         }                        
       
  2421                    }
       
  2422                 if ( hasDrawn )
       
  2423                 	{
       
  2424                 	redrawNeeded = EFalse;
       
  2425                 	}
       
  2426                 break;
       
  2427                 }
       
  2428 
       
  2429             default:
       
  2430                 break;
       
  2431             }
       
  2432             if (redrawNeeded)    
       
  2433                 {
       
  2434                 DrawNow();
       
  2435                 }
       
  2436         }
       
  2437     }
       
  2438 
       
  2439 // -----------------------------------------------------------------------------
       
  2440 // CAknButton::PositionChanged
       
  2441 // 
       
  2442 // -----------------------------------------------------------------------------
       
  2443 //
       
  2444 EXPORT_C void CAknButton::PositionChanged()
       
  2445     {
       
  2446     if ( iExtension ) iExtension->HandleFeedbackAreaChange();
       
  2447     CAknControl::PositionChanged();
       
  2448     }
       
  2449     
       
  2450 // -----------------------------------------------------------------------------
       
  2451 // CAknButton::FocusChanged
       
  2452 // This function is called whenever a control gains or loses focus.
       
  2453 // -----------------------------------------------------------------------------
       
  2454 //
       
  2455 EXPORT_C void CAknButton::FocusChanged( TDrawNow aDrawNow )
       
  2456     {
       
  2457     if ( !IsFocused() && iButtonPressed )
       
  2458         {
       
  2459         iButtonPressed = EFalse; 
       
  2460         iKeyDownReported = EFalse; 
       
  2461         }
       
  2462     if ( IsVisible() )
       
  2463         {
       
  2464         
       
  2465         if ( IsFocused() && iShowHelp )
       
  2466             {
       
  2467             TRAP_IGNORE( ShowHelpL() );
       
  2468             }
       
  2469         else
       
  2470             {
       
  2471             HideHelp();
       
  2472 
       
  2473             // Stop the timers if active
       
  2474             StopLongPressTimer();
       
  2475             StopKeyRepeatTimer();
       
  2476             }
       
  2477         if ( !IsBackedUp() && aDrawNow ) 
       
  2478             {
       
  2479             DrawNow();
       
  2480             }
       
  2481         }
       
  2482 
       
  2483     iShowHelp = EFalse;
       
  2484     }
       
  2485 
       
  2486 // -----------------------------------------------------------------------------
       
  2487 // CAknButton::ExtensionInterface
       
  2488 // For future extensions
       
  2489 // -----------------------------------------------------------------------------
       
  2490 //
       
  2491 EXPORT_C void* CAknButton::ExtensionInterface( TUid /*aInterface*/ )
       
  2492     {
       
  2493     return NULL;
       
  2494     }
       
  2495 
       
  2496 // -----------------------------------------------------------------------------
       
  2497 // CAknButton::Draw
       
  2498 // Draw a control called by window server.
       
  2499 // -----------------------------------------------------------------------------
       
  2500 //
       
  2501 EXPORT_C void CAknButton::Draw( const TRect& /*aRect*/ ) const
       
  2502     {
       
  2503     TRect rect( Rect() );
       
  2504     TAknLayoutRect centerLayout;
       
  2505     centerLayout.LayoutRect( rect,
       
  2506         AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
       
  2507     TRect innerRect( centerLayout.Rect() );
       
  2508     TRect highlightRect( HighlightRect() );
       
  2509     CWindowGc& gc = SystemGc();
       
  2510     CAknButtonState* state = State();
       
  2511 
       
  2512     // Skin ids are determined here (a bit too early than necessary) so that 
       
  2513     // we can avoid doing the same thing in DrawMaskedL.
       
  2514     if ( !( iFlags & KAknButtonNoFrame ) )
       
  2515         {
       
  2516         TInt frameIdIndex = KFrameId;
       
  2517 
       
  2518         if ( iButtonPressed )
       
  2519             {
       
  2520             frameIdIndex = KPressedFrameId;
       
  2521             }
       
  2522         else if ( state && state->Flags() & KAknButtonStateHasLatchedFrame )
       
  2523             {
       
  2524             if ( IsDimmed() )
       
  2525                 {
       
  2526                 // dimmed latched frame
       
  2527                 frameIdIndex = KLatchedDimmedFrameId;
       
  2528                 }
       
  2529             else
       
  2530                 {
       
  2531                 // latched down
       
  2532                 frameIdIndex = KLatchedFrameId;
       
  2533                 }
       
  2534             }
       
  2535         else if ( IsDimmed())
       
  2536             {
       
  2537             // dimmed frame
       
  2538             frameIdIndex = KDimmedFrameId;
       
  2539             }
       
  2540 
       
  2541         if ( SkinIID( frameIdIndex ) != KAknsIIDNone )
       
  2542             {
       
  2543             iBgContext->SetFrame( SkinIID( frameIdIndex ) );
       
  2544             iBgContext->SetCenter( SkinIID( ++frameIdIndex ) );
       
  2545             iBgContext->SetFrameRects( rect, innerRect );
       
  2546             }
       
  2547         }
       
  2548 
       
  2549     if ( !iExtension->iFlags.IsSet( CAknButtonExtension::EUseAdditionalMask ) )
       
  2550         {
       
  2551         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  2552         MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
       
  2553 
       
  2554         if ( !( iFlags & KAknButtonNoFrame ) )
       
  2555             {
       
  2556             // frame graphics
       
  2557             if ( !AknsDrawUtils::Background( skin, iBgContext, NULL, gc,
       
  2558                   rect, KAknsDrawParamNoClearUnderImage ) )
       
  2559                 {
       
  2560                 gc.SetBrushColor( KRgbRed );
       
  2561                 gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
  2562                 gc.DrawRect( rect );
       
  2563                 }
       
  2564                 
       
  2565 
       
  2566             if ( IsFocused() && !highlightRect.IsEmpty() )
       
  2567                 {
       
  2568                 iBgContext->SetFrame( KAknsIIDQsnFrButtonHighlight ); 
       
  2569                 iBgContext->SetCenter( KAknsIIDQsnFrButtonHighlightCenter ); 
       
  2570                 iBgContext->SetFrameRects( rect, innerRect );
       
  2571 
       
  2572                 // frame graphics
       
  2573                 if ( !AknsDrawUtils::Background( skin, iBgContext, NULL, gc,
       
  2574                       rect, KAknsDrawParamNoClearUnderImage ) )
       
  2575                     {
       
  2576                     gc.SetBrushColor( KRgbRed );
       
  2577                     gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
       
  2578                     gc.DrawRect( rect );
       
  2579                     }
       
  2580                 }
       
  2581             }
       
  2582         else if ( ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame ) &&
       
  2583                     ( iButtonPressed ||
       
  2584                     ( state && state->Flags() & KAknButtonStateHasLatchedFrame &&
       
  2585                     !IsDimmed() ) ) )
       
  2586             {
       
  2587             gc.BitBltMasked( Rect().iTl, iExtension->iPressedDownBmp, 
       
  2588                              TRect( TPoint(0,0), Size() ), 
       
  2589                              iExtension->iPressedDownBmpMask, EFalse ); 
       
  2590             }
       
  2591         }
       
  2592     else if ( !( iFlags & KAknButtonNoFrame ) )
       
  2593         {
       
  2594         if ( AknsUtils::SkinInstance() )
       
  2595             {
       
  2596             AknsDrawUtils::Background( AknsUtils::SkinInstance(), iBgContext, this, gc,
       
  2597                    rect, KAknsDrawParamNoClearUnderImage );
       
  2598             }
       
  2599         }
       
  2600 
       
  2601     TBool hasIcon = ( GetCurrentIcon() != NULL );
       
  2602     TBool hasText = state && state->HasText();
       
  2603 
       
  2604     if ( hasIcon && hasText )
       
  2605         {
       
  2606         DrawTextAndIconButton( gc );
       
  2607         }
       
  2608     else if ( hasText )
       
  2609         {
       
  2610         DrawTextButton( gc );
       
  2611         }
       
  2612     else if ( hasIcon )
       
  2613         {
       
  2614         DrawIconButton( gc );
       
  2615         }
       
  2616     }
       
  2617 
       
  2618 // -----------------------------------------------------------------------------
       
  2619 // CAknButton::ConstructFromResourceL
       
  2620 // Constructs controls from a resource file.
       
  2621 // @param aResourceId is the ID for this component's resource
       
  2622 // -----------------------------------------------------------------------------
       
  2623 //
       
  2624 EXPORT_C void CAknButton::ConstructFromResourceL( const TInt aResourceId )
       
  2625     {
       
  2626     if ( aResourceId )
       
  2627         {
       
  2628         TResourceReader reader;
       
  2629         iCoeEnv->CreateResourceReaderLC( reader, aResourceId );
       
  2630         ConstructFromResourceL( reader );
       
  2631         CleanupStack::PopAndDestroy();
       
  2632         }
       
  2633     }
       
  2634 
       
  2635 // -----------------------------------------------------------------------------
       
  2636 // CAknButton::SetCurrentState
       
  2637 // Sets active button state index
       
  2638 // @param aStateIndex is the index inside state array
       
  2639 // @param aDrawNow should be ETrue for the button to be redrawn
       
  2640 // -----------------------------------------------------------------------------
       
  2641 //
       
  2642 EXPORT_C void CAknButton::SetCurrentState( const TInt aStateIndex,
       
  2643                                            const TBool aDrawNow )
       
  2644     {
       
  2645     TInt newIndex = -1;
       
  2646     if ( iStates && iStates->Count() )
       
  2647         {
       
  2648         newIndex = aStateIndex % iStates->Count();
       
  2649         }
       
  2650 
       
  2651     TRAP_IGNORE( SetStateIndexL( newIndex ) );
       
  2652     if ( aDrawNow )
       
  2653         {
       
  2654         DrawNow();
       
  2655         }
       
  2656     }
       
  2657 
       
  2658 // -----------------------------------------------------------------------------
       
  2659 // CAknButton::AddStateL
       
  2660 // Adds one more state for the button to the end of state array.
       
  2661 // -----------------------------------------------------------------------------
       
  2662 //
       
  2663 EXPORT_C void CAknButton::AddStateL( CGulIcon* aIcon,
       
  2664                                      CGulIcon* aDimmedIcon,
       
  2665                                      CGulIcon* aPressedIcon,
       
  2666                                      CGulIcon* aHoverIcon,
       
  2667                                      const TDesC& aText,
       
  2668                                      const TDesC& aHelpText,
       
  2669                                      const TInt aStateFlags )
       
  2670     {
       
  2671     CAknButtonState* state = new (ELeave) CAknButtonState( aStateFlags );
       
  2672     CleanupStack::PushL( state );
       
  2673     state->ConstructL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText,
       
  2674                        aHelpText );
       
  2675     iStates->AppendL( state );
       
  2676     CleanupStack::Pop( state );
       
  2677     }
       
  2678 
       
  2679 // -----------------------------------------------------------------------------
       
  2680 // CAknButton::AddStateL
       
  2681 // Adds one more state for the button to the end of state array.
       
  2682 // -----------------------------------------------------------------------------
       
  2683 //
       
  2684 EXPORT_C void CAknButton::AddStateL( const TDesC& aFilePath,
       
  2685                                      const TInt aBmpId,
       
  2686                                      const TInt aMaskId,
       
  2687                                      const TInt aDimmedBmpId,
       
  2688                                      const TInt aDimmedMaskId,
       
  2689                                      const TInt aPressedBmpId,
       
  2690                                      const TInt aPressedMaskId,
       
  2691                                      const TInt aHoverBmpId,
       
  2692                                      const TInt aHoverMaskId,
       
  2693                                      const TDesC& aText,
       
  2694                                      const TDesC& aHelpText,
       
  2695                                      const TInt aStateFlags,
       
  2696                                      const TAknsItemID& aId,
       
  2697                                      const TAknsItemID& aDimmedId,
       
  2698                                      const TAknsItemID& aPressedId,
       
  2699                                      const TAknsItemID& aHoverId )
       
  2700     {
       
  2701     CAknButtonState* state = new (ELeave) CAknButtonState( aStateFlags );
       
  2702     CleanupStack::PushL( state );
       
  2703     state->ConstructL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId,
       
  2704          aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId,
       
  2705          aText, aHelpText, aId, aDimmedId, aPressedId, aHoverId );
       
  2706     iStates->AppendL( state );
       
  2707     CleanupStack::Pop( state );
       
  2708     }
       
  2709 
       
  2710 
       
  2711 // -----------------------------------------------------------------------------
       
  2712 // CAknButton::AddStateL
       
  2713 // Adds one more state for the button to the end of state array.
       
  2714 // -----------------------------------------------------------------------------
       
  2715 //
       
  2716 void CAknButton::AddStateL( CGulIcon* aIcon,
       
  2717                             CGulIcon* aDimmedIcon,
       
  2718                             CGulIcon* aPressedIcon,
       
  2719                             CGulIcon* aHoverIcon,
       
  2720                             const TDesC& aText,
       
  2721                             const TDesC& aHelpText,
       
  2722                             const TInt aStateFlags,
       
  2723                             const TInt aCommandId )
       
  2724     {
       
  2725     CAknCommandButtonState* state =
       
  2726         new (ELeave) CAknCommandButtonState( aStateFlags, aCommandId );
       
  2727     CleanupStack::PushL( state );
       
  2728     state->ConstructL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText,
       
  2729                        aHelpText );
       
  2730     iStates->AppendL( state );
       
  2731     CleanupStack::Pop( state );
       
  2732     }
       
  2733 
       
  2734 
       
  2735 // -----------------------------------------------------------------------------
       
  2736 // CAknButton::SetFlags
       
  2737 // Sets the button flags
       
  2738 // -----------------------------------------------------------------------------
       
  2739 //
       
  2740 EXPORT_C void CAknButton::SetButtonFlags( const TInt aFlags )
       
  2741     {
       
  2742     if ( !(iFlags & KAknButtonNoFrame ) && aFlags & KAknButtonNoFrame )
       
  2743         {
       
  2744         iExtension->iMargins.SetAllValuesTo( 0 );
       
  2745         }
       
  2746     if ( aFlags & KAknButtonHitTest )
       
  2747         {
       
  2748         SetHitTest( iExtension );
       
  2749         iExtension->HandleFeedbackAreaChange();
       
  2750         }
       
  2751     if ( aFlags & KAknButtonNoFrame && aFlags & KAknButtonPressedDownFrame )
       
  2752         {
       
  2753         TRAP_IGNORE ( CreatePressedDownFrameL() );
       
  2754         }
       
  2755     iFlags = aFlags;
       
  2756     }
       
  2757 
       
  2758 // -----------------------------------------------------------------------------
       
  2759 // CAknButton::SetFrameAndCenterIds
       
  2760 // Sets specified frame IDs. Can be used when default frame is not suitable.
       
  2761 // Use KAknsIIDNone value in case when some frame or center drawing is not
       
  2762 // needed or KAknsIIDDefault when the default button frame should be used.
       
  2763 // -----------------------------------------------------------------------------
       
  2764 //
       
  2765 EXPORT_C void CAknButton::SetFrameAndCenterIds( 
       
  2766     const TAknsItemID& aFrameId,
       
  2767     const TAknsItemID& aCenterId,
       
  2768     const TAknsItemID& aLatchedFrameId,
       
  2769     const TAknsItemID& aLatchedCenterId,
       
  2770     const TAknsItemID& aDimmedFrameId,
       
  2771     const TAknsItemID& aDimmedCenterId,
       
  2772     const TAknsItemID& aPressedFrameId,
       
  2773     const TAknsItemID& aPressedCenterId,
       
  2774     const TAknsItemID& aLatchedDimmedFrameId,
       
  2775     const TAknsItemID& aLatchedDimmedCenterId  )
       
  2776     {
       
  2777     RArray<TAknsItemID>& skinIds = iExtension->iFrameAndCenterIds;
       
  2778     
       
  2779     if ( aFrameId != KAknsIIDDefault )
       
  2780         {
       
  2781         skinIds[KFrameId] = aFrameId;
       
  2782         }
       
  2783     if ( aCenterId != KAknsIIDDefault )
       
  2784         {
       
  2785         skinIds[KCenterId] = aCenterId;
       
  2786         }
       
  2787     if ( aLatchedFrameId != KAknsIIDDefault )
       
  2788         {
       
  2789         skinIds[KLatchedFrameId] = aLatchedFrameId;
       
  2790         }
       
  2791     if ( aLatchedCenterId != KAknsIIDDefault )
       
  2792         {
       
  2793         skinIds[KLatchedCenterId] = aLatchedCenterId;
       
  2794         }
       
  2795     if ( aDimmedFrameId != KAknsIIDDefault )
       
  2796         {
       
  2797         skinIds[KDimmedFrameId] = aDimmedFrameId;
       
  2798         }
       
  2799     if ( aDimmedCenterId != KAknsIIDDefault )
       
  2800         {
       
  2801         skinIds[KDimmedCenterId] = aDimmedCenterId;
       
  2802         }
       
  2803     if ( aPressedFrameId != KAknsIIDDefault )
       
  2804         {
       
  2805         skinIds[KPressedFrameId] = aPressedFrameId;
       
  2806         }
       
  2807     if ( aPressedCenterId != KAknsIIDDefault )
       
  2808         {
       
  2809         skinIds[KPressedCenterId] = aPressedCenterId;
       
  2810         }
       
  2811     if ( aLatchedDimmedFrameId != KAknsIIDDefault )
       
  2812         {
       
  2813         skinIds[KLatchedDimmedFrameId] = aLatchedDimmedFrameId;
       
  2814         }
       
  2815     if ( aLatchedDimmedCenterId != KAknsIIDDefault )
       
  2816         {
       
  2817         skinIds[KLatchedDimmedCenterId] = aLatchedDimmedCenterId;
       
  2818         }
       
  2819     }
       
  2820 
       
  2821 // -----------------------------------------------------------------------------
       
  2822 // CAknButton::SetBackgroundIds
       
  2823 // -----------------------------------------------------------------------------
       
  2824 //
       
  2825 EXPORT_C void CAknButton::SetBackgroundIds( 
       
  2826     const TAknsItemID& aBackgroundId,
       
  2827     const TAknsItemID& aLatchedBackgroundId,
       
  2828     const TAknsItemID& aDimmedBackgroundId,
       
  2829     const TAknsItemID& aPressedBackgroundId,
       
  2830     const TAknsItemID& aLatchedDimmedBackgroundId )
       
  2831     {
       
  2832     CAknButton::SetFrameAndCenterIds( aBackgroundId, aBackgroundId,
       
  2833                                       aLatchedBackgroundId, 
       
  2834                                       aLatchedBackgroundId,
       
  2835                                       aDimmedBackgroundId, aDimmedBackgroundId,
       
  2836                                       aPressedBackgroundId, 
       
  2837                                       aPressedBackgroundId,
       
  2838                                       aLatchedDimmedBackgroundId, 
       
  2839                                       aLatchedDimmedBackgroundId );
       
  2840     }
       
  2841 
       
  2842 // -----------------------------------------------------------------------------
       
  2843 // CAknButton::SetTextFont
       
  2844 // Sets some specific text font.
       
  2845 // -----------------------------------------------------------------------------
       
  2846 //
       
  2847 EXPORT_C void CAknButton::SetTextFont( const CFont* aFont )
       
  2848     {
       
  2849     iFont = aFont;
       
  2850     }
       
  2851 
       
  2852 // -----------------------------------------------------------------------------
       
  2853 // CAknButton::SetTextColorIds
       
  2854 // Sets the color table and color index for the button text.
       
  2855 // It will be used on button drawing if color of the text shouldn't be taken
       
  2856 // from text layout.
       
  2857 // -----------------------------------------------------------------------------
       
  2858 //
       
  2859 EXPORT_C void CAknButton::SetTextColorIds( const TAknsItemID& aTextColorTableId,
       
  2860                                            const TInt aTextColorIndex )
       
  2861     {
       
  2862     iTextColorTableId = aTextColorTableId;
       
  2863     iTextColorIndex = aTextColorIndex;
       
  2864 
       
  2865     TRgb textColor;
       
  2866     
       
  2867     if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor, 
       
  2868         iTextColorTableId, iTextColorIndex ) == KErrNone )
       
  2869         {
       
  2870         TRAP_IGNORE( OverrideColorL( EColorButtonText, textColor ) );
       
  2871         DrawDeferred();
       
  2872         }
       
  2873     }
       
  2874 
       
  2875 // -----------------------------------------------------------------------------
       
  2876 // CAknButton::SetTextHorizontalAlignment
       
  2877 // Sets the horizontal alignment for the text inside the button. It will be used
       
  2878 // if alignment shouldn't be taken from text layout. By default it will be
       
  2879 // centered.
       
  2880 // -----------------------------------------------------------------------------
       
  2881 //
       
  2882 EXPORT_C void CAknButton::SetTextHorizontalAlignment(
       
  2883     const CGraphicsContext::TTextAlign aHorizontalAlignment )
       
  2884     {
       
  2885     iHorizontalAlignment = aHorizontalAlignment;
       
  2886     }
       
  2887 
       
  2888 // -----------------------------------------------------------------------------
       
  2889 // CAknButton::SetTextVerticalAlignment
       
  2890 // Sets the vertical alignment for the text inside the button. It will be used
       
  2891 // if alignment shouldn't be taken from text layout. By default it will be
       
  2892 // centered.
       
  2893 // -----------------------------------------------------------------------------
       
  2894 //
       
  2895 EXPORT_C void CAknButton::SetTextVerticalAlignment(
       
  2896     const CAknButton::TAlignment aVerticalAlignment )
       
  2897     {
       
  2898     iVerticalAlignment = aVerticalAlignment;
       
  2899     }
       
  2900 
       
  2901 // -----------------------------------------------------------------------------
       
  2902 // CAknButton::SetTextUnderlineStyle
       
  2903 // Sets the text underline style for the text inside the button.
       
  2904 // -----------------------------------------------------------------------------
       
  2905 //
       
  2906 EXPORT_C void CAknButton::SetTextUnderlineStyle( TFontUnderline aUnderlineStyle )
       
  2907     {
       
  2908     iExtension->iUnderlineStyle = aUnderlineStyle;
       
  2909     }
       
  2910 
       
  2911 // -----------------------------------------------------------------------------
       
  2912 // CAknButton::SetIconScaleMode
       
  2913 // Sets the scale mode for the icon inside the button. The default is
       
  2914 // EAspectRatioNotPreserved.
       
  2915 // -----------------------------------------------------------------------------
       
  2916 //
       
  2917 EXPORT_C void CAknButton::SetIconScaleMode( const TScaleMode aScaleMode )
       
  2918     {
       
  2919     iScaleMode = aScaleMode;
       
  2920     
       
  2921     for ( TInt i = 0; i < iStates->Count(); ++i )
       
  2922         {
       
  2923         CAknButtonState* state = iStates->At( i );
       
  2924         
       
  2925         if ( state )
       
  2926             {
       
  2927             state->SetIconScaleMode( aScaleMode );
       
  2928             }
       
  2929         }
       
  2930     }
       
  2931     
       
  2932 // -----------------------------------------------------------------------------
       
  2933 // CAknButton::SetIconHorizontalAlignment
       
  2934 // Sets the horizontal alignment for the icon inside the button.
       
  2935 // The default is ECenter
       
  2936 // -----------------------------------------------------------------------------
       
  2937 //
       
  2938 EXPORT_C void CAknButton::SetIconHorizontalAlignment( 
       
  2939             const CAknButton::TAlignment aHorizontalAlignment )
       
  2940     {
       
  2941     iExtension->iHorizontalIconAlignment = aHorizontalAlignment;
       
  2942     }
       
  2943 // -----------------------------------------------------------------------------
       
  2944 // CAknButton::SetIconVerticalAlignment
       
  2945 // Sets the vertical alignment for the icon inside the button.
       
  2946 // The default is ECenter
       
  2947 // -----------------------------------------------------------------------------
       
  2948 //
       
  2949 EXPORT_C void CAknButton::SetIconVerticalAlignment( 
       
  2950             const CAknButton::TAlignment aVerticalAlignment )
       
  2951     {
       
  2952     iExtension->iVerticalIconAlignment = aVerticalAlignment;
       
  2953     }
       
  2954 
       
  2955 // -----------------------------------------------------------------------------
       
  2956 // CAknButton::SetTextAndIconAlignment
       
  2957 // Sets the icon and text alignment for the button having both
       
  2958 // The default is EIconBeforeText
       
  2959 // -----------------------------------------------------------------------------
       
  2960 //
       
  2961 EXPORT_C void CAknButton::SetTextAndIconAlignment ( 
       
  2962             const CAknButton::TTextAndIconAlignment aAlignment )
       
  2963     {
       
  2964     iExtension->iTextAndIconAlignment = aAlignment;
       
  2965     }
       
  2966 
       
  2967 // -----------------------------------------------------------------------------
       
  2968 // CAknButton::SetHelpNoteTimeouts
       
  2969 // Sets the delay before the help text is shown and also specifies the time for
       
  2970 // how long help text is visible.
       
  2971 // -----------------------------------------------------------------------------
       
  2972 //
       
  2973 EXPORT_C void CAknButton::SetHelpNoteTimeouts( const TInt aBeforeTimeout,
       
  2974                                                const TInt aInViewTimeout )
       
  2975     {
       
  2976     if ( aBeforeTimeout >= 0 )
       
  2977         {
       
  2978         iHelpNoteWaitInterval = aBeforeTimeout;
       
  2979         }
       
  2980     if ( aInViewTimeout >= 0 )
       
  2981         {
       
  2982         iHelpNoteInViewInterval = aInViewTimeout;
       
  2983         }
       
  2984 
       
  2985     if(iHelpNote)
       
  2986         {
       
  2987         iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval );
       
  2988         iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval );
       
  2989         }
       
  2990     }
       
  2991 
       
  2992 // -----------------------------------------------------------------------------
       
  2993 // CAknButton::SetKeyRepeatInterval
       
  2994 // Sets the interval for the key repeat.
       
  2995 // -----------------------------------------------------------------------------
       
  2996 //
       
  2997 EXPORT_C void CAknButton::SetKeyRepeatInterval( const TInt aKeyRepeatDelay,
       
  2998         const TInt aKeyRepeatInterval )
       
  2999     {
       
  3000     // Convert time intervals to microseconds
       
  3001     iKeyRepeatDelay = aKeyRepeatDelay * 1000;
       
  3002     iKeyRepeatInterval = aKeyRepeatInterval * 1000;
       
  3003     }
       
  3004 
       
  3005 // -----------------------------------------------------------------------------
       
  3006 // CAknButton::SetLongPressInterval
       
  3007 // Sets the interval for the long presses.
       
  3008 // -----------------------------------------------------------------------------
       
  3009 //
       
  3010 EXPORT_C void CAknButton::SetLongPressInterval( const TInt aLongPressInterval )
       
  3011     {
       
  3012     iExtension->iLongPressInterval = aLongPressInterval * 1000;
       
  3013     }
       
  3014 
       
  3015 // -----------------------------------------------------------------------------
       
  3016 // CAknButton::StateIndex
       
  3017 // Returns the index of the current button state.
       
  3018 // -----------------------------------------------------------------------------
       
  3019 //
       
  3020 EXPORT_C TInt CAknButton::StateIndex() const
       
  3021     {
       
  3022     return iStateIndex;
       
  3023     }
       
  3024 
       
  3025 // -----------------------------------------------------------------------------
       
  3026 // CAknButton::EnablePictographsL
       
  3027 // Enables pictograph drawing in the button text.
       
  3028 // Only effective in Japanese variant.
       
  3029 // By default, it is disabled.
       
  3030 // -----------------------------------------------------------------------------
       
  3031 //
       
  3032 EXPORT_C void CAknButton::EnablePictographsL( CAknPictographInterface& aInterface )
       
  3033     {
       
  3034     iExtension->iPictographInterface = &aInterface;
       
  3035     }
       
  3036 
       
  3037 // -----------------------------------------------------------------------------
       
  3038 // CAknButton::DisablePictographs
       
  3039 // Disables pictograph drawing in the button text.
       
  3040 // Only effective in Japanese variant.
       
  3041 // By default, it is disabled.
       
  3042 // -----------------------------------------------------------------------------
       
  3043 //
       
  3044 EXPORT_C void CAknButton::DisablePictographs()
       
  3045     {
       
  3046     iExtension->iPictographInterface = NULL;
       
  3047     }
       
  3048 
       
  3049 // -----------------------------------------------------------------------------
       
  3050 // CAknButton::SetHighlightRect
       
  3051 // It will change the default highlight rectangular around
       
  3052 // the focused button
       
  3053 // -----------------------------------------------------------------------------
       
  3054 //
       
  3055 EXPORT_C void CAknButton::SetHighlightRect( const TRect& aRect )
       
  3056     {
       
  3057     iHighlightRect = aRect;
       
  3058     }
       
  3059 
       
  3060 // -----------------------------------------------------------------------------
       
  3061 // CAknButton::HighlightRect
       
  3062 // Returns highlight rectangular around button
       
  3063 // -----------------------------------------------------------------------------
       
  3064 //
       
  3065 EXPORT_C TRect CAknButton::HighlightRect() const
       
  3066     {
       
  3067     if ( IsNonFocusing() )
       
  3068         {
       
  3069         return TRect();
       
  3070         }
       
  3071     else
       
  3072         {
       
  3073         return iHighlightRect;
       
  3074         }
       
  3075     }
       
  3076 
       
  3077 // -----------------------------------------------------------------------------
       
  3078 // CAknButton::SetTooltipPosition
       
  3079 // -----------------------------------------------------------------------------
       
  3080 //
       
  3081 EXPORT_C void CAknButton::SetTooltipPosition( const TTooltipPosition aPosition )
       
  3082     {
       
  3083     iExtension->iTooltipPosition = aPosition;
       
  3084     }
       
  3085 
       
  3086 // -----------------------------------------------------------------------------
       
  3087 // CAknButton::RequestExit
       
  3088 // -----------------------------------------------------------------------------
       
  3089 //
       
  3090 EXPORT_C void CAknButton::SetRequestExit( const TBool aRequestExit )
       
  3091     {
       
  3092     if (aRequestExit)
       
  3093         {
       
  3094         iFlags |= KAknButtonRequestExitOnButtonUpEvent;
       
  3095         }
       
  3096     else
       
  3097         {
       
  3098         iFlags &= ~KAknButtonRequestExitOnButtonUpEvent;
       
  3099         }
       
  3100     }
       
  3101 
       
  3102 // -----------------------------------------------------------------------------
       
  3103 // CAknButton::IsDimmed
       
  3104 // -----------------------------------------------------------------------------
       
  3105 //
       
  3106 EXPORT_C TBool CAknButton::IsDimmed() const
       
  3107     {
       
  3108     return iExtension->iFlags.IsSet( CAknButtonExtension::EDimmed );
       
  3109     }
       
  3110 
       
  3111 // -----------------------------------------------------------------------------
       
  3112 // CAknButton::SetHelpTextL
       
  3113 // Sets the help text for dimmed button
       
  3114 // -----------------------------------------------------------------------------
       
  3115 //
       
  3116 EXPORT_C void CAknButton::SetDimmedHelpTextL( const TDesC& aHelpText )
       
  3117     {
       
  3118     delete iDimmedHelpText;
       
  3119     iDimmedHelpText = NULL;
       
  3120 
       
  3121     iDimmedHelpText = aHelpText.AllocL();
       
  3122     }
       
  3123 
       
  3124 // -----------------------------------------------------------------------------
       
  3125 // CAknButton::ChangeState
       
  3126 // Changes the state of the button
       
  3127 // -----------------------------------------------------------------------------
       
  3128 //
       
  3129 EXPORT_C TInt CAknButton::ChangeState( TBool aDrawNow )
       
  3130     {
       
  3131     if ( !iStates || !iStates->Count() )
       
  3132         {
       
  3133         return -1;
       
  3134         }
       
  3135 
       
  3136     TInt newIndex( iStateIndex + 1 );
       
  3137 
       
  3138     if ( iStateIndex == iStates->Count() - 1 )
       
  3139         {
       
  3140         newIndex = 0;
       
  3141         }
       
  3142     
       
  3143     TRAP_IGNORE( SetStateIndexL( newIndex ) );
       
  3144     
       
  3145     if ( aDrawNow )
       
  3146         {
       
  3147         DrawNow();
       
  3148         }
       
  3149 
       
  3150     return iStateIndex;
       
  3151     }
       
  3152 
       
  3153 // -----------------------------------------------------------------------------
       
  3154 // CAknButton::GetCurrentText
       
  3155 // Returns the texts which will be displayed inside the button for the current
       
  3156 // state.
       
  3157 // -----------------------------------------------------------------------------
       
  3158 //
       
  3159 EXPORT_C const TDesC& CAknButton::GetCurrentText() const
       
  3160     {
       
  3161     CAknButtonState* state = State();
       
  3162     if ( state )
       
  3163         {
       
  3164         return state->Text();
       
  3165         }
       
  3166     else
       
  3167         {
       
  3168         return KNullDesC();
       
  3169         }
       
  3170     }
       
  3171 
       
  3172 // -----------------------------------------------------------------------------
       
  3173 // CAknButton::GetCurrentIcon
       
  3174 // Returns the right icon for the current state
       
  3175 // -----------------------------------------------------------------------------
       
  3176 //
       
  3177 EXPORT_C const CGulIcon* CAknButton::GetCurrentIcon() const
       
  3178     {
       
  3179     CAknButtonState* state = State();
       
  3180     const CGulIcon* icon = NULL;
       
  3181     if ( state )
       
  3182         {
       
  3183         if ( iButtonPressed && state->PressedIcon() )
       
  3184             {
       
  3185             icon = state->PressedIcon();
       
  3186             }
       
  3187         else if ( IsDimmed() && state->DimmedIcon() )
       
  3188             {
       
  3189             icon = state->DimmedIcon();
       
  3190             }
       
  3191         else
       
  3192             {
       
  3193             icon = state->Icon();
       
  3194             }
       
  3195         }
       
  3196     return icon;
       
  3197     }
       
  3198 
       
  3199 // -----------------------------------------------------------------------------
       
  3200 // CAknButton::ShowHelpL
       
  3201 // Shows help text for a certain period of time.
       
  3202 // -----------------------------------------------------------------------------
       
  3203 //
       
  3204 EXPORT_C void CAknButton::ShowHelpL()
       
  3205     {
       
  3206     if ( !IsVisible() )
       
  3207         {
       
  3208         return;
       
  3209         }
       
  3210     if ( !iHelpNote )
       
  3211         {
       
  3212         iHelpNote = CAknInfoPopupNoteController::NewL();
       
  3213         
       
  3214         iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval );
       
  3215         iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval );
       
  3216         iHelpNote->SetTooltipModeL( ETrue );
       
  3217         }
       
  3218         
       
  3219     if ( IsDimmed() && iDimmedHelpText )
       
  3220         {
       
  3221         iHelpNote->SetTextL( *iDimmedHelpText );
       
  3222         }
       
  3223     else
       
  3224         {
       
  3225         CAknButtonState* state = State();
       
  3226         if ( state && state->HasHelp() )
       
  3227             {
       
  3228             iHelpNote->SetTextL( state->HelpText() );
       
  3229             }
       
  3230         else
       
  3231             {
       
  3232             return;
       
  3233             }
       
  3234         }
       
  3235 
       
  3236     UpdateTooltipPosition();
       
  3237     iHelpNote->ShowInfoPopupNote();
       
  3238     }
       
  3239 
       
  3240 // -----------------------------------------------------------------------------
       
  3241 // CAknButton::HideHelp
       
  3242 // Hides help text after certain interval.
       
  3243 // -----------------------------------------------------------------------------
       
  3244 //
       
  3245 EXPORT_C void CAknButton::HideHelp()
       
  3246     {
       
  3247     if(iHelpNote)
       
  3248         {
       
  3249         iHelpNote->HideInfoPopupNote();
       
  3250         }
       
  3251     }
       
  3252 
       
  3253 // -----------------------------------------------------------------------------
       
  3254 // CAknButton::State
       
  3255 // Returns current state.
       
  3256 // -----------------------------------------------------------------------------
       
  3257 //
       
  3258 EXPORT_C CAknButtonState* CAknButton::State() const
       
  3259     {
       
  3260     return State( iStateIndex );
       
  3261     }
       
  3262 
       
  3263 // -----------------------------------------------------------------------------
       
  3264 // CAknButton::State
       
  3265 // Returns the state under the specified index.
       
  3266 // -----------------------------------------------------------------------------
       
  3267 //
       
  3268 EXPORT_C CAknButtonState* CAknButton::State( const TInt aStateIndex ) const
       
  3269     {
       
  3270     CAknButtonState* state = NULL;
       
  3271     if ( iStates && aStateIndex >= 0 && aStateIndex < iStates->Count() )
       
  3272         {
       
  3273         state = iStates->At( aStateIndex );
       
  3274         }
       
  3275     return state;
       
  3276     }
       
  3277 
       
  3278 // -----------------------------------------------------------------------------
       
  3279 // CAknButton::Flags
       
  3280 // -----------------------------------------------------------------------------
       
  3281 //
       
  3282 EXPORT_C TInt CAknButton::ButtonFlags() const
       
  3283     {
       
  3284     return iFlags;
       
  3285     }
       
  3286 
       
  3287 // -----------------------------------------------------------------------------
       
  3288 // CAknButton::SetMargins
       
  3289 // Sets button's marginals.
       
  3290 // -----------------------------------------------------------------------------
       
  3291 //
       
  3292 EXPORT_C void CAknButton::SetMargins( const TMargins8& aMargins )
       
  3293     {
       
  3294     iExtension->iFlags.Clear( CAknButtonExtension::EUseDefaultMargins );
       
  3295     iExtension->iMargins = aMargins;
       
  3296     SizeChanged();
       
  3297     }
       
  3298     
       
  3299 // -----------------------------------------------------------------------------
       
  3300 // CAknButton::SetIconSize
       
  3301 // Sets button's icon size.
       
  3302 // -----------------------------------------------------------------------------
       
  3303 //
       
  3304 EXPORT_C TInt CAknButton::SetIconSize( const TSize& aSize )
       
  3305     {
       
  3306     iExtension->iFlags.Clear( CAknButtonExtension::EUseDefaultIconSize );
       
  3307     iExtension->iIconSize = aSize;
       
  3308     
       
  3309     return ScaleIcons();
       
  3310     }
       
  3311        
       
  3312 // -----------------------------------------------------------------------------
       
  3313 // CAknButton::ResetState
       
  3314 // Sets button to unpressed state. 
       
  3315 // -----------------------------------------------------------------------------
       
  3316 //
       
  3317 EXPORT_C void CAknButton::ResetState( )
       
  3318     {
       
  3319     StopKeyRepeatTimer();
       
  3320     StopLongPressTimer();
       
  3321     iButtonPressed = EFalse;
       
  3322     HideHelp();
       
  3323     if ( iExtension )
       
  3324         {
       
  3325         if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() )
       
  3326             {
       
  3327             TRAP_IGNORE( Observer()->HandleControlEventL( this, 
       
  3328             static_cast<MCoeControlObserver::TCoeEvent>( CAknButton::ELongPressEndedEvent ) ) );
       
  3329             }
       
  3330         
       
  3331         iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
       
  3332         iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
       
  3333         } 
       
  3334     }
       
  3335 
       
  3336 // -----------------------------------------------------------------------------
       
  3337 // CAknButton::CalculateDefaultMargins
       
  3338 // Calculates default margins.
       
  3339 // -----------------------------------------------------------------------------
       
  3340 //
       
  3341 void CAknButton::CalculateDefaultMargins()
       
  3342     {
       
  3343     if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultMargins ) )
       
  3344         {
       
  3345         if ( !( iFlags & KAknButtonNoFrame ) )
       
  3346             {
       
  3347             TAknLayoutRect layoutRect;
       
  3348             layoutRect.LayoutRect( Rect(), 
       
  3349                 AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine() );
       
  3350             iExtension->iMargins.SetAllValuesTo( 
       
  3351                 layoutRect.Rect().Size().iWidth / 10 ); // always square 
       
  3352             }
       
  3353         }
       
  3354 
       
  3355     if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultIconSize ) )
       
  3356         {
       
  3357         // ensure that icon size never exceeds the space inside margins
       
  3358         TRect rectInsideMargins( iExtension->iMargins.InnerRect( Rect() ) );
       
  3359         
       
  3360         if ( rectInsideMargins.Size().iWidth < iExtension->iIconSize.iWidth )
       
  3361             {
       
  3362             iExtension->iIconSize.iWidth = 
       
  3363                 Max( 0, rectInsideMargins.Size().iWidth );
       
  3364             }
       
  3365             
       
  3366         if ( rectInsideMargins.Size().iHeight < iExtension->iIconSize.iHeight )
       
  3367             {
       
  3368             iExtension->iIconSize.iHeight = 
       
  3369                 Max( 0, rectInsideMargins.Size().iHeight );
       
  3370             }
       
  3371         }
       
  3372     }
       
  3373 
       
  3374 // -----------------------------------------------------------------------------
       
  3375 // CAknButton::ScaleIcons
       
  3376 // Scales all icons.
       
  3377 // -----------------------------------------------------------------------------
       
  3378 //
       
  3379 TInt CAknButton::ScaleIcons()
       
  3380     {
       
  3381     TInt retval = KErrNone;
       
  3382     
       
  3383     for ( TInt i = 0; i < iStates->Count(); ++i )
       
  3384         {
       
  3385         CAknButtonState* state = iStates->At( i );
       
  3386         
       
  3387         if ( state )
       
  3388             {
       
  3389             retval = Min( retval, state->ScaleIcons( iExtension->iIconSize,
       
  3390                                                      iScaleMode ) );
       
  3391             if ( iExtension->iFlags.IsSet( CAknButtonExtension::EDimmed ) && 
       
  3392                 !state->iDimmedIcon &&
       
  3393                 state->iIcon )
       
  3394                 {
       
  3395                 TRAP_IGNORE( CreateAndSetDimmedIconL( state->iDimmedIcon, 
       
  3396                     state->iIcon, state->ScaleMode() ) );
       
  3397                 }
       
  3398             }
       
  3399         }
       
  3400         
       
  3401     return retval;        
       
  3402     }
       
  3403     
       
  3404 // -----------------------------------------------------------------------------
       
  3405 // CAknButton::DrawTextButton
       
  3406 // Continues drawing of the button which has only text
       
  3407 // -----------------------------------------------------------------------------
       
  3408 //
       
  3409 void CAknButton::DrawTextButton( CWindowGc& aGc ) const
       
  3410     {
       
  3411     CAknButtonState* state = State();
       
  3412     if ( !state || !state->HasText() )
       
  3413         return;
       
  3414 
       
  3415     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  3416 
       
  3417     TRect textRect = iExtension->iMargins.InnerRect( Rect() );
       
  3418 
       
  3419     if ( !( iFlags & KAknButtonNoFrame ) && 
       
  3420          ( iFlags & KAknButtonTextInsideFrame ) )
       
  3421         {
       
  3422         TAknLayoutRect center;
       
  3423         center.LayoutRect( Rect(), 
       
  3424             AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
       
  3425 
       
  3426         textRect = center.Rect();
       
  3427         }
       
  3428 
       
  3429     aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
  3430 
       
  3431     TRgb penColor;
       
  3432     TRgb brushColor;
       
  3433     GetTextColors( penColor, brushColor ); 
       
  3434     aGc.SetPenColor( penColor ); 
       
  3435     aGc.SetBrushColor( brushColor ); 
       
  3436 
       
  3437     const CFont* font = iFont;
       
  3438     if ( !font )
       
  3439         {
       
  3440         font = iCoeEnv->NormalFont();
       
  3441         }
       
  3442     aGc.UseFont( font );
       
  3443 
       
  3444     aGc.SetUnderlineStyle( iExtension->iUnderlineStyle );
       
  3445 
       
  3446     // buffer for visually ordered text
       
  3447     TBuf<255 + KAknBidiExtraSpacePerLine> visualText; 
       
  3448     TInt clipWidth = textRect.Width();
       
  3449 
       
  3450     // bidi processing - using AknBidiTextUtils.
       
  3451     AknBidiTextUtils::ConvertToVisualAndClip(
       
  3452         state->Text(),
       
  3453         visualText,
       
  3454         *font,
       
  3455         clipWidth,
       
  3456         clipWidth );
       
  3457 
       
  3458     TInt baselineOffset = 0;
       
  3459     switch ( iVerticalAlignment )
       
  3460         {
       
  3461         case ETop:
       
  3462             baselineOffset = font->AscentInPixels();
       
  3463             break;
       
  3464 
       
  3465         case EBottom:
       
  3466             baselineOffset = textRect.Height();
       
  3467             break;
       
  3468 
       
  3469         default:  // centered
       
  3470             baselineOffset = font->AscentInPixels() +
       
  3471                            ( textRect.Height() - font->AscentInPixels() ) / 2;
       
  3472         }
       
  3473 
       
  3474     CGraphicsContext::TTextAlign horAlignment = iHorizontalAlignment;
       
  3475 
       
  3476     aGc.DrawText( visualText, textRect, baselineOffset, horAlignment );
       
  3477     if ( iExtension->iPictographInterface )
       
  3478         {
       
  3479         // For Japanese variant only
       
  3480         iExtension->iPictographInterface->Interface()->DrawPictographsInText(
       
  3481             aGc, *font, visualText, textRect, baselineOffset, horAlignment );
       
  3482         }
       
  3483     }
       
  3484 
       
  3485 // -----------------------------------------------------------------------------
       
  3486 // CAknButton::DrawIconButton
       
  3487 // Continues drawing of the button which has only an icon in it
       
  3488 // -----------------------------------------------------------------------------
       
  3489 //
       
  3490 void CAknButton::DrawIconButton( CWindowGc& aGc ) const
       
  3491     {
       
  3492     TRect iconRect( iExtension->iMargins.InnerRect( Rect() ) );
       
  3493     
       
  3494     aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
       
  3495 
       
  3496     const CGulIcon* icon = GetCurrentIcon();
       
  3497     if ( !icon )
       
  3498         return;
       
  3499 
       
  3500     CFbsBitmap* buttonBmp = icon->Bitmap();
       
  3501     CFbsBitmap* buttonMask = icon->Mask();
       
  3502 
       
  3503     TPoint iconPoint;
       
  3504     TSize iconSize ( buttonBmp->SizeInPixels());
       
  3505 
       
  3506     switch ( iExtension->iHorizontalIconAlignment )
       
  3507         {
       
  3508         case ERight:
       
  3509             {
       
  3510             iconPoint.iX = iconRect.iBr.iX - iconSize.iWidth;                        
       
  3511             }
       
  3512             break;  
       
  3513 
       
  3514         case ECenter:
       
  3515             {
       
  3516             iconPoint.iX = iconRect.iTl.iX + 
       
  3517             (iconRect.Width() / 2 - iconSize.iWidth / 2 );
       
  3518             } 
       
  3519             break;
       
  3520             
       
  3521         case ELeft:
       
  3522             {
       
  3523             iconPoint.iX = iconRect.iTl.iX;
       
  3524             }
       
  3525             break; 
       
  3526         
       
  3527         default:
       
  3528             // Should never come here
       
  3529             break;
       
  3530         }
       
  3531 
       
  3532     switch ( iExtension->iVerticalIconAlignment )
       
  3533         {
       
  3534         case ETop:
       
  3535             {
       
  3536             iconPoint.iY = iconRect.iTl.iY;
       
  3537             }
       
  3538             break;
       
  3539         
       
  3540         case ECenter:
       
  3541             {
       
  3542             iconPoint.iY = iconRect.iTl.iY +
       
  3543             ( iconRect.Height() / 2 - iconSize.iHeight / 2 );
       
  3544             }
       
  3545             break;
       
  3546           
       
  3547         case EBottom:
       
  3548             {
       
  3549             iconPoint.iY = iconRect.iBr.iY - iconSize.iHeight;
       
  3550             }
       
  3551             break;
       
  3552             
       
  3553         default:
       
  3554             // Should never come here
       
  3555             break;
       
  3556         }
       
  3557 
       
  3558     if( buttonBmp && buttonMask )
       
  3559         {
       
  3560         aGc.BitBltMasked( iconPoint, buttonBmp,
       
  3561             iconRect.Size(), buttonMask, ETrue );
       
  3562         }
       
  3563     else if ( buttonBmp )
       
  3564         {
       
  3565         aGc.BitBlt( iconPoint, buttonBmp, iconRect.Size() );
       
  3566         }
       
  3567     }
       
  3568 
       
  3569 // -----------------------------------------------------------------------------
       
  3570 // CAknButton::DrawTextAndIconButton
       
  3571 // Continues drawing of the button which has both text and icon
       
  3572 // -----------------------------------------------------------------------------
       
  3573 //
       
  3574 void CAknButton::DrawTextAndIconButton( CWindowGc& aGc ) const
       
  3575     {
       
  3576     CAknButtonState* state = State();
       
  3577     if ( !state  || !state->HasText() )
       
  3578         {
       
  3579         return;
       
  3580         }
       
  3581     
       
  3582     const CGulIcon* icon = GetCurrentIcon();
       
  3583     if ( !icon )
       
  3584         {
       
  3585         return;
       
  3586         }
       
  3587 
       
  3588     TRect rect = iExtension->iMargins.InnerRect( Rect() );
       
  3589     TRect iconRect;
       
  3590     TRect textRect;
       
  3591     
       
  3592     if ( !( iFlags & KAknButtonNoFrame ) &&
       
  3593           ( iFlags & KAknButtonTextInsideFrame ))
       
  3594         {
       
  3595         TAknLayoutRect centerLayout;
       
  3596         centerLayout.LayoutRect( rect,
       
  3597         AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
       
  3598         rect = centerLayout.Rect();
       
  3599         }
       
  3600 
       
  3601     CFbsBitmap* buttonBmp = icon->Bitmap();
       
  3602     CFbsBitmap* buttonMask = icon->Mask();
       
  3603     TSize iconSize ( buttonBmp->SizeInPixels());
       
  3604     
       
  3605     // Set rects for icon and text according to their positioning
       
  3606     // First icon rect according to icon size - rest is for text
       
  3607     
       
  3608     switch ( iExtension->iTextAndIconAlignment )        
       
  3609         {
       
  3610         case EIconBeforeText:
       
  3611             if ( AknLayoutUtils::LayoutMirrored() ) 
       
  3612                 {
       
  3613                 textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
       
  3614                 rect.iBr.iX - iconSize.iWidth, rect.iBr.iY);
       
  3615                 iconRect.SetRect( rect.iTl.iX + 
       
  3616                     rect.Width() -iconSize.iWidth,
       
  3617                 rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );    
       
  3618                 }
       
  3619             else
       
  3620                 {
       
  3621                 iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
       
  3622                 rect.iTl.iX + iconSize.iWidth, rect.iBr.iY);
       
  3623                 textRect.SetRect( rect.iTl.iX + iconSize.iWidth,
       
  3624                 rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );    
       
  3625                 }
       
  3626             
       
  3627             break;
       
  3628             
       
  3629         case EIconAfterText:
       
  3630             if ( AknLayoutUtils::LayoutMirrored() ) 
       
  3631                 {
       
  3632                 iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
       
  3633                 rect.iTl.iX + iconSize.iWidth, rect.iBr.iY);
       
  3634                 textRect.SetRect( rect.iTl.iX + iconSize.iWidth,
       
  3635                 rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );    
       
  3636                 }
       
  3637             else
       
  3638                 {
       
  3639                 textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
       
  3640                 rect.iBr.iX - iconSize.iWidth, rect.iBr.iY);
       
  3641                 iconRect.SetRect( rect.iTl.iX + 
       
  3642                     rect.Width() -iconSize.iWidth,
       
  3643                 rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
       
  3644                 }
       
  3645             break;
       
  3646         
       
  3647         case EIconOverText:
       
  3648             iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
       
  3649             rect.iBr.iX, rect.iTl.iY + iconSize.iHeight );
       
  3650             textRect.SetRect( rect.iTl.iX, rect.iTl.iY + iconSize.iHeight,
       
  3651             rect.iBr.iX, rect.iBr.iY );
       
  3652             break;
       
  3653             
       
  3654         case EIconUnderText:
       
  3655             textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
       
  3656             rect.iBr.iX, rect.iBr.iY - iconSize.iHeight );
       
  3657             iconRect.SetRect( rect.iTl.iX, rect.iBr.iY - iconSize.iHeight,
       
  3658             rect.iBr.iX, rect.iBr.iY );
       
  3659             break;
       
  3660 
       
  3661         case EOverlay:
       
  3662             {
       
  3663             textRect = rect;
       
  3664             iconRect = rect;
       
  3665             }
       
  3666             break;
       
  3667             
       
  3668         default:
       
  3669             return;
       
  3670         }
       
  3671 
       
  3672     // Draw icon
       
  3673     TPoint iconPoint;
       
  3674     switch ( iExtension->iHorizontalIconAlignment )
       
  3675         {
       
  3676         case ERight:
       
  3677             {
       
  3678             iconPoint.iX = iconRect.iBr.iX - iconSize.iWidth;                        
       
  3679             }
       
  3680             break;  
       
  3681 
       
  3682         case ECenter:
       
  3683             {
       
  3684             iconPoint.iX = iconRect.iTl.iX + 
       
  3685             (iconRect.Width() / 2 - iconSize.iWidth / 2 );
       
  3686             } 
       
  3687             break;
       
  3688             
       
  3689         case ELeft:
       
  3690             {
       
  3691             iconPoint.iX = iconRect.iTl.iX;
       
  3692             }
       
  3693             break; 
       
  3694         
       
  3695         default:
       
  3696             // Should never come here
       
  3697             break;
       
  3698         }
       
  3699 
       
  3700     switch ( iExtension->iVerticalIconAlignment )
       
  3701         {
       
  3702         case ETop:
       
  3703             {
       
  3704             iconPoint.iY = iconRect.iTl.iY;
       
  3705             }
       
  3706             break;
       
  3707         
       
  3708         case ECenter:
       
  3709             {
       
  3710             iconPoint.iY = iconRect.iTl.iY +
       
  3711             ( iconRect.Height() / 2 - iconSize.iHeight / 2 );
       
  3712             }
       
  3713             break;
       
  3714           
       
  3715         case EBottom:
       
  3716             {
       
  3717             iconPoint.iY = iconRect.iBr.iY - iconSize.iHeight;
       
  3718             }
       
  3719             break;
       
  3720             
       
  3721         default:
       
  3722             // Should never come here
       
  3723             break;
       
  3724         }
       
  3725 
       
  3726     if( buttonBmp && buttonMask )
       
  3727         {
       
  3728         aGc.BitBltMasked( iconPoint, buttonBmp,
       
  3729             iconRect.Size(), buttonMask, ETrue );
       
  3730         }
       
  3731     else if ( buttonBmp )
       
  3732         {
       
  3733         aGc.BitBlt( iconPoint, buttonBmp, iconRect.Size() );
       
  3734         }
       
  3735 
       
  3736     const CFont* font = iFont;
       
  3737     if ( !font )
       
  3738         {
       
  3739         font = iCoeEnv->NormalFont();
       
  3740         }
       
  3741     aGc.UseFont( font );
       
  3742         
       
  3743     TRgb penColor;
       
  3744     TRgb brushColor;
       
  3745     GetTextColors( penColor, brushColor ); 
       
  3746     aGc.SetPenColor( penColor ); 
       
  3747     aGc.SetBrushColor( brushColor ); 
       
  3748 
       
  3749     aGc.SetUnderlineStyle( iExtension->iUnderlineStyle );
       
  3750 
       
  3751     TBuf<255 + KAknBidiExtraSpacePerLine> visualText; // buffer for visually ordered text
       
  3752     TInt clipWidth = textRect.Width();
       
  3753 
       
  3754     // bidi processing - using AknBidiTextUtils.
       
  3755     AknBidiTextUtils::ConvertToVisualAndClip(
       
  3756         state->Text(),
       
  3757         visualText,
       
  3758         *font,
       
  3759         clipWidth,
       
  3760         clipWidth );
       
  3761 
       
  3762     TInt baselineOffset = 0;
       
  3763     switch ( iVerticalAlignment )
       
  3764         {
       
  3765         case ETop:
       
  3766             baselineOffset = font->AscentInPixels();
       
  3767             break;
       
  3768 
       
  3769         case EBottom:
       
  3770             baselineOffset = textRect.Height();
       
  3771             break;
       
  3772 
       
  3773         default:  // centered
       
  3774             baselineOffset = font->AscentInPixels() +
       
  3775                            ( textRect.Height() - font->AscentInPixels() ) / 2;
       
  3776         }
       
  3777 
       
  3778     CGraphicsContext::TTextAlign horAlignment = iHorizontalAlignment;
       
  3779 
       
  3780     aGc.DrawText( visualText, textRect, baselineOffset, horAlignment );
       
  3781     if ( iExtension->iPictographInterface )
       
  3782         {
       
  3783         // For Japanese variant only
       
  3784         iExtension->iPictographInterface->Interface()->DrawPictographsInText(
       
  3785             aGc, *font, visualText, textRect, baselineOffset, horAlignment );
       
  3786         }
       
  3787     }
       
  3788 
       
  3789 // -----------------------------------------------------------------------------
       
  3790 // Starts the long press timer.
       
  3791 // -----------------------------------------------------------------------------
       
  3792 //
       
  3793 void CAknButton::StartLongPressTimerL()
       
  3794     {
       
  3795     if ( iExtension )
       
  3796         {
       
  3797         iExtension->StartLongPressTimerL();
       
  3798         }
       
  3799     }
       
  3800 
       
  3801 // -----------------------------------------------------------------------------
       
  3802 // Stops the long press timer.
       
  3803 // -----------------------------------------------------------------------------
       
  3804 //
       
  3805 void CAknButton::StopLongPressTimer()
       
  3806     {
       
  3807     if ( iExtension && iExtension->iLongPressTimer &&
       
  3808         iExtension->iLongPressTimer->IsActive() )
       
  3809         {
       
  3810         iExtension->iLongPressTimer->Cancel();
       
  3811         }
       
  3812     }
       
  3813 
       
  3814 // -----------------------------------------------------------------------------
       
  3815 // CAknButton::StartKeyRepeatTimerL
       
  3816 // Starts the timer for the long presses. The timer is constructed when used
       
  3817 // for the first time.
       
  3818 // -----------------------------------------------------------------------------
       
  3819 //
       
  3820 void CAknButton::StartKeyRepeatTimerL()
       
  3821     {
       
  3822     if ( !iKeyRepeatTimer )
       
  3823         {
       
  3824         iKeyRepeatTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
  3825         }
       
  3826     else if ( iKeyRepeatTimer->IsActive() )
       
  3827         {
       
  3828         iKeyRepeatTimer->Cancel();
       
  3829         }
       
  3830 
       
  3831     if ( iKeyRepeatInterval > 0 )
       
  3832         {
       
  3833         iKeyRepeatTimer->Start( iKeyRepeatDelay, iKeyRepeatInterval,
       
  3834             TCallBack( ReportKeyRepeatL, this ) );
       
  3835         }
       
  3836     }
       
  3837 
       
  3838 // -----------------------------------------------------------------------------
       
  3839 // Stops the key repeat timer.
       
  3840 // -----------------------------------------------------------------------------
       
  3841 //
       
  3842 void CAknButton::StopKeyRepeatTimer()
       
  3843     {
       
  3844     if ( iKeyRepeatTimer && iKeyRepeatTimer->IsActive() )
       
  3845         {
       
  3846         iKeyRepeatTimer->Cancel();
       
  3847         }
       
  3848     }
       
  3849 
       
  3850 // -----------------------------------------------------------------------------
       
  3851 // CAknButton::ReportKeyRepeatL
       
  3852 // Cancel the timer.
       
  3853 // -----------------------------------------------------------------------------
       
  3854 //
       
  3855 TInt CAknButton::ReportKeyRepeatL( TAny* aThis )
       
  3856     {
       
  3857     // Fixes TSW error AJUA-7CEF8H 
       
  3858     User::ResetInactivityTime();
       
  3859     CAknButton* self = reinterpret_cast< CAknButton* >( aThis );
       
  3860 
       
  3861     if ( self->IsVisible() && 
       
  3862         !self->iExtension->iFlags.IsSet( CAknButtonExtension::EDimmed ) )
       
  3863         {
       
  3864         if ( self->iStates->Count() > 1 )
       
  3865             {
       
  3866             self->ChangeState( ETrue );
       
  3867             }
       
  3868 
       
  3869         if ( self->Observer() )
       
  3870             {
       
  3871             self->Observer()->HandleControlEventL( self,
       
  3872                 MCoeControlObserver::EEventStateChanged );
       
  3873             }
       
  3874 
       
  3875         TBool feedbackNeeded = (self->iStates->Count() > 1) || (self->Observer());
       
  3876         TBool pointerRepeat = (self->iButtonPressed & KPointerFlag);  // it was caused by pointer event
       
  3877         if ( self->iExtension->iFeedback && feedbackNeeded && pointerRepeat)
       
  3878             {
       
  3879             self->iExtension->iFeedback->InstantFeedback( self, ETouchFeedbackSensitiveButton );
       
  3880             }
       
  3881 
       
  3882         self->iExtension->iFlags.Set( CAknButtonExtension::EKeyRepeatEventReported );
       
  3883         }
       
  3884     else if ( self->iKeyRepeatTimer && self->iKeyRepeatTimer->IsActive() )
       
  3885         {
       
  3886         self->iKeyRepeatTimer->Cancel();
       
  3887         }
       
  3888 
       
  3889     return 1; // CPeriodic ignores return value
       
  3890     }
       
  3891 
       
  3892 // -----------------------------------------------------------------------------
       
  3893 // CAknButton::Extension
       
  3894 // -----------------------------------------------------------------------------
       
  3895 //
       
  3896 CAknButtonExtension* CAknButton::Extension() const
       
  3897     {
       
  3898     return iExtension;
       
  3899     }
       
  3900 
       
  3901 // -----------------------------------------------------------------------------
       
  3902 // CAknButton::UpdateTooltipPosition
       
  3903 // -----------------------------------------------------------------------------
       
  3904 //
       
  3905 void CAknButton::UpdateTooltipPosition()
       
  3906     {
       
  3907     TPoint position;
       
  3908 
       
  3909     if ( AknsUtils::GetControlPosition( this, position ) != KErrNone )
       
  3910         {
       
  3911         position = PositionRelativeToScreen();
       
  3912         }
       
  3913     TRect rect( position, Size() );
       
  3914 
       
  3915     TPoint center = rect.Center();
       
  3916 
       
  3917     switch ( iExtension->iTooltipPosition )
       
  3918         {
       
  3919         case EPositionTop:
       
  3920             {
       
  3921             iHelpNote->SetPositionAndAlignment(
       
  3922                 TPoint( center.iX, rect.iTl.iY ), EHCenterVBottom );
       
  3923             break;
       
  3924             }
       
  3925         case EPositionBottom:
       
  3926             {
       
  3927             iHelpNote->SetPositionAndAlignment(
       
  3928                 TPoint( center.iX, rect.iBr.iY ), EHCenterVTop );
       
  3929             break;
       
  3930             }
       
  3931         case EPositionLeft:
       
  3932             {
       
  3933             iHelpNote->SetPositionAndAlignment(
       
  3934                 TPoint( rect.iTl.iX, center.iY ), EHRightVCenter );
       
  3935             break;
       
  3936             }
       
  3937         case EPositionRight:
       
  3938             {
       
  3939             iHelpNote->SetPositionAndAlignment(
       
  3940                 TPoint( rect.iBr.iX, center.iY ), EHLeftVCenter );
       
  3941             break;
       
  3942             }
       
  3943         default:
       
  3944             {
       
  3945             return;
       
  3946             }
       
  3947         }
       
  3948     }
       
  3949 
       
  3950 // -----------------------------------------------------------------------------
       
  3951 // CAknButton::RequestExit
       
  3952 // Returns whether button should send EEventRequestExit to command observer
       
  3953 // on button up events.
       
  3954 // -----------------------------------------------------------------------------
       
  3955 //
       
  3956 TBool CAknButton::RequestExit() const
       
  3957     {
       
  3958     if ( iFlags & KAknButtonRequestExitOnButtonUpEvent )
       
  3959         {
       
  3960         return ETrue;
       
  3961         }
       
  3962     else
       
  3963         {
       
  3964         return EFalse;
       
  3965         }
       
  3966     }
       
  3967 
       
  3968 // -----------------------------------------------------------------------------
       
  3969 // CAknButton::ContentRect
       
  3970 // Returns the the rectangle reserved for frame center, or the rect for text and
       
  3971 // icon, if the button has no frames (controls rect for now).
       
  3972 // -----------------------------------------------------------------------------
       
  3973 //
       
  3974 TRect CAknButton::ContentRect() const
       
  3975     {    
       
  3976     TRect rect( Size() );
       
  3977     if ( !( iFlags & KAknButtonNoFrame ) && 
       
  3978           ( iFlags & KAknButtonTextInsideFrame ) )
       
  3979         {
       
  3980         TAknLayoutRect centerLayout;
       
  3981         centerLayout.LayoutRect( rect,
       
  3982         AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
       
  3983         rect = centerLayout.Rect();        
       
  3984         }
       
  3985     return rect;
       
  3986     }
       
  3987 
       
  3988 // -----------------------------------------------------------------------------
       
  3989 // CAknButton::NeedsRedrawWhenPressed
       
  3990 // Returns boolean value indicating whether button needs redraw when it is
       
  3991 // pressed or released without changes in its state.
       
  3992 // -----------------------------------------------------------------------------
       
  3993 //
       
  3994 TBool CAknButton::NeedsRedrawWhenPressed() const
       
  3995     {
       
  3996     CAknButtonState* state = State();
       
  3997     if ( !iButtonPressed && iStates->Count() > 1 )
       
  3998         {
       
  3999         return EFalse; 
       
  4000         }
       
  4001 
       
  4002     if ( iButtonPressed && iFlags & KAknButtonPressedDownFrame )
       
  4003         {
       
  4004         return ETrue;
       
  4005         }
       
  4006         
       
  4007     return ( state && state->PressedIcon() ||
       
  4008              ( !( iFlags & KAknButtonNoFrame ) &&
       
  4009                !( iFlags & KAknButtonNoFramePressEvent ) &&
       
  4010                !( state && state->Flags() & KAknButtonStateHasLatchedFrame &&
       
  4011                   SkinIID( KPressedFrameId ) == SkinIID( KLatchedFrameId ) ) ) );
       
  4012     }
       
  4013 
       
  4014 // -----------------------------------------------------------------------------
       
  4015 // CAknButton::SkinIID
       
  4016 // -----------------------------------------------------------------------------
       
  4017 //
       
  4018 TAknsItemID CAknButton::SkinIID( const TInt aIndex ) const
       
  4019     {
       
  4020     if ( iExtension && aIndex >= 0 &&
       
  4021          aIndex < iExtension->iFrameAndCenterIds.Count() )
       
  4022         {
       
  4023         return iExtension->iFrameAndCenterIds[aIndex];
       
  4024         }
       
  4025     else
       
  4026         {
       
  4027         return KAknsIIDNone;
       
  4028         }
       
  4029     }
       
  4030     
       
  4031 // -----------------------------------------------------------------------------
       
  4032 // CAknButton::HitAreaContainsL
       
  4033 // Checks if a button icon's non-transparent area was tapped.
       
  4034 // -----------------------------------------------------------------------------
       
  4035 //
       
  4036 TBool CAknButton::HitAreaContainsL( const TPoint& aPoint, TBool aCheckHitArea ) const
       
  4037     {
       
  4038     TBool buttonEvent( ETrue );
       
  4039 
       
  4040     if ( aCheckHitArea )
       
  4041         {
       
  4042         if ( TouchArea().Contains( aPoint ) )
       
  4043             {
       
  4044             return ETrue; 
       
  4045             }
       
  4046         else
       
  4047             {
       
  4048             return EFalse; 
       
  4049             }
       
  4050         }
       
  4051     else if ( iFlags & KAknButtonHitTest )        
       
  4052         {
       
  4053         TRect rect( Size() );
       
  4054         TRect contentRect( ContentRect() );
       
  4055         
       
  4056         CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
       
  4057         CleanupStack::PushL( bitmap );
       
  4058         
       
  4059         User::LeaveIfError( bitmap->Create( rect.Size(), EGray256 ) );
       
  4060             
       
  4061         CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( bitmap );
       
  4062         
       
  4063         CleanupStack::PushL( device );
       
  4064         CFbsBitGc* gc = CFbsBitGc::NewL();
       
  4065         gc->Activate( device );                            
       
  4066         gc->SetBrushStyle( CGraphicsContext::ENullBrush );
       
  4067 
       
  4068         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  4069         MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
       
  4070         
       
  4071         if ( !(iFlags & KAknButtonNoFrame ) )
       
  4072             {    
       
  4073             CAknButtonState* state = State();
       
  4074             
       
  4075             TInt frameIdIndex = KFrameId;
       
  4076             if ( iButtonPressed )
       
  4077                 {
       
  4078                 frameIdIndex = KPressedFrameId;
       
  4079                 }
       
  4080             else if ( state && state->Flags() & KAknButtonStateHasLatchedFrame )
       
  4081                 {
       
  4082                 if ( IsDimmed() )
       
  4083                     {
       
  4084                     // dimmed latched frame
       
  4085                     frameIdIndex = KLatchedDimmedFrameId;
       
  4086                     }
       
  4087                 else
       
  4088                     {
       
  4089                     // latched down
       
  4090                     frameIdIndex = KLatchedFrameId;
       
  4091                     }
       
  4092                 }
       
  4093             else if ( IsDimmed())
       
  4094                 {
       
  4095                 // dimmed frame
       
  4096                 frameIdIndex = KDimmedFrameId;
       
  4097                 }
       
  4098 
       
  4099             if ( SkinIID( frameIdIndex ) != KAknsIIDNone )
       
  4100                 {
       
  4101                 TAknsItemID frameId = SkinIID( frameIdIndex );
       
  4102                 TAknsItemID centerId = SkinIID( frameIdIndex + 1 );                                       
       
  4103                 
       
  4104                 gc->SetBrushColor( KRgbWhite );
       
  4105                 
       
  4106                 if ( !AknsDrawUtils::DrawFrame( skin, *gc, rect, 
       
  4107                     contentRect, frameId, centerId, KAknsSDMAlphaOnly ) )
       
  4108                     {                                                                                    
       
  4109                     gc->DrawRect( rect );
       
  4110                     }                                                            
       
  4111                 gc->DrawRect( contentRect );                        
       
  4112                 }
       
  4113             }
       
  4114         else if ( GetCurrentIcon() )
       
  4115             {
       
  4116             // if button has (only) icon, then mark other parts transparent
       
  4117             gc->SetBrushColor( KRgbBlack );
       
  4118             gc->Clear();
       
  4119             CFbsBitmap* mask = GetCurrentIcon()->Mask();
       
  4120             if ( mask )
       
  4121                 {
       
  4122                 gc->BitBlt( contentRect.iTl, mask, mask->SizeInPixels() );
       
  4123                 }
       
  4124             }
       
  4125         else if ( GetCurrentText() != KNullDesC )
       
  4126             {
       
  4127             gc->SetBrushColor( KRgbWhite );
       
  4128             gc->Clear( contentRect );
       
  4129             }
       
  4130         else
       
  4131             {
       
  4132             // if this happens.. make the whole button transparent!
       
  4133             gc->SetBrushColor( KRgbBlack );
       
  4134             gc->Clear( contentRect );                
       
  4135             }
       
  4136 
       
  4137         TRgb pixel;
       
  4138         TPoint point( aPoint - Rect().iTl );
       
  4139         bitmap->GetPixel( pixel, point );
       
  4140         
       
  4141         delete gc;                    
       
  4142         CleanupStack::PopAndDestroy( 2 ); // bitmap, device
       
  4143 
       
  4144         if ( pixel == KRgbBlack )
       
  4145             {
       
  4146             buttonEvent = EFalse;
       
  4147             }
       
  4148         } // iFlags & KAknButtonHitTest
       
  4149     return buttonEvent;
       
  4150     }
       
  4151 
       
  4152 // -----------------------------------------------------------------------------
       
  4153 // CAknButton::UsesDefaultMargins
       
  4154 // Checks if the button uses default margins.
       
  4155 // -----------------------------------------------------------------------------
       
  4156 //
       
  4157 TBool CAknButton::UsesDefaultMargins() const
       
  4158     {
       
  4159     return iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultMargins );
       
  4160     }
       
  4161 
       
  4162 // -----------------------------------------------------------------------------
       
  4163 // CAknButton::TextColor
       
  4164 // Gets the correct text color.
       
  4165 // -----------------------------------------------------------------------------
       
  4166 //
       
  4167 TRgb CAknButton::TextColor() const
       
  4168     {
       
  4169     TRgb color;
       
  4170     
       
  4171     if ( IsDimmed() )
       
  4172         {
       
  4173         color = iEikonEnv->ControlColor( EColorButtonText, *this );
       
  4174         color.SetAlpha( 77 );
       
  4175         }
       
  4176     else if ( iButtonPressed )
       
  4177         {
       
  4178         color = iEikonEnv->ControlColor( EColorButtonTextPressed, *this );
       
  4179         }
       
  4180     else
       
  4181         {
       
  4182         color = iEikonEnv->ControlColor( EColorButtonText, *this );
       
  4183         }
       
  4184         
       
  4185     return color;
       
  4186     }
       
  4187     
       
  4188 // -----------------------------------------------------------------------------
       
  4189 // CAknButton::CreatePressedDownFrameL
       
  4190 // Generates a pressed down mask
       
  4191 // -----------------------------------------------------------------------------
       
  4192 //    
       
  4193 void CAknButton::CreatePressedDownFrameL()
       
  4194     {
       
  4195 
       
  4196     // Fetch frames from frame provider if one exists
       
  4197     if ( iExtension->FetchProviderPressedBmpsL() )
       
  4198         {
       
  4199         return;
       
  4200         }
       
  4201 
       
  4202     if ( iExtension->iPressedDownBmp &&
       
  4203          iExtension->iPressedDownBmp->SizeInPixels() == Size() )
       
  4204         {
       
  4205         iExtension->SetProviderPressedBmpsL();
       
  4206         return;
       
  4207         }
       
  4208 
       
  4209     iExtension->DeletePressedBmps();
       
  4210 
       
  4211     // Fetch preffered display mode for icon type images
       
  4212     AknIconConfig::TPreferredDisplayMode displayMode;
       
  4213     AknIconConfig::PreferredDisplayMode( 
       
  4214         displayMode, AknIconConfig::EImageTypeIcon );
       
  4215 
       
  4216     iExtension->iPressedDownBmp = new ( ELeave ) CFbsBitmap;
       
  4217     User::LeaveIfError( iExtension->iPressedDownBmp->Create( Size(),
       
  4218         displayMode.iBitmapMode) );
       
  4219     iExtension->iPressedDownBmpMask = new ( ELeave ) CFbsBitmap;
       
  4220     User::LeaveIfError( iExtension->iPressedDownBmpMask->Create( Size(), 
       
  4221         displayMode.iMaskMode ) );
       
  4222 
       
  4223     CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL( 
       
  4224         iExtension->iPressedDownBmp );
       
  4225     CleanupStack::PushL( bmpDevice );
       
  4226      
       
  4227     CFbsBitGc* bmpGc (NULL );
       
  4228     User::LeaveIfError( bmpDevice->CreateContext( bmpGc ) );
       
  4229     CleanupStack::PushL( bmpGc );
       
  4230 
       
  4231     CFbsBitmapDevice* bmpMaskDevice = CFbsBitmapDevice::NewL(
       
  4232         iExtension->iPressedDownBmpMask );
       
  4233     CleanupStack::PushL( bmpMaskDevice );
       
  4234         
       
  4235     CFbsBitGc* bmpMaskGc( NULL );
       
  4236     User::LeaveIfError( bmpMaskDevice->CreateContext( bmpMaskGc ) );
       
  4237     CleanupStack::PushL( bmpMaskGc );
       
  4238 
       
  4239     TRect rect ( Size() );
       
  4240     TAknLayoutRect centerLayout;
       
  4241     centerLayout.LayoutRect( rect,
       
  4242         AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
       
  4243     TRect innerRect( centerLayout.Rect() );
       
  4244 
       
  4245     TAknWindowLineLayout unit = AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine();
       
  4246     innerRect.Shrink( unit.iW/10, unit.iH/10 ); 
       
  4247         
       
  4248     AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
       
  4249                               *bmpGc, rect, innerRect,
       
  4250                               SkinIID( KPressedFrameId ), KAknsIIDDefault,
       
  4251                               KAknsDrawParamRGBOnly );
       
  4252         
       
  4253     AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(), 
       
  4254                               *bmpMaskGc, rect, innerRect,
       
  4255                               SkinIID( KPressedFrameId ), KAknsIIDDefault, 
       
  4256                               KAknsSDMAlphaOnly );
       
  4257 
       
  4258     // Modify mask 50% transparent
       
  4259     iExtension->iPressedDownBmpMask->LockHeap();
       
  4260     
       
  4261     TInt w = iExtension->iPressedDownBmpMask->SizeInPixels().iWidth; 
       
  4262     TInt h = iExtension->iPressedDownBmpMask->SizeInPixels().iHeight;
       
  4263     TInt dataStride = iExtension->iPressedDownBmpMask->DataStride() - w; 
       
  4264     unsigned char* address = (unsigned char *)iExtension->iPressedDownBmpMask->DataAddress();  
       
  4265     
       
  4266             
       
  4267             for ( TInt i = 0; i < h; ++i )
       
  4268                 {
       
  4269                 for ( TInt j = 0; j < w; ++j )
       
  4270                     {
       
  4271                     *address >>= 1;
       
  4272                     ++address;
       
  4273                     }
       
  4274                 address += dataStride;         
       
  4275                 }
       
  4276 
       
  4277     iExtension->iPressedDownBmpMask->UnlockHeap();
       
  4278 
       
  4279     // Set created frames to frame provider if one exists
       
  4280     iExtension->SetProviderPressedBmpsL();
       
  4281 
       
  4282     CleanupStack::PopAndDestroy( 4 ); // bmpDevice, bmpGc, bmpMaskDevice, bmpMaskGc
       
  4283     }
       
  4284 
       
  4285 
       
  4286 // -----------------------------------------------------------------------------
       
  4287 // CAknButton::HideTooltipWhenAppFaded
       
  4288 // Sets tooltip to show or hide itself when background faded. By default tooltip
       
  4289 // is not shown when background faded. 
       
  4290 // -----------------------------------------------------------------------------
       
  4291 //
       
  4292 void CAknButton::HideTooltipWhenAppFaded( TBool aHide )
       
  4293     {
       
  4294     if(iHelpNote)
       
  4295         {
       
  4296         iHelpNote->HideWhenAppFaded( aHide ); 
       
  4297         }
       
  4298     }
       
  4299 
       
  4300 
       
  4301 // -----------------------------------------------------------------------------
       
  4302 // CAknButton::CheckHitArea
       
  4303 // This checks hit area for fixed toolbar buttons. 
       
  4304 // -----------------------------------------------------------------------------
       
  4305 //
       
  4306 void CAknButton::CheckHitArea( )
       
  4307     {
       
  4308     iExtension->iFlags.Set( CAknButtonExtension::ECheckHitArea );
       
  4309     SetHitTest( iExtension ); 
       
  4310     iExtension->HandleFeedbackAreaChange();
       
  4311     }
       
  4312 
       
  4313 // -----------------------------------------------------------------------------
       
  4314 // CAknButton::UseAdditionalMask
       
  4315 // Sets button to use additional masks during drawing.
       
  4316 // -----------------------------------------------------------------------------
       
  4317 //
       
  4318 void CAknButton::UseMaskedDraw( TBool aMaskedDraw )
       
  4319     {
       
  4320     if ( aMaskedDraw )
       
  4321         {
       
  4322         iExtension->iFlags.Set( CAknButtonExtension:: EUseAdditionalMask );
       
  4323         }
       
  4324     else
       
  4325         {
       
  4326         iExtension->iFlags.Clear( CAknButtonExtension:: EUseAdditionalMask );
       
  4327         }
       
  4328     }
       
  4329 
       
  4330 
       
  4331 // -----------------------------------------------------------------------------
       
  4332 // Registers resource provider.
       
  4333 // -----------------------------------------------------------------------------
       
  4334 //
       
  4335 void CAknButton::RegisterResourceProvider( CAknResourceProvider* aProvider )
       
  4336     {
       
  4337     iExtension->iResourceProvider = aProvider;
       
  4338     }
       
  4339 
       
  4340 
       
  4341 // -----------------------------------------------------------------------------
       
  4342 // Unregisters resource provider.
       
  4343 // -----------------------------------------------------------------------------
       
  4344 //
       
  4345 void CAknButton::UnregisterResourceProvider()
       
  4346     {
       
  4347     iExtension->iResourceProvider = 0;
       
  4348     }
       
  4349     
       
  4350     
       
  4351 CAknsFrameBackgroundControlContext* CAknButton::BgContext()
       
  4352     {
       
  4353     return iBgContext;
       
  4354     }
       
  4355 
       
  4356 
       
  4357 // -----------------------------------------------------------------------------
       
  4358 // CAknButton::RemoveCurrentState
       
  4359 // Removes the current state.
       
  4360 // -----------------------------------------------------------------------------
       
  4361 //
       
  4362 void CAknButton::RemoveCurrentState()
       
  4363     {
       
  4364     // Can't remove the state if it's the only one left. 
       
  4365     if ( iStates->Count() > 1 )
       
  4366         {
       
  4367         CAknButtonState* state = iStates->At( iStateIndex );
       
  4368         delete state;
       
  4369         state = NULL;
       
  4370         iStates->Delete( iStateIndex );
       
  4371         
       
  4372         iStateIndex <= 0 ? iStateIndex = 0 : iStateIndex--;
       
  4373         DrawNow();
       
  4374         }
       
  4375     }
       
  4376 
       
  4377 
       
  4378 // -----------------------------------------------------------------------------
       
  4379 // CAknButton::CalculateLuminance
       
  4380 // Calculates color's luminance value.
       
  4381 // -----------------------------------------------------------------------------
       
  4382 //
       
  4383 TInt CAknButton::CalculateLuminance( const TRgb& aColor ) const 
       
  4384     { 
       
  4385     TInt R = aColor.Red(); 
       
  4386     TInt G = aColor.Green(); 
       
  4387     TInt B = aColor.Blue(); 
       
  4388     // Should be scaled to 0-255? 
       
  4389     TInt Y = (((66 * R) + (129 * G) + (25 * B) + 128) >> 8) + 16; 
       
  4390     return Y; 
       
  4391     } 
       
  4392 
       
  4393 
       
  4394 // -----------------------------------------------------------------------------
       
  4395 // CAknButton::ConvertColorsForOutlineEffect
       
  4396 // Converts the outline color to be white or black if the fill color is 
       
  4397 // too similar to outline color. 
       
  4398 // -----------------------------------------------------------------------------
       
  4399 //
       
  4400 void CAknButton::ConvertColorsForOutlineEffect( TRgb& aFillColor, TRgb& aOutlineColor ) const 
       
  4401     { 
       
  4402     // @todo maybe there is already some conversion utility in multimedia image library? 
       
  4403     TInt innerLum = CalculateLuminance(aFillColor); 
       
  4404     TInt outerLum = CalculateLuminance(aOutlineColor); 
       
  4405     
       
  4406     // if the defined colours are the same, then change the outline color so that 
       
  4407     // it's either black or white, contrasting according to the font label text color's brightness 
       
  4408     TInt difference = outerLum - innerLum; 
       
  4409     difference = Abs(difference); 
       
  4410     TInt half = (0xff / 2); // @todo figure out hlsMax somehow 
       
  4411     TInt threshold = (0xff / 3); // @todo figure out hlsMax somehow, and decide on the threshold! 
       
  4412     if(difference < threshold) 
       
  4413         { 
       
  4414         // if inner luminance is low, the outer luminance should be high, i.e. white 
       
  4415         aOutlineColor = (innerLum < half) ? KRgbWhite : KRgbBlack; 
       
  4416         } 
       
  4417     } 
       
  4418 
       
  4419 // -----------------------------------------------------------------------------
       
  4420 // CAknButton::GetTextColors
       
  4421 // Gets correct text colors 
       
  4422 // -----------------------------------------------------------------------------
       
  4423 //
       
  4424 void CAknButton::GetTextColors( TRgb& aPenColor, TRgb& aBrushColor ) const 
       
  4425     {
       
  4426     TBool outlineEffectOn = EFalse;
       
  4427     const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull( iFont ); 
       
  4428     if ( layoutFont ) 
       
  4429         {
       
  4430         outlineEffectOn = layoutFont->FontSpecification().IsOutlineEffectOn(); 
       
  4431         }
       
  4432 
       
  4433     if ( IsDimmed() ) 
       
  4434         {
       
  4435         aPenColor = TextColor(); 
       
  4436         aBrushColor = iEikonEnv->ControlColor( EColorControlDimmedBackground,*this ); 
       
  4437         }
       
  4438     else
       
  4439         {
       
  4440         aPenColor = TextColor(); 
       
  4441         aBrushColor = iEikonEnv->ControlColor( EColorControlBackground,*this );   
       
  4442         }
       
  4443     if ( outlineEffectOn )
       
  4444         {
       
  4445         ConvertColorsForOutlineEffect( aBrushColor, aPenColor ); 
       
  4446         }
       
  4447     }    
       
  4448 
       
  4449 // -----------------------------------------------------------------------------
       
  4450 // CAknButton::SetStateIndexL
       
  4451 // Sets new state index
       
  4452 // -----------------------------------------------------------------------------
       
  4453 //
       
  4454 void CAknButton::SetStateIndexL( TInt aNewIndex )
       
  4455     {
       
  4456     if ( iStateIndex != aNewIndex )
       
  4457         {
       
  4458         iStateIndex = aNewIndex;
       
  4459         // Create new popup note controller every time state changes
       
  4460         // (text is not updated properly in help note if this is not done)
       
  4461         if ( iHelpNote )
       
  4462             {
       
  4463             delete iHelpNote;
       
  4464             iHelpNote = 0;        
       
  4465             }
       
  4466         iHelpNote = CAknInfoPopupNoteController::NewL();
       
  4467         iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval );
       
  4468         iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval );
       
  4469         iHelpNote->SetTooltipModeL( ETrue );
       
  4470         }
       
  4471     }
       
  4472 
       
  4473 // -----------------------------------------------------------------------------
       
  4474 // CAknButton::TouchArea
       
  4475 // Returns the button touchable area.
       
  4476 // -----------------------------------------------------------------------------
       
  4477 //
       
  4478 TRect CAknButton::TouchArea() const
       
  4479     {
       
  4480     TRect touchRect( Rect() );
       
  4481     if ( iExtension->iFlags.IsSet( CAknButtonExtension::ECheckHitArea ) )
       
  4482         {
       
  4483         TAknLayoutRect layoutRect;
       
  4484         layoutRect.LayoutRect( Rect(), 
       
  4485             AknLayoutScalable_Avkon::aid_touch_sctrl_middle( 
       
  4486             !Layout_Meta_Data::IsLandscapeOrientation() ).LayoutLine() );
       
  4487         touchRect = layoutRect.Rect();
       
  4488         }
       
  4489     return touchRect;
       
  4490     }
       
  4491 // end of file