--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/eikfrlbd.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,4503 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <eikfrlbd.h>
+#include <aknlists.h>
+#include <AknMarqueeControl.h>
+#include <AknPictographInterface.h>
+#include <AknPictographDrawerInterface.h>
+#include <AknsEffectAnim.h>
+#include <AknsListBoxBackgroundControlContext.h>
+#include <AknsFrameBackgroundControlContext.h>
+#include <AknPanic.h>
+#include <AknBidiTextUtils.h>
+#include <centralrepository.h>
+#include <AvkonInternalCRKeys.h>
+#include <gulicon.h>
+#include <eikslbd.h>
+#include "AknDebug.h"
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <layoutmetadata.cdl.h>
+#include <aknphysics.h>
+
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+#include <aknlistloadertfx.h>
+#include <aknlistboxtfxinternal.h>
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+
+#include <touchfeedback.h>
+#include "akntrace.h"
+
+// there are 17(!) subcells in qdial grid (0 ... 16)
+const TInt KMaxSubCellIndex = 16 + 1;
+
+// colored tick marks support
+const TInt KColorIconFlag = -1;
+const TInt KColorIconIdx = 0;
+
+/**
+* This class needs to be in .cpp file so that we do not accidentally make it
+* derivable; that would destroy all the binary compability advantages this
+* class has..
+*
+* About animation usage:
+* All animation usage is implemented in this class. Animation is eye candy and
+* low priority when it comes to resources -> on resource failures animation
+* fails fast to release resources for more critical functionality. Also, no
+* attempt to (re)construct failed animation is made.
+*
+* User inactivity is not being observed. Only one animation is used. Extension
+* is CActive to make it possible to postpone animation deletion on animation
+* failure.
+*/
+NONSHARABLE_CLASS(CFormattedCellListBoxDataExtension) :
+ public CActive,
+ public MAknPictographAnimatorCallBack,
+ public MCoeForegroundObserver,
+ public MAknsEffectAnimObserver,
+ public MListBoxItemChangeObserver
+ {
+public:
+ enum TFlag
+ {
+ // Set if current item background should be copied to animation as
+ // input layer.
+ EFlagUpdateBg = 0,
+
+ // Set if animation has been resized at least once
+ EFlagHasLayers = 1,
+
+ // Set if foreground has been gained.
+ EFlagHasForeground = 2
+ };
+
+ enum TSubCellType
+ {
+ EAknSLGraphic,
+ EAknSLText,
+ EAknSLNumeric
+ };
+
+public:
+ CFormattedCellListBoxDataExtension();
+ void ConstructL( CFormattedCellListBoxData* aListBoxData,
+ const TAknsItemID& aAnimationIID );
+ ~CFormattedCellListBoxDataExtension();
+ void CreatePictographInterfaceL();
+ void CreateMarqueeControlL();
+ static TInt RedrawEvent(TAny* aControl); // Marquee draw callback
+ TBool IsMarqueeOn();
+ struct SRowAndSubCell
+ {
+ TInt iIndex; // 24 bits for row and 8 bits for subcell
+ const CFont* iFont;
+ //TBool iUnderline;
+ //TBool iStrikethrough;
+ };
+ struct SSLSubCell
+ {
+ TInt iSubCell; // Must be first entry
+ TAknTextLineLayout iTextLayout;
+ TAknWindowLineLayout iGraphicLayout;
+ TInt iSubCellType;
+ TInt iConditionValue; // used with conditional layouts for not always drawn subcells
+ };
+
+ SRowAndSubCell& At(TInt aArrayIndex);
+ const SRowAndSubCell& At(TInt aArrayIndex) const;
+ void AddRowAndSubCellL(TInt aRow,TInt aSubCell);
+ TInt FindRowAndSubCellIndex(TInt& aArrayIndex,TInt aRow,TInt aSubCell) const;
+ void FindRowAndSubCellIndexOrAddL(TInt& aArrayIndex,TInt aRow,TInt aSubCell);
+
+ SSLSubCell& AtSL(TInt aArrayIndex);
+ const SSLSubCell& AtSL(TInt aArrayIndex) const;
+ void AddSLSubCellL(TInt aSubCell);
+ TInt FindSLSubCellIndex(TInt& aArrayIndex, TInt aSubCell) const;
+ void FindSLSubCellIndexOrAddL(TInt& aArrayIndex, TInt aSubCell);
+ void ResetSLSubCellArray();
+
+ inline void NoAnimIfError( TInt aError );
+ void TryCreateAnimation();
+ TBool SyncAnim( const TSize& aSize );
+ TBool SyncAndDrawAnim( CBitmapContext& aGc, const TRect& aRect );
+ MAknsControlContext* SkinBackgroundContext() const;
+ void DeleteAnim();
+ void FocusGained();
+ void FocusLost();
+ void SkinChanged();
+ void SetControl( CCoeControl* aControl );
+
+ // Implementation of MCoeForegroundObserver
+ void HandleGainingForeground();
+ void HandleLosingForeground();
+
+ // Implementation of MAknsEffectAnimObserver
+ void AnimFrameReady( TInt aError, TInt );
+
+ // Implementation of MListBoxItemChangeObserver
+ void ListBoxItemsChanged(CEikListBox* aListBox);
+
+ // Overloads CActive::DoCancel
+ void DoCancel();
+ // Overloads CActive::RunL
+ void RunL();
+
+ void Play();
+
+ void CreateColorBitmapsL( TSize aSize );
+ void CreateColorBitmapsL();
+
+ TBool DrawPressedDownEffect( MAknsSkinInstance* aSkin,
+ CWindowGc& aGc,
+ const TRect& aOutRect,
+ const TRect& aInnerRect ) const;
+private: // New internal methods
+ TBool DrawHighlightBackground( CFbsBitGc& aGc );
+ void PostDeleteAnimation();
+ void CreateAnimationL();
+ void DoResizeL( const TSize& aHighlightSize, TBool aAboutToStart );
+
+public:
+ struct TSubCellExt
+ {
+ TInt iSubCell; // Must be first entry
+ TBool iLayoutAlign;
+ };
+
+ TInt AddSubCellExtL(TInt aSubCell);
+ void FindSubCellExtIndexOrAddL( TInt& aArrayIndex,TInt aSubCell);
+
+ void SetSubCellLayoutAlignmentL( TInt aSubCellIndex );
+
+
+ TInt FindSubCellExtIndex(TInt& aArrayIndex,TInt aSubCell) const;
+ TBool SubCellLayoutAlignment(TInt aSubCellIndex) const;
+
+private: // From MAknPictographAnimatorCallBack
+ void DrawPictographArea();
+
+public:
+ CCoeControl *iControl; // not owned
+ CFormattedCellListBoxData* iListBoxData; // Not owned
+ CAknsListBoxBackgroundControlContext* iSkinControlContext;
+ TBool iSkinEnabled;
+ const TAknsItemID *iSkinHighlightFrameId;
+ const TAknsItemID *iSkinHighlightFrameCenterId;
+ TBool iRespectFocus;
+// not used ? HBufC *iTempTextBuffer;
+ TRect iSkinPopupInnerRect;
+ TRect iSkinPopupOuterRect;
+ CAknsFrameBackgroundControlContext* iPopupFrame;
+ TBool iUseLogicalToVisualConversion;
+ TInt16 iFirstWordWrappedSubcellIndex;
+ TInt16 iSecondWordWrappedSubcellIndex;
+ CAknPictographInterface* iPictoInterface;
+ CAknMarqueeControl* iMarquee;
+ CAknMarqueeControl* i2ndLineMarquee;
+ TInt iCurrentItem; // Current list item index that marquee draws/has drawn.
+ TInt iCurrentRow; // Current list row being drawn. // not true - cache of currentitemindex
+ TInt iCurrentlyDrawnItemIndex;
+ CArrayFix<SRowAndSubCell>* iRowAndSubCellArray;
+ CArrayFix<SSLSubCell>* iSLSubCellArray;
+ TBool iDrawBackground; // Determines if background should be drawn (transparency)
+ TSize iSubCellIconSize[KMaxSubCellIndex]; // Store icon sizes for each subcell
+ TAknSeparatorLinePosition iSeparatorLinePosition;
+ CAknsEffectAnim* iAnimation;
+ TBitFlags32 iAnimFlags;
+ TRgb iHighlightedTextColor;
+ TRgb iTextColor;
+ TBool iDrawScrollbarBackground;
+ TBool iSimpleList;
+
+ TBool iUnderlineFlagSet; // underlining support for more than
+ TBitFlags32 iUnderlineFlags; // one text subcell
+ TBool iHideSecondRow;
+ TBool iSubCellsMightIntersect;
+ TBool iStretchingEnabled;
+ TAknsItemID iAnimIID;
+ MListBoxAnimBackgroundDrawer* iHighlightBgDrawer;
+ TSize iAnimSize; // TODO Deprecating old style anim API and removing this
+ // Drop shadows can be toggled on/off in
+ // "transparent" lists (eg. transparent camera setting page).
+ TBool iUseDropShadows;
+
+ // highlight color skinning for setstyle lists - to be deprecated once correct color skinning is available
+ TBool iUseHighligthIconSwapping;
+
+ // colorskin highlight icons
+ CFbsBitmap* iColorBmp;
+ CFbsBitmap* iHiliBmp;
+ TRgb iIconColor;
+ TRgb iHiliIconColor;
+
+ TInt iConditionalCells;
+
+ // which columns of highlighted item have clipped text ?
+ TUint32 iClippedSubcells;
+ TUint32 iClippedByWrap;
+ TBool iUseClippedByWrap;
+
+ CArrayFix<TSubCellExt>* iSubCellExtArray; //for subcell alignment
+
+ TRect iMarginRect;
+ TBool iKineticScrolling;
+ };
+
+
+/**
+* High priority is well argumented because running the active object will
+* result in animation deletion -> results in freeing resources.
+*/
+CFormattedCellListBoxDataExtension::CFormattedCellListBoxDataExtension():
+ CActive( EPriorityHigh )
+ {}
+
+void CFormattedCellListBoxDataExtension::ConstructL(
+ CFormattedCellListBoxData* aListBoxData,
+ const TAknsItemID& aAnimationIID )
+ {
+ _AKNTRACE_FUNC_ENTER;
+ iListBoxData = aListBoxData;
+ iRowAndSubCellArray = new(ELeave) CArrayFixFlat<SRowAndSubCell>(4);
+ iSLSubCellArray = new(ELeave) CArrayFixFlat<SSLSubCell>(4);
+
+ iSubCellExtArray = new(ELeave) CArrayFixFlat<TSubCellExt>(4);
+
+ // bi-di algorithm support (NON_LEAVING_VERSION)
+// not used ? iTempTextBuffer = HBufC::NewL(256);
+ iUseLogicalToVisualConversion = ETrue;
+
+ iFirstWordWrappedSubcellIndex = -1;
+ iSecondWordWrappedSubcellIndex = -1;
+
+ iDrawBackground = ETrue;
+ iSeparatorLinePosition = ENoLine;
+
+ iAnimIID = aAnimationIID;
+ CActiveScheduler::Add( this );
+ TryCreateAnimation(); // Animations are created by default
+
+ iTextColor = NULL; // just in case
+ iHighlightedTextColor = NULL; // just in case
+ iDrawScrollbarBackground = ETrue;
+
+#ifdef RD_LIST_STRETCH
+ // check list stretching from cenrep
+ CRepository* cenRep = CRepository::NewL( KCRUidAvkon );
+ cenRep->Get( KAknAutomaticListStretching, iStretchingEnabled );
+ delete cenRep;
+#endif
+
+ iKineticScrolling = CAknPhysics::FeatureEnabled();
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+CFormattedCellListBoxDataExtension::~CFormattedCellListBoxDataExtension()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ Cancel();
+
+ // Stop receiving foreground events
+ CCoeEnv* env = CCoeEnv::Static();
+ env->RemoveForegroundObserver( *this );
+
+ delete iRowAndSubCellArray;
+ iRowAndSubCellArray = NULL;
+ delete iSLSubCellArray;
+ iSLSubCellArray = NULL;
+ delete iSubCellExtArray;
+ iSubCellExtArray = NULL;
+ delete iPopupFrame;
+ delete iSkinControlContext;
+// not used ? delete iTempTextBuffer;
+ delete iPictoInterface;
+ delete iMarquee;
+ delete i2ndLineMarquee;
+ delete iAnimation;
+ delete iColorBmp;
+ delete iHiliBmp;
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+void
+CFormattedCellListBoxDataExtension::AddRowAndSubCellL(TInt aRow,TInt aSubCell)
+ {
+ _AKNTRACE("CFormattedCellListBoxDataExtension::AddRowAndSubCellL aRow = %d, aSubCell=%d",
+ aRow, aSubCell);
+ SRowAndSubCell subcell;
+ subcell.iIndex = (aRow << 8) | (aSubCell & 0xff);
+ subcell.iFont=NULL;
+ TKeyArrayFix key(0,ECmpTInt32);
+ iRowAndSubCellArray->InsertIsqL(subcell,key);
+ }
+
+
+CFormattedCellListBoxDataExtension::SRowAndSubCell&
+CFormattedCellListBoxDataExtension::At(TInt aArrayIndex)
+ {
+/* SRowAndSubCell subcell;
+ for (int a=0;a<iRowAndSubCellArray->Count();a++)
+ subcell = iRowAndSubCellArray->At(a); */
+
+ __ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iRowAndSubCellArray->Count(),Panic(EAknPanicOutOfRange));
+ return(iRowAndSubCellArray->At(aArrayIndex));
+ }
+
+const CFormattedCellListBoxDataExtension::SRowAndSubCell&
+CFormattedCellListBoxDataExtension::At(TInt aArrayIndex) const
+ {
+ __ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iRowAndSubCellArray->Count(),Panic(EAknPanicOutOfRange));
+ return(iRowAndSubCellArray->At(aArrayIndex));
+ }
+
+TInt CFormattedCellListBoxDataExtension::FindRowAndSubCellIndex(TInt& aArrayIndex,
+ TInt aRow,
+ TInt aSubCell) const
+ {
+ if (iRowAndSubCellArray->Count()==0)
+ return(KErrNotFound);
+ TKeyArrayFix key(0,ECmpTInt32);
+ SRowAndSubCell rowAndSubcell;
+ rowAndSubcell.iIndex = (aRow << 8) | (aSubCell & 0xff);
+ return(iRowAndSubCellArray->FindIsq(rowAndSubcell,key,aArrayIndex));
+ }
+
+void CFormattedCellListBoxDataExtension::FindRowAndSubCellIndexOrAddL(TInt& aArrayIndex,
+ TInt aRow,
+ TInt aSubCell)
+ {
+ if (FindRowAndSubCellIndex(aArrayIndex,aRow,aSubCell)!=0) //==KErrNotFound)
+ {
+ AddRowAndSubCellL(aRow,aSubCell);
+ FindRowAndSubCellIndex(aArrayIndex,aRow,aSubCell);
+ }
+/* SRowAndSubCell rowAndSubcell;
+ rowAndSubcell = iRowAndSubCellArray->At(aArrayIndex); */
+ }
+
+
+void
+CFormattedCellListBoxDataExtension::AddSLSubCellL(TInt aSubCell)
+ {
+ _AKNTRACE("CFormattedCellListBoxDataExtension::AddSLSubCellL aSubCell = %d",
+ aSubCell);
+ SSLSubCell subcell;
+ subcell.iSubCell = aSubCell;
+ subcell.iTextLayout = NULL;
+ subcell.iGraphicLayout = NULL;
+ subcell.iSubCellType = 0;
+ subcell.iConditionValue = -1;
+
+ TKeyArrayFix key(0,ECmpTInt32);
+ iSLSubCellArray->InsertIsqL(subcell,key);
+ }
+
+
+CFormattedCellListBoxDataExtension::SSLSubCell&
+CFormattedCellListBoxDataExtension::AtSL(TInt aArrayIndex)
+ {
+ __ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iSLSubCellArray->Count(),Panic(EAknPanicOutOfRange));
+ return(iSLSubCellArray->At(aArrayIndex));
+ }
+
+const CFormattedCellListBoxDataExtension::SSLSubCell&
+CFormattedCellListBoxDataExtension::AtSL(TInt aArrayIndex) const
+ {
+ __ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iSLSubCellArray->Count(),Panic(EAknPanicOutOfRange));
+ return(iSLSubCellArray->At(aArrayIndex));
+ }
+
+TInt CFormattedCellListBoxDataExtension::FindSLSubCellIndex(TInt& aArrayIndex,
+ TInt aSubCell) const
+ {
+ if (iSLSubCellArray->Count()==0)
+ return(KErrNotFound);
+ TKeyArrayFix key(0,ECmpTInt32);
+ SSLSubCell SLSubCell;
+ SLSubCell.iSubCell = aSubCell;
+ return(iSLSubCellArray->FindIsq(SLSubCell,key,aArrayIndex));
+ }
+
+void CFormattedCellListBoxDataExtension::FindSLSubCellIndexOrAddL(TInt& aArrayIndex,
+ TInt aSubCell)
+ {
+ if (FindSLSubCellIndex(aArrayIndex, aSubCell)!=0) //==KErrNotFound)
+ {
+ AddSLSubCellL(aSubCell);
+ FindSLSubCellIndex(aArrayIndex,aSubCell);
+ }
+ }
+
+void CFormattedCellListBoxDataExtension::ResetSLSubCellArray()
+ {
+ iSLSubCellArray->Reset();
+ iRowAndSubCellArray->Reset();
+ }
+
+void CFormattedCellListBoxDataExtension::CreatePictographInterfaceL()
+ {
+ if ( !iPictoInterface )
+ {
+ iPictoInterface = CAknPictographInterface::NewL( *iControl, *this );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::NoAnimIfError
+// -----------------------------------------------------------------------------
+//
+inline void CFormattedCellListBoxDataExtension::NoAnimIfError( TInt aError )
+ {
+ if( KErrNone != aError )
+ {
+ DeleteAnim();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::TryCreateAnimation
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::TryCreateAnimation()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if( !iControl )
+ {
+ _AKNTRACE("CFormattedCellListBoxDataExtension::TryCreateAnimation iControl==NULL");
+ _AKNTRACE_FUNC_EXIT;
+ return;
+ }
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ CEikListBox* list = static_cast<CEikListBox*>( iControl );
+ CListBoxView* view = list->View();
+ if ( !view || !view->ItemDrawer() )
+ {
+ return;
+ }
+ CWindowGc* gc = view->ItemDrawer()->Gc();
+ MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( gc );
+ if ( transApi && transApi->VerifyKml() == KErrNone )
+ {
+ return;
+ }
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+
+
+ // Ideally we should not create animation if the list has zero items.
+ // Unfortunately, this will cause problems elsewhere as setting item text
+ // array to list requires not calling HandleItemAddition (or similar
+ // method) -> in some situations animation would not be created at all as
+ // we don't receive item change event. Fortunately, creating animation to
+ // empty list doesn't carry much overhead as layer creation is delayed to
+ // first render.
+
+ if( !iAnimation )
+ {
+ // This must be the first call because animation does not exist.
+ // Animation layers are created when the animation is rendered for the
+ // first time.
+ TRAPD( err, CreateAnimationL() );
+ NoAnimIfError( err );
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::SyncAnim
+// -----------------------------------------------------------------------------
+//
+TBool CFormattedCellListBoxDataExtension::SyncAnim( const TSize& aSize )
+ {
+ _AKNTRACE_FUNC_ENTER;
+ _AKNTRACE("CFormattedCellListBoxDataExtension::SyncAnim aSize=(%d,%d)",
+ aSize.iWidth, aSize.iHeight);
+ if( !iAnimation || aSize.iWidth <= 0 || aSize.iHeight <= 0 )
+ {
+ _AKNTRACE("SyncAnim: invalid size or no iAnimation");
+ _AKNTRACE_FUNC_EXIT;
+ return EFalse;
+ }
+
+ if( iAnimation->Size() != aSize || iAnimation->NeedsInputLayer() )
+ {
+ // Resizing will update animation background
+ iAnimFlags.Clear( EFlagUpdateBg );
+
+ // Animation exists but its size is out of sync or input layers have
+ // been released
+ TRAPD( err, DoResizeL( aSize, iAnimFlags.IsSet( EFlagHasForeground ) ) );
+
+ if( err )
+ {
+ DeleteAnim();
+ return EFalse;
+ }
+ iAnimFlags.Set( EFlagHasLayers );
+ }
+
+ // Highlight animation background needs update (current item has changed)
+ if( iAnimFlags.IsSet( EFlagUpdateBg ) )
+ {
+ iAnimFlags.Clear( EFlagUpdateBg );
+
+ if( iAnimation->InputRgbGc() )
+ {
+ DrawHighlightBackground( *iAnimation->InputRgbGc() );
+ // We need to update the output frame (otherwise the highlight
+ // would drawn with the old output before the next new animation
+ // frame).
+ NoAnimIfError( iAnimation->UpdateOutput() );
+ if( !iAnimation )
+ {
+ return EFalse;
+ }
+ }
+ }
+
+ _AKNTRACE_FUNC_EXIT;
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::SyncAndDrawAnim
+// -----------------------------------------------------------------------------
+//
+TBool CFormattedCellListBoxDataExtension::SyncAndDrawAnim(
+ CBitmapContext& aGc, const TRect& aRect )
+ {
+ if( iAnimation )
+ {
+ // When application loses foreground or has not yet gained foreground
+ // animation is in stopped state and input layers are not present. It
+ // is possible that list is repainted in this situation. Calling
+ // SyncAnim will create the non-present layers -> WSERV flush ->
+ // flicker. To prevent flickering we just render the existing frame.
+ // This can lead to incorrect draw if the current item index is changed
+ // when the app has no foreground (very unlikely). If EFlagHasLayers is
+ // not set we need to do SyncAnim because it is the first call to draw
+ // (and flicker is not an issue).
+ if( EAknsAnimStateStopped == iAnimation->State() &&
+ !iAnimFlags.IsSet( EFlagHasForeground ) &&
+ iAnimFlags.IsSet( EFlagHasLayers ) &&
+ !iAnimFlags.IsSet( EFlagUpdateBg ) )
+ {
+ return iAnimation->Render( aGc, aRect );
+ }
+ }
+
+ if( SyncAnim( aRect.Size() ) )
+ {
+ return iAnimation->Render( aGc, aRect );
+ }
+
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::SkinBackgroundContext
+// -----------------------------------------------------------------------------
+//
+MAknsControlContext* CFormattedCellListBoxDataExtension::SkinBackgroundContext() const
+ {
+ if( iSkinEnabled )
+ return iSkinControlContext;
+ else
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::DeleteAnim
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::DeleteAnim()
+ {
+ // Stop receiving foreground events
+ _AKNTRACE_FUNC_ENTER;
+ CCoeEnv* env = CCoeEnv::Static();
+ env->RemoveForegroundObserver( *this );
+
+ delete iAnimation;
+ iAnimation = NULL;
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::FocusGained
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::FocusGained()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ Play();
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::FocusLost
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::FocusLost()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if( iAnimation )
+ {
+ _AKNTRACE("CFormattedCellListBoxDataExtension::FocusLost begin pause "
+ "animation");
+ NoAnimIfError( iAnimation->Pause() );
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::SkinChanged
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::SkinChanged()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ DeleteAnim();
+ TryCreateAnimation();
+ TRAP_IGNORE(CreateColorBitmapsL());
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::SetControl
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::SetControl( CCoeControl* aControl )
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if( iControl )
+ {
+ CEikListBox* list = (CEikListBox*) iControl;
+ list->RemoveItemChangeObserver( this );
+ }
+
+ iControl = aControl;
+
+ if( iControl )
+ {
+ CEikListBox* list = (CEikListBox*) iControl;
+ TRAP_IGNORE( list->AddItemChangeObserverL(this) );
+
+ if( !iAnimation )
+ {
+ TryCreateAnimation();
+ }
+
+ if( iAnimation )
+ {
+ Play();
+ }
+ }
+ else
+ {
+ DeleteAnim();
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::HandleGainingForeground
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::HandleGainingForeground()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ // Most of the time focus focus events happen between foreground events.
+ // Unfortunately, there are embedded app related cases where this does not
+ // always hold (it is possible to focus in non-foreground application or
+ // gain foreground without getting a focus gained). Therefore animations
+ // must be started here. This causes potential problem case: foreground
+ // events are broadcasted to all animations, if there are multiple lists
+ // that have focus the result will be multiple animations running at the
+ // same time.
+ iAnimFlags.Set( EFlagHasForeground );
+
+ if( iAnimation )
+ {
+ // Because we are gaining foreground we must restore input layers
+ // (which are released when animation stops to reduce memory usage).
+ SyncAnim( iAnimation->Size() );
+ }
+
+ if( iControl )
+ {
+ if( iControl->IsFocused() )
+ {
+ Play();
+ }
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::HandleLosingForeground
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::HandleLosingForeground()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ iAnimFlags.Clear( EFlagHasForeground );
+ if( iAnimation )
+ {
+ NoAnimIfError( iAnimation->Stop() );
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::AnimFrameReady
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::AnimFrameReady( TInt aError, TInt )
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if( KErrNone != aError )
+ {
+ _AKNTRACE("AnimFrameReady£º aError=%d, return",aError);
+ // Animation has failed to run -> schedule the animation for
+ // deletion to fall back to normal rendering.
+ PostDeleteAnimation();
+ return;
+ }
+
+ // This situation should never happen because we start/stop animation when
+ // the extension's control is set.
+ if( !iControl )
+ {
+ _AKNTRACE("AnimFrameReady£º no iControl, return");
+ return;
+ }
+
+ // From now on, we have a valid control pointer
+ CEikListBox* list = static_cast<CEikListBox*>( iControl );
+ CListBoxView* view = list->View();
+
+ if( !view )
+ {
+ _AKNTRACE("AnimFrameReady£º no view, return");
+ return;
+ }
+
+ // We should not run animation when control is in certain states. When
+ // control is in these states we idle the animation until the control state
+ // becomes valid again.
+ TBool invalid = !iControl->IsVisible() ||
+ iControl->IsDimmed() ||
+ (view->ItemDrawer()->Flags() & CListItemDrawer::EDisableHighlight);
+
+ _AKNTRACE("AnimFrameReady£º invalid=%d", invalid);
+ // Check for idling
+ if( iAnimation->IsIdling() )
+ {
+ if( invalid )
+ {
+ // We are idling and the control is still invalid -> keep on
+ // idling.
+ return;
+ }
+ else
+ {
+ // Control is in valid state, animation should be continued
+ TInt err = iAnimation->Continue();
+ if( err )
+ PostDeleteAnimation();
+ return;
+ }
+ }
+ else if( invalid ) // Not idling and invalid control -> start idling
+ {
+ iAnimation->SetIdling( KAknsEffectAnimDefaultIdleInterval );
+ // If the highlight has been disabled, render once to clear the
+ // highlight (not returning in that case).
+ if( !(view->ItemDrawer()->Flags() & CListItemDrawer::EDisableHighlight) )
+ return;
+ }
+
+ // From now on, we have a valid control pointer and control has enabled
+ // highlight, is visible and is not dimmed.
+
+ // No items, no drawing
+ if( list->Model()->NumberOfItems() == 0 )
+ return;
+
+ if( iListBoxData->LastSubCell() < 0 )
+ return;
+
+
+
+ TBool customGcInUse = list->GetGc() != &CEikonEnv::Static()->SystemGc();
+
+ // if remoteGc is in use (CCoeControl has custom gc set)
+ // then draw the whole control as the transition system
+ // expects the draw to be initiated from CONE control
+
+ if( !customGcInUse )
+ {
+ // Repaint the highlighted cell only
+ list->RedrawItem( view->CurrentItemIndex() );
+ }
+ else
+ {
+ CCoeControl* ctrl = (CCoeControl*)list;
+ ctrl->DrawNow();
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::ListBoxItemsChanged
+//
+// this is called from from:
+// - CEikListBox::Reset()
+// - CEikListBox::HandleItemRemoval{WithoutSelections}L()
+// - CEikListBox::HandleItemAdditionL()
+// - CEikListBox::FireItemChange()
+// In all cases:
+// - feedback areas might be invalid
+// - application is responsible for redrawing the listbox.
+//
+// since re-drawing listbox fixes feedback areas, those can be reset here.
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::ListBoxItemsChanged(
+ CEikListBox* aListBox)
+ {
+ _AKNTRACE_FUNC_ENTER;
+ TInt items = aListBox->Model()->NumberOfItems();
+
+ if( iAnimation )
+ {
+ if( 0 == items )
+ {
+ DeleteAnim();
+ }
+ else
+ {
+ Play();
+ }
+ }
+ else if( !iAnimation )
+ {
+ // Animation doesn't exist and we have > 0 items
+ TryCreateAnimation();
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::DoCancel()
+ {
+ // Required method, but not needed
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::RunL
+// Postponed animation deletion is done here.
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::RunL()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ DeleteAnim();
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::Play
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::Play()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if( !iAnimation )
+ {
+ _AKNTRACE("Play: no iAnimation, return");
+ return;
+ }
+
+ // No need to start running/finished animation
+ if( EAknsAnimStateRunning == iAnimation->State() ||
+ EAknsAnimStateFinished == iAnimation->State() )
+ {
+ _AKNTRACE("Play: animation already started or finished");
+ return;
+ }
+
+ // Check that application is on foreground because there are cases where
+ // focus changes are done after foreground is lost -> potentially leads to
+ // multiple running animations.
+ if( !iAnimFlags.IsSet( EFlagHasForeground ) )
+ {
+ _AKNTRACE("Play: animation is not foreground, return");
+ return;
+ }
+
+ // Animation cannot run if we don't have control (nowhere to draw)
+ if( !iControl )
+ {
+ _AKNTRACE("Play: no iControl, return");
+ return;
+ }
+
+ // The control must also have the focus
+ if( !iControl->IsFocused() )
+ {
+ _AKNTRACE("Play: iControl doesn't have focus, return");
+ return;
+ }
+
+ // Don't animate empty list
+ CEikListBox* list = static_cast<CEikListBox*>( iControl );
+ if( list->Model()->NumberOfItems() == 0 )
+ {
+ _AKNTRACE("Play: empty list, return");
+ return;
+ }
+
+ // All preconditions are met: we have animation, foreground, focus, more
+ // than zero items and animation is either paused or stopped. Invisibility,
+ // dimming and disabled highlight are handled by idling the animation (see
+ // AnimFrameReady).
+
+ if( EAknsAnimStatePaused == iAnimation->State() )
+ {
+ NoAnimIfError( iAnimation->Continue() );
+ }
+ else if( EAknsAnimStateStopped == iAnimation->State() )
+ {
+ NoAnimIfError( iAnimation->Start() );
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::DrawHighlightBackground
+// -----------------------------------------------------------------------------
+//
+TBool CFormattedCellListBoxDataExtension::DrawHighlightBackground( CFbsBitGc& aGc )
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if( iHighlightBgDrawer ) // Bg drawing is done externally (in derived class)
+ {
+ return iHighlightBgDrawer->DrawHighlightAnimBackground( aGc );
+ }
+
+ // Draw the background under the current highlight. This is simplified
+ // drawing, we only grab a piece from the list background bitmap.
+ CEikListBox* list = static_cast<CEikListBox*>( iControl );
+ CListBoxView* view = list->View();
+ TRect itemRect;
+ TInt index = view->CurrentItemIndex();
+
+ // It is possible that the animation is constructed when the list is
+ // empty. In this case draw the first element background (drawing works ok
+ // even if the list has no items).
+ if( list->Model()->NumberOfItems() == 0 )
+ {
+ index = 0;
+ }
+ itemRect.SetRect( view->ItemPos( index ), iAnimation->Size() );
+
+ MAknsControlContext* cc = AknsDrawUtils::ControlContext( iControl );
+
+ if( !cc )
+ {
+ cc = SkinBackgroundContext();
+ }
+
+ TBool ret = AknsDrawUtils::DrawBackground( AknsUtils::SkinInstance(), cc, iControl, aGc, TPoint(0,0),
+ itemRect, KAknsDrawParamBottomLevelRGBOnly );
+ _AKNTRACE_FUNC_EXIT;
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::PostDeleteAnimation
+// Schedules the animation for deletion by activating the extension itself.
+// Deletion is postponed because in many error/failure occasions the caller has
+// been animation and direct deletion is possibly not safe (because function
+// stack would return through the deleted object).
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::PostDeleteAnimation()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::CreateAnimationL
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::CreateAnimationL()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ DeleteAnim();
+
+ // Check if derived class wants to disable highlight animation. Also, no
+ // highlight animation on lists that don't have background
+ if( ( KAknsIIDNone == iAnimIID ) ||
+ !iListBoxData->IsBackgroundDrawingEnabled() )
+ {
+ _AKNTRACE("CreateAnimationL: derived class wants to disable hightlight"
+ " or highlight animation on lists don't have background.");
+ return;
+ }
+
+ // Create animation
+ CCoeEnv* env = CCoeEnv::Static();
+ env->AddForegroundObserverL( *this );
+
+ iAnimation = CAknsEffectAnim::NewL( this );
+ TBool ok = iAnimation->ConstructFromSkinL( iAnimIID );
+
+ if( !ok ) // Animation for the ID was not found from the skin
+ {
+ _AKNTRACE("CreateAnimationL: Animation ID was not found from the skin.");
+ User::Leave( KErrNotFound );
+ }
+
+ // Sync the local foreground flag state. Foreground state is stored locally
+ // because calling AppUi::IsForeground causes WSERV flush (shocking) and
+ // therefore it cannot be used in draw routines.
+ CAknAppUi* aui = static_cast<CAknAppUi*>(CEikonEnv::Static()->AppUi());
+ iAnimFlags.Assign( EFlagHasForeground, aui->IsForeground() );
+
+ Play();
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxDataExtension::DoResizeL
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxDataExtension::DoResizeL(
+ const TSize& aHighlightSize, TBool aAboutToStart )
+ {
+ _AKNTRACE_FUNC_ENTER;
+ _AKNTRACE("DoResizeL: aHightlightSize=(%d,%d), aAboutToStart=%d",
+ aHighlightSize.iWidth, aHighlightSize.iHeight, aAboutToStart);
+ iAnimation->BeginConfigInputLayersL( aHighlightSize, aAboutToStart );
+
+ if( iAnimation->InputRgbGc() )
+ {
+ DrawHighlightBackground( *iAnimation->InputRgbGc() );
+ }
+
+ iAnimation->EndConfigInputLayersL();
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+///////////handling TSubCellExt,start
+
+TInt
+CFormattedCellListBoxDataExtension::AddSubCellExtL(TInt aSubCell)
+ {
+ TSubCellExt subcell;
+ subcell.iSubCell=aSubCell;
+ subcell.iLayoutAlign = ETrue;
+
+ TKeyArrayFix key(0,ECmpTInt);
+ return iSubCellExtArray->InsertIsqL(subcell,key);
+
+ }
+
+void
+CFormattedCellListBoxDataExtension::FindSubCellExtIndexOrAddL(
+ TInt& aArrayIndex,
+ TInt aSubCell)
+ {
+ if (FindSubCellExtIndex(aArrayIndex,aSubCell)==KErrNotFound)
+ {
+ aArrayIndex = AddSubCellExtL(aSubCell);
+ //FindSubCellExtIndex(aArrayIndex,aSubCell);
+ }
+ }
+
+void
+CFormattedCellListBoxDataExtension::SetSubCellLayoutAlignmentL(
+ TInt aSubCellIndex )
+ {
+ TInt index = 0;
+ FindSubCellExtIndexOrAddL(index,aSubCellIndex);
+ iSubCellExtArray->At(index).iLayoutAlign = EFalse;
+ }
+
+
+TInt
+CFormattedCellListBoxDataExtension::FindSubCellExtIndex(
+ TInt& aArrayIndex,
+ TInt aSubCell) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if (aSubCell<0 || iSubCellExtArray->Count()==0)
+ {
+ _AKNTRACE("FindSubCellExtIndex: aSubCell<0 || iSubCellExtArray->Count==0");
+ return(KErrNotFound);
+ }
+ TKeyArrayFix key(0,ECmpTInt);
+ TSubCellExt subcell;
+ subcell.iSubCell=aSubCell;
+ TInt retVal = iSubCellExtArray->FindIsq(subcell,key,aArrayIndex);
+ if (retVal != 0)
+ {
+ _AKNTRACE("FindSubCellExtIndex: retVal != 0");
+ return KErrNotFound;
+ }
+
+ _AKNTRACE_FUNC_EXIT;
+ return retVal;
+ }
+
+TBool
+CFormattedCellListBoxDataExtension::SubCellLayoutAlignment(
+ TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellExtIndex(index,aSubCellIndex)==KErrNotFound)
+ return (ETrue);
+ return(iSubCellExtArray->At(index).iLayoutAlign);
+ }
+
+
+
+///////////handling TSubCellExt,end
+
+void CFormattedCellListBoxDataExtension::DrawPictographArea()
+ {
+ // This callback is never invoked, if iControl is NULL.
+ iControl->DrawNow();
+ }
+
+void CFormattedCellListBoxDataExtension::CreateMarqueeControlL()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if ( !iMarquee )
+ {
+ iMarquee = CAknMarqueeControl::NewL();
+ }
+
+ if ( !i2ndLineMarquee )
+ {
+ i2ndLineMarquee = CAknMarqueeControl::NewL();
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+TInt CFormattedCellListBoxDataExtension::RedrawEvent(TAny* aControl)
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if (!((CCoeControl*)aControl)->IsVisible())
+ {
+ _AKNTRACE("RedrawEvent: control is invisible, return");
+ return EFalse;
+ }
+ CEikFormattedCellListBox* listBox =
+ (CEikFormattedCellListBox*)aControl;
+ if (listBox->CurrentItemIndex() >= 0)
+ {
+ listBox->RedrawItem(listBox->CurrentItemIndex());
+ }
+ _AKNTRACE_FUNC_EXIT;
+ return ETrue;
+ }
+
+TBool CFormattedCellListBoxDataExtension::IsMarqueeOn()
+ {
+ TBool isOn = EFalse;
+ if (iMarquee)
+ isOn = iMarquee->IsMarqueeOn();
+ return isOn;
+ }
+
+TBool CFormattedCellListBoxDataExtension::DrawPressedDownEffect(MAknsSkinInstance* aInstance,
+ CWindowGc& aGc,
+ const TRect& aOutRect,
+ const TRect& aInnerRect ) const
+ {
+ return AknsDrawUtils::DrawFrame( aInstance,
+ aGc,
+ aOutRect,
+ aInnerRect,
+ KAknsIIDQsnFrListPressed,
+ KAknsIIDQsnFrListCenterPressed );
+ }
+
+
+EXPORT_C CCoeControl *CFormattedCellListBoxData::Control() const
+ {
+ return iExtension->iControl;
+ }
+
+EXPORT_C void CFormattedCellListBoxData::SetSeparatorLinePosition(TAknSeparatorLinePosition aPosition)
+ {
+ if (iExtension)
+ iExtension->iSeparatorLinePosition = aPosition;
+ }
+EXPORT_C TAknSeparatorLinePosition CFormattedCellListBoxData::SeparatorLinePosition() const
+ {
+ if (iExtension)
+ return iExtension->iSeparatorLinePosition;
+ else
+ return ENoLine;
+ }
+EXPORT_C CAknLayoutData *CFormattedCellListBoxData::LayoutData() const
+ {
+ return NULL;
+ }
+
+EXPORT_C TBool CFormattedCellListBoxData::LayoutInit() const
+ {
+ return EFalse;
+ }
+EXPORT_C void CFormattedCellListBoxData::SetLayoutInit(TBool /*aValue*/)
+ {
+ }
+
+CFormattedCellListBoxDataExtension *CFormattedCellListBoxData::Extension() { return iExtension; }
+CFormattedCellListBoxDataExtension *CFormattedCellListBoxData::Extension() const { return iExtension; }
+
+EXPORT_C void CFormattedCellListBoxData::SetControl(CCoeControl *aControl)
+ {
+ iExtension->SetControl( aControl );
+ }
+
+EXPORT_C MAknsControlContext* CFormattedCellListBoxData::SkinBackgroundContext() const
+ {
+ if (iExtension->iSkinEnabled)
+ {
+ if (iExtension->iPopupFrame)
+ {
+ return iExtension->iPopupFrame;
+ }
+ else
+ {
+ return iExtension->iSkinControlContext;
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+
+EXPORT_C void CFormattedCellListBoxData::SetSkinEnabledL(TBool aEnabled)
+ {
+ CListBoxData::SetSkinEnabledL(aEnabled);
+ iExtension->iSkinEnabled = aEnabled;
+ }
+
+EXPORT_C TBool CFormattedCellListBoxData::SkinEnabled() const
+ {
+ return iExtension->iSkinEnabled;
+ }
+
+EXPORT_C void CFormattedCellListBoxData::SetSkinStyle(const TAknsItemID *id, const TRect &aTileRect)
+ {
+
+ if (iExtension->iSkinControlContext)
+ {
+ iExtension->iSkinControlContext->SetTiledBitmap(*id);
+ iExtension->iSkinControlContext->SetTiledRect(aTileRect);
+ }
+ }
+EXPORT_C void CFormattedCellListBoxData::SetSkinParentPos(const TPoint &aPos)
+ {
+ if (iExtension->iSkinControlContext)
+ {
+ iExtension->iSkinControlContext->SetParentPos(aPos);
+ }
+ }
+EXPORT_C void CFormattedCellListBoxData::SetBackgroundSkinStyle(const TAknsItemID *aId, const TRect &aRect)
+ {
+ if (iExtension->iSkinControlContext)
+ {
+ iExtension->iSkinControlContext->SetBitmap(*aId);
+ iExtension->iSkinControlContext->SetRect(aRect);
+ }
+ }
+EXPORT_C void CFormattedCellListBoxData::SetListEndSkinStyle(const TAknsItemID *aListEndId, const TRect &aRect)
+ {
+ if (iExtension->iSkinControlContext)
+ {
+ iExtension->iSkinControlContext->SetBottomBitmap(*aListEndId);
+ iExtension->iSkinControlContext->SetBottomRect(aRect);
+ }
+ }
+
+EXPORT_C void CFormattedCellListBoxData::SetSkinHighlightFrame(const TAknsItemID *aFrameId, const TAknsItemID *aFrameCenterId)
+ {
+ iExtension->iSkinHighlightFrameId = aFrameId;
+ iExtension->iSkinHighlightFrameCenterId = aFrameCenterId;
+ }
+
+EXPORT_C void CFormattedCellListBoxData::SetSkinPopupFrame(const TAknsItemID *aFrameId, const TAknsItemID *aFrameCenterId)
+ {
+ if (iExtension && iExtension->iPopupFrame)
+ {
+ iExtension->iPopupFrame->SetFrame(*aFrameId);
+ iExtension->iPopupFrame->SetCenter(*aFrameCenterId);
+ }
+ else
+ {
+ TRAPD(err, iExtension->iPopupFrame = CAknsFrameBackgroundControlContext::NewL(
+ KAknsIIDNone,
+ TRect(0,0,1,1), // these must be set by using SetSkinPopupFramePosition
+ TRect(0,0,1,1),
+ EFalse ) );
+ if (!err)
+ {
+ iExtension->iPopupFrame->SetFrame(*aFrameId);
+ iExtension->iPopupFrame->SetCenter(*aFrameCenterId);
+ }
+ }
+ }
+
+EXPORT_C void CFormattedCellListBoxData::SetSkinPopupFramePosition(const TRect &aOuterRect, const TRect &aInnerRect)
+ {
+ if (iExtension && iExtension->iPopupFrame)
+ iExtension->iPopupFrame->SetFrameRects(aOuterRect, aInnerRect);
+ }
+
+EXPORT_C void CFormattedCellListBoxData::UseLogicalToVisualConversion(
+ TBool aUseConversion )
+ {
+ if (iExtension)
+ iExtension->iUseLogicalToVisualConversion = aUseConversion;
+ }
+
+void CFormattedCellListBoxData::CreatePictographInterfaceL()
+ {
+ iExtension->CreatePictographInterfaceL();
+ }
+
+void CFormattedCellListBoxData::CreateMarqueeControlL()
+ {
+ TCallBack callBack(CFormattedCellListBoxDataExtension::RedrawEvent, iExtension->iControl);
+ //iExtension->iMarquee = CAknMarqueeControl::NewL();
+ iExtension->CreateMarqueeControlL();
+ iExtension->iMarquee->SetRedrawCallBack(callBack);
+ iExtension->i2ndLineMarquee->SetRedrawCallBack(callBack);
+ }
+
+const TInt KSubCellListBoxGranularity=4;
+const TInt KNoActualSubCellFont=-1;
+
+EXPORT_C
+CFormattedCellListBoxData* CFormattedCellListBoxData::NewL()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ CFormattedCellListBoxData* self=new(ELeave) CFormattedCellListBoxData;
+ self->ConstructLD( KAknsIIDQsnAnimList );
+ _AKNTRACE_FUNC_EXIT;
+ return(self);
+ }
+
+EXPORT_C
+CPopupFormattedListBoxData* CPopupFormattedListBoxData::NewL()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ CPopupFormattedListBoxData* self=new(ELeave) CPopupFormattedListBoxData;
+ self->ConstructLD( KAknsIIDQsnAnimList );
+
+ _AKNTRACE_FUNC_EXIT;
+ return(self);
+ }
+
+EXPORT_C
+CFormattedCellGridData* CFormattedCellGridData::NewL()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ CFormattedCellGridData* self=new(ELeave) CFormattedCellGridData;
+ self->ConstructLD( KAknsIIDQsnAnimGrid );
+ _AKNTRACE_FUNC_EXIT;
+ return(self);
+ }
+
+EXPORT_C
+CSettingItemEditingListBoxData* CSettingItemEditingListBoxData::NewL()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ CSettingItemEditingListBoxData* self=new(ELeave) CSettingItemEditingListBoxData;
+ self->ConstructLD( KAknsIIDQsnAnimSetOptFoc );
+ _AKNTRACE_FUNC_EXIT;
+ return(self);
+ }
+
+EXPORT_C
+CFormGraphicListBoxData* CFormGraphicListBoxData::NewL()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ CFormGraphicListBoxData* self=new(ELeave) CFormGraphicListBoxData;
+ self->ConstructLD( KAknsIIDQsnAnimList );
+ _AKNTRACE_FUNC_EXIT;
+ return(self);
+ }
+
+EXPORT_C
+CFormattedCellListBoxData::~CFormattedCellListBoxData()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ delete iExtension;
+ delete iSubCellArray;
+ if (iIconArray)
+ {
+ iIconArray->ResetAndDestroy();
+ delete iIconArray;
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+EXPORT_C TSize
+CFormattedCellListBoxData::SubCellSize(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return TSize(0,0);
+ return(iSubCellArray->At(index).iSize);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetSubCellSizeL(TInt aSubCellIndex, TSize aSize)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iSize=aSize;
+ // if someone uses this api directly, revert to old draw
+ // new api will turn this to ETrue again.
+ UseScalableLayoutData( EFalse );
+ }
+
+
+EXPORT_C TInt
+CFormattedCellListBoxData::SubCellBaselinePos(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return TInt(0);
+ return(iSubCellArray->At(index).iBaseline);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetSubCellBaselinePosL(TInt aSubCellIndex, TInt aPos)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iBaseline=aPos;
+ }
+
+
+EXPORT_C TInt
+CFormattedCellListBoxData::SubCellTextClipGap(TInt aSubCellIndex) const
+ {
+ TInt index;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return TInt(0);
+ return(iSubCellArray->At(index).iTextClipGap);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetSubCellTextClipGapL(TInt aSubCellIndex, TInt aGap)
+ {
+ TInt index;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iTextClipGap=aGap;
+ }
+
+TSize
+CFormattedCellListBoxData::SubCellRealSize(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return TSize(0,0);
+ return(iSubCellArray->At(index).iRealSize);
+ }
+
+void
+CFormattedCellListBoxData::SetSubCellRealSize(TInt aSubCellIndex, TSize aRealSize) const
+ {
+ TInt index = 0;
+ if (!(FindSubCellIndex(index, aSubCellIndex)==KErrNotFound))
+ {
+ MUTABLE_CAST(TSize&,At(index).iRealSize)=aRealSize;
+ }
+ }
+
+TSize
+CFormattedCellListBoxData::SubCellRealTextSize(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return TSize(0,0);
+ return(iSubCellArray->At(index).iRealTextSize);
+ }
+
+void
+CFormattedCellListBoxData::SetSubCellRealTextSize(TInt aSubCellIndex, TSize aRealTextSize) const
+ {
+ TInt index = 0;
+ if (!(FindSubCellIndex(index, aSubCellIndex)==KErrNotFound))
+ {
+ MUTABLE_CAST(TSize&,At(index).iRealTextSize)=aRealTextSize;
+ }
+ }
+
+EXPORT_C TPoint
+CFormattedCellListBoxData::SubCellPosition(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return TPoint(0,0);
+ return(iSubCellArray->At(index).iPosition);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetSubCellPositionL(TInt aSubCellIndex, TPoint aPosition)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iPosition=aPosition;
+ // if someone uses this api directly, revert to old draw
+ // new api will turn this to ETrue again.
+ UseScalableLayoutData( EFalse );
+ }
+
+EXPORT_C TMargins
+CFormattedCellListBoxData::SubCellMargins(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ {
+ TMargins tm = {0,0,0,0};
+ return tm;
+ }
+ return(iSubCellArray->At(index).iMargin);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetSubCellMarginsL(TInt aSubCellIndex, TMargins aMargins)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iMargin=aMargins;
+ }
+
+EXPORT_C const CFont*
+CFormattedCellListBoxData::SubCellFont(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return 0;
+ return(iSubCellArray->At(index).iBaseFont);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetSubCellFontL(TInt aSubCellIndex, const CFont* aFont)
+ {
+#if 0
+ TInt subcells=iSubCellArray->Count();
+#endif
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ if (At(index).iBaseFont != aFont)
+ {
+#if 0
+ TInt actualFontIndex=0;
+ TRAPD(err, actualFontIndex=AddActualFontL(aFont));
+ if (err)
+ {
+ if (subcells!=iSubCellArray->Count())
+ {
+ iSubCellArray->Delete(index);
+ }
+ User::Leave(err);
+ }
+ At(index).iActualFontIndex=actualFontIndex;
+#endif
+ At(index).iBaseFont=aFont;
+ }
+ }
+
+EXPORT_C CGraphicsContext::TTextAlign
+CFormattedCellListBoxData::SubCellAlignment(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return CGraphicsContext::ELeft;
+ return(iSubCellArray->At(index).iAlign);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetSubCellAlignmentL(TInt aSubCellIndex, CGraphicsContext::TTextAlign aAlign)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iAlign=aAlign;
+
+ iExtension->SetSubCellLayoutAlignmentL( aSubCellIndex );
+ }
+
+
+EXPORT_C const CFormattedCellListBoxData::TColors &
+CFormattedCellListBoxData::SubCellColors(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex) == KErrNotFound) return defaultcolors;
+ return(iSubCellArray->At(index).iColors);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetSubCellColorsL(TInt aSubCellIndex, const TColors & aColors)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iColors=aColors;
+ At(index).iUseSubCellColors = ETrue;
+ }
+
+EXPORT_C TBool CFormattedCellListBoxData::UseSubCellColors(TInt aSubCell) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index, aSubCell)==KErrNotFound) return EFalse;
+ return At(index).iUseSubCellColors;
+ }
+
+
+EXPORT_C CGraphicsContext::TPenStyle
+CFormattedCellListBoxData::SubCellRightSeparatorStyle(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return CGraphicsContext::ENullPen;
+ return(iSubCellArray->At(index).iRightSeparatorStyle);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetSubCellRightSeparatorStyleL(TInt aSubCellIndex, CGraphicsContext::TPenStyle aStyle)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iRightSeparatorStyle=aStyle;
+ }
+
+
+EXPORT_C TBool
+CFormattedCellListBoxData::SubCellIsGraphics(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return EFalse;
+ return(iSubCellArray->At(index).iGraphics);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetGraphicsSubCellL(TInt aSubCellIndex, TBool aIsGraphics)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iGraphics=aIsGraphics;
+ // if someone uses this api directly, revert to old draw
+ // new api will turn this to ETrue again.
+ UseScalableLayoutData( EFalse );
+ }
+
+
+EXPORT_C TBool
+CFormattedCellListBoxData::SubCellIsNumberCell(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return EFalse;
+ return(iSubCellArray->At(index).iNumberCell);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetNumberCellL(TInt aSubCellIndex, TBool aIsNumberCell)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iNumberCell=aIsNumberCell;
+ }
+
+
+
+EXPORT_C TBool
+CFormattedCellListBoxData::SubCellIsTransparent(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return EFalse;
+ return(iSubCellArray->At(index).iTransparent);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetTransparentSubCellL(TInt aSubCellIndex, TBool aIsTransparent)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iTransparent=aIsTransparent;
+ }
+
+
+EXPORT_C TBool
+CFormattedCellListBoxData::SubCellIsNotAlwaysDrawn(TInt aSubCellIndex) const
+ {
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)==KErrNotFound)
+ return EFalse;
+ return(iSubCellArray->At(index).iNotAlwaysDrawn);
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetNotAlwaysDrawnSubCellL(TInt aSubCellIndex, TBool aIsNotAlwaysDrawn)
+ {
+ TInt index = 0;
+ FindSubCellIndexOrAddL(index,aSubCellIndex);
+ At(index).iNotAlwaysDrawn=aIsNotAlwaysDrawn;
+ }
+
+EXPORT_C CArrayPtr<CGulIcon>*
+CFormattedCellListBoxData::IconArray() const
+ {
+ return iIconArray;
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetIconArrayL(CArrayPtr<CGulIcon>* aArray)
+ {
+ iIconArray=aArray;
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::SetIconArray(CArrayPtr<CGulIcon>* aArray)
+ {
+ iIconArray=aArray;
+ }
+
+
+EXPORT_C TBool CFormattedCellListBoxData::RespectFocus() const
+ {
+ if (iExtension)
+ return iExtension->iRespectFocus;
+ return EFalse;
+ }
+
+EXPORT_C void CFormattedCellListBoxData::SetRespectFocus(TBool aBool)
+ {
+ if (iExtension)
+ iExtension->iRespectFocus = aBool;
+ }
+
+EXPORT_C CFont*
+CFormattedCellListBoxData::Font(const TListItemProperties& /*aItemProperties*/,
+ TInt aSubCellIndex) const
+ {
+ return const_cast<CFont*>(SubCellFont(aSubCellIndex));
+#if 0
+ TInt index = 0;
+ if (FindSubCellIndex(index,aSubCellIndex)!=0/*KErrNotFound*/)
+ return(NULL);
+ TInt actualFontIndex=iSubCellArray->At(index).iActualFontIndex;
+ if (actualFontIndex==KNoActualSubCellFont)
+ return(NULL);
+ if ((aItemProperties.IsBold()) && (aItemProperties.IsItalics()))
+ {
+ return iBoldItalicFont.iFonts->At(actualFontIndex);
+ }
+ else if (aItemProperties.IsBold())
+ {
+ return iBoldFont.iFonts->At(actualFontIndex);
+ }
+ else if (aItemProperties.IsItalics())
+ {
+ return iItalicFont.iFonts->At(actualFontIndex);
+ }
+ else return iNormalFont.iFonts->At(actualFontIndex);
+#endif
+ }
+
+EXPORT_C
+void CFormattedCellGridData::Draw( TListItemProperties aProperties,
+ CWindowGc& aGc,
+ const TDesC* aText,
+ const TRect& aRect,
+ TBool aHighlight,
+ const TColors& aColors ) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ _AKNTRACE("Draw: aText=%S, aRect=(%d,%d,%d,%d)",
+ aText, aRect.iTl.iX, aRect.iTl.iY, aRect.iBr.iX, aRect.iBr.iY);
+ //
+ // Grid highlight!
+ //
+ CListBoxView* view = static_cast<CEikListBox*>( Extension()->iControl )->View();
+ TBool pressedDown = view->ItemDrawer()->Flags() & CListItemDrawer::EPressedDownState;
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal(&aGc);
+ if( aHighlight )
+ {
+ if ( transApi )
+ {
+ transApi->Invalidate(MAknListBoxTfxInternal::EListHighlight );
+ transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, aRect );
+ transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight );
+ }
+ TAknLayoutRect hiliCenter;
+ TBool windowFrameDrawn = EFalse;
+
+ hiliCenter.LayoutRect( aRect, AknLayoutScalable_Avkon::cell_highlight_pane_g1() );
+ aGc.SetPenStyle(CGraphicsContext::ENullPen);
+
+ // Try drawing the animated highlight
+ if ( Extension()->iAnimation )
+ {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ if ( transApi && transApi->VerifyKml() == KErrNone )
+ {
+ Extension()->DeleteAnim();
+ }
+ else
+ {
+ windowFrameDrawn = Extension()->SyncAndDrawAnim( aGc, aRect );
+ }
+#else //RD_UI_TRANSITION_EFFECTS_LIST
+ windowFrameDrawn = Extension()->SyncAndDrawAnim( aGc, aRect );
+#endif
+ }
+
+ if( !windowFrameDrawn )
+ {
+ // Animated highlight was not available, use normal skinned
+ // rendering.
+ MAknsSkinInstance *skin = AknsUtils::SkinInstance();
+ MAknsControlContext *cc = AknsDrawUtils::ControlContext( Control() );
+ CListBoxView* view = static_cast<CEikListBox*>( Extension()->iControl )->View();
+ if ( pressedDown )
+ {
+ windowFrameDrawn = AknsDrawUtils::DrawFrame( skin,
+ aGc,
+ aRect,
+ hiliCenter.Rect(),
+ KAknsIIDQsnFrGridPressed,
+ KAknsIIDQsnFrGridCenterPressed);
+ }
+ else
+ {
+ if (!cc) cc = SkinBackgroundContext();
+ if (cc)
+ {
+ windowFrameDrawn = AknsDrawUtils::DrawFrame(skin,
+ aGc,
+ aRect,
+ hiliCenter.Rect(),
+ KAknsIIDQsnFrGrid,
+ KAknsIIDQsnFrGridCenter);
+ }
+ }
+ }
+
+ // Both animated highlight and normal highlight drawing have failed.
+ if (!windowFrameDrawn)
+ {
+ aGc.SetPenStyle( CGraphicsContext::ESolidPen );
+ aGc.SetPenColor( KRgbBlack );
+ aGc.DrawRect( aRect );
+ }
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ if ( transApi )
+ {
+ transApi->StopDrawing();
+ transApi->EndRedraw( MAknListBoxTfxInternal::EListHighlight );
+ }
+#else //RD_UI_TRANSITION_EFFECTS_LIST
+ }
+ else // Draw without highlight
+ {
+ aGc.SetPenColor(aColors.iBack);
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+ }
+#endif
+ DrawFormatted(aProperties, aGc, aText, aRect, aHighlight, aColors);
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+
+EXPORT_C
+void CSettingItemEditingListBoxData::Draw( TListItemProperties aProperties,
+ CWindowGc& aGc,
+ const TDesC* aText,
+ const TRect& aRect,
+ TBool aHighlight,
+ const TColors& aColors ) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ _AKNTRACE("Draw: aText=%S, aRect=(%d,%d,%d,%d)",
+ aText, aRect.iTl.iX, aRect.iTl.iY, aRect.iBr.iX, aRect.iBr.iY);
+ //
+ // Setting item editing highlight!
+ //
+ MAknsSkinInstance *skin = AknsUtils::SkinInstance();
+ CCoeControl* control = Control();
+ // When this flag set, draw pressed down state and don't use animation.
+ // There are several derived CListboxData in this file. All of them do
+ // this same thing.
+ CListBoxView* view = static_cast<CEikListBox*>( Extension()->iControl )->View();
+ TBool pressedDown = view->ItemDrawer()->Flags() & CListItemDrawer::EPressedDownState;
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( &aGc );
+#endif
+
+ TBool highlightDraw = EFalse;
+
+ if ( control )
+ {
+ // Get context from setting page.
+ MAknsControlContext *context = AknsDrawUtils::ControlContext( control );
+
+ if ( !context )
+ {
+ context = SkinBackgroundContext();
+ }
+
+ const MCoeControlBackground* backgroundDrawer =
+ control->FindBackground();
+
+ if (context)
+ {
+
+ if (aHighlight)
+ {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ if ( transApi )
+ {
+ transApi->Invalidate(MAknListBoxTfxInternal::EListHighlight );
+ transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, aRect );
+ transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight );
+ }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+ if ( Extension()->iAnimation )
+ {
+ highlightDraw = Extension()->SyncAndDrawAnim( aGc, aRect );
+ }
+
+ if( !highlightDraw )
+ {
+ TAknLayoutRect innerRect;
+ innerRect.LayoutRect( aRect, AknLayoutScalable_Avkon::list_highlight_pane_g1_cp1().LayoutLine() );
+ if ( pressedDown )
+ {
+ highlightDraw = Extension()->DrawPressedDownEffect( skin, aGc, aRect, innerRect.Rect());
+ }
+ else
+ {
+ highlightDraw = AknsDrawUtils::DrawFrame( skin, aGc,
+ aRect, innerRect.Rect(),
+ KAknsIIDQsnFrSetOptFoc, KAknsIIDQsnFrSetOptFocCenter );
+ }
+ }
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ if ( transApi )
+ {
+ transApi->StopDrawing();
+ transApi->EndRedraw( MAknListBoxTfxInternal::EListHighlight );
+ }
+ }
+ if ( IsBackgroundDrawingEnabled() )
+ {
+ // Must always draw background if effects are turned on to remove highlight
+ // edges from background
+ if ( transApi && !transApi->EffectsDisabled() )
+ {
+ highlightDraw = ETrue;
+ if ( transApi->StartDrawing( MAknListBoxTfxInternal::EListView ) )
+ {
+ if ( !backgroundDrawer )
+ {
+ highlightDraw = AknsDrawUtils::Background( skin, context, control, aGc, aRect );
+ }
+ }
+ transApi->StopDrawing();
+ }
+ else if ( !aHighlight )
+ {
+ if ( !backgroundDrawer )
+ {
+ highlightDraw = AknsDrawUtils::Background( skin, context, control, aGc, aRect );
+ }
+ else
+ {
+ highlightDraw = ETrue;
+ }
+ }
+ }
+#else
+ }
+ else if( IsBackgroundDrawingEnabled() )
+ {
+ if ( !backgroundDrawer )
+ {
+ highlightDraw = AknsDrawUtils::Background( skin, context, control, aGc, aRect );
+ }
+ else
+ {
+ highlightDraw = ETrue;
+ }
+ }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+ }
+ }
+
+ if (!highlightDraw)
+ {
+ if (!IsBackgroundDrawingEnabled())
+ {
+ if ( aHighlight )
+ {
+ aGc.SetBrushColor(aColors.iHighlightedBack);
+ aGc.Clear(aRect);
+ }
+ }
+ else
+ {
+ if ( aHighlight )
+ {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ if ( transApi)
+ {
+ transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, aRect );
+ transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight );
+ }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+ aGc.SetBrushColor(aColors.iHighlightedBack);
+ }
+ else
+ {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ if ( transApi)
+ {
+ transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
+ }
+#endif // RD_UI_TRANSITION_EFFECTS_LIST
+ aGc.SetBrushColor(aColors.iBack);
+ }
+ aGc.Clear(aRect);
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ if ( transApi )
+ {
+ transApi->StopDrawing();
+ if ( aHighlight )
+ {
+ transApi->EndRedraw( MAknListBoxTfxInternal::EListHighlight );
+ }
+ }
+#endif
+ }
+ }
+
+ HBufC* buf = NULL;
+
+ if ( aHighlight && UseHighlightIconSwapping() )
+ {
+ /*
+ * list item string format: "1\tShortLabel"
+ * list item string format: "\t\tLongLabel"
+ */
+ buf = HBufC::New( aText->Size() + 1 ); // iconindex 9+1 causes length change
+
+ if ( buf )
+ {
+ TPtrC text;
+
+ TextUtils::ColumnText( text, 0, aText );
+ TLex lex( *aText );
+ TInt index;
+
+ if ( lex.Val( index ) == KErrNone && index != KColorIconFlag )
+ {
+ index += 2;
+ TextUtils::ColumnText( text, 1, aText );
+ buf->Des().Format(_L("%d\t"), index );
+ buf->Des().Append( text );
+ }
+ else
+ {
+ delete buf;
+ buf = NULL;
+ }
+ }
+ }
+
+ DrawFormatted(aProperties, aGc, buf ? buf : aText, aRect, aHighlight, aColors);
+
+ if ( buf )
+ {
+ delete buf;
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+
+EXPORT_C
+void CFormGraphicListBoxData::Draw( TListItemProperties aProperties,
+ CWindowGc& aGc,
+ const TDesC* aText,
+ const TRect& aRect,
+ TBool aHighlight,
+ const TColors& aColors ) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ // Call the base class. This is pretty safe since although layout data
+ // components for highlight are different those will in practise always
+ // have the same values -> quite a lot of duplicate code is avoided.
+ CFormattedCellListBoxData::Draw( aProperties, aGc, aText, aRect, aHighlight, aColors );
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+EXPORT_C void CFormattedCellListBoxData::Draw(TListItemProperties aProperties, CWindowGc& aGc,const TDesC* aText,const TRect& aRect,TBool aHighlight, const TColors& aColors) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ DrawDefaultHighlight(aGc, aRect, aHighlight);
+
+ // Draw the actual items.
+ DrawFormatted(aProperties,aGc,aText,aRect,aHighlight,aColors);
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+EXPORT_C void
+CFormattedCellListBoxData::DrawFormatted( TListItemProperties aProperties,
+ CWindowGc& aGc,
+ const TDesC* aText,
+ const TRect& aItemRect,
+ TBool aHighlight,
+ const TColors& aColors ) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ _AKNTRACE("DrawFormatted: aText=%S, aItemRect=(%d,%d,%d,%d)",
+ aText, aItemRect.iTl.iX, aItemRect.iTl.iY, aItemRect.iBr.iX,
+ aItemRect.iBr.iY);
+
+ CListBoxView* view = static_cast<CEikListBox*>( iExtension->iControl )->View();
+ if (!view->ViewRect().Intersects(aItemRect))
+ {
+ // outside of the clipping rect -> don't process this item
+ return;
+ }
+
+ if ( aHighlight )
+ {
+ iExtension->iClippedSubcells = 0;
+ }
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( &aGc );
+ if ( transApi )
+ {
+ transApi->StartDrawing( MAknListBoxTfxInternal::EListItem );
+ if(transApi->EffectsDisabled())
+ {
+ aGc.SetClippingRect( view->ViewRect() );
+ }
+ }
+#else
+ CListBoxView* view = static_cast<CEikListBox*>( iExtension->iControl )->View();
+ aGc.SetClippingRect( view->ViewRect() );
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+
+ if ( UsesScalableLayoutData() )
+ {
+ /* this is a AvKon list or list is created using methods in aknlists.cpp
+ * which is _the_ way to set up a list
+ */
+ DrawFormattedSimple( aProperties, aGc, aText, aItemRect, aHighlight, aColors );
+ }
+ else
+ {
+ /* someone used directly the (unfortunately) exported methods
+ * from this file. These should be fixed in such way, that
+ * DrawFormattedOld could be removed.
+ */
+ DrawFormattedOld( aProperties, aGc, aText, aItemRect, aHighlight, aColors );
+ }
+
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ if ( transApi )
+ {
+ if(transApi->EffectsDisabled())
+ {
+ aGc.CancelClippingRect();
+ }
+
+ transApi->StopDrawing();
+ }
+#else
+ aGc.CancelClippingRect();
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+
+void
+CFormattedCellListBoxData::BitBltColored( CWindowGc& aGc,
+ TBool aHighlight,
+ const CGulIcon* aIcon,
+ TInt aSubcell,
+ TBool aColorIcon,
+ const TRect& aGraphicRect ) const
+ {
+ // se also eikclbd.cpp ( sigh ).
+ CFbsBitmap* bitmap( aIcon->Bitmap() );
+ CFbsBitmap* mask( aIcon->Mask() );
+
+ // possibly colorskinnable icon. Check must be after SetSize()
+ TBool bw( bitmap->DisplayMode() == EGray2 );
+
+ // center graphics
+ TSize size=bitmap->SizeInPixels();
+ TInt yDiff = ( aGraphicRect.Height() - size.iHeight ) / 2;
+ TInt xDiff = ( aGraphicRect.Width() - size.iWidth ) / 2;
+ TPoint posInBitmap( 0,0 );
+
+ if (xDiff < 0) // icon's width bigger than subcell's width
+ { // possible, if icon is not a aknicon
+ posInBitmap.iX = -xDiff;
+ xDiff = 0;
+ }
+
+ if (yDiff < 0) // icon's height bigger than subcell's height
+ {
+ posInBitmap.iY = -yDiff;
+ yDiff = 0;
+ }
+
+ TPoint bmpPos( aGraphicRect.iTl + TPoint( xDiff, yDiff ) );
+ TRect sourcerect( posInBitmap, aGraphicRect.Size() );
+
+ if ( mask )
+ {
+ TInt i( 0x01 );
+ i = i << aSubcell;
+ if ( ((i & iExtension->iConditionalCells) && bw) || aColorIcon )
+ {
+ aGc.BitBltMasked( bmpPos,
+ aHighlight ? iExtension->iHiliBmp : iExtension->iColorBmp,
+ TRect(posInBitmap, size), mask, ETrue );
+ }
+ else
+ {
+ aGc.BitBltMasked( bmpPos, bitmap, sourcerect, mask, ETrue );
+ }
+ }
+ else
+ {
+ aGc.BitBlt( bmpPos, bitmap ,sourcerect );
+ }
+ }
+
+
+void
+CFormattedCellListBoxData::DrawFormattedSimple( TListItemProperties& aProperties,
+ CWindowGc& aGc,
+ const TDesC* aText,
+ const TRect& aItemRect,
+ TBool aHighlight,
+ const TColors& aColors ) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ _AKNTRACE("DrawFormattedSimple: aText=%S, aItemRect=(%d,%d,%d,%d)",
+ aText, aItemRect.iTl.iX, aItemRect.iTl.iY, aItemRect.iBr.iX,
+ aItemRect.iBr.iY);
+
+ TRect textRect(aItemRect);
+ const TColors *subcellColors = &aColors;
+
+ TInt lastSubCell = Min( LastSubCell(), KMaxSubCellIndex );
+
+ TInt subcell=0;
+ TPtrC text;
+ TPtrC tempText;
+ TRect textShadowRect; // For transparent list
+ TRgb textShadowColour = AKN_LAF_COLOR_STATIC(215); // Black shadow for item text.
+
+ MAknsControlContext *cc = AknsDrawUtils::ControlContext( Control() );
+ if (!cc)
+ {
+ cc = SkinBackgroundContext();
+ }
+
+ TAknTextLineLayout textLines[KMaxSubCellIndex];
+ TBool rectClipped[KMaxSubCellIndex];
+
+ Mem::FillZ( &rectClipped[0], KMaxSubCellIndex * sizeof( TBool ) );
+
+ if ( iExtension->iSubCellsMightIntersect )
+ {
+ CheckIfSubCellsIntersect( &textLines[0], &rectClipped[0], *aText, aItemRect );
+ }
+
+ TInt SCindex=0;
+
+ // This loop does the drawing.
+ aGc.SetPenStyle(CGraphicsContext::ENullPen);
+ subcell=0;
+ FOREVER
+ {
+ if (subcell>lastSubCell)
+ {
+ break;
+ }
+
+ TextUtils::ColumnText(text,subcell, aText);
+ if (text == KNullDesC)
+ {
+ // empty subcell, continue to draw next subcell
+ ++ subcell;
+ continue;
+ }
+ if (!iExtension) break;
+ if (iExtension->FindSLSubCellIndex(SCindex,subcell)!=0) break;
+
+ if (UseSubCellColors(subcell))
+ {
+ subcellColors = &SubCellColors(subcell);
+ }
+ else
+ {
+ subcellColors = &aColors;
+ }
+
+ TRgb color;
+
+ if (aHighlight)
+ {
+ color = subcellColors->iHighlightedText;
+ aGc.SetBrushColor(subcellColors->iHighlightedBack);
+ if ( AknsUtils::AvkonSkinEnabled() )
+ {
+ if ( iExtension->iHighlightedTextColor != NULL )
+ {
+ color = iExtension->iHighlightedTextColor;
+ }
+ }
+ }
+ else
+ {
+ color = subcellColors->iText;
+ aGc.SetBrushColor(subcellColors->iBack);
+ if ( AknsUtils::AvkonSkinEnabled() )
+ {
+ if ( iExtension->iTextColor != NULL )
+ {
+ color = iExtension->iTextColor;
+ }
+ }
+ }
+
+ // graphics or text column
+ if (iExtension->AtSL(SCindex).iSubCellType == CFormattedCellListBoxDataExtension::EAknSLText)
+ {
+ const CFont* rowAndCellFont=RowAndSubCellFont(iExtension->iCurrentlyDrawnItemIndex,subcell);
+ const CFont* cellFont=Font(aProperties, subcell);
+ const CFont* tempFont=(cellFont) ? cellFont : NULL;
+ const CFont* usedFont=(rowAndCellFont) ? rowAndCellFont : tempFont;
+
+ TAknTextLineLayout textLineLayout = NULL;
+
+ if ( rectClipped[subcell] )
+ {
+ textLineLayout = textLines[subcell];
+ }
+ else
+ {
+ // check if there are icons affecting this text layout
+ TInt gSC = iExtension->AtSL(SCindex).iConditionValue; // graphical subcell which might affect this text subcell
+
+ if (gSC > -1)
+ {
+ TInt tempIndex;
+ while (gSC > -1) // when gSC == -1, we have found our graphical subcell
+ {
+ if (iExtension->FindSLSubCellIndex(tempIndex,gSC)!=0) break;
+ TextUtils::ColumnText(tempText,gSC, aText);
+ if (tempText != KNullDesC)
+ {
+ textLineLayout = iExtension->AtSL(tempIndex).iTextLayout;
+ break;
+ }
+ gSC = iExtension->AtSL(tempIndex).iConditionValue;
+ }
+ }
+
+ if (gSC == -1) // no affecting icons -> use default layout
+ {
+ textLineLayout = iExtension->AtSL(SCindex).iTextLayout;
+ }
+ }
+
+
+ CGraphicsContext::TTextAlign align=SubCellAlignment(subcell); //gumq
+ TBool isLayoutAlignment = iExtension->SubCellLayoutAlignment(subcell); //gumq
+ if( !isLayoutAlignment )
+ {
+ switch(align)
+ {
+ case CGraphicsContext::ELeft :
+ {
+ textLineLayout.iJ = ELayoutAlignLeft;
+ }
+ break;
+ case CGraphicsContext::ECenter:
+ {
+ textLineLayout.iJ = ELayoutAlignCenter;
+ }
+ break;
+ case CGraphicsContext::ERight:
+ {
+ textLineLayout.iJ = ELayoutAlignRight;
+ }
+ break;
+ default: break;
+ };
+ }
+
+ TAknLayoutText textLayout;
+ textLayout.LayoutText(textRect, textLineLayout, usedFont);
+
+ SetUnderlineStyle( aProperties, aGc, subcell );
+
+ // * 2 == leave some room for marquee
+ const TInt maxlen( KMaxColumnDataLength * 2 );
+ TBuf<maxlen> convBuf = text.Left(maxlen);
+
+ // Note that this potentially modifies the text so its lenght in pixels
+ // might increase. Therefore, this should always be done before
+ // wrapping/clipping text. In some cases, WordWrapListItem is called
+ // before coming here. Is it certain that it is not done for number subcells?
+
+ // Do number conversion if required.
+ if (SubCellIsNumberCell(subcell))
+ {
+ AknTextUtils::LanguageSpecificNumberConversion(convBuf);
+ }
+
+ // Check whether logical to visual conversion should be done here or not.
+ TBool bidiConv =
+ iExtension->iUseLogicalToVisualConversion &&
+ subcell != iExtension->iFirstWordWrappedSubcellIndex &&
+ subcell != iExtension->iSecondWordWrappedSubcellIndex;
+
+ TBool doesNotFit( EFalse );
+ if ( aHighlight )
+ {
+ doesNotFit = usedFont->TextWidthInPixels( convBuf ) > textLayout.TextRect().Width();
+
+ if ( doesNotFit )
+ {
+ iExtension->iClippedSubcells |= ( 1 << subcell );
+ }
+ else
+ {
+ iExtension->iClippedSubcells &= ~( 1 << subcell );
+ }
+
+ if ( iExtension->iUseClippedByWrap ) // override if already clipped
+ {
+ iExtension->iClippedSubcells = iExtension->iClippedByWrap;
+ }
+ }
+
+
+ // marquee
+ CAknMarqueeControl* marquee =
+ subcell == 1 || subcell == 3 ? iExtension->iMarquee :
+ iExtension->i2ndLineMarquee;
+ TBool marqueeDisabled =
+ static_cast<CEikListBox*>(
+ Control() )->View()->ItemDrawer()->Flags() & CListItemDrawer::EDisableMarquee;
+
+ if ( aHighlight && iExtension->IsMarqueeOn() && doesNotFit && !marqueeDisabled )
+ {
+ iExtension->iMarquee->UseLogicalToVisualConversion( bidiConv );
+
+ if ( marquee->DrawText( aGc, textRect, textLineLayout, convBuf, usedFont, color ) )
+ {
+ // all the loops have been executed
+ textLayout.DrawText( aGc, convBuf, bidiConv, color );
+ }
+ }
+ else
+ {
+ if ( marquee && marqueeDisabled )
+ {
+ marquee->Stop();
+ }
+
+ textLayout.DrawText( aGc, convBuf, bidiConv, color );
+ }
+
+ if ( iExtension->iPictoInterface )
+ {
+
+ TRect pictoRect = textLayout.TextRect();
+ pictoRect.Normalize();
+ if ( convBuf.Length() && bidiConv )
+ {
+ TInt maxWidth = pictoRect.Size().iWidth;
+ TInt charsCanBeDisplayed = textLayout.Font()->TextCount(
+ convBuf, maxWidth );
+ if ( charsCanBeDisplayed < convBuf.Length() )
+ {
+ TInt clipCharWidth = textLayout.Font()->CharWidthInPixels(
+ KEllipsis /*aClipChar*/ );
+ // Check how many characters fit in given space with truncation char.
+ charsCanBeDisplayed = textLayout.Font()->TextCount(
+ convBuf, maxWidth - clipCharWidth );
+
+ // This is "avkon rule": should not insert ellipsis right after a space.
+ if ( charsCanBeDisplayed > 1 &&
+ convBuf[charsCanBeDisplayed - 1] == ' ' &&
+ convBuf[charsCanBeDisplayed - 2] != ' ' )
+ {
+ charsCanBeDisplayed--;
+ }
+
+ TInt pictoRectWidth = textLayout.Font()->TextWidthInPixels(
+ convBuf.Left( charsCanBeDisplayed ) );
+ pictoRect.SetWidth( pictoRectWidth );
+ }
+ }
+
+
+ iExtension->iPictoInterface->Interface()->DrawPictographsInText(
+ aGc, *usedFont, convBuf,
+ pictoRect,
+ textLayout.BaselineOffset(),
+ textLayout.Align(),
+ 0 );
+ }
+
+ aGc.SetUnderlineStyle( EUnderlineOff );
+ }
+ else // Graphics subcell
+ {
+ TLex lex(text);
+ TInt index;
+ TInt indexValue;
+
+ indexValue=lex.Val(index);
+
+ if (indexValue!=KErrNone)
+ {
+ // wrong icon index
+ ++ subcell;
+ continue;
+ }
+
+ __ASSERT_DEBUG(indexValue==KErrNone, Panic(EAknPanicFormattedCellListInvalidBitmapIndex));
+
+ TBool colorIcon( EFalse );
+ if ( index == KColorIconFlag )
+ {
+ if ( iExtension->iColorBmp && iExtension->iHiliBmp )
+ {
+ colorIcon = ETrue;
+ }
+ index = KColorIconIdx;
+ }
+
+ if( !iIconArray )
+ {
+ ++ subcell;
+ continue;
+ }
+
+ if (aHighlight && (index > 0xffff))
+ {
+ index = index >> 16; // we have different icon for highlight
+ }
+
+ index = index & 0xffff; // mask off possible highlight icon
+ __ASSERT_DEBUG((index>=0 && index<iIconArray->Count()),Panic(EAknPanicFormattedCellListInvalidBitmapIndex));
+
+ TAknWindowLineLayout graphicLayout = iExtension->AtSL(SCindex).iGraphicLayout;
+ TAknLayoutRect graphicRect;
+
+ graphicRect.LayoutRect(textRect,graphicLayout);
+ TSize graphicSize( graphicRect.Rect().Size() );
+
+ if (index>=0 && iIconArray)
+ {
+ CGulIcon* icon=(*iIconArray)[index];
+ CFbsBitmap* bitmap=icon->Bitmap();
+ // Sometimes we get fake bitmap...
+ if ( bitmap )
+ {
+ TSize size( bitmap->SizeInPixels() ); // set size if not already
+ if ( size.iWidth != graphicSize.iWidth && size.iHeight != graphicSize.iHeight )
+ {
+ AknIconUtils::SetSize( bitmap,
+ graphicSize,
+ EAspectRatioPreservedAndUnusedSpaceRemoved);
+ }
+ BitBltColored( aGc, aHighlight, icon, subcell, colorIcon, graphicRect.Rect() );
+ aGc.SetPenStyle(CGraphicsContext::ESolidPen);
+ }
+ }
+ }
+ ++subcell;
+ }
+
+ // Clear information of wordwrapped and bidi-reordered subcells.
+ const_cast<CFormattedCellListBoxData*>( this )->
+ SetWordWrappedSubcellIndices( -1, -1 );
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+
+EXPORT_C
+CFormattedCellListBoxData::CFormattedCellListBoxData()
+ : CListBoxData()
+ {
+ }
+
+EXPORT_C void CFormattedCellListBoxData::ConstructLD()
+ {
+ TRAPD( err, DoConstructL( KAknsIIDQsnAnimList ) );
+ if( err )
+ {
+ delete(this);
+ User::Leave( err );
+ }
+ }
+
+EXPORT_C void CFormattedCellListBoxData::ConstructLD(
+ const TAknsItemID& aAnimationIID )
+ {
+ TRAPD( err, DoConstructL( aAnimationIID ) );
+ if( err )
+ {
+ delete(this);
+ User::Leave( err );
+ }
+ }
+
+void CFormattedCellListBoxData::DoConstructL( const TAknsItemID& aAnimationIID )
+ {
+ iSubCellArray = new(ELeave) CArrayFixFlat<SSubCell>(KSubCellListBoxGranularity);
+ iExtension = new(ELeave) CFormattedCellListBoxDataExtension;
+
+ iExtension->iSkinEnabled = AknsUtils::AvkonSkinEnabled();
+ SetupSkinContextL();
+
+ // Preallocate so that SizeChanged() methods do not leave so often.
+ CListBoxData::ConstructL(NULL);
+ iExtension->ConstructL( this, aAnimationIID );
+ CListBoxData::SetSkinBackgroundControlContextL(iExtension->iSkinControlContext);
+ AddSubCellL(0);
+ AddSubCellL(1);
+ AddSubCellL(2);
+ AddSubCellL(3);
+ AddSubCellL(4);
+ }
+
+TInt CFormattedCellListBoxData::LastSubCell() const
+ {
+ TInt count=iSubCellArray->Count(); if (!count)
+ return(KErrNotFound);
+ return(At(count-1).iSubCell);
+ }
+
+void
+CFormattedCellListBoxData::AddSubCellL(TInt aSubCell)
+ {
+ _AKNTRACE_FUNC_ENTER;
+ _AKNTRACE("AddSubCellL: aSubCell=%d",aSubCell);
+ SSubCell subcell;
+ TMargins m={0,0,0,0};
+ subcell.iSubCell=aSubCell;
+ subcell.iWidth=0;
+ subcell.iMargin=m;
+ subcell.iBaseFont=NULL;
+ subcell.iActualFontIndex=KNoActualSubCellFont;
+ subcell.iGraphics=EFalse;
+ subcell.iTransparent=EFalse;
+ subcell.iNotAlwaysDrawn=EFalse;
+ subcell.iRightSeparatorStyle = CGraphicsContext::ENullPen;
+ subcell.iAlign=CGraphicsContext::ELeft;
+ subcell.iPosition=TPoint(0,0);
+ subcell.iBaseline = 0;
+ subcell.iSize=TSize(0,0);
+ subcell.iUseSubCellColors = EFalse;
+ subcell.iTextClipGap = 0;
+ subcell.iNumberCell = 0;
+ TKeyArrayFix key(0,ECmpTInt);
+ iSubCellArray->InsertIsqL(subcell,key);
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+CFormattedCellListBoxData::SSubCell&
+CFormattedCellListBoxData::At(TInt aArrayIndex)
+ {
+ __ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iSubCellArray->Count(),Panic(EAknPanicOutOfRange));
+ return(iSubCellArray->At(aArrayIndex));
+ }
+
+const CFormattedCellListBoxData::SSubCell&
+CFormattedCellListBoxData::At(TInt aArrayIndex) const
+ {
+ __ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iSubCellArray->Count(),Panic(EAknPanicOutOfRange));
+ return(iSubCellArray->At(aArrayIndex));
+ }
+
+TInt
+CFormattedCellListBoxData::FindSubCellIndex(TInt& aArrayIndex,TInt aSubCell) const
+ {
+ if (aSubCell<0 || iSubCellArray->Count()==0)
+ return(KErrNotFound);
+ TKeyArrayFix key(0,ECmpTInt);
+ SSubCell subcell;
+ subcell.iSubCell=aSubCell;
+ TInt retVal = iSubCellArray->FindIsq(subcell,key,aArrayIndex);
+ if (retVal != 0)
+ {
+ return KErrNotFound;
+ }
+
+ return retVal;
+ }
+
+void
+CFormattedCellListBoxData::FindSubCellIndexOrAddL(TInt& aArrayIndex,TInt aSubCell)
+ {
+ if (FindSubCellIndex(aArrayIndex,aSubCell)==KErrNotFound)
+ {
+ AddSubCellL(aSubCell);
+ FindSubCellIndex(aArrayIndex,aSubCell);
+ }
+ }
+
+
+EXPORT_C
+CFormattedCellListBoxData::TColors::TColors()
+ : iText(KRgbBlack), iBack(KRgbWhite), iHighlightedText(KRgbWhite), iHighlightedBack(KRgbBlack),
+ iRightSeparatorColor(AKN_LAF_COLOR_STATIC(215))
+ {
+ }
+
+
+
+TInt CFormattedCellListBoxData::AddActualFontL(const CFont* aBaseFont)
+ {
+ _AKNTRACE_FUNC_ENTER;
+ if (!iNormalFont.iFonts)
+ {
+ iNormalFont.iFonts=new (ELeave) CArrayPtrFlat<CFont> (1);
+ iBoldFont.iFonts=new (ELeave) CArrayPtrFlat<CFont> (1);
+ iItalicFont.iFonts=new (ELeave) CArrayPtrFlat<CFont> (1);
+ iBoldItalicFont.iFonts=new (ELeave) CArrayPtrFlat<CFont> (1);
+ }
+
+ // Reserves extra space for each font array.
+ TInt fontCount=iNormalFont.iFonts->Count()+1;
+ iNormalFont.iFonts->SetReserveL(fontCount);
+ iBoldFont.iFonts->SetReserveL(fontCount);
+ iItalicFont.iFonts->SetReserveL(fontCount);
+ iBoldItalicFont.iFonts->SetReserveL(fontCount);
+
+ // Add Fonts.
+ ConstructFontL(aBaseFont, TFontStyle(EPostureUpright, EStrokeWeightNormal, EPrintPosNormal), iNormalFont);
+ ConstructFontL(aBaseFont, TFontStyle(EPostureUpright, EStrokeWeightBold, EPrintPosNormal), iBoldFont);
+ ConstructFontL(aBaseFont, TFontStyle(EPostureItalic, EStrokeWeightNormal, EPrintPosNormal), iItalicFont);
+ ConstructFontL(aBaseFont, TFontStyle(EPostureItalic, EStrokeWeightBold, EPrintPosNormal), iBoldItalicFont);
+
+ _AKNTRACE_FUNC_EXIT;
+ return fontCount-1;
+ }
+
+EXPORT_C void CPopupFormattedListBoxData::Draw(TListItemProperties aProperties, CWindowGc& aGc,const TDesC* aText,const TRect& aRect,TBool aHighlight, const TColors& aColors) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ const TRect &aItemRect = aRect;
+
+ DrawPopupHighlight(aGc, aItemRect, aHighlight);
+
+ // Draw the actual items.
+ DrawFormatted(aProperties,aGc,aText,aItemRect,aHighlight,aColors);
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+void CFormattedCellListBoxData::DrawDefaultHighlight(CWindowGc &aGc, const TRect &aItemRect, TBool aHighlight) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ // When this flag set, draw pressed down state and don't use animation.
+ // There are several derived CListboxData in this file. All of them do
+ // this same thing.
+ CListBoxView* view = static_cast<CEikListBox*>( iExtension->iControl )->View();
+ TBool pressedDown = view->ItemDrawer()->Flags() & CListItemDrawer::EPressedDownState;
+
+ if( aHighlight )
+ {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( &aGc );
+ if ( transApi )
+ {
+ transApi->Invalidate(MAknListBoxTfxInternal::EListHighlight );
+ if ( !transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight,
+ aItemRect ) )
+ {
+ // No need to execute drawing if no drawing will occur
+ transApi->EndRedraw( MAknListBoxTfxInternal::EListHighlight );
+ return;
+ }
+ transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight );
+ }
+#endif //RD_UI_TRANSITION_EFFECTS_LIST
+
+ TBool highlightDrawn = EFalse;
+
+ TAknLayoutRect outerRect;
+ TAknLayoutRect innerRect;
+ outerRect.LayoutRect( aItemRect, TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Avkon::list_highlight_pane_cp1(),
+ AknLayoutScalable_Avkon::list_highlight_pane_g10_cp1() ).LayoutLine() );
+ innerRect.LayoutRect( aItemRect, TAknWindowComponentLayout::Compose(
+ AknLayoutScalable_Avkon::list_highlight_pane_cp1(),
+ AknLayoutScalable_Avkon::list_highlight_pane_g1_cp1() ).LayoutLine() );
+
+ if ( iExtension->iAnimation ) // animated highlight
+ {
+ aGc.SetPenStyle( CGraphicsContext::ENullPen );
+ highlightDrawn = iExtension->SyncAndDrawAnim( aGc, outerRect.Rect() );
+ }
+
+ if ( !highlightDrawn ) // normal skinned highlight
+ {
+ if ( pressedDown )
+ {
+ highlightDrawn = iExtension->DrawPressedDownEffect( AknsUtils::SkinInstance(), aGc, outerRect.Rect(), innerRect.Rect() );
+ }
+ else
+ {
+ MAknsControlContext *cc = AknsDrawUtils::ControlContext( Control() );
+
+ if ( !cc )
+ {
+ cc = SkinBackgroundContext();
+ }
+
+ if ( cc )
+ {
+
+
+ aGc.SetPenStyle( CGraphicsContext::ENullPen );
+
+ highlightDrawn = AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(),
+ aGc,
+ outerRect.Rect(),
+ innerRect.Rect(),
+ *iExtension->iSkinHighlightFrameId,
+ *iExtension->iSkinHighlightFrameCenterId );
+ }
+ }
+ }
+
+ if ( !highlightDrawn ) // legacy fallback
+ {
+ TRgb color( AKN_LAF_COLOR( 244 ) );
+ aGc.SetPenColor( color );
+ aGc.SetBrushColor( color );
+ aGc.SetPenStyle( CGraphicsContext::ESolidPen );
+ aGc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+ aGc.DrawRect( aItemRect );
+ }
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ if ( transApi )
+ {
+ transApi->StopDrawing();
+ transApi->EndRedraw( MAknListBoxTfxInternal::EListHighlight );
+ }
+#endif
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+void CFormattedCellListBoxData::DrawSettingHighlight(CWindowGc &aGc, const TRect &aItemRect, TBool aHighlight) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ DrawDefaultHighlight( aGc, aItemRect, aHighlight );
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+void CFormattedCellListBoxData::DrawPopupHighlight(CWindowGc &aGc, const TRect &aItemRect, TBool aHighlight) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ DrawDefaultHighlight( aGc, aItemRect, aHighlight );
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+void CFormattedCellListBoxData::DrawPopupFrame(CWindowGc &aGc) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ CCoeControl* control = Control();
+
+ if ( control )
+ {
+ aGc.SetPenStyle( CGraphicsContext::ENullPen );
+
+ TBool done = AknsDrawUtils::Background( AknsUtils::SkinInstance(),
+ iExtension->iPopupFrame,
+ control,
+ aGc,
+ control->Rect() );
+
+ if ( !done )
+ {
+ aGc.Clear( control->Rect() );
+ }
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+void CFormattedCellListBoxData::SetWordWrappedSubcellIndices(
+ TInt aFirstIndex,
+ TInt aSecondIndex )
+ {
+ iExtension->iFirstWordWrappedSubcellIndex = (TInt16)aFirstIndex;
+ iExtension->iSecondWordWrappedSubcellIndex = (TInt16)aSecondIndex;
+ }
+
+EXPORT_C void CFormattedCellListBoxData::EnableMarqueeL(TBool aEnable)
+ {
+ // CreateMarqueeControlL does nothing if marquee already exists,
+ // so let's just call it just in case.
+ CreateMarqueeControlL();
+ iExtension->iMarquee->EnableMarquee(aEnable);
+ iExtension->i2ndLineMarquee->EnableMarquee(aEnable);
+ }
+
+// Two versions to eliminate compiler warnings.
+#ifdef __WINS__
+EXPORT_C const TBool CFormattedCellListBoxData::IsMarqueeOn()
+ {
+ return iExtension->IsMarqueeOn();
+ }
+#else
+EXPORT_C TBool CFormattedCellListBoxData::IsMarqueeOn()
+ {
+ return iExtension->IsMarqueeOn();
+ }
+#endif // __WINS__
+
+
+void CFormattedCellListBoxData::FocusGained()
+ {
+ iExtension->FocusGained();
+ }
+
+void CFormattedCellListBoxData::FocusLost()
+ {
+ iExtension->FocusLost();
+ }
+
+void CFormattedCellListBoxData::HandleResourceChange( TInt aType )
+ {
+ _AKNTRACE_FUNC_ENTER;
+ // Animation is skin dependent, whenever skin changes animation changes
+ // too.
+ if( KAknsMessageSkinChange == aType )
+ {
+ iExtension->SkinChanged();
+ }
+ else if(aType == KEikDynamicLayoutVariantSwitch)
+ {
+ // What is under highlight may have changed -> we need to update
+ // highlight background to animation.
+ iExtension->iAnimFlags.Set( CFormattedCellListBoxDataExtension::EFlagUpdateBg );
+ }
+ else if( ( aType == KEikMessageUnfadeWindows ) ||
+ ( aType == KEikMessageFadeAllWindows ) )
+ {
+ if( iExtension->iMarquee )
+ {
+ iExtension->iMarquee->HandleResourceChange( aType );
+ }
+ if( iExtension->i2ndLineMarquee )
+ {
+ iExtension->i2ndLineMarquee->HandleResourceChange( aType );
+ }
+ }
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::HighlightAnim
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const CAknsEffectAnim* CFormattedCellListBoxData::HighlightAnim() const
+ {
+ if( iExtension )
+ return iExtension->iAnimation;
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::AboutToDrawHighlightAnim
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CFormattedCellListBoxData::AboutToDrawHighlightAnim() const
+ {
+ if( !iExtension )
+ {
+ return;
+ }
+ if( !iExtension->iAnimation || !iExtension->iControl )
+ {
+ return;
+ }
+
+ CEikListBox* list = static_cast<CEikListBox*>( iExtension->iControl );
+ CListBoxView* view = list->View();
+ if( !view )
+ {
+ return;
+ }
+
+ if( view->CurrentItemIndex() != iExtension->iCurrentRow )
+ {
+ iExtension->iAnimFlags.Set( CFormattedCellListBoxDataExtension::EFlagUpdateBg );
+ iExtension->iCurrentRow = view->CurrentItemIndex();
+ }
+
+ iExtension->SyncAnim( iExtension->iAnimSize );
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::SetHighlightAnimBackgroundDrawer
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CFormattedCellListBoxData::SetHighlightAnimBackgroundDrawer(
+ MListBoxAnimBackgroundDrawer* aDrawer )
+ {
+ if( iExtension )
+ {
+ iExtension->iHighlightBgDrawer = aDrawer;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::SetItemCellSize
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CFormattedCellListBoxData::SetItemCellSize( const TSize& aSize )
+ {
+ if( iExtension )
+ {
+ if( iExtension->iAnimSize != aSize )
+ {
+ iExtension->Play();
+ }
+ iExtension->iAnimSize = aSize;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::HasHighlightAnim
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CFormattedCellListBoxData::HasHighlightAnim() const
+ {
+ if( !iExtension )
+ return EFalse;
+ if( !iExtension->iAnimation )
+ return EFalse;
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::DrawHighlightAnim
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool CFormattedCellListBoxData::DrawHighlightAnim(
+ CBitmapContext& aGc, const TRect& aRect ) const
+ {
+ if( !iExtension )
+ return EFalse;
+
+ if( !iExtension->iAnimation )
+ return EFalse;
+
+ return iExtension->SyncAndDrawAnim( aGc, aRect );
+ }
+
+void CFormattedCellListBoxData::ResetMarquee()
+ {
+ if (iExtension->iMarquee)
+ {
+ iExtension->iMarquee->Reset();
+ }
+ if (iExtension->i2ndLineMarquee)
+ {
+ iExtension->i2ndLineMarquee->Reset();
+ }
+ }
+
+TInt CFormattedCellListBoxData::CurrentMarqueeItemIndex()
+ {
+ return iExtension->iCurrentItem;
+ }
+
+void CFormattedCellListBoxData::SetCurrentMarqueeItemIndex(TInt aIndex)
+ {
+ _AKNTRACE("CFormattedCellListBoxData::SetCurrentMarqueeItemIndex aIndex=%d",
+ aIndex);
+
+ iExtension->iCurrentItem = aIndex;
+ }
+
+void CFormattedCellListBoxData::SetCurrentItemIndex(TInt aIndex)
+ {
+ _AKNTRACE("CFormattedCellListBoxData::SetCurrentItemIndex aIndex=%d", aIndex);
+ if( iExtension->iCurrentRow != aIndex )
+ {
+ iExtension->iAnimFlags.Set( CFormattedCellListBoxDataExtension::EFlagUpdateBg );
+ }
+ iExtension->iCurrentRow = aIndex;
+ }
+
+void CFormattedCellListBoxData::SetCurrentlyDrawnItemIndex( TInt aIndex )
+ {
+ _AKNTRACE("CFormattedCellListBoxData::SetCurrentlyDrawnItemIndex aIndex=%d",
+ aIndex);
+ if ( iExtension )
+ {
+ iExtension->iCurrentlyDrawnItemIndex = aIndex;
+ }
+ }
+
+EXPORT_C const CFont*
+CFormattedCellListBoxData::RowAndSubCellFont(TInt aRow,TInt aSubCellIndex) const
+ {
+ if (!iExtension) return 0;
+ TInt index = 0;
+ if (iExtension->FindRowAndSubCellIndex(index,aRow,aSubCellIndex)!=0)
+ return 0;
+ return(iExtension->At(index).iFont);
+ }
+
+EXPORT_C void CFormattedCellListBoxData::SetSubCellFontForRowL(TInt aRowIndex,
+ TInt aSubCellIndex,
+ const CFont* aFont)
+ {
+ if (!iExtension) return;
+ TInt index = 0;
+ iExtension->FindRowAndSubCellIndexOrAddL(index,aRowIndex,aSubCellIndex);
+ iExtension->At(index).iFont=aFont;
+ }
+
+/**
+* Enables / disables transparency effect, ie. does the listbox draw it's own background or not.
+* @param aDrawBackground EFalse enables transparency
+*/
+EXPORT_C void CFormattedCellListBoxData::SetDrawBackground(const TBool aDrawBackground)
+ {
+ iExtension->iDrawBackground = aDrawBackground;
+ if( !aDrawBackground )
+ {
+ iExtension->DeleteAnim();
+ }
+ }
+
+/**
+* Is the listbox drawing the background itself or not (= "transparency")
+*/
+TBool CFormattedCellListBoxData::IsBackgroundDrawingEnabled() const
+ {
+ return iExtension->iDrawBackground;
+ }
+
+
+/**
+* Enables / disables drawing background after scrollbar
+* @param aDrawBackground default ETrue
+*/
+void CFormattedCellListBoxData::SetDrawScrollbarBackground(const TBool aDrawBackground)
+ {
+ iExtension->iDrawScrollbarBackground = aDrawBackground;
+ }
+
+/**
+* Is the listbox drawing the background after scrollbar or not
+*/
+TBool CFormattedCellListBoxData::IsScrollbarBackgroundDrawingEnabled() const
+ {
+ return iExtension->iDrawScrollbarBackground;
+ }
+
+
+EXPORT_C void CFormattedCellListBoxData::SetMarqueeParams(const TInt aLoops, const TInt aScrollAmount,
+ const TInt aScrollDelay, const TInt aInterval)
+ {
+ if ( iExtension->iMarquee )
+ {
+ iExtension->iMarquee->SetLoops( aLoops );
+ iExtension->iMarquee->SetSpeedInPixels( aScrollAmount );
+ iExtension->iMarquee->SetDelay( aScrollDelay );
+ iExtension->iMarquee->SetInterval( aInterval );
+ }
+ if ( iExtension->i2ndLineMarquee )
+ {
+ iExtension->i2ndLineMarquee->SetLoops( aLoops );
+ iExtension->i2ndLineMarquee->SetSpeedInPixels( aScrollAmount );
+ iExtension->i2ndLineMarquee->SetDelay( aScrollDelay );
+ iExtension->i2ndLineMarquee->SetInterval( aInterval );
+ }
+ }
+
+
+EXPORT_C void CFormattedCellListBoxData::SetSubCellIconSize(TInt aIndex, TSize aSize)
+ {
+ if (iExtension && aIndex <= KMaxSubCellIndex && aIndex >= 0)
+ {
+ iExtension->iSubCellIconSize[aIndex] = aSize;
+ }
+ }
+
+TSize CFormattedCellListBoxData::GetSubCellIconSize(TInt aIndex)
+ {
+ if (iExtension && aIndex <= KMaxSubCellIndex && aIndex >= 0)
+ {
+ return iExtension->iSubCellIconSize[aIndex];
+ }
+ return TSize(0,0);
+ }
+
+// Moved here from eikslbd.cpp
+EXPORT_C void CSettingsListBoxData::Draw(const TListItemProperties& aItemProperties,
+ CWindowGc& aGc,
+ const TDesC* aText,
+ const TRect& aRect,
+ TBool aHighlight,
+ const TColors& aColors) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ // Draw the actual items.
+ DrawFormatted(aItemProperties,aGc,aText,aRect,aHighlight,aColors);
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+// Moved here from eikslbd.cpp
+EXPORT_C
+CSettingsListBoxData* CSettingsListBoxData::NewL()
+ {
+ _AKNTRACE_FUNC_ENTER;
+ CSettingsListBoxData* self=new(ELeave) CSettingsListBoxData;
+ self->ConstructLD( KAknsIIDQsnAnimList );
+
+ _AKNTRACE_FUNC_EXIT;
+ return(self);
+ }
+
+void CFormattedCellListBoxData::SetupSkinContextL()
+ {
+ __ASSERT_DEBUG( iExtension, Panic( EAknPanicNullPointer ));
+
+ // list's own rect cannot be used since it might be unknown at this point
+ TRect mainPane;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPane );
+
+ TRect mainPaneRect( mainPane.Size() );
+
+ if ( !iExtension->iSkinControlContext )
+ {
+ iExtension->iSkinControlContext =
+ CAknsListBoxBackgroundControlContext::NewL( KAknsIIDQsnBgAreaMainListGene,
+ mainPaneRect,
+ EFalse, // Changed to EFalse: See TSW defect avao-6eelpv
+ KAknsIIDNone,
+ mainPaneRect );
+ }
+ else
+ {
+ iExtension->iSkinControlContext->SetRect( mainPaneRect );
+ }
+
+ if ( iExtension->iPopupFrame )
+ {
+ iExtension->iPopupFrame->SetRect( mainPaneRect );
+ }
+
+ iExtension->iSkinHighlightFrameId = &KAknsIIDQsnFrList;
+ iExtension->iSkinHighlightFrameCenterId = &KAknsIIDQsnFrListCenter;
+ }
+
+// extended skin support
+void CFormattedCellListBoxData::SetESSTextColor( TAknsQsnTextColorsIndex aIndex )
+ {
+ TRgb color;
+
+ TInt error = AknsUtils::GetCachedColor( AknsUtils::SkinInstance(),
+ color,
+ KAknsIIDQsnTextColors,
+ aIndex );
+ if ( !error && iExtension )
+ {
+ iExtension->iTextColor = color;
+ }
+ }
+
+
+// extended skin support
+void CFormattedCellListBoxData::SetESSHighlightedTextColor( TAknsQsnTextColorsIndex aIndex )
+ {
+ TRgb color;
+
+ TInt error = AknsUtils::GetCachedColor( AknsUtils::SkinInstance(),
+ color,
+ KAknsIIDQsnTextColors,
+ aIndex );
+ if ( !error )
+ {
+ iExtension->iHighlightedTextColor = color;
+ }
+ }
+
+
+void CFormattedCellListBoxData::SetGraphicSubCellL( TInt aSubCell,
+ const TAknWindowLineLayout &aGraphicLayout )
+ {
+ if ( !iExtension ) return;
+ CEikFormattedCellListBox* list = static_cast<CEikFormattedCellListBox*>( iExtension->iControl );
+ // this does happen with caknsetstyle, caknform(wide)style lists.
+ // eventually they'll get here again with list!=0, so this check is enough
+ if ( !list ) return;
+
+ TInt index = 0;
+ iExtension->FindSLSubCellIndexOrAddL(index,aSubCell);
+ iExtension->AtSL(index).iTextLayout=NULL;
+ iExtension->AtSL(index).iGraphicLayout=aGraphicLayout;
+ iExtension->AtSL(index).iSubCellType=CFormattedCellListBoxDataExtension::EAknSLGraphic;
+
+ // For compabitility - needed at least for text wrapping.
+ // Beware - some of these WILL be overriden if you got here trough
+ // old layout methods like AknListBoxLayouts::SetupFormTextCell()
+ // & friends.
+ TAknLayoutRect r;
+
+ r.LayoutRect( list->View()->ItemDrawer()->ItemCellSize(), aGraphicLayout );
+ SetSubCellSizeL( aSubCell, r.Rect().Size() );
+ SetSubCellPositionL( aSubCell, r.Rect().iTl );
+ SetSubCellAlignmentL( aSubCell, CGraphicsContext::ECenter );
+ SetGraphicsSubCellL( aSubCell, ETrue );
+ UseScalableLayoutData( ETrue );
+ if ( iExtension->iMarginRect == TRect::EUninitialized )
+ {
+ iExtension->iMarginRect = r.Rect();
+ }
+ else
+ {
+ iExtension->iMarginRect.BoundingRect( r.Rect() );
+ }
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ MAknListBoxTfxInternal* transApi =
+ CAknListLoader::TfxApiInternal( list->View()->ItemDrawer()->Gc() );
+ if ( transApi )
+ {
+ transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, iExtension->iMarginRect.iTl );
+ TSize size = list->View()->ItemDrawer()->ItemCellSize();
+ TPoint br( size.AsPoint() - iExtension->iMarginRect.iBr );
+ transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin,
+ br );
+ }
+#endif
+ }
+
+void CFormattedCellListBoxData::SetTextSubCellL( TInt aSubCell,
+ const TAknTextLineLayout &aTextLayout )
+ {
+ if (!iExtension) return;
+ CEikFormattedCellListBox* list = static_cast<CEikFormattedCellListBox*>( iExtension->iControl );
+ // this does happen with caknsetstyle, caknform(wide)style lists.
+ // eventually they'll get here again with list!=0, so this check is enough
+ if ( !list ) return;
+
+ TInt index = 0;
+ iExtension->FindSLSubCellIndexOrAddL(index,aSubCell);
+ iExtension->AtSL(index).iTextLayout=aTextLayout;
+ iExtension->AtSL(index).iGraphicLayout=NULL;
+ iExtension->AtSL(index).iSubCellType=CFormattedCellListBoxDataExtension::EAknSLText;
+
+
+ // For compabitility - needed at least for text wrapping.
+ // Beware - some of these WILL be overriden if you got here trough
+ // old layout methods like AknListBoxLayouts::SetupFormTextCell()
+ // & friends.
+ TAknLayoutText t;
+ t.LayoutText( list->View()->ItemDrawer()->ItemCellSize(), aTextLayout );
+ SetSubCellSizeL( aSubCell, t.TextRect().Size() );
+ SetSubCellPositionL( aSubCell, t.TextRect().iTl );
+ SetSubCellFontL( aSubCell, t.Font() );
+ SetSubCellAlignmentL( aSubCell, AknLayoutUtils::TextAlignFromId( aTextLayout.iJ ) );
+ TInt B = AknLayoutUtils::CorrectBaseline( list->View()->ItemDrawer()->ItemCellSize().iHeight, aTextLayout.iB, aTextLayout.FontId() );
+ SetSubCellBaselinePosL( aSubCell, B );
+ UseScalableLayoutData( ETrue );
+ if ( iExtension->iMarginRect == TRect::EUninitialized )
+ {
+ iExtension->iMarginRect = t.TextRect();
+ }
+ else
+ {
+ iExtension->iMarginRect.BoundingRect( t.TextRect() );
+ }
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ MAknListBoxTfxInternal* transApi =
+ CAknListLoader::TfxApiInternal( list->View()->ItemDrawer()->Gc() );
+ if ( transApi )
+ {
+ transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, iExtension->iMarginRect.iTl );
+ TSize size = list->View()->ItemDrawer()->ItemCellSize();
+ TPoint br( size.AsPoint() - iExtension->iMarginRect.iBr );
+ transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin,
+ br );
+ }
+#endif
+
+ }
+
+void CFormattedCellListBoxData::SetConditionalSubCellL(TInt aSubCell,
+ const TAknTextLineLayout &aTextLayout,
+ TInt aAffectedSubCell)
+ {
+ // iConditionValue of affected subcell (=text subcell, which has different layouts)
+ // contains index of graphical subcell, which existence should be checked first.
+ // This graphical subcell has in iConditionValue index of graphical subcell,
+ // which existence should be checked second etc. Each graphical subcell can
+ // affect only to 1 text subcell (or none).
+
+ // for compabitility - needed at least for text wrapping
+ SetNotAlwaysDrawnSubCellL( aSubCell, ETrue );
+
+ if (!iExtension) return;
+
+ TInt i = 0x01;
+ i = i << aSubCell;
+ iExtension->iConditionalCells = iExtension->iConditionalCells | i;
+
+ TInt graphicalIndex = 0;
+ if (iExtension->FindSLSubCellIndex(graphicalIndex, aSubCell)!=0) return; // subcell not found
+ // conditional layoutline can be only added to graphical subcells
+ if (iExtension->AtSL(graphicalIndex).iSubCellType!=CFormattedCellListBoxDataExtension::EAknSLGraphic) return;
+
+ TInt textIndex = 0; // index of affected subcell
+ if (iExtension->FindSLSubCellIndex(textIndex, aAffectedSubCell)!=0) return; // subcell not found
+ // affected subcell can only be text subcell
+ if (iExtension->AtSL(textIndex).iSubCellType==CFormattedCellListBoxDataExtension::EAknSLGraphic) return;
+
+ TInt gSC = iExtension->AtSL(textIndex).iConditionValue; // text subcell to be added in priority chain
+
+ while (gSC > -1)
+ {
+ if (iExtension->FindSLSubCellIndex(textIndex, gSC)!=0) return; // subcell not found
+ gSC = iExtension->AtSL(textIndex).iConditionValue;
+ }
+ iExtension->AtSL(textIndex).iConditionValue = aSubCell; // add next subcell to chain
+ iExtension->AtSL(graphicalIndex).iTextLayout=aTextLayout;
+
+ iExtension->CreateColorBitmapsL( SubCellSize( aSubCell ) );
+
+ TRect r( SubCellPosition( aSubCell ), SubCellSize( aSubCell ) );
+ if ( iExtension->iMarginRect == TRect::EUninitialized )
+ {
+ iExtension->iMarginRect = r;
+ }
+ else
+ {
+ iExtension->iMarginRect.BoundingRect( r );
+ }
+ CEikFormattedCellListBox* list = static_cast<CEikFormattedCellListBox*>( iExtension->iControl );
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ MAknListBoxTfxInternal* transApi =
+ CAknListLoader::TfxApiInternal( list->View()->ItemDrawer()->Gc() );
+ if ( transApi )
+ {
+ transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, iExtension->iMarginRect.iTl );
+ TSize size = list->View()->ItemDrawer()->ItemCellSize();
+ TPoint br( size.AsPoint() - iExtension->iMarginRect.iBr );
+ transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin,
+ br );
+ }
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::UsesScalableLayoutData
+// -----------------------------------------------------------------------------
+//
+TBool CFormattedCellListBoxData::UsesScalableLayoutData() const
+ {
+ if (iExtension)
+ return iExtension->iSimpleList;
+
+ return EFalse;
+ }
+void CFormattedCellListBoxData::UseScalableLayoutData( TBool aUse )
+ {
+ if ( iExtension )
+ {
+ if ( !aUse && iExtension->iSimpleList )
+ {
+#ifdef RD_UI_TRANSITION_EFFECTS_LIST
+ CEikFormattedCellListBox* list = static_cast<CEikFormattedCellListBox*>( iExtension->iControl );
+ MAknListBoxTfxInternal* transApi =
+ CAknListLoader::TfxApiInternal( list->View()->ItemDrawer()->Gc() );
+ if ( transApi )
+ {
+ transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, TPoint( 0, 0 ) );
+ transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin, TPoint( 0, 0 ) );
+ }
+#endif
+ }
+ iExtension->iSimpleList = aUse;
+ }
+ }
+
+EXPORT_C void CFormattedCellListBoxData::SetSubcellUnderlined( TBitFlags32 aUnderlinedCells )
+ {
+ if ( iExtension )
+ {
+ iExtension->iUnderlineFlagSet = ETrue;
+ iExtension->iUnderlineFlags = aUnderlinedCells;
+ }
+ }
+
+void CFormattedCellListBoxData::SetUnderlineStyle( TListItemProperties aProperties,
+ CWindowGc& aGc,
+ TInt aSubCell ) const
+ {
+ if ( !iExtension )
+ {
+ return;
+ }
+
+ if ( !iExtension->iUnderlineFlagSet )
+ {
+ // underlining is already either on or off and
+ // hardcoded off turning will ensure old style
+ // behaviour
+ return;
+ }
+
+ if ( aProperties.IsUnderlined()
+ && iExtension->iUnderlineFlagSet
+ && iExtension->iUnderlineFlags.IsSet( aSubCell ) )
+ {
+ aGc.SetUnderlineStyle( EUnderlineOn );
+ }
+ else
+ {
+ aGc.SetUnderlineStyle( EUnderlineOff );
+ }
+ }
+
+void CFormattedCellListBoxData::UseHighlightIconSwapping( TBool aUse )
+ {
+ if ( iExtension )
+ {
+ iExtension->iUseHighligthIconSwapping = aUse;
+ }
+ }
+
+TBool CFormattedCellListBoxData::UseHighlightIconSwapping() const
+ {
+ if ( iExtension )
+ {
+ return iExtension->iUseHighligthIconSwapping;
+ }
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::SetStretchableGraphicSubCellL
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxData::SetStretchableGraphicSubCellL(
+ TInt aSubCell,
+ const TAknWindowComponentLayout& aNormalLayout,
+ const TAknWindowComponentLayout& aStretchedLayout )
+ {
+ if ( Layout_Meta_Data::IsLandscapeOrientation() &&
+ Layout_Meta_Data::IsListStretchingEnabled() &&
+ StretchingEnabled() )
+ {
+ SetGraphicSubCellL( aSubCell, aStretchedLayout.LayoutLine() );
+ }
+ else
+ {
+ SetGraphicSubCellL( aSubCell, aNormalLayout.LayoutLine() );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::SetStretchableTextSubCellL
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxData::SetStretchableTextSubCellL(
+ TInt aSubCell,
+ const TAknTextComponentLayout& aNormalLayout,
+ const TAknTextComponentLayout& aStretchedLayout )
+ {
+ if ( Layout_Meta_Data::IsLandscapeOrientation() &&
+ Layout_Meta_Data::IsListStretchingEnabled() &&
+ StretchingEnabled() )
+ {
+ SetTextSubCellL( aSubCell, aStretchedLayout.LayoutLine() );
+ }
+ else
+ {
+ SetTextSubCellL( aSubCell, aNormalLayout.LayoutLine() );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::SetStretchableConditionalSubCellL
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxData::SetStretchableConditionalSubCellL(
+ TInt aSubCell,
+ const TAknTextComponentLayout& aNormalLayout,
+ const TAknTextComponentLayout& aStretchedLayout,
+ TInt aNormalSubCell,
+ TInt aStretchedSubCell )
+ {
+ if ( Layout_Meta_Data::IsLandscapeOrientation() &&
+ Layout_Meta_Data::IsListStretchingEnabled() &&
+ StretchingEnabled() )
+ {
+ SetConditionalSubCellL( aSubCell, aStretchedLayout.LayoutLine(), aStretchedSubCell );
+ }
+ else
+ {
+ SetConditionalSubCellL( aSubCell, aNormalLayout.LayoutLine(), aNormalSubCell );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::ResetSLSubCellArray
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxData::ResetSLSubCellArray()
+ {
+ if ( !iExtension )
+ {
+ return;
+ }
+
+ iExtension->iMarginRect = TRect::EUninitialized;
+
+ UseScalableLayoutData( EFalse );
+ iExtension->ResetSLSubCellArray();
+ // This function gets called always when size changes, so here is called
+ // SetupSkinContextL to update the layout rect of the background skin
+ // context (mainpane rect can change for example if toolbar is hidden.
+ TRAP_IGNORE( SetupSkinContextL() );
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::StretchingEnabled
+// -----------------------------------------------------------------------------
+//
+TBool CFormattedCellListBoxData::StretchingEnabled() const
+ {
+#ifdef RD_LIST_STRETCH
+ if ( !iExtension )
+ {
+ return EFalse;
+ }
+
+ return iExtension->iStretchingEnabled;
+#else
+ return EFalse;
+#endif // #ifdef RD_LIST_STRETCH
+ }
+
+#ifdef RD_LIST_STRETCH
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::EnableStretching
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxData::EnableStretching( const TBool aEnabled )
+ {
+ if ( !iExtension )
+ {
+ return;
+ }
+
+ iExtension->iStretchingEnabled = aEnabled;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::HideSecondRow
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxData::HideSecondRow( const TBool aHide )
+ {
+ if ( !iExtension )
+ {
+ return;
+ }
+
+ iExtension->iHideSecondRow = aHide;
+ }
+#endif // RD_LIST_STRETCH
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::SecondRowHidden
+// -----------------------------------------------------------------------------
+//
+TBool CFormattedCellListBoxData::SecondRowHidden() const
+ {
+ if ( !iExtension )
+ {
+ return EFalse;
+ }
+
+ return iExtension->iHideSecondRow;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::ToggleDropShadows
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxData::ToggleDropShadows( const TBool aEnable )
+ {
+ if ( !iExtension )
+ {
+ return;
+ }
+ iExtension->iUseDropShadows = aEnable;
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::CheckIfSubCellsIntersect
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxData::CheckIfSubCellsIntersect(
+ TAknTextLineLayout* aLayouts,
+ TBool* aResults,
+ const TDesC& aText,
+ const TRect& aItemRect ) const
+ {
+ TInt subCell = 0;
+ TInt subCell2;
+ TInt subCellIndex;
+ TInt subCellIndex2;
+ TInt lastSubCell = Min( KMaxSubCellIndex, LastSubCell() );
+ TPtrC text;
+ TBool isEmpty[KMaxSubCellIndex];
+
+ // cache the empty text states
+ while ( ETrue )
+ {
+ if ( subCell > lastSubCell )
+ {
+ break;
+ }
+
+ TextUtils::ColumnText( text, subCell, &aText );
+
+ if ( text == KNullDesC && SubCellIsNotAlwaysDrawn( subCell ) )
+ {
+ isEmpty[subCell] = ETrue;
+ }
+ else
+ {
+ isEmpty[subCell] = EFalse;
+ }
+
+ ++subCell;
+ }
+
+ subCell = 0;
+
+ while ( ETrue )
+ {
+ if ( subCell > lastSubCell )
+ {
+ break;
+ }
+
+ if ( iExtension->FindSLSubCellIndex( subCellIndex, subCell ) != 0 )
+ {
+ break;
+ }
+
+ if ( isEmpty[subCell] )
+ {
+ ++subCell;
+ continue;
+ }
+
+ TRect bRect( SubCellPosition( subCell ), SubCellSize( subCell ) );
+
+ for ( subCell2 = subCell + 1; subCell2 <= lastSubCell; ++subCell2 )
+ {
+ if ( isEmpty[subCell2] )
+ {
+ continue;
+ }
+
+ if ( iExtension->FindSLSubCellIndex( subCellIndex2, subCell2 ) != 0 )
+ {
+ break;
+ }
+
+ TRect bRect2( SubCellPosition( subCell2 ), SubCellSize( subCell2 ) );
+
+ if ( bRect.Intersects( bRect2 ) && !SubCellIsTransparent( subCell ) && !SubCellIsTransparent( subCell2 ) )
+ {
+ aResults[subCell] = ETrue;
+
+ if ( !AknLayoutUtils::LayoutMirrored() )
+ {
+ bRect.iBr.iX = bRect2.iTl.iX;
+ }
+ else
+ {
+ bRect.iTl.iX = bRect2.iBr.iX;
+ }
+ }
+ }
+
+ if ( aResults[subCell] )
+ {
+ if ( iExtension->AtSL( subCellIndex ).iSubCellType == CFormattedCellListBoxDataExtension::EAknSLText )
+ {
+ TAknTextLineLayout textLine = iExtension->AtSL( subCellIndex ).iTextLayout;
+
+ textLine.iW = bRect.Width();
+
+ if ( !AknLayoutUtils::LayoutMirrored() )
+ {
+ textLine.ir = aItemRect.iBr.iX - bRect.iBr.iX;
+ }
+ else
+ {
+ textLine.il = bRect.iTl.iX - aItemRect.iTl.iX;
+ }
+
+ aLayouts[subCell] = textLine;
+ }
+ }
+
+ ++subCell;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CFormattedCellListBoxData::SubCellsMightIntersect
+// -----------------------------------------------------------------------------
+//
+void CFormattedCellListBoxData::SubCellsMightIntersect( const TBool aMightIntersect )
+ {
+ iExtension->iSubCellsMightIntersect = aMightIntersect;
+ }
+
+
+void CFormattedCellListBoxDataExtension::CreateColorBitmapsL( )
+ {
+ if ( iColorBmp )
+ {
+ CreateColorBitmapsL( iColorBmp->SizeInPixels() );
+ }
+ }
+
+void CFormattedCellListBoxDataExtension::CreateColorBitmapsL( TSize aSize )
+ {
+ _AKNTRACE_FUNC_ENTER;
+ _AKNTRACE("CreateColorBitmapsL: aSize=(%d,%d)", aSize.iWidth, aSize.iHeight);
+
+ TRgb color, hiliColor;
+ TInt error;
+ // icon #13 main area additional list icons #215
+ // icon #16 list highlight additional list iconsform checkbox, radio button #215
+
+ error = AknsUtils::GetCachedColor( AknsUtils::SkinInstance(),
+ color,
+ KAknsIIDQsnIconColors,
+ EAknsCIQsnIconColorsCG13 );
+ if ( error )
+ {
+ _AKNTRACE("CreateColorBitmapsL: Get EAknsCIQsnIconColorsCG13 error, return");
+ return;
+ }
+
+ error = AknsUtils::GetCachedColor( AknsUtils::SkinInstance(),
+ hiliColor,
+ KAknsIIDQsnIconColors,
+ EAknsCIQsnIconColorsCG16 );
+ if ( error )
+ {
+ _AKNTRACE("CreateColorBitmapsL: Get EAknsCIQsnIconColorsCG16 error, return");
+ return;
+ }
+
+ if ( iColorBmp && iColorBmp->SizeInPixels() == aSize
+ && color == iIconColor && hiliColor == iHiliIconColor )
+ {
+ _AKNTRACE("CreateColorBitmapsL: no change happened, ignore and return");
+ return;
+ }
+
+ iIconColor = color;
+ iHiliIconColor = hiliColor;
+
+ if ( !iColorBmp )
+ {
+ iColorBmp = new( ELeave ) CFbsBitmap();
+ iColorBmp->Create( aSize, CCoeEnv::Static()->ScreenDevice()->DisplayMode() );
+ }
+ else if ( iColorBmp->SizeInPixels() != aSize )
+ {
+ iColorBmp->Resize( aSize );
+ }
+ if ( !iHiliBmp )
+ {
+ iHiliBmp = new( ELeave ) CFbsBitmap();
+ iHiliBmp->Create( aSize, CCoeEnv::Static()->ScreenDevice()->DisplayMode() );
+ }
+ else if ( iHiliBmp->SizeInPixels() != aSize )
+ {
+ iHiliBmp->Resize( aSize );
+ }
+
+ CFbsBitGc* fbsBitGc = CFbsBitGc::NewL();
+ CleanupStack::PushL( fbsBitGc );
+
+ CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL( iColorBmp );
+ CleanupStack::PushL( bmpDevice );
+ fbsBitGc->Activate( bmpDevice );
+ fbsBitGc->SetPenStyle(CGraphicsContext::ENullPen);
+ fbsBitGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ fbsBitGc->SetBrushColor( color );
+ fbsBitGc->Clear();
+ CleanupStack::PopAndDestroy( bmpDevice );
+ bmpDevice = NULL;
+
+ bmpDevice = CFbsBitmapDevice::NewL( iHiliBmp );
+ CleanupStack::PushL( bmpDevice );
+ fbsBitGc->Activate( bmpDevice );
+ fbsBitGc->SetPenStyle(CGraphicsContext::ENullPen);
+ fbsBitGc->SetBrushStyle(CGraphicsContext::ESolidBrush);
+ fbsBitGc->SetBrushColor( hiliColor );
+ fbsBitGc->Clear();
+ CleanupStack::PopAndDestroy( bmpDevice );
+ bmpDevice = NULL;
+
+ CleanupStack::PopAndDestroy( fbsBitGc );
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+
+void
+CFormattedCellListBoxData::DrawFormattedOld( TListItemProperties& aProperties,
+ CWindowGc& aGc,
+ const TDesC* aText,
+ const TRect& aItemRect,
+ TBool aHighlight,
+ const TColors& aColors ) const
+ {
+ _AKNTRACE_FUNC_ENTER;
+ TRect aRect(aItemRect);
+ const TColors *subcellColors = &aColors;
+
+ TInt lastSubCell=LastSubCell();
+ if (lastSubCell==KErrNotFound)
+ {
+ aGc.UseFont(CEikonEnv::Static()->NormalFont());
+ aGc.DrawText(TPtrC(),aRect,0); // use draw text so that don't need to change pen color/style
+ aGc.DiscardFont(); // Release the font cache
+ return;
+ }
+ const CFont* font=SubCellFont(0);
+ if (font==NULL)
+ {
+ font=CEikonEnv::Static()->NormalFont();
+ }
+
+ TInt extraVerticalSpace=(aRect.Height()-font->HeightInPixels());
+ TInt baseLineOffset=extraVerticalSpace/2+font->AscentInPixels();
+ TRect textRect=aRect;
+ textRect.iBr.iX=aRect.iTl.iX;
+ TInt subcell=0;
+ TInt subcell2=0;
+ TPtrC text;
+ TBool textNull[30];
+ TRgb bmpBackColor, bmpForeColor;
+ TRect textShadowRect; // For transparent list
+ TRgb textShadowColour = AKN_LAF_COLOR_STATIC(215); // Black shadow for item text.
+
+ MAknsControlContext *cc = AknsDrawUtils::ControlContext( Control() );
+ TBool layoutMirrored = AknLayoutUtils::LayoutMirrored();
+ TBool skinEnabled = AknsUtils::AvkonSkinEnabled();
+
+ if (!cc)
+ {
+ cc = SkinBackgroundContext();
+ }
+
+ Mem::FillZ( textNull, sizeof( textNull ) );
+
+ // cache the text states.
+ subcell = 0;
+ for(;;)
+ {
+ if (subcell>lastSubCell)
+ {
+ break;
+ }
+
+ TextUtils::ColumnText(text,subcell, aText);
+ if (text == KNullDesC && SubCellIsNotAlwaysDrawn(subcell))
+ {
+ textNull[subcell] = ETrue;
+ }
+
+ subcell++;
+ }
+
+
+ // this loop handles rectangles that are clipped because of other subcells.
+ subcell=0;
+ for(;;)
+ {
+ if (subcell>lastSubCell)
+ {
+ break;
+ }
+
+ if (textNull[subcell])
+ {
+ ++subcell;
+ continue;
+ }
+
+ TRect bRect(SubCellPosition(subcell),SubCellSize(subcell));
+ TMargins m(SubCellMargins(subcell));
+ TRect cRect(bRect.iTl+TSize(m.iLeft,m.iTop),bRect.Size()-TSize(m.iRight+m.iLeft,m.iBottom+m.iTop));
+
+ for (subcell2=subcell+1; subcell2<=lastSubCell; subcell2++)
+ {
+ if (textNull[subcell2])
+ {
+ continue;
+ }
+
+ // This is called O(N^2) times - Do not put anything extra to it, it'll slow down drawing!
+ TRect bRect2 = TRect(SubCellPosition(subcell2),SubCellSize(subcell2));
+ if (cRect.Intersects(bRect2) && bRect.Intersects(bRect2) && !SubCellIsTransparent(subcell) && !SubCellIsTransparent(subcell2))
+ {
+ if (!layoutMirrored)
+ {
+ cRect.iBr.iX = bRect2.iTl.iX;
+ bRect.iBr.iX = bRect2.iTl.iX;
+ }
+ else
+ {
+ cRect.iTl.iX = bRect2.iBr.iX;
+ bRect.iTl.iX = bRect2.iBr.iX;
+ }
+ }
+ }
+ SetSubCellRealTextSize(subcell, cRect.Size());
+ SetSubCellRealSize(subcell, bRect.Size());
+ subcell++;
+ }
+
+ // This loop does the drawing.
+ aGc.SetPenStyle(CGraphicsContext::ENullPen);
+ subcell=0;
+ for(;;)
+ {
+ if (subcell>lastSubCell)
+ {
+ break;
+ }
+
+ if (textNull[subcell])
+ {
+ ++ subcell;
+ continue;
+ }
+
+ // SetPosition, SetSize and margins support
+ TRect bRect(SubCellPosition(subcell),SubCellRealSize(subcell));
+ TMargins m(SubCellMargins(subcell));
+ TRect cRect(bRect.iTl+TSize(m.iLeft,m.iTop),SubCellRealTextSize(subcell));
+
+
+ if (bRect.iBr.iX == 0)
+ {
+ ++subcell;
+ continue;
+ }
+
+ if ( layoutMirrored )
+ {
+ TRect bRect = TRect(SubCellPosition(subcell),SubCellSize(subcell));
+ TRect cRect2 = TRect(bRect.iTl+TSize(m.iLeft,m.iTop),bRect.Size()-TSize(m.iRight+m.iLeft,m.iBottom+m.iTop));
+
+ TInt shift = (cRect2.Size() - SubCellRealTextSize(subcell)).iWidth;
+ cRect.iTl.iX += shift;
+ cRect.iBr.iX += shift;
+ }
+
+ textRect.SetRect(aItemRect.iTl+cRect.iTl,cRect.Size());
+
+ if (UseSubCellColors(subcell))
+ {
+ subcellColors = &SubCellColors(subcell);
+ }
+ else
+ {
+ subcellColors = &aColors;
+ }
+
+ if (aHighlight)
+ {
+ aGc.SetPenColor(subcellColors->iHighlightedText);
+ aGc.SetBrushColor(subcellColors->iHighlightedBack);
+ bmpBackColor = subcellColors->iHighlightedBack;
+ bmpForeColor = subcellColors->iHighlightedText;
+ if ( skinEnabled && iExtension )
+ {
+ if ( iExtension->iHighlightedTextColor != NULL )
+ {
+ aGc.SetPenColor( iExtension->iHighlightedTextColor );
+ bmpForeColor = iExtension->iHighlightedTextColor;
+ }
+ }
+ }
+ else
+ {
+ aGc.SetPenColor(subcellColors->iText);
+ aGc.SetBrushColor(subcellColors->iBack);
+ bmpBackColor = subcellColors->iBack;
+ bmpForeColor = subcellColors->iText;
+
+ if ( skinEnabled && iExtension )
+ {
+ if ( iExtension->iTextColor != NULL )
+ {
+ aGc.SetPenColor( iExtension->iTextColor );
+ bmpForeColor = iExtension->iTextColor;
+ }
+ }
+ }
+
+ aGc.SetBrushStyle(CGraphicsContext::ENullBrush);
+
+ // The following draws subcells to textRect
+ if (textRect.iBr.iX!=textRect.iTl.iX)
+ {
+ TextUtils::ColumnText(text,subcell,aText);
+
+ // graphics or text column
+ CGraphicsContext::TTextAlign align=SubCellAlignment(subcell);
+ if (!SubCellIsGraphics(subcell))
+ {
+ const CFont* rowAndCellFont=RowAndSubCellFont(iExtension->iCurrentlyDrawnItemIndex,subcell);
+ const CFont* cellFont=Font(aProperties, subcell);
+ const CFont* tempFont=(cellFont) ? cellFont : font;
+ const CFont* usedFont=(rowAndCellFont) ? rowAndCellFont : tempFont;
+ aGc.UseFont(usedFont);
+ SetUnderlineStyle( aProperties, aGc, subcell );
+
+ // baseline calc needed for each cell.
+ baseLineOffset = SubCellBaselinePos(subcell);
+ baseLineOffset -= cRect.iTl.iY;
+ if (!baseLineOffset)
+ {
+ baseLineOffset = (cRect.Size().iHeight-usedFont->HeightInPixels())/2 + usedFont->AscentInPixels();
+ }
+
+ TBuf<KMaxColumnDataLength + KAknBidiExtraSpacePerLine> clipbuf =
+ text.Left(KMaxColumnDataLength);
+
+ // Note that this potentially modifies the text so its lenght in pixels
+ // might increase. Therefore, this should always be done before
+ // wrapping/clipping text. In some cases, WordWrapListItem is called
+ // before coming here. Is it certain that it is not done for number subcells?
+ if (SubCellIsNumberCell(subcell))
+ {
+ AknTextUtils::LanguageSpecificNumberConversion(clipbuf);
+ }
+
+ TBool clipped( EFalse );
+ TInt clipgap = SubCellTextClipGap( subcell );
+
+ if ( iExtension->iUseLogicalToVisualConversion &&
+ subcell != iExtension->iFirstWordWrappedSubcellIndex &&
+ subcell != iExtension->iSecondWordWrappedSubcellIndex )
+ {
+ TInt maxClipWidth = textRect.Size().iWidth + clipgap;
+
+ clipped = AknBidiTextUtils::ConvertToVisualAndClip(
+ text.Left(KMaxColumnDataLength),
+ clipbuf,
+ *usedFont,
+ textRect.Size().iWidth,
+ maxClipWidth );
+ }
+
+ if (clipped)
+ {
+ if (!layoutMirrored)
+ {
+ textRect.iBr.iX+=clipgap;
+ }
+ else
+ {
+ textRect.iTl.iX-=clipgap;
+ }
+ }
+
+ if ( aHighlight )
+ {
+ if ( clipped )
+ {
+ iExtension->iClippedSubcells |= ( 1 << subcell );
+ }
+ else
+ {
+ iExtension->iClippedSubcells &= ~( 1 << subcell );
+ }
+
+ if ( iExtension->iUseClippedByWrap ) // override if already clipped
+ {
+ iExtension->iClippedSubcells = iExtension->iClippedByWrap;
+ }
+ }
+
+ CAknMarqueeControl* marquee =
+ subcell == 1 ? iExtension->iMarquee :
+ iExtension->i2ndLineMarquee;
+
+ TBool marqueeDisabled =
+ static_cast<CEikListBox*>(
+ Control() )->View()->ItemDrawer()->Flags() & CListItemDrawer::EDisableMarquee;
+
+ if ( aHighlight && iExtension->IsMarqueeOn() && clipped && !marqueeDisabled )
+ {
+ // Let marquee know if it needs to do bidi conversion.
+ marquee->UseLogicalToVisualConversion( clipped );
+
+ if ( marquee->DrawText( aGc, textRect, text, baseLineOffset, align, *usedFont ) )
+ {
+ // All the loops have been executed -> the text needs to be truncated.
+ aGc.DrawText( clipbuf, textRect, baseLineOffset, align, 0 );
+ }
+ }
+ else
+ {
+ if ( marquee && marqueeDisabled )
+ {
+ marquee->Stop();
+ }
+
+ if ( IsBackgroundDrawingEnabled() )
+ {
+ aGc.DrawText( clipbuf, textRect, baseLineOffset, align, 0 );
+ }
+ else // "Transparent" list, draw text shadow first, then the actual text.
+ {
+ textShadowRect = textRect;
+ textShadowRect.Move( 1, 1 );
+ aGc.SetPenColor( textShadowColour );
+ aGc.DrawText( clipbuf, textShadowRect, baseLineOffset, align, 0 );
+ if ( aHighlight )
+ {
+ aGc.SetPenColor( subcellColors->iHighlightedText );
+ }
+ else
+ {
+ aGc.SetPenColor( subcellColors->iText );
+ }
+ aGc.DrawText( clipbuf, textRect, baseLineOffset, align, 0 );
+ }
+ }
+
+ if ( iExtension->iPictoInterface )
+ {
+ iExtension->iPictoInterface->Interface()->DrawPictographsInText(
+ aGc, *usedFont, clipbuf, textRect, baseLineOffset, align, 0 );
+ }
+ // disable underline after first text.
+ // at least phonebook uses this. See SetSubcellUnderlined to override
+ aGc.SetUnderlineStyle(EUnderlineOff);
+ aGc.DiscardFont(); // Release the font cache
+ }
+ else // Graphics subcell
+ {
+ TLex lex(text);
+ TInt index;
+ __ASSERT_ALWAYS(lex.Val(index)==KErrNone,Panic(EAknPanicFormattedCellListInvalidBitmapIndex));
+ __ASSERT_DEBUG(iIconArray, Panic(EAknPanicOutOfRange));
+ if ( index == KColorIconFlag ) index = KColorIconIdx;
+ __ASSERT_DEBUG((index>=0 && index<iIconArray->Count()),Panic(EAknPanicFormattedCellListInvalidBitmapIndex));
+ TRect bmpRect;
+ bmpRect.iTl=textRect.iTl;
+
+ if (index>=0 && iIconArray)
+ {
+ CGulIcon* icon=(*iIconArray)[index];
+ CFbsBitmap* bitmap=icon->Bitmap();
+
+ if ( iExtension )
+ {
+ TInt w, h;
+ TSize sz = bitmap->SizeInPixels();
+
+ w = iExtension->iSubCellIconSize[subcell].iWidth;
+ h = iExtension->iSubCellIconSize[subcell].iHeight;
+
+ if (h != 0 && w != 0 && !( sz.iWidth == w || sz.iHeight == h ) )
+ {
+ AknIconUtils::SetSize( bitmap,
+ iExtension->iSubCellIconSize[subcell],
+ EAspectRatioPreservedAndUnusedSpaceRemoved );
+ }
+ else if ( sz.iWidth == 0 || sz.iHeight == 0 ) // check if size is set at all
+ {
+ // just in case fallback
+ AknIconUtils::SetSize( bitmap,
+ textRect.Size(),
+ EAspectRatioPreservedAndUnusedSpaceRemoved );
+ }
+ }
+
+ TSize size=bitmap->SizeInPixels();
+
+ if (size.iWidth>textRect.Size().iWidth)
+ {
+ size.iWidth = textRect.Size().iWidth;
+ }
+
+ if (size.iHeight>textRect.Size().iHeight)
+ {
+ size.iHeight = textRect.Size().iHeight;
+ }
+
+ TPoint bmpPos=textRect.iTl;
+ bmpPos.iY+=(textRect.Height()-size.iHeight)>>1;
+ switch (align)
+ {
+ case ELeft:
+ break;
+ case ECenter:
+ bmpPos.iX+=(textRect.Width()-size.iWidth)>>1;
+ break;
+ case ERight:
+ bmpPos.iX=textRect.iBr.iX-size.iWidth;
+ break;
+ }
+ bmpRect=TRect(bmpPos,size);
+ TPoint posInBitmap = TPoint(0,0) + bitmap->SizeInPixels() - textRect.Size();
+ posInBitmap.iX /= 2;
+ posInBitmap.iY /= 2;
+ if (posInBitmap.iX < 0)
+ {
+ posInBitmap.iX = 0;
+ }
+ if (posInBitmap.iY < 0)
+ {
+ posInBitmap.iY = 0;
+ }
+ TRect rect(posInBitmap,textRect.Size());
+
+ if (icon->Mask())
+ {
+ aGc.BitBltMasked( bmpPos, bitmap, rect, icon->Mask(), ETrue );
+ }
+ else
+ {
+ aGc.BitBlt( bmpPos, bitmap ,rect );
+ }
+ }
+ aGc.SetPenStyle(CGraphicsContext::ESolidPen);
+ }
+ }
+ aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
+ ++subcell;
+ }
+
+ // Clear information of wordwrapped and bidi-reordered subcells.
+ const_cast<CFormattedCellListBoxData*>( this )->
+ SetWordWrappedSubcellIndices( -1, -1 );
+ _AKNTRACE_FUNC_EXIT;
+ }
+
+void CFormattedCellListBoxData::SetClippedByWrap( TUint32 aClippedCells, TBool aUseClippedByWrap )
+ {
+ if ( iExtension )
+ {
+ iExtension->iClippedByWrap = aClippedCells;
+ iExtension->iUseClippedByWrap = aUseClippedByWrap;
+ }
+ }
+
+EXPORT_C TUint32 CFormattedCellListBoxData::CurrentItemTextWasClipped() const
+ {
+ return iExtension ? iExtension->iClippedSubcells : 0;
+ }
+
+
+
+TBool CFormattedCellListBoxData::KineticScrollingEnabled() const
+ {
+ if ( iExtension )
+ {
+ return iExtension->iKineticScrolling;
+ }
+ return EFalse;
+ }
+
+
+CEikListBox* CFormattedCellListBoxData::ListBox() const
+ {
+ if ( iExtension && iExtension->iControl )
+ {
+ return static_cast<CEikListBox*>( iExtension->iControl );
+ }
+ return NULL;
+ }
+
+
+// End of File