--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/EikStd/coctlsrc/eikcba.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,8366 @@
+/*
+* Copyright (c) 2002-2009 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: Command button array implementation.
+*
+*/
+
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <uikon/eikdefmacros.h>
+#endif
+#include <barsread.h>
+#include "eikcba.h"
+#include <eiklabel.h>
+#include <eiksoftkeyimage.h>
+#include <eiksoftkeypostingtransparency.h>
+#include <eikbtgpc.h>
+#include <aknappui.h>
+#include <AknUtils.h> // LayoutUtils
+#include <aknlayoutscalable_apps.cdl.h>
+#include <AknsBasicBackgroundControlContext.h>
+#include <AknsMaskedLayerBackgroundControlContext.h>
+#include <AknsDrawUtils.h>
+#include <AknsConstants.h>
+#include <aknconsts.h>
+#include <AknSgcc.h>
+#include <AknStatuspaneUtils.h>
+#include <aknpriv.rsg> // R_ENHANCED_CBA_PRIORITIES
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <layoutmetadata.cdl.h>
+#include <avkon.mbg>
+#include <centralrepository.h>
+#include <AvkonInternalCRKeys.h> // KAknMiddleSoftkeyEnabled
+#include <cenrepnotifyhandler.h>
+#include <AknSkinsInternalCRKeys.h>
+#include <aknQueryControl.h>
+#include <aknbutton.h>
+#include <akniconconfig.h>
+
+#include <akncommandbuttonstate.h>
+
+#include <AknTasHook.h>
+#include <akncbacontentobserver.h>
+#include <aknitemactionmenu.h>
+#include "akncollectionobserver.h"
+#include "aknitemactionmenuregister.h"
+
+/**
+ * Color value for transparent pixel (ARGB format).
+ */
+const TUint32 KAknCbaColorKey = 0x00000000;
+
+/**
+ * Mask for opaque pixel (ARGB format).
+ */
+const TUint32 KAknCbaOpaqueMask = 0xFF000000;
+
+/**
+ * Mask for outline font in font id.
+ */
+const TUint32 KOutlineFontMask = 0x00000040;
+#include <touchfeedback.h>
+
+inline TAknWindowComponentLayout DoCompose(TAknWindowComponentLayout aLine1,
+ TAknWindowComponentLayout aLine2)
+ {
+ return TAknWindowComponentLayout::Compose(aLine1, aLine2);
+ }
+
+inline TAknTextComponentLayout DoComposeText(TAknWindowComponentLayout aLine1,
+ TAknTextComponentLayout aLine2)
+ {
+ return TAknWindowComponentLayout::ComposeText(aLine1, aLine2);
+ }
+
+/**
+* Checks if right side pane is active.
+* @return ETrue if right side pane is active, EFalse otherwise.
+*/
+static TBool IsAreaSideRightPaneActive()
+ {
+ return EFalse;
+ }
+
+
+/**
+* Checks if MSK-enabled layout is in use.
+*/
+static TBool IsMskEnabledLayoutActive()
+ {
+ TBool result( EFalse );
+
+ if ( Layout_Meta_Data::IsMSKEnabled() )
+ {
+ // First check if MSK is enabled in the layout metadata.
+ result = ETrue;
+ }
+ else
+ {
+ TInt statusPaneLayout(
+ AVKONENV->StatusPaneResIdForCurrentLayout(
+ AknStatuspaneUtils::CurrentStatusPaneLayoutResId() ) );
+
+ if ( statusPaneLayout ==
+ R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT_NO_SOFTKEYS ||
+ ( statusPaneLayout == R_AVKON_STATUS_PANE_LAYOUT_IDLE_FLAT &&
+ AknLayoutUtils::PenEnabled() &&
+ !Layout_Meta_Data::IsLandscapeOrientation() ) )
+ {
+ // MSK is not enabled in the layout metadata, but for
+ // these status pane layouts an exception is made.
+ result = ETrue;
+ }
+ }
+
+ return result;
+ }
+
+
+/*
+ * Checks if bitmap must be updated, i.e. bitmap does not exist or
+ * expected size does not match with actual size.
+ */
+static TBool IsBitmapUpdateNeeded( CFbsBitmap* aOldBitmap, const TSize& aSize )
+ {
+ return !aOldBitmap || ( aOldBitmap->SizeInPixels() != aSize );
+ }
+
+
+/**
+ * Implementation of class CEikCba - Control button array.
+ */
+const TInt KNoResource = 0;
+const TInt KMaxSeries60Softkeys = 3; // 3 softkeys for S60 with MSK
+const TInt KControlArrayCBAButton1Posn = 0;
+const TInt KControlArrayScrollBarPosn = 1;
+const TInt KControlArrayCBAButton2Posn = 2;
+const TInt KControlArrayCBAButtonMSKPosn = 3;
+const TInt KCbaScrollBarButtonWidth = 9; // in pixels
+
+/** Alpha value used in drawing CBA button contents in pressed down state. */
+const TInt KPressedDownAlphaValue = 127;
+
+
+/**
+* Local panic definitions.
+*/
+enum TEikPanicCBA
+ {
+ EEikPanicCBAControlArraySize,
+ EEikPanicCBANullButton,
+ EEikPanicCBACannotConvertToCEikCommandButton,
+ EEikPanicCBAIsNotEnhancedCba,
+ EEikPanicCBAButtonCountDiffersFromCommandTableSize
+ };
+
+/**
+* Local AknLayout definintions.
+*/
+enum TAknLayoutFlags
+ {
+ EAknLayoutCbaInControlPane = 0x1,
+ EAknLayoutCbaInStaconPane = 0x2,
+ EAknLayoutCbaInStaconPaneRight = 0x4,
+ EAknLayoutCbaInStaconPaneLeft = 0x8,
+ EAknLayoutCbaInStaconPaneIdle = 0x10,
+ EAknLayoutCbaInRightPane = 0x20
+ };
+
+/**
+* Enumeration for CEikCommandTable for fetching commands.
+*/
+enum TCommandTableCbaPositions
+ {
+ ECommandTableCommand1Posn = 0,
+ ECommandTableCommand2Posn = 1,
+ ECommandTableCommand3Posn = 2,
+ ECommandTableCommand4Posn = 3
+ };
+
+enum TCbaChangeRecordedFlags
+ {
+ ECbaChangeRecordedLayout,
+ ECbaChangeRecordedSkin,
+ ECbaChangeRecordedColor,
+ ECbaInsideDialog,
+ ECbaEmbedded, // cba is embedded in a parent control (dialog or popup)
+ ECbaHasContent, // cba has content and should be visible when embedded
+ ECbaParentAsControl, // cba's parent window group is treated as CCoeControl
+ ECbaActivationDelayed, // activation delayed
+ ECbaSingleClickEnabled, // single click enabled in appUi
+ ECbaItemSoftkeyDisabled, // item specific softkey disabled
+ ECbaItemSpecificSoftkeyInUse, // item specific softkey is in use
+ ECbaItemSoftkeyDisabledByClient // client has disabled item specific softkey
+ };
+
+enum TCbaLayers
+ {
+ ECbaLayerWallpaper,
+ ECbaLayerBackground,
+ ECbaLayerN
+ };
+
+/**
+* Local panic routine.
+*/
+#if defined(_DEBUG)
+LOCAL_C void Panic(TEikPanicCBA aPanic)
+ {
+ _LIT(KPanicCat,"CBA");
+ User::Panic(KPanicCat, aPanic);
+ }
+#endif
+
+
+/**
+* Internal extension class.
+*/
+class CEikCbaExtension : public CBase,
+ public MCenRepNotifyHandlerCallback,
+ public MAknCollectionObserver
+ {
+public:
+
+ CEikCbaExtension( CEikCba& aOwner ) : iOwner( aOwner ),
+ iCbaBgIIDSetExt( EFalse )
+ ,iLeftFrameMask( NULL ),
+ iRightFrameMask( NULL ),
+ iItemActionMenu( NULL )
+ {
+ };
+
+ static CEikCbaExtension* NewL( CEikCba& aOwner )
+ {
+ CEikCbaExtension* self = new (ELeave) CEikCbaExtension( aOwner );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+ void ConstructL()
+ {
+ // Wallpaper is not drawn by embedded CBA.
+ if ( !iOwner.Flags().IsSet( ECbaEmbedded ) )
+ {
+ iRepository = CRepository::NewL( KCRUidPersonalisation );
+ iRepository->Get( KPslnWallpaperType, iWallpaperInUse );
+
+ iCRListener = CCenRepNotifyHandler::NewL( *this,
+ *iRepository,
+ CCenRepNotifyHandler::EIntKey,
+ KPslnWallpaperType );
+ iCRListener->StartListeningL();
+ }
+
+ iBackgroundMaskID = KAknsIIDNone;
+ iCbaRect = TRect( 0,0,0,0 );
+ iIfSkinChanged = EFalse;
+ iIfMskIconSet = EFalse;
+ iSemiBgID = KAknsIIDNone;
+
+ if ( iOwner.Flags().IsSet( ECbaSingleClickEnabled ) )
+ {
+ AknItemActionMenuRegister::RegisterCollectionObserverL(
+ *this );
+ }
+ }
+
+ ~CEikCbaExtension()
+ {
+ if ( iOwner.Flags().IsSet( ECbaSingleClickEnabled ) )
+ {
+ AknItemActionMenuRegister::UnregisterCollectionObserver( *this );
+ }
+ if ( iCRListener )
+ {
+ iCRListener->StopListening();
+ delete iCRListener;
+ }
+
+ delete iRepository;
+ delete iPressedMSKFrameBitmap;
+ delete iLeftFrameMask;
+ delete iRightFrameMask;
+ delete iLskPostingOverlayBitmap;
+ delete iRskPostingOverlayBitmap;
+ delete iBmpFile;
+ }
+
+ /** From base class MCenRepNotifyHandlerCallback */
+ void HandleNotifyInt( TUint32 /*aId*/, TInt aNewValue )
+ {
+ iWallpaperInUse = aNewValue;
+ iOwner.SetSkinBackgroundId( KAknsIIDNone );
+ }
+
+ void UpdateSoftkeyFrameL( TBool aForcedUpdate )
+ {
+ if ( !AknLayoutUtils::PenEnabled() )
+ {
+ return;
+ }
+ TAknLayoutRect cbarect;
+
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TAknWindowComponentLayout applicationWindow(
+ AknLayoutScalable_Avkon::application_window( 0 ) );
+
+ TRect innerRect;
+ TRect outerRect;
+ TRect mskOuterRect;
+ TRect mskInnerRect;
+
+ if ( iOwner.Flags().IsSet( ECbaEmbedded ) )
+ {
+ TRect rect ( iOwner.Rect() );
+ if ( rect.Width() > 0 && rect.Height() > 0 )
+ {
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::popup_sk_window_g1( 0 ) );
+
+ TInt margin = layoutRect.Rect().iTl.iX - rect.iTl.iX;
+ TInt buttonWidth = ( rect.Width() - margin * 2 ) / 2;
+ outerRect = TRect( 0, 0, buttonWidth,
+ layoutRect.Rect().Height() );
+
+ layoutRect.LayoutRect( outerRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ innerRect = layoutRect.Rect();
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ const TSize maskSize = outerRect.Size();
+ if (skin && ( aForcedUpdate || IsBitmapUpdateNeeded( iLeftFrameMask, maskSize )
+ || IsBitmapUpdateNeeded( iRightFrameMask, maskSize ) ) )
+ {
+ delete iLeftFrameMask;
+ iLeftFrameMask = NULL;
+ delete iRightFrameMask;
+ iRightFrameMask = NULL;
+ }
+ }
+ }
+ else
+ {
+ TBool rightPaneActive( IsAreaSideRightPaneActive() );
+
+ TBool bskLandscape( Layout_Meta_Data::IsLandscapeOrientation() &&
+ !rightPaneActive );
+
+ if ( rightPaneActive )
+ {
+ cbarect.LayoutRect(
+ screen,
+ DoCompose(
+ applicationWindow,
+ AknLayoutScalable_Avkon::area_side_right_pane( 0 ) ).LayoutLine() );
+ }
+ else
+ {
+ cbarect.LayoutRect(
+ screen,
+ DoCompose(
+ applicationWindow,
+ DoCompose(
+ AknLayoutScalable_Avkon::area_bottom_pane( bskLandscape ? 2 : 1 ),
+ AknLayoutScalable_Avkon::control_pane() ) ).LayoutLine() );
+ }
+
+ TRect cbaRect( cbarect.Rect() );
+
+ TBool mskEnabled( IsMskEnabledLayoutActive() );
+
+ TAknWindowComponentLayout frameLayout;
+ if ( rightPaneActive )
+ {
+ frameLayout = AknLayoutScalable_Avkon::sctrl_sk_top_pane();
+ }
+ else if ( bskLandscape || mskEnabled )
+ {
+ frameLayout = AknLayoutScalable_Avkon::control_pane_g6( 0 );
+ }
+ else
+ {
+ frameLayout = AknLayoutScalable_Avkon::bg_sctrl_sk_pane_cp1();
+ }
+
+ cbarect.LayoutRect( cbaRect, frameLayout );
+
+ outerRect.SetRect( TPoint( 0, 0 ), cbarect.Rect().Size() );
+
+ if ( mskEnabled )
+ {
+ cbarect.LayoutRect(
+ cbaRect,
+ AknLayoutScalable_Avkon::control_pane_g7( 0 ) );
+
+ mskOuterRect.SetRect( TPoint( 0, 0 ), cbarect.Rect().Size() );
+ }
+ else
+ {
+
+ iUpdateMSKFrameOuterRect.SetRect( 0, 0, 0, 0 );
+ }
+
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect(
+ outerRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1().LayoutLine() );
+ innerRect = layoutRect.Rect();
+ if ( mskEnabled )
+ {
+ layoutRect.LayoutRect(
+ mskOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1() );
+ mskInnerRect = layoutRect.Rect();
+ }
+ }
+
+
+ iUpdateFrameOuterRect = outerRect;
+ iUpdateFrameInnerRect = innerRect;
+ iUpdateMSKFrameOuterRect = mskOuterRect;
+ iUpdateMskFrameInnerRect = mskInnerRect;
+ }
+
+
+
+
+ /**
+ * Merges mask into color bitmap.
+ * @internal
+ * @since S60 v5.0
+ * @param aMask mask to be merged.
+ * @param aDestBitmap bitmap to merge mask with.
+ */
+ static void MergeMaskInto16MA( CFbsBitmap* aMask, CFbsBitmap* aDestBitmap )
+ {
+ // aMask display mode must be EGray256.
+ // aMask must not be compressed in RAM.
+ // aDestBitmap display mode must be EColor16MA.
+ // aDestBitmap must not be compressed in RAM.
+ // aMask size must equal to aDestBitmap size.
+ // See UpdatePostingOverlayBitmapL.
+
+ TSize size = aMask->SizeInPixels();
+ TUint32 pitch = CFbsBitmap::ScanLineLength( size.iWidth, EGray256 );
+ TUint32 destPitch = CFbsBitmap::ScanLineLength( size.iWidth, EColor16MA ) / 4;
+ aMask->LockHeap();
+ aDestBitmap->LockHeap();
+ TUint8* dataAddr =
+ reinterpret_cast<TUint8*>( aMask->DataAddress() );
+ TUint32* destAddr =
+ reinterpret_cast<TUint32*>( aDestBitmap->DataAddress() );
+
+ for ( TUint32 y = 0; y < size.iHeight; y++ )
+ {
+ for ( TUint32 x = 0; x < size.iWidth; x++ )
+ {
+ TUint8 value = (TUint8)dataAddr[ y * pitch + x ];
+ // Round mask value to fully opaque or transparent
+ if ( value > 0x7f )
+ {
+ // Opaque pixel.
+ destAddr[ y * destPitch + x ] |= KAknCbaOpaqueMask;
+ }
+ else
+ {
+ // Transparent pixel
+ destAddr[ y * destPitch + x ] = KAknCbaColorKey;
+ }
+ }
+ }
+ aDestBitmap->UnlockHeap();
+ aMask->UnlockHeap();
+ }
+
+ /**
+ * Updates posting overlay bitmap.
+ * @internal
+ * @since S60 v5.0
+ * @param aBitmap Reference to bitmap pointer to get the new bitmap.
+ * @param aRect Rectangle for the CBA button.
+ * @param aControl CEikCba control.
+ * @param aButton CEikCbaButton control for the button.
+ */
+ void UpdatePostingOverlayBitmapL(
+ CFbsBitmap*& aBitmap,
+ const TRect& aRect,
+ CEikCbaButton* aButton )
+ {
+ delete aBitmap;
+ aBitmap = NULL;
+
+ // If you modify this method, please make sure that assumptions
+ // mentioned in MergeMaskInto16MA still hold.
+
+ CFbsBitmap* bitmap = new ( ELeave ) CFbsBitmap();
+ CleanupStack::PushL( bitmap );
+ User::LeaveIfError( bitmap->Create( aRect.Size(), EColor16MA ) );
+
+ CFbsBitGc* bitmapContext = NULL;
+ CFbsBitmapDevice* bitmapDevice =
+ CFbsBitmapDevice::NewL( bitmap );
+ CleanupStack::PushL( bitmapDevice );
+ User::LeaveIfError( bitmapDevice->CreateContext( bitmapContext ) );
+ CleanupStack::PushL( bitmapContext );
+
+ // Zero alpha channel to make bitmap fully transparent
+ bitmapContext->SetDrawMode( CGraphicsContext::EDrawModeWriteAlpha );
+ bitmapContext->SetBrushColor( TRgb::Color16MA( 0 ) );
+ bitmapContext->Clear();
+
+ // Draw button text into bitmap
+ if ( aButton )
+ {
+ CFbsBitmap* textBitmapMask = new ( ELeave ) CFbsBitmap();
+ CleanupStack::PushL( textBitmapMask );
+ User::LeaveIfError( textBitmapMask->Create( aRect.Size(), EGray256 ) );
+
+ CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( textBitmapMask );
+ CleanupStack::PushL( device );
+ CFbsBitGc* gc = NULL;
+ User::LeaveIfError( device->CreateContext( gc ) );
+ CleanupStack::PushL( gc );
+
+ // Clear bitmap
+ gc->SetBrushColor( KRgbBlack );
+ gc->Clear();
+
+ aButton->DrawToContext( *bitmapContext, *gc, aRect.iTl );
+
+ CleanupStack::PopAndDestroy( gc );
+ CleanupStack::PopAndDestroy( device );
+
+ // Merge text mask into the alpha channel to make the text fully opaque
+ MergeMaskInto16MA( textBitmapMask, bitmap );
+
+ CleanupStack::PopAndDestroy( textBitmapMask );
+ }
+
+ CleanupStack::PopAndDestroy( 2, bitmapDevice );
+ CleanupStack::Pop( bitmap );
+ aBitmap = bitmap;
+ }
+
+ /**
+ * Updates posting overlay bitmaps.
+ * @param aCbaRect cba rect.
+ * @param aLeftButton left button.
+ * @param aRightButton right button.
+ */
+ void UpdatePostingOverlayBitmapsL(
+ const TRect& aCbaRect,
+ CEikCbaButton* aLeftButton,
+ CEikCbaButton* aRightButton,
+ TInt aAknLayoutFlags )
+ {
+ TRect rightSoftKeyButtonRect;
+ TRect leftSoftKeyButtonRect;
+ if( aAknLayoutFlags & EAknLayoutCbaInRightPane )
+ {
+ // Read right (top in landscape) softkey layout.
+ TAknWindowLineLayout rightSoftkeyLayout(
+ DoCompose( AknLayoutScalable_Avkon::area_side_right_pane( 0 ),
+ AknLayoutScalable_Avkon::sctrl_sk_top_pane() ).LayoutLine() );
+
+ TAknLayoutRect rightSoftkeyLayoutRect;
+ rightSoftkeyLayoutRect.LayoutRect( aCbaRect, rightSoftkeyLayout );
+ rightSoftKeyButtonRect = rightSoftkeyLayoutRect.Rect() ;
+
+ // Read left (bottom in landscape) softkey layout.
+ TAknWindowLineLayout leftSoftkeyLayout(
+ DoCompose( AknLayoutScalable_Avkon::area_side_right_pane( 0 ),
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane() ).LayoutLine() );
+
+ TAknLayoutRect leftSoftkeyLayoutRect;
+ leftSoftkeyLayoutRect.LayoutRect( aCbaRect, leftSoftkeyLayout );
+ leftSoftKeyButtonRect = leftSoftkeyLayoutRect.Rect() ;
+ }
+ else if( aAknLayoutFlags & EAknLayoutCbaInControlPane )
+ {
+ TAknLayoutRect layoutRect;
+ TRect rect( 0,0,0,0 );
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_right().LayoutLine() );
+ leftSoftKeyButtonRect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_left().LayoutLine() );
+ rightSoftKeyButtonRect = layoutRect.Rect();
+ }
+ else
+ {
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_left().LayoutLine() );
+ leftSoftKeyButtonRect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_right().LayoutLine() );
+ rightSoftKeyButtonRect = layoutRect.Rect();
+ }
+ }
+ else
+ {
+ TInt variety = 0;
+ if ( aAknLayoutFlags & EAknLayoutCbaInStaconPaneLeft )
+ {
+ variety = 1;
+ }
+
+ TAknWindowComponentLayout layout0;
+ TAknWindowComponentLayout layout1;
+ TAknWindowComponentLayout layout2;
+
+ // Read right (top in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_top_pane( 2 );
+ layout1 = AknLayoutScalable_Avkon::stacon_top_pane();
+
+ // If clock is shown in stacon, cba area is smaller.
+ TInt topCbaVariety = variety;
+ if ( AknStatuspaneUtils::ExtendedStaconPaneActive() )
+ {
+ topCbaVariety += 4;
+ }
+
+ layout2 = AknLayoutScalable_Avkon::control_top_pane_stacon( topCbaVariety );
+
+ TAknWindowLineLayout rightSoftkeyLayout(
+ DoCompose( layout0,DoCompose( layout1, layout2 ) ).LayoutLine() );
+
+ TAknLayoutRect rightSoftkeyLayoutRect;
+ rightSoftkeyLayoutRect.LayoutRect( aCbaRect, rightSoftkeyLayout );
+ rightSoftKeyButtonRect = rightSoftkeyLayoutRect.Rect();
+
+ // Read left (bottom in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_bottom_pane( 2 );
+ layout1 = AknLayoutScalable_Avkon::stacon_bottom_pane();
+
+ // If clock is shown in stacon, cba area is smaller.
+ TInt bottomCbaVariety = variety;
+ if ( AknStatuspaneUtils::ExtendedStaconPaneActive() )
+ {
+ bottomCbaVariety += 2;
+ }
+
+ layout2 = AknLayoutScalable_Avkon::control_bottom_pane_stacon(
+ bottomCbaVariety );
+
+ TAknWindowLineLayout leftSoftkeyLayout(
+ DoCompose( layout0, DoCompose( layout1, layout2 ) ).LayoutLine() );
+
+ TAknLayoutRect leftSoftkeyLayoutRect;
+ leftSoftkeyLayoutRect.LayoutRect( aCbaRect, leftSoftkeyLayout );
+ leftSoftKeyButtonRect = leftSoftkeyLayoutRect.Rect();
+ }
+ UpdatePostingOverlayBitmapL(
+ iLskPostingOverlayBitmap,
+ leftSoftKeyButtonRect,
+ aLeftButton );
+ UpdatePostingOverlayBitmapL(
+ iRskPostingOverlayBitmap,
+ rightSoftKeyButtonRect,
+ aRightButton );
+ }
+
+ /**
+ * From MAknCollectionObserver.
+ * This method is used to set the item action menu to observer.
+ *
+ * @param aItemActionMenu Item action menu.
+ */
+ void SetItemActionMenu( CAknItemActionMenu* aItemActionMenu )
+ {
+ iItemActionMenu = aItemActionMenu;
+ }
+
+ /**
+ * From MAknCollectionObserver.
+ * This method is called when there are changes in collection state.
+ * LSK should be hidden when there is no highlight in list.
+ *
+ * @param aCollectionVisible ETrue if changed collection is visible.
+ */
+ void CollectionChanged( TBool aCollectionVisible )
+ {
+ // Do not update state if invisible collection tries to enable sk
+ if ( aCollectionVisible
+ || iOwner.Flags().IsClear( ECbaItemSoftkeyDisabled ) )
+ {
+ iOwner.UpdateItemSpecificSoftkey();
+ }
+ }
+
+ /**
+ * From MAknCollectionObserver.
+ * This method returns ETrue if collection observer is active.
+ *
+ * @return ETrue if observer is active.
+ */
+ TBool Active() const
+ {
+ return iOwner.IsVisible() && !iOwner.IsEmpty();
+ }
+
+ /*
+ * Using the special theme Id draw background
+ */
+ void DrawSemiTransparencyL(CWindowGc& aGc,
+ const TRect& aRect)
+ {
+ //Temporary inner rectangal value
+ TRect innerRect = aRect;
+ innerRect.Shrink( 5, 5 );
+ if ( iSemiBgID != KAknsIIDNone )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ aGc, aRect, innerRect, iSemiBgID, iSemiBgCenterID );
+ }
+ }
+
+public:
+
+ CEikCba& iOwner;
+ CRepository* iRepository;
+ CCenRepNotifyHandler* iCRListener;
+ TInt iWallpaperInUse;
+ CFbsBitmap* iFrameBitmap;
+ CFbsBitmap* iPressedFrameBitmap;
+ CFbsBitmap* iMSKFrameBitmap;
+ CFbsBitmap* iPressedMSKFrameBitmap;
+ CFbsBitmap* iLskPostingOverlayBitmap;
+ CFbsBitmap* iRskPostingOverlayBitmap;
+ TBool iEnablePostingTransparency;
+
+ TBool iCbaBgIIDSetExt;
+ TBool iIfSkinChanged;
+
+ CFbsBitmap* iLeftFrameMask;
+ CFbsBitmap* iRightFrameMask;
+
+ TAknsItemID iBackgroundMaskID;
+ TRect iCbaRect;
+ TBool iIfMskIconSet;
+ TAknsItemID iMSKSkinID;
+ HBufC* iBmpFile;
+ TInt32 iBmp;
+ TInt32 iBmpM;
+ /**
+ * Pointer to the CBA button which currently has the pointer grab.
+ * Not own.
+ */
+ CCoeControl* iPointerGrabbingButton;
+
+ /** Rectangle in which the left (or bottom) softkey frame is drawn to. */
+ TRect iLeftFrameOuterRect;
+ TRect iLeftFrameInnerRect;
+
+ /** Rectangle in which the right (or top) softkey frame is drawn to. */
+ TRect iRightFrameOuterRect;
+ TRect iRightFrameInnerRect;
+
+ /** Rectangle in which the middle softkey frame is drawn to if used. */
+ TRect iMiddleFrameOuterRect;
+ TRect iMiddleFrameInnerRect;
+
+ /**
+ * Content observer.
+ */
+ TCallBack iContentObserver;
+
+ /**
+ * Outer rect used in UpdateSoftkeyFrameL method.
+ */
+ TRect iUpdateFrameOuterRect;
+
+ /*
+ * Frame and center theme ID, using for semi-transparent
+ */
+ TAknsItemID iSemiBgID;
+ TAknsItemID iSemiBgCenterID;
+ /**
+ * Inner rect used in UpdateSoftkeyFrameL method.
+ */
+ TRect iUpdateFrameInnerRect;
+
+ /**
+ * Outer MSK rect used in UpdateSoftkeyFrameL method.
+ */
+ TRect iUpdateMSKFrameOuterRect;
+ /*
+ *
+ */
+ TRect iUpdateMskFrameInnerRect;
+
+ /**
+ * Item action menu.
+ * Not own.
+ */
+ CAknItemActionMenu* iItemActionMenu;
+ };
+
+
+CEikCba* CEikCba::NewL(const CEikCba* aPrevious, MEikCommandObserver* aCommandObserver,
+ RWindowGroup* aParentWg)
+ {
+ CEikCba* self = CEikCba::NewLC(aPrevious, aCommandObserver, aParentWg); // static
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CEikCba* CEikCba::NewL(TInt aResourceId, const CEikCba* aPrevious,
+ MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg)
+ {
+ CEikCba* self = CEikCba::NewLC(aResourceId, aPrevious, aCommandObserver, aParentWg); // static
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+CEikCba* CEikCba::NewLC(const CEikCba* aPrevious, MEikCommandObserver* aCommandObserver,
+ RWindowGroup* aParentWg)
+ {
+ return CEikCba::NewLC(KNoResource, aPrevious, aCommandObserver, aParentWg); // static
+ }
+
+CEikCba* CEikCba::NewLC(const CEikCba* aPrevious,
+ MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg,
+ TUint aFlags)
+ {
+ return CEikCba::NewLC(KNoResource, aPrevious, aCommandObserver,
+ aParentWg, aFlags);
+ }
+
+CEikCba* CEikCba::NewLC(TInt aResourceId, const CEikCba* aPrevious,
+ MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg)
+ {
+ CEikCba* self = new(ELeave) CEikCba(aPrevious, aCommandObserver, aParentWg); // static
+ CleanupStack::PushL(self);
+ self->ConstructL(aResourceId);
+ AKNTASHOOK_ADDL( self, "CEikCba" );
+ return self;
+ }
+
+CEikCba* CEikCba::NewLC(TInt aResourceId, const CEikCba* aPrevious,
+ MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg,
+ TUint aFlags)
+ {
+ CEikCba* self = new(ELeave) CEikCba(aPrevious, aCommandObserver,
+ aParentWg, aFlags);
+ CleanupStack::PushL(self);
+ self->ConstructL(aResourceId);
+ AKNTASHOOK_ADDL( self, "CEikCba" );
+ return self;
+ }
+
+
+/**
+* Destructor.
+*/
+CEikCba::~CEikCba()
+ {
+ AKNTASHOOK_REMOVE();
+ // Revert the clock and indicator pane area of status pane
+ // to use the previous skin background.
+ CEikStatusPaneBase* sp = CEikStatusPaneBase::Current();
+ if ( sp &&
+ iClockIndicBgIID.iMajor &&
+ iClockIndicBgIID.iMinor &&
+ iIsClockIndicBgIIDSet )
+ {
+ sp->SetCbaAreaBackgroundID( iClockIndicBgIID,
+ CEikStatusPaneBase::EDrawDeferred );
+ }
+
+ AknsUtils::DeregisterControlPosition( this );
+
+ // Remove scroll bar from control array to prevent double deletion
+ // but only if has been properly constructed.
+ if (iControlArray)
+ {
+ if (iControlArray->Count() > KControlArrayScrollBarPosn)
+ {
+ iControlArray->Delete(KControlArrayScrollBarPosn);
+ }
+ }
+
+ if(iEikonEnv && iEikonEnv->EikAppUi())
+ {
+ iEikonEnv->EikAppUi()->RemoveFromStack(this);
+ }
+
+ // Don't release font, as we are using layout utils to use SAME font every time.
+
+ delete iBrushAndPenContext;
+ delete iSBFrame;
+
+ delete iMLBgContext;
+ delete iStaconBgContextTop;
+ delete iStaconBgContextBottom;
+
+#ifdef RD_ENHANCED_CBA
+ delete iCommandTable;
+#endif // RD_ENHANCED_CBA
+
+ delete iExtension;
+ }
+
+/**
+* Constructor.
+*/
+CEikCba::CEikCba(const CEikCba* aPrevious,
+ MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg,
+ TUint aFlags)
+ : iLink(aPrevious), iCommandObserver(aCommandObserver), iParentWg(aParentWg)
+ {
+ if (aFlags & CEikButtonGroupContainer::EIsEmbedded)
+ {
+ // CBA is embedded in another component (eg. dialog/popup/setting page
+ iFlags.Set(ECbaEmbedded);
+ }
+
+ if ( aFlags & CEikButtonGroupContainer::EParentIsControl )
+ {
+ iFlags.Set( ECbaParentAsControl );
+ }
+
+ if ( aFlags & CEikButtonGroupContainer::EDelayActivation )
+ {
+ iFlags.Set( ECbaActivationDelayed );
+ }
+
+ CAknAppUi* appUi = static_cast<CAknAppUi*>( iCoeEnv->AppUi() );
+ if ( appUi && appUi->IsSingleClickCompatible() )
+ {
+ iFlags.Set( ECbaSingleClickEnabled );
+ iFlags.Set( ECbaItemSpecificSoftkeyInUse );
+ }
+
+ SetNonFocusing();
+ }
+
+
+void CEikCba::SetContainerWindowL( const CCoeControl& aContainer )
+ {
+ // CCoeControl::SetContainerWindowL closes the previously own window and
+ // deactivates control. Therefore store the activation status and re-set
+ // it after the container window has been set.
+
+ // Removed to enable drawing of Query Input in one phase
+ //TBool wasActivated = IsActivated();
+ // Check that this method was called from CAknQueryControl. Otherwise just
+ // bail out so that previous functionality (i.e. the one before SetContainerWindowL
+ // was overridded) is preserved.
+ CAknQueryControl* queryControl;
+
+ queryControl = const_cast<CCoeControl&>( aContainer ).MopGetObject( queryControl );
+
+ if ( queryControl == &aContainer )
+ {
+ CCoeControl::SetContainerWindowL( aContainer );
+
+ // Convert all CEikCbaButtons to CAknButtons
+ iFlags.Set( ECbaInsideDialog );
+
+ TAknTextComponentLayout layout = AknLayoutScalable_Apps::cell_vitu2_itu_pane_t1( 0 );
+ TAknLayoutText layoutText;
+ layoutText.LayoutText(Rect(), layout.LayoutLine() );
+
+ CCoeControl *leftSoftkey = (*iControlArray)[KControlArrayCBAButton1Posn].iControl;
+ CCoeControl *rightSoftkey = (*iControlArray)[KControlArrayCBAButton2Posn].iControl;
+
+ TInt leftCommandId( (*iControlArray)[KControlArrayCBAButton1Posn].iId );
+ TInt rightCommandId( (*iControlArray)[KControlArrayCBAButton2Posn].iId );
+
+ TRgb color = layoutText.Color();
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG65 );
+
+
+ CAknButton* button = CAknButton::NewL();
+ button->SetObserver( this );
+
+
+ switch ( AknLayoutScalable_Apps::area_vitu2_query_pane_t1( 0 ).J() )
+ {
+ case ELayoutAlignRight:
+ {
+ button->SetTextHorizontalAlignment( CGraphicsContext::ERight );
+ break;
+ }
+
+ case ELayoutAlignLeft:
+ {
+ button->SetTextHorizontalAlignment( CGraphicsContext::ELeft );
+ break;
+ }
+
+ case ELayoutAlignCenter:
+ default:
+ {
+ button->SetTextHorizontalAlignment( CGraphicsContext::ECenter );
+ break;
+ }
+ }
+
+ if ( !static_cast<CEikCbaButton*>( leftSoftkey )->IsImageOn() )
+ {
+ CEikLabel* label = static_cast<CEikLabel*>( leftSoftkey->ComponentControl( 0 ) );
+
+ const TDesC* text = label->Text();
+ button->AddStateL( NULL, NULL, NULL, NULL, *text, KNullDesC, 0, leftCommandId );
+
+ if ( text->Length() == 0 || !text->Compare( _L(" ") ) )
+ {
+ button->SetDimmed( ETrue );
+ }
+ }
+
+ button->OverrideColorL( EColorButtonText, color );
+ button->OverrideColorL( EColorButtonTextPressed, color );
+ button->OverrideColorL( EColorButtonTextDimmed, color );
+
+ button->SetBackgroundIds( KAknsIIDQsnFrFunctionButtonNormal,
+ KAknsIIDQsnFrFunctionButtonPressed, KAknsIIDQsnFrFunctionButtonInactive,
+ KAknsIIDQsnFrFunctionButtonPressed, KAknsIIDQsnFrFunctionButtonInactive );
+
+
+ delete leftSoftkey;
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl = button;
+
+ button = CAknButton::NewL();
+ button->SetObserver( this );
+
+
+ switch ( AknLayoutScalable_Apps::area_vitu2_query_pane_t2( 0 ).J() )
+ {
+ case ELayoutAlignRight:
+ {
+ button->SetTextHorizontalAlignment( CGraphicsContext::ERight );
+ break;
+ }
+
+ case ELayoutAlignLeft:
+ {
+ button->SetTextHorizontalAlignment( CGraphicsContext::ELeft );
+ break;
+ }
+
+ case ELayoutAlignCenter:
+ default:
+ {
+ button->SetTextHorizontalAlignment( CGraphicsContext::ECenter );
+ break;
+ }
+ }
+
+ if ( !static_cast<CEikCbaButton*>( rightSoftkey )->IsImageOn() )
+ {
+ CEikLabel* label = static_cast<CEikLabel*>( rightSoftkey->ComponentControl( 0 ) );
+
+ const TDesC* text = label->Text();
+ button->AddStateL( NULL, NULL, NULL, NULL, *text, KNullDesC, 0, rightCommandId );
+
+ if ( text->Length() == 0 || !text->Compare( _L(" ") ) )
+ {
+ button->SetDimmed( ETrue );
+ }
+ }
+
+ button->OverrideColorL( EColorButtonText, color );
+ button->OverrideColorL( EColorButtonTextPressed, color );
+ button->OverrideColorL( EColorButtonTextDimmed, color );
+
+ button->SetBackgroundIds( KAknsIIDQsnFrFunctionButtonNormal,
+ KAknsIIDQsnFrFunctionButtonPressed, KAknsIIDQsnFrFunctionButtonInactive,
+ KAknsIIDQsnFrFunctionButtonPressed, KAknsIIDQsnFrFunctionButtonInactive );
+
+ delete rightSoftkey;
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl = button;
+
+ // CCoeControl::ComponentControl can't be used since base class CEikControlGroup
+ // doesn't necessarily return all child controls.
+ for ( TInt i = 0; i < iControlArray->Count(); ++i )
+ {
+ if ( (*iControlArray)[i].iControl )
+ {
+ (*iControlArray)[i].iControl->SetContainerWindowL( *this );
+ }
+ }
+ }
+
+ else if ( iFlags.IsSet( ECbaEmbedded ) &&
+ !iFlags.IsSet( ECbaParentAsControl ) )
+ {
+ if ( OwnsWindow() )
+ {
+ CloseWindow();
+ }
+
+ CreateWindowL( &aContainer );
+ EnableWindowTransparency();
+
+ RWindow& window = Window();
+ window.SetPointerGrab(ETrue);
+ EnableDragEvents();
+ window.SetShadowDisabled(ETrue);
+
+ TBool isEmpty = IsEmpty();
+
+ if ( !isEmpty && !iFlags.IsSet( ECbaHasContent ) )
+ {
+ iFlags.Set( ECbaHasContent );
+ }
+
+ for ( TInt i = 0; i < iControlArray->Count(); ++i )
+ {
+ if ( (*iControlArray)[i].iControl )
+ {
+ (*iControlArray)[i].iControl->SetContainerWindowL( *this );
+ }
+ }
+ }
+ else
+ {
+ CCoeControl::SetContainerWindowL( aContainer );
+ }
+ }
+
+void CEikCba::ActivateL()
+ {
+ CCoeControl::ActivateL();
+ }
+
+void CEikCba::BaseConstructL()
+ {
+ if ( iFlags.IsSet( ECbaEmbedded ) && iFlags.IsSet( ECbaParentAsControl ) )
+ {
+ __ASSERT_DEBUG( iParentWg, User::Invariant() );
+ CreateWindowL( (CCoeControl*)iParentWg );
+ EnableWindowTransparency();
+ iParentWg = NULL;
+ iCbaFlags &= ~EEikCbaFlagTransparent;
+ }
+ else
+ {
+ CreateWindowL( iParentWg );
+
+ if ( ( ( iCbaFlags & EEikCbaFlagTransparent ) ||
+ iCbaFlags & EEikCbaFlagSemiTransparent ) &&
+ CAknEnv::Static()->TransparencyEnabled() )
+ {
+ Window().SetRequiredDisplayMode( EColor16MA ); // Without this, ACT does not work in all cases in HW
+ TInt err = Window().SetTransparencyAlphaChannel();
+
+ if ( err == KErrNone )
+ {
+ // Set the window initially completely transparent. This needs to be called only once.
+ Window().SetBackgroundColor(~0);
+ }
+ else
+ {
+ // SetTransparencyAlphaChannel returned an error.
+ // Revert back to non-transparent CBA.
+ iCbaFlags &= ~EEikCbaFlagTransparent;
+ }
+ }
+ else
+ {
+ // Transparency not supported or not enabled
+ iCbaFlags &= ~EEikCbaFlagTransparent;
+ }
+ }
+
+ iExtension = CEikCbaExtension::NewL( *this );
+ //create bitmap for semi-transparent background
+ if ( iCbaFlags & EEikCbaFlagSemiTransparent && iExtension )
+ {
+ iExtension->iSemiBgID = KAknsIIDQsnHomeBgWidget;
+ iExtension->iSemiBgCenterID = KAknsIIDQsnHomeBgWidgetCenter;
+ }
+
+ // Skin background is not drawn by embedded CBA.
+ if ( !iFlags.IsSet( ECbaEmbedded ) )
+ {
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ // Construct background control context, SizeChanged will update
+ // the layout rectangle.
+ iBgIID = AknStatuspaneUtils::IdleLayoutActive() ?
+ KAknsIIDQsnBgAreaControlIdle :
+ KAknsIIDQsnBgAreaControl;
+
+ iMLBgContext = CAknsMaskedLayerBackgroundControlContext::NewL(
+ KAknsIIDWallpaper,
+ TRect( 0, 0, 1, 1 ),
+ ETrue,
+ 2 );
+
+ // Other context for staconpane
+
+ // There is a need for two layers in each context: one for wallpaper,
+ // the other for skin graphics.
+ iStaconBgContextTop = CAknsMaskedLayerBackgroundControlContext::NewL(
+ KAknsIIDWallpaper, TRect( 0, 0, 1, 1 ), ETrue, ECbaLayerN );
+ iStaconBgContextBottom = CAknsMaskedLayerBackgroundControlContext::NewL(
+ KAknsIIDWallpaper, TRect( 0, 0, 1, 1 ), ETrue, ECbaLayerN );
+
+ for ( TInt i = 0; i < ECbaLayerN; i++ )
+ {
+ iStaconBgContextBottom->SetLayerImage( i, KAknsIIDNone );
+ }
+
+ TAknWindowLineLayout layout( AknLayoutScalable_Avkon::area_top_pane(2).LayoutLine() );
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( screen, layout );
+ TRect staconTop( layoutRect.Rect() );
+
+ layout = AknLayoutScalable_Avkon::area_bottom_pane(2).LayoutLine();
+ layoutRect.LayoutRect( screen, layout );
+ TRect staconBottom( layoutRect.Rect() );
+
+ // Set layers to stacon contexts.
+ // Set bottom as parent to top, so that top is re-drawn, if bottom is drawn.
+ iStaconBgContextTop->SetLayerImage( ECbaLayerWallpaper, KAknsIIDWallpaper );
+ iStaconBgContextTop->SetLayerRect( ECbaLayerWallpaper, screen );
+ iStaconBgContextTop->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconRt );
+ iStaconBgContextTop->SetLayerRect( ECbaLayerBackground, staconTop );
+
+ iStaconBgContextBottom->SetLayerImage( ECbaLayerWallpaper, KAknsIIDWallpaper );
+ iStaconBgContextBottom->SetLayerRect( ECbaLayerWallpaper, screen );
+ iStaconBgContextBottom->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconRb );
+ iStaconBgContextBottom->SetLayerRect( ECbaLayerBackground, staconBottom );
+ iStaconBgContextBottom->SetParentPos( TPoint( 0, 0 ) );
+
+ iStaconBgContextTop->SetParentContext( iStaconBgContextBottom );
+
+ TBool idle = AknLayoutFlags() & EAknLayoutCbaInStaconPaneIdle;
+ if ( idle )
+ {
+ iStaconBgContextTop->SetLayerMaskAndSizeL( KAknsIIDQgnGrafBgLscTopMaskIcon, staconTop );
+ iStaconBgContextBottom->SetLayerMaskAndSizeL( KAknsIIDQgnGrafBgLscBottomMaskIcon, staconBottom );
+ }
+
+ }
+
+ iExtension->UpdateSoftkeyFrameL( EFalse );
+
+ CRepository* cenRep = NULL;
+ TRAPD(err, cenRep = CRepository::NewL( KCRUidAvkon ));
+ if (!err)
+ {
+ err = cenRep->Get( KAknMiddleSoftkeyEnabled, iMSKEnabledInPlatform );
+ delete cenRep;
+ }
+
+ RWindow& window = Window();
+ window.SetPointerGrab(ETrue);
+ EnableDragEvents();
+ window.SetShadowDisabled(ETrue);
+ if ( ! ( iCbaFlags & EEikCbaFlagTransparent ) )
+ {
+ window.SetBackgroundColor(iEikonEnv->ControlColor(EColorToolbarBackground, *this));
+ }
+ CEikControlGroup::ConstructL(CEikControlGroup::EFromBottomLeft, CEikControlGroup::ELayHorizontally);
+ SetLengthInPixels(iAvkonAppUi->ApplicationRect().Width());
+ SetNumberOfLines(1, ETrue);
+ iBrushAndPenContext = CCoeBrushAndPenContext::NewL();
+ CheckSkinAndUpdateContext();
+ iBrushAndPenContext->SetBrushColor(iEikonEnv->ControlColor(EColorToolbarBackground, *this));
+ iBrushAndPenContext->SetPenColor(iEikonEnv->ControlColor(EColorToolbarText, *this));
+ SetControlContext(iBrushAndPenContext);
+ iEikonEnv->EikAppUi()->AddToStackL(this, ECoeStackPriorityCba, ECoeStackFlagRefusesFocus);
+ UpdateFonts();
+
+ SetMSKVisibility( MskAllowed() );
+
+ if ( !iFlags.IsSet( ECbaEmbedded ) )
+ {
+ if ( AknStatuspaneUtils::ExtendedFlatLayoutActive() )
+ {
+ // Store the current skin background ID of the clock and indicator
+ // pane area to draw their background correctly if custom CBA
+ // background is used.
+ CEikStatusPaneBase* sp = CEikStatusPaneBase::Current();
+ if ( sp )
+ {
+ iClockIndicBgIID = sp->CbaAreaBackgroundID();
+ if ( iClockIndicBgIID == KAknsIIDQsnBgAreaControlMp )
+ {
+ // Skin background ID needs to be reverted back
+ // in destructor.
+ iIsClockIndicBgIIDSet = ETrue;
+ }
+ sp->SetCbaAreaBackgroundID( iBgIID, CEikStatusPaneBase::EDrawDeferred );
+ }
+ else
+ {
+ // Default value.
+ iClockIndicBgIID = KAknsIIDQsnBgAreaControl;
+ }
+ }
+ }
+ }
+
+void CEikCba::ConstructL(TInt aResourceId)
+ {
+ if (aResourceId != KNoResource)
+ {
+ TResourceReader reader;
+ iCoeEnv->CreateResourceReaderLC(reader, aResourceId);
+ iCbaFlags = reader.ReadInt32(); // flags resource
+
+ // If using enhanced cba.
+ if ( (iCbaFlags & EEikEnhancedButtonGroup) == EEikEnhancedButtonGroup )
+ {
+#ifdef RD_ENHANCED_CBA
+ iCommandTable = CEikCommandTable::NewL();
+ BaseConstructL();
+ CreateScrollBarFrameL();
+
+ iSize.iWidth = reader.ReadInt16();
+ reader.ReadInt32(); // Skip related buttons resource.
+ TInt count( reader.ReadInt16() ); // Read the amount of enhanced cba buttons.
+
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ TUint8 version( (TUint8)reader.ReadUint8() );
+ TInt commandId( 0 );
+ TInt longCommandId( 0 );
+ CEikEnhancedCbaButton* button = new (ELeave) CEikEnhancedCbaButton;
+ button->SetTextBitmapMode( iExtension->iEnablePostingTransparency );
+ CleanupStack::PushL( button );
+
+ if( version == EEikCbaButtonLink )
+ {
+ TInt aButtonId( reader.ReadInt32() ); // Read ENHANCED_CBA_BUTTON id from LLINK.
+ TResourceReader linkReader; // Reader for reading linked resource.
+ iCoeEnv->CreateResourceReaderLC( linkReader, aButtonId );
+ TUint8 ver( linkReader.ReadUint8() );
+ if( ver == EEikEnhancedCbaButton )
+ {
+ button->ConstructFromResourceL( linkReader );
+ }
+ CleanupStack::PopAndDestroy( ); // linkReader
+ }
+ else if( version == EEikEnhancedCbaButton )
+ {
+ button->ConstructFromResourceL( reader );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( button );
+ continue; // Jump over the rest.
+ }
+
+ iCommandTable->AddCommandL( button ); // Transfers ownership.
+ CleanupStack::Pop( button );
+ }
+
+ // Set observer and add to control group if placed in the command table.
+ for ( TInt i = 0; i < KMaxButtonsInCommandTable; i++ )
+ {
+ CEikEnhancedCbaButton* button = iCommandTable->Command( i );
+ if( button )
+ {
+ button->SetObserver( Observer() );
+ button->SetLabelFont( iLabelFont );
+
+ TEikGroupControl groupCtrl(
+ button,
+ button->CommandId(),
+ button->Size().iWidth,
+ TEikGroupControl::ESetLength);
+
+ groupCtrl.iLongId = 0;
+ AddControlL(groupCtrl); // Transfers ownership.
+ }
+ else
+ {
+ // Add dummy button if no command for this index.
+ button = new (ELeave) CEikEnhancedCbaButton;
+ button->SetTextBitmapMode( iExtension->iEnablePostingTransparency );
+ CleanupStack::PushL( button );
+ button->ConstructEmptyButtonL();
+ CleanupStack::Pop( button );
+
+ TEikGroupControl groupCtrl(
+ button,
+ button->CommandId(),
+ button->Size().iWidth,
+ TEikGroupControl::ESetLength);
+
+ AddControlL(groupCtrl);
+ }
+ }
+
+ InsertScrollBarL();
+
+ // This needs to be after all buttons are inserted to control group.
+ SetBoundingRect(TRect());
+
+ ActivateL();
+#else // RD_ENHANCED_CBA
+ User::Leave( KErrNotSupported );
+#endif // RD_ENHANCED_CBA
+ }
+ else // Not using enhanced cba.
+ {
+ reader.Rewind(4);
+ ConstructFromResourceL(reader);
+ }
+
+ CleanupStack::PopAndDestroy(); // reader
+ }
+ else // aResourceId == KNoResource
+ {
+ BaseConstructL();
+ CreateScrollBarFrameL();
+ // Alignments for left, right and MSK.
+ TGulAlignmentValue anAlignment[3] = {EHLeftVCenter, EHRightVCenter, EHCenterVCenter};
+ const TInt commands = MaxCommands();
+
+ for (TInt ii = 0; ii < commands; ii++)
+ {
+ CEikCbaButton* button = new(ELeave) CEikCbaButton;
+ button->SetTextBitmapMode( iExtension->iEnablePostingTransparency );
+ button->SetObserver(Observer());
+ CleanupStack::PushL(button);
+ button->ConstructL(anAlignment[ii]);
+
+ // Initialise button size.
+ if(Orientation() == ELayHorizontally)
+ {
+ TSize buttonSize((MinimumSize().iWidth) / commands, button->MinimumSize().iHeight);
+ button->SetSize(buttonSize);
+ }
+
+ TEikGroupControl groupCtrl(button, ii, 0, TEikGroupControl::EAllowStretch);
+ AddControlL(groupCtrl);
+ button->SetLabelFont(iLabelFont);
+ CleanupStack::Pop( button );
+ }
+
+ InsertScrollBarL(); // into control group
+ iMSKset = EFalse;
+
+ // This needs to be after all buttons are inserted to control group.
+ SetBoundingRect(TRect());
+
+ if ( !iFlags.IsSet( ECbaActivationDelayed ) )
+ {
+ ActivateL();
+ }
+
+ // We need to activate MSK in here - it won't be otherwise activated in landscape.
+ if ( iMSKEnabledInPlatform && AknLayoutUtils::MSKEnabled() &&
+ iControlArray->Count() == (MaxCommands() + 1) ) // scrollbar added
+ {
+ if ( (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl )
+ {
+ (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl->ActivateL();
+ }
+ }
+ }
+
+ // Set CBA faded in case the softkeys are empty.
+ SetFadeState();
+ }
+
+
+void CEikCba::ConstructFromResourceL(TResourceReader& aReader)
+ {
+ BaseConstructL();
+ CreateScrollBarFrameL();
+ TGulAlignmentValue anAlignment[3] = {EHLeftVCenter, EHRightVCenter, EHCenterVCenter};
+ iCbaFlags = aReader.ReadInt32(); // flags resource
+ iSize.iWidth = aReader.ReadInt16();
+ aReader.ReadInt32(); // Skip related buttons resource.
+
+ // Ignore any commands that won't fit on screen.
+ TInt count = Min(aReader.ReadInt16(), MaxCommands());
+ __ASSERT_DEBUG(iControlArray->Count() <= count + 2, Panic(EEikPanicCBAControlArraySize));
+
+ for (TInt ii = 0; ii < count; ii++)
+ {
+ TUint8 version = (TUint8)aReader.ReadUint8();
+ TInt commandId;
+ TInt longCommandId;
+ if (version == KAknCbaVersion)
+ {
+ commandId = aReader.ReadInt16();
+ longCommandId = aReader.ReadInt16();
+ }
+ else
+ {
+ commandId = aReader.ReadInt16();
+ longCommandId = 0;
+ }
+ CEikCbaButton* button = new(ELeave) CEikCbaButton;
+ button->SetTextBitmapMode( iExtension->iEnablePostingTransparency );
+ button->SetObserver(Observer());
+ CleanupStack::PushL(button);
+ button->ConstructFromResourceL(aReader, anAlignment[ii]);
+ // Initialise button size.
+ if(Orientation() == ELayHorizontally)
+ {
+ TSize buttonSize((MinimumSize().iWidth)/count, button->MinimumSize().iHeight);
+ button->SetSize(buttonSize);
+ }
+ TEikGroupControl groupCtrl(
+ button,
+ commandId,
+ button->Size().iWidth,
+ TEikGroupControl::ESetLength);
+
+ groupCtrl.iLongId = longCommandId;
+ AddControlL(groupCtrl);
+ button->SetLabelFont(iLabelFont);
+ CleanupStack::Pop( button );
+ }
+
+ InsertScrollBarL(); // into control group
+ iMSKset = ETrue;
+
+ // MSK is not mandatory, so add empty button if resource not found.
+ if (iControlArray->Count() < MaxCommands() + 1) // scrollbar added
+ {
+ iMSKset = EFalse;
+ CEikCbaButton* button = new (ELeave) CEikCbaButton;
+ button->SetTextBitmapMode( iExtension->iEnablePostingTransparency );
+ CleanupStack::PushL( button );
+ button->ConstructEmptyButtonL();
+ CleanupStack::Pop( button );
+ TEikGroupControl groupCtrl(button, 0, button->Size().iWidth,TEikGroupControl::ESetLength);
+ AddControlL(groupCtrl);
+ }
+
+ // This needs to be after all buttons are inserted to control group.
+ if (iMSKset)
+ {
+ SetMSKIconL();
+ }
+
+ SetBoundingRect(TRect());
+
+ if ( !iFlags.IsSet( ECbaActivationDelayed ) )
+ {
+ ActivateL();
+ }
+
+ // We need to activate MSK in here - it won't be otherwise activated in landscape.
+ if ( iMSKEnabledInPlatform && AknLayoutUtils::MSKEnabled() &&
+ iControlArray->Count() == (MaxCommands() + 1) ) // scrollbar added
+ {
+ if ( (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl )
+ {
+ (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl->ActivateL();
+ }
+ }
+
+ // Set CBA faded in case the softkeys are empty.
+ SetFadeState();
+ }
+
+
+TInt CEikCba::MaxCommands() const
+ {
+ return KMaxSeries60Softkeys;
+ }
+
+TInt CEikCba::MSKEnabledInPlatform() const
+ {
+ return iMSKEnabledInPlatform;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Sets the middle softkey icon.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::SetMSKIconL()
+ {
+ // MSK is not supported by dialog-embedded CBAs.
+ if ( iFlags.IsSet( ECbaInsideDialog ) || iFlags.IsSet( ECbaEmbedded ) )
+ {
+ return;
+ }
+
+ if ( !MskAllowed() )
+ {
+ return;
+ }
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ if ( !skin )
+ {
+ return;
+ }
+ if( iExtension->iIfMskIconSet )
+ {
+ // UpdateIconL();
+ return;
+ }
+ TEikGroupControl &gCtrl = iControlArray->At( KControlArrayCBAButtonMSKPosn );
+
+ CEikCbaButton *button = static_cast<CEikCbaButton*>( gCtrl.iControl );
+ if ( !button )
+ {
+ return;
+ }
+
+ CFbsBitmap *bitmap = NULL;
+ CFbsBitmap *mask = NULL;
+
+ TAknLayoutRect qgn_graf_sk_msk;
+ TRect rect;
+ qgn_graf_sk_msk.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::control_pane_g4( 0 ).LayoutLine() );
+
+ TSize iconSize( qgn_graf_sk_msk.Rect().Width(),
+ qgn_graf_sk_msk.Rect().Height() );
+ TInt leftId = (*iControlArray)[KControlArrayCBAButton1Posn].iId;
+
+ TRgb MSKColor;
+ TInt errorMSK;
+
+ TInt iconColorId(0);
+ TInt leftCBAColorId(0);
+
+ TBool idleState = AknStatuspaneUtils::IdleLayoutActive();
+ if ( idleState )
+ {
+ iconColorId = EAknsCIQsnIconColorsCG28;
+ leftCBAColorId = EAknsCIQsnTextColorsCG15;
+
+ errorMSK = AknsUtils::GetCachedColor(
+ skin,
+ MSKColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG57 );
+ }
+ else if ( iPopupVisible )
+ {
+ iconColorId = EAknsCIQsnIconColorsCG29;
+ leftCBAColorId = EAknsCIQsnTextColorsCG17;
+
+ errorMSK = AknsUtils::GetCachedColor(
+ skin,
+ MSKColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG58 );
+ }
+ else
+ {
+ iconColorId = EAknsCIQsnIconColorsCG27;
+ leftCBAColorId = EAknsCIQsnTextColorsCG13;
+
+ errorMSK = AknsUtils::GetCachedColor(
+ skin,
+ MSKColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG56 );
+ }
+
+ if ( errorMSK )
+ {
+ // Use black if no color specified for MSK in skin.
+ MSKColor = KRgbBlack;
+ AknsUtils::GetCachedColor( skin,
+ MSKColor,
+ KAknsIIDQsnTextColors,
+ leftCBAColorId );
+ }
+
+ if ( gCtrl.iId == EAknSoftkeyContextOptions )
+ {
+ // Set context specific options menu icon.
+ AknsUtils::CreateColorIconL(
+ skin,
+ KAknsIIDQgnPropMskMenu,
+ KAknsIIDQsnIconColors,
+ iconColorId, // There is no color for icon -> use text color.
+ bitmap,
+ mask,
+ KAvkonBitmapFile,
+ EMbmAvkonQgn_prop_msk_menu,
+ EMbmAvkonQgn_prop_msk_menu_mask,
+ MSKColor );
+ }
+ else if ( gCtrl.iId == EAknSoftkeyDialler )
+ {
+ // Set context specific options menu icon.
+ AknsUtils::CreateColorIconL(
+ skin,
+ KAknsIIDQgnIndiTpDialler,
+ KAknsIIDQsnIconColors,
+ iconColorId, // There is no color for icon -> use text color.
+ bitmap,
+ mask,
+ KAvkonBitmapFile,
+ EMbmAvkonQgn_indi_tp_dialler,
+ EMbmAvkonQgn_indi_tp_dialler_mask,
+ MSKColor );
+ }
+ else if ( leftId == gCtrl.iId)
+ {
+ if ( leftId != EEikBidBlank &&
+ leftId != EAknSoftkeyEmpty &&
+ leftId != 0 )
+ {
+ // Same as left softkey icon.
+ AknsUtils::CreateColorIconL(
+ skin,
+ KAknsIIDQgnPropMskSelect,
+ KAknsIIDQsnIconColors,
+ iconColorId, // There is no color for icon -> use text color.
+ bitmap,
+ mask,
+ KAvkonBitmapFile,
+ EMbmAvkonQgn_prop_msk_select,
+ EMbmAvkonQgn_prop_msk_select_mask,
+ MSKColor );
+ }
+ }
+
+ if ( bitmap ) // Bitmap not set -> do not use image.
+ {
+ AknIconUtils::DisableCompression( bitmap );
+ AknIconUtils::DisableCompression( mask );
+ AknIconUtils::SetSize( bitmap, iconSize );
+
+ CEikImage* image = new (ELeave) CEikImage;
+ image->SetPicture( bitmap, mask );
+
+ // Transfers ownership of the image (image owns bitmap and mask).
+ button->SetImage( *image );
+ }
+ else
+ {
+ button->ReplaceImageByLabel(); // remove old image
+ }
+
+ button->SetContainerWindowL( *this );
+ }
+
+EXPORT_C TBool CEikCba::UpdateMSKIconL( const TAknsItemID& aId,
+ const TDesC& aBmpFile,
+ const TInt32 aBmp,
+ const TInt32 aBmpM,
+ TBool aEnable )
+ {
+ iExtension->iIfMskIconSet = EFalse;
+
+ // MSK is not supported by dialog-embedded CBAs.
+ if (!aEnable)
+ {
+ SetMSKIconL();
+ return ETrue;
+ }
+
+ delete iExtension->iBmpFile;
+ iExtension->iBmpFile = NULL;
+ iExtension->iBmpFile = aBmpFile.AllocL();
+
+ iExtension->iIfMskIconSet = ETrue;
+ iExtension->iMSKSkinID = aId;
+
+ iExtension->iBmp = aBmp;
+ iExtension->iBmpM = aBmpM;
+
+ return UpdateIconL();
+ }
+
+
+// ----------------------------------------------------------------------------
+// CEikCba::EnableItemSpecificSoftkey
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CEikCba::EnableItemSpecificSoftkey( TBool aEnable )
+ {
+ if ( iFlags.IsSet( ECbaSingleClickEnabled ) )
+ {
+ iFlags.Assign( ECbaItemSpecificSoftkeyInUse, aEnable );
+
+ if ( aEnable )
+ {
+ UpdateItemSpecificSoftkey();
+ }
+ else
+ {
+ TEikGroupControl& leftSoftkey =
+ ( *iControlArray )[KControlArrayCBAButton1Posn];
+
+ if ( !iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ leftSoftkey.iControl->MakeVisible( ETrue );
+ }
+ else
+ {
+ leftSoftkey.iControl->SetDimmed( EFalse );
+ leftSoftkey.iControl->DrawDeferred();
+ }
+ }
+ }
+ }
+
+
+void CEikCba::SetMSKCommandObserver(MEikCommandObserver* aCommandObserver)
+ {
+ // aCommandObserver set to NULL when removing observer.
+ iMSKCommandObserver = aCommandObserver;
+ }
+
+void CEikCba::UpdateCbaLabels(TBool aScrollerOn)
+ {
+ // This method is called only from scrollbar that has nothing to do with
+ // dialog-embedded CBAs -> ignore the call.
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ return;
+ }
+
+ // Communicate change to CBA buttons.
+ for (TInt ii = 0; ii < iControlArray->Count(); ii++)
+ {
+ if (ii != KControlArrayScrollBarPosn) // To avoid tinkering with scrollbar.
+ {
+ TEikGroupControl& gCtrl = iControlArray->At(ii);
+ CEikCbaButton* button = STATIC_CAST(CEikCbaButton*, gCtrl.iControl);
+ TRAP_IGNORE(button->SwitchToShortTextL(aScrollerOn));
+ }
+ }
+ // Change of text may affect layout.
+ SizeChanged();
+ DrawDeferred() ;
+ }
+
+void CEikCba::SetSBFrameObserver(MEikScrollBarObserver* aObserver)
+ {
+ if(iSBFrame)
+ {
+ iSBFrame->SetScrollBarFrameObserver(aObserver);
+ }
+ }
+
+void CEikCba::SetScrollBarModelL(TEikScrollBarModel* aModel)
+ {
+ if(iSBFrame)
+ {
+ VScrollBarAsControl()->SetModelL(aModel);
+ }
+ }
+
+const CEikCbaScrollBarFrame* CEikCba::ScrollBarFrame() const
+ {
+ return STATIC_CAST(const CEikCbaScrollBarFrame*, iSBFrame);
+ }
+
+CAknScrollBar* CEikCba::VScrollBarAsControl()
+ {
+ return STATIC_CAST(CAknScrollBar*, VScrollBarAsGroupControl().iControl);
+ }
+
+void CEikCba::InsertControlL(TEikGroupControl& aGroupControl,TInt aIndex)
+ {
+ iControlArray->InsertL(aIndex,aGroupControl); // Takes ownership at this point.
+ }
+
+
+void CEikCba::SetCommandL( TInt aPosition,
+ TInt aCommandId,
+ const TDesC* aText,
+ const CFbsBitmap* /*aBitmap*/,
+ const CFbsBitmap* /*aMask*/ )
+ {
+ // We need to check if this call changes the softkeys from being
+ // empty to having a command or vice versa to be able to maintain
+ // correct fade state.
+ TBool isEmptyBefore( IsEmpty() );
+
+ TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
+ groupCtrl.iId = aCommandId;
+ groupCtrl.iLongId = 0;
+ if ( !iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ if ( aText )
+ {
+ static_cast<CEikCbaButton*>(
+ groupCtrl.iControl )->AddCommandL( *aText );
+ }
+
+ if ( aPosition == KControlArrayCBAButtonMSKPosn )
+ {
+ iMSKset = ETrue;
+ }
+ SetMSKIconL(); // If MSK or left CBA was changed, this sets MSK icon accordingly.
+
+ // Force labels to be re-formatted...
+ SizeChanged();
+ }
+ else if ( aPosition != KControlArrayCBAButtonMSKPosn )
+ {
+ CAknButton* button = static_cast<CAknButton*>( groupCtrl.iControl );
+ CAknCommandButtonState* buttonState =
+ static_cast<CAknCommandButtonState*>( button->State() );
+ buttonState->SetTextL( *aText );
+ buttonState->SetCommand( aCommandId );
+ }
+
+ TBool isEmptyAfter( IsEmpty() );
+
+ if ( !COMPARE_BOOLS( isEmptyBefore, isEmptyAfter ) )
+ {
+ SetFadeState();
+ }
+
+ ReportContentChangedEvent();
+ }
+
+
+void CEikCba::SetCommandL(TInt aPosition,TInt aResourceId)
+ {
+ TResourceReader reader;
+ iCoeEnv->CreateResourceReaderLC(reader,aResourceId);
+ TInt version = reader.ReadInt8(); // version
+
+#ifdef RD_ENHANCED_CBA
+ if( version == EEikCbaButtonLink )
+ {
+ TInt aButtonId = reader.ReadInt32(); // Read ENHANCED_CBA_BUTTON id from LLINK.
+ CleanupStack::PopAndDestroy(); // reader
+ iCoeEnv->CreateResourceReaderLC( reader, aButtonId );
+ TUint8 aVersion = reader.ReadUint8();
+
+ // Panics if linked resource is not enhanced cba button.
+ __ASSERT_DEBUG( aVersion == EEikEnhancedCbaButton, Panic(EEikPanicCBAIsNotEnhancedCba) );
+
+ reader.ReadUint8(); // commandType
+ }
+ else if( version == EEikEnhancedCbaButton )
+ {
+ reader.ReadUint8(); // commandType
+ }
+#endif // RD_ENHANCED_CBA
+ TInt commandId(0);
+ if (version == KAknCbaVersion)
+ {
+ commandId = reader.ReadInt16();
+ reader.ReadInt16();
+ }
+ else
+ {
+ commandId = reader.ReadInt16();
+ }
+
+ TPtrC text = reader.ReadTPtrC();
+ SetCommandL(aPosition, commandId, &text, NULL, NULL);
+ CleanupStack::PopAndDestroy(); // reader
+
+ ReportContentChangedEvent();
+ }
+
+/**
+* Installs a new set of commands to be associated with the cba buttons.
+* The previous command set is restored if there is an error while adding
+* the new command set.
+*/
+void CEikCba::SetCommandSetL(TInt aResourceId)
+ {
+ TResourceReader reader;
+ iCoeEnv->CreateResourceReaderLC(reader, aResourceId);
+
+ iCbaFlags = reader.ReadInt32();
+
+ if ( ( iCbaFlags & EEikEnhancedButtonGroup ) == EEikEnhancedButtonGroup )
+ {
+ CleanupStack::PopAndDestroy(); // reader
+ OfferCommandListL( aResourceId );
+ return;
+ }
+
+ SetButtonGroupFlags( iCbaFlags );
+ reader.ReadInt16(); // Skip width resource.
+ reader.ReadInt32(); // Skip related buttons resource.
+ const TInt maxCommands = MaxCommands();
+
+ // Ignore any commands that won't fit on screen.
+ TInt count = Min(reader.ReadInt16(), maxCommands);
+
+ TInt previousIds[KMaxSeries60Softkeys + 1]; // Uses 16 bytes stack, +1 for scrollbar.
+
+ __ASSERT_DEBUG(iControlArray->Count() <= count + 2, Panic(EEikPanicCBAControlArraySize));
+
+ // Replace the existing command set.
+ TInt controlId = 0;
+ for (controlId = 0; controlId < count + 1; controlId++) // (+1 for scroll bar)
+ {
+ if (controlId != KControlArrayScrollBarPosn) // To avoid tinkering with scrollbar.
+ {
+ // Store the existing commands.
+ TEikGroupControl& groupCtrl = (*iControlArray)[controlId];
+ previousIds[controlId] = groupCtrl.iId;
+ TUint8 version = (TUint8)reader.ReadUint8();
+ TInt commandId;
+ TInt errorcode;
+
+ if (version == KAknCbaVersion)
+ {
+ commandId = reader.ReadInt16();
+ reader.ReadInt16(); // Skip long command id.
+ }
+ else
+ {
+ commandId = reader.ReadInt16();
+ }
+ TPtrC text=reader.ReadTPtrC();
+ reader.ReadTPtrC(); // bmp filename
+ reader.ReadInt16(); // bmp id
+ reader.ReadInt16(); // bmp mask id
+
+ // Add the new commands.
+ TRAP(errorcode, AddCommandToStackWithoutSizeChangedL(controlId, commandId, &text));
+ if (errorcode) // In case of error restore previous commands before leave.
+ {
+ if (controlId > 0)
+ {
+ for (TInt counter = 0; counter < controlId; counter++)
+ {
+ // Do not deal with the scroller as a CEikCbaButton; skip its index.
+ if (counter != KControlArrayScrollBarPosn)
+ {
+ RemoveCommandFromStack(counter,previousIds[counter]);
+ }
+ }
+ }
+ User::Leave(errorcode);
+ }
+ }
+ }
+
+ // Remove the original commands from the temporary store.
+ for (controlId = 0; controlId < count + 1; controlId++) // +1 for scroll bar
+ {
+ if (controlId != KControlArrayScrollBarPosn)
+ {
+ TInt controlPosition = controlId;
+ if (controlId > 1)
+ {
+ controlPosition-=1;
+ }
+ RemovePreviousCommandWithoutSizeChanged(controlId);
+ }
+ }
+ SetMSKIconL();
+ // If MSK was not defined in softkey resources, set MSK command id same as left
+ // softkey's command id and set label empty.
+ // We can't restore original commands any more, so if setting MSK fails,
+ // at least left and right softkeys are set.
+ if (count < KControlArrayCBAButtonMSKPosn)
+ {
+ TRAP_IGNORE( SetCommandL(
+ KControlArrayCBAButtonMSKPosn,
+ (*iControlArray)[KControlArrayCBAButton1Posn].iId,
+ &KNullDesC,
+ NULL,
+ NULL) );
+
+ iMSKset = ETrue;
+ }
+ else
+ {
+ SetMSKIconL(); // If MSK id was changed, this sets MSK icon accordingly.
+ }
+
+ CleanupStack::PopAndDestroy(); // reader
+
+ // Force labels to be re-formatted...
+ SizeChanged();
+ ReportContentChangedEvent();
+ }
+
+void CEikCba::AddCommandL(TInt /*aPosition*/, TInt /*aCommandId*/, const TDesC* /*aText*/,
+ const CFbsBitmap* /*aBitmap*/, const CFbsBitmap* /*aMask*/)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+
+void CEikCba::AddCommandToStackWithoutSizeChangedL(TInt aPosition,
+ TInt aCommandId,
+ const TDesC* aText)
+ {
+ // We need to check if this call changes the softkeys from being
+ // empty to having a command or vice versa to be able to maintain
+ // correct fade state.
+ TBool isEmptyBefore( IsEmpty() );
+
+ TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
+
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ CAknButton* button = static_cast<CAknButton*>( groupCtrl.iControl );
+ button->AddStateL( NULL, NULL, NULL, NULL, *aText, KNullDesC, 0, aCommandId );
+
+ if ( aText->Length() == 0 || !aText->Compare( _L(" ") ) )
+ {
+ button->SetDimmed( ETrue );
+ }
+
+ TInt state( button->StateIndex() + 1 );
+
+ // DrawDeferred must be used here to reduce flicker,
+ // as ECS may cause unnecessary CBA label updates in queries.
+ button->SetCurrentState( state, EFalse );
+ button->DrawDeferred();
+ }
+ else
+ {
+ static_cast<CEikCbaButton*>(groupCtrl.iControl)->PushCommandL(groupCtrl.iId /*aCommandId*/,
+ *aText);
+ }
+
+ groupCtrl.iId = aCommandId;
+ groupCtrl.iLongId = 0;
+
+ if ( aPosition == KControlArrayCBAButtonMSKPosn )
+ {
+ iMSKset = ETrue;
+ }
+ SetMSKIconL(); // If MSK id was changed, this sets MSK icon accordingly.
+
+ TBool isEmptyAfter( IsEmpty() );
+
+ if ( !COMPARE_BOOLS( isEmptyBefore, isEmptyAfter ) )
+ {
+ SetFadeState();
+ }
+
+ ReportContentChangedEvent();
+ }
+
+void CEikCba::AddCommandToStackL( TInt aPosition,
+ TInt aCommandId,
+ const TDesC* aText,
+ const CFbsBitmap* /*aBitmap*/,
+ const CFbsBitmap* /*aMask*/ )
+ {
+
+ AddCommandToStackWithoutSizeChangedL( aPosition, aCommandId, aText);
+ // Force labels to be re-formatted...
+ SizeChanged();
+ }
+
+
+void CEikCba::AddCommandToStackL(TInt aPosition, TInt aResourceId)
+ {
+ TResourceReader reader;
+ iCoeEnv->CreateResourceReaderLC(reader,aResourceId);
+ TUint8 version = (TUint8)reader.ReadInt8();
+ TInt commandId(0);
+ if (version == KAknCbaVersion)
+ {
+ commandId = reader.ReadInt16();
+ reader.ReadInt16(); // Skip long command id.
+ }
+ else
+ {
+ commandId = reader.ReadInt16();
+ }
+ TPtrC text=reader.ReadTPtrC();
+ AddCommandToStackL(aPosition, commandId, &text, NULL, NULL);
+ CleanupStack::PopAndDestroy(); // reader
+
+ ReportContentChangedEvent();
+ }
+
+void CEikCba::AddCommandSetToStackL(TInt aResourceId)
+ {
+ TResourceReader reader;
+ iCoeEnv->CreateResourceReaderLC(reader,aResourceId);
+
+ iCbaFlags = reader.ReadInt32(); // Flags resource.
+ reader.ReadInt16(); // Skip width resource.
+ reader.ReadInt32(); // Skip related buttons resource.
+
+ SetButtonGroupFlags( iCbaFlags );
+ // Ignore any commands that won't fit on screen.
+ const TInt maxCommands = MaxCommands();
+ const TInt count = Min(reader.ReadInt16(), maxCommands);
+
+ __ASSERT_DEBUG(iControlArray->Count() <= count + 2, Panic(EEikPanicCBAControlArraySize));
+
+ for (TInt ii = 0; ii < count + 1; ii++) // +1 for scroll bar
+ {
+ if (ii != KControlArrayScrollBarPosn) // To avoid tinkering with the scrollbar.
+ {
+ TUint8 version = (TUint8)reader.ReadUint8();
+ TInt commandId;
+
+ if (version == KAknCbaVersion)
+ {
+ commandId = reader.ReadInt16();
+ reader.ReadInt16(); // Skip long command id.
+ }
+ else
+ {
+ commandId = reader.ReadInt16();
+ }
+ TPtrC text = reader.ReadTPtrC();
+ reader.ReadTPtrC(); // bmp filename
+ reader.ReadInt16(); // bmp id
+ reader.ReadInt16(); // bmp mask id
+ TInt errorcode;
+ TRAP(errorcode, AddCommandToStackWithoutSizeChangedL(ii, commandId, &text));
+ if (errorcode) // Restore previous commands before leave.
+ {
+ if (ii > 0)
+ {
+ for (TInt counter = 0; counter < ii; counter++)
+ {
+ if (counter != KControlArrayScrollBarPosn)
+ {
+ TEikGroupControl& groupCtrl = (*iControlArray)[counter];
+
+ groupCtrl.iId =
+ STATIC_CAST(CEikCbaButton*, groupCtrl.iControl)->PopCommand();
+
+ groupCtrl.iLongId = 0;
+ }
+ }
+ }
+ User::Leave(errorcode);
+ }
+ }
+ }
+
+ if (count == KControlArrayCBAButtonMSKPosn)
+ {
+ iMSKset = ETrue;
+ }
+ SetMSKIconL(); // If MSK id was changed, this sets MSK icon accordingly.
+
+ CleanupStack::PopAndDestroy(); // reader
+
+ // Force labels to be re-formatted...
+ SizeChanged();
+ ReportContentChangedEvent();
+ }
+
+void CEikCba::SetDefaultCommand(TInt /*aCommandId*/)
+ {
+ }
+
+TSize CEikCba::CalcMinimumSizeL(TInt /*aResourceId*/)
+ {
+ return MinimumSize();
+ }
+
+
+void CEikCba::RemoveCommandFromStack( TInt aPosition, TInt aCommandId )
+ {
+ // We need to check if this call changes the softkeys from being
+ // empty to having a command or vice versa to be able to maintain
+ // correct fade state.
+ TBool isEmptyBefore( IsEmpty() );
+
+ TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
+ if ( groupCtrl.iId == aCommandId )
+ {
+ // Command to be removed is topmost.
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ CAknButton* button = static_cast<CAknButton*>( groupCtrl.iControl );
+ button->RemoveCurrentState();
+
+ CAknCommandButtonState* buttonState =
+ static_cast<CAknCommandButtonState*>( button->State() );
+
+ groupCtrl.iId = buttonState->CommandId();
+ groupCtrl.iLongId = 0;
+
+ if ( buttonState->Text().Length() == 0 ||
+ !buttonState->Text().Compare( _L(" ") ) )
+ {
+ button->SetDimmed( ETrue );
+ }
+ }
+ else
+ {
+ groupCtrl.iId = static_cast<CEikCbaButton*>( groupCtrl.iControl )->PopCommand();
+ groupCtrl.iLongId = 0;
+ }
+ }
+ else // Command to be removed is not on the top, check the whole stack.
+ {
+ STATIC_CAST(CEikCbaButton*, groupCtrl.iControl)->RemoveCommand(aCommandId);
+ }
+
+ // If MSK or left CBA was changed, this sets MSK icon accordingly.
+ TRAP_IGNORE( SetMSKIconL() );
+
+ // Force labels to be re-formatted...
+ SizeChanged();
+
+ TBool isEmptyAfter( IsEmpty() );
+
+ if ( !COMPARE_BOOLS( isEmptyBefore, isEmptyAfter ) )
+ {
+ SetFadeState();
+ }
+
+ DrawDeferred();
+ ReportContentChangedEvent();
+ }
+
+void CEikCba::RemovePreviousCommandWithoutSizeChanged(TInt aPosition)
+ {
+ TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
+ STATIC_CAST(CEikCbaButton*, groupCtrl.iControl)->RemovePreviousCommand();
+ }
+
+void CEikCba::RemovePreviousCommand(TInt aPosition)
+ {
+ RemovePreviousCommandWithoutSizeChanged( aPosition );
+ // If MSK or left CBA was changed, this sets MSK icon accordingly.
+ TRAP_IGNORE( SetMSKIconL() );
+
+ // Force labels to be re-formatted...
+ SizeChanged();
+ ReportContentChangedEvent();
+ }
+
+
+TInt CEikCba::CommandPos(TInt aCommandId) const
+ {
+ return IndexById(aCommandId);
+ }
+
+void CEikCba::DimCommand(TInt aCommandId,TBool aDimmed)
+ {
+ CCoeControl* control( ButtonById( aCommandId ) );
+ if ( control )
+ {
+ if ( SoftkeyStatusChangeAllowed( IndexById( aCommandId ), aDimmed ) )
+ {
+ control->SetDimmed( aDimmed );
+ }
+ }
+ }
+
+TBool CEikCba::IsCommandDimmed(TInt aCommandId) const
+ {
+ if( ButtonById(aCommandId) )
+ {
+ return ButtonById(aCommandId)->IsDimmed();
+ }
+ return EFalse;
+ }
+
+void CEikCba::MakeCommandVisible(TInt aCommandId, TBool aVisible)
+ {
+ CCoeControl* control( ButtonById( aCommandId ) );
+ if ( control )
+ {
+ if ( SoftkeyStatusChangeAllowed( IndexById( aCommandId ), !aVisible ) )
+ {
+ control->MakeVisible( aVisible );
+ }
+ }
+ }
+
+TBool CEikCba::IsCommandVisible(TInt aCommandId) const
+ {
+ if( ButtonById(aCommandId) )
+ {
+ return ButtonById(aCommandId)->IsVisible();
+ }
+ return EFalse;
+ }
+
+void CEikCba::AnimateCommand(TInt /*aCommandId*/)
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// Sets the dimming status of a button with the specified position.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::DimCommandByPosition( TInt aPosition, TBool aDimmed )
+ {
+ if ( aPosition >= iControlArray->Count() )
+ {
+ return;
+ }
+
+ if ( SoftkeyStatusChangeAllowed( aPosition, aDimmed ) )
+ {
+ TEikGroupControl& groupCtrl = ( *iControlArray )[ aPosition ];
+ groupCtrl.iControl->SetDimmed( aDimmed );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// Returns the dimming status of a button with the specified position.
+// ---------------------------------------------------------------------------
+//
+TBool CEikCba::IsCommandDimmedByPosition( TInt aPosition ) const
+ {
+ if ( aPosition >= iControlArray->Count() )
+ {
+ return EFalse;
+ }
+
+ TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
+ return groupCtrl.iControl->IsDimmed();
+ }
+
+
+// ---------------------------------------------------------------------------
+// Sets the visibility of a button with the specified position.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::MakeCommandVisibleByPosition( TInt aPosition, TBool aVisible )
+ {
+ if ( aPosition >= iControlArray->Count() )
+ {
+ return;
+ }
+
+ if ( SoftkeyStatusChangeAllowed( aPosition, !aVisible ) )
+ {
+ TEikGroupControl& groupCtrl = ( *iControlArray )[ aPosition ];
+
+ if ( !iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ groupCtrl.iControl->MakeVisible( aVisible );
+ }
+ else
+ {
+ // Just dim the button, don't hide it.
+ groupCtrl.iControl->SetDimmed( !aVisible );
+ groupCtrl.iControl->DrawDeferred();
+ }
+ }
+ }
+
+
+TBool CEikCba::IsCommandVisibleByPosition(TInt aPosition) const
+ {
+ if (aPosition >= iControlArray->Count())
+ {
+ return EFalse;
+ }
+ TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
+
+ if ( !iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ return STATIC_CAST(CEikCbaButton*, groupCtrl.iControl)->IsVisible();
+ }
+
+ return !groupCtrl.iControl->IsDimmed();
+ }
+
+void CEikCba::AnimateCommandByPosition(TInt /*aPosition*/)
+ {
+ }
+
+/*CCoeControl* CEikCba::GroupControlByPosition(TInt aPosition) const
+ {
+ if (aPosition >= iControlArray->Count())
+ {
+ return NULL;
+ }
+ TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
+ return groupCtrl.iControl;
+ }*/
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::ButtonRectByPosition
+// Gets a CBA button rectangle.
+// ---------------------------------------------------------------------------
+//
+TRect CEikCba::ButtonRectByPosition( TInt aPosition, TBool aRelativeToScreen )
+ {
+ TRect rect( 0, 0, 0, 0 );
+
+ if ( aPosition >= iControlArray->Count() || aPosition < 0 )
+ {
+ return rect;
+ }
+
+ if ( !AknLayoutUtils::PenEnabled() )
+ {
+ // Button rectangle is the actual control rect.
+ rect = ( *iControlArray )[aPosition].iControl->Rect();
+ }
+ else
+ {
+ // In touch layouts the button areas are read from the
+ // layout data because they are larger than the actual
+ // control size.
+ // Also, currently touch layouts do not support MSK,
+ // so it's ignored.
+ TRect containerRect( Rect() );
+ TAknLayoutRect layoutRect;
+ TRect button1Rect( 0, 0, 0, 0 );
+ TRect button2Rect( 0, 0, 0, 0 );
+ TRect buttonMSKRect( 0, 0, 0, 0 );
+
+ if ( iFlags.IsSet( ECbaEmbedded ) )
+ {
+ TRect rect ( Rect() );
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::popup_sk_window_g1( 0 ) );
+
+ // Button widths are calculated based on cba area width
+ // margin width is taken from layout
+ TInt margin = layoutRect.Rect().iTl.iX - rect.iTl.iX;
+ TInt buttonWidth = ( rect.Width() - margin * 2 ) / 2;
+ TSize buttonSize ( buttonWidth, layoutRect.Rect().Height() );
+
+ button1Rect = TRect(
+ TPoint( rect.iTl.iX + margin, layoutRect.Rect().iTl.iY ),
+ buttonSize );
+ button2Rect = TRect(
+ TPoint( button1Rect.iBr.iX, layoutRect.Rect().iTl.iY ),
+ TPoint( rect.iBr.iX - margin,
+ layoutRect.Rect().iBr.iY ) );
+ }
+ else if ( AknLayoutFlags() & EAknLayoutCbaInRightPane )
+ {
+ // Landcsape nHD layout, button parent rectangle
+ // is the whole screen so aRelativeToScreen parameter
+ // is not taken into account.
+ TAknWindowComponentLayout rightAreaLayout(
+ AknLayoutScalable_Avkon::area_side_right_pane( 0 ) );
+
+ layoutRect.LayoutRect(
+ containerRect,
+ DoCompose(
+ rightAreaLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane() ).LayoutLine() );
+ TRect bottomSKRect( layoutRect.Rect() );
+
+ layoutRect.LayoutRect(
+ containerRect,
+ DoCompose(
+ rightAreaLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_top_pane() ).LayoutLine() );
+ TRect topSKRect( layoutRect.Rect() );
+
+ layoutRect.LayoutRect(
+ bottomSKRect,
+ AknLayoutScalable_Avkon::aid_touch_sctrl_bottom().LayoutLine() );
+ button1Rect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ topSKRect,
+ AknLayoutScalable_Avkon::aid_touch_sctrl_top().LayoutLine() );
+ button2Rect = layoutRect.Rect();
+ }
+ else if ( AknLayoutFlags() & EAknLayoutCbaInControlPane )
+ {
+ TBool mskDisabled( !MskAllowed() );
+
+ TBool flatLscLayout(
+ Layout_Meta_Data::IsLandscapeOrientation() &&
+ AknStatuspaneUtils::FlatLayoutActive() );
+
+ if ( mskDisabled && !flatLscLayout )
+ {
+ if ( aRelativeToScreen )
+ {
+ AknLayoutUtils::LayoutMetricsRect(
+ AknLayoutUtils::EControlPane, containerRect );
+ }
+
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_right().LayoutLine() );
+ button1Rect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_left().LayoutLine() );
+ button2Rect = layoutRect.Rect();
+ }
+ else
+ {
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_left().LayoutLine() );
+ button1Rect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::aid_touch_ctrl_right().LayoutLine() );
+ button2Rect = layoutRect.Rect();
+ }
+ }
+ else
+ {
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::control_pane_g6( 0 ).LayoutLine() );
+ button1Rect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::control_pane_g8( 0 ).LayoutLine() );
+ button2Rect = layoutRect.Rect();
+
+ if ( !mskDisabled )
+ {
+ layoutRect.LayoutRect(
+ containerRect,
+ AknLayoutScalable_Avkon::control_pane_g7( 0 ).LayoutLine() );
+ buttonMSKRect = layoutRect.Rect();
+ }
+ else
+ {
+ buttonMSKRect.SetRect( 0, 0, 0, 0 );
+ }
+ }
+ }
+
+ switch ( aPosition )
+ {
+ case KControlArrayCBAButton1Posn:
+ {
+ rect = button1Rect;
+ break;
+ }
+
+ case KControlArrayCBAButton2Posn:
+ {
+ rect = button2Rect;
+ break;
+ }
+
+ case KControlArrayCBAButtonMSKPosn:
+ {
+ rect = buttonMSKRect;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ return rect;
+ }
+
+
+CCoeControl* CEikCba::AsControl()
+ {
+ return this;
+ }
+
+const CCoeControl* CEikCba::AsControl() const
+ {
+ return this;
+ }
+
+
+void CEikCba::SetBoundingRect( const TRect& /*aBoundingRect*/ )
+ {
+ if ( iFlags.IsSet( ECbaEmbedded ) )
+ {
+ return;
+ }
+
+ // If background skin id has not been set from outside CBA,
+ // update it in case status pane layout has changed
+ if ( !iExtension->iCbaBgIIDSetExt )
+ {
+ iBgIID = AknStatuspaneUtils::IdleLayoutActive() ?
+ KAknsIIDQsnBgAreaControlIdle :
+ KAknsIIDQsnBgAreaControl;
+ }
+
+ // If CBA is inserted into a query dialog then it is positioned by the
+ // query control.
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ return;
+ }
+
+ TRect oldRect( Rect() );
+
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ // Enable the MSK icon if status pane layout is changed from
+ // MSK disabled to MSK enabled one.
+ TBool mskDisabled( !MskAllowed() );
+
+ const TInt aknLayoutFlags = AknLayoutFlags();
+ if ( aknLayoutFlags & EAknLayoutCbaInControlPane )
+ {
+ if ( mskDisabled )
+ {
+ SetMSKVisibility( EFalse );
+ }
+ else
+ {
+ SetMSKVisibility( ETrue );
+ TRAP_IGNORE( SetMSKIconL() );
+ }
+
+ // We must check for landscape mode bottom sks
+ TInt bottomPaneVariety = 1;
+ if ( Layout_Meta_Data::IsLandscapeOrientation() )
+ {
+ bottomPaneVariety = 6;
+ }
+
+ TAknWindowLineLayout controlPane( DoCompose(
+ AknLayoutScalable_Avkon::application_window( 0 ),
+ DoCompose( AknLayoutScalable_Avkon::area_bottom_pane( bottomPaneVariety ),
+ AknLayoutScalable_Avkon::control_pane() ) ).LayoutLine() );
+
+ TAknLayoutRect cbarect;
+ cbarect.LayoutRect( screen, controlPane );
+
+ SetRect( cbarect.Rect() );
+
+ // Set correct window region incase we have been in stacon mode.
+ RRegion region;
+ region.AddRect( Rect() );
+
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+
+ // If status indicators and clock are shown in control pane area,
+ // then remove those areas from cba window region.
+ //
+ // NOTE: MSK is not supported in landscape.
+ //
+ if ( statusPane &&
+ statusPane->IsVisible() &&
+ AknStatuspaneUtils::ExtendedFlatLayoutActive() &&
+ ( iBgIID == KAknsIIDQsnBgAreaControl ||
+ iBgIID == KAknsIIDQsnBgAreaControlIdle ||
+ iBgIID == KAknsIIDQsnBgAreaControlMp ||
+ ( iBgIID == KAknsIIDWallpaper &&
+ AknStatuspaneUtils::IdleLayoutActive() ) ) )
+ {
+ TRect digitalClockRect( 0,0,0,0 );
+ TRect indicatorRect( 0,0,0,0 );
+
+ if ( iBgIID == KAknsIIDQsnBgAreaControlMp )
+ {
+ if ( !iIsClockIndicBgIIDSet )
+ {
+ statusPane->SetCbaAreaBackgroundID(
+ iBgIID,
+ CEikStatusPaneBase::EDrawDeferred );
+ iIsClockIndicBgIIDSet = ETrue;
+ }
+ }
+ else
+ {
+ if ( statusPane->CbaAreaBackgroundID() != iBgIID )
+ {
+ statusPane->SetCbaAreaBackgroundID(
+ iBgIID,
+ CEikStatusPaneBase::EDrawDeferred );
+ }
+ }
+
+ TRAPD( err1,
+ indicatorRect = statusPane->PaneRectL( TUid::Uid(
+ EEikStatusPaneUidIndic ) ) );
+
+ TRAPD( err2,
+ digitalClockRect = statusPane->PaneRectL( TUid::Uid(
+ EEikStatusPaneUidDigitalClock ) ) );
+
+ if ( !err1 && !err2 )
+ {
+ TPoint cbaPositionRelativeToScreen( PositionRelativeToScreen() );
+ TRect cbaRectRelativeToScreen( cbaPositionRelativeToScreen, Size() );
+
+ if ( cbaRectRelativeToScreen.Intersects( indicatorRect ) )
+ {
+ indicatorRect.Move(
+ -cbaPositionRelativeToScreen.iX,
+ -cbaPositionRelativeToScreen.iY );
+
+ region.SubRect( indicatorRect );
+ }
+
+ if ( cbaRectRelativeToScreen.Intersects( digitalClockRect ) )
+ {
+ digitalClockRect.Move(
+ -cbaPositionRelativeToScreen.iX,
+ -cbaPositionRelativeToScreen.iY );
+
+ region.SubRect( digitalClockRect );
+ }
+ }
+ }
+
+ if ( !region.CheckError() )
+ {
+ Window().SetShape( region );
+ }
+ region.Close();
+ }
+ else if ( aknLayoutFlags & EAknLayoutCbaInRightPane )
+ {
+ // Softkeys in right pane.
+ //
+ // We set the rect to whole screen and then set window to
+ // clip other parts than softkey buttons.
+
+ TRect rect( screen );
+ SetRect( rect );
+
+ // Read right (top in landscape) softkey layout.
+ TAknWindowLineLayout rightSoftkeyLayout(
+ DoCompose( AknLayoutScalable_Avkon::area_side_right_pane( 0 ),
+ AknLayoutScalable_Avkon::sctrl_sk_top_pane() ).LayoutLine() );
+
+ TAknLayoutRect rightSoftkeyLayoutRect;
+ rightSoftkeyLayoutRect.LayoutRect( rect, rightSoftkeyLayout );
+ TRect rightSoftKeyButtonRect( rightSoftkeyLayoutRect.Rect() );
+
+ // Read left (bottom in landscape) softkey layout.
+ TAknWindowLineLayout leftSoftkeyLayout(
+ DoCompose( AknLayoutScalable_Avkon::area_side_right_pane( 0 ),
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane() ).LayoutLine() );
+
+ TAknLayoutRect leftSoftkeyLayoutRect;
+ leftSoftkeyLayoutRect.LayoutRect( rect, leftSoftkeyLayout );
+ TRect leftSoftKeyButtonRect( leftSoftkeyLayoutRect.Rect() );
+
+ // Set the window shape.
+ RRegion region;
+ region.AddRect( leftSoftKeyButtonRect );
+ region.AddRect( rightSoftKeyButtonRect );
+ if ( !region.CheckError() )
+ {
+ Window().SetShape( region );
+ }
+ region.Close();
+ }
+ else
+ {
+ // Stacon pane (combined status and control pane).
+ //
+ // Control pane is splitted. We set the rect to whole screen and then set window to
+ // clip other parts than softkey buttons.
+
+ TRect rect( screen );
+ SetRect( rect );
+
+ TInt variety = 0;
+ if ( AknLayoutFlags() & EAknLayoutCbaInStaconPaneLeft )
+ {
+ variety = 1;
+ }
+
+ TAknWindowComponentLayout layout0;
+ TAknWindowComponentLayout layout1;
+ TAknWindowComponentLayout layout2;
+
+ // Read right (top in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_top_pane( 2 );
+ layout1 = AknLayoutScalable_Avkon::stacon_top_pane();
+
+ // If clock is shown in stacon, cba area is smaller.
+ TInt topCbaVariety = variety;
+ if ( AknStatuspaneUtils::ExtendedStaconPaneActive()
+ || AknStatuspaneUtils::ExtendedLayoutActive() )
+ {
+ topCbaVariety += 4;
+ }
+
+ layout2 = AknLayoutScalable_Avkon::control_top_pane_stacon( topCbaVariety );
+
+ TAknWindowLineLayout rightSoftkeyLayout(
+ DoCompose( layout0,DoCompose( layout1, layout2 ) ).LayoutLine() );
+
+ TAknLayoutRect rightSoftkeyLayoutRect;
+ rightSoftkeyLayoutRect.LayoutRect( rect, rightSoftkeyLayout );
+ TRect rightSoftKeyButtonRect( rightSoftkeyLayoutRect.Rect() );
+
+ // Read left (bottom in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_bottom_pane( 2 );
+ layout1 = AknLayoutScalable_Avkon::stacon_bottom_pane();
+
+ // If clock is shown in stacon, cba area is smaller.
+ TInt bottomCbaVariety = variety;
+ if ( AknStatuspaneUtils::ExtendedStaconPaneActive()
+ || AknStatuspaneUtils::ExtendedLayoutActive() )
+ {
+ bottomCbaVariety += 2;
+ }
+
+ layout2 =
+ AknLayoutScalable_Avkon::control_bottom_pane_stacon(
+ bottomCbaVariety );
+
+ TAknWindowLineLayout leftSoftkeyLayout(
+ DoCompose( layout0, DoCompose( layout1, layout2 ) ).LayoutLine() );
+
+ TAknLayoutRect leftSoftkeyLayoutRect;
+ leftSoftkeyLayoutRect.LayoutRect( rect, leftSoftkeyLayout );
+ TRect leftSoftKeyButtonRect( leftSoftkeyLayoutRect.Rect() );
+
+ // Set the window shape.
+ RRegion region;
+ region.AddRect( leftSoftKeyButtonRect );
+ region.AddRect( rightSoftKeyButtonRect );
+ if ( !region.CheckError() )
+ {
+ Window().SetShape( region );
+ }
+ region.Close();
+ }
+
+ // The softkey frame needs to be updated if the size or
+ // position of CBA was changed.
+ if ( iExtension && Rect() != oldRect )
+ {
+ TRAP_IGNORE( iExtension->UpdateSoftkeyFrameL( EFalse ) );
+
+ // Finally ensure that MSK drawing is disabled if the status pane
+ // layout is changed from MSK enabled to MSK disabled one.
+ if ( mskDisabled )
+ {
+ SetMSKVisibility( EFalse );
+ }
+
+ DrawDeferred();
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// Subtracts the area occupied by the button group from the specified
+// bounding rectangle.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::ReduceRect( TRect& aBoundingRect ) const
+ {
+ // CBA inside Popup/Query Input does not reduce bounding rect
+ if ( iFlags.IsSet( ECbaEmbedded ) || iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ return;
+ }
+
+ if ( !IsVisible() )
+ {
+ return;
+ }
+
+ const TInt aknLayoutFlags = AknLayoutFlags();
+
+ if ( aknLayoutFlags & EAknLayoutCbaInControlPane )
+ {
+ // Cba in control pane.
+ if ( aBoundingRect.Intersects( TRect( iPosition, iSize ) ) )
+ {
+ aBoundingRect.iBr.iY = Position().iY;
+ }
+ }
+ else if ( aknLayoutFlags & EAknLayoutCbaInRightPane )
+ {
+ // Cba in right pane.
+
+ TRect rect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, rect );
+
+ const TAknWindowLineLayout rightPaneLayout(
+ AknLayoutScalable_Avkon::area_side_right_pane( 0 ).LayoutLine() );
+
+ TAknLayoutRect rightPaneRect;
+ rightPaneRect.LayoutRect( rect, rightPaneLayout );
+
+ const TRect rightPane( rightPaneRect.Rect() );
+
+ if ( aBoundingRect.Intersects( rightPane ) )
+ {
+ // Always on the right side, won't be mirrored.
+ aBoundingRect.iBr.iX = rightPane.iTl.iX;
+ }
+ }
+ else
+ {
+ // CBA in stacon pane.
+ if ( iControlArray->Count() != 0 )
+ {
+ CCoeControl *leftSoftkey =
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl;
+ CCoeControl *rightSoftkey =
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl;
+ if ( leftSoftkey && rightSoftkey )
+ {
+ RRegion boundingRegion;
+ TRect originalboundingRect( aBoundingRect );
+ boundingRegion.AddRect( originalboundingRect );
+
+ TRect rect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen,
+ rect );
+
+ TInt variety = 0;
+ if ( aknLayoutFlags & EAknLayoutCbaInStaconPaneLeft )
+ {
+ variety = 1;
+ }
+
+ TAknWindowComponentLayout layout0;
+ TAknWindowComponentLayout layout1;
+ TAknWindowComponentLayout layout2;
+
+ // Read right (top in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_top_pane( 2 );
+ layout1 = AknLayoutScalable_Avkon::stacon_top_pane();
+
+ // If clock is shown in stacon, CBA area is smaller.
+ TInt topCbaVariety = variety;
+ TInt bottomCbaVariety = variety;
+ if ( AknStatuspaneUtils::ExtendedStaconPaneActive() )
+ {
+ topCbaVariety += 4;
+ bottomCbaVariety += 2;
+ }
+
+ layout2 = AknLayoutScalable_Avkon::control_top_pane_stacon( topCbaVariety );
+
+ TAknWindowLineLayout rightSoftkeyLayout(
+ DoCompose( layout0,
+ DoCompose( layout1, layout2 ) ).LayoutLine() );
+
+ TAknLayoutRect rightSoftkeyLayoutRect;
+ rightSoftkeyLayoutRect.LayoutRect( rect, rightSoftkeyLayout );
+ TRect rightSoftKeyRect( rightSoftkeyLayoutRect.Rect() );
+
+ // Read left (bottom in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_bottom_pane( 2 );
+ layout1 = AknLayoutScalable_Avkon::stacon_bottom_pane();
+ layout2 = AknLayoutScalable_Avkon::control_bottom_pane_stacon( bottomCbaVariety );
+
+ TAknWindowLineLayout leftSoftkeyLayout(
+ DoCompose( layout0,
+ DoCompose( layout1, layout2 ) ).LayoutLine() );
+
+ TAknLayoutRect leftSoftkeyLayoutRect;
+ leftSoftkeyLayoutRect.LayoutRect( rect, leftSoftkeyLayout );
+ TRect leftSoftKeyRect( leftSoftkeyLayoutRect.Rect() );
+
+ boundingRegion.SubRect( leftSoftKeyRect );
+ boundingRegion.SubRect( rightSoftKeyRect );
+
+ TInt count = boundingRegion.Count();
+
+ TRect largestBoundingRect( 0, 0, 0, 0 );
+ TRect boundingRect( 0, 0, 0, 0 );
+ for ( TInt j = 0; j < count; j++ )
+ {
+ boundingRect = boundingRegion[j];
+ if ( boundingRect.Height() >= largestBoundingRect.Height() )
+ {
+ largestBoundingRect = boundingRect;
+ }
+ }
+
+ // Return largest bounding rect.
+ aBoundingRect = largestBoundingRect;
+ boundingRegion.Close();
+ }
+ }
+ }
+ }
+
+
+CCoeControl* CEikCba::GroupControlById(TInt aCommandId)
+ {
+ return ButtonById(aCommandId);
+ }
+
+
+CCoeControl* CEikCba::GroupControlById(TInt aCommandId) const
+ {
+ return ButtonById(aCommandId);
+ }
+
+TInt CEikCba::CommandId(TInt aCommandPos) const
+ {
+ return (*iControlArray)[aCommandPos].iId;
+ }
+
+TInt CEikCba::ButtonCount() const
+ {
+ return (iControlArray->Count()-1); // -1 for scroll bar;
+ }
+
+CEikCommandButton* CEikCba::GroupControlAsButton(TInt /*aCommandId*/) const
+ {
+ // It is not possible to convert a CBA button to a CEikCommandButton.
+ // Please use an interface that does not use a CEikCommandButton conversion,
+ // e.g. CEikButtonGroupContainer::SetCommandL().
+#if defined(_DEBUG)
+ Panic(EEikPanicCBACannotConvertToCEikCommandButton);
+#endif
+ return NULL;
+ }
+
+TUint CEikCba::ButtonGroupFlags() const
+ {
+ return iCbaFlags ;
+ }
+
+EXPORT_C void CEikCba::SetButtonGroupFlags(TInt aFlags)
+ {
+ iCbaFlags = aFlags;
+ if (( iCbaFlags & EEikCbaFlagTransparent || iCbaFlags & EEikCbaFlagSemiTransparent ) &&
+ CAknEnv::Static()->TransparencyEnabled() )
+ {
+ Window().SetRequiredDisplayMode( EColor16MA );
+ TInt err = Window().SetTransparencyAlphaChannel();
+ if( err == KErrNone )
+ {
+ Window().SetBackgroundColor( ~0 );
+ if ( iExtension && iExtension->iEnablePostingTransparency )
+ {
+ iExtension->iEnablePostingTransparency = EFalse;
+ delete iExtension->iLskPostingOverlayBitmap;
+ iExtension->iLskPostingOverlayBitmap = NULL;
+ delete iExtension->iRskPostingOverlayBitmap;
+ iExtension->iRskPostingOverlayBitmap = NULL;
+ BroadcastPostingTransparency( EFalse );
+ }
+ }
+ else
+ {
+ iCbaFlags &= ~EEikCbaFlagTransparent;
+ }
+ }
+ else
+ {
+ iCbaFlags &= ~EEikCbaFlagTransparent;
+ }
+ if ( iCbaFlags & EEikCbaFlagSemiTransparent )
+ {
+ if ( iExtension )
+ {
+ iExtension->iSemiBgID = KAknsIIDQsnHomeBgWidget;
+ iExtension->iSemiBgCenterID = KAknsIIDQsnHomeBgWidgetCenter;
+ }
+ }
+ else
+ {
+ if ( iExtension )
+ {
+ iExtension->iSemiBgID = KAknsIIDNone;
+ iExtension->iSemiBgCenterID = KAknsIIDNone;
+ }
+ }
+
+ UpdateFonts();
+ }
+
+// -----------------------------------------------------------------------------
+// CEikCba::SetSkinBackgroundId
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CEikCba::SetSkinBackgroundId( const TAknsItemID& aIID )
+ {
+ // Skin background is not drawn by embedded CBA.
+ if ( iFlags.IsSet( ECbaEmbedded ) )
+ {
+ return;
+ }
+
+ if ( iBgIID != KAknsIIDNone )
+ {
+ if ( iBgIID != aIID )
+ {
+ TRAP_IGNORE( iExtension->UpdateSoftkeyFrameL( EFalse ) );
+ }
+
+ iBgIID = aIID;
+ iExtension->iCbaBgIIDSetExt = ETrue;
+ }
+
+ if ( iMLBgContext )
+ {
+ DoSetLayers( aIID );
+
+ if ( aIID.iMajor == KAknsIIDQsnBgAreaControlPopup.iMajor &&
+ aIID.iMinor == KAknsIIDQsnBgAreaControlPopup.iMinor )
+ {
+ iPopupVisible = ETrue;
+ }
+ else
+ {
+ iPopupVisible = EFalse;
+ }
+
+ }
+
+ CheckSkinAndUpdateContext();
+
+ if ( AknStatuspaneUtils::ExtendedFlatLayoutActive() )
+ {
+ // Clock and indicator pane area must be removed from
+ // this window in extended flat layout.
+ SetBoundingRect( TRect(0,0,0,0) ); // dummy parameter
+ }
+
+ CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
+
+ if ( statusPane &&
+ ( iIsClockIndicBgIIDSet &&
+ iBgIID == KAknsIIDQsnBgAreaControlMp &&
+ statusPane->CbaAreaBackgroundID() != iBgIID ) ||
+ ( iBgIID == KAknsIIDQsnBgAreaControlMp &&
+ AknLayoutFlags() & EAknLayoutCbaInRightPane ) )
+ {
+ statusPane->SetCbaAreaBackgroundID(
+ iBgIID,
+ CEikStatusPaneBase::EDrawDeferred );
+ }
+ }
+
+TKeyResponse CEikCba::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
+ {
+ if (aType != EEventKey)
+ {
+ return EKeyWasNotConsumed;
+ }
+
+ // Return immediately if the control is invisible.
+ if (!IsVisible() && !(iCbaFlags&EAknCBAFlagRespondWhenInvisible))
+ {
+ return EKeyWasNotConsumed;
+ }
+
+ TBool shiftControlPressed =
+ (aKeyEvent.iModifiers & EModifierShift) ||
+ (aKeyEvent.iModifiers & EModifierLeftShift) ||
+ (aKeyEvent.iModifiers & EModifierRightShift) ||
+ (aKeyEvent.iModifiers & EModifierCtrl) ||
+ (aKeyEvent.iModifiers & EModifierRightCtrl);
+
+ TKeyResponse response(EKeyWasNotConsumed);
+
+ // AknLaf - changed to use keys defined in AknKeys.h.
+ // Left soft key will be returned also when MSK is enabled but not defined.
+ if (aKeyEvent.iCode == EKeyCBA1)
+ {
+ if (KControlArrayCBAButton1Posn < iControlArray->Count())
+ {
+ // Return immediately if the button is invisible
+ if ( (*iControlArray)[KControlArrayCBAButton1Posn].iControl &&
+ !(*iControlArray)[KControlArrayCBAButton1Posn].iControl->IsVisible() &&
+ !(iCbaFlags & EAknCBAFlagRespondWhenInvisible) )
+ {
+ return EKeyWasConsumed;
+ }
+ TInt shortCommand = (*iControlArray)[KControlArrayCBAButton1Posn].iId;
+ TInt longCommand = (*iControlArray)[KControlArrayCBAButton1Posn].iLongId;
+
+ // This will pass key event to application - no softkey command is processed.
+ if (shortCommand == EAknSoftkeyForwardKeyEvent)
+ {
+ return EKeyWasNotConsumed;
+ }
+
+ if (aKeyEvent.iRepeats == 0 && shortCommand)
+ {
+ iCommandObserver->ProcessCommandL((TInt)shortCommand);
+ }
+ else if (longCommand)
+ {
+ iCommandObserver->ProcessCommandL((TInt)longCommand);
+ }
+ response = EKeyWasConsumed;
+ }
+ }
+ else if (aKeyEvent.iCode == EKeyCBA2)
+ {
+ if (KControlArrayCBAButton2Posn < iControlArray->Count())
+ {
+ // Return immediately if the button is invisible.
+ if ( (*iControlArray)[KControlArrayCBAButton2Posn].iControl &&
+ !(*iControlArray)[KControlArrayCBAButton2Posn].iControl->IsVisible() &&
+ !(iCbaFlags&EAknCBAFlagRespondWhenInvisible) )
+ {
+ return EKeyWasConsumed;
+ }
+ TInt shortCommand = (*iControlArray)[KControlArrayCBAButton2Posn].iId;
+ TInt longCommand = (*iControlArray)[KControlArrayCBAButton2Posn].iLongId;
+
+ if (!shortCommand && (aKeyEvent.iModifiers & EModifierKeyboardExtend)
+ && (aKeyEvent.iScanCode == EStdKeyDevice1))
+ {
+ shortCommand = EEikBidCancel;
+ }
+
+ // This will pass key event to application - no softkey command is processed.
+ if (shortCommand == EAknSoftkeyForwardKeyEvent)
+ {
+ return EKeyWasNotConsumed;
+ }
+
+ if (aKeyEvent.iRepeats == 0 && shortCommand)
+ {
+ iCommandObserver->ProcessCommandL((TInt)shortCommand);
+ }
+ else if (longCommand)
+ {
+ iCommandObserver->ProcessCommandL((TInt)longCommand);
+ }
+ response=EKeyWasConsumed;
+ }
+ }
+ // Only take care of MSK if there has been something set to MSK (so that this doesn't break old
+ // cbas with only left and right softkeys set).
+
+ // Do not handle key events with middle softkey if single click is enabled
+ else if ( iFlags.IsClear( ECbaSingleClickEnabled )
+ && AknLayoutUtils::MSKEnabled()
+ && iMSKset
+ && aKeyEvent.iCode == EKeyOK
+ && !Window().IsFaded() )
+ {
+ if (KControlArrayCBAButtonMSKPosn < iControlArray->Count())
+ {
+ // Return immediately if the button is invisible.
+ if ( (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl &&
+ !(*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl->IsVisible() &&
+ !(iCbaFlags&EAknCBAFlagRespondWhenInvisible) )
+ {
+ return EKeyWasConsumed;
+ }
+
+ TInt shortCommand = (*iControlArray)[KControlArrayCBAButtonMSKPosn].iId;
+ TInt longCommand = (*iControlArray)[KControlArrayCBAButtonMSKPosn].iLongId;
+
+ // This will pass key event to application - no softkey command is processed.
+ if (shortCommand == EAknSoftkeyForwardKeyEvent)
+ {
+ return EKeyWasNotConsumed;
+ }
+
+ if (aKeyEvent.iRepeats == 0 && shortCommand)
+ {
+ if (iMSKCommandObserver)
+ {
+ iMSKCommandObserver->ProcessCommandL(shiftControlPressed ?
+ EAknSoftkeyShiftMSK : (TInt)shortCommand);
+ }
+ // MSK observer handles shift, no normal MSK after that.
+ if (!(iMSKCommandObserver && shiftControlPressed))
+ {
+ iCommandObserver->ProcessCommandL((TInt)shortCommand);
+ }
+ }
+ else if (longCommand)
+ {
+ if (iMSKCommandObserver)
+ {
+ iMSKCommandObserver->ProcessCommandL(shiftControlPressed ?
+ EAknSoftkeyShiftMSK : (TInt)longCommand);
+ }
+ // MSK observer handles shift, no normal MSK after that.
+ if (!(iMSKCommandObserver && shiftControlPressed))
+ {
+ iCommandObserver->ProcessCommandL((TInt)longCommand);
+ }
+ }
+ response=EKeyWasConsumed;
+ }
+ }
+ // If MSK is enabled but not defined, we return left softkey.
+ // Do not handle key events with middle softkey if single click is enabled
+ else if ( iFlags.IsClear( ECbaSingleClickEnabled )
+ && AknLayoutUtils::MSKEnabled()
+ && !iMSKset
+ && aKeyEvent.iCode == EKeyOK
+ && !Window().IsFaded() )
+ {
+ if (KControlArrayCBAButton1Posn < iControlArray->Count())
+ {
+ // Return immediately if the button is invisible.
+ if ( (*iControlArray)[KControlArrayCBAButton1Posn].iControl &&
+ !(*iControlArray)[KControlArrayCBAButton1Posn].iControl->IsVisible() &&
+ !(iCbaFlags&EAknCBAFlagRespondWhenInvisible) )
+ {
+ return EKeyWasConsumed;
+ }
+
+ TInt shortCommand = (*iControlArray)[KControlArrayCBAButton1Posn].iId;
+ TInt longCommand = (*iControlArray)[KControlArrayCBAButton1Posn].iLongId;
+
+ // This will pass key event to application - no softkey command is processed.
+ if (shortCommand == EAknSoftkeyForwardKeyEvent)
+ {
+ return EKeyWasNotConsumed;
+ }
+
+ if (aKeyEvent.iRepeats == 0 && shortCommand)
+ {
+ // Send shift + MSK to (listbox) observer even if MSK is not defined.
+ if (iMSKCommandObserver && shiftControlPressed)
+ {
+ iMSKCommandObserver->ProcessCommandL(EAknSoftkeyShiftMSK);
+ }
+ else
+ {
+ iCommandObserver->ProcessCommandL((TInt)shortCommand);
+ }
+ }
+ else if (longCommand)
+ {
+ // Send shift + MSK to (listbox) observer even if MSK is not defined.
+ if (iMSKCommandObserver && shiftControlPressed)
+ {
+ iMSKCommandObserver->ProcessCommandL(EAknSoftkeyShiftMSK);
+ }
+ else
+ {
+ iCommandObserver->ProcessCommandL((TInt)longCommand);
+ }
+ }
+ response = EKeyWasConsumed;
+ }
+ }
+
+ return response;
+ }
+
+EXPORT_C void* CEikCba::ExtensionInterface( TUid /*aInterface*/ )
+ {
+ return NULL;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Handles pointer events by passing the event to component controls by using
+// the base class functionality. In addition this function notifies the
+// command observer if a cba button was tapped.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+ {
+ if ( !AknLayoutUtils::PenEnabled() )
+ {
+ return;
+ }
+ else if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ CCoeControl::HandlePointerEventL( aPointerEvent );
+ return;
+ }
+
+ // If a child control is grabbing the pointer, we store the object pointer
+ // before calling base class implementation. This is because the up event
+ // releases the pointer grab.
+ CCoeControl* grabber = GrabbingComponent();
+
+ // Default base class functionality passes event to child controls.
+ CCoeControl::HandlePointerEventL( aPointerEvent );
+
+ // If pointer up event occurred in child control which was grabbing
+ // the pointer, it means that the CBA button was clicked.
+
+ CEikCbaButton* button1 =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl );
+ CEikCbaButton* button2 =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl );
+ CEikCbaButton* buttonMSK = NULL;
+
+ if ( iMSKset && AknLayoutUtils::MSKEnabled() )
+ {
+ buttonMSK =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl );
+ }
+
+ TRect button1Rect;
+ TRect button2Rect;
+ TRect buttonMSKRect;
+
+ if ( AknLayoutFlags() & EAknLayoutCbaInRightPane )
+ {
+ button1Rect = ButtonRectByPosition( KControlArrayCBAButton1Posn, ETrue );
+ button2Rect = ButtonRectByPosition( KControlArrayCBAButton2Posn, ETrue );
+ }
+ else if ( AknLayoutFlags() & EAknLayoutCbaInControlPane )
+ {
+ button1Rect = ButtonRectByPosition( KControlArrayCBAButton1Posn, EFalse );
+ button2Rect = ButtonRectByPosition( KControlArrayCBAButton2Posn, EFalse );
+ buttonMSKRect = ButtonRectByPosition( KControlArrayCBAButtonMSKPosn, EFalse );
+ }
+ else
+ {
+ button1Rect = button1->Rect();
+ button2Rect = button2->Rect();
+ buttonMSKRect = TRect( 0,0,0,0 );
+ }
+
+ // This flag is used to determine whether a pointer hit has
+ // happened in the grabbing control. It is needed to prevent
+ // the event from passing from one softkey to another.
+ TBool noHits = EFalse;
+
+ TBool buttonMSKDown = EFalse;
+ TBool button1Down = button1->PressedDown();
+ TBool button2Down = button2->PressedDown();
+ if ( buttonMSK )
+ {
+ buttonMSKDown = buttonMSK->PressedDown();
+ }
+
+ TBool button1Empty = EFalse;
+ if ( !button1->IsImageOn() && button1->IsEmptyText() )
+ {
+ button1Empty = ETrue;
+ }
+
+ TBool button2Empty = EFalse;
+ if ( !button2->IsImageOn() && button2->IsEmptyText() )
+ {
+ button2Empty = ETrue;
+ }
+
+ TBool buttonMSKEmpty = EFalse;
+ if ( buttonMSK && !buttonMSK->IsImageOn() && buttonMSK->IsEmptyText() )
+ {
+ buttonMSKEmpty = ETrue;
+ }
+
+ // If hits the left softkey.
+ if ( button1Rect.Contains( aPointerEvent.iPosition ) && !button1Empty )
+ {
+ if ( button1->IsVisible() )
+ {
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
+ {
+ button1->SetPressedDown( ETrue );
+
+ // Store the pointer of the button control to be
+ // used as the grabbing control, this is required
+ // in case the pointer events happens in the extended
+ // touch area where the button control doesn't receive
+ // the grab otherwise.
+ iExtension->iPointerGrabbingButton = button1;
+ }
+ else if ( aPointerEvent.iType == TPointerEvent::EButton1Up &&
+ button1->PressedDown() )
+ {
+ // Accept the up event only if the down event has happened
+ // in the same button.
+ button1->SetPressedDown( EFalse );
+ grabber = iExtension->iPointerGrabbingButton;
+
+ // Clear the grabber pointer at up event.
+ iExtension->iPointerGrabbingButton = NULL;
+ }
+ else if ( aPointerEvent.iType == TPointerEvent::EDrag )
+ {
+ if ( iExtension->iPointerGrabbingButton == button1 )
+ {
+ // Accept the drag event only if the down event has happened
+ // in the same button.
+ button1->SetPressedDown( ETrue );
+ button2->SetPressedDown( EFalse);
+ if ( buttonMSK )
+ {
+ buttonMSK->SetPressedDown( EFalse );
+ }
+ }
+ else
+ {
+ // Don't transfer the event to this button.
+ noHits = ETrue;
+ }
+ }
+ else
+ {
+ // The event happened outside the button areas
+ // or up event happened inside a button which
+ // didn't get the down event.
+ noHits = ETrue;
+ }
+ }
+ else
+ {
+ // Button is inactive
+ noHits = ETrue;
+ }
+ }
+ else if ( button2Rect.Contains( aPointerEvent.iPosition ) && !button2Empty )
+ {
+ if ( button2->IsVisible() )
+ {
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
+ {
+ button2->SetPressedDown( ETrue );
+
+ // Store the pointer of the button control to be
+ // used as the grabbing control, this is required
+ // in case the pointer events happens in the extended
+ // touch area where the button control doesn't receive
+ // the grab otherwise.
+ iExtension->iPointerGrabbingButton = button2;
+ }
+ else if ( aPointerEvent.iType == TPointerEvent::EButton1Up &&
+ button2->PressedDown() )
+ {
+ // Accept the up event only if the down event has happened
+ // in the same button.
+ button2->SetPressedDown( EFalse );
+ grabber = iExtension->iPointerGrabbingButton;
+
+ // Clear the grabber pointer at up event.
+ iExtension->iPointerGrabbingButton = NULL;
+ }
+ else if ( aPointerEvent.iType == TPointerEvent::EDrag )
+ {
+ if ( iExtension->iPointerGrabbingButton == button2 )
+ {
+ // Accept the drag event only if the down event has happened
+ // in the same button.
+ button2->SetPressedDown( ETrue );
+ button1->SetPressedDown( EFalse);
+ if ( buttonMSK )
+ {
+ buttonMSK->SetPressedDown( EFalse );
+ }
+ }
+ else
+ {
+ // Don't transfer the event to this button.
+ noHits = ETrue;
+ }
+ }
+ else
+ {
+ // The event happened outside the button areas
+ // or up event happened inside a button which
+ // didn't get the down event.
+ noHits = ETrue;
+ }
+ }
+ else
+ {
+ // Button is inactive
+ noHits = ETrue;
+ }
+ }
+ else if ( buttonMSK &&
+ !buttonMSKEmpty &&
+ buttonMSKRect.Contains( aPointerEvent.iPosition ) )
+ {
+ if ( buttonMSK->IsVisible() )
+ {
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
+ {
+ buttonMSK->SetPressedDown( ETrue );
+
+ // Store the pointer of the button control to be
+ // used as the grabbing control, this is required
+ // in case the pointer events happens in the extended
+ // touch area where the button control doesn't receive
+ // the grab otherwise.
+ iExtension->iPointerGrabbingButton = buttonMSK;
+ }
+ else if ( aPointerEvent.iType == TPointerEvent::EButton1Up &&
+ buttonMSK->PressedDown() )
+ {
+ // Accept the up event only if the down event has happened
+ // in the same button.
+ buttonMSK->SetPressedDown( EFalse );
+ grabber = iExtension->iPointerGrabbingButton;
+
+ // Clear the grabber pointer at up event.
+ iExtension->iPointerGrabbingButton = NULL;
+ }
+ else if ( aPointerEvent.iType == TPointerEvent::EDrag )
+ {
+ if ( iExtension->iPointerGrabbingButton == buttonMSK )
+ {
+ // Accept the drag event only if the down event has happened
+ // in the same button.
+ buttonMSK->SetPressedDown( ETrue );
+ button2->SetPressedDown( EFalse );
+ button1->SetPressedDown( EFalse );
+ }
+ else
+ {
+ // Don't transfer the event to this button.
+ noHits = ETrue;
+ }
+ }
+ else
+ {
+ // The event happened outside the button areas
+ // or up event happened inside a button which
+ // didn't get the down event.
+ noHits = ETrue;
+ }
+ }
+ else
+ {
+ // Button is inactive
+ noHits = ETrue;
+ }
+ }
+ else
+ {
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
+ {
+ // Clear the grabber pointer at up event.
+ iExtension->iPointerGrabbingButton = NULL;
+ }
+
+ noHits = ETrue;
+ }
+
+ if ( noHits )
+ {
+ button1->SetPressedDown( EFalse );
+ button2->SetPressedDown( EFalse );
+ if ( buttonMSK )
+ {
+ buttonMSK->SetPressedDown( EFalse );
+ }
+ }
+ else if ( aPointerEvent.iType != TPointerEvent::EDrag )
+ {
+ // CBA button has been hit with a down or up event, play feedback
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ TTouchFeedbackType fbType = TTouchFeedbackType( ETouchFeedbackAudio |
+ ETouchFeedbackVibra );
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
+ {
+ fbType = ETouchFeedbackVibra;
+ }
+ feedback->InstantFeedback( this,
+ ETouchFeedbackBasicButton,
+ fbType,
+ aPointerEvent );
+ }
+ }
+
+ if (button1Down != button1->PressedDown() ||
+ button2Down != button2->PressedDown() ||
+ (buttonMSK && (buttonMSKDown != buttonMSK->PressedDown())))
+ {
+
+ if ( iFlags.IsSet( ECbaEmbedded ) )
+ {
+ UpdateLabels( EFalse );
+
+ // Redraw only changed buttons. It's assumed that there's no
+ // visible MSK if softkeys are embedded.
+ TRect invalidRect( button1Rect );
+
+ if ( button2Down != button2->PressedDown() )
+ {
+ invalidRect = button2Rect;
+ }
+
+ // TODO: whole control is redrawn as a workaround for NGA bug that
+ // causes incorrect drawing of softkey labels when the second
+ // button is pressed down after the first one has already been
+ // pressed. Actually we should just redraw the invalidRect
+ // calculated above.
+ DrawNow();
+ }
+ else
+ {
+ SizeChanged();
+ DrawNow();
+ }
+ }
+
+ if ( !grabber && !noHits )
+ {
+ // Set the correct button to claim the pointer grab if the
+ // event happened in an extended touch area of the button
+ // (the button control didn't receive the event).
+ grabber = iExtension->iPointerGrabbingButton;
+ }
+
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Up && grabber && !noHits )
+ {
+ // This check also includes the extended touch space for a button.
+ if ( ( button1Rect.Contains( aPointerEvent.iPosition ) &&
+ button1Rect.Intersects( grabber->Rect() ) ) ||
+ ( button2Rect.Contains( aPointerEvent.iPosition ) &&
+ button2Rect.Intersects( grabber->Rect() ) ) ||
+ ( buttonMSKRect.Contains( aPointerEvent.iPosition ) &&
+ buttonMSKRect.Intersects( grabber->Rect() ) ) )
+ {
+ TInt buttoncount = iControlArray->Count();
+ for ( TInt i = 0; i < buttoncount; i++ )
+ {
+ if ( (*iControlArray)[i].iControl == grabber )
+ {
+ if ( !IsVisible() )
+ return;
+
+ // Send the button command to command observer.
+ TInt shortCommand = (*iControlArray)[i].iId;
+ if ( shortCommand &&
+ i == KControlArrayCBAButtonMSKPosn &&
+ iMSKCommandObserver )
+ {
+ iMSKCommandObserver->ProcessCommandL( shortCommand );
+ }
+
+ if( shortCommand )
+ {
+ iCommandObserver->ProcessCommandL( shortCommand );
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+
+TSize CEikCba::MinimumSize()
+ {
+ TSize size = CEikControlGroup::MinimumSize();
+ size.iWidth = iAvkonAppUi->ApplicationRect().Width();
+ const TInt count = iControlArray->Count();
+ for (TInt ii = 0; ii < count; ii++)
+ {
+ size.iHeight = Max(size.iHeight, (*iControlArray)[ii].iControl->MinimumSize().iHeight);
+ }
+ if (iLink)
+ {
+ size.iHeight = Max(size.iHeight, iLink->Size().iHeight);
+ }
+ // Add a standard margin from the laf.
+ return size;
+ }
+
+/**
+* Gets the list of logical colors employed in the drawing of the control,
+* paired with an explanation of how they are used. Appends the list to aColorUseList.
+*
+* @since ER5U
+*/
+void CEikCba::GetColorUseListL(CArrayFix<TCoeColorUse>& aColorUseList) const
+ {
+ CEikControlGroup::GetColorUseListL(aColorUseList);
+
+ TInt commonAttributes = TCoeColorUse::ESurrounds|TCoeColorUse::EActive|TCoeColorUse::ENormal|
+ TCoeColorUse::ENeutral;
+
+ TCoeColorUse colorUse;
+
+ colorUse.SetLogicalColor(EColorToolbarText);
+ colorUse.SetUse(TCoeColorUse::EFore|commonAttributes);
+ aColorUseList.AppendL(colorUse);
+
+ colorUse.SetLogicalColor(EColorToolbarBackground);
+ colorUse.SetUse(TCoeColorUse::EBack|commonAttributes);
+ aColorUseList.AppendL(colorUse);
+ }
+
+
+// ---------------------------------------------------------------------------
+// Handles a change to the control's resources of type aType
+// which are shared across the environment, e.g. colors or fonts.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::HandleResourceChange( TInt aType )
+ {
+ CEikControlGroup::HandleResourceChange( aType );
+
+ switch ( aType )
+ {
+ case KAknsMessageSkinChange:
+ {
+ if ( IsVisible() )
+ {
+ DoSkinChange();
+ if( iExtension->iIfMskIconSet )
+ {
+ TRAP_IGNORE( UpdateIconL() );
+ }
+ }
+ else
+ {
+ iFlags.Set( ECbaChangeRecordedSkin );
+ }
+ break;
+ }
+
+ case KEikColorResourceChange:
+ {
+ if ( IsVisible() )
+ {
+ DoColorChange();
+ }
+ else
+ {
+ iFlags.Set( ECbaChangeRecordedColor );
+ }
+ break;
+ }
+
+ case KEikDynamicLayoutVariantSwitch:
+ {
+ if ( IsVisible() )
+ {
+ DoLayoutChange();
+ SetBoundingRect( TRect() );
+ if ( iFlags.IsSet( ECbaInsideDialog )
+ || iFlags.IsSet( ECbaEmbedded ) )
+ {
+ DrawDeferred();
+ }
+ else
+ {
+ DrawNow();
+ }
+ }
+ else
+ {
+ iFlags.Set( ECbaChangeRecordedLayout );
+ }
+ break;
+ }
+
+ case KAknMessageFocusLost:
+ {
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ return;
+ }
+
+
+ CEikCbaButton* button1 =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl );
+ CEikCbaButton* button2 =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl );
+ CEikCbaButton* buttonMSK = NULL;
+
+ if ( iMSKset && AknLayoutUtils::MSKEnabled() )
+ {
+ buttonMSK =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl );
+ }
+
+ TBool redrawNeeded( EFalse );
+
+ if ( button1 && button1->PressedDown() )
+ {
+ button1->SetPressedDown( EFalse );
+ redrawNeeded = ETrue;
+ }
+ if ( button2 && button2->PressedDown() )
+ {
+ button2->SetPressedDown( EFalse );
+ redrawNeeded = ETrue;
+ }
+ if ( buttonMSK && buttonMSK->PressedDown() )
+ {
+ buttonMSK->SetPressedDown( EFalse );
+ redrawNeeded = ETrue;
+ }
+
+ if ( buttonMSK && iExtension )
+ {
+ SetBoundingRect( TRect( 0, 0, 0, 0 ) );
+ redrawNeeded = ETrue;
+ }
+ if ( redrawNeeded )
+ {
+ SizeChanged();
+ DrawDeferred();
+ }
+
+ if ( iFlags.IsSet( ECbaItemSpecificSoftkeyInUse ) )
+ {
+ UpdateItemSpecificSoftkey( EFalse );
+ }
+ break;
+ }
+
+ case KEikMessageUnfadeWindows:
+ {
+ DoLayoutChange();
+ SetFadeState();
+
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ DrawDeferred();
+ }
+ else
+ {
+ //When touch unsupported,it's unnecessary to call DrawNow()
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ DrawNow();
+ }
+ else
+ {
+ DrawDeferred();
+ }
+ }
+
+ break;
+ }
+
+ case KEikMessageFadeAllWindows:
+ {
+ if ( AknLayoutUtils::PenEnabled() &&
+ AknStatuspaneUtils::IdleLayoutActive() )
+ {
+ SetMSKVisibility( MskAllowed() );
+ }
+ SetFadeState();
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+
+void CEikCba::DoSkinChange()
+ {
+ iExtension->iIfSkinChanged = ETrue;
+ DoSetLayers( KAknsIIDNone );
+ iExtension->iIfSkinChanged = EFalse;
+ if ( iExtension )
+ {
+ TRAP_IGNORE( iExtension->UpdateSoftkeyFrameL( ETrue ) );
+ }
+
+ // This is required for skin resource changes (as well as color resource change).
+ CheckSkinAndUpdateContext();
+ TRAP_IGNORE( SetMSKIconL() );
+ SizeChanged();
+
+ //Skin change uses DrawNow to flus draw cache before layoutchange.
+ DrawNow();
+ iFlags.Clear(ECbaChangeRecordedSkin);
+ }
+
+void CEikCba::DoColorChange()
+ {
+ iBrushAndPenContext->SetBrushColor(iEikonEnv->ControlColor(EColorToolbarBackground, *this));
+ iBrushAndPenContext->SetPenColor(iEikonEnv->ControlColor(EColorToolbarText, *this));
+ Window().SetBackgroundColor(iEikonEnv->ControlColor(EColorToolbarBackground, *this));
+ // This is required for skin resource changes (as well as color resource change).
+ CheckSkinAndUpdateContext();
+ TRAP_IGNORE( SetMSKIconL() );
+ SizeChanged();
+ iFlags.Clear(ECbaChangeRecordedColor);
+ }
+
+
+void CEikCba::DoLayoutChange()
+ {
+ SetBoundingRect( TRect() );
+
+ UpdateFonts();
+
+ TBool mskAllowed( MskAllowed() );
+ if ( !mskAllowed )
+ {
+ SetMSKVisibility( EFalse );
+ }
+ else
+ {
+ SetMSKVisibility( ETrue );
+ TRAP_IGNORE( SetMSKIconL() );
+ }
+
+ if ( iFlags.IsSet( ECbaEmbedded ) )
+ {
+ CEikCbaButton* button1 =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl );
+ CEikCbaButton* button2 =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl );
+
+ if ( button1 )
+ {
+ button1->SetPressedDown( EFalse );
+ }
+
+ if ( button2 )
+ {
+ button2->SetPressedDown( EFalse );
+ }
+ }
+
+ SizeChanged();
+
+ if ( iExtension )
+ {
+ TRAP_IGNORE( iExtension->UpdateSoftkeyFrameL( EFalse ) );
+ }
+
+ iFlags.Clear( ECbaChangeRecordedLayout );
+ }
+
+
+void CEikCba::HandleScrollEventL(CEikScrollBar* /*aScrollBar*/, TEikScrollEvent /*aEventType*/)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+TTypeUid::Ptr CEikCba::MopSupplyObject(TTypeUid aId)
+ {
+ if (aId.iUid == MAknsControlContext::ETypeId)
+ {
+ if ( AknLayoutFlags() & EAknLayoutCbaInControlPane ||
+ AknLayoutFlags() & EAknLayoutCbaInRightPane )
+ {
+ return MAknsControlContext::SupplyMopObject( aId, iMLBgContext );
+ }
+ else
+ {
+ // Always provide top object to mop-chain.
+ // Bottom is parent of Top, so bottom is re-drawn
+ // automatically when top is drawn.
+ return MAknsControlContext::SupplyMopObject( aId, iStaconBgContextTop );
+ }
+ }
+
+ if ( aId.iUid == CEikCba::ETypeId )
+ {
+ return aId.MakePtr( this );
+ }
+
+ return CEikControlGroup::MopSupplyObject(aId);
+ }
+
+
+void CEikCba::Draw( const TRect& aRect ) const
+ {
+ // Embedded CBA doesn't draw anything
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ return;
+ }
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ const TRect rect( Rect() );
+ CWindowGc& gc = SystemGc();
+
+ TRgb rgb( TRgb::Color16MA( 0 ) );
+ gc.SetDrawMode( CGraphicsContext::EDrawModeWriteAlpha );
+ gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+ gc.SetBrushColor( rgb );
+ gc.Clear();
+
+ MAknsControlContext* cc = iMLBgContext;
+
+ if ( iFlags.IsSet( ECbaEmbedded ) )
+ {
+ // Embedded CBA is drawn inside dialog
+ if ( AknLayoutUtils::PenEnabled() && iExtension )
+ {
+ if ( aRect.Intersects( iExtension->iLeftFrameOuterRect ) )
+ {
+ DrawEmbeddedSoftkey(
+ iControlArray->At( KControlArrayCBAButton1Posn ),
+ iExtension->iLeftFrameOuterRect,
+ gc,
+ iExtension->iLeftFrameMask );
+ }
+
+ if ( aRect.Intersects( iExtension->iRightFrameOuterRect ) )
+ {
+ DrawEmbeddedSoftkey(
+ iControlArray->At( KControlArrayCBAButton2Posn ),
+ iExtension->iRightFrameOuterRect,
+ gc,
+ iExtension->iRightFrameMask );
+ }
+ }
+ } //ECbaEmbedded
+ else if ( AknLayoutFlags() & EAknLayoutCbaInControlPane )
+ {
+ if ( AknLayoutUtils::PenEnabled() || ( iCbaFlags & EEikCbaFlagTransparent)
+ ||iExtension->iEnablePostingTransparency )
+ {
+ TAknLayoutRect layoutRect;
+ TRect leftSKRect( iExtension->iLeftFrameOuterRect );
+ TRect rightSKRect( iExtension->iRightFrameOuterRect );
+ TRect middleSKRect( iExtension->iMiddleFrameOuterRect );
+
+ TSize leftSKSize( leftSKRect.Size() );
+ TSize rightSKSize( rightSKRect.Size() );
+ TSize middleSKSize( middleSKRect.Size() );
+
+ if ( iExtension &&
+ iExtension->iLskPostingOverlayBitmap &&
+ iExtension->iRskPostingOverlayBitmap )
+ {
+ // This code may be executed if iExtension->iEnablePostingTransparency
+ // holds. Draw graphics with mask information alpha channel for
+ // transparency for posting overlay
+ gc.SetDrawMode( CGraphicsContext::EDrawModeWriteAlpha );
+ gc.BitBlt( rightSKRect.iTl, iExtension->iRskPostingOverlayBitmap,
+ TRect( rightSKSize ) );
+ gc.BitBlt( leftSKRect.iTl, iExtension->iLskPostingOverlayBitmap,
+ TRect( leftSKSize ) );
+ }
+ else if ( !( ( iCbaFlags & EEikCbaFlagTransparent) || ( iCbaFlags & EEikCbaFlagSemiTransparent)) )
+ {// Old way to render
+ if( !AknsDrawUtils::Background( skin, cc, this, gc, rect ) )
+ {
+ gc.SetPenStyle( CGraphicsContext::ENullPen );
+ gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+ gc.SetBrushColor( AKN_LAF_COLOR( KStatusPaneBackgroundGraphicsColorUsual ) );
+ gc.DrawRect( rect );
+ }
+ if ( iExtension )
+ {
+
+ CEikCbaButton* button1 = static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl );
+ CEikCbaButton* button2 = static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl );
+
+ if ( IsMskEnabledLayoutActive() )
+ {
+ CEikCbaButton* buttonMSK = static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl );
+
+ CFbsBitmap* middleMask =
+ AknsUtils::GetCachedBitmap( skin, KAknsIIDQgnIndiSctrlSkMaskMiddlePrt );
+ AknIconUtils::SetSize( middleMask, middleSKSize, EAspectRatioNotPreserved );
+
+ if( buttonMSK && buttonMSK->PressedDown() )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iMiddleFrameOuterRect,
+ iExtension->iMiddleFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButtonPressed,
+ KAknsIIDQgnFrSctrlSkButtonCenterPressed );
+ }
+ else
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iMiddleFrameOuterRect,
+ iExtension->iMiddleFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButton,
+ KAknsIIDQgnFrSctrlSkButtonCenter);
+ }
+
+ }
+
+ if( button1 && button1->PressedDown() )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iLeftFrameOuterRect,
+ iExtension->iLeftFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButtonPressed,
+ KAknsIIDQgnFrSctrlSkButtonCenterPressed );
+ }
+ else
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iLeftFrameOuterRect,
+ iExtension->iLeftFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButton,
+ KAknsIIDQgnFrSctrlSkButtonCenter);
+ }
+
+ if( button2 && button2->PressedDown() )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iRightFrameOuterRect,
+ iExtension->iRightFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButtonPressed,
+ KAknsIIDQgnFrSctrlSkButtonCenterPressed );
+ }
+ else
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iRightFrameOuterRect,
+ iExtension->iRightFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButton,
+ KAknsIIDQgnFrSctrlSkButtonCenter);
+ }
+
+
+ }
+ }
+ }
+ else
+ {
+ if ( !AknsDrawUtils::Background( skin, cc, this, gc, rect ) )
+ {
+ CEikControlGroup::Draw( aRect );
+ }
+ }
+ }
+ else if ( AknLayoutFlags() & EAknLayoutCbaInRightPane )
+ {
+ TRect bottomSKRect;
+ TRect topSKRect;
+ if ( iExtension )
+ {
+ bottomSKRect = iExtension->iLeftFrameOuterRect;
+ topSKRect = iExtension->iRightFrameOuterRect;
+ }
+
+ if ( iExtension &&
+ iExtension->iLskPostingOverlayBitmap &&
+ iExtension->iRskPostingOverlayBitmap )
+ {
+ // This code may be executed if iExtension->iEnablePostingTransparency
+ // holds. Draw graphics with mask information alpha channel for
+ // transparency for posting overlay
+ gc.SetDrawMode( CGraphicsContext::EDrawModeWriteAlpha );
+ gc.BitBlt( topSKRect.iTl, iExtension->iRskPostingOverlayBitmap,
+ TRect( topSKRect.Size() ) );
+ gc.BitBlt( bottomSKRect.iTl, iExtension->iLskPostingOverlayBitmap,
+ TRect( bottomSKRect.Size() ) );
+ }
+ else if ( !( ( iCbaFlags & EEikCbaFlagTransparent) || ( iCbaFlags & EEikCbaFlagSemiTransparent)) )
+ {
+ // Old way to render
+ if( !AknsDrawUtils::Background( skin, cc, this, gc, rect ) )
+ {
+ gc.SetPenStyle( CGraphicsContext::ENullPen );
+ gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+ gc.SetBrushColor( AKN_LAF_COLOR( KStatusPaneBackgroundGraphicsColorUsual ) );
+ gc.DrawRect( rect );
+ }
+
+ // Draw the softkey frames.
+ if ( iExtension )
+ {
+
+ CEikCbaButton* button1 = static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl );
+ CEikCbaButton* button2 = static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl );
+
+ if ( button1 && button1->PressedDown() )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iLeftFrameOuterRect,
+ iExtension->iLeftFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButtonPressed,
+ KAknsIIDQgnFrSctrlSkButtonCenterPressed );
+ }
+ else
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iLeftFrameOuterRect,
+ iExtension->iLeftFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButton,
+ KAknsIIDQgnFrSctrlSkButtonCenter );
+ }
+
+ if ( button2 && button2->PressedDown() )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iRightFrameOuterRect,
+ iExtension->iRightFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButtonPressed,
+ KAknsIIDQgnFrSctrlSkButtonCenterPressed );
+ }
+ else
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iRightFrameOuterRect,
+ iExtension->iRightFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButton,
+ KAknsIIDQgnFrSctrlSkButtonCenter );
+ }
+ }
+ }
+ else if ( ( iCbaFlags & EEikCbaFlagSemiTransparent) && iExtension )
+ {
+ if ( iExtension->iSemiBgID != KAknsIIDNone )
+ {
+ iExtension->DrawSemiTransparencyL( gc, rect );
+ }
+ }
+ else
+ {
+ // No background since EEikCbaFlagTransparent is set.
+ // Do nothing.
+ }
+ }
+ else
+ {
+ // Combined statusp and control pane
+
+ TRect screen( iAvkonAppUi->ApplicationRect() );
+
+ TInt variety = 0;
+ if ( AknLayoutFlags() & EAknLayoutCbaInStaconPaneLeft )
+ {
+ variety = 1;
+ }
+
+ TAknWindowComponentLayout layout0;
+ TAknWindowComponentLayout layout1;
+ TAknWindowComponentLayout layout2;
+
+ // Read right (top in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_top_pane( 2 );
+ layout1 = AknLayoutScalable_Avkon::stacon_top_pane();
+
+ // If clock is shown in stacon, cba area is smaller.
+ TInt topCbaVariety = variety;
+ if ( AknStatuspaneUtils::ExtendedStaconPaneActive() )
+ {
+ topCbaVariety += 4;
+ }
+
+ layout2 = AknLayoutScalable_Avkon::control_top_pane_stacon( topCbaVariety );
+
+ TAknWindowLineLayout rightSoftkeyLayout(
+ DoCompose( layout0,DoCompose( layout1, layout2 ) ).LayoutLine() );
+
+ TAknLayoutRect rightSoftkeyLayoutRect;
+ rightSoftkeyLayoutRect.LayoutRect( screen, rightSoftkeyLayout );
+
+ // Read left (bottom in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_bottom_pane( 2 );
+ layout1 = AknLayoutScalable_Avkon::stacon_bottom_pane();
+
+ // If clock is shown in stacon, cba area is smaller.
+ TInt bottomCbaVariety = variety;
+ if ( AknStatuspaneUtils::ExtendedStaconPaneActive() )
+ {
+ bottomCbaVariety += 2;
+ }
+
+ layout2 =
+ AknLayoutScalable_Avkon::control_bottom_pane_stacon(
+ bottomCbaVariety );
+
+ TAknWindowLineLayout leftSoftkeyLayout(
+ DoCompose( layout0, DoCompose( layout1, layout2 ) ).LayoutLine() );
+
+ TAknLayoutRect leftSoftkeyLayoutRect;
+ leftSoftkeyLayoutRect.LayoutRect( screen, leftSoftkeyLayout );
+
+ TRect staconBottom( leftSoftkeyLayoutRect.Rect() );
+
+ // First draw bottom area.
+ cc = iStaconBgContextBottom;
+
+ if ( iExtension && iExtension->iLskPostingOverlayBitmap )
+ {
+ // This code may be executed if iExtension->iEnablePostingTransparency
+ // holds. Draw graphics with mask information alpha channel for
+ // transparency for posting overlay
+ gc.SetDrawMode( CGraphicsContext::EDrawModeWriteAlpha );
+
+ gc.BitBlt( staconBottom.iTl, iExtension->iLskPostingOverlayBitmap,
+ TRect( staconBottom.Size() ) );
+ }
+ else if ( !( iCbaFlags & EEikCbaFlagTransparent) )
+ {
+ if( !AknsDrawUtils::Background( skin, cc, this, gc, staconBottom ) )
+ {
+ gc.SetPenStyle(CGraphicsContext::ENullPen);
+ gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ gc.SetBrushColor(AKN_LAF_COLOR(KStatusPaneBackgroundGraphicsColorUsual));
+ gc.DrawRect(staconBottom);
+ }
+ if ( iExtension )
+ {
+ CEikCbaButton* button1 = static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl );
+
+ if ( button1 && button1->PressedDown() )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iLeftFrameOuterRect,
+ iExtension->iLeftFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButtonPressed,
+ KAknsIIDQgnFrSctrlSkButtonCenterPressed );
+ }
+ else
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iLeftFrameOuterRect,
+ iExtension->iLeftFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButton,
+ KAknsIIDQgnFrSctrlSkButtonCenter );
+ }
+ }
+ }
+ // Then top area.
+ cc = iStaconBgContextTop;
+
+ TRect staconTop( rightSoftkeyLayoutRect.Rect() );
+
+ if ( iExtension && iExtension->iRskPostingOverlayBitmap )
+ {
+ // This code may be executed if iExtension->iEnablePostingTransparency
+ // holds. Draw graphics with mask information alpha channel for
+ // transparency for posting overlay
+ gc.SetDrawMode( CGraphicsContext::EDrawModeWriteAlpha );
+
+ gc.BitBlt( staconTop.iTl, iExtension->iRskPostingOverlayBitmap,
+ TRect( staconTop.Size() ) );
+ }
+ else if ( !( iCbaFlags & EEikCbaFlagTransparent) )
+ {
+ if( !AknsDrawUtils::Background( skin, cc, this, gc, staconTop ) )
+ {
+ gc.SetPenStyle(CGraphicsContext::ENullPen);
+ gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ gc.SetBrushColor(AKN_LAF_COLOR(KStatusPaneBackgroundGraphicsColorUsual));
+ gc.DrawRect(staconTop);
+ }
+ if ( iExtension )
+ {
+
+ CEikCbaButton* button2 = static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl );
+
+ if ( button2 && button2->PressedDown() )
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iRightFrameOuterRect,
+ iExtension->iRightFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButtonPressed,
+ KAknsIIDQgnFrSctrlSkButtonCenterPressed );
+ }
+ else
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ gc,
+ iExtension->iRightFrameOuterRect,
+ iExtension->iRightFrameInnerRect,
+ KAknsIIDQgnFrSctrlSkButton,
+ KAknsIIDQgnFrSctrlSkButtonCenter );
+ }
+ }
+ }
+ }
+ gc.SetOpaque( EFalse );
+ }
+
+
+// ---------------------------------------------------------------------------
+// Gets a button control by the specified command ID.
+// ---------------------------------------------------------------------------
+//
+CCoeControl* CEikCba::ButtonById( TInt aCommandId ) const
+ {
+ return ControlById( aCommandId );
+ }
+
+
+// ---------------------------------------------------------------------------
+// Creates the scroll bar frame & sets up the scroll bar.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::CreateScrollBarFrameL()
+ {
+ if ( !iSBFrame )
+ {
+ iSBFrame = new (ELeave) CEikCbaScrollBarFrame( this, this, ETrue );
+ }
+ iSBFrame->ConstructL();
+ }
+
+
+TEikGroupControl CEikCba::VScrollBarAsGroupControl()
+ {
+ // Extracts vertical scroll bar from the scroll bar frame.
+ TEikGroupControl groupCtrl(iSBFrame->VerticalScrollBar(), 0,
+ KCbaScrollBarButtonWidth,TEikGroupControl::ESetLength);
+ return groupCtrl;
+ }
+
+void CEikCba::InsertScrollBarL()
+ {
+ TEikGroupControl SBGroupCtrl = VScrollBarAsGroupControl();
+ // Insert vertical scroll bar into cba control group.
+ InsertControlL(SBGroupCtrl, KControlArrayScrollBarPosn);
+ }
+
+
+// ---------------------------------------------------------------------------
+// Replaces empty scroll bar with actual arrow head scroll bar.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::CreateArrowHeadScrollBarL()
+ {
+ if ( iSBFrame )
+ {
+ iSBFrame->SwitchToArrowHeadScrollBarL();
+ iSBFrame->VerticalScrollBar()->SetContainingCba( this );
+ if ( iControlArray->Count() > KControlArrayScrollBarPosn )
+ {
+ iControlArray->Delete( KControlArrayScrollBarPosn );
+ }
+ InsertScrollBarL();
+ }
+ }
+
+
+void CEikCba::SizeChanged()
+ {
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ Window().SetNonFading( EFalse );
+ SizeChangedInsideDialog();
+ return;
+ }
+ else if ( iFlags.IsSet( ECbaEmbedded ) )
+ {
+ Window().SetNonFading( EFalse );
+ SizeChangedInPopup();
+ return;
+ }
+
+ const TInt aknLayoutFlags = AknLayoutFlags();
+
+ if ( aknLayoutFlags & EAknLayoutCbaInControlPane )
+ {
+ Window().SetNonFading( EFalse );
+ SizeChangedInControlPane();
+ }
+ else if ( aknLayoutFlags & EAknLayoutCbaInRightPane )
+ {
+ Window().SetNonFading( EFalse );
+ SizeChangedInRightPane();
+ }
+ else
+ {
+ Window().SetNonFading(ETrue);
+ SizeChangedInStaconPane();
+ }
+ // Set the feedback areas for the softkeys.
+ if ( iExtension && iExtension->iEnablePostingTransparency )
+ {
+ TBool enabled =
+ // AknLayoutUtils::PenEnabled() &&
+ // ( AknLayoutFlags() & EAknLayoutCbaInRightPane ) &&
+ !Rect().IsEmpty();
+
+ if ( enabled )
+ {
+ CEikCbaButton* button1 =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl );
+ CEikCbaButton* button2 =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl );
+
+ TInt leftId = (*iControlArray)[KControlArrayCBAButton1Posn].iId;
+
+ TRAPD( err, iExtension->UpdatePostingOverlayBitmapsL(
+ Rect(),
+ button1,
+ button2,
+ aknLayoutFlags ) );
+
+ if ( err )
+ {
+ // Bitmaps may not be up-to-date.
+ enabled = EFalse;
+ }
+ }
+
+ if ( !enabled )
+ {
+ // Delete and disable posting overlay support.
+ delete iExtension->iLskPostingOverlayBitmap;
+ iExtension->iLskPostingOverlayBitmap = NULL;
+ delete iExtension->iRskPostingOverlayBitmap;
+ iExtension->iRskPostingOverlayBitmap = NULL;
+ }
+
+ // Broadcast current state to CEikCbaButtons
+ BroadcastPostingTransparency( enabled );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CEikCba::CheckSkinAndUpdateContext
+//
+// -----------------------------------------------------------------------------
+//
+void CEikCba::CheckSkinAndUpdateContext()
+ {
+ if (AknsUtils::SkinInstance())
+ {
+ // Use ENullBrush if there is skin background available.
+ iBrushAndPenContext->SetBrushStyle(CGraphicsContext::ENullBrush);
+ }
+ else
+ {
+ iBrushAndPenContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ }
+ }
+
+void CEikCba::Reserved_MtsmPosition()
+ {
+ }
+
+void CEikCba::Reserved_MtsmObject()
+ {
+ }
+
+TInt CEikCba::AknLayoutFlags() const
+ {
+ TInt flags = 0;
+
+ TBool controlPane = ETrue;
+ TBool staconPane = EFalse;
+ TBool staconPaneLeft = EFalse;
+ TBool staconPaneRight = EFalse;
+ TBool staconPaneIdle = EFalse;
+ TBool rightPane = EFalse;
+
+ TInt currentStatusPaneLayoutResId =
+ AVKONENV->StatusPaneResIdForCurrentLayout(
+ AknStatuspaneUtils::CurrentStatusPaneLayoutResId() );
+
+ staconPane =
+ ((currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_USUAL_SOFTKEYS_RIGHT) ||
+ (currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_USUAL_SOFTKEYS_LEFT) ||
+ (currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_EMPTY_SOFTKEYS_RIGHT) ||
+ (currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_EMPTY_SOFTKEYS_LEFT) ||
+ (currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_IDLE_SOFTKEYS_RIGHT) ||
+ (currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_IDLE_SOFTKEYS_LEFT));
+
+ staconPaneRight =
+ ((currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_USUAL_SOFTKEYS_RIGHT) ||
+ (currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_EMPTY_SOFTKEYS_RIGHT) ||
+ (currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_IDLE_SOFTKEYS_RIGHT));
+
+ staconPaneIdle =
+ ((currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_IDLE_SOFTKEYS_RIGHT) ||
+ (currentStatusPaneLayoutResId == R_AVKON_STACON_PANE_LAYOUT_IDLE_SOFTKEYS_LEFT));
+
+ staconPaneLeft = !staconPaneRight;
+ controlPane = !staconPane;
+
+ if ( IsAreaSideRightPaneActive() )
+ {
+ rightPane = ETrue;
+ controlPane = EFalse;
+ staconPane = EFalse;
+ staconPaneLeft = EFalse;
+ staconPaneRight = EFalse;
+ staconPaneIdle = EFalse;
+ }
+
+ if (staconPane)
+ {
+ flags |= EAknLayoutCbaInStaconPane;
+ }
+ if (controlPane)
+ {
+ flags |= EAknLayoutCbaInControlPane;
+ }
+ if (staconPaneLeft)
+ {
+ flags |= EAknLayoutCbaInStaconPaneLeft;
+ }
+ if (staconPaneRight)
+ {
+ flags |= EAknLayoutCbaInStaconPaneRight;
+ }
+ if (staconPaneIdle)
+ {
+ flags |= EAknLayoutCbaInStaconPaneIdle;
+ }
+ if (rightPane)
+ {
+ flags |= EAknLayoutCbaInRightPane;
+ }
+
+ return flags;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Handles size change events in bottom softkey layout.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::SizeChangedInControlPane()
+ {
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
+ TBool flatLscLayout( isLandscape &&
+ AknStatuspaneUtils::FlatLayoutActive() );
+
+ // We must check for landscape mode bottom softkeys.
+ TInt bottomPaneVariety = isLandscape ? ( flatLscLayout ? 2 : 6 ) : 1;
+
+ TAknWindowComponentLayout controlPane(
+ DoCompose(
+ AknLayoutScalable_Avkon::application_window( 0 ),
+ DoCompose(
+ AknLayoutScalable_Avkon::area_bottom_pane( bottomPaneVariety ),
+ AknLayoutScalable_Avkon::control_pane() ) ) );
+
+ TAknLayoutRect cbarect;
+ cbarect.LayoutRect( screen, controlPane.LayoutLine() );
+ TRect rect( cbarect.Rect().Size() );
+
+ TRect posInScreen( cbarect.Rect() );
+
+ TBool mskEnabledInPlatform( iMSKEnabledInPlatform &&
+ IsMskEnabledLayoutActive() );
+
+ TBool mskEnabledInApplication( AknLayoutUtils::MSKEnabled() && iMSKset );
+
+ // Set the softkey frame rectangles in touch layouts.
+ if ( iExtension && AknLayoutUtils::PenEnabled() )
+ {
+ TAknLayoutRect layoutRect;
+ TBool frameSizeChanged( EFalse );
+
+ if ( mskEnabledInPlatform || flatLscLayout )
+ {
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::control_pane_g6( 0 ).LayoutLine() );
+ frameSizeChanged = layoutRect.Rect() != iExtension->iLeftFrameOuterRect;
+ iExtension->iLeftFrameOuterRect = layoutRect.Rect();
+
+ layoutRect.LayoutRect( iExtension->iLeftFrameOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ iExtension->iLeftFrameInnerRect = layoutRect.Rect();
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::control_pane_g8( 0 ).LayoutLine() );
+ frameSizeChanged = frameSizeChanged || layoutRect.Rect() != iExtension->iRightFrameOuterRect;
+ iExtension->iRightFrameOuterRect = layoutRect.Rect();
+ layoutRect.LayoutRect( iExtension->iRightFrameOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ iExtension->iRightFrameInnerRect = layoutRect.Rect();
+
+ if ( mskEnabledInPlatform )
+ {
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::control_pane_g7( 0 ).LayoutLine() );
+ frameSizeChanged = frameSizeChanged || layoutRect.Rect() != iExtension->iMiddleFrameOuterRect;
+ iExtension->iMiddleFrameOuterRect = layoutRect.Rect();
+ layoutRect.LayoutRect( iExtension->iMiddleFrameOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ iExtension->iMiddleFrameInnerRect = layoutRect.Rect();
+ }
+ else
+ {
+ iExtension->iMiddleFrameOuterRect.SetRect( 0, 0, 0, 0 );
+ }
+ }
+ else
+ {
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_cp1().LayoutLine() );
+ frameSizeChanged = layoutRect.Rect() != iExtension->iRightFrameOuterRect;
+ iExtension->iRightFrameOuterRect = layoutRect.Rect();
+ layoutRect.LayoutRect( iExtension->iRightFrameOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ iExtension->iRightFrameInnerRect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_cp2().LayoutLine() );
+ frameSizeChanged = frameSizeChanged || layoutRect.Rect() != iExtension->iLeftFrameOuterRect;
+ iExtension->iLeftFrameOuterRect = layoutRect.Rect();
+
+ layoutRect.LayoutRect( iExtension->iLeftFrameOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ iExtension->iLeftFrameInnerRect = layoutRect.Rect();
+ }
+ else
+ {
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_cp1().LayoutLine() );
+ frameSizeChanged = layoutRect.Rect() != iExtension->iLeftFrameOuterRect;
+ iExtension->iLeftFrameOuterRect = layoutRect.Rect();
+
+ layoutRect.LayoutRect( iExtension->iLeftFrameOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ iExtension->iLeftFrameInnerRect = layoutRect.Rect();
+
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_cp2().LayoutLine() );
+ frameSizeChanged = frameSizeChanged || layoutRect.Rect() != iExtension->iRightFrameOuterRect;
+ iExtension->iRightFrameOuterRect = layoutRect.Rect();
+ layoutRect.LayoutRect( iExtension->iRightFrameOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ iExtension->iRightFrameInnerRect = layoutRect.Rect();
+ }
+ }
+
+ if ( frameSizeChanged )
+ {
+ TRAP_IGNORE( iExtension->UpdateSoftkeyFrameL( EFalse ) );
+ }
+ }
+
+ DoSetLayers( KAknsIIDNone );
+
+ TInt textVariety;
+ TInt graphVariety;
+
+ // Even if the application is not MSK enabled,
+ // use MSK layout when MSK is enabled in platform.
+ if ( isLandscape )
+ {
+ if ( mskEnabledInPlatform )
+ {
+ textVariety = 3;
+ graphVariety = 2;
+ }
+ else
+ {
+ TBool extendedLayout( AknStatuspaneUtils::ExtendedFlatLayoutActive() );
+ textVariety = extendedLayout ? 3 : 2;
+ graphVariety = extendedLayout ? 3 : 2;
+ }
+ }
+ else if ( mskEnabledInPlatform )
+ {
+ textVariety = 3;
+ graphVariety = 4;
+ }
+ else
+ {
+ textVariety = 0;
+ graphVariety = 4;
+ }
+
+ if ( iExtension->iEnablePostingTransparency ||
+ ( iCbaFlags & EEikCbaFlagTransparent ) || ( iCbaFlags & EEikCbaFlagSemiTransparent ) )
+ {
+ textVariety = 6; // Outline font used
+ }
+
+ // This uses correct coordinates to calculate the positions of softkey labels.
+ // Unfortunately we do not have access to the labels inside CEikCbaButtons,
+ // that's the reason for a hack with ComponentControl().
+ // (This is the only place that knows of all softkeys ...)
+ if ( iControlArray->Count() != 0 )
+ {
+ CCoeControl* leftSoftkey = (*iControlArray)[KControlArrayCBAButton1Posn].iControl;
+ CCoeControl* rightSoftkey = (*iControlArray)[KControlArrayCBAButton2Posn].iControl;
+ CCoeControl* MSKSoftkey = NULL;
+
+ CEikCbaButton* leftSKButton =
+ static_cast<CEikCbaButton*>( leftSoftkey );
+ CEikCbaButton* rightSKButton =
+ static_cast<CEikCbaButton*>( rightSoftkey );
+ CEikCbaButton* MSKButton = NULL;
+
+ TAknTextLineLayout controlPaneTextLayout;
+
+ if ( !leftSKButton->IsImageOn() )
+ {
+ controlPaneTextLayout =
+ AknLayoutScalable_Avkon::control_pane_t1( textVariety ).LayoutLine();
+
+ if ( iCbaFlags & EEikCbaFlagOutlineFont )
+ {
+ // Sets outline font property.
+ controlPaneTextLayout.iFont |= KOutlineFontMask;
+ }
+
+ CEikLabel* cbaLabel =
+ static_cast<CEikLabel*>( leftSoftkey->ComponentControl( 0 ) );
+ AknLayoutUtils::LayoutLabel( cbaLabel,
+ Rect(),
+ controlPaneTextLayout );
+ LayoutControl( leftSKButton, cbaLabel->Rect() );
+ leftSKButton->TruncateLabelText();
+ }
+ else
+ {
+ TAknLayoutRect qgn_graf_sk_left;
+ qgn_graf_sk_left.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::control_pane_g1( graphVariety ).LayoutLine() );
+ leftSoftkey->ComponentControl( 0 )->SetRect( qgn_graf_sk_left.Rect() );
+ leftSoftkey->SetRect( qgn_graf_sk_left.Rect() );
+ }
+
+ if ( !rightSKButton->IsImageOn() )
+ {
+ controlPaneTextLayout =
+ AknLayoutScalable_Avkon::control_pane_t2( textVariety ).LayoutLine();
+
+ if ( iCbaFlags & EEikCbaFlagOutlineFont )
+ {
+ // Sets outline font property.
+ controlPaneTextLayout.iFont |= KOutlineFontMask;
+ }
+
+ CEikLabel* cbaLabel =
+ static_cast<CEikLabel*>( rightSoftkey->ComponentControl( 0 ) );
+ AknLayoutUtils::LayoutLabel( cbaLabel,
+ Rect(),
+ controlPaneTextLayout );
+ LayoutControl( rightSKButton, cbaLabel->Rect() );
+ rightSKButton->TruncateLabelText();
+ }
+ else
+ {
+ TAknLayoutRect qgn_graf_sk_right;
+ qgn_graf_sk_right.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::control_pane_g2( graphVariety ).LayoutLine() );
+ rightSoftkey->ComponentControl( 0 )->SetRect( qgn_graf_sk_right.Rect() );
+ rightSoftkey->SetRect( qgn_graf_sk_right.Rect() );
+ }
+
+ // Scrollbar will go over MSK!!! needs to be fixed.
+ if ( VScrollBarAsControl()->Model()->ScrollBarUseful() )
+ {
+ CCoeControl* scroller = (*iControlArray)[KControlArrayScrollBarPosn].iControl;
+ AknLayoutUtils::LayoutControl(
+ scroller,
+ rect,
+ AKN_LAYOUT_WINDOW_Control_pane_elements_Line_1 );
+ }
+
+ TInt textMSKVariety = 3;
+ TInt graphicMSKVariety = 0;
+
+ if ( mskEnabledInApplication && mskEnabledInPlatform )
+ {
+ MSKSoftkey = (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl;
+ MSKButton = static_cast<CEikCbaButton*>( MSKSoftkey );
+
+ if ( !MSKButton->IsImageOn() )
+ {
+ controlPaneTextLayout =
+ AknLayoutScalable_Avkon::control_pane_t3(
+ textMSKVariety ).LayoutLine();
+
+ if ( iCbaFlags & EEikCbaFlagOutlineFont )
+ {
+ // Sets outline font property.
+ controlPaneTextLayout.iFont |= KOutlineFontMask;
+ }
+
+ CEikLabel* cbaLabel =
+ static_cast<CEikLabel*>( MSKSoftkey->ComponentControl( 0 ) );
+ AknLayoutUtils::LayoutLabel( cbaLabel,
+ Rect(),
+ controlPaneTextLayout );
+ LayoutControl( MSKButton, cbaLabel->Rect() );
+ MSKButton->TruncateLabelText();
+ }
+ else
+ {
+ TAknLayoutRect qgn_graf_sk_msk;
+ qgn_graf_sk_msk.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::control_pane_g4(
+ graphicMSKVariety ).LayoutLine() );
+ TRect rect( qgn_graf_sk_msk.Rect() );
+
+ // aid_value_unit2 is 10ux10u rectangle
+ TAknWindowComponentLayout unit( AknLayoutScalable_Avkon::aid_value_unit2() );
+ TInt delta = unit.LayoutLine().iW / 10 / 2; // half units
+ if ( MSKButton->PressedDown() )
+ {
+ rect.Move( delta, delta );
+ }
+ MSKSoftkey->ComponentControl( 0 )->SetRect( rect );
+ MSKSoftkey->SetRect( rect );
+ }
+ }
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ const TBool transparentSoftkeys =
+ iExtension->iEnablePostingTransparency ||
+ ( iCbaFlags & EEikCbaFlagTransparent ) ||
+ ( iCbaFlags & EEikCbaFlagSemiTransparent );
+ TRgb leftColor;
+ TRgb rightColor;
+ TRgb MSKColor;
+ TInt errorl;
+ TInt errorr;
+ TInt errorMSK;
+
+ TBool idleState = AknStatuspaneUtils::IdleLayoutActive();
+ if ( idleState )
+ {
+ errorl = AknsUtils::GetCachedColor(
+ skin,
+ leftColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG15 );
+
+ errorr = AknsUtils::GetCachedColor(
+ skin,
+ rightColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG16 );
+
+ errorMSK = AknsUtils::GetCachedColor(
+ skin,
+ MSKColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG57 );
+ }
+ else if ( iPopupVisible )
+ {
+ errorl = AknsUtils::GetCachedColor(
+ skin,
+ leftColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG17 );
+
+ errorr = AknsUtils::GetCachedColor(
+ skin,
+ rightColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG18 );
+
+ errorMSK = AknsUtils::GetCachedColor(
+ skin,
+ MSKColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG58 );
+ }
+ else
+ {
+ errorl = AknsUtils::GetCachedColor(
+ skin,
+ leftColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG13 );
+
+ errorr = AknsUtils::GetCachedColor(
+ skin,
+ rightColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG14 );
+
+ errorMSK = AknsUtils::GetCachedColor(
+ skin,
+ MSKColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG56 );
+ }
+
+ if ( transparentSoftkeys )
+ {
+ rightColor = KRgbWhite;
+ leftColor = KRgbWhite;
+ }
+ if ( leftSKButton->PressedDown() )
+ {
+ leftColor.SetAlpha( KPressedDownAlphaValue );
+
+ AknsUtils::GetCachedColor(
+ skin,
+ leftColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG69 );
+
+ if ( transparentSoftkeys )
+ {
+ // alpha has no effect with display posting.
+ leftColor = TRgb( 128, 128, 128 );
+ }
+ }
+ else if ( rightSKButton->PressedDown() )
+ {
+ rightColor.SetAlpha( KPressedDownAlphaValue );
+
+ AknsUtils::GetCachedColor(
+ skin,
+ rightColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG69 );
+
+ if ( transparentSoftkeys )
+ {
+ // alpha has no effect with display posting.
+ rightColor = TRgb( 128, 128, 128 );
+ }
+ }
+ else if ( MSKButton && MSKButton->PressedDown() )
+ {
+ MSKColor.SetAlpha( KPressedDownAlphaValue );
+
+ AknsUtils::GetCachedColor(
+ skin,
+ MSKColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG69 );
+
+ }
+
+ if( !errorl && !errorr )
+ {
+ // Error ignored
+ TRAP( errorl, AknLayoutUtils::OverrideControlColorL(
+ *leftSoftkey,
+ EColorLabelText,
+ leftColor) );
+
+ TRAP( errorr, AknLayoutUtils::OverrideControlColorL(
+ *rightSoftkey,
+ EColorLabelText,
+ rightColor) );
+
+ if ( transparentSoftkeys )
+ {
+ // Outline color is black.
+ TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL(
+ *leftSoftkey,
+ EColorControlBackground,
+ KRgbBlack ) );
+ TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL(
+ *rightSoftkey,
+ EColorControlBackground,
+ KRgbBlack ) );
+ }
+ }
+
+ if ( mskEnabledInApplication && mskEnabledInPlatform && !errorMSK )
+ {
+ // Error ignored.
+ TRAP( errorMSK, AknLayoutUtils::OverrideControlColorL(
+ *MSKSoftkey,
+ EColorLabelText,
+ MSKColor) );
+ }
+
+ // If MSK colors not set in skin, use left CBA color.
+ if ( mskEnabledInApplication && mskEnabledInPlatform && errorMSK && !errorl )
+ {
+ // Error ignored.
+ TRAP( errorMSK,
+ {
+ AknLayoutUtils::OverrideControlColorL(
+ *MSKSoftkey,
+ EColorLabelText,
+ leftColor);
+ } );
+ }
+
+ DrawDeferred();
+ }
+
+ AknsUtils::RegisterControlPosition( this, posInScreen.iTl );
+ }
+
+
+void CEikCba::SizeChangedInStaconPane()
+ {
+ TRect screen( iAvkonAppUi->ApplicationRect() );
+ TBool softKeysUpAndDownMirrored = EFalse;
+
+ TInt variety = 0;
+ if (AknLayoutFlags() & EAknLayoutCbaInStaconPaneLeft)
+ {
+ variety = 1;
+ }
+
+ TAknWindowComponentLayout layout0;
+ TAknWindowComponentLayout layout1;
+ TAknWindowComponentLayout layout2;
+ TAknWindowComponentLayout imageLayout;
+ TAknTextComponentLayout textLayout;
+
+ // Read right (top in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_top_pane(2);
+ layout1 = AknLayoutScalable_Avkon::stacon_top_pane();
+
+ // If clock is shown in stacon, cba area is smaller.
+ TInt topCbaVariety = variety;
+ if (AknStatuspaneUtils::ExtendedStaconPaneActive())
+ {
+ topCbaVariety += 4;
+ }
+
+ TInt textVariety = variety;
+ if ( iExtension->iEnablePostingTransparency || ( iCbaFlags & EEikCbaFlagTransparent ) )
+ {
+ textVariety += 2; // Outline font used
+ }
+
+ layout2 = AknLayoutScalable_Avkon::control_top_pane_stacon(topCbaVariety);
+ imageLayout = AknLayoutScalable_Avkon::control_top_pane_stacon_g1();
+ textLayout = AknLayoutScalable_Avkon::control_top_pane_stacon_t1(textVariety);
+
+ TAknTextComponentLayout rightSoftKeyTextLayout(
+ DoComposeText(layout0, DoComposeText(layout1, DoComposeText(layout2, textLayout))) );
+ TAknWindowComponentLayout rightSoftKeyImageLayout(
+ DoCompose(layout0, DoCompose(layout1, DoCompose(layout2, imageLayout))) );
+
+ // Calculate softkey rects.
+ TAknWindowLineLayout rightSoftkeyLayout(
+ DoCompose( layout0, DoCompose(layout1, layout2)).LayoutLine() );
+ TAknLayoutRect rightSoftkeyLayoutRect;
+ rightSoftkeyLayoutRect.LayoutRect(screen, rightSoftkeyLayout);
+ TRect rightSoftKeyButtonRect( rightSoftkeyLayoutRect.Rect() );
+
+ TAknTextLineLayout rightSoftkeyTextLayout( rightSoftKeyTextLayout.LayoutLine() );
+ TAknWindowLineLayout rightSoftkeyImageLayout( rightSoftKeyImageLayout.LayoutLine() );
+
+ // Read left (bottom in landscape) softkey layout.
+ layout0 = AknLayoutScalable_Avkon::area_bottom_pane(2);
+ layout1 = AknLayoutScalable_Avkon::stacon_bottom_pane();
+
+ // If clock is shown in stacon, cba area is smaller.
+ TInt bottomCbaVariety = variety;
+ if (AknStatuspaneUtils::ExtendedStaconPaneActive())
+ {
+ bottomCbaVariety += 2;
+ }
+
+ layout2 = AknLayoutScalable_Avkon::control_bottom_pane_stacon(bottomCbaVariety);
+ imageLayout = AknLayoutScalable_Avkon::control_bottom_pane_stacon_g1();
+ textLayout = AknLayoutScalable_Avkon::control_bottom_pane_stacon_t1(textVariety);
+
+ TAknTextComponentLayout leftSoftKeyTextLayout(
+ DoComposeText(layout0, DoComposeText(layout1, DoComposeText(layout2, textLayout))) );
+ TAknWindowComponentLayout leftSoftKeyImageLayout(
+ DoCompose(layout0, DoCompose(layout1, DoCompose(layout2, imageLayout))) );
+
+ // Calculate softkey rects
+ TAknWindowLineLayout leftSoftkeyLayout(
+ DoCompose( layout0, DoCompose(layout1, layout2) ).LayoutLine() );
+ TAknLayoutRect leftSoftkeyLayoutRect;
+ leftSoftkeyLayoutRect.LayoutRect(screen, leftSoftkeyLayout);
+ TRect leftSoftKeyButtonRect( leftSoftkeyLayoutRect.Rect() );
+
+ TAknTextLineLayout leftSoftkeyTextLayout( leftSoftKeyTextLayout.LayoutLine() );
+ TAknWindowLineLayout leftSoftkeyImageLayout( leftSoftKeyImageLayout.LayoutLine() );
+
+ // If softkeys are on the "other" side, then swap the texts and images here...
+ if (variety == 1)
+ {
+ CWsScreenDevice* dev = iEikonEnv->ScreenDevice();
+ TPixelsAndRotation sizeAndRotation;
+ dev->GetScreenModeSizeAndRotation(dev->CurrentScreenMode(), sizeAndRotation);
+
+ TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
+
+ // If landscape orientation uses 270 degree rotation ( or 0 degree
+ // rotation in case of default portrait rotation uses 90 degree value),
+ // only then mirror L & R (actually upper and lower in stacon).
+ if ( isLandscape &&
+ ( sizeAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationRotated270 ||
+ sizeAndRotation.iRotation == CFbsBitGc::EGraphicsOrientationNormal ) )
+ {
+ softKeysUpAndDownMirrored = ETrue;
+ TAknTextLineLayout tmpTextLineLayout( leftSoftkeyTextLayout );
+ TAknWindowLineLayout tmpWindowLineLayout( leftSoftkeyImageLayout );
+ TRect tmpRect( leftSoftKeyButtonRect );
+
+ leftSoftKeyButtonRect = rightSoftKeyButtonRect;
+ leftSoftkeyTextLayout = rightSoftkeyTextLayout;
+ leftSoftkeyImageLayout = rightSoftkeyImageLayout;
+
+ rightSoftKeyButtonRect = tmpRect;
+ rightSoftkeyTextLayout = tmpTextLineLayout;
+ rightSoftkeyImageLayout = tmpWindowLineLayout;
+ }
+ }
+
+ // Set skin background.
+ TRect screenRect( iAvkonAppUi->ApplicationRect() );
+ TAknWindowLineLayout layout( AknLayoutScalable_Avkon::area_top_pane(2).LayoutLine() );
+ TAknLayoutRect layoutRect;
+ layoutRect.LayoutRect( screenRect, layout );
+ TRect staconTop( layoutRect.Rect() );
+
+ layout = AknLayoutScalable_Avkon::area_bottom_pane(2).LayoutLine();
+ layoutRect.LayoutRect( screenRect, layout );
+ TRect staconBottom( layoutRect.Rect() );
+
+ TBool skLeft = AknLayoutFlags() & EAknLayoutCbaInStaconPaneLeft;
+ TBool idle = AknLayoutFlags() & EAknLayoutCbaInStaconPaneIdle;
+
+ TAknsItemID topMaskIID = KAknsIIDNone;
+ TAknsItemID bottomMaskIID = KAknsIIDNone;
+
+ if ( idle )
+ {
+ if ( skLeft )
+ {
+ iStaconBgContextTop->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconLtIdle );
+ iStaconBgContextBottom->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconLbIdle );
+ }
+ else
+ {
+ iStaconBgContextTop->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconRtIdle );
+ iStaconBgContextBottom->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconRbIdle );
+ }
+ iStaconBgContextTop->SetLayerImage( ECbaLayerWallpaper, KAknsIIDWallpaper );
+ iStaconBgContextTop->SetLayerRect( ECbaLayerWallpaper, screen );
+ iStaconBgContextTop->SetLayerRect( ECbaLayerBackground, staconTop );
+
+ topMaskIID = KAknsIIDQgnGrafBgLscTopMaskIcon;
+
+ iStaconBgContextBottom->SetLayerImage( ECbaLayerWallpaper, KAknsIIDWallpaper );
+ iStaconBgContextBottom->SetLayerRect( ECbaLayerWallpaper, screen );
+ iStaconBgContextBottom->SetLayerRect( ECbaLayerBackground, staconBottom );
+
+ bottomMaskIID = KAknsIIDQgnGrafBgLscBottomMaskIcon;
+ }
+ else
+ {
+ // If not in idle, then there is no wallpaper, thus clear wallpaper layer.
+ if ( skLeft )
+ {
+ iStaconBgContextTop->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconLt );
+ iStaconBgContextBottom->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconLb );
+ }
+ else
+ {
+ iStaconBgContextTop->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconRt );
+ iStaconBgContextBottom->SetLayerImage( ECbaLayerBackground, KAknsIIDQsnBgAreaStaconRb );
+ }
+ iStaconBgContextTop->SetLayerRect( ECbaLayerBackground, staconTop );
+ iStaconBgContextTop->SetLayerImage( ECbaLayerWallpaper, KAknsIIDNone );
+ topMaskIID = KAknsIIDNone;
+
+ iStaconBgContextBottom->SetLayerRect( ECbaLayerBackground, staconBottom );
+ iStaconBgContextBottom->SetLayerImage( ECbaLayerWallpaper, KAknsIIDNone );
+ bottomMaskIID = KAknsIIDNone;
+ }
+
+ // If setting layer mask fails, ignore the error.
+ // This causes UI elements to be opaque and thus parts of the wallpaper is hidden.
+ TRAP_IGNORE(
+ iStaconBgContextBottom->SetLayerMaskAndSizeL( bottomMaskIID, staconBottom );
+ iStaconBgContextTop->SetLayerMaskAndSizeL( topMaskIID, staconTop );
+ );
+
+ TRect cba( Rect() );
+ // This uses correct coordinates to calculate the positions of softkey labels.
+ // Unfortunately we do not have access to the labels inside CEikCbaButtons,
+ // that's the reason for a hack with ComponentControl().
+ // (This is the only place that knows of both left and right softkey ...)
+ if (iControlArray->Count() != 0)
+ {
+ CCoeControl *leftSoftkey = (*iControlArray)[KControlArrayCBAButton1Posn].iControl;
+ CCoeControl *rightSoftkey = (*iControlArray)[KControlArrayCBAButton2Posn].iControl;
+
+ // Left SK.
+ if (!(((CEikCbaButton*)leftSoftkey)->IsImageOn()))
+ {
+ AknLayoutUtils::LayoutLabel((CEikLabel*)leftSoftkey->ComponentControl( 0 ),
+ Rect(),
+ leftSoftkeyTextLayout );
+ LayoutControl( (CEikCbaButton*)leftSoftkey,
+ leftSoftkey->ComponentControl( 0 )->Rect() );
+ ((CEikCbaButton*)leftSoftkey)->TruncateLabelText();
+ }
+ else
+ {
+ TAknLayoutRect qgn_graf_sk_left;
+ qgn_graf_sk_left.LayoutRect(cba, leftSoftkeyImageLayout);
+ leftSoftkey->ComponentControl(0)->SetRect(qgn_graf_sk_left.Rect());
+ leftSoftkey->SetRect(leftSoftKeyButtonRect);
+
+ // To make sure mop chain is updated, do it here. If not done, only skin background
+ // suffers.
+ TRAP_IGNORE(((CEikCbaButton*)leftSoftkey)->SetContainerWindowL(*this));
+ }
+
+ // Right SK.
+ if (!(((CEikCbaButton*)rightSoftkey)->IsImageOn()))
+ {
+ AknLayoutUtils::LayoutLabel((CEikLabel*)rightSoftkey->ComponentControl( 0 ),
+ Rect(),
+ rightSoftkeyTextLayout );
+ LayoutControl( (CEikCbaButton*)rightSoftkey,
+ rightSoftkey->ComponentControl( 0 )->Rect() );
+ ((CEikCbaButton*)rightSoftkey)->TruncateLabelText();
+ }
+ else
+ {
+ TAknLayoutRect qgn_graf_sk_right;
+ qgn_graf_sk_right.LayoutRect(cba, rightSoftkeyImageLayout);
+ rightSoftkey->ComponentControl(0)->SetRect(qgn_graf_sk_right.Rect());
+ rightSoftkey->SetRect(rightSoftKeyButtonRect);
+
+ // To make sure mop chain is updated, do it here. If not done, only skin background
+ // suffers.
+ TRAP_IGNORE(((CEikCbaButton*)rightSoftkey)->SetContainerWindowL(*this));
+ }
+
+ // Landscape mode scrollbar layout is not set here, let application do if needed.
+ CCoeControl* scroller = (*iControlArray)[KControlArrayScrollBarPosn].iControl;
+ if (scroller)
+ {
+ scroller->SetSize(TSize(0,0));
+ }
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ const TBool transparentSoftkeys =
+ iExtension->iEnablePostingTransparency ||
+ ( iCbaFlags & EEikCbaFlagTransparent );
+ TRgb rightSkColor;
+ TRgb leftSkColor;
+
+ TInt error1 = 0;
+ TInt error2 = 0;
+
+ if (idle)
+ {
+ error1 = AknsUtils::GetCachedColor( skin, rightSkColor, KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG41 ); // text #41 stacon area top softkey text in idle #0
+
+ error2 = AknsUtils::GetCachedColor( skin, leftSkColor, KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG42 ); // text #42 stacon area bottom softkey text in idle #0
+ }
+ else
+ {
+ error1 = AknsUtils::GetCachedColor( skin, rightSkColor, KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG39 ); // text #39 stacon area top softkey text #0
+
+ error2 = AknsUtils::GetCachedColor( skin, leftSkColor, KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG40 ); // text #40 stacon area bottom softkey text #0
+ }
+
+ if ( transparentSoftkeys )
+ {
+ rightSkColor = KRgbWhite;
+ leftSkColor = KRgbWhite;
+ }
+ if (softKeysUpAndDownMirrored)
+ {
+ TRgb tmp = rightSkColor;
+ rightSkColor = leftSkColor;
+ leftSkColor = tmp;
+ }
+
+ if ( ((CEikCbaButton*)leftSoftkey)->PressedDown() )
+ {
+ leftSkColor.SetAlpha( KPressedDownAlphaValue );
+
+ AknsUtils::GetCachedColor(
+ skin,
+ leftSkColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG69 );
+
+ if ( transparentSoftkeys )
+ {
+ // alpha has no effect with display posting.
+ leftSkColor = TRgb( 128, 128, 128 );
+ }
+ }
+ else if ( ((CEikCbaButton*)rightSoftkey)->PressedDown() )
+ {
+ rightSkColor.SetAlpha( KPressedDownAlphaValue );
+
+ AknsUtils::GetCachedColor(
+ skin,
+ rightSkColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG69 );
+
+ if ( transparentSoftkeys )
+ {
+ // alpha has no effect with display posting.
+ rightSkColor = TRgb( 128, 128, 128 );
+ }
+ }
+
+ if( !error1 && !error2 )
+ {
+ // Error ignored.
+ TRAP( error1, AknLayoutUtils::OverrideControlColorL(*leftSoftkey,
+ EColorLabelText,
+ leftSkColor) );
+ TRAP( error2, AknLayoutUtils::OverrideControlColorL(*rightSoftkey,
+ EColorLabelText,
+ rightSkColor) );
+ if ( transparentSoftkeys )
+ {
+ // outline color is black.
+ TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL(
+ *leftSoftkey,
+ EColorControlBackground,
+ KRgbBlack ) );
+ TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL(
+ *rightSoftkey,
+ EColorControlBackground,
+ KRgbBlack ) );
+ }
+ }
+
+ if (iStaconLabelFont)
+ {
+ ((CEikCbaButton*)leftSoftkey)->SetLabelFont(iStaconLabelFont);
+ ((CEikCbaButton*)rightSoftkey)->SetLabelFont(iStaconLabelFont);
+ }
+
+ DrawDeferred();
+ }
+
+ AknsUtils::RegisterControlPosition( this, TPoint(0,0) );
+ }
+
+
+//------------------------------------------------------------------------------
+// CEikCba::SizeChangedInRightPane()
+//------------------------------------------------------------------------------
+//
+void CEikCba::SizeChangedInRightPane()
+ {
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TAknWindowComponentLayout rightAreaLayout(
+ AknLayoutScalable_Avkon::area_side_right_pane( 0 ) );
+
+ TAknWindowComponentLayout topSKLayout(
+ DoCompose( rightAreaLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_top_pane() ) );
+
+ TAknWindowComponentLayout bottomSKLayout(
+ DoCompose( rightAreaLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane() ) );
+
+ // Calculate softkey rects.
+
+ // Right (top in landscape) softkey layout.
+ TAknLayoutRect rightSoftkeyLayoutRect;
+ rightSoftkeyLayoutRect.LayoutRect( screen,
+ topSKLayout.LayoutLine() );
+ TRect rightSoftKeyButtonRect( rightSoftkeyLayoutRect.Rect() );
+
+ // Left (bottom in landscape) softkey layout.
+ TAknLayoutRect leftSoftkeyLayoutRect;
+ leftSoftkeyLayoutRect.LayoutRect( screen,
+ bottomSKLayout.LayoutLine() );
+ TRect leftSoftKeyButtonRect( leftSoftkeyLayoutRect.Rect() );
+
+ // Set the softkey frame rectangles in touch layouts.
+ if ( iExtension && AknLayoutUtils::PenEnabled() )
+ {
+ TBool frameSizeChanged(
+ iExtension->iLeftFrameOuterRect != leftSoftKeyButtonRect ||
+ iExtension->iRightFrameOuterRect != rightSoftKeyButtonRect );
+ iExtension->iLeftFrameOuterRect = leftSoftKeyButtonRect;
+ iExtension->iRightFrameOuterRect = rightSoftKeyButtonRect;
+ if ( frameSizeChanged )
+ {
+ TRAP_IGNORE( iExtension->UpdateSoftkeyFrameL( EFalse ) );
+ }
+ }
+
+ // Calculate softkey image and text layouts.
+ TInt softkeyTextVariety = 0;
+
+ if ( iExtension->iEnablePostingTransparency || ( iCbaFlags & EEikCbaFlagTransparent ) )
+ {
+ softkeyTextVariety = 1; // Outline font used
+ }
+
+ // Right (top in landscape) softkey layout.
+ TAknTextLineLayout rightSoftkeyTextLayout(
+ DoComposeText(
+ topSKLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_top_pane_t1(softkeyTextVariety) ).LayoutLine() );
+
+ TAknWindowLineLayout rightSoftkeyImageLayout(
+ DoCompose(
+ topSKLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_top_pane_g1() ).LayoutLine() );
+
+ // Left (bottom in landscape) softkey layout.
+ TAknTextLineLayout leftSoftkeyTextLayout(
+ DoComposeText(
+ bottomSKLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane_t1(softkeyTextVariety) ).LayoutLine() );
+
+ TAknWindowLineLayout leftSoftkeyImageLayout(
+ DoCompose(
+ bottomSKLayout,
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane_g1() ).LayoutLine() );
+
+ // Set skin background.
+
+ DoSetLayers( KAknsIIDNone );
+
+ TRect cba( Rect() );
+
+ // This uses correct coordinates to calculate the positions
+ // of softkey labels. Unfortunately we do not have access to
+ // the labels inside CEikCbaButtons, that's the reason for a
+ // hack with ComponentControl().
+ // (This is the only place that knows of both left and right softkey ...)
+ if ( iControlArray->Count() != 0 )
+ {
+ CCoeControl* leftSoftkeyControl =
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl;
+ CCoeControl* rightSoftkeyControl =
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl;
+
+ CEikCbaButton* leftSoftkey =
+ static_cast<CEikCbaButton*>( leftSoftkeyControl );
+ CEikCbaButton* rightSoftkey =
+ static_cast<CEikCbaButton*>( rightSoftkeyControl );
+
+ // Left SK.
+ if ( !leftSoftkey->IsImageOn() )
+ {
+ AknLayoutUtils::LayoutLabel(
+ static_cast<CEikLabel*>( leftSoftkeyControl->ComponentControl( 0 ) ),
+ cba,
+ leftSoftkeyTextLayout );
+ LayoutControl(
+ leftSoftkey,
+ leftSoftkeyControl->ComponentControl( 0 )->Rect() );
+ leftSoftkey->TruncateLabelText();
+ }
+ else
+ {
+ TAknLayoutRect qgn_graf_sk_left;
+ qgn_graf_sk_left.LayoutRect( cba, leftSoftkeyImageLayout );
+ leftSoftkeyControl->ComponentControl( 0 )->SetRect( qgn_graf_sk_left.Rect() );
+ leftSoftkeyControl->SetRect( leftSoftKeyButtonRect );
+
+ // To make sure mop chain is updated, do it here.
+ // If not done, only skin background suffers.
+ TRAP_IGNORE( leftSoftkey->SetContainerWindowL( *this ) );
+ }
+
+ // Right SK.
+ if ( !rightSoftkey->IsImageOn() )
+ {
+ AknLayoutUtils::LayoutLabel(
+ static_cast<CEikLabel*>( rightSoftkeyControl->ComponentControl( 0 ) ),
+ cba,
+ rightSoftkeyTextLayout );
+ LayoutControl(
+ rightSoftkey,
+ rightSoftkeyControl->ComponentControl( 0 )->Rect() );
+ rightSoftkey->TruncateLabelText();
+ }
+ else
+ {
+ TAknLayoutRect qgn_graf_sk_right;
+ qgn_graf_sk_right.LayoutRect( cba, rightSoftkeyImageLayout );
+ rightSoftkeyControl->ComponentControl( 0 )->SetRect( qgn_graf_sk_right.Rect() );
+ rightSoftkeyControl->SetRect( rightSoftKeyButtonRect );
+
+ // To make sure mop chain is updated, do it here.
+ // If not done, only skin background suffers.
+ TRAP_IGNORE( rightSoftkey->SetContainerWindowL( *this ) );
+ }
+
+ // Landscape mode scrollbar layout is not set here, let application do if needed.
+ CCoeControl* scroller = (*iControlArray)[KControlArrayScrollBarPosn].iControl;
+ if ( scroller )
+ {
+ scroller->SetSize( TSize( 0, 0 ) );
+ }
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ const TBool transparentSoftkeys =
+ iExtension->iEnablePostingTransparency ||
+ ( iCbaFlags & EEikCbaFlagTransparent );
+
+ TRgb rightSkColor;
+ TRgb leftSkColor;
+
+ TInt error1 = 0;
+ TInt error2 = 0;
+ if ( transparentSoftkeys )
+ {
+ rightSkColor = KRgbWhite;
+ leftSkColor = KRgbWhite;
+ }
+ else if ( AknStatuspaneUtils::IdleLayoutActive() )
+ {
+ // Text #41 stacon area top softkey text in idle #0
+ error1 = AknsUtils::GetCachedColor( skin,
+ rightSkColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG41 );
+
+ // Text #42 stacon area bottom softkey text in idle #0
+ error2 = AknsUtils::GetCachedColor( skin,
+ leftSkColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG42 );
+ }
+ else
+ {
+ // Text #39 stacon area top softkey text #0
+ error1 = AknsUtils::GetCachedColor( skin,
+ rightSkColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG39 );
+
+ // Text #40 stacon area bottom softkey text #0
+ error2 = AknsUtils::GetCachedColor( skin,
+ leftSkColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG40 );
+ }
+
+ if ( leftSoftkey->PressedDown() )
+ {
+ leftSkColor.SetAlpha( KPressedDownAlphaValue );
+
+ AknsUtils::GetCachedColor(
+ skin,
+ leftSkColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG69 );
+
+
+ if ( transparentSoftkeys )
+ {
+ // alpha has no effect with display posting.
+ leftSkColor = TRgb( 128, 128, 128 );
+ }
+ }
+ else if ( rightSoftkey->PressedDown() )
+ {
+ rightSkColor.SetAlpha( KPressedDownAlphaValue );
+
+ AknsUtils::GetCachedColor(
+ skin,
+ rightSkColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG69 );
+
+ if ( transparentSoftkeys )
+ {
+ // alpha has no effect with display posting.
+ rightSkColor = TRgb( 128, 128, 128 );
+ }
+ }
+
+ if( !error1 && !error2 )
+ {
+ // Error ignored.
+ TRAP( error1,
+ AknLayoutUtils::OverrideControlColorL( *leftSoftkeyControl,
+ EColorLabelText,
+ leftSkColor ) );
+ TRAP( error2,
+ AknLayoutUtils::OverrideControlColorL( *rightSoftkeyControl,
+ EColorLabelText,
+ rightSkColor ) );
+
+ if ( transparentSoftkeys )
+ {
+ // outline color is black.
+ TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL(
+ *leftSoftkeyControl,
+ EColorControlBackground,
+ KRgbBlack ) );
+ TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL(
+ *rightSoftkeyControl,
+ EColorControlBackground,
+ KRgbBlack ) );
+ }
+ }
+
+ if ( iRightPaneLabelFont )
+ {
+ leftSoftkey->SetLabelFont( iRightPaneLabelFont );
+ rightSoftkey->SetLabelFont( iRightPaneLabelFont );
+ }
+
+ DrawDeferred();
+ }
+
+ AknsUtils::RegisterControlPosition( this, TPoint( 0, 0 ) );
+ }
+
+
+
+void CEikCba::SizeChangedInsideDialog()
+ {
+ // Give both LSK and RSK buttons half of the available space.
+ //
+ if ( iControlArray )
+ {
+ TRect buttonRect1( Rect() );
+ TRect buttonRect2( Rect() );
+
+ TInt width = ( buttonRect1.iBr.iX - buttonRect1.iTl.iX ) / 2 - 4;
+
+ buttonRect1.iBr.iX = buttonRect1.iTl.iX + width;
+ buttonRect2.iTl.iX = buttonRect2.iBr.iX - width;
+
+ if ( (*iControlArray)[KControlArrayCBAButton1Posn].iControl )
+ {
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl->SetRect( buttonRect1 );
+ }
+
+ if ( (*iControlArray)[KControlArrayCBAButton2Posn].iControl )
+ {
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl->SetRect( buttonRect2 );
+ }
+ }
+ }
+
+
+void CEikCba::SizeChangedInPopup()
+ {
+ TRAP_IGNORE( iExtension->UpdateSoftkeyFrameL( EFalse ) );
+
+ TAknLayoutRect layoutRect;
+ TRect rect ( Rect() );
+
+ // Button widths are calculated based on cba area width
+ // margin width is taken from layout
+ layoutRect.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::popup_sk_window_g1( 0 ) );
+
+ TInt margin = layoutRect.Rect().iTl.iX - rect.iTl.iX;
+ TInt buttonWidth = ( rect.Width() - margin * 2 ) / 2;
+ TSize buttonSize ( buttonWidth, layoutRect.Rect().Height() );
+
+ iExtension->iLeftFrameOuterRect = TRect(
+ TPoint( rect.iTl.iX + margin, layoutRect.Rect().iTl.iY ),
+ buttonSize );
+ iExtension->iRightFrameOuterRect = TRect(
+ TPoint( iExtension->iLeftFrameOuterRect.iBr.iX,
+ layoutRect.Rect().iTl.iY ),
+ TPoint( rect.iBr.iX - margin, layoutRect.Rect().iBr.iY ) );
+
+ layoutRect.LayoutRect( iExtension->iLeftFrameOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ iExtension->iLeftFrameInnerRect = layoutRect.Rect();
+ UpdateLabels( ETrue );
+
+ layoutRect.LayoutRect( iExtension->iRightFrameOuterRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ iExtension->iRightFrameInnerRect = layoutRect.Rect();
+ UpdateLabels( ETrue );
+
+ if ( iControlArray->Count() > KControlArrayCBAButtonMSKPosn )
+ {
+ CCoeControl* msk =
+ (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl;
+
+ if ( msk )
+ {
+ msk->SetRect( TRect() );
+ }
+ }
+ }
+
+
+void CEikCba::UpdateFonts()
+ {
+ // Control pane:
+ // Use the layout dll to get the right font for the CBA.
+ TAknTextLineLayout layout(
+ AknLayoutScalable_Avkon::control_pane_t1(
+ Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 0 ).LayoutLine() );
+ if ( iCbaFlags & EEikCbaFlagOutlineFont )
+ {
+ // Sets outline font property.
+ layout.iFont |= KOutlineFontMask;
+ }
+ const CFont* customfont = 0;
+ iLabelFont = AknLayoutUtils::FontFromId( layout.FontId(), customfont );
+
+ // Stacon pane:
+ TAknTextLineLayout staconTextLayout(
+ AknLayoutScalable_Avkon::control_bottom_pane_stacon_t1( 0 ).LayoutLine() );
+
+ if ( iCbaFlags & EEikCbaFlagOutlineFont )
+ {
+ // Sets outline font property.
+ staconTextLayout.iFont |= KOutlineFontMask;
+ }
+ const CFont* staconCustomfont = 0;
+ iStaconLabelFont = AknLayoutUtils::FontFromId( staconTextLayout.FontId(),
+ staconCustomfont );
+
+ // Right pane:
+ TInt rightPaneTextVariety = 0;
+
+ if ( iExtension->iEnablePostingTransparency ||
+ ( iCbaFlags & EEikCbaFlagTransparent ) || ( iCbaFlags & EEikCbaFlagSemiTransparent ) )
+ {
+ rightPaneTextVariety = 1; // Outline font used
+ }
+
+ TAknTextLineLayout rightPaneTextLayout(
+ AknLayoutScalable_Avkon::sctrl_sk_bottom_pane_t1(
+ rightPaneTextVariety ).LayoutLine() );
+
+ if ( iCbaFlags & EEikCbaFlagOutlineFont )
+ {
+ // Sets outline font property.
+ rightPaneTextLayout.iFont |= KOutlineFontMask;
+ }
+ const CFont* rightPaneCustomFont = 0;
+ iRightPaneLabelFont =
+ AknLayoutUtils::FontFromId(
+ rightPaneTextLayout.FontId(), rightPaneCustomFont );
+ }
+
+// Enhanced CBA
+
+// -----------------------------------------------------------------------------
+// Used to offer list of commands for softkeys.
+// @param aCommandList A list of command ids to be offered for sofkeys.
+// @since 5.0
+// -----------------------------------------------------------------------------
+#ifdef RD_ENHANCED_CBA
+EXPORT_C void CEikCba::OfferCommandListL(const RArray<TInt>& aCommandList)
+ {
+ if( !iCommandTable )
+ {
+ iCommandTable = CEikCommandTable::NewL();
+ }
+ else
+ {
+ delete iCommandTable;
+ iCommandTable = NULL;
+ iCommandTable = CEikCommandTable::NewL();
+ }
+
+ TInt count = aCommandList.Count();
+
+ // Stack existing commands for possible leave while adding the new commands.
+ RArray<TInt> previousIds;
+ CleanupClosePushL( previousIds );
+
+ // Store the existing commands.
+ for ( TInt i = 0; i < iControlArray->Count(); i++ )
+ {
+ TEikGroupControl& groupCtrl=(*iControlArray)[i];
+ previousIds.AppendL( groupCtrl.iId );
+ }
+
+ iCommandTable->Reset();
+
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ TInt resourceId( aCommandList[ii] );
+
+ TResourceReader reader;
+ iCoeEnv->CreateResourceReaderLC( reader, resourceId );
+
+ TUint8 version( (TUint8)reader.ReadUint8() );
+ TInt longCommandId( 0 );
+
+ CEikEnhancedCbaButton* button = new (ELeave) CEikEnhancedCbaButton;
+ CleanupStack::PushL( button );
+
+ if( version == EEikCbaButtonLink )
+ {
+ TInt aButtonId = reader.ReadInt32(); // Read ENHANCED_CBA_BUTTON id from LLINK
+ TResourceReader linkReader; // reader for reading linked resource
+ iCoeEnv->CreateResourceReaderLC( linkReader, aButtonId );
+ TUint8 ver( linkReader.ReadUint8() );
+
+ if( ver == EEikEnhancedCbaButton )
+ {
+ button->ConstructFromResourceL( linkReader );
+ }
+ CleanupStack::PopAndDestroy( ); // linkReader
+ }
+ else if( version == EEikEnhancedCbaButton )
+ {
+ button->ConstructFromResourceL( reader );
+ }
+ else // command version not regognized
+ {
+ CleanupStack::PopAndDestroy(2); // button and reader
+ continue; // go for next command
+ }
+
+ iCommandTable->AddCommandL( button );
+
+ CleanupStack::Pop( button );
+ CleanupStack::PopAndDestroy(); // reader
+ }
+
+ for (TInt i = 0; i < KMaxButtonsInCommandTable + 1; i++) // +1 for scrollbar
+ {
+ if ( i != KControlArrayScrollBarPosn )
+ {
+ CEikEnhancedCbaButton* button;
+ if( i > KControlArrayScrollBarPosn )
+ {
+ button = iCommandTable->Command( i-1 );
+ }
+ else
+ {
+ button = iCommandTable->Command( i );
+ }
+
+ if ( !button )
+ {
+ button = new (ELeave) CEikEnhancedCbaButton;
+ button->SetTextBitmapMode( iExtension->iEnablePostingTransparency );
+ CleanupStack::PushL( button );
+ button->ConstructEmptyButtonL();
+ }
+ else
+ {
+ CleanupStack::PushL( button );
+ }
+
+ TRAPD( errorcode, AddCommandToStackL( i, button->CommandId(), button->LabelText(),
+ NULL, NULL ) );
+
+ if ( errorcode ) // In case of error restore previous commands before leave
+ {
+ for ( TInt counter = 0; counter < i; counter++ )
+ {
+ // Do not deal with the scroller as a CEikCbaButton; skip its index.
+ if (counter != KControlArrayScrollBarPosn)
+ {
+ // Following adjusts for the fact that the scroller command is
+ // missing from the previousIds array. Same index adjust as later on.
+ TInt indexInPreviousIds = counter;
+ if ( counter > 1 )
+ {
+ indexInPreviousIds = counter - 1;
+ }
+ RemoveCommandFromStack( counter,previousIds[indexInPreviousIds] );
+ }
+ }
+
+ User::Leave( errorcode );
+ }
+ CleanupStack::PopAndDestroy( button );
+ }
+ }
+
+ // Remove the original commands from the temporary store. +1 for scroll bar.
+ for ( TInt controlId = 0; controlId < KMaxButtonsInCommandTable + 1; controlId++ )
+ {
+ if ( controlId != KControlArrayScrollBarPosn )
+ {
+ TInt controlPosition = controlId;
+ if ( controlId > 1 )
+ {
+ controlPosition--;
+ }
+ RemovePreviousCommand( controlId );
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // previousIds
+ }
+#else // !RD_ENHANCED_CBA
+EXPORT_C void CEikCba::OfferCommandListL(const RArray<TInt>& /*aCommandList*/)
+ {
+ User::Leave( KErrNotSupported );
+ }
+#endif // RD_ENHANCED_CBA
+
+// -----------------------------------------------------------------------------
+// Used to offer list of commands for softkeys.
+// @param aResourceId Id for CBA resource that defines enhanced cba buttons.
+// @since 5.0
+// -----------------------------------------------------------------------------
+#ifdef RD_ENHANCED_CBA
+EXPORT_C void CEikCba::OfferCommandListL(const TInt aResourceId)
+ {
+ if ( !iCommandTable ) // This is needed if cba was not constructed with enhanced cba.
+ {
+ iCommandTable = CEikCommandTable::NewL();
+ }
+
+ TResourceReader reader;
+ iCoeEnv->CreateResourceReaderLC(reader, aResourceId);
+ iCbaFlags = reader.ReadInt32();
+
+ TBool enhancedCba( EFalse );
+ if ( ( iCbaFlags & EEikEnhancedButtonGroup ) == EEikEnhancedButtonGroup )
+ {
+ enhancedCba = ETrue;
+ }
+
+ __ASSERT_DEBUG( enhancedCba, Panic(EEikPanicCBAIsNotEnhancedCba) );
+
+ reader.ReadInt16(); // Skip width resource.
+ reader.ReadInt32(); // Skip related buttons resource.
+
+ TInt count = reader.ReadInt16();
+
+ // Stack existing commands for possible leave while adding the new commands.
+ RArray<TInt> previousIds;
+ CleanupClosePushL( previousIds );
+
+ // Store the existing commands.
+ for ( TInt i = 0; i < iControlArray->Count(); i++ )
+ {
+ TEikGroupControl& groupCtrl = (*iControlArray)[i];
+ previousIds.AppendL( groupCtrl.iId );
+ }
+
+ iCommandTable->Reset();
+
+ // Get new commands.
+ for ( TInt ii = 0; ii < count; ii++ )
+ {
+ TUint8 version( (TUint8)reader.ReadUint8() );
+ TInt commandId( 0 );
+ TInt longCommandId( 0 );
+
+ CEikEnhancedCbaButton* button = new (ELeave) CEikEnhancedCbaButton;
+ button->SetTextBitmapMode( iExtension->iEnablePostingTransparency );
+ CleanupStack::PushL( button );
+
+ if( version == EEikCbaButtonLink )
+ {
+ TInt aButtonId = reader.ReadInt32(); // Read ENHANCED_CBA_BUTTON id from LLINK
+ TResourceReader linkReader; // reader for reading linked resource
+ iCoeEnv->CreateResourceReaderLC( linkReader, aButtonId );
+ TUint8 ver( linkReader.ReadUint8() );
+
+ if( ver == EEikEnhancedCbaButton )
+ {
+ button->ConstructFromResourceL( linkReader );
+ }
+
+ CleanupStack::PopAndDestroy(); // linkReader
+ }
+ else if( version == EEikEnhancedCbaButton )
+ {
+ button->ConstructFromResourceL( reader );
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( button );
+ continue; // jump over the rest
+ }
+
+ iCommandTable->AddCommandL( button );
+
+ CleanupStack::Pop( button );
+ }
+
+ CleanupStack::PopAndDestroy(); // reader
+
+ for (TInt i = 0; i < KMaxButtonsInCommandTable + 1; i++) // +1 for scrollbar
+ {
+ if ( i != KControlArrayScrollBarPosn )
+ {
+ CEikEnhancedCbaButton* button;
+ if( i > KControlArrayScrollBarPosn )
+ {
+ button = iCommandTable->Command( i - 1 );
+ }
+ else
+ {
+ button = iCommandTable->Command( i );
+ }
+
+ if ( !button )
+ {
+ button = new (ELeave) CEikEnhancedCbaButton;
+ button->SetTextBitmapMode( iExtension->iEnablePostingTransparency );
+ CleanupStack::PushL( button );
+ button->ConstructEmptyButtonL();
+ }
+ else
+ {
+ CleanupStack::PushL( button );
+ }
+
+ TRAPD( errorcode, AddCommandToStackL( i, button->CommandId(), button->LabelText(),
+ NULL, NULL ) );
+
+ if ( errorcode ) // In case of error restore previous commands before leave.
+ {
+ for ( TInt counter = 0; counter < i; counter++ )
+ {
+ // Do not deal with the scroller as a CEikCbaButton; skip its index.
+ if ( counter != KControlArrayScrollBarPosn )
+ {
+ // Following adjusts for the fact that the scroller command is
+ // missing from the previousIds array. Same index adjust as later on.
+ TInt indexInPreviousIds = counter;
+ if ( counter > 1 )
+ {
+ indexInPreviousIds = counter - 1;
+ }
+ RemoveCommandFromStack( counter, previousIds[indexInPreviousIds] );
+ }
+ }
+ User::Leave( errorcode );
+ }
+ CleanupStack::PopAndDestroy( button );
+ }
+ }
+
+ // Remove the original commands from the temporary store. +1 for scroll bar.
+ for ( TInt controlId = 0; controlId < KMaxButtonsInCommandTable + 1; controlId++ )
+ {
+ if ( controlId != KControlArrayScrollBarPosn )
+ {
+ TInt controlPosition=controlId;
+ if ( controlId > 1 )
+ {
+ controlPosition--;
+ }
+
+ RemovePreviousCommand( controlId );
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // previousIds
+ }
+#else // !RD_ENHANCED_CBA
+EXPORT_C void CEikCba::OfferCommandListL(const TInt /*aResourceId*/)
+ {
+ User::Leave( KErrNotSupported );
+ }
+#endif // RD_ENHANCED_CBA
+
+// -----------------------------------------------------------------------------
+// Used to check if a certain command have been approved to the current command set.
+// @param aCommandId The id for command which existence should be checked.
+// @since 5.0
+// -----------------------------------------------------------------------------
+#ifdef RD_ENHANCED_CBA
+EXPORT_C TBool CEikCba::IsCommandInGroup(const TInt aCommandId) const
+ {
+ return ButtonById(aCommandId) ? ETrue : EFalse; // check the iControlArray
+ }
+#else // !RD_ENHANCED_CBA
+EXPORT_C TBool CEikCba::IsCommandInGroup(const TInt /*aCommandId*/) const
+ {
+ return EFalse;
+ }
+#endif // RD_ENHANCED_CBA
+
+// -----------------------------------------------------------------------------
+// Replace existing command with a new command
+// @param aCommandId Id for command that should be replaced.
+// @param aResourceId Resource id for new enhanced cba button.
+// @since 5.0
+// -----------------------------------------------------------------------------
+#ifdef RD_ENHANCED_CBA
+EXPORT_C void CEikCba::ReplaceCommand(const TInt aReplaceCommandId, const TInt aResourceId)
+ {
+ TInt index = IndexById( aReplaceCommandId );
+ TRAPD(err, SetCommandL( index, aResourceId ) );
+ }
+#else
+EXPORT_C void CEikCba::ReplaceCommand(const TInt /*aReplaceCommandId*/, const TInt /*aResourceId*/)
+ {
+ }
+#endif // RD_ENHANCED_CBA
+
+void CEikCba::HandleControlEventL( CCoeControl* aControl, TCoeEvent aEventType )
+ {
+ if ( !iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ //User::Panic( _L( "CBA inside dialog" ), KErrNotSupported );
+ return;
+ }
+
+ if ( aEventType == EEventStateChanged )
+ {
+ TInt command = NULL;
+
+ if ( aControl == (*iControlArray)[KControlArrayCBAButton1Posn].iControl )
+ {
+ command = (*iControlArray)[KControlArrayCBAButton1Posn].iId;
+ }
+ else if ( aControl == (*iControlArray)[KControlArrayCBAButton2Posn].iControl )
+ {
+ command = (*iControlArray)[KControlArrayCBAButton2Posn].iId;
+ }
+
+ // CAknButton sends control event to CEikCba upon pointer event,
+ // while also increasing it's state value. Because of the way
+ // CAknButton is used as softkey control, and it's states as stack
+ // support, we must revert the state back here.
+ CAknButton* button = static_cast<CAknButton*>( aControl );
+ TInt state( button->StateIndex() );
+ if ( state > 0 )
+ {
+ state--;
+ button->SetCurrentState( state, EFalse );
+ }
+
+
+ if( command )
+ {
+ iCommandObserver->ProcessCommandL( command );
+ }
+ }
+ }
+
+
+void CEikCba::MakeVisible( TBool aVisible )
+ {
+ if ( aVisible )
+ {
+ TBool redrawNeeded( EFalse );
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ CEikCbaButton* leftSK = static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton1Posn].iControl );
+ CEikCbaButton* rightSK = static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButton2Posn].iControl );
+ CEikCbaButton* middleSK = NULL;
+
+ if ( iMSKset && AknLayoutUtils::MSKEnabled() )
+ {
+ middleSK =
+ static_cast<CEikCbaButton*>(
+ (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl );
+ }
+
+ if ( leftSK && leftSK->PressedDown() )
+ {
+ leftSK->SetPressedDown( EFalse );
+ redrawNeeded = ETrue;
+ }
+
+ if ( rightSK && rightSK->PressedDown() )
+ {
+ rightSK->SetPressedDown( EFalse );
+ redrawNeeded = ETrue;
+ }
+
+ if ( middleSK && middleSK->PressedDown() )
+ {
+ middleSK->SetPressedDown( EFalse );
+ redrawNeeded = ETrue;
+ }
+
+ if ( redrawNeeded )
+ {
+ SizeChanged();
+ }
+ }
+
+ if ( iFlags[ECbaChangeRecordedSkin] )
+ {
+ DoSkinChange();
+ }
+
+ if ( iFlags[ECbaChangeRecordedLayout] )
+ {
+ DoLayoutChange();
+ redrawNeeded = ETrue;
+ }
+
+ if ( iFlags[ECbaChangeRecordedColor] )
+ {
+ DoColorChange();
+ }
+
+ TBool isVisible = IsVisible();
+ CEikControlGroup::MakeVisible( aVisible );
+
+ if ( redrawNeeded || !isVisible || IsEmpty() )
+ {
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ DrawDeferred();
+ }
+ else
+ {
+ DrawNow();
+ }
+ }
+ }
+ else
+ {
+ Window().ClearRedrawStore();
+ CEikControlGroup::MakeVisible( aVisible );
+ }
+
+ ReportContentChangedEvent();
+ }
+
+
+// -----------------------------------------------------------------------------
+// Sets layer images and rects.
+// @since 5.0
+// -----------------------------------------------------------------------------
+void CEikCba::DoSetLayers( const TAknsItemID& aIID )
+ {
+ // Skin background is not drawn by embedded CBA.
+ if ( iFlags.IsSet( ECbaEmbedded ) )
+ {
+ return;
+ }
+
+ TAknLayoutRect cbarect;
+ TRect screen;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
+
+ TAknWindowComponentLayout applicationWindow(
+ AknLayoutScalable_Avkon::application_window( 0 ) );
+
+ TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
+ TBool rightPaneActive( IsAreaSideRightPaneActive() );
+ TBool idleLayout( AknStatuspaneUtils::IdleLayoutActive() );
+
+ if ( rightPaneActive )
+ {
+ cbarect.LayoutRect(
+ screen,
+ DoCompose(
+ applicationWindow,
+ AknLayoutScalable_Avkon::area_side_right_pane( 0 ) ).LayoutLine() );
+ }
+ else
+ {
+ // We must check for landscape mode bottom SKs
+ TInt bottomPaneVariety = 1;
+
+ if ( isLandscape )
+ {
+ // In flat iBgContext is used and flat is "landscape".
+ bottomPaneVariety = 6;
+ }
+
+ TAknWindowComponentLayout bottomArea(
+ AknLayoutScalable_Avkon::area_bottom_pane( bottomPaneVariety ) );
+ TAknWindowComponentLayout controlPane(
+ AknLayoutScalable_Avkon::control_pane() );
+ controlPane = DoCompose(
+ applicationWindow,
+ DoCompose(
+ bottomArea, controlPane ) );
+ cbarect.LayoutRect( screen, controlPane.LayoutLine() );
+ }
+
+ TRect cbaRect( cbarect.Rect() );
+
+ TAknsItemID myIID( iBgIID );
+ TAknsItemID maskIID( KAknsIIDNone );
+
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ // Widescreen landscape layout or touch portrait.
+
+ // Empty the layers.
+ for ( TInt i = 0; i < ECbaLayerN; i++ )
+ {
+ iMLBgContext->SetLayerImage( i, KAknsIIDNone );
+ }
+
+ TInt currentBgIIDMinor( aIID.iMinor );
+ if ( aIID == KAknsIIDNone )
+ {
+ currentBgIIDMinor = iBgIID.iMinor;
+ }
+
+ // Right pane CBA areas don't have their own skin
+ // backgrounds, so the screen background is used
+ // and correct ID is mapped here.
+ switch ( currentBgIIDMinor )
+ {
+ case EAknsMinorNone:
+ {
+ if ( rightPaneActive )
+ {
+ myIID = idleLayout ? KAknsIIDQsnBgScreenIdle :
+ KAknsIIDQsnBgScreen;
+ }
+ else
+ {
+ myIID = idleLayout ? KAknsIIDQsnBgAreaControlIdle :
+ KAknsIIDQsnBgAreaControl;
+ }
+ break;
+ }
+ case EAknsMinorQsnBgAreaControl:
+ default:
+ {
+ if ( rightPaneActive )
+ {
+ myIID = idleLayout ? KAknsIIDQsnBgScreenIdle :
+ KAknsIIDQsnBgScreen;
+ }
+ else
+ {
+ myIID = idleLayout ? KAknsIIDQsnBgAreaControlIdle :
+ KAknsIIDQsnBgAreaControl;
+ }
+ break;
+ }
+ case EAknsMinorQsnBgAreaControlPopup:
+ {
+ if ( rightPaneActive )
+ {
+ myIID = idleLayout ? KAknsIIDQsnBgScreenIdle :
+ KAknsIIDQsnBgScreen;
+ }
+ else
+ {
+ myIID = idleLayout ? KAknsIIDQsnBgAreaControlIdle :
+ KAknsIIDQsnBgAreaControlPopup;
+ }
+ break;
+ }
+ case EAknsMinorQsnBgAreaControlIdle:
+ {
+ if ( rightPaneActive )
+ {
+ myIID = idleLayout ? KAknsIIDQsnBgScreenIdle :
+ KAknsIIDQsnBgScreen;
+ }
+ else
+ {
+ myIID = idleLayout ? KAknsIIDQsnBgAreaControlIdle :
+ KAknsIIDQsnBgAreaControl;
+ }
+ break;
+ }
+ case EAknsMinorQsnBgAreaControlMp:
+ {
+ myIID = rightPaneActive ? KAknsIIDQsnBgScreenMp :
+ KAknsIIDQsnBgAreaControlMp;
+ break;
+ }
+ }
+ if ( idleLayout && iExtension && !( iExtension->iWallpaperInUse == 0 ))
+ {
+ maskIID = KAknsIIDQgnIndiSctrlSkMaskRightPrt;
+ }
+ else
+ {
+ maskIID = rightPaneActive ? KAknsIIDQgnGrafBgLscBottomMaskIcon :
+ KAknsIIDQgnGrafBgPrtBottomMaskIcon;
+ }
+
+ if ( idleLayout )
+ {
+ if ( iExtension && iExtension->iWallpaperInUse == 0 )
+ {
+ iMLBgContext->SetLayerImage( ECbaLayerWallpaper, myIID );
+ iMLBgContext->SetLayerRect(
+ ECbaLayerWallpaper, rightPaneActive ? screen : cbaRect );
+ }
+ else
+ {
+ iMLBgContext->SetLayerImage( ECbaLayerWallpaper, KAknsIIDWallpaper );
+ iMLBgContext->SetLayerRect( ECbaLayerWallpaper, screen );
+ }
+ }
+ else
+ {
+ iMLBgContext->SetLayerImage( ECbaLayerWallpaper, KAknsIIDNone );
+ maskIID = KAknsIIDNone;
+ }
+
+ iMLBgContext->SetLayerImage( ECbaLayerBackground, myIID );
+ iMLBgContext->SetLayerRect(
+ ECbaLayerBackground, rightPaneActive ? screen : cbaRect );
+
+ if (iExtension &&
+ (!(iExtension->iBackgroundMaskID == maskIID && iExtension->iCbaRect == cbaRect) ||
+ iExtension->iIfSkinChanged ||
+ iExtension->iBackgroundMaskID == KAknsIIDNone))
+ {
+ TRAP_IGNORE( iMLBgContext->SetLayerMaskAndSizeL(
+ maskIID, rightPaneActive ? screen : cbaRect ) );
+ iExtension->iBackgroundMaskID = maskIID;
+ iExtension->iCbaRect = cbaRect;
+ }
+ }
+ else // non-nHD layout
+ {
+ if ( idleLayout )
+ {
+ if ( aIID == KAknsIIDNone )
+ {
+ myIID = iBgIID;
+ }
+
+ iMLBgContext->SetLayerImage( ECbaLayerWallpaper, KAknsIIDWallpaper );
+ iMLBgContext->SetLayerRect( ECbaLayerWallpaper, screen );
+ iMLBgContext->SetLayerImage( ECbaLayerBackground, myIID );
+ iMLBgContext->SetLayerRect( ECbaLayerBackground, cbaRect );
+
+ if ( isLandscape )
+ {
+ maskIID = KAknsIIDQgnGrafBgLscSideRightMaskIcon;
+ }
+ else
+ {
+ maskIID = KAknsIIDQgnGrafBgPrtBottomMaskIcon;
+ }
+ }
+ else
+ {
+ if ( aIID == KAknsIIDNone )
+ {
+ myIID = KAknsIIDQsnBgAreaControl;
+ }
+
+ iMLBgContext->SetLayerImage( ECbaLayerBackground, myIID );
+ iMLBgContext->SetLayerImage( ECbaLayerWallpaper, KAknsIIDNone );
+ iMLBgContext->SetLayerRect( ECbaLayerBackground, cbaRect );
+ }
+
+ TRAP_IGNORE( iMLBgContext->SetLayerMaskAndSizeL( maskIID, cbaRect ) );
+ }
+
+ DrawDeferred();
+ }
+
+
+void CEikCba::LayoutControl( CCoeControl* aControl, const TRect& aRect )
+ {
+ if ( !iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ TRect rect( aRect );
+ // aid_value_unit2 is 10ux10u rectangle.
+ TAknWindowComponentLayout unit( AknLayoutScalable_Avkon::aid_value_unit2() );
+ // Move 0.5 units to right and down.
+ TInt delta = unit.LayoutLine().iW / 10 / 2;
+ if ( ( (CEikCbaButton*)aControl )->PressedDown() )
+ {
+ rect.Move( delta, delta );
+ }
+ aControl->SetRect( rect );
+ aControl->ComponentControl( 0 )->SetRect( rect );
+ }
+ }
+
+void CEikCba::BroadcastPostingTransparency( TBool aEnable )
+ {
+ // Communicate change to CBA buttons.
+ for ( TInt i = 0; i < iControlArray->Count(); i++ )
+ {
+ if ( i != KControlArrayScrollBarPosn ) // To avoid tinkering with scrollbar.
+ {
+ TEikGroupControl& gCtrl = iControlArray->At( i );
+ CEikCbaButton* button = dynamic_cast<CEikCbaButton*>( gCtrl.iControl );
+ if ( button )
+ {
+ button->SetTextBitmapMode( aEnable );
+ }
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::SetFadeState
+// Sets the CBA faded if it's contents are empty.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::SetFadeState()
+ {
+ TBool canBeFaded =
+ IsEmpty() && !( ( iCbaFlags & EEikCbaFlagTransparent )
+ || ( iExtension && iExtension->iEnablePostingTransparency ) );
+
+ // No unfading when system is faded
+ if ( !( !canBeFaded
+ && static_cast<CAknAppUi*>( iCoeEnv->AppUi() )->IsFaded() ) )
+ {
+ Window().SetFaded( canBeFaded, RWindowTreeNode::EFadeIncludeChildren );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::UpdateLabels
+// Updates softkey labels in case of embedded softkeys.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::UpdateLabels( TBool aDrawDeferred )
+ {
+ if ( iControlArray->Count() != 0)
+ {
+ CCoeControl *leftSoftkey = ( *iControlArray )
+ [ KControlArrayCBAButton1Posn ].iControl;
+ CCoeControl *rightSoftkey = ( *iControlArray )
+ [ KControlArrayCBAButton2Posn ].iControl;
+
+ if ( !( ( ( CEikCbaButton* ) leftSoftkey )->IsImageOn() ) )
+ {
+ TAknTextLineLayout textLayout(
+ AknLayoutScalable_Avkon::popup_sk_window_t1( 0 ).LayoutLine() );
+
+ if ( iCbaFlags & EEikCbaFlagOutlineFont )
+ {
+ textLayout.iFont |= KOutlineFontMask;
+ }
+
+ AknLayoutUtils::LayoutLabel( ( CEikLabel* )
+ leftSoftkey->ComponentControl( 0 ),
+ Rect(),
+ textLayout );
+
+ LayoutControl( (CEikCbaButton*)leftSoftkey,
+ leftSoftkey->ComponentControl( 0 )->Rect() );
+ ((CEikCbaButton*)leftSoftkey)->TruncateLabelText();
+ }
+
+ if ( !( ( ( CEikCbaButton* ) rightSoftkey )->IsImageOn() ) )
+ {
+ TAknTextLineLayout textLayout(
+ AknLayoutScalable_Avkon::popup_sk_window_t1_copy1( 0 ).LayoutLine() );
+
+ if ( iCbaFlags & EEikCbaFlagOutlineFont )
+ {
+ textLayout.iFont |= KOutlineFontMask;
+ }
+ AknLayoutUtils::LayoutLabel((CEikLabel*)
+ rightSoftkey->ComponentControl( 0 ),
+ Rect(),
+ textLayout );
+ LayoutControl( (CEikCbaButton*)rightSoftkey,
+ rightSoftkey->ComponentControl( 0 )->Rect() );
+ ((CEikCbaButton*)rightSoftkey)->TruncateLabelText();
+ }
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ TRgb leftColor;
+ TRgb rightColor;
+
+ TInt errorl;
+ TInt errorr;
+
+ if ( iPopupVisible )
+ {
+ errorl = AknsUtils::GetCachedColor(
+ skin,
+ leftColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG17 );
+
+ errorr = AknsUtils::GetCachedColor(
+ skin,
+ rightColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG18 );
+ }
+ else
+ {
+ errorl = AknsUtils::GetCachedColor(
+ skin,
+ leftColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG13 );
+
+ errorr = AknsUtils::GetCachedColor(
+ skin,
+ rightColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG14 );
+ }
+
+ if ( ((CEikCbaButton*)leftSoftkey)->PressedDown() )
+ {
+ leftColor.SetAlpha( KPressedDownAlphaValue );
+
+ AknsUtils::GetCachedColor(
+ skin,
+ leftColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG69 );
+ }
+ else if ( ((CEikCbaButton*)rightSoftkey)->PressedDown() )
+ {
+ rightColor.SetAlpha( KPressedDownAlphaValue );
+
+ AknsUtils::GetCachedColor(
+ skin,
+ rightColor,
+ KAknsIIDQsnTextColors,
+ EAknsCIQsnTextColorsCG69 );
+ }
+
+ if( !errorl && !errorr )
+ {
+ // Error ignored
+ TRAP( errorl, AknLayoutUtils::OverrideControlColorL(
+ *leftSoftkey,
+ EColorLabelText,
+ leftColor) );
+
+ TRAP( errorr, AknLayoutUtils::OverrideControlColorL(
+ *rightSoftkey,
+ EColorLabelText,
+ rightColor) );
+ }
+
+ if ( aDrawDeferred )
+ {
+ DrawDeferred();
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// EikSoftkeyPostingTransparency::MakeTransparent
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt EikSoftkeyPostingTransparency::MakeTransparent(
+ CEikButtonGroupContainer& aButtonGroupContainer,
+ TBool aEnable )
+ {
+ CEikCba* cba = dynamic_cast<CEikCba*>( aButtonGroupContainer.ButtonGroup() );
+ TInt ret = KErrNone;
+ if ( cba )
+ {
+ if ( aEnable && ( cba->ButtonGroupFlags() & EEikCbaFlagTransparent ) )
+ {
+ // EikSoftkeyPostingTransparency is not supported if
+ // EEikCbaFlagTransparent is enabled
+ ret = KErrArgument;
+ }
+ else
+ {
+ cba->EnablePostingTransparency( aEnable );
+ }
+ }
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CEikCba::EnablePostingTransparency
+//
+// -----------------------------------------------------------------------------
+//
+void CEikCba::EnablePostingTransparency( TBool aEnable )
+ {
+ if ( iExtension )
+ {
+ if ( iExtension->iEnablePostingTransparency != aEnable )
+ {
+ iExtension->iEnablePostingTransparency = aEnable;
+
+ UpdateFonts();
+
+ if ( !aEnable )
+ {
+ delete iExtension->iLskPostingOverlayBitmap;
+ iExtension->iLskPostingOverlayBitmap = NULL;
+ delete iExtension->iRskPostingOverlayBitmap;
+ iExtension->iRskPostingOverlayBitmap = NULL;
+
+ // Update label text color. SizeChanged
+ // will not call BroadcastPostingTransparency in this case.
+ // It has to be called directly from here.
+ SizeChanged();
+
+ BroadcastPostingTransparency( EFalse );
+ }
+ else
+ {
+ // Update background bitmaps. SizeChanged
+ // will also call BroadcastPostingTransparency.
+ SizeChanged();
+ }
+
+ DrawDeferred();
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::IsEmpty
+// Checks if the CBA has no commands.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CEikCba::IsEmpty() const
+ {
+ TBool isEmpty( ETrue );
+
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ // Not supported for full screen query.
+ isEmpty = EFalse;
+ }
+ else
+ {
+ for ( TInt i = 0; i < iControlArray->Count(); i++ )
+ {
+ if ( i != KControlArrayScrollBarPosn ) // Do not take scrollbar into account.
+ {
+ TEikGroupControl& gCtrl = iControlArray->At( i );
+ if ( gCtrl.iId != EEikBidBlank &&
+ gCtrl.iId != EAknSoftkeyEmpty &&
+ ( gCtrl.iId < 0 || gCtrl.iId > 2 ) )
+ {
+ isEmpty = EFalse;
+ }
+ else
+ {
+ if ( gCtrl.iControl &&
+ ( !(static_cast<CEikCbaButton*>(gCtrl.iControl))->IsEmptyText()
+ || (static_cast<CEikCbaButton*>(gCtrl.iControl))->IsImageOn() )
+ )
+ {
+ isEmpty = EFalse;
+ }
+ }
+ }
+ }
+ }
+
+ return isEmpty;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::Flags
+// Returns flags.
+// ---------------------------------------------------------------------------
+//
+TBitFlags CEikCba::Flags()
+ {
+ return iFlags;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::SetContentObserver
+// Sets content observer.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::SetContentObserver( TCallBack aCallBack )
+ {
+ if ( iExtension )
+ {
+ iExtension->iContentObserver = aCallBack;
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::ReportContentChangedEvent
+// Reports state changed event if cba changed from empty to non-empty
+// or vice versa.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::ReportContentChangedEvent()
+ {
+ if ( ItemSpecificSoftkey() )
+ {
+ UpdateItemSpecificSoftkey(
+ iExtension->Active() && !Window().IsFaded() );
+ }
+
+ if ( !iFlags.IsSet( ECbaEmbedded ) )
+ {
+ return;
+ }
+
+ TBool isEmpty( !IsVisible() || IsEmpty() );
+ TBool reportStateChanged( EFalse );
+ if ( !isEmpty && !iFlags.IsSet( ECbaHasContent ) )
+ {
+ reportStateChanged = ETrue;
+ iFlags.Set( ECbaHasContent );
+ }
+ else if ( isEmpty && iFlags.IsSet( ECbaHasContent ) )
+ {
+ reportStateChanged = ETrue;
+ iFlags.Clear( ECbaHasContent );
+ }
+
+ // Report state changed event if changed from empty to non-empty
+ // or vice versa. Dialog knows to increase its height so that
+ // also cba is visible
+ if ( reportStateChanged )
+ {
+ Window().Invalidate();
+ if ( iExtension && iExtension->iContentObserver.iFunction )
+ {
+ iExtension->iContentObserver.CallBack(); // return value ignored
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CEikCba::DrawEmbeddedSoftkey
+// Draws embedded softkey
+// ---------------------------------------------------------------------------
+//
+void CEikCba::DrawEmbeddedSoftkey( TEikGroupControl& aGroupControl,
+ const TRect& aRect,
+ CWindowGc& aGc,
+ CFbsBitmap* /*aMask*/ ) const
+ {
+ CEikCbaButton* button =
+ static_cast<CEikCbaButton*>( aGroupControl.iControl );
+
+ TAknLayoutRect layoutRect;
+ TRect innerRect;
+ layoutRect.LayoutRect( aRect,
+ AknLayoutScalable_Avkon::bg_sctrl_sk_pane_g1()
+ .LayoutLine() );
+ innerRect = layoutRect.Rect();
+
+
+ if( button->PressedDown() ) // draw PressedFrame
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ aGc,
+ aRect,
+ innerRect,
+ KAknsIIDQgnFrSctrlSkButtonPressed,
+ KAknsIIDQgnFrSctrlSkButtonCenterPressed );
+ }
+ else // draw Frame
+ {
+ AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ aGc,
+ aRect,
+ innerRect,
+ KAknsIIDQgnFrSctrlSkButton,
+ KAknsIIDQgnFrSctrlSkButtonCenter);
+ }
+ }
+
+TBool CEikCba::UpdateIconL()
+ {
+ if ( iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ return EFalse;
+ }
+
+ if ( !iExtension->iIfMskIconSet ||
+ !MskAllowed() )
+ {
+ return EFalse;
+ }
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ if ( !skin )
+ {
+ return EFalse;
+ }
+
+ TEikGroupControl &gCtrl = iControlArray->At( KControlArrayCBAButtonMSKPosn );
+
+ CEikCbaButton *button = static_cast<CEikCbaButton*>( gCtrl.iControl );
+ if ( !button )
+ {
+ return EFalse;
+ }
+
+ CFbsBitmap *bitmap = NULL;
+ CFbsBitmap *mask = NULL;
+
+ TAknLayoutRect qgn_graf_sk_msk;
+ TRect rect;
+ qgn_graf_sk_msk.LayoutRect(
+ rect,
+ AknLayoutScalable_Avkon::control_pane_g4( 0 ).LayoutLine() );
+
+ TSize iconSize( qgn_graf_sk_msk.Rect().Width(),
+ qgn_graf_sk_msk.Rect().Height() );
+
+ AknsUtils::CreateIconL(
+ skin,
+ iExtension->iMSKSkinID,
+ bitmap,
+ mask,
+ *iExtension->iBmpFile,
+ iExtension->iBmp,
+ iExtension->iBmpM );
+
+ if ( bitmap ) // Bitmap not set -> do not use image.
+ {
+ AknIconUtils::DisableCompression( bitmap );
+ AknIconUtils::DisableCompression( mask );
+ AknIconUtils::SetSize( bitmap, iconSize );
+ CEikImage* image = new (ELeave) CEikImage;
+ image->SetPicture( bitmap, mask );
+
+ // Transfers ownership of the image (image owns bitmap and mask).
+ button->SetImage( *image );
+
+ SizeChanged();
+
+ button->DrawNow();
+ }
+ else
+ {
+ button->ReplaceImageByLabel(); // remove old image
+ }
+
+ button->SetContainerWindowL( *this );
+
+ return ETrue;
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// Checks if the middle softkey should be used.
+// Should be used with the SetMSKVisibility-method to set MSK visibility
+// when on layout changes etc.
+// ---------------------------------------------------------------------------
+//
+TBool CEikCba::MskAllowed() const
+ {
+ return ( iMSKEnabledInPlatform &&
+ AknLayoutUtils::MSKEnabled() &&
+ IsMskEnabledLayoutActive() );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::SoftkeyStatusChangeAllowed
+// Returns ETrue if softkey status change is allowed.
+// ---------------------------------------------------------------------------
+//
+TBool CEikCba::SoftkeyStatusChangeAllowed(
+ TInt aSoftkeyPosition, TBool aDisabled )
+ {
+ TBool allowChange( ETrue );
+ if ( aSoftkeyPosition == KControlArrayCBAButton1Posn )
+ {
+ if ( aDisabled )
+ {
+ iFlags.Set( ECbaItemSoftkeyDisabledByClient );
+ }
+ else
+ {
+ iFlags.Clear( ECbaItemSoftkeyDisabledByClient );
+ if ( iFlags.IsSet( ECbaItemSoftkeyDisabled ) )
+ {
+ allowChange = EFalse;
+ }
+ }
+ }
+ return allowChange;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::ItemSpecificSoftkey
+// Returns item specific softkey control if it state should be updated.
+// ---------------------------------------------------------------------------
+//
+TEikGroupControl* CEikCba::ItemSpecificSoftkey() const
+ {
+ TEikGroupControl* lsk( NULL );
+ if ( iFlags.IsSet( ECbaItemSpecificSoftkeyInUse ) )
+ {
+ TEikGroupControl& leftSoftkey =
+ ( *iControlArray ) [ KControlArrayCBAButton1Posn ];
+ if ( leftSoftkey.iId != EAknSoftkeyOptions
+ || iFlags.IsSet( ECbaItemSoftkeyDisabled ) )
+ {
+ lsk = &leftSoftkey;
+ }
+ }
+ return lsk;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::UpdateItemSpecificSoftkey
+// Updates item specific softkey.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::UpdateItemSpecificSoftkey( TBool aVisibleCollection )
+ {
+ if ( iFlags.IsSet( ECbaSingleClickEnabled )
+ && iExtension && iExtension->iItemActionMenu )
+ {
+ TEikGroupControl* leftSk = ItemSpecificSoftkey();
+ if ( leftSk )
+ {
+ TBool enableSk( leftSk->iId == EAknSoftkeyOptions ||
+ iExtension->iItemActionMenu->CollectionSoftkeyVisible(
+ aVisibleCollection ) );
+ UpdateItemSpecificSoftkey( *leftSk->iControl, enableSk );
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CEikCba::UpdateItemSpecificSoftkey
+// Updates item specific softkey.
+// ---------------------------------------------------------------------------
+//
+void CEikCba::UpdateItemSpecificSoftkey( CCoeControl& aControl, TBool aEnable )
+ {
+ TBool skEnabled( aControl.IsVisible() && !aControl.IsDimmed() );
+ TBool changeState( EFalse );
+ if ( !aEnable )
+ {
+ iFlags.Set( ECbaItemSoftkeyDisabled );
+ if ( skEnabled )
+ {
+ changeState = ETrue;
+ }
+ }
+ else
+ {
+ iFlags.Clear( ECbaItemSoftkeyDisabled );
+ if ( !skEnabled
+ && iFlags.IsClear( ECbaItemSoftkeyDisabledByClient ) )
+ {
+ changeState = ETrue;
+ }
+ }
+ if ( changeState )
+ {
+ if ( !iFlags.IsSet( ECbaInsideDialog ) )
+ {
+ aControl.MakeVisible( aEnable );
+ }
+ else
+ {
+ aControl.SetDimmed( !aEnable );
+ aControl.DrawDeferred();
+ }
+ }
+ }
+
+
+//
+// class CEikCbaButton
+//
+
+CEikCbaButton::~CEikCbaButton()
+ {
+ AKNTASHOOK_REMOVE();
+ delete iLabel;
+ if ( iImage )
+ {
+ iImage->SetMask( iMask );
+ }
+ delete iImage;
+ delete iSfeMask;
+ delete iButtonOptions;
+ delete iText;
+
+ }
+
+void CEikCbaButton::ConstructL(TGulAlignmentValue aAlignment)
+ {
+ iLabel = new(ELeave) CEikLabel;
+ iPressedDown = EFalse;
+ iLabel->SetBufferReserveLengthL(KMaxCbaLabelLength);
+ UpdateLabelText(TPtrC());
+ iLabel->SetAlignment(aAlignment);
+
+ iButtonOptions = new(ELeave) CArrayFixFlat<SButtonOptions>(1);
+ iText = new(ELeave) CDesCArrayFlat(1);
+
+ if ( iUseTextBitmap )
+ {
+ iLabel->MakeVisible( EFalse );
+ }
+ AKNTASHOOK_ADDL( this, "CEikCbaButton" );
+ }
+
+void CEikCbaButton::AddCommandL(const TDesC& aText)
+ {
+ UpdateLabelText(aText);
+ }
+
+struct STempCleanup
+ {
+ CDesCArray* iText;
+ CArrayFix<CEikCbaButton::SButtonOptions>* iButtonOptions;
+ };
+
+LOCAL_C void CleanupTemp(TAny* aPtr)
+ {
+ STempCleanup& temp = *(STempCleanup*)aPtr;
+ const TInt count = temp.iText->Count();
+ if (temp.iButtonOptions->Count() == count)
+ {
+ temp.iButtonOptions->Delete(count - 1);
+ }
+ temp.iText->Delete(count - 1);
+ }
+
+void CEikCbaButton::PushCommandL(TInt aCommandId,const TDesC& aText)
+ {
+ if (!iButtonOptions)
+ {
+ iButtonOptions = new(ELeave) CArrayFixFlat<SButtonOptions>(1);
+ }
+ if (!iText)
+ {
+ iText = new(ELeave) CDesCArrayFlat(1);
+ }
+
+ iText->AppendL(iFullLabelText);
+
+ STempCleanup temp;
+ SButtonOptions options;
+ temp.iText = iText;
+ temp.iButtonOptions = iButtonOptions;
+ CleanupStack::PushL(TCleanupItem(CleanupTemp,&temp));
+ options.iCommandId = aCommandId;
+ options.iDimmed = iLabel->IsDimmed();
+ iLabel->SetDimmed(EFalse);
+ iButtonOptions->AppendL(options);
+ UpdateLabelText(aText);
+ CleanupStack::Pop(); // temp
+ }
+
+TInt CEikCbaButton::PopCommand()
+ {
+ if (!iButtonOptions)
+ {
+ return -1;
+ }
+
+ TInt count = iButtonOptions->Count();
+ --count;
+
+ if (count < 0)
+ {
+ return -1;
+ }
+
+ const SButtonOptions buttonOptions = (*iButtonOptions)[count];
+ iButtonOptions->Delete(count);
+ TPtrC text = (*iText)[count];
+ UpdateLabelText(text);
+ iText->Delete(count);
+ if (iButtonOptions->Count() == 0)
+ {
+ delete iButtonOptions;
+ iButtonOptions = NULL;
+ delete iText;
+ iText = NULL;
+ }
+ iLabel->SetDimmed(buttonOptions.iDimmed);
+ if (!iDoImage)
+ {
+ iLabel->DrawDeferred();
+ }
+ else
+ {
+ iImage->DrawNow();
+ }
+ return buttonOptions.iCommandId;
+ }
+
+void CEikCbaButton::RemoveCommand(TInt aCommandId)
+ {
+ if (!iButtonOptions)
+ {
+ return;
+ }
+ TInt index = IndexFromCommandId(aCommandId);
+ if (index != KErrNotFound)
+ {
+ iButtonOptions->Delete(index);
+ iText->Delete(index);
+ if (iButtonOptions->Count() == 0)
+ {
+ delete iButtonOptions;
+ iButtonOptions = NULL;
+ delete iText;
+ iText = NULL;
+ }
+ }
+ }
+
+void CEikCbaButton::RemovePreviousCommand()
+ {
+ if (!iButtonOptions)
+ {
+ return;
+ }
+ TInt index = iButtonOptions->Count() - 2;
+ if (index >= 0)
+ {
+ iButtonOptions->Delete(index);
+ iText->Delete(index);
+ }
+ }
+
+TInt CEikCbaButton::IndexFromCommandId(TInt aCommandId)
+ {
+ TInt index;
+ TKeyArrayFix key(0, ECmpTInt);
+ SButtonOptions options;
+ options.iCommandId = aCommandId;
+ if (iButtonOptions->Find(options, key, index) == KErrNone)
+ {
+ return index;
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+ }
+
+void CEikCbaButton::SetContainerWindowL(const CCoeControl& aContainer)
+ {
+ CCoeControl::SetContainerWindowL(aContainer);
+ if (!iDoImage)
+ {
+ iLabel->SetContainerWindowL(aContainer);
+ }
+ else
+ {
+ iImage->SetContainerWindowL(aContainer);
+ }
+ }
+
+void CEikCbaButton::ConstructFromResourceL(TResourceReader& aReader, TGulAlignmentValue anAlignment)
+ {
+ ConstructL(anAlignment);
+ UpdateLabelText(aReader.ReadTPtrC());
+ aReader.ReadTPtrC(); // bmp filename
+ aReader.ReadInt16(); // bmp id
+ aReader.ReadInt16(); // bmp mask id
+ }
+
+TSize CEikCbaButton::MinimumSize()
+ {
+ if (!iDoImage)
+ {
+ return iLabel->MinimumSize();
+ }
+ else
+ {
+ return iImage->MinimumSize();
+ }
+ }
+
+TInt CEikCbaButton::CountComponentControls() const
+ {
+ return 1;
+ }
+
+CCoeControl* CEikCbaButton::ComponentControl(TInt aIndex) const
+ {
+ if (aIndex==0)
+ {
+ if (!iDoImage)
+ {
+ return iLabel;
+ }
+ else
+ {
+ // If SfeMask is available, then check the effect state (iPressedDown).
+ if ( iSfeMask )
+ {
+ if ( iPressedDown )
+ {
+ iImage->SetMask( iSfeMask );
+ }
+ else
+ {
+ iImage->SetMask( iMask );
+ }
+ }
+ return iImage;
+ }
+ }
+ return 0;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Handles size change events for CBA button.
+// ---------------------------------------------------------------------------
+//
+void CEikCbaButton::SizeChanged()
+ {
+ // Resizing is done at CEikCba::SizeChanged().
+ // We cannot resize here because this control has wrong
+ // coordinate system available.
+
+ }
+
+
+EXPORT_C void CEikCbaButton::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+ {
+ CCoeControl::HandlePointerEventL(aPointerEvent);
+ }
+
+EXPORT_C void* CEikCbaButton::ExtensionInterface( TUid /*aInterface*/ )
+ {
+ return NULL;
+ }
+
+void CEikCbaButton::SetDimmed(TBool aDimmed)
+ {
+ CCoeControl::SetDimmed(aDimmed);
+ if (!iDoImage)
+ {
+ iLabel->SetDimmed(aDimmed);
+ }
+ else
+ {
+ // Drawing dimmed CEikImages don't work (problem in uiklaf).
+ //iImage->SetDimmed(aDimmed);
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// Updates the softkey label.
+// ---------------------------------------------------------------------------
+//
+void CEikCbaButton::UpdateLabelText( TPtrC aLabelText )
+ {
+ // Updates the label text with the given label, using tab delimited
+ // label text to identify normal / alternative labels.
+ if ( aLabelText.Length() > KMaxCbaLabelLength )
+ {
+ // Cannot take more chars than maximum buffer size.
+ iFullLabelText.Copy( aLabelText.Left( KMaxCbaLabelLength ) );
+ }
+ else
+ {
+ iFullLabelText.Copy( aLabelText );
+ }
+
+ TInt find = aLabelText.Locate( CEditableText::ETabCharacter );
+ if ( find == KErrNotFound )
+ {
+ iLongLabelText.Set( iFullLabelText );
+ iShortLabelText.Set( iFullLabelText );
+ }
+ else
+ {
+ iLongLabelText.Set( iFullLabelText.Left( find ) );
+ iShortLabelText.Set(
+ iFullLabelText.Right( aLabelText.Length() - find - 1 ) );
+ }
+
+ // Default to showing the long text.
+ // Won't leave since we've already set maximum buffer length.
+ TRAP_IGNORE( iLabel->SetTextL( iLongLabelText ) );
+ if ( IsReadyToDraw() )
+ {
+ TruncateLabelText();
+ }
+ }
+
+
+void CEikCbaButton::SetTextBitmapMode( TBool aEnableBitmap )
+ {
+ iUseTextBitmap = aEnableBitmap;
+ if ( iLabel )
+ {
+ iLabel->MakeVisible( !aEnableBitmap );
+ }
+ }
+
+void CEikCbaButton::DrawToContext( CBitmapContext& aContext, CBitmapContext& aMaskContext, const TPoint& aOffset ) const
+ {
+ if ( iLabel )
+ {
+ // Draw text into EColor16MA bitmap
+ aContext.SetOrigin( -aOffset );
+ iLabel->DrawToContext( aContext, NULL );
+
+ // Update mask
+ // The mask should have a black background and the text in white.
+ TRgb maskColor = KRgbWhite;
+ aMaskContext.SetOrigin( -aOffset );
+ iLabel->DrawToContext( aMaskContext, &maskColor );
+ }
+ }
+
+void CEikCbaButton::SwitchToShortTextL(TBool aShortText)
+ {
+ if (aShortText)
+ {
+ iLabel->SetTextL(iShortLabelText);
+ }
+ else
+ {
+ iLabel->SetTextL(iLongLabelText);
+ }
+
+ if (IsReadyToDraw())
+ {
+ TruncateLabelText();
+ }
+
+ if (!iDoImage)
+ {
+ iLabel->DrawDeferred();
+ }
+ else
+ {
+ iImage->DrawDeferred();
+ }
+ }
+
+void CEikCbaButton::SetLabelFont(const CFont* aLabelFont)
+ {
+ iLabel->SetFont(aLabelFont);
+ }
+
+void CEikCbaButton::TruncateLabelText()
+ {
+ // Truncation removed from here, as it was not bidi-text compatible.
+ // Let CEikLabel handle truncation instead.
+ iLabel->CropText();
+ }
+
+TBool CEikCbaButton::IsEmptyText() const
+ {
+ if ( iDoImage )
+ {
+ return EFalse;
+ }
+
+ TPtrC text( iFullLabelText );
+ TBool allSpaces = ETrue;
+
+ for ( TInt i = 0; i < text.Length(); ++i )
+ {
+ if ( !TChar(text[i]).IsSpace() )
+ {
+ allSpaces = EFalse;
+ break;
+ }
+ }
+
+ return allSpaces;
+ }
+
+void CEikCbaButton::ConstructEmptyButtonL()
+ {
+ ConstructL( EHRightVCenter ); // creates label
+ _LIT(KEmptyText, "");
+ TPtrC16 ptr(KEmptyText);
+ UpdateLabelText( ptr );
+ }
+
+TBool CEikCbaButton::PressedDown() const
+ {
+ return iPressedDown;
+ }
+
+void CEikCbaButton::SetPressedDown( const TBool aPressedDown )
+ {
+ iPressedDown = aPressedDown;
+ }
+
+// -----------------------------------------------------------------------------
+// EikSoftkeyImage::SetImage
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void EikSoftkeyImage::SetImage(
+ CEikButtonGroupContainer* aButtonGroupContainer,
+ CEikImage& aImage,
+ TBool aLeft)
+ { // static
+ TInt commandPos = aLeft ? 0 : 2;
+ TInt commandId = aButtonGroupContainer->ButtonGroup()->CommandId(commandPos);
+ CEikCbaButton* cbaButton = (CEikCbaButton*) aButtonGroupContainer->ControlOrNull(commandId);
+ if ( cbaButton )
+ {
+ cbaButton->SetImage(aImage);
+ // Draw button once with old size, as rect size is different with icon and text
+ cbaButton->DrawNow();
+
+ aButtonGroupContainer->SetRect(aButtonGroupContainer->Rect());
+ // Draw previosly set image
+ cbaButton->DrawNow();
+ aButtonGroupContainer->DrawNow();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// EikSoftkeyImage::SetLabel
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void EikSoftkeyImage::SetLabel(
+ CEikButtonGroupContainer* aButtonGroupContainer,
+ TBool aLeft)
+ { // static
+ TInt commandPos = aLeft ? 0 : 2;
+ TInt commandId = aButtonGroupContainer->ButtonGroup()->CommandId(commandPos);
+ CEikCbaButton* cbaButton = (CEikCbaButton*) aButtonGroupContainer->ControlOrNull(commandId);
+ if ( cbaButton )
+ {
+ cbaButton->ReplaceImageByLabel();
+ // Draw button once with old size, as rect size is different with icon and text
+ cbaButton->DrawNow();
+
+ TRect screenRect = iAvkonAppUi->ApplicationRect();
+ aButtonGroupContainer->SetBoundingRect(screenRect);
+ // Draw previosly set label
+ cbaButton->DrawNow();
+ aButtonGroupContainer->DrawNow();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CEikCbaButton::SetImage
+//
+// -----------------------------------------------------------------------------
+//
+void CEikCbaButton::SetImage(CEikImage &aImage)
+ {
+ iDoImage = ETrue;
+
+ if ( iImage )
+ {
+ iImage->SetMask( iMask );
+ }
+ delete iImage;
+ delete iSfeMask;
+ iSfeMask = NULL;
+ iImage = &aImage;
+ if ( iImage )
+ {
+ TRAP_IGNORE( PrepareImageL() );
+ }
+ else
+ {
+ ReplaceImageByLabel();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CEikCbaButton::PrepareImageL
+// Prepares Image for softkey feedback effect. Creates needed mask for
+// pressed down state.
+// -----------------------------------------------------------------------------
+//
+void CEikCbaButton::PrepareImageL()
+ {
+ // 50% transparent pressed down image is made with a alternative mask
+ // which is created when a image is set to CEikCbaButton.
+ // Original mask is copied and each of its pixels color components is
+ // halved. Bit-shifting to the right makes color value to half -->
+ // image looks 50% transparent with this mask
+ const CFbsBitmap* mask = iImage->Mask();
+ iMask = mask;
+
+ if ( !iMask )
+ {
+ return;
+ }
+
+ iSfeMask = new (ELeave) CFbsBitmap;
+ User::LeaveIfError( iSfeMask->Create( mask->SizeInPixels(), mask->DisplayMode() ) );
+
+ CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( iSfeMask );
+ CleanupStack::PushL( device );
+
+ CFbsBitGc* gc( NULL );
+ User::LeaveIfError( device->CreateContext( gc ) );
+
+ gc->SetPenStyle( CGraphicsContext::ESolidPen );
+ gc->BitBlt( TPoint(0,0), mask );
+
+ iSfeMask->LockHeap();
+ TInt w = iSfeMask->SizeInPixels().iWidth;
+ TInt h = iSfeMask->SizeInPixels().iHeight;
+ TInt dataStride = iSfeMask->DataStride() - w;
+ TUint8* address = (TUint8*) iSfeMask->DataAddress();
+
+ for ( TInt i = 0; i < h; ++i )
+ {
+ for ( TInt j = 0; j < w; j++ )
+ {
+ *address >>= 1;
+ ++address;
+ }
+ address += dataStride;
+ }
+
+ iSfeMask->UnlockHeap();
+ CleanupStack::PopAndDestroy( device ); // device
+
+ delete gc;
+ }
+// -----------------------------------------------------------------------------
+// CEikCbaButton::ReplaceImageByLabel
+//
+// -----------------------------------------------------------------------------
+//
+void CEikCbaButton::ReplaceImageByLabel()
+ {
+ iDoImage = EFalse;
+ if ( iImage )
+ {
+ // avoid mem leak.
+ iImage->SetMask( iMask );
+ delete iImage;
+ iImage = NULL;
+ delete iSfeMask;
+ iSfeMask = NULL;
+ }
+ }
+
+//
+// CEikEnhancedCbaButton
+//
+
+// -----------------------------------------------------------------------------
+// default constructor
+// -----------------------------------------------------------------------------
+CEikEnhancedCbaButton::CEikEnhancedCbaButton()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// default destructor
+// -----------------------------------------------------------------------------
+CEikEnhancedCbaButton::~CEikEnhancedCbaButton()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// Sets command type for current button
+// @param aCommandType Command type to be set
+// -----------------------------------------------------------------------------
+#ifdef RD_ENHANCED_CBA
+void CEikEnhancedCbaButton::SetCommandType( const TInt aCommandType )
+ {
+ iCommandType = aCommandType;
+ }
+#else
+void CEikEnhancedCbaButton::SetCommandType( const TInt /*aCommandType*/ )
+ {
+ }
+#endif // RD_ENHANCED_CBA
+// -----------------------------------------------------------------------------
+// returns command's type for current button
+// @return TInt command's type
+// -----------------------------------------------------------------------------
+
+TInt CEikEnhancedCbaButton::CommandType() const
+ {
+#ifdef RD_ENHANCED_CBA
+ return iCommandType;
+#else
+ return 0;
+#endif // RD_ENHANCED_CBA
+ }
+
+// -----------------------------------------------------------------------------
+// returns command id for current button
+// @return TInt command's id
+// -----------------------------------------------------------------------------
+TInt CEikEnhancedCbaButton::CommandId() const
+ {
+#ifdef RD_ENHANCED_CBA
+ return iCommandId;
+#else
+ return 0;
+#endif // RD_ENHANCED_CBA
+ }
+
+// -----------------------------------------------------------------------------
+// constructs button based on resource definition
+// @param aReader created resource reader for reading information from resource file
+// -----------------------------------------------------------------------------
+#ifdef RD_ENHANCED_CBA
+void CEikEnhancedCbaButton::ConstructFromResourceL(TResourceReader& aReader)
+ {
+ // Alignment set to right.
+ ConstructL( EHRightVCenter ); // creates label
+ iCommandType = aReader.ReadUint8();
+ iCommandId = aReader.ReadInt16();
+ // iFullLabelText.Copy( aReader.ReadTPtrC() );
+ UpdateLabelText( aReader.ReadTPtrC() );
+
+ aReader.ReadTPtrC(); // bmp filename
+ aReader.ReadInt16(); // bmp id
+ aReader.ReadInt16(); // bmp mask id
+ }
+#else
+void CEikEnhancedCbaButton::ConstructFromResourceL(TResourceReader&)
+ {
+ }
+#endif // RD_ENHANCED_CBA
+
+// -----------------------------------------------------------------------------
+// Constructs empty button with id EAknSoftkeyEmpty
+// -----------------------------------------------------------------------------
+void CEikEnhancedCbaButton::ConstructEmptyButtonL()
+ {
+#ifdef RD_ENHANCED_CBA
+ ConstructL( EHRightVCenter ); // creates label
+ iCommandType = EEikCommandTypeAnyCommand;
+ iCommandId = EAknSoftkeyEmpty;
+ _LIT(KEmptyText, "");
+ TPtrC16 ptr(KEmptyText);
+ UpdateLabelText( ptr );
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// Used to get the label's text for the button
+// @return TPtrC label text
+// -----------------------------------------------------------------------------
+TPtrC* CEikEnhancedCbaButton::LabelText()
+ {
+#ifdef RD_ENHANCED_CBA
+ return &iLongLabelText;
+#else
+ return NULL;
+#endif
+ }
+
+//
+// CEikCommandTable
+//
+
+CEikCommandTable* CEikCommandTable::NewL()
+ {
+#ifdef RD_ENHANCED_CBA
+ CEikCommandTable* self = CEikCommandTable::NewLC();
+ CleanupStack::Pop( self );
+ return self;
+#else
+ return NULL;
+#endif
+ }
+
+CEikCommandTable* CEikCommandTable::NewLC()
+ {
+#ifdef RD_ENHANCED_CBA
+ CEikCommandTable* self = new (ELeave) CEikCommandTable;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+#else
+ return NULL;
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// Construction for command table
+// priority configuration is read from the resource file
+// -----------------------------------------------------------------------------
+void CEikCommandTable::ConstructL()
+ {
+#ifdef RD_ENHANCED_CBA
+ // Get the cba priority configuration
+ TResourceReader reader;
+ CCoeEnv::Static()->CreateResourceReaderLC( reader, R_EIK_CBA_PRIORITIES );
+
+ // Amount of buttons (should match with KMaxButtonsInCommandTable).
+ TInt count = reader.ReadInt16();
+
+ __ASSERT_DEBUG( count == KMaxButtonsInCommandTable,
+ Panic(EEikPanicCBAButtonCountDiffersFromCommandTableSize) );
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ TInt priorities( reader.ReadInt16() ); // Amount of priorities for current button.
+ RArray<TInt> arr;
+ for ( TInt ii = 0; ii < priorities; ii++ )
+ {
+ TInt8 commandType( reader.ReadInt8() );
+ arr.Append( commandType );
+ }
+ iPriorities.Append( arr );
+ }
+
+ CleanupStack::PopAndDestroy(); // reader
+#endif
+ }
+
+#ifdef RD_ENHANCED_CBA
+CEikCommandTable::CEikCommandTable() : iPriorities(1)
+#else
+CEikCommandTable::CEikCommandTable()
+#endif // RD_ENHANCED_CBA
+ {
+ }
+
+
+CEikCommandTable::~CEikCommandTable()
+ {
+#ifdef RD_ENHANCED_CBA
+ iCommandButtons.Reset(); // Reset array
+ for(TInt i = 0; i < iPriorities.Count(); i++)
+ {
+ iPriorities[i].Reset();
+ }
+ iPriorities.Reset();
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// Used to add a command to CommandTable
+// @param aButton button to be added
+// -----------------------------------------------------------------------------
+#ifndef RD_ENHANCED_CBA
+TInt CEikCommandTable::AddCommandL(CEikEnhancedCbaButton* /*aButton*/)
+ {
+ return KErrNone;
+ }
+#else
+TInt CEikCommandTable::AddCommandL(CEikEnhancedCbaButton* aButton)
+ {
+ // CommandType tells in which button this command should be placed
+ TInt commandType( aButton->CommandType() );
+ TInt index( KErrNotFound );
+
+ // Find button and index for this button.
+ TInt button( 0 );
+ for ( button = 0; button < iPriorities.Count(); button++ )
+ {
+ index = iPriorities[button].Find( commandType );
+ if ( index != KErrNotFound )
+ {
+ CEikEnhancedCbaButton* existingButton = Command( button );
+ // If command placed on this index, check if new priority is lower.
+ if( existingButton )
+ {
+ TInt existingPriority = iPriorities[button].Find( existingButton->CommandType() );
+
+ // Delete existing command button if new command has higher priority (lower index).
+ if( index < existingPriority || existingPriority == KErrNotFound )
+ {
+ delete existingButton;
+ existingButton = NULL;
+ iCommandButtons[button] = aButton;
+ break;
+ }
+ }
+ else
+ {
+ iCommandButtons[button] = aButton;
+ break;
+ }
+ }
+ }
+
+ // Delete button if it's not placed.
+ if( button == iPriorities.Count() )
+ {
+ delete aButton;
+ aButton = NULL;
+ }
+ return KErrNone;
+ }
+#endif // RD_ENHANCED_CBA
+
+// -----------------------------------------------------------------------------
+// Used to check if CommandTable has a button with a certain id.
+// @param aCommandId Id to be checked.
+// -----------------------------------------------------------------------------
+#ifndef RD_ENHANCED_CBA
+TBool CEikCommandTable::IsCommandPlaced(const TInt /*aCommandId*/) const
+ {
+#else // !RD_ENHANCED_CBA
+TBool CEikCommandTable::IsCommandPlaced(const TInt aCommandId) const
+ {
+ TInt count( iCommandButtons.Count() );
+
+ for ( TInt i = 0; i < count; i++ )
+ {
+ if ( iCommandButtons[i] )
+ {
+ if ( iCommandButtons[i]->CommandId() == aCommandId )
+ {
+ return ETrue;
+ }
+ }
+ }
+#endif // RD_ENHANCED_CBA
+ return EFalse; // if no match for command id
+ }
+
+// -----------------------------------------------------------------------------
+// Used to replace command with a new command.
+// @param aCommandId Id for command that should be replaced.
+// @param aResourceId Id for new ENHANCED_CBA_BUTTON resource to be placed in the CommandTable.
+// -----------------------------------------------------------------------------
+#ifndef RD_ENHANCED_CBA
+void CEikCommandTable::ReplaceCommandL( const TInt /*aCommandId*/, const TInt /*aResourceId*/ )
+ {
+#else // !RD_ENHANCED_CBA
+void CEikCommandTable::ReplaceCommandL( const TInt aCommandId, const TInt aResourceId )
+ {
+ // If the command is not in the command table, return.
+ if( !IsCommandPlaced( aCommandId ) )
+ {
+ return;
+ }
+
+ TInt index( iCommandButtons.Count() );
+
+ CEikEnhancedCbaButton* oldButton = NULL;
+
+ for( TInt i = 0; i < index; i++ )
+ {
+ if( iCommandButtons[i] )
+ {
+ if( iCommandButtons[i]->CommandId() == aCommandId )
+ {
+ oldButton = iCommandButtons[i];
+ index = i;
+ break; // Index is the index of replacement.
+ }
+ }
+ }
+
+ CEikEnhancedCbaButton* button = new (ELeave) CEikEnhancedCbaButton;
+ button->SetTextBitmapMode( iExtension->iEnablePostingTransparency );
+ CleanupStack::PushL( button );
+ TResourceReader reader;
+ CCoeEnv::Static()->CreateResourceReaderLC( reader, aResourceId );
+
+ // Construct new button.
+ TUint8 version( (TUint8)reader.ReadUint8() ); // version
+ button->ConstructFromResourceL( reader );
+ CleanupStack::Pop( button );
+ CleanupStack::PopAndDestroy(); // reader
+
+ // Store new button to command table.
+ iCommandButtons[index] = button; // transfers ownership
+
+ // Delete old button.
+ delete oldButton;
+#endif // !RD_ENHANCED_CBA
+ }
+
+// -----------------------------------------------------------------------------
+// Used to get CEikEnhancedCbaButton for current control button (1-4).
+// @param aCommandIndex Index for requested button, use enum TCommandTableCbaPositions.
+// @return CEikCbaButton for current position, NULL if no button placed in that position.
+// -----------------------------------------------------------------------------
+#ifdef RD_ENHANCED_CBA
+CEikEnhancedCbaButton* CEikCommandTable::Command( const TInt aCommandIndex )
+ {
+ return iCommandButtons[aCommandIndex];
+ }
+#else // RD_ENHANCED_CBA
+CEikEnhancedCbaButton* CEikCommandTable::Command( const TInt /*aCommandIndex*/ )
+ {
+ return NULL;
+ }
+#endif // RD_ENHANCED_CBA
+
+// -----------------------------------------------------------------------------
+// Reset CommandTable
+// -----------------------------------------------------------------------------
+void CEikCommandTable::Reset()
+ {
+#ifdef RD_ENHANCED_CBA
+ iCommandButtons.Reset();
+#endif // RD_ENHANCED_CBA
+ }
+
+// -----------------------------------------------------------------------------
+// Sets command observer
+// -----------------------------------------------------------------------------
+EXPORT_C void AknCbaContentObserver::SetContentObserver(
+ CEikCba* aCba,
+ TCallBack aCallBack )
+ {
+ if ( aCba )
+ {
+ aCba->SetContentObserver( aCallBack );
+ }
+ }
+
+// End of file