diff -r 000000000000 -r e686773b3f54 phonebookui/Phonebook2/ccapplication/ccacommlauncherplugin/src/ccappcommlaunchercustomlistboxdata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/ccapplication/ccacommlauncherplugin/src/ccappcommlaunchercustomlistboxdata.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,4015 @@ +/* +* Copyright (c) 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: +* +*/ +/* + * ccappcommlaunchercustomlistboxdata.cpp + * + * Created on: 2009-11-2 + * Author: dev + */ +/* + * ============================================================================ + * Name : Eikfrlbd.cpp + * Part of : Avkon + * + * Description: + * Version: + * + * Copyright � 2002-2009 Nokia Corporation. + * This material, including documentation and any related + * computer programs, is protected by copyright controlled by + * Nokia Corporation. All rights are reserved. Copying, + * including reproducing, storing, adapting or translating, any + * or all of this material requires the prior written consent of + * Nokia Corporation. This material also contains confidential + * information which may not be disclosed to others without the + * prior written consent of Nokia Corporation. + * ============================================================================ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + +#include "ccappcommlaunchercustomlistboxdata.h" + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST +#include +#include +#endif //RD_UI_TRANSITION_EFFECTS_LIST + +#ifdef RD_TACTILE_FEEDBACK +#include +#endif //RD_TACTILE_FEEDBACK +// 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(CCCAppCommLauncherCustomListBoxDataExtension) : 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: + CCCAppCommLauncherCustomListBoxDataExtension(); + void ConstructL(CCCAppCommLauncherCustomListBoxData* aListBoxData, + const TAknsItemID& aAnimationIID); + ~CCCAppCommLauncherCustomListBoxDataExtension(); + 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 DrawPressedDownEffectL(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 + CCCAppCommLauncherCustomListBoxData* 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* iRowAndSubCellArray; + CArrayFix* 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* 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. + */ +CCCAppCommLauncherCustomListBoxDataExtension::CCCAppCommLauncherCustomListBoxDataExtension() : + CActive(EPriorityHigh) + { + } + +void CCCAppCommLauncherCustomListBoxDataExtension::ConstructL( + CCCAppCommLauncherCustomListBoxData* aListBoxData, + const TAknsItemID& aAnimationIID) + { + iListBoxData = aListBoxData; + iRowAndSubCellArray = new (ELeave) CArrayFixFlat (4); + iSLSubCellArray = new (ELeave) CArrayFixFlat (4); + + iSubCellExtArray = new (ELeave) CArrayFixFlat (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(); + } + +CCCAppCommLauncherCustomListBoxDataExtension::~CCCAppCommLauncherCustomListBoxDataExtension() + { + 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; + } + +void CCCAppCommLauncherCustomListBoxDataExtension::AddRowAndSubCellL(TInt aRow, + TInt aSubCell) + { + SRowAndSubCell subcell; + subcell.iIndex = (aRow << 8) | (aSubCell & 0xff); + subcell.iFont = NULL; + TKeyArrayFix key(0, ECmpTInt32); + iRowAndSubCellArray->InsertIsqL(subcell, key); + } + +CCCAppCommLauncherCustomListBoxDataExtension::SRowAndSubCell& +CCCAppCommLauncherCustomListBoxDataExtension::At(TInt aArrayIndex) + { + /* SRowAndSubCell subcell; + for (int a=0;aCount();a++) + subcell = iRowAndSubCellArray->At(a); */ + + //__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndexCount(),Panic(EAknPanicOutOfRange)); + return (iRowAndSubCellArray->At(aArrayIndex)); + } + +const CCCAppCommLauncherCustomListBoxDataExtension::SRowAndSubCell& +CCCAppCommLauncherCustomListBoxDataExtension::At(TInt aArrayIndex) const + { + //__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndexCount(),Panic(EAknPanicOutOfRange)); + return (iRowAndSubCellArray->At(aArrayIndex)); + } + +TInt CCCAppCommLauncherCustomListBoxDataExtension::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 CCCAppCommLauncherCustomListBoxDataExtension::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 CCCAppCommLauncherCustomListBoxDataExtension::AddSLSubCellL(TInt 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); + } + +CCCAppCommLauncherCustomListBoxDataExtension::SSLSubCell& +CCCAppCommLauncherCustomListBoxDataExtension::AtSL(TInt aArrayIndex) + { + //__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndexCount(),Panic(EAknPanicOutOfRange)); + return (iSLSubCellArray->At(aArrayIndex)); + } + +const CCCAppCommLauncherCustomListBoxDataExtension::SSLSubCell& +CCCAppCommLauncherCustomListBoxDataExtension::AtSL(TInt aArrayIndex) const + { + //__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndexCount(),Panic(EAknPanicOutOfRange)); + return (iSLSubCellArray->At(aArrayIndex)); + } + +TInt CCCAppCommLauncherCustomListBoxDataExtension::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 CCCAppCommLauncherCustomListBoxDataExtension::FindSLSubCellIndexOrAddL( + TInt& aArrayIndex, TInt aSubCell) + { + if (FindSLSubCellIndex(aArrayIndex, aSubCell) != 0) //==KErrNotFound) + { + AddSLSubCellL(aSubCell); + FindSLSubCellIndex(aArrayIndex, aSubCell); + } + } + +void CCCAppCommLauncherCustomListBoxDataExtension::ResetSLSubCellArray() + { + iSLSubCellArray->Reset(); + iRowAndSubCellArray->Reset(); + } + +void CCCAppCommLauncherCustomListBoxDataExtension::CreatePictographInterfaceL() + { + if (!iPictoInterface) + { + iPictoInterface = CAknPictographInterface::NewL(*iControl, *this); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::NoAnimIfError +// ----------------------------------------------------------------------------- +// +inline void CCCAppCommLauncherCustomListBoxDataExtension::NoAnimIfError( + TInt aError) + { + if (KErrNone != aError) + { + DeleteAnim(); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::TryCreateAnimation +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::TryCreateAnimation() + { + if (!iControl) + { + return; + } + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + CEikListBox* list = static_cast (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); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::SyncAnim +// ----------------------------------------------------------------------------- +// +TBool CCCAppCommLauncherCustomListBoxDataExtension::SyncAnim(const TSize& aSize) + { + if (!iAnimation || aSize.iWidth <= 0 || aSize.iHeight <= 0) + { + 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; + } + } + } + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::SyncAndDrawAnim +// ----------------------------------------------------------------------------- +// +TBool CCCAppCommLauncherCustomListBoxDataExtension::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; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::SkinBackgroundContext +// ----------------------------------------------------------------------------- +// +MAknsControlContext* CCCAppCommLauncherCustomListBoxDataExtension::SkinBackgroundContext() const + { + if (iSkinEnabled) + return iSkinControlContext; + else + return NULL; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::DeleteAnim +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::DeleteAnim() + { + // Stop receiving foreground events + CCoeEnv* env = CCoeEnv::Static(); + env->RemoveForegroundObserver(*this); + + delete iAnimation; + iAnimation = NULL; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::FocusGained +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::FocusGained() + { + Play(); + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::FocusLost +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::FocusLost() + { + if (iAnimation) + { + NoAnimIfError(iAnimation->Pause()); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::SkinChanged +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::SkinChanged() + { + DeleteAnim(); + TryCreateAnimation(); + TRAP_IGNORE( CreateColorBitmapsL() ); + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::SetControl +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::SetControl( + CCoeControl* aControl) + { + 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(); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::HandleGainingForeground +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::HandleGainingForeground() + { + // 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(); + } + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::HandleLosingForeground +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::HandleLosingForeground() + { + iAnimFlags.Clear(EFlagHasForeground); + if (iAnimation) + { + NoAnimIfError(iAnimation->Stop()); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::AnimFrameReady +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::AnimFrameReady(TInt aError, + TInt) + { + if (KErrNone != 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) + return; + + // From now on, we have a valid control pointer + CEikListBox* list = static_cast (iControl); + CListBoxView* view = list->View(); + + if (!view) + 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); + + // 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(); + } + + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::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 CCCAppCommLauncherCustomListBoxDataExtension::ListBoxItemsChanged( + CEikListBox* aListBox) + { + + 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(); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::DoCancel +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::DoCancel() + { + // Required method, but not needed + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::RunL +// Postponed animation deletion is done here. +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::RunL() + { + DeleteAnim(); + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::Play +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::Play() + { + if (!iAnimation) + { + return; + } + + // No need to start running/finished animation + if (EAknsAnimStateRunning == iAnimation->State() || EAknsAnimStateFinished + == iAnimation->State()) + { + 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)) + { + return; + } + + // Animation cannot run if we don't have control (nowhere to draw) + if (!iControl) + { + return; + } + + // The control must also have the focus + if (!iControl->IsFocused()) + { + return; + } + + // Don't animate empty list + CEikListBox* list = static_cast (iControl); + if (list->Model()->NumberOfItems() == 0) + { + 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()); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::DrawHighlightBackground +// ----------------------------------------------------------------------------- +// +TBool CCCAppCommLauncherCustomListBoxDataExtension::DrawHighlightBackground( + CFbsBitGc& aGc) + { + 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 (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(); + } + + return AknsDrawUtils::DrawBackground(AknsUtils::SkinInstance(), cc, + iControl, aGc, TPoint(0, 0), itemRect, + KAknsDrawParamBottomLevelRGBOnly); + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::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 CCCAppCommLauncherCustomListBoxDataExtension::PostDeleteAnimation() + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::CreateAnimationL +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::CreateAnimationL() + { + 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()) + { + 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 + { + 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 (CEikonEnv::Static()->AppUi()); + iAnimFlags.Assign(EFlagHasForeground, aui->IsForeground()); + + Play(); + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxDataExtension::DoResizeL +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxDataExtension::DoResizeL( + const TSize& aHighlightSize, TBool aAboutToStart) + { + iAnimation->BeginConfigInputLayersL(aHighlightSize, aAboutToStart); + + if (iAnimation->InputRgbGc()) + { + DrawHighlightBackground(*iAnimation->InputRgbGc()); + } + + iAnimation->EndConfigInputLayersL(); + } + +///////////handling TSubCellExt,start + +TInt CCCAppCommLauncherCustomListBoxDataExtension::AddSubCellExtL(TInt aSubCell) + { + TSubCellExt subcell; + subcell.iSubCell = aSubCell; + subcell.iLayoutAlign = ETrue; + + TKeyArrayFix key(0, ECmpTInt); + return iSubCellExtArray->InsertIsqL(subcell, key); + + } + +void CCCAppCommLauncherCustomListBoxDataExtension::FindSubCellExtIndexOrAddL( + TInt& aArrayIndex, TInt aSubCell) + { + if (FindSubCellExtIndex(aArrayIndex, aSubCell) == KErrNotFound) + { + aArrayIndex = AddSubCellExtL(aSubCell); + //FindSubCellExtIndex(aArrayIndex,aSubCell); + } + } + +void CCCAppCommLauncherCustomListBoxDataExtension::SetSubCellLayoutAlignmentL( + TInt aSubCellIndex) + { + TInt index = 0; + FindSubCellExtIndexOrAddL(index, aSubCellIndex); + iSubCellExtArray->At(index).iLayoutAlign = EFalse; + } + +TInt CCCAppCommLauncherCustomListBoxDataExtension::FindSubCellExtIndex( + TInt& aArrayIndex, TInt aSubCell) const + { + if (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) + { + return KErrNotFound; + } + + return retVal; + } + +TBool CCCAppCommLauncherCustomListBoxDataExtension::SubCellLayoutAlignment( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellExtIndex(index, aSubCellIndex) == KErrNotFound) + return (ETrue); + return (iSubCellExtArray->At(index).iLayoutAlign); + } + +///////////handling TSubCellExt,end + +void CCCAppCommLauncherCustomListBoxDataExtension::DrawPictographArea() + { + // This callback is never invoked, if iControl is NULL. + iControl->DrawNow(); + } + +void CCCAppCommLauncherCustomListBoxDataExtension::CreateMarqueeControlL() + { + if (!iMarquee) + { + iMarquee = CAknMarqueeControl::NewL(); + } + + if (!i2ndLineMarquee) + { + i2ndLineMarquee = CAknMarqueeControl::NewL(); + } + } + +TInt CCCAppCommLauncherCustomListBoxDataExtension::RedrawEvent(TAny* aControl) + { + if (!((CCoeControl*) aControl)->IsVisible()) + { + return EFalse; + } + CEikFormattedCellListBox* listBox = (CEikFormattedCellListBox*) aControl; + if (listBox->CurrentItemIndex() >= 0) + { + listBox->RedrawItem(listBox->CurrentItemIndex()); + } + return ETrue; + } + +TBool CCCAppCommLauncherCustomListBoxDataExtension::IsMarqueeOn() + { + TBool isOn = EFalse; + if (iMarquee) + isOn = iMarquee->IsMarqueeOn(); + return isOn; + } + +TBool CCCAppCommLauncherCustomListBoxDataExtension::DrawPressedDownEffectL( + MAknsSkinInstance* aInstance, CWindowGc& aGc, const TRect& aOutRect, + const TRect& aInnerRect) const + { + return AknsDrawUtils::DrawFrame(aInstance, aGc, aOutRect, aInnerRect, + KAknsIIDQsnFrListPressed, KAknsIIDQsnFrListCenterPressed); + } + + CCoeControl *CCCAppCommLauncherCustomListBoxData::Control() const + { + return iExtension->iControl; + } + + void CCCAppCommLauncherCustomListBoxData::SetSeparatorLinePosition( + TAknSeparatorLinePosition aPosition) + { + if (iExtension) + iExtension->iSeparatorLinePosition = aPosition; + } + TAknSeparatorLinePosition CCCAppCommLauncherCustomListBoxData::SeparatorLinePosition() const + { + if (iExtension) + return iExtension->iSeparatorLinePosition; + else + return ENoLine; + } + CAknLayoutData *CCCAppCommLauncherCustomListBoxData::LayoutData() const + { + return NULL; + } + + TBool CCCAppCommLauncherCustomListBoxData::LayoutInit() const + { + return EFalse; + } + void CCCAppCommLauncherCustomListBoxData::SetLayoutInit(TBool /*aValue*/) + { + } + +CCCAppCommLauncherCustomListBoxDataExtension *CCCAppCommLauncherCustomListBoxData::Extension() + { + return iExtension; + } +CCCAppCommLauncherCustomListBoxDataExtension *CCCAppCommLauncherCustomListBoxData::Extension() const + { + return iExtension; + } + + void CCCAppCommLauncherCustomListBoxData::SetControl( + CCoeControl *aControl) + { + iExtension->SetControl(aControl); + } + + MAknsControlContext* CCCAppCommLauncherCustomListBoxData::SkinBackgroundContext() const + { + if (iExtension->iSkinEnabled) + { + if (iExtension->iPopupFrame) + { + return iExtension->iPopupFrame; + } + else + { + return iExtension->iSkinControlContext; + } + } + else + { + return NULL; + } + } + + void CCCAppCommLauncherCustomListBoxData::SetSkinEnabledL( + TBool aEnabled) + { + CListBoxData::SetSkinEnabledL(aEnabled); + iExtension->iSkinEnabled = aEnabled; + } + + TBool CCCAppCommLauncherCustomListBoxData::SkinEnabled() const + { + return iExtension->iSkinEnabled; + } + + void CCCAppCommLauncherCustomListBoxData::SetSkinStyle( + const TAknsItemID *id, const TRect &aTileRect) + { + + if (iExtension->iSkinControlContext) + { + iExtension->iSkinControlContext->SetTiledBitmap(*id); + iExtension->iSkinControlContext->SetTiledRect(aTileRect); + } + } + void CCCAppCommLauncherCustomListBoxData::SetSkinParentPos( + const TPoint &aPos) + { + if (iExtension->iSkinControlContext) + { + iExtension->iSkinControlContext->SetParentPos(aPos); + } + } + void CCCAppCommLauncherCustomListBoxData::SetBackgroundSkinStyle( + const TAknsItemID *aId, const TRect &aRect) + { + if (iExtension->iSkinControlContext) + { + iExtension->iSkinControlContext->SetBitmap(*aId); + iExtension->iSkinControlContext->SetRect(aRect); + } + } + void CCCAppCommLauncherCustomListBoxData::SetListEndSkinStyle( + const TAknsItemID *aListEndId, const TRect &aRect) + { + if (iExtension->iSkinControlContext) + { + iExtension->iSkinControlContext->SetBottomBitmap(*aListEndId); + iExtension->iSkinControlContext->SetBottomRect(aRect); + } + } + + void CCCAppCommLauncherCustomListBoxData::SetSkinHighlightFrame( + const TAknsItemID *aFrameId, const TAknsItemID *aFrameCenterId) + { + iExtension->iSkinHighlightFrameId = aFrameId; + iExtension->iSkinHighlightFrameCenterId = aFrameCenterId; + } + + void CCCAppCommLauncherCustomListBoxData::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); + } + } + } + + void CCCAppCommLauncherCustomListBoxData::SetSkinPopupFramePosition( + const TRect &aOuterRect, const TRect &aInnerRect) + { + if (iExtension && iExtension->iPopupFrame) + iExtension->iPopupFrame->SetFrameRects(aOuterRect, aInnerRect); + } + + void CCCAppCommLauncherCustomListBoxData::UseLogicalToVisualConversion( + TBool aUseConversion) + { + if (iExtension) + iExtension->iUseLogicalToVisualConversion = aUseConversion; + } + +void CCCAppCommLauncherCustomListBoxData::CreatePictographInterfaceL() + { + iExtension->CreatePictographInterfaceL(); + } + +void CCCAppCommLauncherCustomListBoxData::CreateMarqueeControlL() + { + TCallBack callBack( + CCCAppCommLauncherCustomListBoxDataExtension::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; + + +CCCAppCommLauncherCustomListBoxData* CCCAppCommLauncherCustomListBoxData::NewL() + { + CCCAppCommLauncherCustomListBoxData* self = + new (ELeave) CCCAppCommLauncherCustomListBoxData; + self->ConstructLD(KAknsIIDQsnAnimList); + return (self); + } + + CCCAppCommLauncherCustomListBoxData::~CCCAppCommLauncherCustomListBoxData() + { + delete iExtension; + delete iSubCellArray; + if (iIconArray) + { + iIconArray->ResetAndDestroy(); + delete iIconArray; + } + } + + TSize CCCAppCommLauncherCustomListBoxData::SubCellSize( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return TSize(0, 0); + return (iSubCellArray->At(index).iSize); + } + + void CCCAppCommLauncherCustomListBoxData::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); + } + + TInt CCCAppCommLauncherCustomListBoxData::SubCellBaselinePos( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return TInt(0); + return (iSubCellArray->At(index).iBaseline); + } + + void CCCAppCommLauncherCustomListBoxData::SetSubCellBaselinePosL( + TInt aSubCellIndex, TInt aPos) + { + TInt index = 0; + FindSubCellIndexOrAddL(index, aSubCellIndex); + At(index).iBaseline = aPos; + } + + TInt CCCAppCommLauncherCustomListBoxData::SubCellTextClipGap( + TInt aSubCellIndex) const + { + TInt index; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return TInt(0); + return (iSubCellArray->At(index).iTextClipGap); + } + + void CCCAppCommLauncherCustomListBoxData::SetSubCellTextClipGapL( + TInt aSubCellIndex, TInt aGap) + { + TInt index; + FindSubCellIndexOrAddL(index, aSubCellIndex); + At(index).iTextClipGap = aGap; + } + +TSize CCCAppCommLauncherCustomListBoxData::SubCellRealSize(TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return TSize(0, 0); + return (iSubCellArray->At(index).iRealSize); + } + +void CCCAppCommLauncherCustomListBoxData::SetSubCellRealSize( + TInt aSubCellIndex, TSize aRealSize) const + { + TInt index = 0; + if (!(FindSubCellIndex(index, aSubCellIndex) == KErrNotFound)) + { + MUTABLE_CAST(TSize&,At(index).iRealSize) = aRealSize; + } + } + +TSize CCCAppCommLauncherCustomListBoxData::SubCellRealTextSize( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return TSize(0, 0); + return (iSubCellArray->At(index).iRealTextSize); + } + +void CCCAppCommLauncherCustomListBoxData::SetSubCellRealTextSize( + TInt aSubCellIndex, TSize aRealTextSize) const + { + TInt index = 0; + if (!(FindSubCellIndex(index, aSubCellIndex) == KErrNotFound)) + { + MUTABLE_CAST(TSize&,At(index).iRealTextSize) = aRealTextSize; + } + } + + TPoint CCCAppCommLauncherCustomListBoxData::SubCellPosition( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return TPoint(0, 0); + return (iSubCellArray->At(index).iPosition); + } + + void CCCAppCommLauncherCustomListBoxData::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); + } + + TMargins CCCAppCommLauncherCustomListBoxData::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); + } + + void CCCAppCommLauncherCustomListBoxData::SetSubCellMarginsL( + TInt aSubCellIndex, TMargins aMargins) + { + TInt index = 0; + FindSubCellIndexOrAddL(index, aSubCellIndex); + At(index).iMargin = aMargins; + } + + const CFont* +CCCAppCommLauncherCustomListBoxData::SubCellFont(TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return 0; + return (iSubCellArray->At(index).iBaseFont); + } + + void CCCAppCommLauncherCustomListBoxData::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; + } + } + + CGraphicsContext::TTextAlign CCCAppCommLauncherCustomListBoxData::SubCellAlignment( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return CGraphicsContext::ELeft; + return (iSubCellArray->At(index).iAlign); + } + + void CCCAppCommLauncherCustomListBoxData::SetSubCellAlignmentL( + TInt aSubCellIndex, CGraphicsContext::TTextAlign aAlign) + { + TInt index = 0; + FindSubCellIndexOrAddL(index, aSubCellIndex); + At(index).iAlign = aAlign; + + iExtension->SetSubCellLayoutAlignmentL(aSubCellIndex); + } + + const CCCAppCommLauncherCustomListBoxData::TColors & +CCCAppCommLauncherCustomListBoxData::SubCellColors(TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return defaultcolors; + return (iSubCellArray->At(index).iColors); + } + + void CCCAppCommLauncherCustomListBoxData::SetSubCellColorsL( + TInt aSubCellIndex, const TColors & aColors) + { + TInt index = 0; + FindSubCellIndexOrAddL(index, aSubCellIndex); + At(index).iColors = aColors; + At(index).iUseSubCellColors = ETrue; + } + + TBool CCCAppCommLauncherCustomListBoxData::UseSubCellColors( + TInt aSubCell) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCell) == KErrNotFound) + return EFalse; + return At(index).iUseSubCellColors; + } + + CGraphicsContext::TPenStyle CCCAppCommLauncherCustomListBoxData::SubCellRightSeparatorStyle( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return CGraphicsContext::ENullPen; + return (iSubCellArray->At(index).iRightSeparatorStyle); + } + + void CCCAppCommLauncherCustomListBoxData::SetSubCellRightSeparatorStyleL( + TInt aSubCellIndex, CGraphicsContext::TPenStyle aStyle) + { + TInt index = 0; + FindSubCellIndexOrAddL(index, aSubCellIndex); + At(index).iRightSeparatorStyle = aStyle; + } + + TBool CCCAppCommLauncherCustomListBoxData::SubCellIsGraphics( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return EFalse; + return (iSubCellArray->At(index).iGraphics); + } + + void CCCAppCommLauncherCustomListBoxData::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); + } + + TBool CCCAppCommLauncherCustomListBoxData::SubCellIsNumberCell( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return EFalse; + return (iSubCellArray->At(index).iNumberCell); + } + + void CCCAppCommLauncherCustomListBoxData::SetNumberCellL( + TInt aSubCellIndex, TBool aIsNumberCell) + { + TInt index = 0; + FindSubCellIndexOrAddL(index, aSubCellIndex); + At(index).iNumberCell = aIsNumberCell; + } + + TBool CCCAppCommLauncherCustomListBoxData::SubCellIsTransparent( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return EFalse; + return (iSubCellArray->At(index).iTransparent); + } + + void CCCAppCommLauncherCustomListBoxData::SetTransparentSubCellL( + TInt aSubCellIndex, TBool aIsTransparent) + { + TInt index = 0; + FindSubCellIndexOrAddL(index, aSubCellIndex); + At(index).iTransparent = aIsTransparent; + } + + TBool CCCAppCommLauncherCustomListBoxData::SubCellIsNotAlwaysDrawn( + TInt aSubCellIndex) const + { + TInt index = 0; + if (FindSubCellIndex(index, aSubCellIndex) == KErrNotFound) + return EFalse; + return (iSubCellArray->At(index).iNotAlwaysDrawn); + } + + void CCCAppCommLauncherCustomListBoxData::SetNotAlwaysDrawnSubCellL( + TInt aSubCellIndex, TBool aIsNotAlwaysDrawn) + { + TInt index = 0; + FindSubCellIndexOrAddL(index, aSubCellIndex); + At(index).iNotAlwaysDrawn = aIsNotAlwaysDrawn; + } + + CArrayPtr* +CCCAppCommLauncherCustomListBoxData::IconArray() const + { + return iIconArray; + } + + void CCCAppCommLauncherCustomListBoxData::SetIconArrayL(CArrayPtr< + CGulIcon>* aArray) + { + iIconArray = aArray; + } + + void CCCAppCommLauncherCustomListBoxData::SetIconArray(CArrayPtr< + CGulIcon>* aArray) + { + iIconArray = aArray; + } + + TBool CCCAppCommLauncherCustomListBoxData::RespectFocus() const + { + if (iExtension) + return iExtension->iRespectFocus; + return EFalse; + } + + void CCCAppCommLauncherCustomListBoxData::SetRespectFocus(TBool aBool) + { + if (iExtension) + iExtension->iRespectFocus = aBool; + } + + CFont* +CCCAppCommLauncherCustomListBoxData::Font( + const TListItemProperties& /*aItemProperties*/, TInt aSubCellIndex) const + { + return const_cast (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 + } + + void CCCAppCommLauncherCustomListBoxData::Draw( + TListItemProperties aProperties, CWindowGc& aGc, const TDesC* aText, + const TRect& aRect, TBool aHighlight, const TColors& aColors) const + { + DrawDefaultHighlight(aGc, aRect, aHighlight); + + // Draw the actual items. + DrawFormatted(aProperties, aGc, aText, aRect, aHighlight, aColors); + } + + void CCCAppCommLauncherCustomListBoxData::DrawFormatted( + TListItemProperties aProperties, CWindowGc& aGc, const TDesC* aText, + const TRect& aItemRect, TBool aHighlight, const TColors& aColors) const + { + if (aHighlight) + { + iExtension->iClippedSubcells = 0; + } + +#ifdef RD_UI_TRANSITION_EFFECTS_LIST + MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal(&aGc); + TBool effectsDisabled = ETrue; + + if (transApi) + { + transApi->StartDrawing(MAknListBoxTfxInternal::EListItem); + effectsDisabled = transApi->EffectsDisabled(); + + if (effectsDisabled) + { + CListBoxView* view = + static_cast (iExtension->iControl)->View(); + aGc.SetClippingRect(view->ViewRect()); + } + } +#else + CListBoxView* view = static_cast( 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 (effectsDisabled) + { + aGc.CancelClippingRect(); + } + + transApi->StopDrawing(); + } +#else + aGc.CancelClippingRect(); +#endif //RD_UI_TRANSITION_EFFECTS_LIST + } + +void CCCAppCommLauncherCustomListBoxData::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 CCCAppCommLauncherCustomListBoxData::DrawFormattedSimple( + TListItemProperties& aProperties, CWindowGc& aGc, const TDesC* aText, + const TRect& aItemRect, TBool aHighlight, const TColors& aColors) const + { + 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()); + TBool skinEnabled = AknsUtils::AvkonSkinEnabled(); + + 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 ( skinEnabled ) + { + if ( iExtension->iHighlightedTextColor != NULL ) + { + color = iExtension->iHighlightedTextColor; + } + } + } + else + { + color = subcellColors->iText; + aGc.SetBrushColor(subcellColors->iBack); + if ( skinEnabled ) + { + if ( iExtension->iTextColor != NULL ) + { + color = iExtension->iTextColor; + } + } + } + + // graphics or text column + if (iExtension->AtSL(SCindex).iSubCellType == CCCAppCommLauncherCustomListBoxDataExtension::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 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( + 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 );*/ //qiang + } + + 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 ) + { + 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 && indexCount()),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( this )-> +SetWordWrappedSubcellIndices( -1, -1 ); +} + + CCCAppCommLauncherCustomListBoxData::CCCAppCommLauncherCustomListBoxData() : + CListBoxData() + { + } + + void CCCAppCommLauncherCustomListBoxData::ConstructLD() + { + TRAPD( err, DoConstructL( KAknsIIDQsnAnimList ) ); + if (err) + { + delete (this); + User::Leave(err); + } + } + + void CCCAppCommLauncherCustomListBoxData::ConstructLD( + const TAknsItemID& aAnimationIID) + { + TRAPD( err, DoConstructL( aAnimationIID ) ); + if (err) + { + delete (this); + User::Leave(err); + } + } + +void CCCAppCommLauncherCustomListBoxData::DoConstructL( + const TAknsItemID& aAnimationIID) + { + iSubCellArray = new (ELeave) CArrayFixFlat ( + KSubCellListBoxGranularity); + iExtension = new (ELeave) CCCAppCommLauncherCustomListBoxDataExtension; + + 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 CCCAppCommLauncherCustomListBoxData::LastSubCell() const + { + TInt count = iSubCellArray->Count(); + if (!count) + return (KErrNotFound); + return (At(count - 1).iSubCell); + } + +void CCCAppCommLauncherCustomListBoxData::AddSubCellL(TInt 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); + } + +CCCAppCommLauncherCustomListBoxData::SSubCell& +CCCAppCommLauncherCustomListBoxData::At(TInt aArrayIndex) + { + //__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndexCount(),Panic(EAknPanicOutOfRange)); + return (iSubCellArray->At(aArrayIndex)); + } + +const CCCAppCommLauncherCustomListBoxData::SSubCell& +CCCAppCommLauncherCustomListBoxData::At(TInt aArrayIndex) const + { + //__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndexCount(),Panic(EAknPanicOutOfRange)); + return (iSubCellArray->At(aArrayIndex)); + } + +TInt CCCAppCommLauncherCustomListBoxData::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 CCCAppCommLauncherCustomListBoxData::FindSubCellIndexOrAddL( + TInt& aArrayIndex, TInt aSubCell) + { + if (FindSubCellIndex(aArrayIndex, aSubCell) == KErrNotFound) + { + AddSubCellL(aSubCell); + FindSubCellIndex(aArrayIndex, aSubCell); + } + } + + CCCAppCommLauncherCustomListBoxData::TColors::TColors() : + iText(KRgbBlack), iBack(KRgbWhite), iHighlightedText(KRgbWhite), iHighlightedBack( + KRgbBlack), + iRightSeparatorColor(AKN_LAF_COLOR_STATIC(215)) + { + } + +TInt CCCAppCommLauncherCustomListBoxData::AddActualFontL(const CFont* aBaseFont) + { + if (!iNormalFont.iFonts) + { + iNormalFont.iFonts = new (ELeave) CArrayPtrFlat (1); + iBoldFont.iFonts = new (ELeave) CArrayPtrFlat (1); + iItalicFont.iFonts = new (ELeave) CArrayPtrFlat (1); + iBoldItalicFont.iFonts = new (ELeave) CArrayPtrFlat (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); + + return fontCount - 1; + } + +void CCCAppCommLauncherCustomListBoxData::DrawDefaultHighlight(CWindowGc &aGc, + const TRect &aItemRect, TBool aHighlight) const + { + // 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 (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) + { + TRAP_IGNORE( highlightDrawn = iExtension->DrawPressedDownEffectL( + 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 + } + } + +void CCCAppCommLauncherCustomListBoxData::DrawSettingHighlight(CWindowGc &aGc, + const TRect &aItemRect, TBool aHighlight) const + { + DrawDefaultHighlight(aGc, aItemRect, aHighlight); + } + +void CCCAppCommLauncherCustomListBoxData::DrawPopupHighlight(CWindowGc &aGc, + const TRect &aItemRect, TBool aHighlight) const + { + DrawDefaultHighlight(aGc, aItemRect, aHighlight); + } + +void CCCAppCommLauncherCustomListBoxData::DrawPopupFrame(CWindowGc &aGc) const + { + 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()); + } + } + } + +void CCCAppCommLauncherCustomListBoxData::SetWordWrappedSubcellIndices( + TInt aFirstIndex, TInt aSecondIndex) + { + iExtension->iFirstWordWrappedSubcellIndex = (TInt16) aFirstIndex; + iExtension->iSecondWordWrappedSubcellIndex = (TInt16) aSecondIndex; + } + + void CCCAppCommLauncherCustomListBoxData::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__ + const TBool CCCAppCommLauncherCustomListBoxData::IsMarqueeOn() + { + return iExtension->IsMarqueeOn(); + } +#else + TBool CCCAppCommLauncherCustomListBoxData::IsMarqueeOn() + { + return iExtension->IsMarqueeOn(); + } +#endif // __WINS__ + +void CCCAppCommLauncherCustomListBoxData::FocusGained() + { + iExtension->FocusGained(); + } + +void CCCAppCommLauncherCustomListBoxData::FocusLost() + { + iExtension->FocusLost(); + } + +void CCCAppCommLauncherCustomListBoxData::HandleResourceChange(TInt aType) + { + // 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( + CCCAppCommLauncherCustomListBoxDataExtension::EFlagUpdateBg); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::HighlightAnim +// ----------------------------------------------------------------------------- +// + const CAknsEffectAnim* CCCAppCommLauncherCustomListBoxData::HighlightAnim() const + { + if (iExtension) + return iExtension->iAnimation; + return NULL; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::AboutToDrawHighlightAnim +// ----------------------------------------------------------------------------- +// + void CCCAppCommLauncherCustomListBoxData::AboutToDrawHighlightAnim() const + { + if (!iExtension) + { + return; + } + if (!iExtension->iAnimation || !iExtension->iControl) + { + return; + } + + CEikListBox* list = static_cast (iExtension->iControl); + CListBoxView* view = list->View(); + if (!view) + { + return; + } + + if (view->CurrentItemIndex() != iExtension->iCurrentRow) + { + iExtension->iAnimFlags.Set( + CCCAppCommLauncherCustomListBoxDataExtension::EFlagUpdateBg); + iExtension->iCurrentRow = view->CurrentItemIndex(); + } + + iExtension->SyncAnim(iExtension->iAnimSize); + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::SetHighlightAnimBackgroundDrawer +// ----------------------------------------------------------------------------- +// + void CCCAppCommLauncherCustomListBoxData::SetHighlightAnimBackgroundDrawer( + MListBoxAnimBackgroundDrawer* aDrawer) + { + if (iExtension) + { + iExtension->iHighlightBgDrawer = aDrawer; + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::SetItemCellSize +// ----------------------------------------------------------------------------- +// + void CCCAppCommLauncherCustomListBoxData::SetItemCellSize( + const TSize& aSize) + { + if (iExtension) + { + if (iExtension->iAnimSize != aSize) + { + iExtension->Play(); + } + iExtension->iAnimSize = aSize; + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::HasHighlightAnim +// ----------------------------------------------------------------------------- +// + TBool CCCAppCommLauncherCustomListBoxData::HasHighlightAnim() const + { + if (!iExtension) + return EFalse; + if (!iExtension->iAnimation) + return EFalse; + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::DrawHighlightAnim +// ----------------------------------------------------------------------------- +// + TBool CCCAppCommLauncherCustomListBoxData::DrawHighlightAnim( + CBitmapContext& aGc, const TRect& aRect) const + { + if (!iExtension) + return EFalse; + + if (!iExtension->iAnimation) + return EFalse; + + return iExtension->SyncAndDrawAnim(aGc, aRect); + } + +void CCCAppCommLauncherCustomListBoxData::ResetMarquee() + { + if (iExtension->iMarquee) + { + iExtension->iMarquee->Reset(); + } + if (iExtension->i2ndLineMarquee) + { + iExtension->i2ndLineMarquee->Reset(); + } + } + +TInt CCCAppCommLauncherCustomListBoxData::CurrentMarqueeItemIndex() + { + return iExtension->iCurrentItem; + } + +void CCCAppCommLauncherCustomListBoxData::SetCurrentMarqueeItemIndex( + TInt aIndex) + { + iExtension->iCurrentItem = aIndex; + } + +void CCCAppCommLauncherCustomListBoxData::SetCurrentItemIndex(TInt aIndex) + { + if (iExtension->iCurrentRow != aIndex) + { + iExtension->iAnimFlags.Set( + CCCAppCommLauncherCustomListBoxDataExtension::EFlagUpdateBg); + } + iExtension->iCurrentRow = aIndex; + } + +void CCCAppCommLauncherCustomListBoxData::SetCurrentlyDrawnItemIndex( + TInt aIndex) + { + if (iExtension) + { + iExtension->iCurrentlyDrawnItemIndex = aIndex; + } + } + + const CFont* +CCCAppCommLauncherCustomListBoxData::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); + } + + void CCCAppCommLauncherCustomListBoxData::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 + */ + void CCCAppCommLauncherCustomListBoxData::SetDrawBackground( + const TBool aDrawBackground) + { + iExtension->iDrawBackground = aDrawBackground; + if (!aDrawBackground) + { + iExtension->DeleteAnim(); + } + } + +/** + * Is the listbox drawing the background itself or not (= "transparency") + */ +TBool CCCAppCommLauncherCustomListBoxData::IsBackgroundDrawingEnabled() const + { + return iExtension->iDrawBackground; + } + +/** + * Enables / disables drawing background after scrollbar + * @param aDrawBackground default ETrue + */ +void CCCAppCommLauncherCustomListBoxData::SetDrawScrollbarBackground( + const TBool aDrawBackground) + { + iExtension->iDrawScrollbarBackground = aDrawBackground; + } + +/** + * Is the listbox drawing the background after scrollbar or not + */ +TBool CCCAppCommLauncherCustomListBoxData::IsScrollbarBackgroundDrawingEnabled() const + { + return iExtension->iDrawScrollbarBackground; + } + + void CCCAppCommLauncherCustomListBoxData::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); + } + } + + void CCCAppCommLauncherCustomListBoxData::SetSubCellIconSize( + TInt aIndex, TSize aSize) + { + if (iExtension && aIndex <= KMaxSubCellIndex && aIndex >= 0) + { + iExtension->iSubCellIconSize[aIndex] = aSize; + } + } + +TSize CCCAppCommLauncherCustomListBoxData::GetSubCellIconSize(TInt aIndex) + { + if (iExtension && aIndex <= KMaxSubCellIndex && aIndex >= 0) + { + return iExtension->iSubCellIconSize[aIndex]; + } + return TSize(0, 0); + } + +void CCCAppCommLauncherCustomListBoxData::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 CCCAppCommLauncherCustomListBoxData::SetESSTextColor( + TAknsQsnTextColorsIndex aIndex) + { + TRgb color; + + TInt error = AknsUtils::GetCachedColor(AknsUtils::SkinInstance(), color, + KAknsIIDQsnTextColors, aIndex); + if (!error && iExtension) + { + iExtension->iTextColor = color; + } + } + +// extended skin support +void CCCAppCommLauncherCustomListBoxData::SetESSHighlightedTextColor( + TAknsQsnTextColorsIndex aIndex) + { + TRgb color; + + TInt error = AknsUtils::GetCachedColor(AknsUtils::SkinInstance(), color, + KAknsIIDQsnTextColors, aIndex); + if (!error) + { + iExtension->iHighlightedTextColor = color; + } + } + +void CCCAppCommLauncherCustomListBoxData::SetGraphicSubCellL(TInt aSubCell, + const TAknWindowLineLayout &aGraphicLayout) + { + if (!iExtension) + return; + CEikFormattedCellListBox* list = + static_cast (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 + = CCCAppCommLauncherCustomListBoxDataExtension::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 CCCAppCommLauncherCustomListBoxData::SetTextSubCellL(TInt aSubCell, + const TAknTextLineLayout &aTextLayout) + { + if (!iExtension) + return; + CEikFormattedCellListBox* list = + static_cast (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 + = CCCAppCommLauncherCustomListBoxDataExtension::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 = 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 + + } + + +TInt CCCAppCommLauncherCustomListBoxData::CorrectBaseline(TInt aParentHeight, TInt aBaseline, TInt aFontId) + { + TInt B = aBaseline; + + if( /*TAknFontId::IsEncodedFont(aFontId) &&*/ aFontId != ELayoutEmpty ) // This tells us that the font id has come from scalable layout API + { + TInt b = aBaseline; + if (IsParentRelative(b)) { b = aParentHeight - ELayoutP + b; } + + const CAknLayoutFont *font = AknLayoutUtils::LayoutFontFromId(aFontId); + TInt descent = font->BaselineToTextPaneBottom(); + + // calculate distance down from top of parent to bottom of maximal glyph + TInt top2bog = aParentHeight - b; + + // distance down to baseline is distance down to bottom of glyph minus descent + // A further 1 is subtracted to account for the definition of baseline in the + // Series 60 pre-2.8 layout specifications. + B = top2bog - descent - 1; + } + + return B; + } +TBool CCCAppCommLauncherCustomListBoxData::IsParentRelative(TInt aVal) + { + return aVal > ELayoutP-ELayoutPRange && aVal <= ELayoutP; + } + +void CCCAppCommLauncherCustomListBoxData::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 + != CCCAppCommLauncherCustomListBoxDataExtension::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 + == CCCAppCommLauncherCustomListBoxDataExtension::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 (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 + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::UsesScalableLayoutData +// ----------------------------------------------------------------------------- +// +TBool CCCAppCommLauncherCustomListBoxData::UsesScalableLayoutData() const + { + if (iExtension) + return iExtension->iSimpleList; + + return EFalse; + } +void CCCAppCommLauncherCustomListBoxData::UseScalableLayoutData(TBool aUse) + { + if (iExtension) + { + if (!aUse && iExtension->iSimpleList) + { + CEikFormattedCellListBox + * list = + static_cast (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)); + } + } + iExtension->iSimpleList = aUse; + } + } + + void CCCAppCommLauncherCustomListBoxData::SetSubcellUnderlined( + TBitFlags32 aUnderlinedCells) + { + if (iExtension) + { + iExtension->iUnderlineFlagSet = ETrue; + iExtension->iUnderlineFlags = aUnderlinedCells; + } + } + +void CCCAppCommLauncherCustomListBoxData::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 CCCAppCommLauncherCustomListBoxData::UseHighlightIconSwapping(TBool aUse) + { + if (iExtension) + { + iExtension->iUseHighligthIconSwapping = aUse; + } + } + +TBool CCCAppCommLauncherCustomListBoxData::UseHighlightIconSwapping() const + { + if (iExtension) + { + return iExtension->iUseHighligthIconSwapping; + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::SetStretchableGraphicSubCellL +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxData::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()); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::SetStretchableTextSubCellL +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxData::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()); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::SetStretchableConditionalSubCellL +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxData::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); + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::ResetSLSubCellArray +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxData::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() ); + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::StretchingEnabled +// ----------------------------------------------------------------------------- +// +TBool CCCAppCommLauncherCustomListBoxData::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 +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::EnableStretching +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxData::EnableStretching(const TBool aEnabled) + { + if (!iExtension) + { + return; + } + + iExtension->iStretchingEnabled = aEnabled; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::HideSecondRow +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxData::HideSecondRow(const TBool aHide) + { + if (!iExtension) + { + return; + } + + iExtension->iHideSecondRow = aHide; + } +#endif // RD_LIST_STRETCH +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::SecondRowHidden +// ----------------------------------------------------------------------------- +// +TBool CCCAppCommLauncherCustomListBoxData::SecondRowHidden() const + { + if (!iExtension) + { + return EFalse; + } + + return iExtension->iHideSecondRow; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::ToggleDropShadows +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxData::ToggleDropShadows(const TBool aEnable) + { + if (!iExtension) + { + return; + } + iExtension->iUseDropShadows = aEnable; + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::CheckIfSubCellsIntersect +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxData::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]; + TBool layoutMirrored = AknLayoutUtils::LayoutMirrored(); + + // 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 (!layoutMirrored) + { + bRect.iBr.iX = bRect2.iTl.iX; + } + else + { + bRect.iTl.iX = bRect2.iBr.iX; + } + } + } + + if (aResults[subCell]) + { + if (iExtension->AtSL(subCellIndex).iSubCellType + == CCCAppCommLauncherCustomListBoxDataExtension::EAknSLText) + { + TAknTextLineLayout textLine = + iExtension->AtSL(subCellIndex).iTextLayout; + + textLine.iW = bRect.Width(); + + if (!layoutMirrored) + { + textLine.ir = aItemRect.iBr.iX - bRect.iBr.iX; + } + else + { + textLine.il = bRect.iTl.iX - aItemRect.iTl.iX; + } + + aLayouts[subCell] = textLine; + } + } + + ++subCell; + } + } + +// ----------------------------------------------------------------------------- +// CCCAppCommLauncherCustomListBoxData::SubCellsMightIntersect +// ----------------------------------------------------------------------------- +// +void CCCAppCommLauncherCustomListBoxData::SubCellsMightIntersect( + const TBool aMightIntersect) + { + iExtension->iSubCellsMightIntersect = aMightIntersect; + } + +void CCCAppCommLauncherCustomListBoxDataExtension::CreateColorBitmapsL() + { + if (iColorBmp) + { + CreateColorBitmapsL(iColorBmp->SizeInPixels()); + } + } + +void CCCAppCommLauncherCustomListBoxDataExtension::CreateColorBitmapsL( + TSize aSize) + { + 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) + return; + + error = AknsUtils::GetCachedColor(AknsUtils::SkinInstance(), hiliColor, + KAknsIIDQsnIconColors, EAknsCIQsnIconColorsCG16); + if (error) + return; + + if (iColorBmp && iColorBmp->SizeInPixels() == aSize && color == iIconColor + && hiliColor == iHiliIconColor) + { + 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); + } + +void CCCAppCommLauncherCustomListBoxData::DrawFormattedOld( + TListItemProperties& aProperties, CWindowGc& aGc, const TDesC* aText, + const TRect& aItemRect, TBool aHighlight, const TColors& aColors) const + { + 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(); + } + TBool linesShown = AknListBoxUtils::ListBoxLinesShown( + AknsUtils::SkinInstance(), cc); + + 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(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(SubCellPosition(subcell), SubCellSize(subcell)); + TRect cRect2(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 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 (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 && indexCount()),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 >> 1; + posInBitmap.iY >> 1; + 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 (this)-> SetWordWrappedSubcellIndices( + -1, -1); + } + +void CCCAppCommLauncherCustomListBoxData::SetClippedByWrap( + TUint32 aClippedCells, TBool aUseClippedByWrap) + { + if (iExtension) + { + iExtension->iClippedByWrap = aClippedCells; + iExtension->iUseClippedByWrap = aUseClippedByWrap; + } + } + + TUint32 CCCAppCommLauncherCustomListBoxData::CurrentItemTextWasClipped() const + { + return iExtension ? iExtension->iClippedSubcells : 0; + } + +TBool CCCAppCommLauncherCustomListBoxData::KineticScrollingEnabled() const + { + if (iExtension) + { + return iExtension->iKineticScrolling; + } + return EFalse; + } + +CEikListBox* CCCAppCommLauncherCustomListBoxData::ListBox() const + { + if (iExtension && iExtension->iControl) + { + return static_cast (iExtension->iControl); + } + return NULL; + } + +// End of File +