/*
* Copyright (c) 1997-2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
#include <eikclbd.h>
#include <aknlists.h>
#include <AknsEffectAnim.h>
#include <AknPictographInterface.h>
#include <AknPictographDrawerInterface.h>
#include <centralrepository.h>
#include <AvkonInternalCRKeys.h>
#include <AknsListBoxBackgroundControlContext.h>
#include <AknMarqueeControl.h>
#include <eikpanic.h>
#include <eikcoctlpanic.h>
#include <gulicon.h>
#include <AknBidiTextUtils.h>
#include <skinlayout.cdl.h>
#include <layoutmetadata.cdl.h>
#include <aknlayoutscalable_avkon.cdl.h>
#include <aknphysics.h>
#include <AknIconArray.h>
#include <avkon.mbg>
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
#include <aknlistloadertfx.h>
#include <aknlistboxtfxinternal.h>
#endif //RD_UI_TRANSITION_EFFECTS_LIST
#include <touchfeedback.h>
#include "akntrace.h"
const TInt KColumnListBoxGranularity=4;
const TInt KNoActualColumnFont=-1;
const TInt KMaxColumn = 6;
// colored tick marks support
const TInt KColorIconFlag = -1;
const TInt KColorIconIdx = 0;
// Number of icons in marking mode icon array
const TInt KMarkingModeIconArraySize = 2;
/**
* 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(CColumnListBoxDataExtension) :
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
{
EEikSLGraphic,
EEikSLText,
EEikSLNumeric
};
public:
CColumnListBoxDataExtension();
void ConstructL( CColumnListBoxData* aListBoxData,
const TAknsItemID& aAnimationIID );
~CColumnListBoxDataExtension();
static TInt RedrawEvent(TAny* aControl);
TBool IsMarqueeOn();
struct SRowAndColumn
{
TInt iIndex; // 24 bits for row and 8 bits for column
const CFont* iFont;
};
SRowAndColumn& At(TInt aArrayIndex);
const SRowAndColumn& At(TInt aArrayIndex) const;
void AddRowAndColumnL(TInt aRow,TInt aColumn);
TInt FindRowAndColumnIndex(TInt& aArrayIndex,TInt aRow,TInt aColumn) const;
void FindRowAndColumnIndexOrAddL(TInt& aArrayIndex,TInt aRow,TInt aColumn);
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 SkinChangedL();
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();
TBool DrawPressedDownEffectL( MAknsSkinInstance* aInstance,
CWindowGc& aGc,
const TRect& aOutRect,
const TRect& aInnerRect ) const;
void LoadMarkingIconsL();
public: //for handling column alignment
struct TColumnExt
{
TInt iColumn; // Must be first entry
TBool iLayoutAlign;//is layout alignment or Set by client
};
TInt AddColumnExtL(TInt aColumn);
void FindColumnExtIndexOrAddL(TInt& aArrayIndex,TInt aColumn);
void SetColumnLayoutAlignmentL(TInt aColumn);
TBool FindColumnExtIndex(TInt& aArrayIndex,TInt aColumn) const;
TBool ColumnLayoutAlignment(TInt aColumn) const;
public: // new list layout system
struct SRowAndSubCell
{
TInt iIndex; // 24 bits for row and 8 bits for subcell
const CFont* iFont;
};
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
};
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();
private: // New internal methods
TBool DrawHighlightBackground( CFbsBitGc& aGc );
void PostDeleteAnimation();
void CreateAnimationL();
void DoResizeL( const TSize& aHighlightSize, TBool aAboutToStart );
private: // from MAknPictographAnimatorCallback
void DrawPictographArea();
public:
CArrayPtr<CGulIcon>* iIconArray;
CCoeControl *iControl; // not owned
CAknsListBoxBackgroundControlContext* iSkinControlContext;
const TAknsItemID *iSkinHighlightFrameId;
const TAknsItemID *iSkinHighlightFrameCenterId;
TBool iSkinEnabled;
CAknPictographInterface* iPictoInterface;
CAknMarqueeControl* iMarquee;
CAknMarqueeControl* i2ndLineMarquee;
TInt iCurrentItem; // Marquee:
TInt iCurrentRow; // Current list row being drawn.
CArrayFix<SRowAndColumn>* iRowAndColumnArray;
TSize iSubCellIconSize[6]; // Store icon sizes for each column
TAknSeparatorLinePosition iSeparatorLinePosition;
CAknsEffectAnim* iAnimation;
/**
* Stored flags are explained in enumeration TFlags.
*/
TBitFlags32 iAnimFlags;
CColumnListBoxData* iListBoxData;
TRgb iHighlightedTextColor;
TRgb iTextColor;
TAknsItemID iAnimIID;
MColumnListBoxAnimBackgroundDrawer* iHighlightBgDrawer;
TSize iAnimSize; // TODO Deprecating old style anim API and removing this
TBool iUnderlineFlagSet; // underlining support for more than
TBitFlags32 iUnderlineFlags; // one text subcell
TBool iUseLayoutData;
TBool iStretchingEnabled;
CArrayFix<SRowAndSubCell>* iRowAndSubCellArray;
CArrayFix<SSLSubCell>* iSLSubCellArray;
TBool iSubCellsMightIntersect;
TRect iParent; // parent for size calculations
// colorskin highlight icons
CFbsBitmap* iColorBmp;
CFbsBitmap* iHiliBmp;
TRgb iIconColor;
TRgb iHiliIconColor;
TInt iConditionalCells;
// which columns of highlighted item have clipped text ?
TUint32 iClippedColumns;
TBool iKineticScrolling;
CArrayFix<TColumnExt>* iColumnExtArray; //for column alignment
TRect iMarginRect;
CAknIconArray* iMarkingIconArray;
};
/**
* High priority is well argumented because running the active object will
* result in animation deletion -> results in freeing resources.
*/
CColumnListBoxDataExtension::CColumnListBoxDataExtension():
CActive( EPriorityHigh )
{}
void CColumnListBoxDataExtension::ConstructL(
CColumnListBoxData* aListBoxData,
const TAknsItemID& aAnimationIID )
{
_AKNTRACE_FUNC_ENTER;
ASSERT( aListBoxData );
iListBoxData = aListBoxData;
iRowAndColumnArray=new(ELeave) CArrayFixFlat<SRowAndColumn>(4);
iSeparatorLinePosition = ENoLine;
iAnimIID = aAnimationIID;
CActiveScheduler::Add( this );
TryCreateAnimation(); // Animations are created by default
// try to set ESS text colors here so that they will be set at least somewhere...
iTextColor = NULL; // just in case
iHighlightedTextColor = NULL; // just in case
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
TRgb color;
// set ESS text color
TInt error = AknsUtils::GetCachedColor( skin,
color,
KAknsIIDQsnTextColors,
EAknsCIQsnTextColorsCG6 );
if ( !error )
{
iTextColor = color;
}
// set ESS highlighted text color
error = AknsUtils::GetCachedColor( skin,
color,
KAknsIIDQsnTextColors,
EAknsCIQsnTextColorsCG10 );
if ( !error )
{
iHighlightedTextColor = color;
}
iRowAndSubCellArray=new(ELeave) CArrayFixFlat<SRowAndSubCell>(4);
iSLSubCellArray=new(ELeave) CArrayFixFlat<SSLSubCell>(4);
iColumnExtArray = new(ELeave) CArrayFixFlat<TColumnExt>(KColumnListBoxGranularity);
#ifdef RD_LIST_STRETCH
// check list stretching from cenrep
CRepository* cenRep = CRepository::NewL( KCRUidAvkon );
cenRep->Get( KAknAutomaticListStretching, iStretchingEnabled );
delete cenRep;
#endif // RD_LIST_STRETCH
iKineticScrolling = CAknPhysics::FeatureEnabled();
LoadMarkingIconsL();
_AKNTRACE_FUNC_EXIT;
}
CColumnListBoxDataExtension::~CColumnListBoxDataExtension()
{
Cancel();
// Stop receiving foreground events
CCoeEnv* env = CCoeEnv::Static();
env->RemoveForegroundObserver( *this );
delete iRowAndColumnArray;
iRowAndColumnArray = NULL;
delete iSkinControlContext;
delete iPictoInterface;
delete iMarquee;
delete i2ndLineMarquee;
delete iAnimation;
delete iRowAndSubCellArray;
delete iSLSubCellArray;
delete iColorBmp;
delete iHiliBmp;
delete iColumnExtArray;
if ( iMarkingIconArray )
{
iMarkingIconArray->ResetAndDestroy();
}
delete iMarkingIconArray;
}
MAknsControlContext* CColumnListBoxDataExtension::SkinBackgroundContext() const
{
if ( iSkinEnabled )
{
return iSkinControlContext;
}
return NULL;
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::NoAnimIfError
// -----------------------------------------------------------------------------
//
inline void CColumnListBoxDataExtension::NoAnimIfError( TInt aError )
{
if( KErrNone != aError )
{
DeleteAnim();
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::TryCreateAnimation
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::TryCreateAnimation()
{
if( !iControl )
{
return;
}
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
CEikListBox* list = static_cast<CEikListBox*>( iControl );
CListBoxView* view = list->View();
if ( !view || !view->ItemDrawer() )
{
return;
}
CWindowGc* gc = view->ItemDrawer()->Gc();
MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( gc );
if ( transApi && transApi->VerifyKml() == KErrNone )
{
return;
}
#endif //RD_UI_TRANSITION_EFFECTS_LIST
// Ideally we should not create animation if the list has zero items.
// Unfortunately, this will cause problems elsewhere as setting item text
// array to list requires not calling HandleItemAddition (or similar
// method) -> in some situations animation would not be created at all as
// we don't receive item change event. Fortunately, creating animation to
// empty list doesn't carry much overhead as layer creation is delayed to
// first render.
if( !iAnimation )
{
// This must be the first call because animation does not exist.
// Animation layers are created when the animation is rendered for the
// first time.
TRAPD( err, CreateAnimationL() );
NoAnimIfError( err );
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::SyncAnim
// -----------------------------------------------------------------------------
//
TBool CColumnListBoxDataExtension::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;
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::SyncAndDrawAnim
// -----------------------------------------------------------------------------
//
TBool CColumnListBoxDataExtension::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;
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::DeleteAnim
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::DeleteAnim()
{
// Stop receiving foreground events
CCoeEnv* env = CCoeEnv::Static();
env->RemoveForegroundObserver( *this );
delete iAnimation;
iAnimation = NULL;
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::FocusGained
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::FocusGained()
{
Play();
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::FocusLost
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::FocusLost()
{
if( iAnimation )
{
NoAnimIfError( iAnimation->Pause() );
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::SkinChangedL
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::SkinChangedL()
{
DeleteAnim();
TryCreateAnimation();
CreateColorBitmapsL();
LoadMarkingIconsL();
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::SetControl
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::SetControl( CCoeControl* aControl )
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
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();
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::HandleGainingForeground
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::HandleGainingForeground()
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
// 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();
}
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::HandleLosingForeground
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::HandleLosingForeground()
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
iAnimFlags.Clear( EFlagHasForeground );
if( iAnimation )
{
NoAnimIfError( iAnimation->Stop() );
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::AnimFrameReady
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::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
CEikColumnListBox* list = static_cast<CEikColumnListBox*>( 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;
}
// No items, no drawing
if( list->Model()->NumberOfItems() == 0 )
{
return;
}
// Column array is not ready yet
if( iListBoxData->LastColumn() < 0 )
{
return;
}
// Repaint the highlighted cell only
view->DrawItem( view->CurrentItemIndex() );
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::ListBoxItemsChanged
// we get here 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 CColumnListBoxDataExtension::ListBoxItemsChanged(
CEikListBox* aListBox)
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
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();
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::DoCancel
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::DoCancel()
{
// Required method, but not needed
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::RunL
// Postponed animation deletion is done here.
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::RunL()
{
DeleteAnim();
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::Play
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::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
CEikColumnListBox* list = static_cast<CEikColumnListBox*>( 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() );
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::DrawHighlightBackground
// -----------------------------------------------------------------------------
//
TBool CColumnListBoxDataExtension::DrawHighlightBackground( CFbsBitGc& aGc )
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
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.
CEikColumnListBox* list =
static_cast<CEikColumnListBox*>( 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() );
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
MAknsControlContext* cc = AknsDrawUtils::ControlContext( iControl );
if( !cc )
cc = SkinBackgroundContext();
return AknsDrawUtils::DrawBackground( skin, cc, iControl, aGc, TPoint(0,0),
itemRect, KAknsDrawParamBottomLevelRGBOnly );
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::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 CColumnListBoxDataExtension::PostDeleteAnimation()
{
TRequestStatus* status = &iStatus;
User::RequestComplete( status, KErrNone );
SetActive();
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::CreateAnimationL
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::CreateAnimationL()
{
DeleteAnim();
// Check if derived class wants to disable highligh animation
if( KAknsIIDNone == iAnimIID )
{
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<CAknAppUi*>(CEikonEnv::Static()->AppUi());
iAnimFlags.Assign( EFlagHasForeground, aui->IsForeground() );
Play();
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::DoResizeL
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::DoResizeL(
const TSize& aHighlightSize, TBool aAboutToStart )
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
iAnimation->BeginConfigInputLayersL( aHighlightSize, aAboutToStart );
if( iAnimation->InputRgbGc() )
{
DrawHighlightBackground( *iAnimation->InputRgbGc() );
}
iAnimation->EndConfigInputLayersL();
}
void CColumnListBoxDataExtension::DrawPictographArea()
{
iControl->DrawNow();
}
TInt CColumnListBoxDataExtension::RedrawEvent(TAny* aControl)
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
if (!((CCoeControl*)aControl)->IsVisible())
{
return EFalse;
}
CEikColumnListBox* listBox =
(CEikColumnListBox*)aControl;
// HWET-7BDDD4
CListBoxView* view = listBox->View();
TInt index = listBox->CurrentItemIndex();
if ( view->ItemIsVisible( index ) )
{
listBox->DrawItem( index );
}
return ETrue;
}
TBool CColumnListBoxDataExtension::IsMarqueeOn()
{
TBool isOn = EFalse;
if (iMarquee)
isOn = iMarquee->IsMarqueeOn();
_AKNTRACE( "[%s][%s] isOn = %d",
"CColumnListBoxDataExtension", __FUNCTION__, isOn );
return isOn;
}
void CColumnListBoxDataExtension::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);
}
void
CColumnListBoxDataExtension::AddRowAndColumnL(TInt aRow,TInt aColumn)
{
SRowAndColumn column;
column.iIndex = (aRow << 8) | (aColumn & 0xff);
TKeyArrayFix key(0,ECmpTInt32);
iRowAndColumnArray->InsertIsqL(column,key);
}
CColumnListBoxDataExtension::SRowAndColumn&
CColumnListBoxDataExtension::At(TInt aArrayIndex)
{
__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iRowAndColumnArray->Count(),Panic(EEikPanicOutOfRange));
return(iRowAndColumnArray->At(aArrayIndex));
}
const CColumnListBoxDataExtension::SRowAndColumn&
CColumnListBoxDataExtension::At(TInt aArrayIndex) const
{
__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iRowAndColumnArray->Count(),Panic(EEikPanicOutOfRange));
return(iRowAndColumnArray->At(aArrayIndex));
}
TInt CColumnListBoxDataExtension::FindRowAndColumnIndex(TInt& aArrayIndex,
TInt aRow,
TInt aColumn) const
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
if (iRowAndColumnArray->Count()==0)
return(KErrNotFound);
TKeyArrayFix key(0,ECmpTInt32);
SRowAndColumn rowAndColumn;
rowAndColumn.iIndex = (aRow << 8) | (aColumn & 0xff);
return(iRowAndColumnArray->FindIsq(rowAndColumn,key,aArrayIndex));
}
void CColumnListBoxDataExtension::FindRowAndColumnIndexOrAddL(TInt& aArrayIndex,
TInt aRow,
TInt aColumn)
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
if (FindRowAndColumnIndex(aArrayIndex,aRow,aColumn)!=0) //==KErrNotFound)
{
AddRowAndColumnL(aRow,aColumn);
FindRowAndColumnIndex(aArrayIndex,aRow,aColumn);
}
}
/////////////handling TColumnExt,start
TInt CColumnListBoxDataExtension::AddColumnExtL(TInt aColumn)
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
TColumnExt column;
column.iColumn=aColumn;
column.iLayoutAlign = ETrue;
TKeyArrayFix key(0,ECmpTInt);
return iColumnExtArray->InsertIsqL(column,key);
}
void CColumnListBoxDataExtension::FindColumnExtIndexOrAddL(TInt& aArrayIndex,TInt aColumn)
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
if (!FindColumnExtIndex(aArrayIndex,aColumn))
{
aArrayIndex = AddColumnExtL(aColumn);
}
}
void CColumnListBoxDataExtension::SetColumnLayoutAlignmentL(TInt aColumn)
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
TInt index;
FindColumnExtIndexOrAddL(index,aColumn);
iColumnExtArray->At(index).iLayoutAlign = EFalse;
}
TBool CColumnListBoxDataExtension::FindColumnExtIndex(TInt& aArrayIndex,TInt aColumn) const
{
if (aColumn<0 || iColumnExtArray->Count()==0)
return EFalse;
TKeyArrayFix key(0,ECmpTInt);
TColumnExt column;
column.iColumn=aColumn;
// Returns zero if key was found, otherwise non-zero
TInt ret = iColumnExtArray->FindIsq(column,key,aArrayIndex);
return (ret == 0);
}
TBool CColumnListBoxDataExtension::ColumnLayoutAlignment(TInt aColumn) const
{
TInt index;
if (!FindColumnExtIndex(index,aColumn))
return(ETrue);
return(iColumnExtArray->At(index).iLayoutAlign);
}
/////////////handling TColumnExt,end
CColumnListBoxDataExtension::SSLSubCell&
CColumnListBoxDataExtension::AtSL(TInt aArrayIndex)
{
__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iSLSubCellArray->Count(),Panic(EEikPanicOutOfRange));
return(iSLSubCellArray->At(aArrayIndex));
}
const CColumnListBoxDataExtension::SSLSubCell&
CColumnListBoxDataExtension::AtSL(TInt aArrayIndex) const
{
__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iSLSubCellArray->Count(),Panic(EEikPanicOutOfRange));
return(iSLSubCellArray->At(aArrayIndex));
}
TInt CColumnListBoxDataExtension::FindSLSubCellIndex(TInt& aArrayIndex,
TInt aSubCell) const
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
if (iSLSubCellArray->Count()==0)
return(KErrNotFound);
TKeyArrayFix key(0,ECmpTInt32);
SSLSubCell SLSubCell;
SLSubCell.iSubCell = aSubCell;
return(iSLSubCellArray->FindIsq(SLSubCell,key,aArrayIndex));
}
void CColumnListBoxDataExtension::FindSLSubCellIndexOrAddL(TInt& aArrayIndex,
TInt aSubCell)
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
if (FindSLSubCellIndex(aArrayIndex, aSubCell)!=0) //==KErrNotFound)
{
AddSLSubCellL(aSubCell);
FindSLSubCellIndex(aArrayIndex,aSubCell);
}
}
void CColumnListBoxDataExtension::ResetSLSubCellArray()
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
iSLSubCellArray->Reset();
iRowAndSubCellArray->Reset();
}
TBool CColumnListBoxDataExtension::DrawPressedDownEffectL( MAknsSkinInstance* aInstance,
CWindowGc& aGc,const TRect& aOutRect,
const TRect& aInnerRect ) const
{
return AknsDrawUtils::DrawFrame( aInstance,
aGc,
aOutRect,
aInnerRect,
KAknsIIDQsnFrListPressed,
KAknsIIDQsnFrListCenterPressed );
}
// -----------------------------------------------------------------------------
// CColumnListBoxDataExtension::LoadMarkingIconsL
// -----------------------------------------------------------------------------
//
void CColumnListBoxDataExtension::LoadMarkingIconsL()
{
if ( !iMarkingIconArray )
{
iMarkingIconArray = new ( ELeave ) CAknIconArray(
KMarkingModeIconArraySize );
}
else
{
iMarkingIconArray->ResetAndDestroy();
}
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
const TDesC& avkonIconFile = AknIconUtils::AvkonIconFileName();
CGulIcon* icon = AknsUtils::CreateGulIconL( skin,
KAknsIIDQgnPropCheckboxOn,
avkonIconFile,
EMbmAvkonQgn_prop_checkbox_on,
EMbmAvkonQgn_prop_checkbox_on_mask );
CleanupStack::PushL( icon );
iMarkingIconArray->AppendL( icon );
CleanupStack::Pop( icon );
icon = AknsUtils::CreateGulIconL( skin,
KAknsIIDQgnPropCheckboxOff,
avkonIconFile,
EMbmAvkonQgn_prop_checkbox_off,
EMbmAvkonQgn_prop_checkbox_off_mask );
CleanupStack::PushL( icon );
iMarkingIconArray->AppendL( icon );
CleanupStack::Pop( icon );
}
EXPORT_C CCoeControl *CColumnListBoxData::Control() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
return iExtension->iControl;
}
EXPORT_C void CColumnListBoxData::SetControl(CCoeControl *aControl)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->SetControl( aControl );
}
EXPORT_C MAknsControlContext* CColumnListBoxData::SkinBackgroundContext() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
if (iExtension->iSkinEnabled)
{
return iExtension->iSkinControlContext;
}
return NULL;
}
void CColumnListBoxData::SetSkinBackgroundContext(CAknsListBoxBackgroundControlContext *aContext)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
delete iExtension->iSkinControlContext;
iExtension->iSkinControlContext = aContext;
}
void CColumnListBoxData::CreatePictographInterfaceL()
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
if ( !iExtension->iPictoInterface )
{
iExtension->iPictoInterface = CAknPictographInterface::NewL(
*iExtension->iControl, *iExtension );
}
}
EXPORT_C void CColumnListBoxData::SetSkinHighlightFrame(const TAknsItemID *aFrameId, const TAknsItemID *aFrameCenterId)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
iExtension->iSkinHighlightFrameId = aFrameId;
iExtension->iSkinHighlightFrameCenterId = aFrameCenterId;
}
EXPORT_C void CColumnListBoxData::SetSkinEnabledL(TBool aEnabled)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
CListBoxData::SetSkinEnabledL(aEnabled);
iExtension->iSkinEnabled = aEnabled;
}
EXPORT_C void CColumnListBoxData::SetSkinStyle(const TAknsItemID *aId, const TRect &aTileRect)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
if (iExtension->iSkinControlContext)
{
iExtension->iSkinControlContext->SetTiledBitmap(*aId);
iExtension->iSkinControlContext->SetTiledRect(aTileRect);
}
}
EXPORT_C void CColumnListBoxData::SetListEndSkinStyle(const TAknsItemID *aId, const TRect &aTileRect)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
if (iExtension->iSkinControlContext)
{
iExtension->iSkinControlContext->SetBottomBitmap(*aId);
iExtension->iSkinControlContext->SetBottomRect(aTileRect);
}
}
void CColumnListBoxData::CreateMarqueeControlL()
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if ( !iExtension->iMarquee )
{
iExtension->iMarquee = CAknMarqueeControl::NewL();
}
if ( !iExtension->i2ndLineMarquee )
{
iExtension->i2ndLineMarquee = CAknMarqueeControl::NewL();
}
TCallBack callBack(CColumnListBoxDataExtension::RedrawEvent,
iExtension->iControl);
iExtension->iMarquee->SetRedrawCallBack(callBack);
iExtension->i2ndLineMarquee->SetRedrawCallBack(callBack);
}
void CColumnListBoxData::ResetMarquee()
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if (iExtension->iMarquee)
{
iExtension->iMarquee->Reset();
}
if (iExtension->i2ndLineMarquee)
{
iExtension->i2ndLineMarquee->Reset();
}
}
TInt CColumnListBoxData::CurrentMarqueeItemIndex()
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
return iExtension->iCurrentItem;
}
void CColumnListBoxData::SetCurrentMarqueeItemIndex(TInt aIndex)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->iCurrentItem = aIndex;
}
//
// Enables or disables marquee.
//
EXPORT_C void CColumnListBoxData::EnableMarqueeL(TBool aEnable)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
// 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);
}
EXPORT_C void CColumnListBoxData::SetSeparatorLinePosition(TAknSeparatorLinePosition aPosition)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->iSeparatorLinePosition = aPosition;
}
EXPORT_C TAknSeparatorLinePosition CColumnListBoxData::SeparatorLinePosition() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
return iExtension->iSeparatorLinePosition;
}
EXPORT_C CAknLayoutData *CColumnListBoxData::LayoutData() const
{
return NULL;
}
EXPORT_C TBool CColumnListBoxData::LayoutInit() const
{
return EFalse;
}
EXPORT_C void CColumnListBoxData::SetLayoutInit(TBool /*aValue*/) const
{
}
//
// Class CColumnListBoxData::TColors
//
/**
* Constructs and intialises the data colors to blacks and whites.
*/
EXPORT_C CColumnListBoxData::TColors::TColors()
: iText(KRgbBlack), iBack(KRgbWhite), iHighlightedText(KRgbWhite), iHighlightedBack(KRgbBlack)
{
}
//
// Class CColumnListBoxData
//
EXPORT_C CColumnListBoxData* CColumnListBoxData::NewL()
//
// Public c'tor
//
{
CColumnListBoxData* self=new(ELeave) CColumnListBoxData();
self->ConstructLD();
return(self);
}
EXPORT_C CColumnListBoxData::CColumnListBoxData()
: CListBoxData()
//
// Protected c'tor
//
{
__DECLARE_NAME(_S("CColumnListBoxData"));
}
EXPORT_C CColumnListBoxData::~CColumnListBoxData()
//
// D'tor
//
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
delete iColumnArray;
if (IconArray())
{
IconArray()->ResetAndDestroy();
delete iExtension->iIconArray;
}
delete iExtension;
}
EXPORT_C void CColumnListBoxData::ConstructLD()
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TRAPD( err, DoConstructL( KAknsIIDQsnAnimList ) );
if( err )
{
delete(this);
User::Leave( err );
}
}
EXPORT_C void CColumnListBoxData::ConstructLD(
const TAknsItemID& aAnimationIID )
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TRAPD( err, DoConstructL( aAnimationIID ) );
if( err )
{
delete(this);
User::Leave( err );
}
}
void CColumnListBoxData::DoConstructL( const TAknsItemID& aAnimationIID )
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
iColumnArray = new(ELeave) CArrayFixFlat<SColumn>(KColumnListBoxGranularity);
iExtension = new(ELeave) CColumnListBoxDataExtension;
iExtension->iSkinEnabled = AknsUtils::AvkonSkinEnabled();
SetupSkinContextL();
iExtension->ConstructL( this, aAnimationIID );
CListBoxData::SetSkinBackgroundControlContextL(iExtension->iSkinControlContext);
// preallocate columns so that we dont need to leave on
// SizeChanged().
// AddColumnL(0);
// AddColumnL(1);
// AddColumnL(2);
// AddColumnL(3);
// AddColumnL(4);
}
EXPORT_C TInt CColumnListBoxData::LastColumn() const
//
// The last column defined
//
{
TInt count=iColumnArray->Count();
if (!count)
return(KErrNotFound);
return(At(count-1).iColumn);
}
EXPORT_C TInt CColumnListBoxData::ColumnWidthPixel(TInt aColumn) const
//
// Return the width for a column
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
return(0);
return(At(index).iWidth);
}
EXPORT_C void CColumnListBoxData::SetColumnWidthPixelL(TInt aColumn,TInt aWidth)
//
// Set a columns width
//
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
TInt index;
FindColumnIndexOrAddL(index,aColumn);
At(index).iWidth=aWidth;
if ( iExtension->iUseLayoutData )
{
iExtension->iUseLayoutData = EFalse;
CListBoxView* view = static_cast<CEikListBox*>( iExtension->iControl )->View();
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
MAknListBoxTfxInternal* transApi =
CAknListLoader::TfxApiInternal( view->ItemDrawer()->Gc() );
if ( transApi )
{
transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, TPoint( 0, 0 ) );
transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin, TPoint( 0, 0 ) );
}
#endif
}
}
EXPORT_C TInt CColumnListBoxData::ColumnHorizontalGap(TInt aColumn) const
//
// Return the vertical for a column
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
return(0);
return(At(index).iVerticalCap);
}
EXPORT_C void CColumnListBoxData::SetColumnHorizontalGapL(TInt aColumn,TInt aGap)
//
// Set a columns vertical cap
//
{
TInt index;
FindColumnIndexOrAddL(index,aColumn);
At(index).iVerticalCap=aGap;
}
EXPORT_C TInt
CColumnListBoxData::ColumnTextClipGap(TInt aColumnIndex) const
{
TInt index;
if (!FindColumnIndex(index,aColumnIndex))
return TInt(0);
return(iColumnArray->At(index).iTextClipGap);
}
EXPORT_C void
CColumnListBoxData::SetColumnTextClipGapL(TInt aColumnIndex, TInt aGap)
{
TInt index;
FindColumnIndexOrAddL(index,aColumnIndex);
At(index).iTextClipGap=aGap;
}
EXPORT_C TInt CColumnListBoxData::ColumnBaselinePos(TInt aColumn) const
//
// Return the vertical for a column
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
return(0);
return(At(index).iBaseline);
}
EXPORT_C void CColumnListBoxData::SetColumnBaselinePosL(TInt aColumn,TInt aPos)
//
// Set a columns baseline position
//
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TInt index;
FindColumnIndexOrAddL(index,aColumn);
At(index).iBaseline=aPos;
// can not be nicely supported by new drawing system
// --> revert to Symbian style drawing
if ( iExtension->iUseLayoutData )
{
iExtension->iUseLayoutData = EFalse;
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
CListBoxView* view = static_cast<CEikListBox*>( iExtension->iControl )->View();
MAknListBoxTfxInternal* transApi =
CAknListLoader::TfxApiInternal( view->ItemDrawer()->Gc() );
if ( transApi )
{
transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, TPoint( 0, 0 ) );
transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin, TPoint( 0, 0 ) );
}
#endif
}
}
EXPORT_C TMargins CColumnListBoxData::ColumnMargins(TInt aColumn) const
//
// Return the vertical for a column
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
{
TMargins m = {0,0,0,0};
return m;
}
return(At(index).iMargins);
}
EXPORT_C void CColumnListBoxData::SetColumnMarginsL(TInt aColumn,TMargins aMargins)
//
// Set a columns vertical cap
//
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TInt index;
FindColumnIndexOrAddL(index,aColumn);
At(index).iMargins=aMargins;
// can not be nicely supported by new drawing system
// --> revert to Symbian style drawing
if ( iExtension->iUseLayoutData )
{
iExtension->iUseLayoutData = EFalse;
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
CListBoxView* view = static_cast<CEikListBox*>( iExtension->iControl )->View();
MAknListBoxTfxInternal* transApi =
CAknListLoader::TfxApiInternal( view->ItemDrawer()->Gc() );
if ( transApi )
{
transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, TPoint( 0, 0 ) );
transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin, TPoint( 0, 0 ) );
}
#endif
}
}
EXPORT_C TInt CColumnListBoxData::ColumnX(TInt aColumn) const
{
TInt index;
if (!FindColumnIndex(index,aColumn))
{
return 0;
}
return(At(index).iX);
}
EXPORT_C void CColumnListBoxData::SetColumnXL(TInt aColumn,TInt aX) const
{
TInt index;
MUTABLE_CAST(CColumnListBoxData*,this)->FindColumnIndexOrAddL(index,aColumn);
MUTABLE_CAST(TInt&,At(index).iX)=aX;
}
EXPORT_C TInt CColumnListBoxData::ColumnEndX(TInt aColumn) const
{
TInt index;
if (!FindColumnIndex(index,aColumn))
{
return 0;
}
return(At(index).iEndX);
}
EXPORT_C void CColumnListBoxData::SetColumnEndXL(TInt aColumn,TInt aEndX) const
{
TInt index;
MUTABLE_CAST(CColumnListBoxData*,this)->FindColumnIndexOrAddL(index,aColumn);
MUTABLE_CAST(TInt&,At(index).iEndX)=aEndX;
}
EXPORT_C const CFont* CColumnListBoxData::ColumnFont(TInt aColumn) const
//
// Return the font for a column
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
return(NULL);
return(iColumnArray->At(index).iBaseFont);
}
EXPORT_C void CColumnListBoxData::SetColumnFontL(TInt aColumn,const CFont* aFont)
//
// Set a font for a column
//
{
// This corrects error report KBAA-53GEQ5.
#if NOT_NEEDED_IN_SERIES60
TInt columns=iColumnArray->Count();
#endif
TInt index;
FindColumnIndexOrAddL(index,aColumn);
if (!At(index).iBaseFont)
{
// This corrects error report KBAA-53GEQ5.
#if NOT_NEEDED_IN_SERIES60
TInt actualFontIndex=0;
TRAPD(err, actualFontIndex=AddActualFontL(aFont));
if (err)
{
if (columns!=iColumnArray->Count())
{
iColumnArray->Delete(index);
}
User::Leave(err);
}
At(index).iActualFontIndex=actualFontIndex;
#endif
// TPFIX(moved down) At(index).iBaseFont=aFont;
}
At(index).iBaseFont=aFont;
}
EXPORT_C CGraphicsContext::TTextAlign CColumnListBoxData::ColumnAlignment(TInt aColumn) const
//
// Return a columns alignment
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
return(CGraphicsContext::ELeft);
return(iColumnArray->At(index).iAlign);
}
EXPORT_C void CColumnListBoxData::SetColumnAlignmentL(TInt aColumn,CGraphicsContext::TTextAlign aAlign)
//
// Set a columns alignment
//
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
TInt index;
FindColumnIndexOrAddL(index,aColumn);
At(index).iAlign=aAlign;
iExtension->SetColumnLayoutAlignmentL( aColumn);
}
EXPORT_C CGraphicsContext::TPenStyle CColumnListBoxData::ColumnSeparatorStyle(TInt aColumn) const
//
// Return a columns separator style
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
return(CGraphicsContext::ENullPen);
return(iColumnArray->At(index).iSeparator);
}
EXPORT_C void CColumnListBoxData::SetColumnSeparatorStyleL(TInt aColumn,CGraphicsContext::TPenStyle aSeparator)
//
// Set a columns separator style
//
{
TInt index;
FindColumnIndexOrAddL(index,aColumn);
At(index).iSeparator=aSeparator;
}
EXPORT_C TBool CColumnListBoxData::ColumnIsGraphics(TInt aColumn) const
//
// Return true if the column contains graphics
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
return(EFalse);
return(iColumnArray->At(index).iGraphics);
}
EXPORT_C void CColumnListBoxData::SetGraphicsColumnL(TInt aColumn,TBool aIsGraphics)
//
// Sets whether a column shows graphics
//
{
TInt index;
FindColumnIndexOrAddL(index,aColumn);
At(index).iGraphics=aIsGraphics;
}
EXPORT_C TBool CColumnListBoxData::ColumnIsNumber(TInt aColumn) const
//
// Return true if the column contains graphics
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
return(EFalse);
return(iColumnArray->At(index).iNumberColumn);
}
EXPORT_C void CColumnListBoxData::SetNumberColumnL(TInt aColumn,TBool aIsNumber)
//
// Sets whether a column shows graphics
//
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TInt index;
FindColumnIndexOrAddL(index,aColumn);
At(index).iNumberColumn=aIsNumber;
}
EXPORT_C TBool CColumnListBoxData::ColumnIsOptional(TInt aColumn) const
//
// Return true if the column contains graphics
//
{
TInt index;
if (!FindColumnIndex(index,aColumn))
return(EFalse);
return(iColumnArray->At(index).iOptional);
}
EXPORT_C void CColumnListBoxData::SetOptionalColumnL(TInt aColumn,TBool aIsOptional)
//
// Sets whether a column shows graphics
//
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TInt index;
FindColumnIndexOrAddL(index,aColumn);
At(index).iOptional=aIsOptional;
}
EXPORT_C CArrayPtr<CGulIcon>* CColumnListBoxData::IconArray() const
//
// Return the list of icons
//
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
return iExtension->iIconArray;
}
EXPORT_C void CColumnListBoxData::SetIconArray(CArrayPtr<CGulIcon>* aArray)
//
// Passes ownership of the icon list aArray (assumes any previous list has been deleted by the caller)
//
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
iExtension->iIconArray=aArray;
}
EXPORT_C CFont* CColumnListBoxData::Font(const TListItemProperties& /*aItemProperties*/, TInt aColumn) const
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
return const_cast<CFont*>(this->ColumnFont(aColumn));
#if NOT_NEEDED_IN_SERIES60
TInt index;
if (!FindColumnIndex(index,aColumn))
return(NULL);
TInt actualFontIndex=iColumnArray->At(index).iActualFontIndex;
if (actualFontIndex==KNoActualColumnFont)
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 CColumnListBoxData::DrawHighLight( CWindowGc& aGc, const TRect& aRect, TBool aHighlight, MAknsSkinInstance* aSkin ) const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
// SERIES60 Highlight drawing.
if( aHighlight )
{
// same as CFormattedCellListBoxData::DrawDefaultHighlight
CListBoxView* view = static_cast<CEikListBox*>( iExtension->iControl )->View();
TBool pressedDown = view->ItemDrawer()->Flags() & CListItemDrawer::EPressedDownState;
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
MAknListBoxTfxInternal* transApi = CAknListLoader::TfxApiInternal( &aGc );
if ( transApi )
{
transApi->Invalidate(MAknListBoxTfxInternal::EListHighlight ); // This will remove the old bitmap
transApi->BeginRedraw( MAknListBoxTfxInternal::EListHighlight, aRect );
transApi->StartDrawing( MAknListBoxTfxInternal::EListHighlight );
aGc.SetClippingRect( view->ViewRect() );
}
#endif //RD_UI_TRANSITION_EFFECTS_LIST
// Try drawing the animated highlight
TBool highlightDrawn = EFalse;
if ( iExtension->iAnimation )
{
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi && transApi->VerifyKml() == KErrNone )
{
iExtension->DeleteAnim();
}
else
{
#endif
TAknLayoutRect topLeft;
topLeft.LayoutRect(aRect, SkinLayout::List_highlight_skin_placing__general__Line_2());
TAknLayoutRect bottomRight;
bottomRight.LayoutRect(aRect, SkinLayout::List_highlight_skin_placing__general__Line_5());
TRect outerRect(topLeft.Rect().iTl, bottomRight.Rect().iBr);
aGc.SetPenStyle(CGraphicsContext::ENullPen);
highlightDrawn = iExtension->SyncAndDrawAnim( aGc, outerRect );
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
}
#endif
}
if (!highlightDrawn)
{
// Animated highlight was not available, use normal skinned
// rendering.
MAknsControlContext *cc = AknsDrawUtils::ControlContext( Control() );
if (!cc) cc = SkinBackgroundContext();
if (cc)
{
TAknLayoutRect topLeft;
topLeft.LayoutRect(aRect, SkinLayout::List_highlight_skin_placing__general__Line_2());
TAknLayoutRect bottomRight;
bottomRight.LayoutRect(aRect, SkinLayout::List_highlight_skin_placing__general__Line_5());
TRect outerRect(topLeft.Rect().iTl, bottomRight.Rect().iBr);
TRect innerRect(topLeft.Rect().iBr, bottomRight.Rect().iTl);
aGc.SetPenStyle(CGraphicsContext::ENullPen);
if ( pressedDown )
{
highlightDrawn = iExtension->DrawPressedDownEffectL( aSkin, aGc, outerRect, innerRect );
//view->ItemDrawer()->ClearFlags( CListItemDrawer::EItemPressedDown );
}
else
{
highlightDrawn = AknsDrawUtils::DrawFrame( aSkin,
aGc,
outerRect,
innerRect,
*iExtension->iSkinHighlightFrameId,
*iExtension->iSkinHighlightFrameCenterId );
}
}
}
// Both animated highlight and normal highlight drawing have failed.
if (!highlightDrawn)
{
TAknLayoutRect highlightshadow;
TAknLayoutRect highlight;
highlightshadow.LayoutRect(aRect, AKN_LAYOUT_WINDOW_List_pane_highlight_graphics__various__Line_1(aRect));
highlight.LayoutRect(aRect, AKN_LAYOUT_WINDOW_List_pane_highlight_graphics__various__Line_2(aRect));
highlightshadow.DrawRect(aGc);
highlight.DrawRect(aGc);
}
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi )
{
aGc.CancelClippingRect();
transApi->StopDrawing();
transApi->EndRedraw( MAknListBoxTfxInternal::EListHighlight );
}
#endif // RD_UI_TRANSITION_EFFECTS_LIST
}
}
void CColumnListBoxData::BitBltColored( CWindowGc& aGc,
TBool aHighlight,
const CGulIcon* aIcon,
TInt aSubcell,
TBool aColorIcon,
const TRect& aGraphicRect ) const
{
// see also eikfrlbd.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 CColumnListBoxData::DrawSimple( const TListItemProperties& aItemProperties,
CWindowGc& aGc,
const TDesC* aText,
const TRect& aRect,
TBool aHighlight,
const TColors& aColors ) const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
__ASSERT_DEBUG( iExtension->iControl, Panic( EEikPanicNullPointer ));
CEikListBox* listbox = static_cast<CEikListBox*>( iExtension->iControl );
if ( listbox && !listbox->View()->ViewRect().Intersects( aRect ) )
{
// outside of the clipping rect -> don't process this item
return;
}
TInt lastColumn = Min( LastColumn(), KMaxColumn );
TInt column=0;
TPtrC text;
TPtrC tempText;
TRgb aTextColor = aHighlight ? aColors.iHighlightedText : aColors.iText;
MAknsSkinInstance *skin = AknsUtils::SkinInstance();
MAknsControlContext *cc = AknsDrawUtils::ControlContext( Control() );
if ( !cc )
{
cc = SkinBackgroundContext();
}
TAknTextLineLayout textLines[KMaxColumn];
TBool rectClipped[KMaxColumn];
Mem::FillZ( &rectClipped[0], KMaxColumn * sizeof( TBool ) );
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( &aGc );
#endif // RD_UI_TRANSITION_EFFECTS_LIST
if ( !listbox || !listbox->BackgroundDrawingSuppressed() )
{
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi )
{
transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
}
#endif // RD_UI_TRANSITION_EFFECTS_LIST
aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
aGc.SetPenStyle(CGraphicsContext::ESolidPen);
if ( listbox )
{
AknsDrawUtils::Background( skin, cc, listbox, aGc, aRect );
}
else
{
aGc.Clear(aRect);
}
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi )
{
transApi->StopDrawing();
}
#endif // RD_UI_TRANSITION_EFFECTS_LIST
}
if ( iExtension->iCurrentRow < listbox->BottomItemIndex() )
{
AknListUtils::DrawSeparator( aGc, aRect, aColors.iText, skin );
}
DrawHighLight( aGc, aRect, aHighlight, skin );
TRect itemRect( aRect );
DrawMarkingModeIcons( aItemProperties, aGc, itemRect );
if ( iExtension->iSubCellsMightIntersect )
{
CheckIfSubCellsIntersect( &textLines[0], &rectClipped[0], *aText, itemRect );
}
// The column draw loop
column = 0;
TInt subCellIndex = 0;
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi )
{
transApi->StartDrawing( MAknListBoxTfxInternal::EListItem );
CListBoxView* view = listbox->View();
aGc.SetClippingRect( view->ViewRect() );
}
#endif // RD_UI_TRANSITION_EFFECTS_LIST
for( column = 0; column <= lastColumn; column++ )
{
TextUtils::ColumnText( text, column, aText );
if ( text == KNullDesC ) { continue; }
if ( iExtension->FindSLSubCellIndex( subCellIndex, column )!=0 )
{
continue;
}
CGraphicsContext::TTextAlign align=ColumnAlignment(column);
TBool isLayoutAlignment = iExtension->ColumnLayoutAlignment(column);
if ( iExtension->AtSL(subCellIndex).iSubCellType == CColumnListBoxDataExtension::EEikSLText )
{
aGc.SetBrushStyle(CGraphicsContext::ENullBrush);
TRgb textColor( aTextColor );
if ( aHighlight )
{
textColor = aColors.iHighlightedText;
aGc.SetBrushColor(aColors.iHighlightedBack);
}
if ( AknsUtils::AvkonSkinEnabled() )
{
CListBoxView* view = listbox->View();
TBool useOverrideColor = view->ItemDrawer()->Flags() & CListItemDrawer::EUseOverrideSkinTextColor;
if ( !useOverrideColor )
{
if ( iExtension->iTextColor != NULL )
{
textColor = iExtension->iTextColor;
}
if ( aHighlight && iExtension->iHighlightedTextColor != NULL )
{
textColor = iExtension->iHighlightedTextColor;
}
}
}
const CFont* rowAndColFont=RowAndColumnFont(iExtension->iCurrentRow,column);
const CFont* colFont=Font(aItemProperties, column);
const CFont* tempFont=(colFont) ? colFont : NULL;
const CFont* usedFont=(rowAndColFont) ? rowAndColFont : tempFont;
TAknTextLineLayout textLineLayout = NULL;
if ( rectClipped[column] )
{
textLineLayout = textLines[column];
}
else
{
// check if there are icons affecting this text layout
TInt gSC = iExtension->AtSL(subCellIndex).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(subCellIndex).iTextLayout;
}
}
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( itemRect, textLineLayout, usedFont );
// *2 == leave some room for marquee
const TInt maxlen( KMaxColumnDataLength * 2 );
TBuf<maxlen> convBuf = text.Left(maxlen);
// Note that this potentially modifies the text so its lenght in pixels
// might increase. Therefore, this should always be done before
// wrapping/clipping text. In some cases, WordWrapListItem is called
// before coming here. Is it certain that it is not done for number subcells?
// Do number conversion if required.
if ( ColumnIsNumber( column ) )
{
AknTextUtils::LanguageSpecificNumberConversion( convBuf );
}
// Check whether logical to visual conversion should be done here or not.
TBool bidiConv = ETrue; // TODO
// if (ColumnIsNumber(column))
// {
// AknTextUtils::LanguageSpecificNumberConversion( convBuf );
// }
// marquee & clipping detection
TBool doesNotFit( aHighlight &&
textLayout.Font()->TextWidthInPixels( convBuf ) > textLayout.TextRect().Width() );
// iClippedColumns was cleared in ::Draw() so no need to
// clear anything here
if ( doesNotFit )
{
iExtension->iClippedColumns |= ( 1 << column );
}
TBool marqueeDisabled(EFalse);
if ( listbox != NULL &&
listbox->View() != NULL &&
listbox->View()->ItemDrawer() != NULL)
{
marqueeDisabled = listbox->View()->ItemDrawer()->Flags() & CListItemDrawer::EDisableMarquee;
}
if ( iExtension->IsMarqueeOn() && doesNotFit && !marqueeDisabled )
{
iExtension->iMarquee->UseLogicalToVisualConversion( bidiConv );
if ( iExtension->iMarquee->DrawText( aGc, itemRect, textLineLayout, convBuf, usedFont, textColor ) )
{
// all the loops have been executed
textLayout.DrawText( aGc, convBuf, bidiConv, textColor );
}
}
else
{
if ( iExtension->iMarquee && marqueeDisabled )
{
iExtension->iMarquee->Stop();
}
textLayout.DrawText( aGc, convBuf, bidiConv, textColor );
}
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,
usedFont->AscentInPixels(),
textLayout.Align(), 0 );
}
aGc.SetUnderlineStyle(EUnderlineOff); // disable underline after first text.
}
else if ( iExtension->AtSL(subCellIndex).iSubCellType == CColumnListBoxDataExtension::EEikSLGraphic )
{
TLex lex(text);
TInt index;
__ASSERT_ALWAYS(lex.Val(index)==KErrNone,Panic(EEikPanicColumnListInvalidBitmapIndex));
TBool colorIcon( EFalse );
if ( index == KColorIconFlag )
{
if ( iExtension->iColorBmp && iExtension->iHiliBmp )
{
colorIcon = ETrue;
}
index = KColorIconIdx;
}
if ( !IconArray() )
{
continue;
}
if ( aHighlight && (index > 0xffff) )
{
index = index >> 16; // we have different icon for highlight
}
index = index & 0xffff; // mask off possible highlight icon
__ASSERT_DEBUG((index>=0 && index<IconArray()->Count()),Panic(EEikPanicColumnListInvalidBitmapIndex));
TAknWindowLineLayout graphicLayout = iExtension->AtSL(subCellIndex).iGraphicLayout;
TAknLayoutRect graphicRect;
graphicRect.LayoutRect( itemRect,graphicLayout );
TSize graphicSize( graphicRect.Rect().Size() );
if ( index>=0 && IconArray() )
{
CGulIcon* icon=(*IconArray())[index];
CFbsBitmap* bitmap=icon->Bitmap();
// Sometimes we get fake bitmap...
if ( bitmap )
{
TSize size( bitmap->SizeInPixels() );
if ( size.iWidth != graphicSize.iWidth &&
size.iHeight != graphicSize.iHeight )
{
AknIconUtils::SetSize( bitmap,
graphicSize,
EAspectRatioPreservedAndUnusedSpaceRemoved );
}
BitBltColored( aGc, aHighlight, icon, column, colorIcon, graphicRect.Rect() );
}
}
aGc.SetPenStyle(CGraphicsContext::ESolidPen);
}
}
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi )
{
aGc.CancelClippingRect();
transApi->StopDrawing();
}
#endif //RD_UI_TRANSITION_EFFECTS_LIST
}
EXPORT_C
void CColumnListBoxData::Draw( const TListItemProperties& aItemProperties,
CWindowGc& aGc,
const TDesC* aText,
const TRect& aRect,
TBool aHighlight,
const TColors& aColors ) const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if ( aHighlight )
{
iExtension->iClippedColumns = 0;
}
if ( UsesScalableLayoutData() )
{
DrawSimple( aItemProperties, aGc, aText, aRect, aHighlight, aColors );
return;
}
const CFont* font=ColumnFont(0);
CEikonEnv* eikonEnv=CEikonEnv::Static();
if (font==NULL)
{
font=eikonEnv->NormalFont();
}
TInt lastColumn=LastColumn();
if (lastColumn==KErrNotFound)
{
if ( font )
{
// use draw text so that dont need to change pen color/style
aGc.UseFont( font );
aGc.DrawText(TPtrC(),aRect,0);
aGc.DiscardFont();
}
return;
}
CEikListBox* listbox = static_cast<CEikListBox*>( iExtension->iControl );
TRect itemRect( aRect );
TInt extraVerticalSpace=(aRect.Height()-font->HeightInPixels());
TInt baseLineOffset=extraVerticalSpace/2+font->AscentInPixels();
// SERIES60 Background drawing.
MAknsSkinInstance *skin = AknsUtils::SkinInstance();
MAknsControlContext *cc = AknsDrawUtils::ControlContext( Control() );
if (!cc)
{
cc = SkinBackgroundContext();
}
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
MAknListBoxTfxInternal *transApi = CAknListLoader::TfxApiInternal( &aGc );
#endif // RD_UI_TRANSITION_EFFECTS_LIST
if ( !listbox || !listbox->BackgroundDrawingSuppressed() )
{
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi )
{
transApi->StartDrawing( MAknListBoxTfxInternal::EListView );
}
#endif // RD_UI_TRANSITION_EFFECTS_LIST
aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
aGc.SetPenStyle(CGraphicsContext::ESolidPen);
if ( listbox )
{
AknsDrawUtils::Background( skin, cc, listbox, aGc, aRect );
}
else
{
aGc.Clear(aRect);
}
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi )
{
transApi->StopDrawing();
}
#endif // RD_UI_TRANSITION_EFFECTS_LIST
}
if ( iExtension->iCurrentRow < listbox->BottomItemIndex() )
{
AknListUtils::DrawSeparator( aGc, aRect, aColors.iText, skin );
}
DrawHighLight( aGc, aRect, aHighlight, skin );
DrawMarkingModeIcons( aItemProperties, aGc, itemRect );
TRect textRect( itemRect );
textRect.iBr.iX = itemRect.iTl.iX;
TRect textMRect; // textrect with margins.
TInt column=0;
TPtrC text;
TRgb aTextColor = aHighlight ? aColors.iHighlightedText : aColors.iText;
// Turned the drawing to multipass algorithm, because optionalcolumns drawing will
// be too difficult to do without - and this is cleaner solution.
// pass 1, figures out x-coordinates for columns.
TInt x = itemRect.iTl.iX;
TBool mirror = AknLayoutUtils::LayoutMirrored();
if (mirror)
{
x = itemRect.iBr.iX;
}
TInt maxx = x;
while(column <= lastColumn)
{
// order of instructions is important here, do not change.
if (!ColumnIsOptional(column))
{
TRAP_IGNORE(SetColumnXL(column,maxx));
if (!mirror)
x = maxx + ColumnWidthPixel(column);
else
x = maxx - ColumnWidthPixel(column);
maxx = x;
}
else
{
if (!mirror)
x -= ColumnWidthPixel(column);
else
x += ColumnWidthPixel(column);
TRAP_IGNORE(SetColumnXL(column,x));
}
column++;
}
// pass 2, figures out the end x coordinates
column = 0;
TInt endx;
TInt tmpcolumn;
while(column <= lastColumn)
{
if (!mirror)
endx = ColumnX(column) + ColumnWidthPixel(column);
else
endx = ColumnX(column) - ColumnWidthPixel(column);
if (!ColumnIsOptional(column))
{
tmpcolumn = column+1;
while(ColumnIsOptional(tmpcolumn))
{
TextUtils::ColumnText(text,tmpcolumn,aText);
if (text!=KNullDesC) endx = ColumnX(tmpcolumn);
tmpcolumn++;
}
}
if (!mirror)
{
__ASSERT_ALWAYS(ColumnX(column)<endx,Panic(EEikPanicColumnListLayoutError));
}
else
{
__ASSERT_ALWAYS(ColumnX(column)>endx,Panic(EEikPanicColumnListLayoutError));
}
TRAP_IGNORE(SetColumnEndXL(column,endx));
column++;
}
// pass 3 drawing
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi )
{
transApi->StartDrawing( MAknListBoxTfxInternal::EListItem );
CListBoxView* view = static_cast<CEikListBox*>( iExtension->iControl )->View();
aGc.SetClippingRect( view->ViewRect() );
}
#endif // RD_UI_TRANSITION_EFFECTS_LIST
// The column draw loop
column = 0;
FOREVER
{
if (column > lastColumn) break;
if (!mirror)
{
textRect.iTl.iX = ColumnX(column);
textRect.iBr.iX = ColumnEndX(column);
}
else
{
textRect.iBr.iX = ColumnX(column);
textRect.iTl.iX = ColumnEndX(column);
}
TextUtils::ColumnText(text,column,aText);
TBool exit_condition = textRect.iBr.iX==textRect.iTl.iX;
if (ColumnIsOptional(column) && text == KNullDesC)
{
exit_condition = ETrue;
}
if (!exit_condition)
{
// Margins support.
TMargins m = ColumnMargins(column);
textMRect.SetRect(textRect.iTl+TSize(m.iLeft,m.iTop),textRect.Size()-TSize(m.iRight+m.iLeft,m.iBottom+m.iTop));
// end of margins support.
CGraphicsContext::TTextAlign align=ColumnAlignment(column);
if (!ColumnIsGraphics(column))
{
//if (align == CGraphicsContext::ECenter || align == CGraphicsContext::ERight)
// {
// textMRect.iTl.iX+=1;
// textMRect.iBr.iX+=1;
// }
aGc.SetBrushStyle(CGraphicsContext::ENullBrush);
aGc.SetPenStyle(CGraphicsContext::ESolidPen);
aGc.SetPenColor(aTextColor);
SetUnderlineStyle( aItemProperties, aGc, column );
if (aHighlight)
{
aGc.SetPenColor(aColors.iHighlightedText);
aGc.SetBrushColor(aColors.iHighlightedBack);
}
CListBoxView* view = listbox->View();
TBool useOverrideColor = view->ItemDrawer()->Flags() & CListItemDrawer::EUseOverrideSkinTextColor;
if ( AknsUtils::AvkonSkinEnabled() && !useOverrideColor )
{
if (iExtension->iTextColor != NULL)
{
aGc.SetPenColor(iExtension->iTextColor);
}
if (aHighlight && iExtension->iHighlightedTextColor != NULL)
{
aGc.SetPenColor(iExtension->iHighlightedTextColor);
}
}
const CFont* rowAndColFont=RowAndColumnFont(iExtension->iCurrentRow,column);
const CFont* colFont=Font(aItemProperties, column);
const CFont* tempFont=(colFont) ? colFont : font;
const CFont* usedFont=(rowAndColFont) ? rowAndColFont : tempFont;
aGc.UseFont(usedFont);
// baseline calc needed for each column because of margins.
baseLineOffset = ColumnBaselinePos(column);
if (!baseLineOffset)
{
baseLineOffset = (textMRect.Size().iHeight-usedFont->HeightInPixels())/2 + usedFont->AscentInPixels();
}
baseLineOffset -= m.iTop;
// SERIES60 LAF
TBuf<200+KAknBidiExtraSpacePerLine> clipbuf;
TInt clipgap = ColumnTextClipGap(column);
TBool clipped = AknBidiTextUtils::ConvertToVisualAndClip(
text.Left(200),
clipbuf,
*usedFont,
textMRect.Size().iWidth,
textMRect.Size().iWidth+clipgap);
if (clipped)
{
if (!mirror)
{
textMRect.iBr.iX+=clipgap;
}
else
{
textMRect.iTl.iX-=clipgap;
}
if ( aHighlight )
{
iExtension->iClippedColumns |= ( 1 << column );
}
}
if (ColumnIsNumber(column))
{
AknTextUtils::LanguageSpecificNumberConversion(clipbuf);
}
// end of SERIES60 LAF
CAknMarqueeControl* marquee =
column == 1 || column == 3 ? iExtension->iMarquee :
iExtension->i2ndLineMarquee;
TBool marqueeDisabled =
listbox->View()->ItemDrawer()->Flags() & CListItemDrawer::EDisableMarquee;
if ( iExtension->IsMarqueeOn() && aHighlight && clipped && !marqueeDisabled )
{
// Bidi conversion has already been done.
marquee->UseLogicalToVisualConversion( EFalse );
if ( marquee->DrawText( aGc, textMRect, text, baseLineOffset, align, *usedFont ) )
{
// All the loops have been executed -> the text needs to be truncated.
aGc.DrawText( clipbuf, textMRect, baseLineOffset, align, 0 );
}
}
else
{
if ( marquee && marqueeDisabled )
{
marquee->Stop();
}
aGc.DrawText( clipbuf, textMRect, baseLineOffset, align, 0 );
}
if ( iExtension->iPictoInterface )
{
iExtension->iPictoInterface->Interface()->DrawPictographsInText(
aGc, *usedFont, clipbuf, textMRect, baseLineOffset, align, 0 );
}
aGc.SetUnderlineStyle(EUnderlineOff); // disable underline after first text.
}
else
{
aGc.SetBrushStyle(CGraphicsContext::ENullBrush);
if (aHighlight /*&& (LastColumn()==0) */ )
{
aGc.SetBrushColor(aColors.iHighlightedBack);
}
TLex lex(text);
TInt index;
TInt err = lex.Val(index);
__ASSERT_DEBUG(err==KErrNone,Panic(EEikPanicColumnListInvalidBitmapIndex));
if ( index == KColorIconFlag )
{
index = KColorIconIdx;
}
if ( !err )
{
if ( !IconArray() )
{
++column;
continue;
}
__ASSERT_DEBUG((index>=0 && index<IconArray()->Count()),Panic(EEikPanicColumnListInvalidBitmapIndex));
TRect bmpRect;
bmpRect.iTl=textMRect.iTl;
if (index>=0 && IconArray())
{
CGulIcon* icon=(*IconArray())[index];
if ( iExtension->iSubCellIconSize[column] != TSize(0,0) )
{
TSize wanted( iExtension->iSubCellIconSize[column] );
TSize got( icon->Bitmap()->SizeInPixels() );
// correct w or h is enough
if ( wanted.iWidth != got.iWidth
&& wanted.iHeight != got.iHeight )
{
AknIconUtils::SetSize( icon->Bitmap(),
wanted,
EAspectRatioPreservedAndUnusedSpaceRemoved );
}
}
CFbsBitmap* bitmap=icon->Bitmap();
TSize size(bitmap->SizeInPixels());
// next two lines are SERIES60 additions
if (size.iWidth>textMRect.Size().iWidth) size.iWidth = textMRect.Size().iWidth;
if (size.iHeight>textMRect.Size().iHeight) size.iHeight = textMRect.Size().iHeight;
TPoint bmpPos(textMRect.iTl); // was aRect, I dunno why
bmpPos.iY+=(textMRect.Height()-size.iHeight)>>1; // was aRect too...
switch (align)
{
case ELeft:
break;
case ECenter:
bmpPos.iX+=(textMRect.Width()-size.iWidth)>>1;
break;
case ERight:
bmpPos.iX=textMRect.iBr.iX-size.iWidth;
break;
}
bmpRect.SetRect(bmpPos,size);
TPoint posInBitmap;
posInBitmap += bitmap->SizeInPixels() - textMRect.Size();
posInBitmap.iX >>= 1;
posInBitmap.iY >>= 1;
if (posInBitmap.iX < 0) posInBitmap.iX = 0;
if (posInBitmap.iY < 0) posInBitmap.iY = 0;
TRect rect(posInBitmap,textMRect.Size());
if (icon->Mask())
{
aGc.BitBltMasked( bmpPos, bitmap, rect, icon->Mask(), ETrue );
}
else
{
aGc.BitBlt(bmpPos, bitmap,rect);
}
}
aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
aGc.SetPenStyle(CGraphicsContext::ESolidPen);
}
}
}
++column;
}
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
if ( transApi )
{
aGc.CancelClippingRect();
transApi->StopDrawing();
}
#endif //RD_UI_TRANSITION_EFFECTS_LIST
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::DrawMarkingModeIcons
// -----------------------------------------------------------------------------
//
void CColumnListBoxData::DrawMarkingModeIcons(
const TListItemProperties& aProperties,
CWindowGc& aGc,
TRect& aItemRect ) const
{
CEikListBox* listbox = static_cast<CEikListBox*>( iExtension->iControl );
TRect textRect( aItemRect );
if ( listbox->View() && listbox->View()->ItemDrawer() )
{
if ( listbox->View()->ItemDrawer()->Flags()
& CListItemDrawer::EMarkingModeEnabled &&
!aProperties.IsSelectionHidden() &&
iExtension->iMarkingIconArray &&
#ifdef RD_TOUCH2_MARKING
iExtension->iMarkingIconArray->Count() ==
KMarkingModeIconArraySize )
#else
iExtension->iMarkingIconArray->Count() == 2 )
#endif // RD_TOUCH2_MARKING
{
if ( AknLayoutUtils::LayoutMirrored() )
{
textRect.iBr.iX -=
AknLayoutScalable_Avkon::list_single_graphic_pane_t1(
0 ).LayoutLine().ir;
}
else
{
textRect.iTl.iX +=
AknLayoutScalable_Avkon::list_single_graphic_pane_t1(
0 ).LayoutLine().il;
}
TAknLayoutRect layoutRect;
layoutRect.LayoutRect( aItemRect,
AknLayoutScalable_Avkon::list_single_graphic_pane_g1( 0 ) );
// unchecked icon
CGulIcon* icon = (*iExtension->iMarkingIconArray)[1];
if ( listbox->View()->ItemIsSelected( iExtension->iCurrentRow ) )
{
icon = (*iExtension->iMarkingIconArray)[0];
}
CFbsBitmap* bitmap = icon->Bitmap();
if ( bitmap )
{
TSize size( bitmap->SizeInPixels() ); // set size if not already
TSize targetSize( layoutRect.Rect().Size() );
if ( size.iWidth != targetSize.iWidth &&
size.iHeight != targetSize.iHeight )
{
AknIconUtils::SetSize(
bitmap,
targetSize,
EAspectRatioPreservedAndUnusedSpaceRemoved );
}
aGc.BitBltMasked( layoutRect.Rect().iTl,
bitmap,
TRect( layoutRect.Rect().Size() ),
icon->Mask(),
EFalse );
}
aItemRect = textRect;
}
}
}
void CColumnListBoxData::AddColumnL(TInt aColumn)
//
// Add a column's worth of data
//
{
SColumn column;
column.iColumn=aColumn;
column.iWidth=0;
TMargins m = {0,0,0,0};
column.iMargins=m;
column.iBaseFont=NULL;
column.iActualFontIndex=KNoActualColumnFont;
column.iGraphics=EFalse;
column.iNumberColumn = EFalse;
column.iOptional=EFalse;
column.iBaseline = 0;
column.iAlign=CGraphicsContext::ELeft;
column.iSeparator=CGraphicsContext::ENullPen;
column.iTextClipGap = 0;
TKeyArrayFix key(0,ECmpTInt);
iColumnArray->InsertIsqL(column,key);
}
CColumnListBoxData::SColumn& CColumnListBoxData::At(TInt aArrayIndex)
//
// Return a column of data
//
{
__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iColumnArray->Count(),Panic(EEikPanicOutOfRange));
return(iColumnArray->At(aArrayIndex));
}
const CColumnListBoxData::SColumn& CColumnListBoxData::At(TInt aArrayIndex) const
//
// Return a column of data
//
{
__ASSERT_DEBUG(aArrayIndex>=0 && aArrayIndex<iColumnArray->Count(),Panic(EEikPanicOutOfRange));
return(iColumnArray->At(aArrayIndex));
}
TBool CColumnListBoxData::FindColumnIndex(TInt& aArrayIndex,TInt aColumn) const
//
// Find a column if it has been set
//
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if (aColumn<0 || iColumnArray->Count()==0)
return EFalse;
TKeyArrayFix key(0,ECmpTInt);
SColumn column;
column.iColumn=aColumn;
// Returns zero if key was found, otherwise non-zero
TInt ret = iColumnArray->FindIsq(column,key,aArrayIndex);
return (ret ? EFalse: ETrue);
}
void CColumnListBoxData::FindColumnIndexOrAddL(TInt& aArrayIndex,TInt aColumn)
//
// Find a column or add it
//
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if (!FindColumnIndex(aArrayIndex,aColumn))
{
AddColumnL(aColumn);
FindColumnIndex(aArrayIndex,aColumn);
}
}
TInt CColumnListBoxData::AddActualFontL(const CFont* aBaseFont)
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if (!iNormalFont.iFonts)
{
iNormalFont.iFonts=new (ELeave) CArrayPtrFlat<CFont> (1);
iBoldFont.iFonts=new (ELeave) CArrayPtrFlat<CFont> (1);
iItalicFont.iFonts=new (ELeave) CArrayPtrFlat<CFont> (1);
iBoldItalicFont.iFonts=new (ELeave) CArrayPtrFlat<CFont> (1);
}
// Reserves extra space for each font array.
TInt fontCount=iNormalFont.iFonts->Count()+1;
iNormalFont.iFonts->SetReserveL(fontCount);
iBoldFont.iFonts->SetReserveL(fontCount);
iItalicFont.iFonts->SetReserveL(fontCount);
iBoldItalicFont.iFonts->SetReserveL(fontCount);
// Add Fonts.
TFontStyle style=aBaseFont->FontSpecInTwips().iFontStyle;
ConstructFontL(aBaseFont, style, iNormalFont);
ConstructFontL(aBaseFont, style, iBoldFont);
ConstructFontL(aBaseFont, style, iItalicFont);
ConstructFontL(aBaseFont, style, iBoldItalicFont);
return fontCount-1;
}
EXPORT_C TBool CColumnListBoxData::MakeColumnRect( TInt aColumn, TRect& aRect )
// Returns given column rect
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TInt lastColumn = LastColumn();
if ( ( aColumn < 0 ) || ( aColumn > lastColumn ) ) return EFalse;
TRect colRect(aRect); // we need to save original item rect
for ( TInt column=0; column<lastColumn; column++ )
// loop throuhg columns except last one (scroll bar eats small rect from it)
{
TInt colWidth = ColumnWidthPixel( column );
colRect.iBr.iX = colRect.iTl.iX + colWidth; // set column rect width
if ( column == aColumn ) break; // if the column, quit
aRect.iTl.iX += colWidth; // shrink origial rect by column with
colRect = aRect; // set colRect for the LAST column
}
aRect = colRect;
return ETrue;
}
EXPORT_C void CColumnListBoxData::SetColumnFontForRowL(TInt aRow,
TInt aColumn,
const CFont* aFont)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TInt index = 0;
iExtension->FindRowAndColumnIndexOrAddL(index,aRow,aColumn);
iExtension->At(index).iFont=aFont;
}
EXPORT_C const CFont*
CColumnListBoxData::RowAndColumnFont(TInt aRow,TInt aColumn) const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
TInt index = 0;
if (iExtension->FindRowAndColumnIndex(index,aRow,aColumn)!=0)
return 0;
return(iExtension->At(index).iFont);
}
void CColumnListBoxData::SetCurrentItemIndex(TInt aIndex)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if( iExtension->iCurrentRow != aIndex )
{
iExtension->iAnimFlags.Set( CColumnListBoxDataExtension::EFlagUpdateBg );
}
iExtension->iCurrentRow = aIndex;
}
// ---------------------------------------------------------------------------
// Wraps the text drawing functinality with & without marquee into one
// function, so that inherited classes can modify their own drawing
// behaviour more easily.
// ---------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::DrawText(
CWindowGc& aGc,
const TRect& aTextRect,
const TDesC& aText,
const TDesC& aClippedText,
const TInt aBaselineOffset,
const CGraphicsContext::TTextAlign aAlign,
const CFont& aFont,
const TBool aHighlight,
const TBool aIsTextClipped ) const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TBool marqueeDisabled =
static_cast<CEikListBox*>(
Control() )->View()->ItemDrawer()->Flags() & CListItemDrawer::EDisableMarquee;
if ( iExtension->IsMarqueeOn() && aHighlight && aIsTextClipped && !marqueeDisabled )
{
if ( iExtension->iMarquee->DrawText( aGc, aTextRect, aText, aBaselineOffset, aAlign, aFont ) )
{
// All the loops have been executed -> the text needs to be truncated.
aGc.DrawText( aClippedText, aTextRect, aBaselineOffset, aAlign, 0 );
}
}
else
{
if ( iExtension->iMarquee && marqueeDisabled )
{
iExtension->iMarquee->Stop();
}
aGc.DrawText( aClippedText, aTextRect, aBaselineOffset, aAlign, 0 );
}
}
EXPORT_C void CColumnListBoxData::SetMarqueeParams(const TInt aLoops, const TInt aScrollAmount, const TInt aScrollDelay)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if ( iExtension->iMarquee )
{
iExtension->iMarquee->SetLoops( aLoops );
iExtension->iMarquee->SetSpeedInPixels( aScrollAmount );
iExtension->iMarquee->SetDelay( aScrollDelay );
}
if ( iExtension->i2ndLineMarquee )
{
iExtension->i2ndLineMarquee->SetLoops( aLoops );
iExtension->i2ndLineMarquee->SetSpeedInPixels( aScrollAmount );
iExtension->i2ndLineMarquee->SetDelay( aScrollDelay );
}
}
EXPORT_C void CColumnListBoxData::SetMarqueeParams(const TInt aLoops, const TInt aScrollAmount,
const TInt aScrollDelay, const TInt aInterval)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if ( iExtension->iMarquee )
{
iExtension->iMarquee->SetInterval( aInterval );
iExtension->i2ndLineMarquee->SetInterval( aInterval );
SetMarqueeParams( aLoops, aScrollAmount, aScrollDelay );
}
}
EXPORT_C
void CColumnListBoxData::SetSubCellIconSize(TInt aIndex, TSize aSize)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if ( aIndex < 6 && aIndex >= 0 )
{
iExtension->iSubCellIconSize[aIndex] = aSize;
}
}
TSize CColumnListBoxData::GetSubCellIconSize(TInt aIndex)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
if ( aIndex < 6 && aIndex >= 0 )
{
return iExtension->iSubCellIconSize[aIndex];
}
return TSize(0,0);
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::HighlightAnim
// -----------------------------------------------------------------------------
//
EXPORT_C const CAknsEffectAnim* CColumnListBoxData::HighlightAnim() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
return iExtension->iAnimation;
}
// -----------------------------------------------------------------------------
// AboutToDrawHighlightAnim
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::AboutToDrawHighlightAnim() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
if( !iExtension->iAnimation || !iExtension->iControl )
{
return;
}
CEikListBox* list = static_cast<CEikListBox*>( iExtension->iControl );
CListBoxView* view = list->View();
if( !view )
{
return;
}
if( view->CurrentItemIndex() != iExtension->iCurrentRow )
{
iExtension->iAnimFlags.Set( CColumnListBoxDataExtension::EFlagUpdateBg );
iExtension->iCurrentRow = view->CurrentItemIndex();
}
iExtension->SyncAnim( iExtension->iAnimSize );
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::SetHighlightAnimBackgroundDrawer
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::SetHighlightAnimBackgroundDrawer(
MColumnListBoxAnimBackgroundDrawer* aDrawer )
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
iExtension->iHighlightBgDrawer = aDrawer;
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::SetItemCellSize
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::SetItemCellSize( const TSize& aSizeInPixels )
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if( iExtension->iAnimSize != aSizeInPixels )
{
iExtension->Play();
}
iExtension->iAnimSize = aSizeInPixels;
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::HasHighlightAnim
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CColumnListBoxData::HasHighlightAnim() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
if( !iExtension->iAnimation )
return EFalse;
return ETrue;
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::DrawHighlightAnim
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CColumnListBoxData::DrawHighlightAnim(
CBitmapContext& aGc, const TRect& aRect ) const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
if( !iExtension->iAnimation )
return EFalse;
return iExtension->SyncAndDrawAnim( aGc, aRect );
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::FocusGained
// -----------------------------------------------------------------------------
//
void CColumnListBoxData::FocusGained()
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->FocusGained();
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::FocusLost
// -----------------------------------------------------------------------------
//
void CColumnListBoxData::FocusLost()
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->FocusLost();
}
void CColumnListBoxData::HandleResourceChange( TInt aType )
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s] aType = %d", "CColumnListBoxData", __FUNCTION__, aType );
// Animation is skin dependent, whenever skin changes animation changes
// too.
if( KAknsMessageSkinChange == aType )
{
TRAP_IGNORE( iExtension->SkinChangedL() );
}
else if(aType == KEikDynamicLayoutVariantSwitch)
{
// What is under highlight may have changed -> we need to update
// highlight background to animation.
iExtension->iAnimFlags.Set( CColumnListBoxDataExtension::EFlagUpdateBg );
}
else if( ( aType == KEikMessageUnfadeWindows ) ||
( aType == KEikMessageFadeAllWindows ) )
{
if( iExtension->iMarquee )
{
iExtension->iMarquee->HandleResourceChange( aType );
}
if( iExtension->i2ndLineMarquee )
{
iExtension->i2ndLineMarquee->HandleResourceChange( aType );
}
}
}
void CColumnListBoxData::SetupSkinContextL()
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ));
TRect mainPane;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPane );
TRect mainPaneRect( mainPane.Size() );
if ( !iExtension->iSkinControlContext )
{
iExtension->iSkinControlContext = CAknsListBoxBackgroundControlContext::NewL(
KAknsIIDQsnBgAreaMainListGene,
mainPaneRect,
EFalse,
KAknsIIDQsnBgColumnA,
mainPaneRect );
iExtension->iSkinHighlightFrameId = &KAknsIIDQsnFrList;
iExtension->iSkinHighlightFrameCenterId = &KAknsIIDQsnFrListCenter;
}
else
{
iExtension->iSkinControlContext->SetRect( mainPaneRect );
}
}
void CColumnListBoxData::SetESSTextColor(TRgb aTextColor)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->iTextColor = aTextColor;
}
void CColumnListBoxData::SetESSHighlightedTextColor(TRgb aHighlightedTextColor)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->iHighlightedTextColor = aHighlightedTextColor;
}
EXPORT_C void CColumnListBoxData::SetColumnUnderlined( TBitFlags32 aUnderlinedColumns )
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->iUnderlineFlagSet = ETrue;
iExtension->iUnderlineFlags = aUnderlinedColumns;
}
void CColumnListBoxData::SetUnderlineStyle( TListItemProperties aProperties,
CWindowGc& aGc,
TInt aColumn ) const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
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( aColumn ) )
{
aGc.SetUnderlineStyle( EUnderlineOn );
}
else
{
aGc.SetUnderlineStyle( EUnderlineOff );
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::ResetSLSubCellArray
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::ResetSLSubCellArray()
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->iMarginRect = TRect::EUninitialized;
if ( iExtension->iUseLayoutData )
{
iExtension->iUseLayoutData = EFalse;
#ifdef RD_UI_TRANSITION_EFFECTS_LIST
CListBoxView* view = static_cast<CEikListBox*>( iExtension->iControl )->View();
MAknListBoxTfxInternal* transApi =
CAknListLoader::TfxApiInternal( view->ItemDrawer()->Gc() );
if ( transApi )
{
transApi->SetPosition( MAknListBoxTfxInternal::EListTLMargin, TPoint( 0, 0 ) );
transApi->SetPosition( MAknListBoxTfxInternal::EListBRMargin, TPoint( 0, 0 ) );
}
#endif
}
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() );
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::SetGraphicSubCellL
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::SetGraphicSubCellL(TInt aSubCell,
const TAknWindowLineLayout &aGraphicLayout)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TInt index = 0;
iExtension->FindSLSubCellIndexOrAddL(index,aSubCell);
iExtension->AtSL(index).iTextLayout=NULL;
iExtension->AtSL(index).iGraphicLayout=aGraphicLayout;
iExtension->AtSL(index).iSubCellType=CColumnListBoxDataExtension::EEikSLGraphic;
// needed for compatibility
CEikColumnListBox* list = static_cast<CEikColumnListBox*>( iExtension->iControl );
TAknLayoutRect layoutRect;
layoutRect.LayoutRect( list->View()->ItemDrawer()->ItemCellSize(), aGraphicLayout );
TRect rect( layoutRect.Rect() );
SetSubCellIconSize( aSubCell, rect.Size() );
SetColumnWidthPixelL( aSubCell, rect.Width() );
SetGraphicsColumnL( aSubCell, ETrue );
SetColumnXL( aSubCell, rect.iTl.iX );
SetColumnEndXL( aSubCell, rect.iBr.iX );
iExtension->iUseLayoutData=ETrue; // might go to own method...
if ( iExtension->iMarginRect == TRect::EUninitialized )
{
iExtension->iMarginRect = rect;
}
else
{
iExtension->iMarginRect.BoundingRect( 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
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::SetTextSubCellL
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::SetTextSubCellL(TInt aSubCell,
const TAknTextLineLayout &aTextLayout)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TInt index = 0;
iExtension->FindSLSubCellIndexOrAddL(index,aSubCell);
iExtension->AtSL(index).iTextLayout=aTextLayout;
iExtension->AtSL(index).iGraphicLayout=NULL;
iExtension->AtSL(index).iSubCellType=CColumnListBoxDataExtension::EEikSLText;
// needed for compatibility
CEikColumnListBox* list = static_cast<CEikColumnListBox*>( iExtension->iControl );
TAknLayoutText textLayout;
textLayout.LayoutText( list->View()->ItemDrawer()->ItemCellSize(), aTextLayout );
TRect rect( textLayout.TextRect() );
SetColumnWidthPixelL( aSubCell, rect.Width() );
SetColumnFontL( aSubCell, textLayout.Font() );
SetColumnXL( aSubCell, rect.iTl.iX );
SetColumnEndXL( aSubCell, rect.iBr.iX );
SetColumnBaselinePosL( aSubCell, aTextLayout.iB );
iExtension->iUseLayoutData=ETrue; // might go to own method...
if ( iExtension->iMarginRect == TRect::EUninitialized )
{
iExtension->iMarginRect = rect;
}
else
{
iExtension->iMarginRect.BoundingRect( 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
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::SetConditionalSubCellL
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::SetConditionalSubCellL(TInt aSubCell,
const TAknTextLineLayout &aTextLayout,
TInt aAffectedSubCell)
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
// 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
SetOptionalColumnL( aSubCell, ETrue );
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!=CColumnListBoxDataExtension::EEikSLGraphic) 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==CColumnListBoxDataExtension::EEikSLGraphic) 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();
CEikColumnListBox* list = static_cast<CEikColumnListBox*>( iExtension->iControl );
TAknLayoutText textLayout;
textLayout.LayoutText( list->View()->ItemDrawer()->ItemCellSize(), aTextLayout );
if ( iExtension->iMarginRect == TRect::EUninitialized )
{
iExtension->iMarginRect = textLayout.TextRect();
}
else
{
iExtension->iMarginRect.BoundingRect( textLayout.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
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::SetStretchableGraphicSubCellL
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::SetStretchableGraphicSubCellL(
TInt aSubCell,
const TAknWindowComponentLayout& aNormalLayout,
const TAknWindowComponentLayout& aStretchedLayout )
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if ( Layout_Meta_Data::IsLandscapeOrientation() &&
Layout_Meta_Data::IsListStretchingEnabled() &&
StretchingEnabled() )
{
SetGraphicSubCellL( aSubCell, aStretchedLayout.LayoutLine() );
}
else
{
SetGraphicSubCellL( aSubCell, aNormalLayout.LayoutLine() );
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::SetStretchableTextSubCellL
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::SetStretchableTextSubCellL(
TInt aSubCell,
const TAknTextComponentLayout& aNormalLayout,
const TAknTextComponentLayout& aStretchedLayout )
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if ( Layout_Meta_Data::IsLandscapeOrientation() &&
Layout_Meta_Data::IsListStretchingEnabled() &&
StretchingEnabled() )
{
SetTextSubCellL( aSubCell, aStretchedLayout.LayoutLine() );
}
else
{
SetTextSubCellL( aSubCell, aNormalLayout.LayoutLine() );
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::SetStretchableConditionalSubCellL
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::SetStretchableConditionalSubCellL(
TInt aSubCell,
const TAknTextComponentLayout& aNormalLayout,
const TAknTextComponentLayout& aStretchedLayout,
TInt aNormalSubCell,
TInt aStretchedSubCell )
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
if ( Layout_Meta_Data::IsLandscapeOrientation() &&
Layout_Meta_Data::IsListStretchingEnabled() &&
StretchingEnabled() )
{
SetConditionalSubCellL( aSubCell, aStretchedLayout.LayoutLine(), aStretchedSubCell );
}
else
{
SetConditionalSubCellL( aSubCell, aNormalLayout.LayoutLine(), aNormalSubCell );
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::UsesScalableLayoutData
// -----------------------------------------------------------------------------
//
TBool CColumnListBoxData::UsesScalableLayoutData() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
return iExtension->iUseLayoutData;
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::EnableStretching
// -----------------------------------------------------------------------------
//
void CColumnListBoxData::EnableStretching( const TBool aEnabled )
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->iStretchingEnabled = aEnabled;
}
#ifdef RD_LIST_STRETCH
// -----------------------------------------------------------------------------
// CColumnListBoxData::StretchingEnabled
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CColumnListBoxData::StretchingEnabled() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
return iExtension->iStretchingEnabled;
}
#else
// -----------------------------------------------------------------------------
// CColumnListBoxData::StretchingEnabled
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CColumnListBoxData::StretchingEnabled() const
{
return EFalse;
}
#endif // RD_LIST_STRETCH
// -----------------------------------------------------------------------------
// CColumnListBoxData::CheckIfSubCellsIntersect
// -----------------------------------------------------------------------------
//
void CColumnListBoxData::CheckIfSubCellsIntersect(
TAknTextLineLayout* aLayouts,
TBool* aResults,
const TDesC& aText,
const TRect& aItemRect ) const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxData", __FUNCTION__, __LINE__ );
TInt column = 0;
TInt column2;
TInt subCellIndex;
TInt subCellIndex2;
TInt lastColumn = Min( LastColumn(), KMaxColumn );
TPtrC text;
TBool isEmpty[KMaxColumn];
// cache the empty text states
while ( ETrue )
{
if ( column > lastColumn )
{
break;
}
TextUtils::ColumnText( text, column, &aText );
if ( text == KNullDesC || ColumnIsOptional( column ) )
{
isEmpty[column] = ETrue;
}
else
{
isEmpty[column] = EFalse;
}
++column;
}
column = 0;
while ( ETrue )
{
if ( column > lastColumn )
{
break;
}
if ( iExtension->FindSLSubCellIndex( subCellIndex, column ) != 0 )
{
break;
}
if ( isEmpty[column] )
{
++column;
continue;
}
TRect bRect( ColumnX( column ), 0, ColumnEndX( column ), 10 );
for ( column2 = column + 1; column2 <= lastColumn; column2++ )
{
if ( isEmpty[column2] )
{
continue;
}
if ( iExtension->FindSLSubCellIndex( subCellIndex2, column2 ) != 0 )
{
break;
}
TRect bRect2( ColumnX( column2 ), 0, ColumnEndX( column2 ), 10 );
if ( bRect.Intersects( bRect2 ) )
{
aResults[column] = ETrue;
if ( !AknLayoutUtils::LayoutMirrored() )
{
bRect.iBr.iX = bRect2.iTl.iX;
}
else
{
bRect.iTl.iX = bRect2.iBr.iX;
}
}
}
if ( aResults[column] )
{
if ( iExtension->AtSL( subCellIndex ).iSubCellType == CColumnListBoxDataExtension::EEikSLText )
{
TAknTextLineLayout textLine = iExtension->AtSL( subCellIndex ).iTextLayout;
textLine.iW = bRect.Width();
if ( !AknLayoutUtils::LayoutMirrored() )
{
textLine.ir = aItemRect.iBr.iX - bRect.iBr.iX;
}
else
{
textLine.il = bRect.iTl.iX - aItemRect.iTl.iX;
}
aLayouts[column] = textLine;
}
}
++column;
}
}
// -----------------------------------------------------------------------------
// CColumnListBoxData::SubCellsMightIntersect
// -----------------------------------------------------------------------------
//
EXPORT_C void CColumnListBoxData::SubCellsMightIntersect( const TBool aMightIntersect )
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
iExtension->iSubCellsMightIntersect = aMightIntersect;
}
void CColumnListBoxDataExtension::CreateColorBitmapsL()
{
_AKNTRACE( "[%s][%s][%d].", "CColumnListBoxDataExtension", __FUNCTION__, __LINE__ );
/* size calculation relies on fact, that currently all additional
* icons in column lists are same size. Size could be calculated
* from sizes availble in setconditionalsubcelll(), but that would
* be too unreliable. And there is no way to calculate size of
* icons created by symbian's old api.
*/
TRect mainPane;
AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPane );
TAknLayoutRect r;
r.LayoutRect( mainPane, AknLayoutScalable_Avkon::listscroll_gen_pane(0) );
r.LayoutRect( r.Rect(), AknLayoutScalable_Avkon::list_gen_pane(0) );
r.LayoutRect( r.Rect(), AknLayoutScalable_Avkon::list_single_pane(0) );
r.LayoutRect( r.Rect(), AknLayoutScalable_Avkon::list_single_pane_g1(0) );
TSize aSize = r.Rect().Size();
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 );
}
EXPORT_C TUint32 CColumnListBoxData::CurrentItemTextWasClipped() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
return iExtension->iClippedColumns;
}
TBool CColumnListBoxData::KineticScrollingEnabled() const
{
__ASSERT_DEBUG( iExtension, Panic( EEikPanicNullPointer ) );
return iExtension->iKineticScrolling;
}
// End of File