uifw/EikStd/coctlsrc/AknButton.cpp
changeset 0 2f259fa3e83a
child 5 aabf2c525e0f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/EikStd/coctlsrc/AknButton.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,4491 @@
+/*
+* Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Button component
+*
+*/
+
+
+// INCLUDE FILES
+#include <aknbutton.h>
+
+#include <gulicon.h>        // CGulIcon
+#include <barsread.h>       // TResourceReader
+#include <avkon.hrh>
+#include <StringLoader.h>   // StringLoader
+#include <AknsDrawUtils.h>
+#include <AknsControlContext.h>
+#include <AknBidiTextUtils.h>
+#include <aknlayout.cdl.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <AknInfoPopupNoteController.h>
+#include <AknPictographInterface.h>
+#include <AknPictographDrawerInterface.h>
+#include <AknsFrameBackgroundControlContext.h>
+#include <aknconsts.h>
+#include <layoutmetadata.cdl.h>
+#include <AknPriv.hrh>
+#include <AknLayoutFont.h>
+#include <akniconconfig.h>
+
+#include <AknTasHook.h> // for testability hooks
+#include "aknresourceprovider.h"
+#include "aknbitmapresourceitem.h"
+#include "akncommandbuttonstate.h"
+
+#include <touchfeedback.h>
+const TUint KPointerFlag = 3; // second bit
+ 
+
+// CONSTANTS
+enum TSkinItemIdIndex
+    {
+    KFrameId = 0,
+    KCenterId,
+    KLatchedFrameId,
+    KLatchedCenterId,
+    KDimmedFrameId,
+    KDimmedCenterId,
+    KPressedFrameId,
+    KPressedCenterId,
+    KLatchedDimmedFrameId,
+    KLatchedDimmedCenterId
+    };
+
+// ATTENTION, if the values bellow are changed, make the changes in AknButton.h
+const TInt KTimeoutBeforeHelpNote = 150; // in milliseconds
+const TInt KTimeoutInViewHelpNote = 3000; // in milliseconds
+
+const TInt KKeyRepeatDelay = 500000;   // 0,5 seconds
+const TInt KKeyRepeatInterval = 500000; // 0,5 seconds
+const TInt KLongPressInterval = 800000; // 0,8 seconds
+
+const TInt KDragEventSensitivity = 1;
+
+// Value table for 70% Transparency 
+const TInt KTransparency[256] =
+    { 
+    0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7,
+    8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13,
+    14, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 19,
+    19, 19, 20, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 23, 24, 24,
+    24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29,
+    30, 30, 30, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35,
+    35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 40, 40, 40,
+    41, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 46,
+    46, 46, 47, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 50, 51, 51,
+    51, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 56,
+    57, 57, 57, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62,
+    62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67,
+    68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 73,
+    73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77 
+    };
+
+// -----------------------------------------------------------------------------
+// ResizeIcon
+// Tries to resize the given icon. If the operation fails the icon is deleted.
+// -----------------------------------------------------------------------------
+//
+static TInt ResizeIcon( CGulIcon*& aIcon, 
+                        const TSize& aSize, 
+                        TScaleMode aScaleMode )
+    {
+    TInt retval = KErrNotFound;
+    
+    if ( aIcon )
+        {
+        CFbsBitmap* bmp = aIcon->Bitmap();
+        
+        if ( bmp )
+            {
+            retval = !( aSize == bmp->SizeInPixels() );
+            }
+            
+        if ( retval != KErrNone )
+            {
+            retval = AknIconUtils::SetSize( bmp, aSize, aScaleMode );
+            }
+
+        // Retval is checked outside of the "if ( bmp )" scope above in order
+        // to detect if the given icon's bitmap is NULL. This is required since
+        // AknIconUtils::SetSize returns KErrNone for NULL bitmaps and we want
+        // to delete icons that couldn't be resized.
+        if ( retval != KErrNone )
+            {
+            delete aIcon;
+            aIcon = NULL;
+            }
+        }
+        
+    return retval;        
+    }
+    
+static void ReplaceIconStatic( CGulIcon*& aIcon, CGulIcon* aNewIcon, 
+                               TScaleMode aScaleMode )
+    {
+    TSize iconSize( 0, 0 );
+    
+    if ( aIcon && aIcon->Bitmap() )
+        {
+        iconSize = aIcon->Bitmap()->SizeInPixels();
+        }
+        
+    delete aIcon;
+    aIcon = aNewIcon;
+    
+    if ( iconSize != TSize( 0, 0 ) )
+        {
+        ResizeIcon( aIcon, iconSize, aScaleMode );
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CreateAndSetDimmedIconL
+// Creates and sets a dimmed icon from the normal icon 
+// by making a partially transparent version of it.
+//
+// @param aIcon The original icon
+// @param aDimmedIcon The dimmed icon
+// @param aScaleMode The preferred ScaleMode
+// -----------------------------------------------------------------------------
+static void CreateAndSetDimmedIconL( CGulIcon*& aDimmedIcon, 
+                                     const CGulIcon* aIcon, 
+                                     TScaleMode aScaleMode )
+    {
+    if ( aIcon )
+        {
+        CFbsBitmap* mask = aIcon->Mask();
+        
+        if ( mask && mask->DisplayMode() == EGray256 )
+            {
+            CGulIcon* newIcon = CGulIcon::NewLC();
+            CFbsBitmap* newPic = new ( ELeave ) CFbsBitmap;
+            CleanupStack::PushL( newPic );
+            
+            newPic->Duplicate( aIcon->Bitmap()->Handle() );
+            newIcon->SetBitmap( newPic );
+
+            CFbsBitmap* newMask = new ( ELeave ) CFbsBitmap;
+            
+            User::LeaveIfError( newMask->Create( 
+                newIcon->Bitmap()->SizeInPixels(), EGray256 ) );
+            CleanupStack::PushL( newMask );
+               
+            CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL( newMask );
+            CleanupStack::PushL( bitmapDevice );
+            
+            CFbsBitGc* bitGc( NULL );
+            User::LeaveIfError( bitmapDevice->CreateContext( bitGc ) );
+            CleanupStack::PushL( bitGc );
+    
+            bitGc->SetPenStyle( CGraphicsContext::ESolidPen );
+            bitGc->BitBlt( TPoint( 0, 0 ), mask );
+           
+            newMask->LockHeap();
+            TInt w = mask->SizeInPixels().iWidth; 
+            TInt h = mask->SizeInPixels().iHeight;
+            TInt dataStride = mask->DataStride() - w; 
+            unsigned char* address = (unsigned char *)newMask->DataAddress();  
+            
+            for ( TInt i = 0; i < h; ++i )
+                {
+                for ( TInt j = 0; j < w; ++j )
+                    {
+                    *address = KTransparency[*address];
+                    ++address;
+                    }
+                address += dataStride;         
+                }
+
+            newMask->UnlockHeap();
+            newIcon->SetMask( newMask );
+            ReplaceIconStatic( aDimmedIcon, newIcon, aScaleMode );
+                               
+            CleanupStack::PopAndDestroy( 2 ); // bitmapDevice, bitGc
+            CleanupStack::Pop( 3 ); // newIcon, newPic, newMask
+            }
+        }
+    }
+// ============================ EXTENSION CLASS ================================
+
+NONSHARABLE_CLASS( CAknButtonExtension ) : public CBase, MCoeControlHitTest
+    {
+    friend class CAknButton;    
+
+public:
+    // bitflags used to keep track of several button's internal features
+    enum TFlags
+        {
+        EUseAdditionalMask,
+        ECheckHitArea,
+        EDimmed,
+        ELongPressReported,
+        EUseDefaultIconSize,
+        EKeyRepeatEventReported,
+        EUseDefaultMargins
+        };
+        
+    static CAknButtonExtension* NewL( CAknButton& aButton );
+    ~CAknButtonExtension();
+
+    // Starts the long press timer.
+    void StartLongPressTimerL();
+    
+    TBool HitRegionContains( const TPoint &aPoint, 
+                             const CCoeControl &aControl ) const;
+
+    void HandleFeedbackAreaChange();
+private:
+
+    CAknButtonExtension( CAknButton& aButton );
+    void ConstructL();
+
+    // Callback method for long press timer.
+    static TInt ReportLongPressL( TAny* aThis );
+
+    // Handles long press.
+    void DoReportLongPressL();
+
+    // Deletes pressed down bitmaps
+    void DeletePressedBmps();
+
+    // Fetches bitmaps from resource provider (if one exists)
+    TBool FetchProviderPressedBmpsL();
+
+    // Sets bitmaps to resource provider (if one exists)
+    void SetProviderPressedBmpsL();
+
+private: // Data
+
+    CAknButton& iButton;
+    CAknButton::TTooltipPosition iTooltipPosition;
+    CAknPictographInterface* iPictographInterface; // not owned
+    CPeriodic* iLongPressTimer;
+    TInt iLongPressInterval;
+    TFontUnderline iUnderlineStyle;
+    RArray<TAknsItemID> iFrameAndCenterIds;
+    CAknButton::TAlignment iVerticalIconAlignment; 
+    CAknButton::TAlignment iHorizontalIconAlignment;
+    TMargins8 iMargins;
+    TSize iIconSize;
+    CAknButton::TTextAndIconAlignment iTextAndIconAlignment;
+    TBitFlags iFlags;
+    MTouchFeedback* iFeedback;
+    CFbsBitmap* iPressedDownBmp;
+    CFbsBitmap* iPressedDownBmpMask;
+    CAknResourceProvider* iResourceProvider;
+    };
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::CAknButtonExtension
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+CAknButtonExtension::CAknButtonExtension( CAknButton& aButton )
+    : iButton( aButton ),
+      iTooltipPosition( CAknButton::EPositionTop ),
+      iLongPressTimer( NULL ),
+      iLongPressInterval( KLongPressInterval ),
+      iUnderlineStyle( EUnderlineOff ),
+      iFrameAndCenterIds( 2 ),
+      iVerticalIconAlignment( CAknButton::ECenter ),
+      iHorizontalIconAlignment( CAknButton::ECenter ),
+      iTextAndIconAlignment( CAknButton::EIconBeforeText ),
+      iResourceProvider( 0 )
+    {
+    // default margins, these are applied to both text and icon
+    iMargins.SetAllValuesTo( 
+        AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine().iW / 10 );
+        
+    // default icon size
+    TRect rect( TSize( 100, 100 ) );
+    TAknLayoutRect layoutRect;
+    layoutRect.LayoutRect( rect, 
+        AknLayoutScalable_Avkon::toolbar_button_pane_g10().LayoutLine() );
+    iIconSize = layoutRect.Rect().Size();
+    iFlags.Set( EUseDefaultIconSize );
+    iFlags.Set( EUseDefaultMargins );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::~CAknButtonExtension
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CAknButtonExtension::~CAknButtonExtension()
+    {
+    delete iLongPressTimer;
+    iPictographInterface = NULL; // not owned
+    iFrameAndCenterIds.Close();
+    DeletePressedBmps();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::NewL
+// Symbian two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CAknButtonExtension* CAknButtonExtension::NewL( CAknButton& aButton )
+    {
+    CAknButtonExtension* ext = new ( ELeave ) CAknButtonExtension( aButton );
+    CleanupStack::PushL( ext );
+    ext->ConstructL();
+    CleanupStack::Pop( ext );
+    return ext;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::ConstructL
+// Symbian 2nd stage constructor.
+// -----------------------------------------------------------------------------
+//
+void CAknButtonExtension::ConstructL()
+    {
+    // Normal frame and center
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonNormal );
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterNormal );
+    // Latched frame and center
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonPressed );
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterPressed );
+    // Dimmed frame and center
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonInactive );
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterInactive );
+    // Pressed frame and center
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonPressed );
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterPressed );
+    // Latched dimmed frame and center
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonInactive );
+    iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterInactive );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::StartLongPressTimerL
+// Starts the long press timer. The timer is constructed when used for the
+// first time.
+// -----------------------------------------------------------------------------
+//
+void CAknButtonExtension::StartLongPressTimerL()
+    {
+    if ( !iLongPressTimer )
+        {
+        iLongPressTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+        }
+    else if ( iLongPressTimer->IsActive() )
+        {
+        iLongPressTimer->Cancel();
+        }
+
+    if ( iLongPressInterval > 0 )
+        {
+        iLongPressTimer->Start( iLongPressInterval, iLongPressInterval,
+            TCallBack( ReportLongPressL, this ) );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::ReportLongPressL
+// -----------------------------------------------------------------------------
+//
+TInt CAknButtonExtension::ReportLongPressL( TAny* aThis )
+    {
+    static_cast<CAknButtonExtension*>( aThis )->DoReportLongPressL();
+    return 0;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::DoReportLongPressL
+// -----------------------------------------------------------------------------
+//
+void CAknButtonExtension::DoReportLongPressL()
+    {
+    if ( iLongPressTimer && iLongPressTimer->IsActive() )
+        {
+        iLongPressTimer->Cancel();
+        }
+
+    if ( iButton.Observer() )
+        {
+        iButton.Observer()->HandleControlEventL( &iButton,
+            static_cast<MCoeControlObserver::TCoeEvent>(
+                 CAknButton::ELongPressEvent ) );
+
+        iFlags.Set( ELongPressReported );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::DeletePressedBmps
+// Deletes pressed down bitmaps
+// -----------------------------------------------------------------------------
+//
+void CAknButtonExtension::DeletePressedBmps()
+    {
+    delete iPressedDownBmp;
+    delete iPressedDownBmpMask;
+    iPressedDownBmp = 0;
+    iPressedDownBmpMask = 0;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::FetchProviderPressedBmpsL
+// Fetches bitmaps from provider (if one exists). Returns ETrue if bitmaps were
+// found.
+// -----------------------------------------------------------------------------
+//
+TBool CAknButtonExtension::FetchProviderPressedBmpsL()
+    {
+    TBool bmpsFetched = EFalse;
+    if ( iResourceProvider )
+        {
+        MAknResourceItem* resourceItem = 0;
+
+        // Check if resource provider has item for KPressedFrameId
+        if ( iResourceProvider->GetResourceL( 
+                KPressedFrameId, resourceItem ) != KErrNotFound 
+            && resourceItem )
+            {
+            DeletePressedBmps();
+            static_cast<CAknBitmapResourceItem*>( resourceItem )->GetBitmaps( 
+                iPressedDownBmp, iPressedDownBmpMask );
+            delete resourceItem;
+            
+            // Check if found bitmap size matches with button size
+            if ( iPressedDownBmp 
+                && iPressedDownBmpMask
+                && iPressedDownBmp->SizeInPixels() == iButton.Size() )
+                {
+                bmpsFetched = ETrue;
+                }
+            // If not, delete the fetched bitmaps
+            else
+                {
+                DeletePressedBmps();
+                }
+            }
+        }
+    return bmpsFetched;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknButtonExtension::SetProviderPressedBmpsL
+// Sets bitmaps to provider (if one exists).
+// -----------------------------------------------------------------------------
+//
+void CAknButtonExtension::SetProviderPressedBmpsL()
+    {
+    if ( iResourceProvider )
+        {
+        CAknBitmapResourceItem* resourceItem = 
+            CAknBitmapResourceItem::NewL( KPressedFrameId );
+        resourceItem->SetBitmapsL( iPressedDownBmp, iPressedDownBmpMask );
+        iResourceProvider->SetResourceL( 
+            KPressedFrameId, 
+            static_cast<MAknResourceItem*>( resourceItem ) );
+        }
+    }
+    
+    
+
+//
+TBool CAknButtonExtension::HitRegionContains( const TPoint &aPoint, 
+    const CCoeControl& /*aControl*/ ) const
+    {
+    TBool retval = EFalse;
+    
+    TRAP_IGNORE( retval = iButton.HitAreaContainsL( aPoint, iFlags.IsSet( ECheckHitArea ) ) );
+
+    return retval;
+    }
+
+void CAknButtonExtension::HandleFeedbackAreaChange()
+    {
+    // it is possible that feedback does not exist, eg. while booting.
+    // try getting one, and give up if that fails.
+    if ( !iFeedback )
+        {
+        iFeedback = MTouchFeedback::Instance();
+        }
+    if ( !iFeedback )
+        {
+        return;
+        }
+            
+    if ( iButton.ButtonFlags() & KAknButtonHitTest )
+        {
+        // no registry feedback if shaped buttons are used
+        iFeedback->RemoveFeedbackArea( &iButton, 0 );
+        }
+    else
+        {
+        CFeedbackSpec* spec = CFeedbackSpec::New();
+        if (spec)
+            {
+            spec->AddFeedback( ETouchEventStylusDown, 
+                               ETouchFeedbackBasicButton );
+            spec->AddFeedback( ETouchEventStylusUp, 
+                               ETouchFeedbackBasicButton,
+                               ETouchFeedbackVibra );
+            iFeedback->SetFeedbackArea( &iButton, 0, iButton.Rect(), spec );
+            delete spec;
+            }
+        }
+    }
+
+// ============================ EXTENSION CLASS ================================
+
+NONSHARABLE_CLASS( CAknButtonStateExtension ) : public CBase
+    {
+    friend class CAknButtonState;
+
+public:
+    static CAknButtonStateExtension* NewL();
+    ~CAknButtonStateExtension();
+    
+    void ConfigureExtensionFromResourceL( const TInt aResourceId );
+    void ConfigureExtensionFromResourceL( TResourceReader& aReader );
+    
+private:
+    CAknButtonStateExtension();
+    void ConstructL();
+
+private: // Data
+    TBool iGeneratedDimmedIcon;
+    HBufC* iFilePath;
+    TInt iBmpId;
+    TInt iMaskId;
+    TInt iDimmedBmpId;
+    TInt iDimmedMaskId;
+    TInt iPressedBmpId;
+    TInt iPressedMaskId;
+    TInt iHoverBmpId;
+    TInt iHoverMaskId;
+    TAknsItemID iId;
+    TAknsItemID iDimmedId;
+    TAknsItemID iPressedId;
+    TAknsItemID iHoverId;
+    TScaleMode iScaleMode;
+    };
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CAknButtonStateExtension::CAknButtonStateExtension
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+CAknButtonStateExtension::CAknButtonStateExtension()    
+    : iGeneratedDimmedIcon ( EFalse ), iBmpId( -1 ), iMaskId( -1 ),
+      iDimmedBmpId( -1 ), iDimmedMaskId( -1 ), iPressedBmpId( -1 ),
+      iPressedMaskId( -1 ), iHoverBmpId( -1 ), iHoverMaskId( -1 ),
+      iId( KAknsIIDNone ), iDimmedId( KAknsIIDNone ), 
+      iPressedId( KAknsIIDNone ), iHoverId( KAknsIIDNone ), 
+      iScaleMode( EAspectRatioNotPreserved )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonStateExtension::~CAknButtonStateExtension
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CAknButtonStateExtension::~CAknButtonStateExtension()
+    {
+    delete iFilePath;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonStateExtension::NewL
+// Symbian two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CAknButtonStateExtension* CAknButtonStateExtension::NewL()
+    {
+    CAknButtonStateExtension* ext = new ( ELeave ) CAknButtonStateExtension;
+    CleanupStack::PushL( ext );
+    ext->ConstructL();
+    CleanupStack::Pop( ext );
+    return ext;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonStateExtension::ConstructL
+// Symbian 2nd stage constructor.
+// -----------------------------------------------------------------------------
+//
+void CAknButtonStateExtension::ConstructL()
+    {
+    } //lint !e1762 function cannot be made const
+
+// -----------------------------------------------------------------------------
+// CAknButtonStateExtension::ConfigureExtensionFromResourceL
+// -----------------------------------------------------------------------------
+//    
+void CAknButtonStateExtension::ConfigureExtensionFromResourceL( 
+    const TInt aResourceId )    
+    {
+    
+    if ( aResourceId )
+        {
+        TResourceReader reader;
+        CCoeEnv::Static()->CreateResourceReaderLC( reader, aResourceId );
+        ConfigureExtensionFromResourceL( reader );
+        CleanupStack::PopAndDestroy();
+        }    
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonStateExtension::ConfigureExtensionFromResourceL
+// -----------------------------------------------------------------------------
+//        
+void CAknButtonStateExtension::ConfigureExtensionFromResourceL( 
+    TResourceReader& aReader )
+    {
+    TInt version = aReader.ReadInt8();
+
+    // bmp ids 
+    TInt major = aReader.ReadInt32();
+    TInt minor = aReader.ReadInt32();
+    
+    if ( major != 0 && minor != 0 )
+        {
+        iId.Set( major, minor );    
+        }
+
+    // dimmed ids
+    major = aReader.ReadInt32();
+    minor = aReader.ReadInt32();
+    
+    if ( major != 0 && minor != 0 )
+        {
+        iDimmedId.Set( major, minor );    
+        }
+
+    // pressed ids
+    major = aReader.ReadInt32();
+    minor = aReader.ReadInt32();
+    
+    if ( major != 0 && minor != 0 )
+        {
+        iPressedId.Set( major, minor );    
+        }
+
+    // hover ids
+    major = aReader.ReadInt32();
+    minor = aReader.ReadInt32();
+    
+    if ( major != 0 && minor != 0 )
+        {
+        iHoverId.Set( major, minor );    
+        }
+    }
+    
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::CAknButtonState
+// Constructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButtonState::CAknButtonState( const TInt aFlags ) :
+                                           iFlags( aFlags )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::~CAknButtonState
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButtonState::~CAknButtonState()
+    {
+    delete iIcon;
+    delete iDimmedIcon;
+    delete iPressedIcon;
+    delete iHoverIcon;
+    delete iText;
+    delete iHelpText;
+    delete iExtension;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::ConstructFromResourceL
+// Constructs the button state from the resources
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::ConstructFromResourceL( TResourceReader& aReader )
+    {
+    if ( !iExtension )
+        {
+        iExtension = CAknButtonStateExtension::NewL();
+        }
+
+    // flags
+    iFlags = aReader.ReadInt16();
+
+    // txt
+    TPtrC txt = aReader.ReadTPtrC();
+    SetTextL( txt );
+
+    // helptxt
+    TPtrC helpTxt = aReader.ReadTPtrC();
+    SetHelpTextL( helpTxt );
+
+    if ( iExtension->iFilePath )
+        {
+        delete iExtension->iFilePath;
+        iExtension->iFilePath = NULL;
+        }
+
+    // bmpfile
+    iExtension->iFilePath = aReader.ReadTPtrC().AllocL();
+
+    // bmpid & bmpmask
+    iExtension->iBmpId = aReader.ReadInt16();
+    iExtension->iMaskId = aReader.ReadInt16();
+
+    // dim_bmpid & dim_bmpmask
+    iExtension->iDimmedBmpId = aReader.ReadInt16();
+    iExtension->iDimmedMaskId = aReader.ReadInt16();
+
+    // press_bmpid & press_bmpmask
+    iExtension->iPressedBmpId = aReader.ReadInt16();
+    iExtension->iPressedMaskId = aReader.ReadInt16();
+
+    // hover_bmpid & hover_bmpmask
+    iExtension->iHoverBmpId = aReader.ReadInt16();
+    iExtension->iHoverMaskId = aReader.ReadInt16();
+
+    // extension
+    TInt extensionLink = aReader.ReadInt32();
+    
+    if ( extensionLink != 0 )
+        {
+        iExtension->ConfigureExtensionFromResourceL( extensionLink );
+        }
+        
+    LoadButtonIcon( iIcon );
+    LoadButtonIcon( iDimmedIcon );
+    LoadButtonIcon( iPressedIcon );
+    LoadButtonIcon( iHoverIcon );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::ConstructL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::ConstructL( CGulIcon* aIcon,
+                                           CGulIcon* aDimmedIcon,
+                                           CGulIcon* aPressedIcon,
+                                           CGulIcon* aHoverIcon,
+                                           const TDesC& aText,
+                                           const TDesC& aHelpText )
+    {
+    if ( !iExtension )
+        {
+        iExtension = CAknButtonStateExtension::NewL();
+        }
+
+    SetIcon( aIcon );
+    SetDimmedIcon( aDimmedIcon );
+    SetPressedIcon( aPressedIcon );
+    SetHoverIcon( aHoverIcon );
+    SetTextL( aText );
+    SetHelpTextL( aHelpText );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::
+// Symbian 2nd phase constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::ConstructL( const TDesC& aFilePath,
+                                           const TInt aBmpId,
+                                           const TInt aMaskId,
+                                           const TInt aDimmedBmpId,
+                                           const TInt aDimmedMaskId,
+                                           const TInt aPressedBmpId,
+                                           const TInt aPressedMaskId,
+                                           const TInt aHoverBmpId,
+                                           const TInt aHoverMaskId,
+                                           const TDesC& aText,
+                                           const TDesC& aHelpText,
+                                           const TAknsItemID& aId,
+                                           const TAknsItemID& aDimmedId,
+                                           const TAknsItemID& aPressedId,
+                                           const TAknsItemID& aHoverId )
+    {
+    UpdateIconL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId, 
+        aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId, aId, aDimmedId, 
+        aPressedId, aHoverId ); 
+
+    SetTextL( aText );
+    SetHelpTextL( aHelpText );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::Icon
+// Returns the icon for the normal state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const CGulIcon* CAknButtonState::Icon() const
+    {
+    return iIcon;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::DimmedIcon
+// Returns the icon for the dimmed state
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const CGulIcon* CAknButtonState::DimmedIcon() const
+    {
+    return iDimmedIcon;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::PressedIcon
+// Returns the icon for the pressed but not released state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const CGulIcon* CAknButtonState::PressedIcon() const
+    {
+    return iPressedIcon;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::HoverIcon
+// Returns the icon for the hover state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const CGulIcon* CAknButtonState::HoverIcon() const
+    {
+    return iHoverIcon;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::Text
+// Returns the text inside the button.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC& CAknButtonState::Text() const
+    {
+    if ( iText )
+        {
+        return *iText;
+        }
+    else
+        {
+        return KNullDesC();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::HelpText
+// Returns the text inside the help note.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC& CAknButtonState::HelpText() const
+    {
+    if ( iHelpText )
+        {
+        return *iHelpText;
+        }
+    else
+        {
+        return KNullDesC();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::Flags
+// Returns the state flags.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknButtonState::Flags() const
+    {
+    return iFlags;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::SetIcon
+// Sets the icon for the normal state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::SetIcon( CGulIcon* aIcon )
+    {
+    ReplaceIcon( iIcon, aIcon );
+    
+    if ( iExtension->iGeneratedDimmedIcon )
+        {
+        TRAP_IGNORE( CreateAndSetDimmedIconL( iDimmedIcon, iIcon, 
+            iExtension->iScaleMode ) );   
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::SetDimmedIcon
+// Sets the icon for the dimmed state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::SetDimmedIcon( CGulIcon* aDimmedIcon )
+    {
+    ReplaceIcon( iDimmedIcon, aDimmedIcon );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::SetPressedIcon
+// Sets the icon for the pressed but not released state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::SetPressedIcon( CGulIcon* aPressedIcon )
+    {
+    ReplaceIcon( iPressedIcon, aPressedIcon );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::SetHoverIcon
+// Sets the icon for the hover state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::SetHoverIcon( CGulIcon* aHoverIcon )
+    {
+    ReplaceIcon( iHoverIcon, aHoverIcon );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::ReplaceIcon
+// Replaces the given icon with a new one. If the original icon had its size set
+// then the new icon is scaled to that size.
+// -----------------------------------------------------------------------------
+//
+void CAknButtonState::ReplaceIcon( CGulIcon*& aIcon, CGulIcon* aNewIcon )
+    {
+        ReplaceIconStatic( aIcon, aNewIcon, iExtension->iScaleMode );
+    }
+
+    
+// -----------------------------------------------------------------------------
+// CAknButtonState::SetTextL
+// Sets the text inside the button
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::SetTextL( const TDesC& aText )
+    {
+    delete iText;
+    iText = NULL;
+
+    iText = aText.AllocL();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::SetHelpTextL
+// Sets the text inside the help note
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::SetHelpTextL( const TDesC& aHelpText )
+    {
+    delete iHelpText;
+    iHelpText = NULL;
+
+    iHelpText = aHelpText.AllocL();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::
+// Sets state flags.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::SetFlags( const TInt aFlags )
+    {
+    iFlags = aFlags;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::UpdateIconL
+// Updates button icons. 
+// -----------------------------------------------------------------------------
+void CAknButtonState::UpdateIconL( const TDesC& aFilePath, 
+                                   const TInt aBmpId, 
+                                   const TInt aMaskId,
+                                   const TInt aDimmedBmpId,
+                                   const TInt aDimmedMaskId,
+                                   const TInt aPressedBmpId,
+                                   const TInt aPressedMaskId,
+                                   const TInt aHoverBmpId,
+                                   const TInt aHoverMaskId,
+                                   const TAknsItemID& aId,
+                                   const TAknsItemID& aDimmedId,
+                                   const TAknsItemID& aPressedId,
+                                   const TAknsItemID& aHoverId )
+
+    {
+    if ( !iExtension )
+        {
+        iExtension = CAknButtonStateExtension::NewL();
+        }
+
+    if ( iExtension->iFilePath )
+        {        
+        delete iExtension->iFilePath;
+        iExtension->iFilePath = NULL;
+        }
+
+    // try to save some ram by defaulting to avkon bitmap file
+    if ( aFilePath != KAvkonBitmapFile )
+        {
+        iExtension->iFilePath = aFilePath.AllocL();    
+        }
+    
+    iExtension->iBmpId = aBmpId;
+    iExtension->iMaskId = aMaskId;
+    iExtension->iDimmedBmpId = aDimmedBmpId;
+    iExtension->iDimmedMaskId = aDimmedMaskId;
+    iExtension->iPressedBmpId = aPressedBmpId;
+    iExtension->iPressedMaskId = aPressedMaskId;
+    iExtension->iHoverBmpId = aHoverBmpId;
+    iExtension->iHoverMaskId = aHoverMaskId;
+    iExtension->iId = aId;
+    iExtension->iDimmedId = aDimmedId;
+    iExtension->iPressedId = aPressedId;
+    iExtension->iHoverId = aHoverId;
+
+    LoadButtonIcon( iIcon );
+    LoadButtonIcon( iDimmedIcon );
+    LoadButtonIcon( iPressedIcon );
+    LoadButtonIcon( iHoverIcon );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::SizeChanged
+// Scales function graphics to the given size
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButtonState::SizeChanged( const TRect& aRect,
+                                            TScaleMode aScaleMode )
+    {
+    ScaleIcons( aRect.Size(), aScaleMode );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::HasText
+// Returns ETrue if the text inside button is not empty or space.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknButtonState::HasText() const
+    {
+    if ( !iText )
+        return EFalse;
+
+    TBool ret = EFalse;
+    for ( TInt i = 0; i < iText->Des().Length(); i++ )
+        {
+        TChar c ( (iText->Des())[i]);
+
+//        TChar::TCategory cat = c.GetCategory();
+        if ( !c.IsSpace() /*&& cat != TChar::ECoCategory*/ )
+            {
+            // not space and not private use char
+            ret = ETrue;
+            break;
+            }
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::HasHelp
+// Returns ETrue if the text inside the help note is not empty or space.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknButtonState::HasHelp() const
+    {
+    if ( !iHelpText )
+        return EFalse;
+
+    TBool ret = EFalse;
+    for ( TInt i = 0; i < iHelpText->Des().Length(); i++ )
+        {
+        TChar c( ( *iHelpText )[i] );
+
+//        TChar::TCategory cat = c.GetCategory();
+        if ( !c.IsSpace() /*&& cat != TChar::ECoCategory*/ )
+            {
+            // not space and not private use char
+            ret = ETrue;
+            break;
+            }
+        }
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::HandleResourceChange
+// Handles changes in state's environment.
+// -----------------------------------------------------------------------------
+//
+void CAknButtonState::HandleResourceChange( TInt aType )
+    {
+    // Update icons if skin is changed. KEikDynamicLayoutVariantSwitch event is
+    // handled via SizeChanged.
+    if ( aType == KAknsMessageSkinChange )
+        {
+        LoadButtonIcon( iIcon );
+        LoadButtonIcon( iDimmedIcon );
+        LoadButtonIcon( iPressedIcon );
+        LoadButtonIcon( iHoverIcon );
+
+        // generated dimmed state icon has to be regenerated
+        if ( iExtension->iGeneratedDimmedIcon )
+            {
+            TRAP_IGNORE( CreateAndSetDimmedIconL( iDimmedIcon, iIcon, 
+                iExtension->iScaleMode ) );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::SetIconScaleMode
+// Sets default scaling mode.
+// -----------------------------------------------------------------------------
+//
+void CAknButtonState::SetIconScaleMode( const TScaleMode aScaleMode )
+    {
+    iExtension->iScaleMode = aScaleMode;
+    }
+    
+// -----------------------------------------------------------------------------
+// CAknButtonState::CreateButtonIconL
+// Creates one of the icons
+// -----------------------------------------------------------------------------
+//
+void CAknButtonState::CreateButtonIconL( CGulIcon*& aIcon,
+                                         const TDesC& aFilePath,
+                                         TInt aBmpId,
+                                         TInt aMaskId,
+                                         const TAknsItemID& aId ) const
+    {
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+    if ( aIcon )
+        {
+        if ( ( aId != KAknsIIDNone && skin ) || aBmpId != -1 )
+            {
+            delete aIcon;
+            aIcon = NULL;
+            }
+        }
+
+    if ( aFilePath == KNullDesC || aBmpId == -1 )
+        {
+        if ( aId != KAknsIIDNone && skin )
+            {
+            aIcon = AknsUtils::CreateGulIconL( skin, aId, EFalse );
+            }
+        }
+    else
+        {
+        if ( aId != KAknsIIDNone && skin )
+            {
+            aIcon = AknsUtils::CreateGulIconL( skin, aId, aFilePath, aBmpId,
+                                               aMaskId);
+            }
+        else
+            {
+            CFbsBitmap* bmp;
+            CFbsBitmap* mask;
+            AknIconUtils::CreateIconLC( bmp, mask, aFilePath, aBmpId, aMaskId);
+            aIcon = CGulIcon::NewL( bmp, mask ); // ownership passed
+            CleanupStack::Pop( 2 );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::LoadButtonIcon
+// Reloads one button icon.
+// -----------------------------------------------------------------------------
+//
+void CAknButtonState::LoadButtonIcon( CGulIcon*& aIcon ) const
+    {
+    TSize iconSize( 0, 0 );
+    
+    if ( aIcon && aIcon->Bitmap() )
+        {
+        iconSize = aIcon->Bitmap()->SizeInPixels();
+        }
+
+    TInt bmpId = -1;
+    TInt maskId = -1;
+    TAknsItemID skinId = KAknsIIDNone;
+
+    if ( &aIcon == &iIcon )
+        {
+        bmpId = iExtension->iBmpId;
+        maskId = iExtension->iMaskId;
+        skinId = iExtension->iId;
+        }
+    else if ( &aIcon == &iPressedIcon )
+        {
+        bmpId = iExtension->iPressedBmpId;
+        maskId = iExtension->iPressedMaskId;
+        skinId = iExtension->iPressedId;
+        }
+    else if ( &aIcon == &iDimmedIcon )
+        {
+        bmpId = iExtension->iDimmedBmpId;
+        maskId = iExtension->iDimmedMaskId;
+        skinId = iExtension->iDimmedId;
+        }
+    else if ( &aIcon == &iHoverIcon )
+        {
+        bmpId = iExtension->iHoverBmpId;
+        maskId = iExtension->iHoverMaskId;
+        skinId = iExtension->iHoverId;
+        }
+
+    TPtrC16 bitmapFile;
+    
+    if ( iExtension->iFilePath )
+        {
+        bitmapFile.Set( *iExtension->iFilePath );
+        }
+    else
+        {
+        bitmapFile.Set( KAvkonBitmapFile );
+        }
+
+    // aIcon is set to NULL if the next call fails
+    TRAP_IGNORE( CreateButtonIconL( aIcon, bitmapFile, bmpId, maskId, skinId ) );
+            
+    if ( aIcon && iconSize != TSize( 0, 0 ) )
+        {
+        ResizeIcon( aIcon, iconSize, iExtension->iScaleMode );
+        }
+    }                                          
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::ScaleIcons
+// Sets the size for bitmap and mask
+// -----------------------------------------------------------------------------
+//
+TInt CAknButtonState::ScaleIcons( const TSize& aSize, TScaleMode aScaleMode )
+    {
+    TInt retval = ResizeIcon( iIcon, aSize, aScaleMode );
+    retval = Min( retval, ResizeIcon( iPressedIcon, aSize, aScaleMode ) );
+    
+    // Generated dimmed state icon has to be regenerated
+    if ( iExtension->iGeneratedDimmedIcon )
+        {
+        TRAP_IGNORE ( CreateAndSetDimmedIconL( iDimmedIcon, iIcon, aScaleMode ) );
+        }
+    else
+        {
+        retval = Min( retval, ResizeIcon( iDimmedIcon, aSize, aScaleMode ) );
+        }
+        
+    return retval;        
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::ScaleMode
+// Getter for the current scalemode of the state
+// -----------------------------------------------------------------------------
+TScaleMode CAknButtonState::ScaleMode() const
+    {
+    return iExtension->iScaleMode;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::SetGeneratedDimmedIcon
+// Whether the dimmed icon of the state is created by owning Button
+// -----------------------------------------------------------------------------    
+void CAknButtonState::SetGeneratedDimmedIcon( TBool aDimmedIconCreatedByButton )
+    {
+    iExtension->iGeneratedDimmedIcon = aDimmedIconCreatedByButton;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButtonState::Extension
+// -----------------------------------------------------------------------------
+//
+CAknButtonStateExtension* CAknButtonState::Extension() const
+    {
+    return iExtension;
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewL
+// Two-phased constructor.
+// Constructs an empty button
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewL()
+    {
+    CAknButton* self = NewLC();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewLC
+// Two-phased constructor.
+// Constructs an empty button
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewLC()
+    {
+    CAknButton* self = new (ELeave) CAknButton( 0 );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    AKNTASHOOK_ADDL( self, "CAknButton" );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewL
+// Two-phased constructor.
+// Constructs the button from resources.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewL( TResourceReader& aReader )
+    {
+    CAknButton* self = NewLC( aReader );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewLC
+// Two-phased constructor.
+// Constructs the button from resources.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewLC( TResourceReader& aReader )
+    {
+    CAknButton* self = new( ELeave ) CAknButton( 0 );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    self->ConstructFromResourceL( aReader );
+    AKNTASHOOK_ADDL( self, "CAknButton" );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewL
+// Two-phased constructor.
+// Constructs the button from resources.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewL( const TInt aResourceId )
+    {
+    CAknButton* self = NewLC( aResourceId );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewLC
+// Two-phased constructor.
+// Constructs the button from resources.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewLC( const TInt aResourceId )
+    {
+    CAknButton* self = new (ELeave) CAknButton( 0 );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    self->ConstructFromResourceL( aResourceId );
+    AKNTASHOOK_ADDL( self, "CAknButton" );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewL
+// Two-phased constructor.
+// Constructs one state button.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewL( CGulIcon* aIcon,
+                                       CGulIcon* aDimmedIcon,
+                                       CGulIcon* aPressedIcon,
+                                       CGulIcon* aHoverIcon,
+                                       const TDesC& aText,
+                                       const TDesC& aHelpText,
+                                       const TInt aButtonFlags,
+                                       const TInt aStateFlags )
+    {
+    CAknButton* self = NewLC( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon,
+        aText, aHelpText, aButtonFlags, aStateFlags );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewLC
+// Two-phased constructor.
+// Constructs one state button.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewLC( CGulIcon* aIcon,
+                                        CGulIcon* aDimmedIcon,
+                                        CGulIcon* aPressedIcon,
+                                        CGulIcon* aHoverIcon,
+                                        const TDesC& aText,
+                                        const TDesC& aHelpText,
+                                        const TInt aButtonFlags,
+                                        const TInt aStateFlags )
+    {
+    CAknButton* self = new (ELeave) CAknButton( aButtonFlags );
+    CleanupStack::PushL( self );
+    self->ConstructL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText,
+                      aHelpText, aStateFlags );
+    AKNTASHOOK_ADDL( self, "CAknButton" );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewL
+// Two-phased constructor.
+// Constructs one state button.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewL( const TDesC& aFilePath,
+                                       const TInt aBmpId,
+                                       const TInt aMaskId,
+                                       const TInt aDimmedBmpId,
+                                       const TInt aDimmedMaskId,
+                                       const TInt aPressedBmpId,
+                                       const TInt aPressedMaskId,
+                                       const TInt aHoverBmpId,
+                                       const TInt aHoverMaskId,
+                                       const TDesC& aText,
+                                       const TDesC& aHelpText,
+                                       const TInt aButtonFlags,
+                                       const TInt aStateFlags,
+                                       const TAknsItemID& aId,
+                                       const TAknsItemID& aDimmedId,
+                                       const TAknsItemID& aPressedId,
+                                       const TAknsItemID& aHoverId )
+    {
+    CAknButton* self = NewLC( aFilePath, aBmpId, aMaskId, aDimmedBmpId,
+        aDimmedMaskId, aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId,
+        aText, aHelpText, aButtonFlags, aStateFlags, aId, aDimmedId, aPressedId,
+        aHoverId );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NewLC
+// Two-phased constructor.
+// Constructs one state button.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton* CAknButton::NewLC( const TDesC& aFilePath,
+                                        const TInt aBmpId,
+                                        const TInt aMaskId,
+                                        const TInt aDimmedBmpId,
+                                        const TInt aDimmedMaskId,
+                                        const TInt aPressedBmpId,
+                                        const TInt aPressedMaskId,
+                                        const TInt aHoverBmpId,
+                                        const TInt aHoverMaskId,
+                                        const TDesC& aText,
+                                        const TDesC& aHelpText,
+                                        const TInt aButtonFlags,
+                                        const TInt aStateFlags,
+                                        const TAknsItemID& aId,
+                                        const TAknsItemID& aDimmedId,
+                                        const TAknsItemID& aPressedId,
+                                        const TAknsItemID& aHoverId )
+    {
+    CAknButton* self = new (ELeave) CAknButton( aButtonFlags );
+    CleanupStack::PushL( self );
+    self->ConstructL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId,
+        aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId,
+        aText, aHelpText, aStateFlags, aId, aDimmedId, aPressedId, aHoverId );
+    AKNTASHOOK_ADDL( self, "CAknButton" );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::CAknButton
+// C++ constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton::CAknButton( const TInt aFlags )
+    : iFlags( aFlags ),
+      iVerticalAlignment( ECenter ),
+      iHorizontalAlignment( CGraphicsContext::ECenter ),
+      iTextColorTableId( KAknsIIDQsnTextColors ), // TODO
+      iTextColorIndex( EAknsCIQsnTextColorsCG80 ), // TODO
+      iScaleMode( EAspectRatioNotPreserved ),
+      iHelpNoteWaitInterval( KTimeoutBeforeHelpNote ),
+      iHelpNoteInViewInterval( KTimeoutInViewHelpNote ),
+      iKeyRepeatDelay( KKeyRepeatDelay ),
+      iKeyRepeatInterval( KKeyRepeatInterval )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ConstructL
+// Symbian 2nd phase constructor.
+// Constructor for the empty button.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::ConstructL()
+    {
+    TRgb textColor;
+    
+    if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor, 
+        iTextColorTableId, iTextColorIndex ) == KErrNone )
+        {
+        OverrideColorL( EColorButtonText, textColor );
+        }
+
+    if ( !iStates )
+        {
+        iStates = new ( ELeave ) CArrayPtrFlat<CAknButtonState>( 2 );
+        }
+
+    if ( !iBgContext )
+        {
+        iBgContext = CAknsFrameBackgroundControlContext::NewL(
+            KAknsIIDNone, TRect(), TRect(), EFalse );
+        }
+  
+    if ( !iExtension )
+        {
+        iExtension = CAknButtonExtension::NewL( *this );
+        }
+
+    if ( iFlags & KAknButtonHitTest )
+        {
+        SetHitTest( iExtension );
+        }        
+
+    if ( iFlags & KAknButtonNoFrame )
+        {
+        iExtension->iMargins.SetAllValuesTo( 0 );
+        }
+    
+    if ( iFlags & KAknButtonTextLeft )
+        {
+        iHorizontalAlignment = CGraphicsContext::ELeft;
+        }
+    iExtension->HandleFeedbackAreaChange();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ConstructL
+// Symbian 2nd phase constructor for 1 state button.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::ConstructL( CGulIcon* aIcon,
+                                      CGulIcon* aDimmedIcon,
+                                      CGulIcon* aPressedIcon,
+                                      CGulIcon* aHoverIcon,
+                                      const TDesC& aText,
+                                      const TDesC& aHelpText,
+                                      const TInt aStateFlags )
+    {
+    ConstructL();
+    AddStateL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText, aHelpText,
+               aStateFlags);
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ConstructL
+// Symbian 2nd phase constructor for 1 state button
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::ConstructL( const TDesC& aFilePath,
+                                      const TInt aBmpId,
+                                      const TInt aMaskId,
+                                      const TInt aDimmedBmpId,
+                                      const TInt aDimmedMaskId,
+                                      const TInt aPressedBmpId,
+                                      const TInt aPressedMaskId,
+                                      const TInt aHoverBmpId,
+                                      const TInt aHoverMaskId,
+                                      const TDesC& aText,
+                                      const TDesC& aHelpText,
+                                      const TInt aStateFlags,
+                                      const TAknsItemID& aId,
+                                      const TAknsItemID& aDimmedId,
+                                      const TAknsItemID& aPressedId,
+                                      const TAknsItemID& aHoverId )
+    {
+    ConstructL();
+    AddStateL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId,
+        aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId,
+        aText, aHelpText, aStateFlags, aId, aDimmedId, aPressedId, aHoverId );
+    }
+
+// -----------------------------------------------------------------------------
+// Destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButton::~CAknButton()
+    {
+    AKNTASHOOK_REMOVE();
+    if ( iStates )
+        {
+        iStates->ResetAndDestroy();
+        delete iStates;
+        }
+
+    // MTouchFeedback instance lives in AknAppUi. AppUi might be
+    // destroyed when this destructor is running. If there is no
+    // MTouchFeedback instance there is no need to remove any areas
+    // either, as these are ( naturally ) destroyed with
+    // MTouchFeedback instance.
+    MTouchFeedback* fb = MTouchFeedback::Instance();
+    if ( fb )
+        {
+        fb->RemoveFeedbackForControl( this );
+        }
+
+    delete iBgContext;
+    delete iDimmedHelpText;
+    delete iHelpNote;
+    delete iKeyRepeatTimer;
+    delete iExtension;
+    iFont = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ActivateL
+// Sets control as ready to be drawn.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::ActivateL()
+    {
+    // request for drag events outside the button
+    SetAllowStrayPointers();
+    // Requesting pointer drag events
+    EnableDragEvents();
+    
+    CAknControl::ActivateL();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ConstructFromResourceL
+// Constructs controls from a resource file.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::ConstructFromResourceL( TResourceReader& aReader )
+    {
+    if ( !iExtension )
+        {
+        iExtension = CAknButtonExtension::NewL( *this );
+        }
+
+    // flags
+    iFlags = aReader.ReadInt16();
+
+    // state index
+    SetStateIndexL( aReader.ReadInt16() );
+
+    // read states
+    const TInt stateCount = aReader.ReadInt16();
+    for ( TInt ii = 0; ii < stateCount; ii++ )
+        {
+        CAknButtonState* state = new (ELeave) CAknButtonState( 0 );
+        CleanupStack::PushL( state );
+        state->ConstructFromResourceL( aReader );
+        iStates->AppendL( state );
+        CleanupStack::Pop( state );
+        }
+
+    aReader.ReadInt32(); // extension link, not used currently
+
+    if ( iFlags & KAknButtonHitTest )
+        {
+        SetHitTest( iExtension );
+        }        
+
+    if ( iFlags & KAknButtonNoFrame )
+        {
+        iExtension->iMargins.SetAllValuesTo( 0 );
+        }
+
+    if ( iFlags & KAknButtonTextLeft )
+        {
+        iHorizontalAlignment = CGraphicsContext::ELeft;
+        }
+    iExtension->HandleFeedbackAreaChange();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::HandleResourceChange
+// Handles a change to the control's resources.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::HandleResourceChange( TInt aType )
+    {
+    // No need to call base class implementation since CountComponentControls
+    // is always zero.
+        
+    if ( aType == KAknsMessageSkinChange || aType == KEikDynamicLayoutVariantSwitch )
+        {
+        if ( iButtonPressed )
+            {
+            ResetState();
+            DrawDeferred();
+            }
+        }
+        
+    // UIFW informs control about lost focus when moved to background.
+    // Rest of pointer events are no longer forvarded to control.    
+    if ( aType == KAknMessageFocusLost || aType == KEikMessageFadeAllWindows )
+        {
+        if (iHelpNote)
+            {
+            iHelpNote->HideInfoPopupNote();
+            }
+        
+        if (iButtonPressed)
+            {
+            ResetState();
+            DrawDeferred();
+            }
+        return;
+        }
+    
+    if ( iStates )
+        {
+        for ( TInt i = 0; i < iStates->Count(); ++i )
+            {
+            CAknButtonState* state = iStates->At( i );
+            
+            if ( state )
+                {
+                state->HandleResourceChange( aType );
+                }
+            }
+        }
+
+    if ( aType == KAknsMessageSkinChange )
+        {
+        TRgb textColor;
+        
+        if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor, 
+                iTextColorTableId, iTextColorIndex ) == KErrNone )
+            {
+            TRAP_IGNORE( OverrideColorL( EColorButtonText, textColor ) );
+            }
+    
+        // generated pressed frame has to be regenerated
+        if ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame )
+            {
+            iExtension->DeletePressedBmps();
+            TRAP_IGNORE( CreatePressedDownFrameL() );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::MinimumSize
+// Returns the control's minimum required size. This doesn't include highlight
+// area.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TSize CAknButton::MinimumSize()
+    {
+    // by default, margins decide the absolute minimum size...
+    TInt width = iExtension->iMargins.iLeft + iExtension->iMargins.iRight;
+    TInt height = iExtension->iMargins.iTop + iExtension->iMargins.iBottom;
+    
+    // ...but possible frames may enlarge the required area...
+    if ( !( iFlags & KAknButtonNoFrame ) )
+        {
+        TAknLayoutRect tl;
+        tl.LayoutRect( Rect(), 
+            AknLayoutScalable_Avkon::toolbar_button_pane_g2().LayoutLine() );
+
+        TAknLayoutRect br;
+        br.LayoutRect( Rect(),
+            AknLayoutScalable_Avkon::toolbar_button_pane_g5().LayoutLine() );
+
+        TInt frameWidth = tl.Rect().Width() + br.Rect().Width();
+        TInt frameHeight = tl.Rect().Height() + br.Rect().Height();
+        
+        if ( !( iFlags & KAknButtonTextInsideFrame ) )
+            {
+            width = Max( width, frameWidth );
+            height = Max( height, frameHeight );
+            }
+        else
+            {
+            width = frameWidth;
+            height = frameHeight;
+            }
+        }
+    
+    // ...as well as evil flags
+    if ( iStates && ( iFlags & KAknButtonSizeFitText ) )
+        {
+        if ( !iFont )
+            {
+            iFont = iCoeEnv->NormalFont();
+            }
+
+        height += iFont->FontMaxHeight();
+
+        TInt textWidth = 0;
+        
+        // choose the longest one
+        for ( TInt ii = 0; ii < iStates->Count(); ii++ )
+            {
+            CAknButtonState* state = iStates->At( ii );
+            if ( state && state->HasText() )
+                {
+                TInt tempWidth = iFont->TextWidthInPixels( state->Text() );
+                textWidth = Max( textWidth, tempWidth );
+                }
+            }
+            
+        width += textWidth;
+        }
+    
+    return TSize( width, height );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetDimmed
+// Sets button dimmed. Doesn't redraw.
+// Button needs to get pointer events even if it is dimmed to be able to show
+// help text in dimmed state. So, the CCoeControl::SetDimmed(TBool) cannot be
+// used to set button dimmed if the help text is used.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetDimmed( TBool aDimmed )
+    {
+    if ( aDimmed )
+        {
+        StopKeyRepeatTimer();
+        StopLongPressTimer();
+        HideHelp();
+        iButtonPressed = EFalse;
+        }
+    
+    if ( aDimmed )
+        {
+        iExtension->iFlags.Set( CAknButtonExtension::EDimmed );
+        }
+    else
+        {
+        iExtension->iFlags.Clear( CAknButtonExtension::EDimmed );
+        }
+    if ( iExtension->iFeedback )
+        {
+        if ( aDimmed )
+            {
+            iExtension->iFeedback->MoveFeedbackAreaToFirstPriority( this, 0 );
+            }        
+        iExtension->iFeedback->EnableFeedbackForControl( this, !aDimmed && IsVisible() );
+        }
+
+    TBool hasHelp ( EFalse );
+    
+    for ( TInt i = 0; i < iStates->Count(); ++i )
+        {
+        CAknButtonState* state = iStates->At( i );
+        
+        if ( state )
+            {
+            if ( !state->iDimmedIcon )
+                {
+                TRAP_IGNORE ( CreateAndSetDimmedIconL( state->iDimmedIcon, 
+                    state->iIcon, state->ScaleMode() ) );
+                state->SetGeneratedDimmedIcon( ETrue );
+                }
+            
+            if ( state->HasHelp() )
+                {
+                hasHelp = ETrue;
+                }
+            }
+        }
+    // None of states has help text, CCoeControl::SetDimmed can be used        
+    if ( !hasHelp )
+        {
+        CCoeControl::SetDimmed( aDimmed );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::OfferKeyEventL
+// Handles key events.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TKeyResponse CAknButton::OfferKeyEventL( const TKeyEvent& aKeyEvent,
+                                                  TEventCode aType )
+    {
+    if ( IsDimmed() )
+        return EKeyWasNotConsumed;
+
+    if ( aType == EEventKeyDown && IsVisible() )
+        {
+        HideHelp(); // hides help text as soon as the first key event comes.
+        }
+
+    if ( aKeyEvent.iScanCode == EStdKeyDevice3 ||
+         aKeyEvent.iScanCode == EStdKeyEnter )
+        {
+        if ( aType == EEventKeyDown )
+            {
+            iKeyDownReported = ETrue;
+
+            if ( !iButtonPressed )
+                {
+                // show press changes
+                iButtonPressed = ETrue;
+                if ( NeedsRedrawWhenPressed() )
+                    {
+                    DrawNow();
+                    }
+                }
+
+            if ( iFlags & KAknButtonReportOnKeyDown )
+                {
+                ChangeState( ETrue );
+                if ( Observer() )
+                    {
+                    Observer()->HandleControlEventL( this,
+                        MCoeControlObserver::EEventStateChanged );
+                    }
+                }
+
+            if ( iFlags & KAknButtonKeyRepeat )
+                {
+                iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
+                StartKeyRepeatTimerL();
+                }
+
+            if ( iFlags & KAknButtonReportOnLongPress )
+                {
+                iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
+                iExtension->StartLongPressTimerL();
+                }
+            }
+
+        else if ( aType == EEventKeyUp )
+            {
+            if ( iButtonPressed )
+                {
+                iButtonPressed = EFalse;
+
+                if ( NeedsRedrawWhenPressed() )
+                    {
+                    DrawNow();
+                    }
+                }
+
+            StopKeyRepeatTimer();
+            StopLongPressTimer();
+
+            // The state is not changed, if it is already changed on key
+            // down event, or if a long press or a key repeat event is
+            // already reported to the observer.
+            if ( !( iFlags & KAknButtonReportOnKeyDown ) &&
+                 !( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) &&
+                 !( iExtension->iFlags.IsSet( CAknButtonExtension::EKeyRepeatEventReported ) ) &&
+                 iKeyDownReported )
+                {
+                ChangeState( ETrue );
+                if ( Observer() )
+                    {
+                    Observer()->HandleControlEventL( this,
+                        MCoeControlObserver::EEventStateChanged );
+                    }
+                }
+            else
+                {
+                if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && iKeyDownReported )
+                    {
+                    Observer()->HandleControlEventL( this, 
+                        static_cast<MCoeControlObserver::TCoeEvent>( 
+                        CAknButton::ELongPressEndedEvent ) );
+                    }
+                iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
+                iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
+                }
+
+            if ( iKeyDownReported && RequestExit() && Observer() )
+                {
+                Observer()->HandleControlEventL( this,
+                    MCoeControlObserver::EEventRequestExit );
+                }
+
+            iKeyDownReported = EFalse;
+            }
+        // we don't want aKeyEvent to go somewhere else :)
+        return EKeyWasConsumed;
+        }
+
+    return EKeyWasNotConsumed;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::MakeVisible
+// Sets this control as visible or invisible.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::MakeVisible( TBool aVisible )
+    {
+    if ( aVisible != IsVisible() )
+        {
+        CAknControl::MakeVisible( aVisible );
+        if ( iExtension->iFeedback )
+            {
+            if ( aVisible )
+                {
+                iExtension->iFeedback->MoveFeedbackAreaToFirstPriority( this, 
+                                                                        0 );
+                }
+            iExtension->iFeedback->EnableFeedbackForControl( 
+                    this, 
+                    aVisible && !IsDimmed() );
+            }
+
+        CAknButtonState* state = State();
+        if ( !aVisible && state && state->HasHelp() )
+            {
+            HideHelp();
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::PrepareForFocusLossL
+// This function is called by the dialog framework immediately before it removes
+// keyboard focus from a control within a dialog.
+// Currently has empty implementation.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::PrepareForFocusLossL()
+    {
+    CAknControl::PrepareForFocusLossL(); // empty but it can be changed... :)
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::PrepareForFocusGainL
+// Prepares the control for gaining focus.
+// Must be used before calling SetFocus() function in case when help note
+// should be shown.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::PrepareForFocusGainL()
+    {
+    CAknControl::PrepareForFocusGainL(); // empty but it can be changed... :)
+
+    CAknButtonState* state = State();
+    if ( state && state->HasHelp() && IsVisible() && !IsFocused() )
+        {
+        iShowHelp = ETrue;
+        }
+    else
+        {
+        iShowHelp = EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SizeChanged
+// Responds to size changes to sets the size and position of the contents of
+// this control.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SizeChanged()
+    {
+    // If default icon size from LAF is used re-request that, otherwise trust
+    // that size will be updated by the utilising application.
+    if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultIconSize ) )
+        {
+        if ( iFlags & KAknButtonNoFrame && !State()->HasText() )
+            {
+            iExtension->iIconSize = Size();
+            }
+        else
+            {
+            TAknLayoutRect layoutRect;
+            layoutRect.LayoutRect( Rect(), 
+                AknLayoutScalable_Avkon::toolbar_button_pane_g10().LayoutLine() );
+            iExtension->iIconSize = layoutRect.Rect().Size();
+            }
+        }
+
+    // Update margins from LAF if default values are used. This also refreshes
+    // icon size in case it overlaps margins.
+    CalculateDefaultMargins();
+        
+    // scale all icons
+    ScaleIcons();
+
+    // Pressed down frame has to be regenerated
+    if ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame ) 
+       {
+        TRAP_IGNORE( CreatePressedDownFrameL() );
+        }
+
+    iExtension->HandleFeedbackAreaChange();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::HandlePointerEventL
+// Handles pointer events.
+// @param aPointerEvent is the pointer event.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+    {
+    if ( AknLayoutUtils::PenEnabled() )
+        {
+        if ( !IsVisible() )
+            {
+            if ( iButtonPressed )
+                {
+                ResetState();               
+                }
+            return;
+            }
+        TBool buttonEvent( TouchArea().Contains( aPointerEvent.iPosition ) );
+        CAknButtonState* state = State();
+        if ( !state )
+            {
+            return;
+            }            
+        
+        if ( ( iFlags & KAknButtonHitTest ) && 
+             !HitAreaContainsL( aPointerEvent.iPosition, EFalse ) )
+            {
+            buttonEvent = EFalse;
+            }
+        
+        TBool redrawNeeded(EFalse);
+        switch ( aPointerEvent.iType )
+            {
+            case TPointerEvent::EButton1Down:
+                {
+                if ( buttonEvent && IsDimmed() )
+                    {
+                    ShowHelpL();
+                    }
+                else if ( buttonEvent )
+                    {
+                    if ( !iButtonPressed )
+                        {
+                        iButtonPressed = ETrue;
+                        // feedback/basic on down event, if hit test is
+                        // used. Area registry is used for rectangular
+                        // buttons
+                        if ( ( iFlags & KAknButtonHitTest ) 
+                           && !IsDimmed() 
+                           && iExtension->iFeedback )
+                            {
+                            iExtension->iFeedback->InstantFeedback(
+                                                    this,
+                                                    ETouchFeedbackBasicButton,
+                                                    aPointerEvent );
+                            }
+
+                        // make a mark so that we can later test that the button press comes from pointer event
+                        iButtonPressed |= KPointerFlag;
+
+                        // Redraw button, if needed
+                        if ( NeedsRedrawWhenPressed() )
+                            {
+                            redrawNeeded = ETrue;
+                            }
+
+                        ShowHelpL();
+                        }
+
+                    if ( iFlags & KAknButtonReportOnKeyDown )
+                        {
+                        // State is changed on button down event
+                        ChangeState( EFalse );
+                        redrawNeeded = EFalse;
+                        DrawNow();  //Redraw before noticing the observer for observer might open dialog                        
+                        if ( Observer() )
+                            {
+                            Observer()->HandleControlEventL( this,
+                                MCoeControlObserver::EEventStateChanged );
+                            }
+                        }
+
+                    if ( iFlags & KAknButtonKeyRepeat )
+                        {
+                        // Key repeat
+                        iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
+                        StartKeyRepeatTimerL();
+                        }
+
+                    if ( iFlags & KAknButtonReportOnLongPress )
+                        {
+                        iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
+                        iExtension->StartLongPressTimerL();
+                        }
+                    }
+                break;
+                }
+
+            case TPointerEvent::EDrag:
+                {
+                iNumberOfDragEvents++;
+                if ( iNumberOfDragEvents >= KDragEventSensitivity  )
+                    {
+                    iNumberOfDragEvents = 0;
+
+                    // Pointer is dragged out of the button area
+                    if ( !buttonEvent && iButtonPressed )
+                        {
+                        // Redraw button, if needed
+                        if ( NeedsRedrawWhenPressed() )
+                            {
+                            iButtonPressed = EFalse;
+                            redrawNeeded = ETrue;
+                            }
+                        iButtonPressed = EFalse;
+
+                        StopKeyRepeatTimer();
+                        StopLongPressTimer();
+
+                        if ( !IsFocused() )
+                            {
+                            HideHelp();
+                            }
+                        if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() )
+                            {
+                            Observer()->HandleControlEventL( this, 
+                                static_cast<MCoeControlObserver::TCoeEvent>( 
+                                CAknButton::ELongPressEndedEvent ) );
+                            }
+                        iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
+                        }
+
+                    // Pointer is dragged back into button area
+                    else if ( buttonEvent && !iButtonPressed && !IsDimmed() )
+                        {
+                        iButtonPressed = ETrue;
+
+                        // Redraw button, if needed
+                        if ( NeedsRedrawWhenPressed() )
+                            {
+                            redrawNeeded = ETrue;
+                            }
+
+                        if ( iFlags & KAknButtonKeyRepeat )
+                            {
+                            // Continue key repeat
+                            StartKeyRepeatTimerL();
+                            }
+
+                        if ( ( iFlags & KAknButtonReportOnLongPress ) &&
+                             !( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) )
+                            {
+                            // Restart long press timer
+                            StartLongPressTimerL();
+                            }
+                        }
+                    }
+                break;
+                }
+
+            case TPointerEvent::EButton1Up:
+                {
+                iNumberOfDragEvents = 0;
+                HideHelp();
+
+                StopKeyRepeatTimer();
+                StopLongPressTimer();
+
+                if ( iButtonPressed )
+                    {
+                    // Redraw button, if needed
+                    if ( NeedsRedrawWhenPressed() )
+                        {
+                        iButtonPressed = EFalse;
+                        if ( ! ( buttonEvent && iStates->Count() > 1 ) ) 
+                            {
+                            redrawNeeded = ETrue;
+                            }
+                        }
+                    iButtonPressed = EFalse;
+                    }
+
+                TBool hasDrawn( EFalse );
+                if ( buttonEvent && !IsDimmed() )
+                    {
+                        // feedback/BasicButton on up event, if hit test is
+                        // used. Area registry is used for rectangular
+                        // buttons
+                        if ( ( iFlags & KAknButtonHitTest ) 
+                           && iExtension->iFeedback )
+                            {
+                            iExtension->iFeedback->InstantFeedback(
+                                                    this,
+                                                    ETouchFeedbackBasicButton,
+                                                    ETouchFeedbackVibra,
+                                                    aPointerEvent );
+                            }
+                    // The state is not changed, if it is already changed on key
+                    // down event, or if a long press or a key repeat event is
+                    // already reported to the observer.
+                    if ( !( iFlags & KAknButtonReportOnKeyDown ) &&
+                         !( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) &&
+                         !( iExtension->iFlags.IsSet( CAknButtonExtension::EKeyRepeatEventReported ) ) )
+                        {
+                        ChangeState( EFalse );
+                        if ( !hasDrawn )
+                        	{
+	                        DrawNow();
+	                        hasDrawn = ETrue;
+                        	}
+                        
+                        if ( Observer() )
+                            {
+                            Observer()->HandleControlEventL( this,
+                                MCoeControlObserver::EEventStateChanged );
+                            }
+                        }
+                   else
+                        {
+                        if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() )
+                            {
+                            if ( redrawNeeded && !hasDrawn )
+                            	{
+                            	DrawNow();
+                            	hasDrawn = ETrue;
+                            	}
+                            Observer()->HandleControlEventL( this, 
+                                static_cast<MCoeControlObserver::TCoeEvent>( 
+                                CAknButton::ELongPressEndedEvent ) );
+                            }
+                        iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
+                        iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
+                        }
+
+                    if ( RequestExit() && Observer() )
+                        {
+                        if ( redrawNeeded && !hasDrawn )
+                        	{
+                        	DrawNow();
+                        	hasDrawn = ETrue;
+                        	}
+                        Observer()->HandleControlEventL( this,
+                            MCoeControlObserver::EEventRequestExit );
+                        }
+                    }
+                        
+                if ( !buttonEvent && !IsDimmed() && Observer() )
+                   {
+                   if ( redrawNeeded && !hasDrawn )
+                	   {
+                	   DrawNow();
+                	   hasDrawn = ETrue;
+                	   }
+                   Observer()->HandleControlEventL( this,
+                        MCoeControlObserver::EEventRequestCancel );
+                        
+                    if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) )
+                        {
+                        Observer()->HandleControlEventL( this, 
+                            static_cast<MCoeControlObserver::TCoeEvent>( 
+                            CAknButton::ELongPressEndedEvent ) );
+                        iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
+                        iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
+                        }                        
+                   }
+                if ( hasDrawn )
+                	{
+                	redrawNeeded = EFalse;
+                	}
+                break;
+                }
+
+            default:
+                break;
+            }
+            if (redrawNeeded)    
+                {
+                DrawNow();
+                }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::PositionChanged
+// 
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::PositionChanged()
+    {
+    if ( iExtension ) iExtension->HandleFeedbackAreaChange();
+    CAknControl::PositionChanged();
+    }
+    
+// -----------------------------------------------------------------------------
+// CAknButton::FocusChanged
+// This function is called whenever a control gains or loses focus.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::FocusChanged( TDrawNow aDrawNow )
+    {
+    if ( !IsFocused() && iButtonPressed )
+        {
+        iButtonPressed = EFalse; 
+        iKeyDownReported = EFalse; 
+        }
+    if ( IsVisible() )
+        {
+        
+        if ( IsFocused() && iShowHelp )
+            {
+            TRAP_IGNORE( ShowHelpL() );
+            }
+        else
+            {
+            HideHelp();
+
+            // Stop the timers if active
+            StopLongPressTimer();
+            StopKeyRepeatTimer();
+            }
+        if ( !IsBackedUp() && aDrawNow ) 
+            {
+            DrawNow();
+            }
+        }
+
+    iShowHelp = EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ExtensionInterface
+// For future extensions
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void* CAknButton::ExtensionInterface( TUid /*aInterface*/ )
+    {
+    return NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::Draw
+// Draw a control called by window server.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::Draw( const TRect& /*aRect*/ ) const
+    {
+    TRect rect( Rect() );
+    TAknLayoutRect centerLayout;
+    centerLayout.LayoutRect( rect,
+        AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
+    TRect innerRect( centerLayout.Rect() );
+    TRect highlightRect( HighlightRect() );
+    CWindowGc& gc = SystemGc();
+    CAknButtonState* state = State();
+
+    // Skin ids are determined here (a bit too early than necessary) so that 
+    // we can avoid doing the same thing in DrawMaskedL.
+    if ( !( iFlags & KAknButtonNoFrame ) )
+        {
+        TInt frameIdIndex = KFrameId;
+
+        if ( iButtonPressed )
+            {
+            frameIdIndex = KPressedFrameId;
+            }
+        else if ( state && state->Flags() & KAknButtonStateHasLatchedFrame )
+            {
+            if ( IsDimmed() )
+                {
+                // dimmed latched frame
+                frameIdIndex = KLatchedDimmedFrameId;
+                }
+            else
+                {
+                // latched down
+                frameIdIndex = KLatchedFrameId;
+                }
+            }
+        else if ( IsDimmed())
+            {
+            // dimmed frame
+            frameIdIndex = KDimmedFrameId;
+            }
+
+        if ( SkinIID( frameIdIndex ) != KAknsIIDNone )
+            {
+            iBgContext->SetFrame( SkinIID( frameIdIndex ) );
+            iBgContext->SetCenter( SkinIID( ++frameIdIndex ) );
+            iBgContext->SetFrameRects( rect, innerRect );
+            }
+        }
+
+    if ( !iExtension->iFlags.IsSet( CAknButtonExtension::EUseAdditionalMask ) )
+        {
+        MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+        MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
+
+        if ( !( iFlags & KAknButtonNoFrame ) )
+            {
+            // frame graphics
+            if ( !AknsDrawUtils::Background( skin, iBgContext, NULL, gc,
+                  rect, KAknsDrawParamNoClearUnderImage ) )
+                {
+                gc.SetBrushColor( KRgbRed );
+                gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+                gc.DrawRect( rect );
+                }
+                
+
+            if ( IsFocused() && !highlightRect.IsEmpty() )
+                {
+                iBgContext->SetFrame( KAknsIIDQsnFrButtonHighlight ); 
+                iBgContext->SetCenter( KAknsIIDQsnFrButtonHighlightCenter ); 
+                iBgContext->SetFrameRects( rect, innerRect );
+
+                // frame graphics
+                if ( !AknsDrawUtils::Background( skin, iBgContext, NULL, gc,
+                      rect, KAknsDrawParamNoClearUnderImage ) )
+                    {
+                    gc.SetBrushColor( KRgbRed );
+                    gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+                    gc.DrawRect( rect );
+                    }
+                }
+            }
+        else if ( ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame ) &&
+                    ( iButtonPressed ||
+                    ( state && state->Flags() & KAknButtonStateHasLatchedFrame &&
+                    !IsDimmed() ) ) )
+            {
+            gc.BitBltMasked( Rect().iTl, iExtension->iPressedDownBmp, 
+                             TRect( TPoint(0,0), Size() ), 
+                             iExtension->iPressedDownBmpMask, EFalse ); 
+            }
+        }
+    else if ( !( iFlags & KAknButtonNoFrame ) )
+        {
+        if ( AknsUtils::SkinInstance() )
+            {
+            AknsDrawUtils::Background( AknsUtils::SkinInstance(), iBgContext, this, gc,
+                   rect, KAknsDrawParamNoClearUnderImage );
+            }
+        }
+
+    TBool hasIcon = ( GetCurrentIcon() != NULL );
+    TBool hasText = state && state->HasText();
+
+    if ( hasIcon && hasText )
+        {
+        DrawTextAndIconButton( gc );
+        }
+    else if ( hasText )
+        {
+        DrawTextButton( gc );
+        }
+    else if ( hasIcon )
+        {
+        DrawIconButton( gc );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ConstructFromResourceL
+// Constructs controls from a resource file.
+// @param aResourceId is the ID for this component's resource
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::ConstructFromResourceL( const TInt aResourceId )
+    {
+    if ( aResourceId )
+        {
+        TResourceReader reader;
+        iCoeEnv->CreateResourceReaderLC( reader, aResourceId );
+        ConstructFromResourceL( reader );
+        CleanupStack::PopAndDestroy();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetCurrentState
+// Sets active button state index
+// @param aStateIndex is the index inside state array
+// @param aDrawNow should be ETrue for the button to be redrawn
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetCurrentState( const TInt aStateIndex,
+                                           const TBool aDrawNow )
+    {
+    TInt newIndex = -1;
+    if ( iStates && iStates->Count() )
+        {
+        newIndex = aStateIndex % iStates->Count();
+        }
+
+    TRAP_IGNORE( SetStateIndexL( newIndex ) );
+    if ( aDrawNow )
+        {
+        DrawNow();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::AddStateL
+// Adds one more state for the button to the end of state array.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::AddStateL( CGulIcon* aIcon,
+                                     CGulIcon* aDimmedIcon,
+                                     CGulIcon* aPressedIcon,
+                                     CGulIcon* aHoverIcon,
+                                     const TDesC& aText,
+                                     const TDesC& aHelpText,
+                                     const TInt aStateFlags )
+    {
+    CAknButtonState* state = new (ELeave) CAknButtonState( aStateFlags );
+    CleanupStack::PushL( state );
+    state->ConstructL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText,
+                       aHelpText );
+    iStates->AppendL( state );
+    CleanupStack::Pop( state );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::AddStateL
+// Adds one more state for the button to the end of state array.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::AddStateL( const TDesC& aFilePath,
+                                     const TInt aBmpId,
+                                     const TInt aMaskId,
+                                     const TInt aDimmedBmpId,
+                                     const TInt aDimmedMaskId,
+                                     const TInt aPressedBmpId,
+                                     const TInt aPressedMaskId,
+                                     const TInt aHoverBmpId,
+                                     const TInt aHoverMaskId,
+                                     const TDesC& aText,
+                                     const TDesC& aHelpText,
+                                     const TInt aStateFlags,
+                                     const TAknsItemID& aId,
+                                     const TAknsItemID& aDimmedId,
+                                     const TAknsItemID& aPressedId,
+                                     const TAknsItemID& aHoverId )
+    {
+    CAknButtonState* state = new (ELeave) CAknButtonState( aStateFlags );
+    CleanupStack::PushL( state );
+    state->ConstructL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId,
+         aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId,
+         aText, aHelpText, aId, aDimmedId, aPressedId, aHoverId );
+    iStates->AppendL( state );
+    CleanupStack::Pop( state );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknButton::AddStateL
+// Adds one more state for the button to the end of state array.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::AddStateL( CGulIcon* aIcon,
+                            CGulIcon* aDimmedIcon,
+                            CGulIcon* aPressedIcon,
+                            CGulIcon* aHoverIcon,
+                            const TDesC& aText,
+                            const TDesC& aHelpText,
+                            const TInt aStateFlags,
+                            const TInt aCommandId )
+    {
+    CAknCommandButtonState* state =
+        new (ELeave) CAknCommandButtonState( aStateFlags, aCommandId );
+    CleanupStack::PushL( state );
+    state->ConstructL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText,
+                       aHelpText );
+    iStates->AppendL( state );
+    CleanupStack::Pop( state );
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetFlags
+// Sets the button flags
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetButtonFlags( const TInt aFlags )
+    {
+    if ( !(iFlags & KAknButtonNoFrame ) && aFlags & KAknButtonNoFrame )
+        {
+        iExtension->iMargins.SetAllValuesTo( 0 );
+        }
+    if ( aFlags & KAknButtonHitTest )
+        {
+        SetHitTest( iExtension );
+        iExtension->HandleFeedbackAreaChange();
+        }
+    if ( aFlags & KAknButtonNoFrame && aFlags & KAknButtonPressedDownFrame )
+        {
+        TRAP_IGNORE ( CreatePressedDownFrameL() );
+        }
+    iFlags = aFlags;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetFrameAndCenterIds
+// Sets specified frame IDs. Can be used when default frame is not suitable.
+// Use KAknsIIDNone value in case when some frame or center drawing is not
+// needed or KAknsIIDDefault when the default button frame should be used.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetFrameAndCenterIds( 
+    const TAknsItemID& aFrameId,
+    const TAknsItemID& aCenterId,
+    const TAknsItemID& aLatchedFrameId,
+    const TAknsItemID& aLatchedCenterId,
+    const TAknsItemID& aDimmedFrameId,
+    const TAknsItemID& aDimmedCenterId,
+    const TAknsItemID& aPressedFrameId,
+    const TAknsItemID& aPressedCenterId,
+    const TAknsItemID& aLatchedDimmedFrameId,
+    const TAknsItemID& aLatchedDimmedCenterId  )
+    {
+    RArray<TAknsItemID>& skinIds = iExtension->iFrameAndCenterIds;
+    
+    if ( aFrameId != KAknsIIDDefault )
+        {
+        skinIds[KFrameId] = aFrameId;
+        }
+    if ( aCenterId != KAknsIIDDefault )
+        {
+        skinIds[KCenterId] = aCenterId;
+        }
+    if ( aLatchedFrameId != KAknsIIDDefault )
+        {
+        skinIds[KLatchedFrameId] = aLatchedFrameId;
+        }
+    if ( aLatchedCenterId != KAknsIIDDefault )
+        {
+        skinIds[KLatchedCenterId] = aLatchedCenterId;
+        }
+    if ( aDimmedFrameId != KAknsIIDDefault )
+        {
+        skinIds[KDimmedFrameId] = aDimmedFrameId;
+        }
+    if ( aDimmedCenterId != KAknsIIDDefault )
+        {
+        skinIds[KDimmedCenterId] = aDimmedCenterId;
+        }
+    if ( aPressedFrameId != KAknsIIDDefault )
+        {
+        skinIds[KPressedFrameId] = aPressedFrameId;
+        }
+    if ( aPressedCenterId != KAknsIIDDefault )
+        {
+        skinIds[KPressedCenterId] = aPressedCenterId;
+        }
+    if ( aLatchedDimmedFrameId != KAknsIIDDefault )
+        {
+        skinIds[KLatchedDimmedFrameId] = aLatchedDimmedFrameId;
+        }
+    if ( aLatchedDimmedCenterId != KAknsIIDDefault )
+        {
+        skinIds[KLatchedDimmedCenterId] = aLatchedDimmedCenterId;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetBackgroundIds
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetBackgroundIds( 
+    const TAknsItemID& aBackgroundId,
+    const TAknsItemID& aLatchedBackgroundId,
+    const TAknsItemID& aDimmedBackgroundId,
+    const TAknsItemID& aPressedBackgroundId,
+    const TAknsItemID& aLatchedDimmedBackgroundId )
+    {
+    CAknButton::SetFrameAndCenterIds( aBackgroundId, aBackgroundId,
+                                      aLatchedBackgroundId, 
+                                      aLatchedBackgroundId,
+                                      aDimmedBackgroundId, aDimmedBackgroundId,
+                                      aPressedBackgroundId, 
+                                      aPressedBackgroundId,
+                                      aLatchedDimmedBackgroundId, 
+                                      aLatchedDimmedBackgroundId );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetTextFont
+// Sets some specific text font.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetTextFont( const CFont* aFont )
+    {
+    iFont = aFont;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetTextColorIds
+// Sets the color table and color index for the button text.
+// It will be used on button drawing if color of the text shouldn't be taken
+// from text layout.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetTextColorIds( const TAknsItemID& aTextColorTableId,
+                                           const TInt aTextColorIndex )
+    {
+    iTextColorTableId = aTextColorTableId;
+    iTextColorIndex = aTextColorIndex;
+
+    TRgb textColor;
+    
+    if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor, 
+        iTextColorTableId, iTextColorIndex ) == KErrNone )
+        {
+        TRAP_IGNORE( OverrideColorL( EColorButtonText, textColor ) );
+        DrawDeferred();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetTextHorizontalAlignment
+// Sets the horizontal alignment for the text inside the button. It will be used
+// if alignment shouldn't be taken from text layout. By default it will be
+// centered.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetTextHorizontalAlignment(
+    const CGraphicsContext::TTextAlign aHorizontalAlignment )
+    {
+    iHorizontalAlignment = aHorizontalAlignment;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetTextVerticalAlignment
+// Sets the vertical alignment for the text inside the button. It will be used
+// if alignment shouldn't be taken from text layout. By default it will be
+// centered.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetTextVerticalAlignment(
+    const CAknButton::TAlignment aVerticalAlignment )
+    {
+    iVerticalAlignment = aVerticalAlignment;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetTextUnderlineStyle
+// Sets the text underline style for the text inside the button.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetTextUnderlineStyle( TFontUnderline aUnderlineStyle )
+    {
+    iExtension->iUnderlineStyle = aUnderlineStyle;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetIconScaleMode
+// Sets the scale mode for the icon inside the button. The default is
+// EAspectRatioNotPreserved.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetIconScaleMode( const TScaleMode aScaleMode )
+    {
+    iScaleMode = aScaleMode;
+    
+    for ( TInt i = 0; i < iStates->Count(); ++i )
+        {
+        CAknButtonState* state = iStates->At( i );
+        
+        if ( state )
+            {
+            state->SetIconScaleMode( aScaleMode );
+            }
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CAknButton::SetIconHorizontalAlignment
+// Sets the horizontal alignment for the icon inside the button.
+// The default is ECenter
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetIconHorizontalAlignment( 
+            const CAknButton::TAlignment aHorizontalAlignment )
+    {
+    iExtension->iHorizontalIconAlignment = aHorizontalAlignment;
+    }
+// -----------------------------------------------------------------------------
+// CAknButton::SetIconVerticalAlignment
+// Sets the vertical alignment for the icon inside the button.
+// The default is ECenter
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetIconVerticalAlignment( 
+            const CAknButton::TAlignment aVerticalAlignment )
+    {
+    iExtension->iVerticalIconAlignment = aVerticalAlignment;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetTextAndIconAlignment
+// Sets the icon and text alignment for the button having both
+// The default is EIconBeforeText
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetTextAndIconAlignment ( 
+            const CAknButton::TTextAndIconAlignment aAlignment )
+    {
+    iExtension->iTextAndIconAlignment = aAlignment;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetHelpNoteTimeouts
+// Sets the delay before the help text is shown and also specifies the time for
+// how long help text is visible.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetHelpNoteTimeouts( const TInt aBeforeTimeout,
+                                               const TInt aInViewTimeout )
+    {
+    if ( aBeforeTimeout >= 0 )
+        {
+        iHelpNoteWaitInterval = aBeforeTimeout;
+        }
+    if ( aInViewTimeout >= 0 )
+        {
+        iHelpNoteInViewInterval = aInViewTimeout;
+        }
+
+    if(iHelpNote)
+        {
+        iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval );
+        iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetKeyRepeatInterval
+// Sets the interval for the key repeat.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetKeyRepeatInterval( const TInt aKeyRepeatDelay,
+        const TInt aKeyRepeatInterval )
+    {
+    // Convert time intervals to microseconds
+    iKeyRepeatDelay = aKeyRepeatDelay * 1000;
+    iKeyRepeatInterval = aKeyRepeatInterval * 1000;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetLongPressInterval
+// Sets the interval for the long presses.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetLongPressInterval( const TInt aLongPressInterval )
+    {
+    iExtension->iLongPressInterval = aLongPressInterval * 1000;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::StateIndex
+// Returns the index of the current button state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknButton::StateIndex() const
+    {
+    return iStateIndex;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::EnablePictographsL
+// Enables pictograph drawing in the button text.
+// Only effective in Japanese variant.
+// By default, it is disabled.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::EnablePictographsL( CAknPictographInterface& aInterface )
+    {
+    iExtension->iPictographInterface = &aInterface;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::DisablePictographs
+// Disables pictograph drawing in the button text.
+// Only effective in Japanese variant.
+// By default, it is disabled.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::DisablePictographs()
+    {
+    iExtension->iPictographInterface = NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetHighlightRect
+// It will change the default highlight rectangular around
+// the focused button
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetHighlightRect( const TRect& aRect )
+    {
+    iHighlightRect = aRect;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::HighlightRect
+// Returns highlight rectangular around button
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TRect CAknButton::HighlightRect() const
+    {
+    if ( IsNonFocusing() )
+        {
+        return TRect();
+        }
+    else
+        {
+        return iHighlightRect;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetTooltipPosition
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetTooltipPosition( const TTooltipPosition aPosition )
+    {
+    iExtension->iTooltipPosition = aPosition;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::RequestExit
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetRequestExit( const TBool aRequestExit )
+    {
+    if (aRequestExit)
+        {
+        iFlags |= KAknButtonRequestExitOnButtonUpEvent;
+        }
+    else
+        {
+        iFlags &= ~KAknButtonRequestExitOnButtonUpEvent;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::IsDimmed
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CAknButton::IsDimmed() const
+    {
+    return iExtension->iFlags.IsSet( CAknButtonExtension::EDimmed );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetHelpTextL
+// Sets the help text for dimmed button
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetDimmedHelpTextL( const TDesC& aHelpText )
+    {
+    delete iDimmedHelpText;
+    iDimmedHelpText = NULL;
+
+    iDimmedHelpText = aHelpText.AllocL();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ChangeState
+// Changes the state of the button
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknButton::ChangeState( TBool aDrawNow )
+    {
+    if ( !iStates || !iStates->Count() )
+        {
+        return -1;
+        }
+
+    TInt newIndex( iStateIndex + 1 );
+
+    if ( iStateIndex == iStates->Count() - 1 )
+        {
+        newIndex = 0;
+        }
+    
+    TRAP_IGNORE( SetStateIndexL( newIndex ) );
+    
+    if ( aDrawNow )
+        {
+        DrawNow();
+        }
+
+    return iStateIndex;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::GetCurrentText
+// Returns the texts which will be displayed inside the button for the current
+// state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC& CAknButton::GetCurrentText() const
+    {
+    CAknButtonState* state = State();
+    if ( state )
+        {
+        return state->Text();
+        }
+    else
+        {
+        return KNullDesC();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::GetCurrentIcon
+// Returns the right icon for the current state
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const CGulIcon* CAknButton::GetCurrentIcon() const
+    {
+    CAknButtonState* state = State();
+    const CGulIcon* icon = NULL;
+    if ( state )
+        {
+        if ( iButtonPressed && state->PressedIcon() )
+            {
+            icon = state->PressedIcon();
+            }
+        else if ( IsDimmed() && state->DimmedIcon() )
+            {
+            icon = state->DimmedIcon();
+            }
+        else
+            {
+            icon = state->Icon();
+            }
+        }
+    return icon;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ShowHelpL
+// Shows help text for a certain period of time.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::ShowHelpL()
+    {
+    if ( !IsVisible() )
+        {
+        return;
+        }
+    if ( !iHelpNote )
+        {
+        iHelpNote = CAknInfoPopupNoteController::NewL();
+        
+        iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval );
+        iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval );
+        iHelpNote->SetTooltipModeL( ETrue );
+        }
+        
+    if ( IsDimmed() && iDimmedHelpText )
+        {
+        iHelpNote->SetTextL( *iDimmedHelpText );
+        }
+    else
+        {
+        CAknButtonState* state = State();
+        if ( state && state->HasHelp() )
+            {
+            iHelpNote->SetTextL( state->HelpText() );
+            }
+        else
+            {
+            return;
+            }
+        }
+
+    UpdateTooltipPosition();
+    iHelpNote->ShowInfoPopupNote();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::HideHelp
+// Hides help text after certain interval.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::HideHelp()
+    {
+    if(iHelpNote)
+        {
+        iHelpNote->HideInfoPopupNote();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::State
+// Returns current state.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButtonState* CAknButton::State() const
+    {
+    return State( iStateIndex );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::State
+// Returns the state under the specified index.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAknButtonState* CAknButton::State( const TInt aStateIndex ) const
+    {
+    CAknButtonState* state = NULL;
+    if ( iStates && aStateIndex >= 0 && aStateIndex < iStates->Count() )
+        {
+        state = iStates->At( aStateIndex );
+        }
+    return state;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::Flags
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknButton::ButtonFlags() const
+    {
+    return iFlags;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetMargins
+// Sets button's marginals.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::SetMargins( const TMargins8& aMargins )
+    {
+    iExtension->iFlags.Clear( CAknButtonExtension::EUseDefaultMargins );
+    iExtension->iMargins = aMargins;
+    SizeChanged();
+    }
+    
+// -----------------------------------------------------------------------------
+// CAknButton::SetIconSize
+// Sets button's icon size.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CAknButton::SetIconSize( const TSize& aSize )
+    {
+    iExtension->iFlags.Clear( CAknButtonExtension::EUseDefaultIconSize );
+    iExtension->iIconSize = aSize;
+    
+    return ScaleIcons();
+    }
+       
+// -----------------------------------------------------------------------------
+// CAknButton::ResetState
+// Sets button to unpressed state. 
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAknButton::ResetState( )
+    {
+    StopKeyRepeatTimer();
+    StopLongPressTimer();
+    iButtonPressed = EFalse;
+    HideHelp();
+    if ( iExtension )
+        {
+        if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() )
+            {
+            TRAP_IGNORE( Observer()->HandleControlEventL( this, 
+            static_cast<MCoeControlObserver::TCoeEvent>( CAknButton::ELongPressEndedEvent ) ) );
+            }
+        
+        iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported );
+        iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported );
+        } 
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::CalculateDefaultMargins
+// Calculates default margins.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::CalculateDefaultMargins()
+    {
+    if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultMargins ) )
+        {
+        if ( !( iFlags & KAknButtonNoFrame ) )
+            {
+            TAknLayoutRect layoutRect;
+            layoutRect.LayoutRect( Rect(), 
+                AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine() );
+            iExtension->iMargins.SetAllValuesTo( 
+                layoutRect.Rect().Size().iWidth / 10 ); // always square 
+            }
+        }
+
+    if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultIconSize ) )
+        {
+        // ensure that icon size never exceeds the space inside margins
+        TRect rectInsideMargins( iExtension->iMargins.InnerRect( Rect() ) );
+        
+        if ( rectInsideMargins.Size().iWidth < iExtension->iIconSize.iWidth )
+            {
+            iExtension->iIconSize.iWidth = 
+                Max( 0, rectInsideMargins.Size().iWidth );
+            }
+            
+        if ( rectInsideMargins.Size().iHeight < iExtension->iIconSize.iHeight )
+            {
+            iExtension->iIconSize.iHeight = 
+                Max( 0, rectInsideMargins.Size().iHeight );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ScaleIcons
+// Scales all icons.
+// -----------------------------------------------------------------------------
+//
+TInt CAknButton::ScaleIcons()
+    {
+    TInt retval = KErrNone;
+    
+    for ( TInt i = 0; i < iStates->Count(); ++i )
+        {
+        CAknButtonState* state = iStates->At( i );
+        
+        if ( state )
+            {
+            retval = Min( retval, state->ScaleIcons( iExtension->iIconSize,
+                                                     iScaleMode ) );
+            if ( iExtension->iFlags.IsSet( CAknButtonExtension::EDimmed ) && 
+                !state->iDimmedIcon &&
+                state->iIcon )
+                {
+                TRAP_IGNORE( CreateAndSetDimmedIconL( state->iDimmedIcon, 
+                    state->iIcon, state->ScaleMode() ) );
+                }
+            }
+        }
+        
+    return retval;        
+    }
+    
+// -----------------------------------------------------------------------------
+// CAknButton::DrawTextButton
+// Continues drawing of the button which has only text
+// -----------------------------------------------------------------------------
+//
+void CAknButton::DrawTextButton( CWindowGc& aGc ) const
+    {
+    CAknButtonState* state = State();
+    if ( !state || !state->HasText() )
+        return;
+
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+    TRect textRect = iExtension->iMargins.InnerRect( Rect() );
+
+    if ( !( iFlags & KAknButtonNoFrame ) && 
+         ( iFlags & KAknButtonTextInsideFrame ) )
+        {
+        TAknLayoutRect center;
+        center.LayoutRect( Rect(), 
+            AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
+
+        textRect = center.Rect();
+        }
+
+    aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
+
+    TRgb penColor;
+    TRgb brushColor;
+    GetTextColors( penColor, brushColor ); 
+    aGc.SetPenColor( penColor ); 
+    aGc.SetBrushColor( brushColor ); 
+
+    const CFont* font = iFont;
+    if ( !font )
+        {
+        font = iCoeEnv->NormalFont();
+        }
+    aGc.UseFont( font );
+
+    aGc.SetUnderlineStyle( iExtension->iUnderlineStyle );
+
+    // buffer for visually ordered text
+    TBuf<255 + KAknBidiExtraSpacePerLine> visualText; 
+    TInt clipWidth = textRect.Width();
+
+    // bidi processing - using AknBidiTextUtils.
+    AknBidiTextUtils::ConvertToVisualAndClip(
+        state->Text(),
+        visualText,
+        *font,
+        clipWidth,
+        clipWidth );
+
+    TInt baselineOffset = 0;
+    switch ( iVerticalAlignment )
+        {
+        case ETop:
+            baselineOffset = font->AscentInPixels();
+            break;
+
+        case EBottom:
+            baselineOffset = textRect.Height();
+            break;
+
+        default:  // centered
+            baselineOffset = font->AscentInPixels() +
+                           ( textRect.Height() - font->AscentInPixels() ) / 2;
+        }
+
+    CGraphicsContext::TTextAlign horAlignment = iHorizontalAlignment;
+
+    aGc.DrawText( visualText, textRect, baselineOffset, horAlignment );
+    if ( iExtension->iPictographInterface )
+        {
+        // For Japanese variant only
+        iExtension->iPictographInterface->Interface()->DrawPictographsInText(
+            aGc, *font, visualText, textRect, baselineOffset, horAlignment );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::DrawIconButton
+// Continues drawing of the button which has only an icon in it
+// -----------------------------------------------------------------------------
+//
+void CAknButton::DrawIconButton( CWindowGc& aGc ) const
+    {
+    TRect iconRect( iExtension->iMargins.InnerRect( Rect() ) );
+    
+    aGc.SetBrushStyle( CGraphicsContext::ENullBrush );
+
+    const CGulIcon* icon = GetCurrentIcon();
+    if ( !icon )
+        return;
+
+    CFbsBitmap* buttonBmp = icon->Bitmap();
+    CFbsBitmap* buttonMask = icon->Mask();
+
+    TPoint iconPoint;
+    TSize iconSize ( buttonBmp->SizeInPixels());
+
+    switch ( iExtension->iHorizontalIconAlignment )
+        {
+        case ERight:
+            {
+            iconPoint.iX = iconRect.iBr.iX - iconSize.iWidth;                        
+            }
+            break;  
+
+        case ECenter:
+            {
+            iconPoint.iX = iconRect.iTl.iX + 
+            (iconRect.Width() / 2 - iconSize.iWidth / 2 );
+            } 
+            break;
+            
+        case ELeft:
+            {
+            iconPoint.iX = iconRect.iTl.iX;
+            }
+            break; 
+        
+        default:
+            // Should never come here
+            break;
+        }
+
+    switch ( iExtension->iVerticalIconAlignment )
+        {
+        case ETop:
+            {
+            iconPoint.iY = iconRect.iTl.iY;
+            }
+            break;
+        
+        case ECenter:
+            {
+            iconPoint.iY = iconRect.iTl.iY +
+            ( iconRect.Height() / 2 - iconSize.iHeight / 2 );
+            }
+            break;
+          
+        case EBottom:
+            {
+            iconPoint.iY = iconRect.iBr.iY - iconSize.iHeight;
+            }
+            break;
+            
+        default:
+            // Should never come here
+            break;
+        }
+
+    if( buttonBmp && buttonMask )
+        {
+        aGc.BitBltMasked( iconPoint, buttonBmp,
+            iconRect.Size(), buttonMask, ETrue );
+        }
+    else if ( buttonBmp )
+        {
+        aGc.BitBlt( iconPoint, buttonBmp, iconRect.Size() );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::DrawTextAndIconButton
+// Continues drawing of the button which has both text and icon
+// -----------------------------------------------------------------------------
+//
+void CAknButton::DrawTextAndIconButton( CWindowGc& aGc ) const
+    {
+    CAknButtonState* state = State();
+    if ( !state  || !state->HasText() )
+        {
+        return;
+        }
+    
+    const CGulIcon* icon = GetCurrentIcon();
+    if ( !icon )
+        {
+        return;
+        }
+
+    TRect rect = iExtension->iMargins.InnerRect( Rect() );
+    TRect iconRect;
+    TRect textRect;
+    
+    if ( !( iFlags & KAknButtonNoFrame ) &&
+          ( iFlags & KAknButtonTextInsideFrame ))
+        {
+        TAknLayoutRect centerLayout;
+        centerLayout.LayoutRect( rect,
+        AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
+        rect = centerLayout.Rect();
+        }
+
+    CFbsBitmap* buttonBmp = icon->Bitmap();
+    CFbsBitmap* buttonMask = icon->Mask();
+    TSize iconSize ( buttonBmp->SizeInPixels());
+    
+    // Set rects for icon and text according to their positioning
+    // First icon rect according to icon size - rest is for text
+    
+    switch ( iExtension->iTextAndIconAlignment )        
+        {
+        case EIconBeforeText:
+            if ( AknLayoutUtils::LayoutMirrored() ) 
+                {
+                textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+                rect.iBr.iX - iconSize.iWidth, rect.iBr.iY);
+                iconRect.SetRect( rect.iTl.iX + 
+                    rect.Width() -iconSize.iWidth,
+                rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );    
+                }
+            else
+                {
+                iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+                rect.iTl.iX + iconSize.iWidth, rect.iBr.iY);
+                textRect.SetRect( rect.iTl.iX + iconSize.iWidth,
+                rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );    
+                }
+            
+            break;
+            
+        case EIconAfterText:
+            if ( AknLayoutUtils::LayoutMirrored() ) 
+                {
+                iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+                rect.iTl.iX + iconSize.iWidth, rect.iBr.iY);
+                textRect.SetRect( rect.iTl.iX + iconSize.iWidth,
+                rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );    
+                }
+            else
+                {
+                textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+                rect.iBr.iX - iconSize.iWidth, rect.iBr.iY);
+                iconRect.SetRect( rect.iTl.iX + 
+                    rect.Width() -iconSize.iWidth,
+                rect.iTl.iY, rect.iBr.iX, rect.iBr.iY );
+                }
+            break;
+        
+        case EIconOverText:
+            iconRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+            rect.iBr.iX, rect.iTl.iY + iconSize.iHeight );
+            textRect.SetRect( rect.iTl.iX, rect.iTl.iY + iconSize.iHeight,
+            rect.iBr.iX, rect.iBr.iY );
+            break;
+            
+        case EIconUnderText:
+            textRect.SetRect( rect.iTl.iX, rect.iTl.iY,
+            rect.iBr.iX, rect.iBr.iY - iconSize.iHeight );
+            iconRect.SetRect( rect.iTl.iX, rect.iBr.iY - iconSize.iHeight,
+            rect.iBr.iX, rect.iBr.iY );
+            break;
+
+        case EOverlay:
+            {
+            textRect = rect;
+            iconRect = rect;
+            }
+            break;
+            
+        default:
+            return;
+        }
+
+    // Draw icon
+    TPoint iconPoint;
+    switch ( iExtension->iHorizontalIconAlignment )
+        {
+        case ERight:
+            {
+            iconPoint.iX = iconRect.iBr.iX - iconSize.iWidth;                        
+            }
+            break;  
+
+        case ECenter:
+            {
+            iconPoint.iX = iconRect.iTl.iX + 
+            (iconRect.Width() / 2 - iconSize.iWidth / 2 );
+            } 
+            break;
+            
+        case ELeft:
+            {
+            iconPoint.iX = iconRect.iTl.iX;
+            }
+            break; 
+        
+        default:
+            // Should never come here
+            break;
+        }
+
+    switch ( iExtension->iVerticalIconAlignment )
+        {
+        case ETop:
+            {
+            iconPoint.iY = iconRect.iTl.iY;
+            }
+            break;
+        
+        case ECenter:
+            {
+            iconPoint.iY = iconRect.iTl.iY +
+            ( iconRect.Height() / 2 - iconSize.iHeight / 2 );
+            }
+            break;
+          
+        case EBottom:
+            {
+            iconPoint.iY = iconRect.iBr.iY - iconSize.iHeight;
+            }
+            break;
+            
+        default:
+            // Should never come here
+            break;
+        }
+
+    if( buttonBmp && buttonMask )
+        {
+        aGc.BitBltMasked( iconPoint, buttonBmp,
+            iconRect.Size(), buttonMask, ETrue );
+        }
+    else if ( buttonBmp )
+        {
+        aGc.BitBlt( iconPoint, buttonBmp, iconRect.Size() );
+        }
+
+    const CFont* font = iFont;
+    if ( !font )
+        {
+        font = iCoeEnv->NormalFont();
+        }
+    aGc.UseFont( font );
+        
+    TRgb penColor;
+    TRgb brushColor;
+    GetTextColors( penColor, brushColor ); 
+    aGc.SetPenColor( penColor ); 
+    aGc.SetBrushColor( brushColor ); 
+
+    aGc.SetUnderlineStyle( iExtension->iUnderlineStyle );
+
+    TBuf<255 + KAknBidiExtraSpacePerLine> visualText; // buffer for visually ordered text
+    TInt clipWidth = textRect.Width();
+
+    // bidi processing - using AknBidiTextUtils.
+    AknBidiTextUtils::ConvertToVisualAndClip(
+        state->Text(),
+        visualText,
+        *font,
+        clipWidth,
+        clipWidth );
+
+    TInt baselineOffset = 0;
+    switch ( iVerticalAlignment )
+        {
+        case ETop:
+            baselineOffset = font->AscentInPixels();
+            break;
+
+        case EBottom:
+            baselineOffset = textRect.Height();
+            break;
+
+        default:  // centered
+            baselineOffset = font->AscentInPixels() +
+                           ( textRect.Height() - font->AscentInPixels() ) / 2;
+        }
+
+    CGraphicsContext::TTextAlign horAlignment = iHorizontalAlignment;
+
+    aGc.DrawText( visualText, textRect, baselineOffset, horAlignment );
+    if ( iExtension->iPictographInterface )
+        {
+        // For Japanese variant only
+        iExtension->iPictographInterface->Interface()->DrawPictographsInText(
+            aGc, *font, visualText, textRect, baselineOffset, horAlignment );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// Starts the long press timer.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::StartLongPressTimerL()
+    {
+    if ( iExtension )
+        {
+        iExtension->StartLongPressTimerL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// Stops the long press timer.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::StopLongPressTimer()
+    {
+    if ( iExtension && iExtension->iLongPressTimer &&
+        iExtension->iLongPressTimer->IsActive() )
+        {
+        iExtension->iLongPressTimer->Cancel();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::StartKeyRepeatTimerL
+// Starts the timer for the long presses. The timer is constructed when used
+// for the first time.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::StartKeyRepeatTimerL()
+    {
+    if ( !iKeyRepeatTimer )
+        {
+        iKeyRepeatTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+        }
+    else if ( iKeyRepeatTimer->IsActive() )
+        {
+        iKeyRepeatTimer->Cancel();
+        }
+
+    if ( iKeyRepeatInterval > 0 )
+        {
+        iKeyRepeatTimer->Start( iKeyRepeatDelay, iKeyRepeatInterval,
+            TCallBack( ReportKeyRepeatL, this ) );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// Stops the key repeat timer.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::StopKeyRepeatTimer()
+    {
+    if ( iKeyRepeatTimer && iKeyRepeatTimer->IsActive() )
+        {
+        iKeyRepeatTimer->Cancel();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ReportKeyRepeatL
+// Cancel the timer.
+// -----------------------------------------------------------------------------
+//
+TInt CAknButton::ReportKeyRepeatL( TAny* aThis )
+    {
+    // Fixes TSW error AJUA-7CEF8H 
+    User::ResetInactivityTime();
+    CAknButton* self = reinterpret_cast< CAknButton* >( aThis );
+
+    if ( self->IsVisible() && 
+        !self->iExtension->iFlags.IsSet( CAknButtonExtension::EDimmed ) )
+        {
+        if ( self->iStates->Count() > 1 )
+            {
+            self->ChangeState( ETrue );
+            }
+
+        if ( self->Observer() )
+            {
+            self->Observer()->HandleControlEventL( self,
+                MCoeControlObserver::EEventStateChanged );
+            }
+
+        TBool feedbackNeeded = (self->iStates->Count() > 1) || (self->Observer());
+        TBool pointerRepeat = (self->iButtonPressed & KPointerFlag);  // it was caused by pointer event
+        if ( self->iExtension->iFeedback && feedbackNeeded && pointerRepeat)
+            {
+            self->iExtension->iFeedback->InstantFeedback( self, ETouchFeedbackSensitiveButton );
+            }
+
+        self->iExtension->iFlags.Set( CAknButtonExtension::EKeyRepeatEventReported );
+        }
+    else if ( self->iKeyRepeatTimer && self->iKeyRepeatTimer->IsActive() )
+        {
+        self->iKeyRepeatTimer->Cancel();
+        }
+
+    return 1; // CPeriodic ignores return value
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::Extension
+// -----------------------------------------------------------------------------
+//
+CAknButtonExtension* CAknButton::Extension() const
+    {
+    return iExtension;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::UpdateTooltipPosition
+// -----------------------------------------------------------------------------
+//
+void CAknButton::UpdateTooltipPosition()
+    {
+    TPoint position;
+
+    if ( AknsUtils::GetControlPosition( this, position ) != KErrNone )
+        {
+        position = PositionRelativeToScreen();
+        }
+    TRect rect( position, Size() );
+
+    TPoint center = rect.Center();
+
+    switch ( iExtension->iTooltipPosition )
+        {
+        case EPositionTop:
+            {
+            iHelpNote->SetPositionAndAlignment(
+                TPoint( center.iX, rect.iTl.iY ), EHCenterVBottom );
+            break;
+            }
+        case EPositionBottom:
+            {
+            iHelpNote->SetPositionAndAlignment(
+                TPoint( center.iX, rect.iBr.iY ), EHCenterVTop );
+            break;
+            }
+        case EPositionLeft:
+            {
+            iHelpNote->SetPositionAndAlignment(
+                TPoint( rect.iTl.iX, center.iY ), EHRightVCenter );
+            break;
+            }
+        case EPositionRight:
+            {
+            iHelpNote->SetPositionAndAlignment(
+                TPoint( rect.iBr.iX, center.iY ), EHLeftVCenter );
+            break;
+            }
+        default:
+            {
+            return;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::RequestExit
+// Returns whether button should send EEventRequestExit to command observer
+// on button up events.
+// -----------------------------------------------------------------------------
+//
+TBool CAknButton::RequestExit() const
+    {
+    if ( iFlags & KAknButtonRequestExitOnButtonUpEvent )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::ContentRect
+// Returns the the rectangle reserved for frame center, or the rect for text and
+// icon, if the button has no frames (controls rect for now).
+// -----------------------------------------------------------------------------
+//
+TRect CAknButton::ContentRect() const
+    {    
+    TRect rect( Size() );
+    if ( !( iFlags & KAknButtonNoFrame ) && 
+          ( iFlags & KAknButtonTextInsideFrame ) )
+        {
+        TAknLayoutRect centerLayout;
+        centerLayout.LayoutRect( rect,
+        AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
+        rect = centerLayout.Rect();        
+        }
+    return rect;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::NeedsRedrawWhenPressed
+// Returns boolean value indicating whether button needs redraw when it is
+// pressed or released without changes in its state.
+// -----------------------------------------------------------------------------
+//
+TBool CAknButton::NeedsRedrawWhenPressed() const
+    {
+    CAknButtonState* state = State();
+    if ( !iButtonPressed && iStates->Count() > 1 )
+        {
+        return EFalse; 
+        }
+
+    if ( iButtonPressed && iFlags & KAknButtonPressedDownFrame )
+        {
+        return ETrue;
+        }
+        
+    return ( state && state->PressedIcon() ||
+             ( !( iFlags & KAknButtonNoFrame ) &&
+               !( iFlags & KAknButtonNoFramePressEvent ) &&
+               !( state && state->Flags() & KAknButtonStateHasLatchedFrame &&
+                  SkinIID( KPressedFrameId ) == SkinIID( KLatchedFrameId ) ) ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::SkinIID
+// -----------------------------------------------------------------------------
+//
+TAknsItemID CAknButton::SkinIID( const TInt aIndex ) const
+    {
+    if ( iExtension && aIndex >= 0 &&
+         aIndex < iExtension->iFrameAndCenterIds.Count() )
+        {
+        return iExtension->iFrameAndCenterIds[aIndex];
+        }
+    else
+        {
+        return KAknsIIDNone;
+        }
+    }
+    
+// -----------------------------------------------------------------------------
+// CAknButton::HitAreaContainsL
+// Checks if a button icon's non-transparent area was tapped.
+// -----------------------------------------------------------------------------
+//
+TBool CAknButton::HitAreaContainsL( const TPoint& aPoint, TBool aCheckHitArea ) const
+    {
+    TBool buttonEvent( ETrue );
+
+    if ( aCheckHitArea )
+        {
+        if ( TouchArea().Contains( aPoint ) )
+            {
+            return ETrue; 
+            }
+        else
+            {
+            return EFalse; 
+            }
+        }
+    else if ( iFlags & KAknButtonHitTest )        
+        {
+        TRect rect( Size() );
+        TRect contentRect( ContentRect() );
+        
+        CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
+        CleanupStack::PushL( bitmap );
+        
+        User::LeaveIfError( bitmap->Create( rect.Size(), EGray256 ) );
+            
+        CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( bitmap );
+        
+        CleanupStack::PushL( device );
+        CFbsBitGc* gc = CFbsBitGc::NewL();
+        gc->Activate( device );                            
+        gc->SetBrushStyle( CGraphicsContext::ENullBrush );
+
+        MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+        MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
+        
+        if ( !(iFlags & KAknButtonNoFrame ) )
+            {    
+            CAknButtonState* state = State();
+            
+            TInt frameIdIndex = KFrameId;
+            if ( iButtonPressed )
+                {
+                frameIdIndex = KPressedFrameId;
+                }
+            else if ( state && state->Flags() & KAknButtonStateHasLatchedFrame )
+                {
+                if ( IsDimmed() )
+                    {
+                    // dimmed latched frame
+                    frameIdIndex = KLatchedDimmedFrameId;
+                    }
+                else
+                    {
+                    // latched down
+                    frameIdIndex = KLatchedFrameId;
+                    }
+                }
+            else if ( IsDimmed())
+                {
+                // dimmed frame
+                frameIdIndex = KDimmedFrameId;
+                }
+
+            if ( SkinIID( frameIdIndex ) != KAknsIIDNone )
+                {
+                TAknsItemID frameId = SkinIID( frameIdIndex );
+                TAknsItemID centerId = SkinIID( frameIdIndex + 1 );                                       
+                
+                gc->SetBrushColor( KRgbWhite );
+                
+                if ( !AknsDrawUtils::DrawFrame( skin, *gc, rect, 
+                    contentRect, frameId, centerId, KAknsSDMAlphaOnly ) )
+                    {                                                                                    
+                    gc->DrawRect( rect );
+                    }                                                            
+                gc->DrawRect( contentRect );                        
+                }
+            }
+        else if ( GetCurrentIcon() )
+            {
+            // if button has (only) icon, then mark other parts transparent
+            gc->SetBrushColor( KRgbBlack );
+            gc->Clear();
+            CFbsBitmap* mask = GetCurrentIcon()->Mask();
+            if ( mask )
+                {
+                gc->BitBlt( contentRect.iTl, mask, mask->SizeInPixels() );
+                }
+            }
+        else if ( GetCurrentText() != KNullDesC )
+            {
+            gc->SetBrushColor( KRgbWhite );
+            gc->Clear( contentRect );
+            }
+        else
+            {
+            // if this happens.. make the whole button transparent!
+            gc->SetBrushColor( KRgbBlack );
+            gc->Clear( contentRect );                
+            }
+
+        TRgb pixel;
+        TPoint point( aPoint - Rect().iTl );
+        bitmap->GetPixel( pixel, point );
+        
+        delete gc;                    
+        CleanupStack::PopAndDestroy( 2 ); // bitmap, device
+
+        if ( pixel == KRgbBlack )
+            {
+            buttonEvent = EFalse;
+            }
+        } // iFlags & KAknButtonHitTest
+    return buttonEvent;
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::UsesDefaultMargins
+// Checks if the button uses default margins.
+// -----------------------------------------------------------------------------
+//
+TBool CAknButton::UsesDefaultMargins() const
+    {
+    return iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultMargins );
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::TextColor
+// Gets the correct text color.
+// -----------------------------------------------------------------------------
+//
+TRgb CAknButton::TextColor() const
+    {
+    TRgb color;
+    
+    if ( IsDimmed() )
+        {
+        color = iEikonEnv->ControlColor( EColorButtonText, *this );
+        color.SetAlpha( 77 );
+        }
+    else if ( iButtonPressed )
+        {
+        color = iEikonEnv->ControlColor( EColorButtonTextPressed, *this );
+        }
+    else
+        {
+        color = iEikonEnv->ControlColor( EColorButtonText, *this );
+        }
+        
+    return color;
+    }
+    
+// -----------------------------------------------------------------------------
+// CAknButton::CreatePressedDownFrameL
+// Generates a pressed down mask
+// -----------------------------------------------------------------------------
+//    
+void CAknButton::CreatePressedDownFrameL()
+    {
+
+    // Fetch frames from frame provider if one exists
+    if ( iExtension->FetchProviderPressedBmpsL() )
+        {
+        return;
+        }
+
+    if ( iExtension->iPressedDownBmp &&
+         iExtension->iPressedDownBmp->SizeInPixels() == Size() )
+        {
+        iExtension->SetProviderPressedBmpsL();
+        return;
+        }
+
+    iExtension->DeletePressedBmps();
+
+    // Fetch preffered display mode for icon type images
+    AknIconConfig::TPreferredDisplayMode displayMode;
+    AknIconConfig::PreferredDisplayMode( 
+        displayMode, AknIconConfig::EImageTypeIcon );
+
+    iExtension->iPressedDownBmp = new ( ELeave ) CFbsBitmap;
+    User::LeaveIfError( iExtension->iPressedDownBmp->Create( Size(),
+        displayMode.iBitmapMode) );
+    iExtension->iPressedDownBmpMask = new ( ELeave ) CFbsBitmap;
+    User::LeaveIfError( iExtension->iPressedDownBmpMask->Create( Size(), 
+        displayMode.iMaskMode ) );
+
+    CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL( 
+        iExtension->iPressedDownBmp );
+    CleanupStack::PushL( bmpDevice );
+     
+    CFbsBitGc* bmpGc (NULL );
+    User::LeaveIfError( bmpDevice->CreateContext( bmpGc ) );
+    CleanupStack::PushL( bmpGc );
+
+    CFbsBitmapDevice* bmpMaskDevice = CFbsBitmapDevice::NewL(
+        iExtension->iPressedDownBmpMask );
+    CleanupStack::PushL( bmpMaskDevice );
+        
+    CFbsBitGc* bmpMaskGc( NULL );
+    User::LeaveIfError( bmpMaskDevice->CreateContext( bmpMaskGc ) );
+    CleanupStack::PushL( bmpMaskGc );
+
+    TRect rect ( Size() );
+    TAknLayoutRect centerLayout;
+    centerLayout.LayoutRect( rect,
+        AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() );
+    TRect innerRect( centerLayout.Rect() );
+
+    TAknWindowLineLayout unit = AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine();
+    innerRect.Shrink( unit.iW/10, unit.iH/10 ); 
+        
+    AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+                              *bmpGc, rect, innerRect,
+                              SkinIID( KPressedFrameId ), KAknsIIDDefault,
+                              KAknsDrawParamRGBOnly );
+        
+    AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(), 
+                              *bmpMaskGc, rect, innerRect,
+                              SkinIID( KPressedFrameId ), KAknsIIDDefault, 
+                              KAknsSDMAlphaOnly );
+
+    // Modify mask 50% transparent
+    iExtension->iPressedDownBmpMask->LockHeap();
+    
+    TInt w = iExtension->iPressedDownBmpMask->SizeInPixels().iWidth; 
+    TInt h = iExtension->iPressedDownBmpMask->SizeInPixels().iHeight;
+    TInt dataStride = iExtension->iPressedDownBmpMask->DataStride() - w; 
+    unsigned char* address = (unsigned char *)iExtension->iPressedDownBmpMask->DataAddress();  
+    
+            
+            for ( TInt i = 0; i < h; ++i )
+                {
+                for ( TInt j = 0; j < w; ++j )
+                    {
+                    *address >>= 1;
+                    ++address;
+                    }
+                address += dataStride;         
+                }
+
+    iExtension->iPressedDownBmpMask->UnlockHeap();
+
+    // Set created frames to frame provider if one exists
+    iExtension->SetProviderPressedBmpsL();
+
+    CleanupStack::PopAndDestroy( 4 ); // bmpDevice, bmpGc, bmpMaskDevice, bmpMaskGc
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknButton::HideTooltipWhenAppFaded
+// Sets tooltip to show or hide itself when background faded. By default tooltip
+// is not shown when background faded. 
+// -----------------------------------------------------------------------------
+//
+void CAknButton::HideTooltipWhenAppFaded( TBool aHide )
+    {
+    if(iHelpNote)
+        {
+        iHelpNote->HideWhenAppFaded( aHide ); 
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknButton::CheckHitArea
+// This checks hit area for fixed toolbar buttons. 
+// -----------------------------------------------------------------------------
+//
+void CAknButton::CheckHitArea( )
+    {
+    iExtension->iFlags.Set( CAknButtonExtension::ECheckHitArea );
+    SetHitTest( iExtension ); 
+    iExtension->HandleFeedbackAreaChange();
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::UseAdditionalMask
+// Sets button to use additional masks during drawing.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::UseMaskedDraw( TBool aMaskedDraw )
+    {
+    if ( aMaskedDraw )
+        {
+        iExtension->iFlags.Set( CAknButtonExtension:: EUseAdditionalMask );
+        }
+    else
+        {
+        iExtension->iFlags.Clear( CAknButtonExtension:: EUseAdditionalMask );
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// Registers resource provider.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::RegisterResourceProvider( CAknResourceProvider* aProvider )
+    {
+    iExtension->iResourceProvider = aProvider;
+    }
+
+
+// -----------------------------------------------------------------------------
+// Unregisters resource provider.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::UnregisterResourceProvider()
+    {
+    iExtension->iResourceProvider = 0;
+    }
+    
+    
+CAknsFrameBackgroundControlContext* CAknButton::BgContext()
+    {
+    return iBgContext;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknButton::RemoveCurrentState
+// Removes the current state.
+// -----------------------------------------------------------------------------
+//
+void CAknButton::RemoveCurrentState()
+    {
+    // Can't remove the state if it's the only one left. 
+    if ( iStates->Count() > 1 )
+        {
+        CAknButtonState* state = iStates->At( iStateIndex );
+        delete state;
+        state = NULL;
+        iStates->Delete( iStateIndex );
+        
+        iStateIndex <= 0 ? iStateIndex = 0 : iStateIndex--;
+        DrawNow();
+        }
+    }
+
+
+// -----------------------------------------------------------------------------
+// CAknButton::CalculateLuminance
+// Calculates color's luminance value.
+// -----------------------------------------------------------------------------
+//
+TInt CAknButton::CalculateLuminance( const TRgb& aColor ) const 
+    { 
+    TInt R = aColor.Red(); 
+    TInt G = aColor.Green(); 
+    TInt B = aColor.Blue(); 
+    // Should be scaled to 0-255? 
+    TInt Y = (((66 * R) + (129 * G) + (25 * B) + 128) >> 8) + 16; 
+    return Y; 
+    } 
+
+
+// -----------------------------------------------------------------------------
+// CAknButton::ConvertColorsForOutlineEffect
+// Converts the outline color to be white or black if the fill color is 
+// too similar to outline color. 
+// -----------------------------------------------------------------------------
+//
+void CAknButton::ConvertColorsForOutlineEffect( TRgb& aFillColor, TRgb& aOutlineColor ) const 
+    { 
+    // @todo maybe there is already some conversion utility in multimedia image library? 
+    TInt innerLum = CalculateLuminance(aFillColor); 
+    TInt outerLum = CalculateLuminance(aOutlineColor); 
+    
+    // if the defined colours are the same, then change the outline color so that 
+    // it's either black or white, contrasting according to the font label text color's brightness 
+    TInt difference = outerLum - innerLum; 
+    difference = Abs(difference); 
+    TInt half = (0xff / 2); // @todo figure out hlsMax somehow 
+    TInt threshold = (0xff / 3); // @todo figure out hlsMax somehow, and decide on the threshold! 
+    if(difference < threshold) 
+        { 
+        // if inner luminance is low, the outer luminance should be high, i.e. white 
+        aOutlineColor = (innerLum < half) ? KRgbWhite : KRgbBlack; 
+        } 
+    } 
+
+// -----------------------------------------------------------------------------
+// CAknButton::GetTextColors
+// Gets correct text colors 
+// -----------------------------------------------------------------------------
+//
+void CAknButton::GetTextColors( TRgb& aPenColor, TRgb& aBrushColor ) const 
+    {
+    TBool outlineEffectOn = EFalse;
+    const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull( iFont ); 
+    if ( layoutFont ) 
+        {
+        outlineEffectOn = layoutFont->FontSpecification().IsOutlineEffectOn(); 
+        }
+
+    if ( IsDimmed() ) 
+        {
+        aPenColor = TextColor(); 
+        aBrushColor = iEikonEnv->ControlColor( EColorControlDimmedBackground,*this ); 
+        }
+    else
+        {
+        aPenColor = TextColor(); 
+        aBrushColor = iEikonEnv->ControlColor( EColorControlBackground,*this );   
+        }
+    if ( outlineEffectOn )
+        {
+        ConvertColorsForOutlineEffect( aBrushColor, aPenColor ); 
+        }
+    }    
+
+// -----------------------------------------------------------------------------
+// CAknButton::SetStateIndexL
+// Sets new state index
+// -----------------------------------------------------------------------------
+//
+void CAknButton::SetStateIndexL( TInt aNewIndex )
+    {
+    if ( iStateIndex != aNewIndex )
+        {
+        iStateIndex = aNewIndex;
+        // Create new popup note controller every time state changes
+        // (text is not updated properly in help note if this is not done)
+        if ( iHelpNote )
+            {
+            delete iHelpNote;
+            iHelpNote = 0;        
+            }
+        iHelpNote = CAknInfoPopupNoteController::NewL();
+        iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval );
+        iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval );
+        iHelpNote->SetTooltipModeL( ETrue );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAknButton::TouchArea
+// Returns the button touchable area.
+// -----------------------------------------------------------------------------
+//
+TRect CAknButton::TouchArea() const
+    {
+    TRect touchRect( Rect() );
+    if ( iExtension->iFlags.IsSet( CAknButtonExtension::ECheckHitArea ) )
+        {
+        TAknLayoutRect layoutRect;
+        layoutRect.LayoutRect( Rect(), 
+            AknLayoutScalable_Avkon::aid_touch_sctrl_middle( 
+            !Layout_Meta_Data::IsLandscapeOrientation() ).LayoutLine() );
+        touchRect = layoutRect.Rect();
+        }
+    return touchRect;
+    }
+// end of file