--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailcontacts/contactactionmenu/src/cfsccontactactionmenulist.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,917 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation of the class CFscContactActionMenuList.
+*
+*/
+//<cmail> Layout changes
+
+
+// INCUDES
+#include "emailtrace.h"
+#include <e32std.h>
+#include <e32base.h>
+#include <eikclbd.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <gulicon.h>
+#include <coeaui.h>
+#include <coefontprovider.h>
+#include <gulfont.h>
+#include <AknBidiTextUtils.h>
+#include <AknLayoutFont.h>
+#include <AknLayout2ScalableDataDef.h>
+#include <AknLayout2ScalableDef.h>
+#include <layoutmetadata.cdl.h>
+#include <CdlEngine.h>
+#include <coemain.h>
+#include <AknsListBoxBackgroundControlContext.h>
+
+#include <aknlayoutscalable_apps.cdl.h>
+#include <layoutmetadata.cdl.h>
+
+#include "cfsccontactactionmenulist.h"
+#include "mfsccontactactionmenulistobserver.h"
+#include "mfsccontactactionmenumodel.h"
+#include "cfsccontactactionmenuitem.h"
+#include "cfsccontactactionmenulistbox.h"
+#include "fsccontactactionmenuuidefines.h"
+
+//_LIT( KListItemTextFormat, "%d\t%S" );
+_LIT( KListItemTextFormat, "\t%d\t\t%S" );
+
+const TInt KPeriodicDelay = 0; // immediately
+const TInt KPeriodicInterval = 20*1000; // 20ms
+
+// ======== LOCAL FUNCTIONS ========
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::NewL
+// ---------------------------------------------------------------------------
+//
+CFscContactActionMenuList* CFscContactActionMenuList::NewL(
+ MFscContactActionMenuListObserver* aObserver,
+ MFscContactActionMenuModel* aModel,
+ TBool aAiMode,
+ MFsActionMenuPositionGiver* aPositionGiver,
+ TBool aOpenedFromMR )
+ {
+ FUNC_LOG;
+
+ CFscContactActionMenuList* self = new (ELeave) CFscContactActionMenuList(
+ aObserver, aModel, aAiMode, aPositionGiver, aOpenedFromMR );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::~CFscContactActionMenuList
+// ---------------------------------------------------------------------------
+//
+CFscContactActionMenuList::~CFscContactActionMenuList()
+ {
+ FUNC_LOG;
+ Hide( EFalse );
+ delete iPeriodic;
+ ClearControls();
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::OfferKeyEventL
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CFscContactActionMenuList::OfferKeyEventL(
+ const TKeyEvent& aKeyEvent, TEventCode aType )
+ {
+ FUNC_LOG;
+
+ TKeyResponse ret = ( EKeyWasConsumed );
+
+ if ( iObserver->IsOperationCompleted() )
+ {
+ ret = EKeyWasNotConsumed;
+ TInt closeKey = AknLayoutUtils::LayoutMirrored() ?
+ EStdKeyRightArrow : EStdKeyLeftArrow;
+ if ( aType == EEventKey && aKeyEvent.iScanCode == closeKey )
+ {
+ iObserver->HandleListEvent(
+ MFscContactActionMenuListObserver::EFscMenuEventCloseKey );
+ ret = EKeyWasConsumed;
+ }
+ else if ( aType == EEventKey && aKeyEvent.iCode == EKeyEscape )
+ {
+ ret = EKeyWasConsumed;
+ // Handle application exit
+ iObserver->HandleListEvent(
+ MFscContactActionMenuListObserver::EFscMenuEventExitKey );
+ }
+ else if ( aType == EEventKey && aKeyEvent.iCode == EKeyYes )
+ {
+ // Send key is not active in the action menu
+ ret = EKeyWasConsumed;
+ }
+ else if ( !iAiMode ||
+ aKeyEvent.iScanCode == EStdKeyRightArrow ||
+ aKeyEvent.iScanCode == EStdKeyUpArrow ||
+ aKeyEvent.iScanCode == EStdKeyDownArrow ||
+ aKeyEvent.iScanCode == EStdKeyEnter ||
+ aKeyEvent.iScanCode == EStdKeyDevice0 || //RSK
+ aKeyEvent.iScanCode == EStdKeyDevice1 || //LSK
+ aKeyEvent.iScanCode == EStdKeyDevice3 ) //
+ {
+ ret = iListBox->OfferKeyEventL( aKeyEvent, aType );
+ }
+ else if ( aType == EEventKey )
+ {
+ // iAiMode == ETrue && some special key pressed
+ // Inform observer and remove menu from stack
+ iObserver->HandleListEvent(
+ MFscContactActionMenuListObserver::EFscMenuEventExitKey );
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// <cmail> Touch
+// CFscContactActionMenuList::HandlePointerEventL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::HandlePointerEventL(const TPointerEvent& aPointerEvent)
+ {
+ iListHasConsumedPointed = EFalse;
+ iListBox->HandlePointerEventL(aPointerEvent);
+ if (!iListHasConsumedPointed && aPointerEvent.iType == TPointerEvent::EButton1Up)
+ {
+ Hide(ETrue);
+ }
+ }
+
+// </cmail>
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::HandleResourceChange
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::HandleResourceChange( TInt aType )
+ {
+ FUNC_LOG;
+ CCoeControl::HandleResourceChange( aType );
+ if ( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ //This code was commented out because of ELLO-7PDHT2
+ //but perhaps error related to switching layout may be fixed, so
+ //code is left here for future use
+ if ( iOpenedFromMR )
+ {
+ iObserver->HandleListEvent(
+ MFscContactActionMenuListObserver::EFscMenuLayoutChanged );
+ }
+ else
+ {
+ LayoutPopupWindow( ETrue );
+ }
+ }
+ else if ( aType == KAknsMessageSkinChange ||
+ aType == KEikMessageColorSchemeChange )
+ {
+ UpdateColors();
+ DrawDeferred();
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::CountComponentControls
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::CountComponentControls() const
+ {
+ FUNC_LOG;
+ TInt result = 1;
+ return result;
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ComponentControl
+// ---------------------------------------------------------------------------
+//
+CCoeControl* CFscContactActionMenuList::ComponentControl( TInt aIndex ) const
+ {
+ FUNC_LOG;
+ CCoeControl* control = NULL;
+
+ if ( aIndex == 0 && iListBox != NULL )
+ {
+ control = iListBox;
+ } // No need for else block
+
+ return control;
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::HandleListBoxEventL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::HandleListBoxEventL(
+ CEikListBox* aListBox, TListBoxEvent aEventType )
+ {
+ FUNC_LOG;
+ if( aListBox == iListBox )
+ {
+// <cmail> Touch
+ // Handle pointer events
+ TBool executeAction = EFalse;
+ if ( aEventType == EEventItemDraggingActioned )
+ {
+ iHasBeenDragged = ETrue;
+ }
+ else if ( aEventType == EEventItemClicked )
+ {
+ if (!iHasBeenDragged)
+ {
+ executeAction = ETrue;
+ }
+ else
+ {
+ iHasBeenDragged = EFalse;
+ }
+ }
+ else if ( aEventType == EEventEnterKeyPressed)
+ {
+ executeAction = ETrue;
+ iHasBeenDragged = EFalse;
+ }
+ iListHasConsumedPointed = ETrue;
+ if ( executeAction )
+ {
+ iObserver->HandleListEvent(
+ MFscContactActionMenuListObserver::EFscMenuEventItemClicked
+ );
+ }
+
+ /*
+ if ( aEventType == EEventItemClicked ||
+ aEventType == EEventEnterKeyPressed )
+ {
+ iObserver->HandleListEvent(
+ MFscContactActionMenuListObserver::EFscMenuEventItemClicked
+ );
+ }*/
+// </cmail>
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ShowL
+// ---------------------------------------------------------------------------
+//
+// <cmail> Touch
+void CFscContactActionMenuList::ShowL(
+ TFscContactActionMenuPosition aPosition,
+ TInt aIndex )
+ {
+ FUNC_LOG;
+
+ iPosition = aPosition;
+// </cmail>
+
+ //UpdateListContentL();
+ //UpdateWindowL();
+ UpdateColors();
+
+ DrawableWindow()->SetOrdinalPosition( KZero, KZero );
+ SetupMenuOffset();
+ iState = ESlidingIn;
+ iMenuOffset.SetWithSpeed( KZero, KMenuSlideSpeed );
+ if ( iMenuOffset.Interpolating() && !iPeriodic->IsActive() )
+ {
+ TCallBack callback( UpdateWindowPosition, this );
+ iPeriodic->Start( KPeriodicDelay, KPeriodicInterval, callback );
+ }
+
+ iEikonEnv->EikAppUi()->AddToStackL( this, ECoeStackPriorityDialog );
+ MakeVisible( ETrue );
+ SetFocus( ETrue, EDrawNow );
+ iListBox->SetCurrentItemIndex( aIndex );
+
+ DrawDeferred();
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::Hide
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::Hide( TBool aSlide )
+ {
+ FUNC_LOG;
+
+ if ( aSlide && ( iState == EIn || iState == ESlidingIn ) )
+ {
+ // Start sliding out when menu is fully or partialy shown
+ iState = ESlidingOut;
+ const TInt windowWidth( Rect().Width() );
+ TInt newPos =
+ AknLayoutUtils::LayoutMirrored() ?
+ -windowWidth : windowWidth;
+ iMenuOffset.SetWithSpeed( newPos, KMenuSlideSpeed );
+ if ( iMenuOffset.Interpolating() && !iPeriodic->IsActive() )
+ {
+ TCallBack callback( UpdateWindowPosition, this );
+ iPeriodic->Start( KPeriodicDelay, KPeriodicInterval, callback );
+ }
+ }
+ else
+ {
+ // Hide menu now
+ SetFocus( EFalse );
+ MakeVisible( EFalse );
+ iEikonEnv->EikAppUi()->RemoveFromStack( this );
+
+ // If periodic running, stop it
+ iPeriodic->Cancel();
+
+ if ( iState != EOut )
+ {
+ iState = EOut;
+ // Inform observer
+ iObserver->HandleListEvent(
+ MFscContactActionMenuListObserver::EFscMenuEventMenuHidden
+ );
+ }
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::SelectedItemIndex
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::SelectedItemIndex()
+ {
+ FUNC_LOG;
+ return iListBox->CurrentItemIndex();
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ItemCount
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::ItemCount()
+ {
+ FUNC_LOG;
+ return iListBox->Model()->ItemTextArray()->MdcaCount();
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::CFscContactActionMenuList
+// ---------------------------------------------------------------------------
+//
+// <cmail>
+CFscContactActionMenuList::CFscContactActionMenuList(
+ MFscContactActionMenuListObserver* aObserver,
+ MFscContactActionMenuModel* aModel,
+ TBool aAiMode,
+ MFsActionMenuPositionGiver* aPositionGiver,
+ TBool aOpenedFromMR )
+ : iState( EOut ), iObserver( aObserver ), iModel( aModel ),
+ iAiMode( aAiMode ), iPositionGiver(aPositionGiver),
+ iOpenedFromMR( aOpenedFromMR )
+ {
+// </cmail>
+ FUNC_LOG;
+ ASSERT( aObserver != NULL && aModel != NULL);
+
+ iListItemId = KAknsIIDQgnFsGrafContactsContent;
+ iListBottomId = KAknsIIDQsnBgColumnA;
+ iHighlightId = KAknsIIDQgnFsList;
+ iHighlightCenterId = KAknsIIDQgnFsListCenter;
+
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::ConstructL()
+ {
+ FUNC_LOG;
+
+ iPeriodic = CPeriodic::NewL( CActive::EPriorityUserInput );
+
+ CreateWindowL();
+
+ SetNonFocusing();
+ SetBlank(); // This control need not draw
+#ifndef FF_CMAIL_INTEGRATION
+ EnableWindowTransparency(); //Needed to draw background correctly Not supported in 5.0
+#endif
+
+ // <cmail> Touch
+ Window().SetPointerCapture(RWindowBase::TCaptureFlagEnabled | RWindowBase::TCaptureFlagAllGroups);
+ // </cmail>
+
+ //InitializeLayoutL();
+ ConstructControlsL();
+
+ // Finalize construct
+ MakeVisible(ETrue);
+ ActivateL();
+
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::LayoutList
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::LayoutList()
+ {
+ FUNC_LOG;
+ TRAPD( error, LayoutListL() );
+ return error;
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::LayoutListL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::LayoutListL()
+ {
+ FUNC_LOG;
+
+ const TRect menuPaneRect( Rect() );
+
+ // Menu list pane
+ TAknLayoutRect menuListPane;
+ menuListPane.LayoutRect( menuPaneRect,
+ AknLayoutScalable_Apps::sp_fs_action_menu_list_pane(
+ Max( 0, iModel->ItemCount() - 1 ) ) );
+ const TRect menuPaneListRect( menuListPane.Rect() );
+
+ // Menu gene pane
+ TAknLayoutRect menuGenePane;
+ menuGenePane.LayoutRect( menuPaneListRect,
+ AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane( 0 ) );
+ const TRect menuGenePaneRect( menuGenePane.Rect() );
+
+ // Menu gene pane g1
+ TAknLayoutRect menuGenePaneG1;
+ menuGenePaneG1.LayoutRect( menuGenePaneRect,
+ AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane_g1( 0 ) );
+ const TRect menuGenePaneG1Rect( menuGenePaneG1.Rect() );
+
+ // Menu gene pane t1
+ TAknLayoutText menuGenePaneT1;
+ menuGenePaneT1.LayoutText( menuGenePaneRect,
+ AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane_t1( 0 ) );
+ const TRect menuGenePaneT1Rect( menuGenePaneT1.TextRect() );
+ iFont = menuGenePaneT1.Font();
+
+ iListBox->SetRect( menuPaneListRect );
+
+ // Setup listbox columns
+ CColumnListBoxData& columnData( *iListBox->ItemDrawer()->ColumnData() );
+ columnData.SetColumnWidthPixelL( ELeftMarginColumn,
+ LeftMargin( menuGenePaneRect, menuGenePaneG1Rect ) );
+ columnData.SetColumnWidthPixelL( EIconColumn, menuGenePaneG1Rect.Width() );
+ columnData.SetColumnWidthPixelL( EMidleMarginColumn,
+ MiddleMargin( menuGenePaneG1Rect, menuGenePaneT1Rect ) );
+ columnData.SetColumnWidthPixelL( ETextColumn, menuGenePaneT1Rect.Width() );
+ columnData.SetGraphicsColumnL( EIconColumn, ETrue );
+ columnData.SetColumnFontL( ETextColumn, iFont );
+ columnData.SetColumnBaselinePosL( ETextColumn,
+ iFont->HeightInPixels() +
+ (menuGenePaneRect.Height() - iFont->HeightInPixels() - iFont->FontMaxDescent()) / 2 );
+
+ AknLayoutUtils::LayoutMirrored() ?
+ columnData.SetColumnAlignmentL( ETextColumn, CGraphicsContext::ERight ) :
+ columnData.SetColumnAlignmentL( ETextColumn, CGraphicsContext::ELeft );
+
+ // Setup item height
+ columnData.SetItemCellSize( menuGenePaneRect.Size() );
+ iListBox->SetItemHeightL( menuGenePaneRect.Height() );
+ iListBox->SetBackgroundRect( menuPaneRect );
+
+ UpdateListContentL( menuGenePaneG1Rect.Size() );
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::LeftMargin
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::LeftMargin( const TRect& aMenuPane,
+ const TRect& aG1 ) const
+ {
+ FUNC_LOG;
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ return Abs( aMenuPane.iBr.iX - aG1.iBr.iX );
+ }
+ return Abs( aG1.iTl.iX - aMenuPane.iTl.iX );
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::MiddleMargin
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::MiddleMargin( const TRect& aG1,
+ const TRect& aT1 ) const
+ {
+ FUNC_LOG;
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ return Abs( aG1.iTl.iX - aT1.iBr.iX );
+ }
+ return Abs( aG1.iBr.iX - aT1.iTl.iX );
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::RightMargin
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::RightMargin( const TRect& aMenuPane,
+ const TRect& aT1 ) const
+ {
+ FUNC_LOG;
+ if ( AknLayoutUtils::LayoutMirrored() )
+ {
+ return Abs( aT1.iTl.iX - aMenuPane.iTl.iX );
+ }
+ return Abs( aMenuPane.iBr.iX - aT1.iBr.iX );
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ConstructControlsL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::ConstructControlsL()
+ {
+ FUNC_LOG;
+
+ // Create list control
+ iListBox = new ( ELeave ) CFscContactActionMenuListBox();
+ iListBox->ConstructL( this );
+ iListBox->HandleItemAdditionL();
+ iListBox->SetFocus( ETrue );
+ iListBox->SetContainerWindowL( *this );
+ iListBox->SetListBoxObserver( this );
+ // Set icon array
+ CArrayPtrFlat<CGulIcon>* iconArray =
+ new (ELeave) CArrayPtrFlat<CGulIcon>( KGranularity );
+ iListBox->ItemDrawer()->ColumnData()->SetIconArray( iconArray );
+ LayoutPopupWindow();
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::ClearControls
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::ClearControls()
+ {
+ FUNC_LOG;
+
+ if ( iListBox )
+ {
+ delete iListBox;
+ iListBox = NULL;
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::UpdateListL
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::UpdateListContentL( const TSize& aIconSize )
+ {
+ FUNC_LOG;
+
+ CDesCArray* desArray =
+ static_cast<CDesCArray*>( iListBox->Model()->ItemTextArray() );
+ desArray->Reset();
+
+ CArrayPtr<CGulIcon>* iconArray =
+ iListBox->ItemDrawer()->ColumnData()->IconArray();
+ iconArray->ResetAndDestroy(); // Remove old icons
+
+ TInt itemCount = iModel->VisibleItemCount();
+ for ( TInt i = 0; i < itemCount; i++ )
+ {
+ CFscContactActionMenuItem& item = iModel->VisibleItemL( i );
+
+ const CGulIcon* origIcon = item.Icon();
+ ASSERT( origIcon != NULL );
+
+ CGulIcon* icon = CGulIcon::NewL(
+ origIcon->Bitmap(), origIcon->Mask() );
+ CleanupStack::PushL( icon );
+ icon->SetBitmapsOwnedExternally( ETrue );
+
+ AknIconUtils::SetSize( icon->Bitmap(), aIconSize );
+ AknIconUtils::SetSize( icon->Mask(), aIconSize );
+ iconArray->AppendL(icon);
+ CleanupStack::Pop( icon );
+
+ const TDesC& text = item.MenuText();
+ HBufC* tempDes = HBufC::NewLC(
+ text.Length() + KListItemTextFormat().Length() );
+ tempDes->Des().Format( KListItemTextFormat, i, &text );
+ desArray->AppendL( *tempDes );
+ CleanupStack::PopAndDestroy( tempDes );
+ }
+
+ iListBox->HandleItemAdditionL();
+ iListBox->UpdateScrollBarsL();
+
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::SetupMenuOffset
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::SetupMenuOffset()
+ {
+ FUNC_LOG;
+
+ switch( iState )
+ {
+ case EOut:
+ case ESlidingOut:
+ {
+ const TInt windowWidth( Rect().Width() );
+ // Menu is out of the screen
+ TInt newPos =
+ AknLayoutUtils::LayoutMirrored() ?
+ -windowWidth : windowWidth;
+ iMenuOffset.Set( newPos );
+ }
+ break;
+ case EIn:
+ case ESlidingIn:
+ {
+ // Menu is visible
+ iMenuOffset.Set( 0 );
+ }
+ break;
+ default:
+ {
+ //Nothing to do
+ break;
+ }
+ }
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::UpdateColors
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::UpdateColors()
+ {
+ FUNC_LOG;
+
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ TRgb color;
+
+ // Highlight text color
+ TInt error = AknsUtils::GetCachedColor(
+ skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG10 );
+ if ( !error )
+ {
+ iListBox->ItemDrawer()->SetHighlightedTextColor( color );
+ }
+ else
+ {
+ error = AknsUtils::GetCachedColor(
+ skin, color, KAknsIIDFsHighlightColors, EAknsCIFsHighlightColorsCG1 );
+ if ( !error )
+ {
+ iListBox->ItemDrawer()->SetHighlightedTextColor( color );
+ }
+ }
+
+ // Text color
+ error = AknsUtils::GetCachedColor(
+ skin, color, KAknsIIDFsTextColors, EAknsCIQsnTextColorsCG19 );
+ if ( !error )
+ {
+ iListBox->ItemDrawer()->SetTextColor( color );
+ }
+ else
+ {
+ // if colors are not found from the skins, set the default values
+ error = AknsUtils::GetCachedColor(
+ skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6 );
+ if ( !error )
+ {
+ iListBox->ItemDrawer()->SetTextColor( color );
+ }
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::MaxListTextWidth
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::MaxListTextWidth()
+ {
+ FUNC_LOG;
+ TPtrC itemText;
+ TInt maxLength( 0 );
+ for ( TInt i = 0; i < iModel->VisibleItemCount(); i++ )
+ {
+ TRAPD( error, itemText.Set( iModel->VisibleItemL( i ).MenuText() ) );
+ if ( !error )
+ {
+ TInt offset( itemText.LocateReverse( TChar('\t') ) );
+ if ( offset != KErrNotFound && ++offset < itemText.Length() )
+ {
+ itemText.Set( itemText.Mid( offset ) );
+ }
+ const TInt length( AknBidiTextUtils::MeasureTextBoundsWidth(
+ *iFont, itemText, CFont::TMeasureTextInput::EFVisualOrder ) );
+ maxLength = length > maxLength ? length : maxLength;
+ }
+ }
+ return maxLength;
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::UpdateWindowPosition
+// ---------------------------------------------------------------------------
+//
+TInt CFscContactActionMenuList::UpdateWindowPosition( TAny *aPtr )
+ {
+ FUNC_LOG;
+ CFscContactActionMenuList* list =
+ static_cast<CFscContactActionMenuList*>( aPtr );
+
+ TRect newRect( list->iOrigMenuRect );
+ newRect.Move( list->iMenuOffset.Now(), 0 );
+ list->SetPosition( newRect.iTl );
+
+ if ( !list->iMenuOffset.Interpolating() )
+ {
+ // Stop timer
+ list->iPeriodic->Cancel();
+ if ( list->iState == ESlidingOut )
+ {
+ // Hide window totally
+ list->iState = EOut;
+ list->SetFocus( EFalse );
+ list->MakeVisible( EFalse );
+ static_cast< CEikonEnv* >
+ ( list->iCoeEnv )->EikAppUi()->RemoveFromStack( list );
+
+ // Inform observer
+ list->iObserver->HandleListEvent(
+ MFscContactActionMenuListObserver::EFscMenuEventMenuHidden
+ );
+ }
+ else if ( list->iState == ESlidingIn )
+ {
+ list->iState = EIn;
+ }
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::LayoutPopupWindow
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::LayoutPopupWindow( const TBool aLayoutChange )
+ {
+ FUNC_LOG;
+ // Application window
+ TRect applicationRect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EApplicationWindow,
+ applicationRect );
+
+ // Main 2 pane. This is the main pane that is used as parent layout
+ // for the popup menup pane in the layout data, but using this would
+ // make popup to overlap with the cba area.
+ TAknLayoutRect main2Pane;
+ main2Pane.LayoutRect( applicationRect, AknLayoutScalable_Apps::main2_pane(
+ Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 3 ) );
+ TRect main2PaneRect = main2Pane.Rect();
+
+ // Main pane
+ TRect mainPaneRect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect );
+
+ // Menu pane
+ TAknLayoutRect menuPane;
+ menuPane.LayoutRect( mainPaneRect,
+ AknLayoutScalable_Apps::popup_sp_fs_action_menu_pane(
+ iModel->ItemCount() + 1 ) );
+
+ iOrigMenuRect = menuPane.Rect();
+ AdjustByContent( iOrigMenuRect );
+ if ( iPositionGiver )
+ {
+ TPoint customPos = iPositionGiver->ActionMenuPosition();
+ iOrigMenuRect.Move( 0, -iOrigMenuRect.iTl.iY + mainPaneRect.iTl.iY
+ + customPos.iY );
+ }
+
+ // Adjust menu pane position to keep it fully visible. The main2pane is
+ // used here to enable menu pane to overlap with status pane area.
+ if ( iOrigMenuRect.iTl.iY < main2PaneRect.iTl.iY )
+ {
+ iOrigMenuRect.Move( 0, main2PaneRect.iTl.iY - iOrigMenuRect.iTl.iY );
+ }
+ else if ( iOrigMenuRect.iBr.iY > main2PaneRect.iBr.iY )
+ {
+ iOrigMenuRect.Move( 0, main2PaneRect.iBr.iY - iOrigMenuRect.iBr.iY );
+ }
+
+ SetRect( iOrigMenuRect );
+
+ if ( !aLayoutChange )
+ {
+ const TInt width( iOrigMenuRect.Width() );
+ TPoint tl( iOrigMenuRect.iTl );
+ tl.iX += AknLayoutUtils::LayoutMirrored() ? -width : width;
+ SetPosition( tl );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::AdjustByContent
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::AdjustByContent( TRect& aRect )
+ {
+ FUNC_LOG;
+ // Menu list pane
+ TAknLayoutRect menuListPane;
+ menuListPane.LayoutRect( aRect,
+ AknLayoutScalable_Apps::sp_fs_action_menu_list_pane(
+ Max( 0, iModel->ItemCount() - 1 ) ) );
+ const TRect menuPaneListRect( menuListPane.Rect() );
+
+ // Menu gene pane
+ TAknLayoutRect menuGenePane;
+ menuGenePane.LayoutRect( menuPaneListRect,
+ AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane( 0 ) );
+ const TRect menuGenePaneRect( menuGenePane.Rect() );
+
+ // Menu gene pane g1
+ TAknLayoutRect menuGenePaneG1;
+ menuGenePaneG1.LayoutRect( menuGenePaneRect,
+ AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane_g1( 0 ) );
+ const TRect menuGenePaneG1Rect( menuGenePaneG1.Rect() );
+
+ // Menu gene pane t1
+ TAknLayoutText menuGenePaneT1;
+ menuGenePaneT1.LayoutText( menuGenePaneRect,
+ AknLayoutScalable_Apps::sp_fs_action_menu_list_gene_pane_t1( 0 ) );
+ const TRect menuGenePaneT1Rect( menuGenePaneT1.TextRect() );
+ iFont = menuGenePaneT1.Font();
+
+ const TInt textColumnWidth( menuGenePaneT1Rect.Width() );
+ const TInt maxTextWidth( MaxListTextWidth() +
+ RightMargin( menuGenePaneRect, menuGenePaneT1Rect ) );
+
+ if ( maxTextWidth < textColumnWidth )
+ {
+ const TInt widthAdjustment( textColumnWidth - maxTextWidth );
+ if ( !AknLayoutUtils::LayoutMirrored() )
+ {
+ aRect.Move( widthAdjustment, 0 );
+ }
+ aRect.Resize( -widthAdjustment, 0 );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CFscContactActionMenuList::SizeChanged
+// ---------------------------------------------------------------------------
+//
+void CFscContactActionMenuList::SizeChanged()
+ {
+ FUNC_LOG;
+ LayoutList();
+ }
+
+//</cmail>
+