/*
* Copyright (c) 2002-2010 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 <eikappui.h>
#include <eikapp.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"
#include "aknmarkingmode.h"
#include "akntrace.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)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return TAknWindowComponentLayout::Compose(aLine1, aLine2);
}
inline TAknTextComponentLayout DoComposeText(TAknWindowComponentLayout aLine1,
TAknTextComponentLayout aLine2)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
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()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
/**
* Checks if MSK-enabled layout is in use.
*/
static TBool IsMskEnabledLayoutActive()
{
_AKNTRACE_FUNC_ENTER;
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;
}
}
_AKNTRACE_FUNC_EXIT;
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 )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
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
ECbaMultipleMarkingActive, // multiple marking has changed RSK
ECbaCombinePaneUncovered // The combine pane in status pane is invisible.
};
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 )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
};
static CEikCbaExtension* NewL( CEikCba& aOwner )
{
_AKNTRACE_FUNC_ENTER;
CEikCbaExtension* self = new (ELeave) CEikCbaExtension( aOwner );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
_AKNTRACE_FUNC_EXIT;
return self;
}
void ConstructL()
{
_AKNTRACE_FUNC_ENTER;
// 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;
if ( iOwner.Flags().IsSet( ECbaSingleClickEnabled ) )
{
AknItemActionMenuRegister::RegisterCollectionObserverL(
*this );
}
_AKNTRACE_FUNC_EXIT;
}
~CEikCbaExtension()
{
_AKNTRACE_FUNC_ENTER;
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;
_AKNTRACE_FUNC_EXIT;
}
/** From base class MCenRepNotifyHandlerCallback */
void HandleNotifyInt( TUint32 /*aId*/, TInt aNewValue )
{
_AKNTRACE_FUNC_ENTER;
iWallpaperInUse = aNewValue;
iOwner.SetSkinBackgroundId( KAknsIIDNone );
_AKNTRACE_FUNC_EXIT;
}
void UpdateSoftkeyFrameL( TBool aForcedUpdate )
{
_AKNTRACE_FUNC_ENTER;
if ( !AknLayoutUtils::PenEnabled() )
{
_AKNTRACE_FUNC_EXIT;
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;
_AKNTRACE_FUNC_EXIT;
}
/**
* 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 )
{
_AKNTRACE_FUNC_ENTER;
// 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();
_AKNTRACE_FUNC_EXIT;
}
/**
* 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 )
{
_AKNTRACE_FUNC_ENTER;
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;
_AKNTRACE_FUNC_EXIT;
}
/**
* 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 )
{
_AKNTRACE_FUNC_ENTER;
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 );
_AKNTRACE_FUNC_EXIT;
}
/**
* Returns ETrue if the command cancels multiple marking and should not
* be forwarded to actual command observer.
*
* @return ETrue if multiple marking was cancelled.
*/
TBool CancelMultipleMarking( TInt aCommandId )
{
_AKNTRACE_FUNC_ENTER;
TBool cancelled( EFalse );
if ( aCommandId == EAknSoftkeyCancel
&& iItemActionMenu
&& iOwner.Flags().IsSet( ECbaMultipleMarkingActive ) )
{
iItemActionMenu->MarkingMode().SetCollectionMultipleMarkingState(
EFalse );
cancelled = ETrue;
}
_AKNTRACE_FUNC_EXIT;
return cancelled;
}
/**
* From MAknCollectionObserver.
* This method is used to set the item action menu to observer.
*
* @param aItemActionMenu Item action menu.
*/
void SetItemActionMenu( CAknItemActionMenu* aItemActionMenu )
{
_AKNTRACE_FUNC_ENTER;
iItemActionMenu = aItemActionMenu;
_AKNTRACE_FUNC_EXIT;
}
/**
* 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 )
{
_AKNTRACE_FUNC_ENTER;
// Do not update state if invisible collection tries to enable sk
if ( aCollectionVisible
|| iOwner.Flags().IsClear( ECbaItemSoftkeyDisabled ) )
{
iOwner.UpdateItemSpecificSoftkey();
}
iOwner.UpdateMultipleMarkingSoftkey();
_AKNTRACE_FUNC_EXIT;
}
/**
* From MAknCollectionObserver.
* This method returns ETrue if collection observer is active.
*
* @return ETrue if observer is active.
*/
TBool Active() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return iOwner.IsVisible() && !iOwner.IsEmpty();
}
/*
* Using the special theme Id draw background
*/
void DrawSemiTransparency( CWindowGc& aGc )
{
_AKNTRACE_FUNC_ENTER;
TAknsItemID SemiButtonID = KAknsIIDQgnFrSctrlSkButton;
TAknsItemID SemiButtonCenterID = KAknsIIDQgnFrSctrlSkButtonCenter;
TAknsItemID SemiButtonPressedID = KAknsIIDQgnFrSctrlSkButtonPressed;
TAknsItemID SemiButtonPressedCenterID = KAknsIIDQgnFrSctrlSkButtonCenterPressed;
CEikCbaButton* button1 = static_cast<CEikCbaButton*>
(iOwner.Control(KControlArrayCBAButton1Posn));
CEikCbaButton* button2 = static_cast<CEikCbaButton*>
(iOwner.Control(KControlArrayCBAButton2Posn));
if (IsMskEnabledLayoutActive())
{
CEikCbaButton* buttonMSK = static_cast<CEikCbaButton*>
(iOwner.Control(KControlArrayCBAButtonMSKPosn));
if (buttonMSK && buttonMSK->PressedDown())
{
AknsDrawUtils::DrawFrame(AknsUtils::SkinInstance(), aGc,
iMiddleFrameOuterRect,
iMiddleFrameInnerRect,
SemiButtonPressedID,
SemiButtonPressedCenterID);
}
else
{
AknsDrawUtils::DrawFrame(AknsUtils::SkinInstance(), aGc,
iMiddleFrameOuterRect,
iMiddleFrameInnerRect,
SemiButtonID,
SemiButtonCenterID);
}
}
if (button1 && button1->PressedDown())
{
AknsDrawUtils::DrawFrame(AknsUtils::SkinInstance(), aGc,
iLeftFrameOuterRect,
iLeftFrameInnerRect,
SemiButtonPressedID,
SemiButtonPressedCenterID);
}
else
{
AknsDrawUtils::DrawFrame(AknsUtils::SkinInstance(), aGc,
iLeftFrameOuterRect,
iLeftFrameInnerRect,
SemiButtonID,
SemiButtonCenterID);
}
if (button2 && button2->PressedDown())
{
AknsDrawUtils::DrawFrame(AknsUtils::SkinInstance(), aGc,
iRightFrameOuterRect,
iRightFrameInnerRect,
SemiButtonPressedID,
SemiButtonPressedCenterID);
}
else
{
AknsDrawUtils::DrawFrame(AknsUtils::SkinInstance(), aGc,
iRightFrameOuterRect,
iRightFrameInnerRect,
SemiButtonID,
SemiButtonCenterID);
}
_AKNTRACE_FUNC_EXIT;
}
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;
/**
* 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)
{
_AKNTRACE_FUNC_ENTER;
CEikCba* self = CEikCba::NewLC(aPrevious, aCommandObserver, aParentWg); // static
CleanupStack::Pop( self );
_AKNTRACE_FUNC_EXIT;
return self;
}
CEikCba* CEikCba::NewL(TInt aResourceId, const CEikCba* aPrevious,
MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg)
{
_AKNTRACE_FUNC_ENTER;
CEikCba* self = CEikCba::NewLC(aResourceId, aPrevious, aCommandObserver, aParentWg); // static
CleanupStack::Pop( self );
_AKNTRACE_FUNC_EXIT;
return self;
}
CEikCba* CEikCba::NewLC(const CEikCba* aPrevious, MEikCommandObserver* aCommandObserver,
RWindowGroup* aParentWg)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return CEikCba::NewLC(KNoResource, aPrevious, aCommandObserver, aParentWg); // static
}
CEikCba* CEikCba::NewLC(const CEikCba* aPrevious,
MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg,
TUint aFlags)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return CEikCba::NewLC(KNoResource, aPrevious, aCommandObserver,
aParentWg, aFlags);
}
CEikCba* CEikCba::NewLC(TInt aResourceId, const CEikCba* aPrevious,
MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg)
{
_AKNTRACE_FUNC_ENTER;
CEikCba* self = new(ELeave) CEikCba(aPrevious, aCommandObserver, aParentWg); // static
CleanupStack::PushL(self);
self->ConstructL(aResourceId);
AKNTASHOOK_ADDL( self, "CEikCba" );
_AKNTRACE_FUNC_EXIT;
return self;
}
CEikCba* CEikCba::NewLC(TInt aResourceId, const CEikCba* aPrevious,
MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg,
TUint aFlags)
{
_AKNTRACE_FUNC_ENTER;
CEikCba* self = new(ELeave) CEikCba(aPrevious, aCommandObserver,
aParentWg, aFlags);
CleanupStack::PushL(self);
self->ConstructL(aResourceId);
AKNTASHOOK_ADDL( self, "CEikCba" );
_AKNTRACE_FUNC_EXIT;
return self;
}
/**
* Destructor.
*/
CEikCba::~CEikCba()
{
_AKNTRACE_FUNC_ENTER;
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;
_AKNTRACE_FUNC_EXIT;
}
/**
* Constructor.
*/
CEikCba::CEikCba(const CEikCba* aPrevious,
MEikCommandObserver* aCommandObserver, RWindowGroup* aParentWg,
TUint aFlags)
: iLink(aPrevious), iCommandObserver(aCommandObserver), iParentWg(aParentWg)
{
_AKNTRACE_FUNC_ENTER;
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();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SetContainerWindowL( const CCoeControl& aContainer )
{
_AKNTRACE_FUNC_ENTER;
// 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 );
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::ActivateL()
{
_AKNTRACE_FUNC_ENTER;
CCoeControl::ActivateL();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::BaseConstructL()
{
_AKNTRACE_FUNC_ENTER;
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 );
// 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;
}
}
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::ConstructL(TInt aResourceId)
{
_AKNTRACE_FUNC_ENTER;
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();
}
}
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::ConstructFromResourceL(TResourceReader& aReader)
{
_AKNTRACE_FUNC_ENTER;
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();
}
}
_AKNTRACE_FUNC_EXIT;
}
TInt CEikCba::MaxCommands() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return KMaxSeries60Softkeys;
}
TInt CEikCba::MSKEnabledInPlatform() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return iMSKEnabledInPlatform;
}
// ---------------------------------------------------------------------------
// Sets the middle softkey icon.
// ---------------------------------------------------------------------------
//
void CEikCba::SetMSKIconL()
{
_AKNTRACE_FUNC_ENTER;
// MSK is not supported by dialog-embedded CBAs.
if ( iFlags.IsSet( ECbaInsideDialog ) || iFlags.IsSet( ECbaEmbedded ) )
{
_AKNTRACE_FUNC_EXIT;
return;
}
if ( !MskAllowed() )
{
_AKNTRACE_FUNC_EXIT;
return;
}
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
if ( !skin )
{
_AKNTRACE_FUNC_EXIT;
return;
}
if( iExtension->iIfMskIconSet )
{
// UpdateIconL();
_AKNTRACE_FUNC_EXIT;
return;
}
TEikGroupControl &gCtrl = iControlArray->At( KControlArrayCBAButtonMSKPosn );
CEikCbaButton *button = static_cast<CEikCbaButton*>( gCtrl.iControl );
if ( !button )
{
_AKNTRACE_FUNC_EXIT;
return;
}
CFbsBitmap *bitmap = NULL;
CFbsBitmap *mask = NULL;
TAknLayoutRect qgn_graf_sk_msk;
TRect rect;
TInt graphicMSKVariety = 1;
if ( iCbaFlags & EEikCbaFlagAppMskIcon )
{
graphicMSKVariety = 0 ;
}
qgn_graf_sk_msk.LayoutRect(
rect,
AknLayoutScalable_Avkon::control_pane_g4( graphicMSKVariety ).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 );
_AKNTRACE_FUNC_EXIT;
}
EXPORT_C TBool CEikCba::UpdateMSKIconL( const TAknsItemID& aId,
const TDesC& aBmpFile,
const TInt32 aBmp,
const TInt32 aBmpM,
TBool aEnable )
{
_AKNTRACE_FUNC_ENTER;
iExtension->iIfMskIconSet = EFalse;
// MSK is not supported by dialog-embedded CBAs.
if (!aEnable)
{
SetMSKIconL();
_AKNTRACE_FUNC_EXIT;
return ETrue;
}
delete iExtension->iBmpFile;
iExtension->iBmpFile = NULL;
iExtension->iBmpFile = aBmpFile.AllocL();
iExtension->iIfMskIconSet = ETrue;
iExtension->iMSKSkinID = aId;
iExtension->iBmp = aBmp;
iExtension->iBmpM = aBmpM;
_AKNTRACE_FUNC_EXIT;
return UpdateIconL();
}
// ----------------------------------------------------------------------------
// CEikCba::EnableItemSpecificSoftkey
// ----------------------------------------------------------------------------
//
EXPORT_C void CEikCba::EnableItemSpecificSoftkey( TBool aEnable )
{
_AKNTRACE_FUNC_ENTER;
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();
}
}
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SetMSKCommandObserver(MEikCommandObserver* aCommandObserver)
{
_AKNTRACE_FUNC_ENTER;
// aCommandObserver set to NULL when removing observer.
iMSKCommandObserver = aCommandObserver;
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::UpdateCbaLabels(TBool aScrollerOn)
{
_AKNTRACE_FUNC_ENTER;
// This method is called only from scrollbar that has nothing to do with
// dialog-embedded CBAs -> ignore the call.
if ( iFlags.IsSet( ECbaInsideDialog ) )
{
_AKNTRACE_FUNC_EXIT;
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() ;
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SetSBFrameObserver(MEikScrollBarObserver* aObserver)
{
_AKNTRACE_FUNC_ENTER;
if(iSBFrame)
{
iSBFrame->SetScrollBarFrameObserver(aObserver);
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SetScrollBarModelL(TEikScrollBarModel* aModel)
{
_AKNTRACE_FUNC_ENTER;
if(iSBFrame)
{
VScrollBarAsControl()->SetModelL(aModel);
}
_AKNTRACE_FUNC_EXIT;
}
const CEikCbaScrollBarFrame* CEikCba::ScrollBarFrame() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return STATIC_CAST(const CEikCbaScrollBarFrame*, iSBFrame);
}
CAknScrollBar* CEikCba::VScrollBarAsControl()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return STATIC_CAST(CAknScrollBar*, VScrollBarAsGroupControl().iControl);
}
void CEikCba::InsertControlL(TEikGroupControl& aGroupControl,TInt aIndex)
{
_AKNTRACE_FUNC_ENTER;
iControlArray->InsertL(aIndex,aGroupControl); // Takes ownership at this point.
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SetCommandL( TInt aPosition,
TInt aCommandId,
const TDesC* aText,
const CFbsBitmap* /*aBitmap*/,
const CFbsBitmap* /*aMask*/ )
{
_AKNTRACE_FUNC_ENTER;
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 );
}
ReportContentChangedEvent();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SetCommandL(TInt aPosition,TInt aResourceId)
{
_AKNTRACE_FUNC_ENTER;
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();
_AKNTRACE_FUNC_EXIT;
}
/**
* 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)
{
_AKNTRACE_FUNC_ENTER;
TResourceReader reader;
iCoeEnv->CreateResourceReaderLC(reader, aResourceId);
iCbaFlags = reader.ReadInt32();
if ( ( iCbaFlags & EEikEnhancedButtonGroup ) == EEikEnhancedButtonGroup )
{
CleanupStack::PopAndDestroy(); // reader
OfferCommandListL( aResourceId );
_AKNTRACE_FUNC_EXIT;
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();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::AddCommandL(TInt /*aPosition*/, TInt /*aCommandId*/, const TDesC* /*aText*/,
const CFbsBitmap* /*aBitmap*/, const CFbsBitmap* /*aMask*/)
{
_AKNTRACE_FUNC_ENTER;
User::Leave(KErrNotSupported);
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::AddCommandToStackWithoutSizeChangedL(TInt aPosition,
TInt aCommandId,
const TDesC* aText)
{
_AKNTRACE_FUNC_ENTER;
if ( !CommandChangeAllowed() )
{
_AKNTRACE_FUNC_EXIT;
return;
}
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.
ReportContentChangedEvent();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::AddCommandToStackL( TInt aPosition,
TInt aCommandId,
const TDesC* aText,
const CFbsBitmap* /*aBitmap*/,
const CFbsBitmap* /*aMask*/ )
{
_AKNTRACE_FUNC_ENTER;
AddCommandToStackWithoutSizeChangedL( aPosition, aCommandId, aText);
// Force labels to be re-formatted...
SizeChanged();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::AddCommandToStackL(TInt aPosition, TInt aResourceId)
{
_AKNTRACE_FUNC_ENTER;
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();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::AddCommandSetToStackL(TInt aResourceId)
{
_AKNTRACE_FUNC_ENTER;
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();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SetDefaultCommand(TInt /*aCommandId*/)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
TSize CEikCba::CalcMinimumSizeL(TInt /*aResourceId*/)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return MinimumSize();
}
void CEikCba::RemoveCommandFromStack( TInt aPosition, TInt aCommandId )
{
_AKNTRACE_FUNC_ENTER;
// 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() );
DrawDeferred();
ReportContentChangedEvent();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::RemovePreviousCommandWithoutSizeChanged(TInt aPosition)
{
_AKNTRACE_FUNC_ENTER;
TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
STATIC_CAST(CEikCbaButton*, groupCtrl.iControl)->RemovePreviousCommand();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::RemovePreviousCommand(TInt aPosition)
{
_AKNTRACE_FUNC_ENTER;
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();
_AKNTRACE_FUNC_EXIT;
}
TInt CEikCba::CommandPos(TInt aCommandId) const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return IndexById(aCommandId);
}
void CEikCba::DimCommand(TInt aCommandId,TBool aDimmed)
{
_AKNTRACE_FUNC_ENTER;
CCoeControl* control( ButtonById( aCommandId ) );
if ( control )
{
if ( SoftkeyStatusChangeAllowed( IndexById( aCommandId ), aDimmed ) )
{
control->SetDimmed( aDimmed );
}
}
_AKNTRACE_FUNC_EXIT;
}
TBool CEikCba::IsCommandDimmed(TInt aCommandId) const
{
_AKNTRACE_FUNC_ENTER;
if( ButtonById(aCommandId) )
{
_AKNTRACE_FUNC_EXIT;
return ButtonById(aCommandId)->IsDimmed();
}
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
void CEikCba::MakeCommandVisible(TInt aCommandId, TBool aVisible)
{
_AKNTRACE_FUNC_ENTER;
CCoeControl* control( ButtonById( aCommandId ) );
if ( control )
{
if ( SoftkeyStatusChangeAllowed( IndexById( aCommandId ), !aVisible ) )
{
control->MakeVisible( aVisible );
}
}
_AKNTRACE_FUNC_EXIT;
}
TBool CEikCba::IsCommandVisible(TInt aCommandId) const
{
_AKNTRACE_FUNC_ENTER;
if( ButtonById(aCommandId) )
{
_AKNTRACE_FUNC_EXIT;
return ButtonById(aCommandId)->IsVisible();
}
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
void CEikCba::AnimateCommand(TInt /*aCommandId*/)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// Sets the dimming status of a button with the specified position.
// ---------------------------------------------------------------------------
//
void CEikCba::DimCommandByPosition( TInt aPosition, TBool aDimmed )
{
_AKNTRACE_FUNC_ENTER;
if ( aPosition >= iControlArray->Count() )
{
_AKNTRACE_FUNC_EXIT;
return;
}
if ( SoftkeyStatusChangeAllowed( aPosition, aDimmed ) )
{
TEikGroupControl& groupCtrl = ( *iControlArray )[ aPosition ];
groupCtrl.iControl->SetDimmed( aDimmed );
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// Returns the dimming status of a button with the specified position.
// ---------------------------------------------------------------------------
//
TBool CEikCba::IsCommandDimmedByPosition( TInt aPosition ) const
{
_AKNTRACE_FUNC_ENTER;
if ( aPosition >= iControlArray->Count() )
{
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
_AKNTRACE_FUNC_EXIT;
return groupCtrl.iControl->IsDimmed();
}
// ---------------------------------------------------------------------------
// Sets the visibility of a button with the specified position.
// ---------------------------------------------------------------------------
//
void CEikCba::MakeCommandVisibleByPosition( TInt aPosition, TBool aVisible )
{
_AKNTRACE_FUNC_ENTER;
if ( aPosition >= iControlArray->Count() )
{
_AKNTRACE_FUNC_EXIT;
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();
}
}
_AKNTRACE_FUNC_EXIT;
}
TBool CEikCba::IsCommandVisibleByPosition(TInt aPosition) const
{
_AKNTRACE_FUNC_ENTER;
if (aPosition >= iControlArray->Count())
{
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
TEikGroupControl& groupCtrl = (*iControlArray)[aPosition];
if ( !iFlags.IsSet( ECbaInsideDialog ) )
{
_AKNTRACE_FUNC_EXIT;
return STATIC_CAST(CEikCbaButton*, groupCtrl.iControl)->IsVisible();
}
_AKNTRACE_FUNC_EXIT;
return !groupCtrl.iControl->IsDimmed();
}
void CEikCba::AnimateCommandByPosition(TInt /*aPosition*/)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
/*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 )
{
_AKNTRACE_FUNC_ENTER;
TRect rect( 0, 0, 0, 0 );
if ( aPosition >= iControlArray->Count() || aPosition < 0 )
{
_AKNTRACE_FUNC_EXIT;
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;
}
}
}
_AKNTRACE_FUNC_EXIT;
return rect;
}
CCoeControl* CEikCba::AsControl()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return this;
}
const CCoeControl* CEikCba::AsControl() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return this;
}
void CEikCba::SetBoundingRect( const TRect& /*aBoundingRect*/ )
{
_AKNTRACE_FUNC_ENTER;
if ( iFlags.IsSet( ECbaEmbedded ) )
{
_AKNTRACE_FUNC_EXIT;
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 ) )
{
_AKNTRACE_FUNC_EXIT;
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
TBool isLandscapeOrient = Layout_Meta_Data::IsLandscapeOrientation();
TInt bottomPaneVariety = 1;
if ( isLandscapeOrient )
{
bottomPaneVariety = 6;
}
// SetBoundingRect is always called by status pane when it is changing visibility.
// If the status pane is invisible in landscape, softkey need to draw frame to cover
// the area of combine pane.
CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current();
if (statusPane && !statusPane->IsVisible() && isLandscapeOrient &&
statusPane->PaneCapabilities(TUid::Uid(EEikStatusPaneUidCombined)).IsInCurrentLayout())
{
iFlags.Set( ECbaCombinePaneUncovered );
}
else
{
iFlags.Clear( ECbaCombinePaneUncovered );
}
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() );
// 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() )
{
if ( iBgIID == KAknsIIDQsnBgAreaControlMp )
{
if ( !iIsClockIndicBgIIDSet )
{
statusPane->SetCbaAreaBackgroundID(
iBgIID,
CEikStatusPaneBase::EDrawDeferred );
iIsClockIndicBgIIDSet = ETrue;
}
}
else
{
if ( statusPane->CbaAreaBackgroundID() != iBgIID )
{
statusPane->SetCbaAreaBackgroundID(
iBgIID,
CEikStatusPaneBase::EDrawDeferred );
}
}
if ( statusPane->PaneCapabilities(
TUid::Uid( EEikStatusPaneUidCombined ) ).IsInCurrentLayout() )
{
TRect combinedPaneRect( 0, 0, 0, 0 );
TRAPD( err,
combinedPaneRect =
statusPane->PaneRectL( TUid::Uid(
EEikStatusPaneUidCombined ) ) );
if ( !err )
{
TPoint cbaPositionRelativeToScreen( PositionRelativeToScreen() );
TRect cbaRectRelativeToScreen( cbaPositionRelativeToScreen, Size() );
if ( cbaRectRelativeToScreen.Intersects( combinedPaneRect ) )
{
combinedPaneRect.Move(
-cbaPositionRelativeToScreen.iX,
-cbaPositionRelativeToScreen.iY );
region.SubRect( combinedPaneRect );
}
}
}
else
{
TRect digitalClockRect( 0, 0, 0, 0 );
TRect indicatorRect( 0, 0, 0, 0 );
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();
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// Subtracts the area occupied by the button group from the specified
// bounding rectangle.
// ---------------------------------------------------------------------------
//
void CEikCba::ReduceRect( TRect& aBoundingRect ) const
{
_AKNTRACE_FUNC_ENTER;
// CBA inside Popup/Query Input does not reduce bounding rect
if ( iFlags.IsSet( ECbaEmbedded ) || iFlags.IsSet( ECbaInsideDialog ) )
{
_AKNTRACE_FUNC_EXIT;
return;
}
if ( !IsVisible() )
{
_AKNTRACE_FUNC_EXIT;
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();
}
}
}
_AKNTRACE_FUNC_EXIT;
}
CCoeControl* CEikCba::GroupControlById(TInt aCommandId)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return ButtonById(aCommandId);
}
CCoeControl* CEikCba::GroupControlById(TInt aCommandId) const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return ButtonById(aCommandId);
}
TInt CEikCba::CommandId(TInt aCommandPos) const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return (*iControlArray)[aCommandPos].iId;
}
TInt CEikCba::ButtonCount() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return (iControlArray->Count()-1); // -1 for scroll bar;
}
CEikCommandButton* CEikCba::GroupControlAsButton(TInt /*aCommandId*/) const
{
_AKNTRACE_FUNC_ENTER;
// 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
_AKNTRACE_FUNC_EXIT;
return NULL;
}
TUint CEikCba::ButtonGroupFlags() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return iCbaFlags ;
}
EXPORT_C void CEikCba::SetButtonGroupFlags(TInt aFlags)
{
_AKNTRACE_FUNC_ENTER;
iCbaFlags = aFlags;
//has not supported semi-transparent, ignore the flag at this moment.
//TODO: if the tranparent style CBA is approved and the new icon was delivered, open it again.
//steven yao
//iCbaFlags &= ~EEikCbaFlagSemiTransparent;
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;
}
UpdateFonts();
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// CEikCba::SetSkinBackgroundId
//
// -----------------------------------------------------------------------------
//
EXPORT_C void CEikCba::SetSkinBackgroundId( const TAknsItemID& aIID )
{
_AKNTRACE_FUNC_ENTER;
// Skin background is not drawn by embedded CBA.
if ( iFlags.IsSet( ECbaEmbedded ) )
{
iPopupVisible = ETrue;
_AKNTRACE_FUNC_EXIT;
return;
}
else
{
iPopupVisible = EFalse;
}
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 );
}
_AKNTRACE_FUNC_EXIT;
}
TKeyResponse CEikCba::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
_AKNTRACE_FUNC_ENTER;
if (aType != EEventKey)
{
_AKNTRACE_FUNC_EXIT;
return EKeyWasNotConsumed;
}
// Return immediately if the control is invisible.
if (!IsVisible() && !(iCbaFlags&EAknCBAFlagRespondWhenInvisible))
{
_AKNTRACE_FUNC_EXIT;
return EKeyWasNotConsumed;
}
TBool shiftControlPressed =
(aKeyEvent.iModifiers & EModifierShift) ||
(aKeyEvent.iModifiers & EModifierLeftShift) ||
(aKeyEvent.iModifiers & EModifierRightShift) ||
(aKeyEvent.iModifiers & EModifierCtrl) ||
(aKeyEvent.iModifiers & EModifierRightCtrl);
TKeyResponse response(EKeyWasNotConsumed);
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 );
}
// 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())
{
if( button1->IsDimmed() )
{
return EKeyWasConsumed;
}
// Return immediately if the button is invisible
if ( (*iControlArray)[KControlArrayCBAButton1Posn].iControl &&
!(*iControlArray)[KControlArrayCBAButton1Posn].iControl->IsVisible() &&
!(iCbaFlags & EAknCBAFlagRespondWhenInvisible) )
{
_AKNTRACE_FUNC_EXIT;
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)
{
_AKNTRACE_FUNC_EXIT;
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())
{
if( button2->IsDimmed() )
{
return EKeyWasConsumed;
}
// Return immediately if the button is invisible.
if ( (*iControlArray)[KControlArrayCBAButton2Posn].iControl &&
!(*iControlArray)[KControlArrayCBAButton2Posn].iControl->IsVisible() &&
!(iCbaFlags&EAknCBAFlagRespondWhenInvisible) )
{
_AKNTRACE_FUNC_EXIT;
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)
{
_AKNTRACE_FUNC_EXIT;
return EKeyWasNotConsumed;
}
if (aKeyEvent.iRepeats == 0 && shortCommand)
{
// Notify command observer only if multiple marking
// was not cancelled
if ( !iExtension || !iExtension->CancelMultipleMarking(
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( buttonMSK->IsDimmed() )
{
return EKeyWasConsumed;
}
if (KControlArrayCBAButtonMSKPosn < iControlArray->Count())
{
// Return immediately if the button is invisible.
if ( (*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl &&
!(*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl->IsVisible() &&
!(iCbaFlags&EAknCBAFlagRespondWhenInvisible) )
{
_AKNTRACE_FUNC_EXIT;
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)
{
_AKNTRACE_FUNC_EXIT;
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) )
{
_AKNTRACE_FUNC_EXIT;
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)
{
_AKNTRACE_FUNC_EXIT;
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;
}
}
_AKNTRACE_FUNC_EXIT;
return response;
}
EXPORT_C void* CEikCba::ExtensionInterface( TUid /*aInterface*/ )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
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 )
{
_AKNTRACE_FUNC_ENTER;
if ( !AknLayoutUtils::PenEnabled() )
{
_AKNTRACE_FUNC_EXIT;
return;
}
else if ( iFlags.IsSet( ECbaInsideDialog ) )
{
CCoeControl::HandlePointerEventL( aPointerEvent );
_AKNTRACE_FUNC_EXIT;
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->IsDimmed() )
{
CCoeControl::HandlePointerEventL( aPointerEvent );
return;
}
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->IsDimmed() )
{
CCoeControl::HandlePointerEventL( aPointerEvent );
return;
}
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->IsDimmed() )
{
CCoeControl::HandlePointerEventL( aPointerEvent );
return;
}
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() )
{
_AKNTRACE_FUNC_EXIT;
return;
}
// Send the button command to command observer.
TInt shortCommand = (*iControlArray)[i].iId;
if ( shortCommand &&
i == KControlArrayCBAButtonMSKPosn &&
iMSKCommandObserver )
{
iMSKCommandObserver->ProcessCommandL( shortCommand );
}
if( shortCommand )
{
// Notify command observer only if multiple marking
// was not cancelled
if ( !iExtension || !iExtension->CancelMultipleMarking(
shortCommand ) )
{
iCommandObserver->ProcessCommandL( shortCommand );
}
}
break;
}
}
}
}
_AKNTRACE_FUNC_EXIT;
}
TSize CEikCba::MinimumSize()
{
_AKNTRACE_FUNC_ENTER;
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);
}
_AKNTRACE_FUNC_EXIT;
// 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
{
_AKNTRACE_FUNC_ENTER;
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);
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// 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 )
{
_AKNTRACE_FUNC_ENTER;
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 ) )
{
_AKNTRACE_FUNC_EXIT;
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();
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() );
}
break;
}
default:
{
break;
}
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::DoSkinChange()
{
_AKNTRACE_FUNC_ENTER;
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);
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::DoColorChange()
{
_AKNTRACE_FUNC_ENTER;
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);
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::DoLayoutChange()
{
_AKNTRACE_FUNC_ENTER;
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 );
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::HandleScrollEventL(CEikScrollBar* /*aScrollBar*/, TEikScrollEvent /*aEventType*/)
{
_AKNTRACE_FUNC_ENTER;
User::Leave(KErrNotSupported);
_AKNTRACE_FUNC_EXIT;
}
TTypeUid::Ptr CEikCba::MopSupplyObject(TTypeUid aId)
{
_AKNTRACE_FUNC_ENTER;
if (aId.iUid == MAknsControlContext::ETypeId)
{
if ( AknLayoutFlags() & EAknLayoutCbaInControlPane ||
AknLayoutFlags() & EAknLayoutCbaInRightPane )
{
_AKNTRACE_FUNC_EXIT;
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.
_AKNTRACE_FUNC_EXIT;
return MAknsControlContext::SupplyMopObject( aId, iStaconBgContextTop );
}
}
if ( aId.iUid == CEikCba::ETypeId )
{
_AKNTRACE_FUNC_EXIT;
return aId.MakePtr( this );
}
_AKNTRACE_FUNC_EXIT;
return CEikControlGroup::MopSupplyObject(aId);
}
void CEikCba::Draw( const TRect& aRect ) const
{
_AKNTRACE_FUNC_ENTER;
// Embedded CBA doesn't draw anything
if ( iFlags.IsSet( ECbaInsideDialog ) )
{
return;
}
if ( iCbaFlags & EEikCbaFlagSemiTransparent )
{
CWindowGc &gc = SystemGc();
iExtension->DrawSemiTransparency( gc );
return;
}
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
const TRect rect( Rect() );
CWindowGc& gc = SystemGc();
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 ) )
{// 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() || iFlags.IsSet( ECbaCombinePaneUncovered ) )
{
CEikCbaButton* buttonMSK = static_cast<CEikCbaButton*>(
(*iControlArray)[KControlArrayCBAButtonMSKPosn].iControl );
CFbsBitmap* middleMask =
AknsUtils::GetCachedBitmap( skin, KAknsIIDQgnIndiSctrlSkMaskMiddlePrt );
if ( middleMask )
{
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) )
{
// 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
{
// 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 );
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// Gets a button control by the specified command ID.
// ---------------------------------------------------------------------------
//
CCoeControl* CEikCba::ButtonById( TInt aCommandId ) const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return ControlById( aCommandId );
}
// ---------------------------------------------------------------------------
// Creates the scroll bar frame & sets up the scroll bar.
// ---------------------------------------------------------------------------
//
void CEikCba::CreateScrollBarFrameL()
{
_AKNTRACE_FUNC_ENTER;
if ( !iSBFrame )
{
iSBFrame = new (ELeave) CEikCbaScrollBarFrame( this, this, ETrue );
}
iSBFrame->ConstructL();
_AKNTRACE_FUNC_EXIT;
}
TEikGroupControl CEikCba::VScrollBarAsGroupControl()
{
_AKNTRACE_FUNC_ENTER;
// Extracts vertical scroll bar from the scroll bar frame.
TEikGroupControl groupCtrl(iSBFrame->VerticalScrollBar(), 0,
KCbaScrollBarButtonWidth,TEikGroupControl::ESetLength);
_AKNTRACE_FUNC_EXIT;
return groupCtrl;
}
void CEikCba::InsertScrollBarL()
{
_AKNTRACE_FUNC_ENTER;
TEikGroupControl SBGroupCtrl = VScrollBarAsGroupControl();
// Insert vertical scroll bar into cba control group.
InsertControlL(SBGroupCtrl, KControlArrayScrollBarPosn);
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// Replaces empty scroll bar with actual arrow head scroll bar.
// ---------------------------------------------------------------------------
//
void CEikCba::CreateArrowHeadScrollBarL()
{
_AKNTRACE_FUNC_ENTER;
if ( iSBFrame )
{
iSBFrame->SwitchToArrowHeadScrollBarL();
iSBFrame->VerticalScrollBar()->SetContainingCba( this );
if ( iControlArray->Count() > KControlArrayScrollBarPosn )
{
iControlArray->Delete( KControlArrayScrollBarPosn );
}
InsertScrollBarL();
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SizeChanged()
{
_AKNTRACE_FUNC_ENTER;
if ( iFlags.IsSet( ECbaInsideDialog ) )
{
Window().SetNonFading( EFalse );
SizeChangedInsideDialog();
_AKNTRACE_FUNC_EXIT;
return;
}
else if ( iFlags.IsSet( ECbaEmbedded ) )
{
Window().SetNonFading( EFalse );
SizeChangedInPopup();
_AKNTRACE_FUNC_EXIT;
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 );
}
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// CEikCba::CheckSkinAndUpdateContext
//
// -----------------------------------------------------------------------------
//
void CEikCba::CheckSkinAndUpdateContext()
{
_AKNTRACE_FUNC_ENTER;
if (AknsUtils::SkinInstance())
{
// Use ENullBrush if there is skin background available.
iBrushAndPenContext->SetBrushStyle(CGraphicsContext::ENullBrush);
}
else
{
iBrushAndPenContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::Reserved_MtsmPosition()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::Reserved_MtsmObject()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
TInt CEikCba::AknLayoutFlags() const
{
_AKNTRACE_FUNC_ENTER;
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;
}
_AKNTRACE_FUNC_EXIT;
return flags;
}
// ---------------------------------------------------------------------------
// Handles size change events in bottom softkey layout.
// ---------------------------------------------------------------------------
//
void CEikCba::SizeChangedInControlPane()
{
_AKNTRACE_FUNC_ENTER;
TRect screen;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen );
TBool isLandscape( Layout_Meta_Data::IsLandscapeOrientation() );
TInt spLayout( AknStatuspaneUtils::CurrentStatusPaneLayoutResId() );
// Treat the empty status pane layout the same way as the flat layout
// in landscape orientation, as the CBA layout is the same in both.
TBool flatLscLayout(
isLandscape &&
( spLayout == R_AVKON_STATUS_PANE_LAYOUT_USUAL_FLAT ||
spLayout == R_AVKON_STATUS_PANE_LAYOUT_IDLE_FLAT ||
spLayout == R_AVKON_WIDESCREEN_PANE_LAYOUT_USUAL_FLAT ||
spLayout == R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT ||
spLayout == R_AVKON_WIDESCREEN_PANE_LAYOUT_USUAL_FLAT_NO_SOFTKEYS ||
spLayout == R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT_NO_SOFTKEYS ||
spLayout == R_AVKON_STATUS_PANE_LAYOUT_EMPTY ) );
// We must check for landscape mode bottom softkeys.
TInt bottomPaneVariety = isLandscape ? ( flatLscLayout ? 2 : 6 ) : 1;
// Skip application_window between screen and area_bottom_pane since
// screen and application_window are always the same.
TAknWindowComponentLayout controlPane(
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 || ( isLandscape && iFlags.IsSet( ECbaCombinePaneUncovered ) ) )
{
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 ) )
{
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 = 1;
if ( iCbaFlags & EEikCbaFlagAppMskIcon )
{
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 );
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 );
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SizeChangedInStaconPane()
{
_AKNTRACE_FUNC_ENTER;
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) );
_AKNTRACE_FUNC_EXIT;
}
//------------------------------------------------------------------------------
// CEikCba::SizeChangedInRightPane()
//------------------------------------------------------------------------------
//
void CEikCba::SizeChangedInRightPane()
{
_AKNTRACE_FUNC_ENTER;
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 ) );
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SizeChangedInsideDialog()
{
_AKNTRACE_FUNC_ENTER;
// 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 );
}
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::SizeChangedInPopup()
{
_AKNTRACE_FUNC_ENTER;
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();
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() );
}
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::UpdateFonts()
{
_AKNTRACE_FUNC_ENTER;
// 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 && iExtension->iEnablePostingTransparency ) ||
( iCbaFlags & EEikCbaFlagTransparent ) )
{
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 );
_AKNTRACE_FUNC_EXIT;
}
// 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)
{
_AKNTRACE_FUNC_ENTER;
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
_AKNTRACE_FUNC_EXIT;
}
#else // !RD_ENHANCED_CBA
EXPORT_C void CEikCba::OfferCommandListL(const RArray<TInt>& /*aCommandList*/)
{
_AKNTRACE_FUNC_ENTER;
User::Leave( KErrNotSupported );
_AKNTRACE_FUNC_EXIT;
}
#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)
{
_AKNTRACE_FUNC_ENTER;
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
_AKNTRACE_FUNC_EXIT;
}
#else // !RD_ENHANCED_CBA
EXPORT_C void CEikCba::OfferCommandListL(const TInt /*aResourceId*/)
{
_AKNTRACE_FUNC_ENTER;
User::Leave( KErrNotSupported );
_AKNTRACE_FUNC_EXIT;
}
#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
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return ButtonById(aCommandId) ? ETrue : EFalse; // check the iControlArray
}
#else // !RD_ENHANCED_CBA
EXPORT_C TBool CEikCba::IsCommandInGroup(const TInt /*aCommandId*/) const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
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)
{
_AKNTRACE_FUNC_ENTER;
TInt index = IndexById( aReplaceCommandId );
TRAPD(err, SetCommandL( index, aResourceId ) );
_AKNTRACE_FUNC_EXIT;
}
#else
EXPORT_C void CEikCba::ReplaceCommand(const TInt /*aReplaceCommandId*/, const TInt /*aResourceId*/)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
#endif // RD_ENHANCED_CBA
void CEikCba::HandleControlEventL( CCoeControl* aControl, TCoeEvent aEventType )
{
_AKNTRACE_FUNC_ENTER;
if ( !iFlags.IsSet( ECbaInsideDialog ) )
{
//User::Panic( _L( "CBA inside dialog" ), KErrNotSupported );
_AKNTRACE_FUNC_EXIT;
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 );
}
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::MakeVisible( TBool aVisible )
{
_AKNTRACE_FUNC_ENTER;
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();
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// Sets layer images and rects.
// @since 5.0
// -----------------------------------------------------------------------------
void CEikCba::DoSetLayers( const TAknsItemID& aIID )
{
_AKNTRACE_FUNC_ENTER;
// Skin background is not drawn by embedded CBA.
if ( iFlags.IsSet( ECbaEmbedded ) )
{
_AKNTRACE_FUNC_EXIT;
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();
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::LayoutControl( CCoeControl* aControl, const TRect& aRect )
{
_AKNTRACE_FUNC_ENTER;
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 );
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCba::BroadcastPostingTransparency( TBool aEnable )
{
_AKNTRACE_FUNC_ENTER;
// 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 );
}
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// CEikCba::UpdateLabels
// Updates softkey labels in case of embedded softkeys.
// ---------------------------------------------------------------------------
//
void CEikCba::UpdateLabels( TBool aDrawDeferred )
{
_AKNTRACE_FUNC_ENTER;
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();
}
}
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// EikSoftkeyPostingTransparency::MakeTransparent
// -----------------------------------------------------------------------------
//
EXPORT_C TInt EikSoftkeyPostingTransparency::MakeTransparent(
CEikButtonGroupContainer& aButtonGroupContainer,
TBool aEnable )
{
_AKNTRACE_FUNC_ENTER;
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 );
}
}
_AKNTRACE_FUNC_EXIT;
return ret;
}
// -----------------------------------------------------------------------------
// CEikCba::EnablePostingTransparency
//
// -----------------------------------------------------------------------------
//
void CEikCba::EnablePostingTransparency( TBool aEnable )
{
_AKNTRACE_FUNC_ENTER;
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();
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// CEikCba::IsEmpty
// Checks if the CBA has no commands.
// ---------------------------------------------------------------------------
//
EXPORT_C TBool CEikCba::IsEmpty() const
{
_AKNTRACE_FUNC_ENTER;
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;
}
}
}
}
}
_AKNTRACE_FUNC_EXIT;
return isEmpty;
}
// ---------------------------------------------------------------------------
// CEikCba::Flags
// Returns flags.
// ---------------------------------------------------------------------------
//
TBitFlags CEikCba::Flags()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return iFlags;
}
// ---------------------------------------------------------------------------
// CEikCba::SetContentObserver
// Sets content observer.
// ---------------------------------------------------------------------------
//
void CEikCba::SetContentObserver( TCallBack aCallBack )
{
_AKNTRACE_FUNC_ENTER;
if ( iExtension )
{
iExtension->iContentObserver = aCallBack;
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// CEikCba::ReportContentChangedEvent
// Reports state changed event if cba changed from empty to non-empty
// or vice versa.
// ---------------------------------------------------------------------------
//
void CEikCba::ReportContentChangedEvent()
{
_AKNTRACE_FUNC_ENTER;
if ( ItemSpecificSoftkey() )
{
UpdateItemSpecificSoftkey(
iExtension->Active() && !Window().IsFaded() );
}
if ( !iFlags.IsSet( ECbaEmbedded ) )
{
_AKNTRACE_FUNC_EXIT;
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
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// CEikCba::DrawEmbeddedSoftkey
// Draws embedded softkey
// ---------------------------------------------------------------------------
//
void CEikCba::DrawEmbeddedSoftkey( TEikGroupControl& aGroupControl,
const TRect& aRect,
CWindowGc& aGc,
CFbsBitmap* /*aMask*/ ) const
{
_AKNTRACE_FUNC_ENTER;
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);
}
_AKNTRACE_FUNC_EXIT;
}
TBool CEikCba::UpdateIconL()
{
_AKNTRACE_FUNC_ENTER;
if ( iFlags.IsSet( ECbaInsideDialog ) )
{
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
if ( !iExtension->iIfMskIconSet ||
!MskAllowed() )
{
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
if ( !skin )
{
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
TEikGroupControl &gCtrl = iControlArray->At( KControlArrayCBAButtonMSKPosn );
CEikCbaButton *button = static_cast<CEikCbaButton*>( gCtrl.iControl );
if ( !button )
{
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
CFbsBitmap *bitmap = NULL;
CFbsBitmap *mask = NULL;
TInt graphicMSKVariety = 1;
if ( iCbaFlags & EEikCbaFlagAppMskIcon )
{
graphicMSKVariety = 0 ;
}
TAknLayoutRect qgn_graf_sk_msk;
TRect rect;
qgn_graf_sk_msk.LayoutRect(
rect,
AknLayoutScalable_Avkon::control_pane_g4( graphicMSKVariety ).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 );
_AKNTRACE_FUNC_EXIT;
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
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return ( iMSKEnabledInPlatform &&
AknLayoutUtils::MSKEnabled() &&
IsMskEnabledLayoutActive() );
}
// ---------------------------------------------------------------------------
// CEikCba::SoftkeyStatusChangeAllowed
// Returns ETrue if softkey status change is allowed.
// ---------------------------------------------------------------------------
//
TBool CEikCba::SoftkeyStatusChangeAllowed(
TInt aSoftkeyPosition, TBool aDisabled )
{
_AKNTRACE_FUNC_ENTER;
TBool allowChange( ETrue );
if ( aSoftkeyPosition == KControlArrayCBAButton1Posn )
{
if ( aDisabled )
{
iFlags.Set( ECbaItemSoftkeyDisabledByClient );
}
else
{
iFlags.Clear( ECbaItemSoftkeyDisabledByClient );
if ( iFlags.IsSet( ECbaItemSoftkeyDisabled ) &&
iFlags.IsSet( ECbaItemSpecificSoftkeyInUse ) )
{
allowChange = EFalse;
}
}
}
_AKNTRACE_FUNC_EXIT;
return allowChange;
}
// ---------------------------------------------------------------------------
// CEikCba::ItemSpecificSoftkey
// Returns item specific softkey control if it state should be updated.
// ---------------------------------------------------------------------------
//
TEikGroupControl* CEikCba::ItemSpecificSoftkey() const
{
_AKNTRACE_FUNC_ENTER;
TEikGroupControl* lsk( NULL );
if ( iFlags.IsSet( ECbaItemSpecificSoftkeyInUse ) )
{
TEikGroupControl& leftSoftkey =
( *iControlArray ) [ KControlArrayCBAButton1Posn ];
if ( leftSoftkey.iId != EAknSoftkeyOptions
|| iFlags.IsSet( ECbaItemSoftkeyDisabled ) )
{
lsk = &leftSoftkey;
}
}
_AKNTRACE_FUNC_EXIT;
return lsk;
}
// ---------------------------------------------------------------------------
// CEikCba::UpdateItemSpecificSoftkey
// Updates item specific softkey.
// ---------------------------------------------------------------------------
//
void CEikCba::UpdateItemSpecificSoftkey( TBool aVisibleCollection )
{
_AKNTRACE_FUNC_ENTER;
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 );
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// CEikCba::UpdateItemSpecificSoftkey
// Updates item specific softkey.
// ---------------------------------------------------------------------------
//
void CEikCba::UpdateItemSpecificSoftkey( CCoeControl& aControl, TBool aEnable )
{
_AKNTRACE_FUNC_ENTER;
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();
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// CEikCba::UpdateMultipleMarkingSoftkey
// Updates RSK when multiple marking is activated or deactivated.
// ---------------------------------------------------------------------------
//
void CEikCba::UpdateMultipleMarkingSoftkey()
{
_AKNTRACE_FUNC_ENTER;
if ( iFlags.IsSet( ECbaSingleClickEnabled )
&& iExtension && iExtension->iItemActionMenu )
{
TBool markingActive(
iExtension->iItemActionMenu->MarkingMode(
).MultipleMarkingActive() );
TBool markingActivated( iFlags.IsSet( ECbaMultipleMarkingActive ) );
if ( markingActive && !markingActivated )
{
TRAPD( error,
AddCommandSetToStackL( R_AVKON_SOFTKEYS_OPTIONS_CANCEL ) );
if ( error == KErrNone )
{
iFlags.Set( ECbaMultipleMarkingActive );
}
}
else if ( !markingActive && markingActivated )
{
RemoveCommandFromStack(
KControlArrayCBAButton1Posn, EAknSoftkeyOptions );
RemoveCommandFromStack(
KControlArrayCBAButton2Posn, EAknSoftkeyCancel );
iFlags.Clear( ECbaMultipleMarkingActive );
}
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// CEikCba::CommandChangeAllowed
// ---------------------------------------------------------------------------
//
TBool CEikCba::CommandChangeAllowed() const
{
return ( !( iFlags.IsSet( ECbaSingleClickEnabled )
&& iFlags.IsSet( ECbaMultipleMarkingActive ) ) );
}
//
// class CEikCbaButton
//
CEikCbaButton::~CEikCbaButton()
{
_AKNTRACE_FUNC_ENTER;
AKNTASHOOK_REMOVE();
delete iLabel;
if ( iImage )
{
iImage->SetMask( iMask );
}
delete iImage;
delete iSfeMask;
delete iButtonOptions;
delete iText;
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::ConstructL(TGulAlignmentValue aAlignment)
{
_AKNTRACE_FUNC_ENTER;
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" );
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::AddCommandL(const TDesC& aText)
{
_AKNTRACE_FUNC_ENTER;
UpdateLabelText(aText);
_AKNTRACE_FUNC_EXIT;
}
struct STempCleanup
{
CDesCArray* iText;
CArrayFix<CEikCbaButton::SButtonOptions>* iButtonOptions;
};
LOCAL_C void CleanupTemp(TAny* aPtr)
{
_AKNTRACE_FUNC_ENTER;
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);
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::PushCommandL(TInt aCommandId,const TDesC& aText)
{
_AKNTRACE_FUNC_ENTER;
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
_AKNTRACE_FUNC_EXIT;
}
TInt CEikCbaButton::PopCommand()
{
_AKNTRACE_FUNC_ENTER;
if (!iButtonOptions)
{
_AKNTRACE_FUNC_EXIT;
return -1;
}
TInt count = iButtonOptions->Count();
--count;
if (count < 0)
{
_AKNTRACE_FUNC_EXIT;
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();
}
_AKNTRACE_FUNC_EXIT;
return buttonOptions.iCommandId;
}
void CEikCbaButton::RemoveCommand(TInt aCommandId)
{
_AKNTRACE_FUNC_ENTER;
if (!iButtonOptions)
{
_AKNTRACE_FUNC_EXIT;
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;
}
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::RemovePreviousCommand()
{
_AKNTRACE_FUNC_ENTER;
if (!iButtonOptions)
{
_AKNTRACE_FUNC_EXIT;
return;
}
TInt index = iButtonOptions->Count() - 2;
if (index >= 0)
{
iButtonOptions->Delete(index);
iText->Delete(index);
}
_AKNTRACE_FUNC_EXIT;
}
TInt CEikCbaButton::IndexFromCommandId(TInt aCommandId)
{
_AKNTRACE_FUNC_ENTER;
TInt index;
TKeyArrayFix key(0, ECmpTInt);
SButtonOptions options;
options.iCommandId = aCommandId;
if (iButtonOptions->Find(options, key, index) == KErrNone)
{
_AKNTRACE_FUNC_EXIT;
return index;
}
else
{
_AKNTRACE_FUNC_EXIT;
return KErrNotFound;
}
}
void CEikCbaButton::SetContainerWindowL(const CCoeControl& aContainer)
{
_AKNTRACE_FUNC_ENTER;
CCoeControl::SetContainerWindowL(aContainer);
if (!iDoImage)
{
iLabel->SetContainerWindowL(aContainer);
}
else
{
iImage->SetContainerWindowL(aContainer);
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::ConstructFromResourceL(TResourceReader& aReader, TGulAlignmentValue anAlignment)
{
_AKNTRACE_FUNC_ENTER;
ConstructL(anAlignment);
UpdateLabelText(aReader.ReadTPtrC());
aReader.ReadTPtrC(); // bmp filename
aReader.ReadInt16(); // bmp id
aReader.ReadInt16(); // bmp mask id
_AKNTRACE_FUNC_EXIT;
}
TSize CEikCbaButton::MinimumSize()
{
_AKNTRACE_FUNC_ENTER;
if (!iDoImage)
{
_AKNTRACE_FUNC_EXIT;
return iLabel->MinimumSize();
}
else
{
_AKNTRACE_FUNC_EXIT;
return iImage->MinimumSize();
}
}
TInt CEikCbaButton::CountComponentControls() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return 1;
}
CCoeControl* CEikCbaButton::ComponentControl(TInt aIndex) const
{
_AKNTRACE_FUNC_ENTER;
if (aIndex==0)
{
if (!iDoImage)
{
_AKNTRACE_FUNC_EXIT;
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;
}
}
_AKNTRACE_FUNC_EXIT;
return 0;
}
// ---------------------------------------------------------------------------
// Handles size change events for CBA button.
// ---------------------------------------------------------------------------
//
void CEikCbaButton::SizeChanged()
{
_AKNTRACE_FUNC_ENTER;
// Resizing is done at CEikCba::SizeChanged().
// We cannot resize here because this control has wrong
// coordinate system available.
_AKNTRACE_FUNC_EXIT;
}
EXPORT_C void CEikCbaButton::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
_AKNTRACE_FUNC_ENTER;
CCoeControl::HandlePointerEventL(aPointerEvent);
_AKNTRACE_FUNC_EXIT;
}
EXPORT_C void* CEikCbaButton::ExtensionInterface( TUid /*aInterface*/ )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return NULL;
}
void CEikCbaButton::SetDimmed(TBool aDimmed)
{
_AKNTRACE_FUNC_ENTER;
CCoeControl::SetDimmed(aDimmed);
if (!iDoImage)
{
iLabel->SetDimmed(aDimmed);
}
else
{
// Drawing dimmed CEikImages don't work (problem in uiklaf).
//iImage->SetDimmed(aDimmed);
}
_AKNTRACE_FUNC_EXIT;
}
// ---------------------------------------------------------------------------
// Updates the softkey label.
// ---------------------------------------------------------------------------
//
void CEikCbaButton::UpdateLabelText( TPtrC aLabelText )
{
_AKNTRACE_FUNC_ENTER;
// 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();
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::SetTextBitmapMode( TBool aEnableBitmap )
{
_AKNTRACE_FUNC_ENTER;
iUseTextBitmap = aEnableBitmap;
if ( iLabel )
{
iLabel->MakeVisible( !aEnableBitmap );
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::DrawToContext( CBitmapContext& aContext, CBitmapContext& aMaskContext, const TPoint& aOffset ) const
{
_AKNTRACE_FUNC_ENTER;
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 );
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::SwitchToShortTextL(TBool aShortText)
{
_AKNTRACE_FUNC_ENTER;
if (aShortText)
{
iLabel->SetTextL(iShortLabelText);
}
else
{
iLabel->SetTextL(iLongLabelText);
}
if (IsReadyToDraw())
{
TruncateLabelText();
}
if (!iDoImage)
{
iLabel->DrawDeferred();
}
else
{
iImage->DrawDeferred();
}
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::SetLabelFont(const CFont* aLabelFont)
{
_AKNTRACE_FUNC_ENTER;
iLabel->SetFont(aLabelFont);
_AKNTRACE_FUNC_EXIT;
}
void CEikCbaButton::TruncateLabelText()
{
_AKNTRACE_FUNC_ENTER;
// Truncation removed from here, as it was not bidi-text compatible.
// Let CEikLabel handle truncation instead.
iLabel->CropText();
_AKNTRACE_FUNC_EXIT;
}
TBool CEikCbaButton::IsEmptyText() const
{
_AKNTRACE_FUNC_ENTER;
if ( iDoImage )
{
_AKNTRACE_FUNC_EXIT;
return EFalse;
}
TPtrC text( iFullLabelText );
TBool allSpaces = ETrue;
for ( TInt i = 0; i < text.Length(); ++i )
{
if ( !TChar(text[i]).IsSpace() )
{
allSpaces = EFalse;
break;
}
}
_AKNTRACE_FUNC_EXIT;
return allSpaces;
}
void CEikCbaButton::ConstructEmptyButtonL()
{
_AKNTRACE_FUNC_ENTER;
ConstructL( EHRightVCenter ); // creates label
_LIT(KEmptyText, "");
TPtrC16 ptr(KEmptyText);
UpdateLabelText( ptr );
_AKNTRACE_FUNC_EXIT;
}
TBool CEikCbaButton::PressedDown() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return iPressedDown;
}
void CEikCbaButton::SetPressedDown( const TBool aPressedDown )
{
_AKNTRACE_FUNC_ENTER;
iPressedDown = aPressedDown;
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// EikSoftkeyImage::SetImage
//
// -----------------------------------------------------------------------------
//
EXPORT_C void EikSoftkeyImage::SetImage(
CEikButtonGroupContainer* aButtonGroupContainer,
CEikImage& aImage,
TBool aLeft)
{ // static
_AKNTRACE_FUNC_ENTER;
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();
}
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// EikSoftkeyImage::SetLabel
//
// -----------------------------------------------------------------------------
//
EXPORT_C void EikSoftkeyImage::SetLabel(
CEikButtonGroupContainer* aButtonGroupContainer,
TBool aLeft)
{ // static
_AKNTRACE_FUNC_ENTER;
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();
}
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// CEikCbaButton::SetImage
//
// -----------------------------------------------------------------------------
//
void CEikCbaButton::SetImage(CEikImage &aImage)
{
_AKNTRACE_FUNC_ENTER;
iDoImage = ETrue;
if ( iImage )
{
iImage->SetMask( iMask );
}
delete iImage;
delete iSfeMask;
iSfeMask = NULL;
iImage = &aImage;
if ( iImage )
{
TRAP_IGNORE( PrepareImageL() );
}
else
{
ReplaceImageByLabel();
}
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// CEikCbaButton::PrepareImageL
// Prepares Image for softkey feedback effect. Creates needed mask for
// pressed down state.
// -----------------------------------------------------------------------------
//
void CEikCbaButton::PrepareImageL()
{
_AKNTRACE_FUNC_ENTER;
// 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 )
{
_AKNTRACE_FUNC_EXIT;
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;
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// CEikCbaButton::ReplaceImageByLabel
//
// -----------------------------------------------------------------------------
//
void CEikCbaButton::ReplaceImageByLabel()
{
_AKNTRACE_FUNC_ENTER;
iDoImage = EFalse;
if ( iImage )
{
// avoid mem leak.
iImage->SetMask( iMask );
delete iImage;
iImage = NULL;
delete iSfeMask;
iSfeMask = NULL;
}
_AKNTRACE_FUNC_EXIT;
}
//
// CEikEnhancedCbaButton
//
// -----------------------------------------------------------------------------
// default constructor
// -----------------------------------------------------------------------------
CEikEnhancedCbaButton::CEikEnhancedCbaButton()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// default destructor
// -----------------------------------------------------------------------------
CEikEnhancedCbaButton::~CEikEnhancedCbaButton()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// Sets command type for current button
// @param aCommandType Command type to be set
// -----------------------------------------------------------------------------
#ifdef RD_ENHANCED_CBA
void CEikEnhancedCbaButton::SetCommandType( const TInt aCommandType )
{
_AKNTRACE_FUNC_ENTER;
iCommandType = aCommandType;
_AKNTRACE_FUNC_EXIT;
}
#else
void CEikEnhancedCbaButton::SetCommandType( const TInt /*aCommandType*/ )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
#endif // RD_ENHANCED_CBA
// -----------------------------------------------------------------------------
// returns command's type for current button
// @return TInt command's type
// -----------------------------------------------------------------------------
TInt CEikEnhancedCbaButton::CommandType() const
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
#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
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
#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)
{
_AKNTRACE_FUNC_ENTER
// 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
_AKNTRACE_FUNC_EXIT;
}
#else
void CEikEnhancedCbaButton::ConstructFromResourceL(TResourceReader&)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
}
#endif // RD_ENHANCED_CBA
// -----------------------------------------------------------------------------
// Constructs empty button with id EAknSoftkeyEmpty
// -----------------------------------------------------------------------------
void CEikEnhancedCbaButton::ConstructEmptyButtonL()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
#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()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
#ifdef RD_ENHANCED_CBA
return &iLongLabelText;
#else
return NULL;
#endif
}
//
// CEikCommandTable
//
CEikCommandTable* CEikCommandTable::NewL()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
#ifdef RD_ENHANCED_CBA
CEikCommandTable* self = CEikCommandTable::NewLC();
CleanupStack::Pop( self );
return self;
#else
return NULL;
#endif
}
CEikCommandTable* CEikCommandTable::NewLC()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
#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()
{
_AKNTRACE_FUNC_ENTER;
#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
_AKNTRACE_FUNC_EXIT;
}
#ifdef RD_ENHANCED_CBA
CEikCommandTable::CEikCommandTable() : iPriorities(1)
#else
CEikCommandTable::CEikCommandTable()
#endif // RD_ENHANCED_CBA
{
}
CEikCommandTable::~CEikCommandTable()
{
_AKNTRACE_FUNC_ENTER;
#ifdef RD_ENHANCED_CBA
iCommandButtons.Reset(); // Reset array
for(TInt i = 0; i < iPriorities.Count(); i++)
{
iPriorities[i].Reset();
}
iPriorities.Reset();
#endif
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// Used to add a command to CommandTable
// @param aButton button to be added
// -----------------------------------------------------------------------------
#ifndef RD_ENHANCED_CBA
TInt CEikCommandTable::AddCommandL(CEikEnhancedCbaButton* /*aButton*/)
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return KErrNone;
}
#else
TInt CEikCommandTable::AddCommandL(CEikEnhancedCbaButton* aButton)
{
_AKNTRACE_FUNC_ENTER;
// 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;
}
_AKNTRACE_FUNC_EXIT;
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
{
_AKNTRACE_FUNC_ENTER;
#else // !RD_ENHANCED_CBA
TBool CEikCommandTable::IsCommandPlaced(const TInt aCommandId) const
{
_AKNTRACE_FUNC_ENTER;
TInt count( iCommandButtons.Count() );
for ( TInt i = 0; i < count; i++ )
{
if ( iCommandButtons[i] )
{
if ( iCommandButtons[i]->CommandId() == aCommandId )
{
_AKNTRACE_FUNC_EXIT;
return ETrue;
}
}
}
#endif // RD_ENHANCED_CBA
_AKNTRACE_FUNC_EXIT;
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*/ )
{
_AKNTRACE_FUNC_ENTER;
#else // !RD_ENHANCED_CBA
void CEikCommandTable::ReplaceCommandL( const TInt aCommandId, const TInt aResourceId )
{
_AKNTRACE_FUNC_ENTER;
// If the command is not in the command table, return.
if( !IsCommandPlaced( aCommandId ) )
{
_AKNTRACE_FUNC_EXIT;
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
_AKNTRACE_FUNC_EXIT;
}
// -----------------------------------------------------------------------------
// 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 )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return iCommandButtons[aCommandIndex];
}
#else // RD_ENHANCED_CBA
CEikEnhancedCbaButton* CEikCommandTable::Command( const TInt /*aCommandIndex*/ )
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
return NULL;
}
#endif // RD_ENHANCED_CBA
// -----------------------------------------------------------------------------
// Reset CommandTable
// -----------------------------------------------------------------------------
void CEikCommandTable::Reset()
{
_AKNTRACE_FUNC_ENTER;
_AKNTRACE_FUNC_EXIT;
#ifdef RD_ENHANCED_CBA
iCommandButtons.Reset();
#endif // RD_ENHANCED_CBA
}
// -----------------------------------------------------------------------------
// Sets command observer
// -----------------------------------------------------------------------------
EXPORT_C void AknCbaContentObserver::SetContentObserver(
CEikCba* aCba,
TCallBack aCallBack )
{
_AKNTRACE_FUNC_ENTER;
if ( aCba )
{
aCba->SetContentObserver( aCallBack );
}
_AKNTRACE_FUNC_EXIT;
}
// End of file