Example applications for various Homescreen APIs.
/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies)..
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
* Implementation of the widget listbox for WidgetManager
*
*/
// INCLUDE FILES
#include <coemain.h>
#include <AknsDrawUtils.h>
#include <AknsFrameBackgroundControlContext.h>
#include <AknsListBoxBackgroundControlContext.h>
#include <aknlayout.cdl.h>
#include <layoutmetadata.cdl.h>
#include <aknlayoutscalable_avkon.cdl.h>
#include <aknlayoutscalable_apps.cdl.h>
#include <AknLayout.lag>
#include <AknIconArray.h>
#include <gulicon.h>
#include <widgetmanagerview.rsg>
#include <widgetmanager.mbg>
#include "wmcommon.h"
#include "wmplugin.h"
#include "wmresourceloader.h"
#include "wmlistbox.h"
#include "wmwidgetdata.h"
#include "wmwidgetorderdata.h"
// CONSTANTS
// MEMBER FUNCTIONS
// ---------------------------------------------------------
// CWmListItemDrawer::NewL
// ---------------------------------------------------------
//
CWmListItemDrawer* CWmListItemDrawer::NewL(
CWmPlugin& aWmPlugin,
MTextListBoxModel* aTextListBoxModel,
const CFont* aFont,
CFormattedCellListBoxData* aFormattedCellData,
CWmListBox* aListBox )
{
CWmListItemDrawer* self = new ( ELeave ) CWmListItemDrawer(
aWmPlugin,
aTextListBoxModel,
aFont,
aFormattedCellData,
aListBox );
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
// ---------------------------------------------------------
// CWmListItemDrawer::CWmListItemDrawer
// ---------------------------------------------------------
//
CWmListItemDrawer::CWmListItemDrawer(
CWmPlugin& aWmPlugin,
MTextListBoxModel* aTextListBoxModel,
const CFont* aFont,
CFormattedCellListBoxData* aFormattedCellData,
CWmListBox* aListBox )
: CFormattedCellListBoxItemDrawer( aTextListBoxModel,aFont,aFormattedCellData ),
iWmPlugin( aWmPlugin )
{
iCellData = aFormattedCellData;
iListBox = aListBox;
}
// ---------------------------------------------------------
// CWmListItemDrawer::ConstructL
// ---------------------------------------------------------
//
void CWmListItemDrawer::ConstructL()
{
SetSkinEnabledL( ETrue );
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
AknsUtils::CreateIconL(
skin,
KAknsIIDQgnMenuHswidget,
iDefaultLogoImage,
iDefaultLogoImageMask,
iWmPlugin.ResourceLoader().IconFilePath(),
EMbmWidgetmanagerQgn_menu_hswidget,
EMbmWidgetmanagerQgn_menu_hswidget_mask
);
// This is temporary fix for ou1cimx1#228810
// Can be removed when avkon provides real fix for this error.
// Currently forever loop in CFormattedCellListBoxData::DrawFormattedSimple
// never exits if there is no iconarray and name contains tab+digit which
// confuses listbox e.g. considering name as icon index
CArrayPtr<CGulIcon>* dummyArray = new( ELeave ) CAknIconArray(2);
CleanupStack::PushL(dummyArray);
CFbsBitmap* dummyBmp = new(ELeave) CFbsBitmap;
CleanupStack::PushL( dummyBmp );
User::LeaveIfError( dummyBmp->Create( TSize(0,0), EColor256 ) );
CGulIcon* dummyIcon = CGulIcon::NewL( dummyBmp );
CleanupStack::Pop( dummyBmp ); //ownership transfered
CleanupStack::PushL( dummyIcon );
CFbsBitmap* dummyBmp2 = new(ELeave) CFbsBitmap;
CleanupStack::PushL( dummyBmp2 );
User::LeaveIfError( dummyBmp2->Create( TSize(0,0), EColor256 ) );
CGulIcon* dummyIcon2 = CGulIcon::NewL( dummyBmp2 );
CleanupStack::Pop( dummyBmp2 ); //ownership transfered
CleanupStack::PushL( dummyIcon2 );
dummyArray->AppendL(dummyIcon);
dummyArray->AppendL(dummyIcon2);
ColumnData()->SetIconArray(dummyArray);
CleanupStack::Pop( dummyIcon2 );
CleanupStack::Pop( dummyIcon );
CleanupStack::Pop( dummyArray );
}
// ---------------------------------------------------------
// CWmListItemDrawer::~CWmListItemDrawer
// ---------------------------------------------------------
//
CWmListItemDrawer::~CWmListItemDrawer()
{
iCellData = NULL;
iListBox = NULL;
// dispose icons
delete iDefaultLogoImage;
delete iDefaultLogoImageMask;
}
// ---------------------------------------------------------
// CWmListItemDrawer::UpdateItemHeight
// ---------------------------------------------------------
//
void CWmListItemDrawer::UpdateItemHeight()
{
// sets item height according to layout
TAknWindowLineLayout listPane = AknLayoutScalable_Apps
::list_wgtman_pane().LayoutLine();
TAknLayoutRect listPaneRect;
listPaneRect.LayoutRect( iListBox->Rect(), listPane );
TAknWindowLineLayout listRowPane = AknLayoutScalable_Apps
::listrow_wgtman_pane().LayoutLine();
TAknLayoutRect listRowPaneRect;
listRowPaneRect.LayoutRect( listPaneRect.Rect(), listRowPane );
TRect itemRect = listRowPaneRect.Rect();
TRAP_IGNORE( iListBox->SetItemHeightL( itemRect.Height() ); );
iListBox->View()->ItemDrawer()->SetItemCellSize( itemRect.Size() );
// update view rect according to layout ( ou1cimx1#402776 )
iListBox->View()->SetViewRect( listPaneRect.Rect() );
}
// ---------------------------------------------------------
// CWmListItemDrawer::DrawItem
// ---------------------------------------------------------
//
void CWmListItemDrawer::DrawItem( TInt aItemIndex, TPoint aItemRectPos,
TBool /*aItemIsSelected*/, TBool aItemIsCurrent,
TBool /*aViewIsEmphasized*/, TBool aViewIsDimmed ) const
{
TSize cellSize = ItemCellSize();
CWmWidgetData& wData = iListBox->WidgetData( aItemIndex );
// Get graphics context which is used for drawing.
CWindowGc& gc = *Gc();
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
TBool highlightEnabled = !( iListBox->ItemDrawer()->Flags() &
CListItemDrawer::ESingleClickDisabledHighlight );
TBool listFocused = ((iListBox->IsFocused() && !aViewIsDimmed) ? ETrue : EFalse);
TRect itemRect = TRect( aItemRectPos, cellSize );
CFormattedCellListBoxItemDrawer::DrawEmptyItem(
aItemIndex, aItemRectPos, aViewIsDimmed );
if ( aItemIsCurrent && listFocused && highlightEnabled )
{
TRect innerRect( itemRect );
const TInt highlightOffset = 5;
innerRect.Shrink( highlightOffset, highlightOffset );
AknsDrawUtils::DrawFrame( skin,
gc,
itemRect,
innerRect,
KAknsIIDQsnFrList,
KAknsIIDQsnFrListCenter );
}
// DRAW LOGO
CFbsBitmap* bitmap = const_cast<CFbsBitmap*>(wData.LogoImage());
CFbsBitmap* mask = const_cast<CFbsBitmap*>(wData.LogoImageMask());
TAknLayoutRect logoLayout;
logoLayout.LayoutRect( itemRect,
AknLayoutScalable_Apps::listrow_wgtman_pane_g1().LayoutLine() );
if ( ( !bitmap || !mask ) && iDefaultLogoImage && iDefaultLogoImageMask )
{
// real logo missing use default
TSize size = logoLayout.Rect().Size();
if ( iDefaultLogoImage->SizeInPixels() != size )
{
// Resize default icons only when they are really needed
AknIconUtils::SetSize(
iDefaultLogoImage, size, EAspectRatioPreserved );
AknIconUtils::SetSize(
iDefaultLogoImageMask, size, EAspectRatioPreserved );
}
gc.DrawBitmapMasked( logoLayout.Rect(),
iDefaultLogoImage,
TRect(TPoint(0, 0), iDefaultLogoImage->SizeInPixels()),
iDefaultLogoImageMask,
EFalse );
}
else if( bitmap && mask )
{
gc.DrawBitmapMasked( logoLayout.Rect(),
bitmap,
TRect(TPoint(0, 0), bitmap->SizeInPixels()),
mask,
ETrue );
}
// DRAW NAME
TRgb textColor;
TAknsQsnTextColorsIndex index =
( aItemIsCurrent && listFocused && highlightEnabled )?
EAknsCIQsnTextColorsCG10 : EAknsCIQsnTextColorsCG6;
AknsUtils::GetCachedColor(
skin, textColor, KAknsIIDQsnTextColors, index );
TAknTextLineLayout titleTextLayout;
if ( !wData.IsUninstalling() )
{
// centered 1 row layout
titleTextLayout =
AknLayoutScalable_Apps::listrow_wgtman_pane_t1(1).LayoutLine();
}
else
{
// 2 row layout for uninstalling
titleTextLayout =
AknLayoutScalable_Apps::listrow_wgtman_pane_t1(0).LayoutLine();
}
TAknLayoutText textLayoutTitle;
textLayoutTitle.LayoutText( itemRect, titleTextLayout );
textLayoutTitle.DrawText( gc, wData.Name(), ETrue, textColor );
if ( wData.IsUninstalling() )
{
// DRAW UNINSTALL ANIMATION
TAknLayoutRect animationLayout;
animationLayout.LayoutRect( itemRect,
AknLayoutScalable_Apps::wait_bar_pane_cp09().LayoutLine() );
TSize size = animationLayout.Rect().Size();
CFbsBitmap* animBitmap =
const_cast<CFbsBitmap*>(wData.AnimationBitmap( size ));
CFbsBitmap* animMask =
const_cast<CFbsBitmap*>(wData.AnimationMask( size ));
if ( animBitmap && animMask )
{
animationLayout.DrawImage( gc, animBitmap, animMask );
}
}
}
// ---------------------------------------------------------
// CWmListItemDrawer::DefaultLogoImage()
// ---------------------------------------------------------
//
const CFbsBitmap* CWmListItemDrawer::DefaultLogoImage()
{
return iDefaultLogoImage;
}
// ---------------------------------------------------------
// CWmListItemDrawer::DefaultLogoMask()
// ---------------------------------------------------------
//
const CFbsBitmap* CWmListItemDrawer::DefaultLogoMask()
{
return iDefaultLogoImageMask;
}
// ---------------------------------------------------------
// CWmListBox::NewL
// ---------------------------------------------------------
//
CWmListBox* CWmListBox::NewL(
CWmPlugin& aWmPlugin,
const TRect& aRect,
const CCoeControl* aParent,
TInt aFlags )
{
CWmListBox* self = new ( ELeave ) CWmListBox( aWmPlugin);
CleanupStack::PushL( self );
self->ConstructL( aRect, aParent, aFlags );
CleanupStack::Pop( self );
return self;
}
// ---------------------------------------------------------
// CWmListBox::CWmListBox
// ---------------------------------------------------------
//
CWmListBox::CWmListBox( CWmPlugin& aWmPlugin ):
CEikFormattedCellListBox(),
iWmPlugin( aWmPlugin )
{
iFindPaneIsVisible = EFalse;
iLogoSize = TSize( 0, 0);
}
// ---------------------------------------------------------
// CWmListBox::~CWmListBox
// ---------------------------------------------------------
//
CWmListBox::~CWmListBox()
{
iVisibleWidgetArray.ResetAndDestroy();
iOrderDataArray.ResetAndDestroy();
}
// ---------------------------------------------------------
// CWmListBox::ConstructL
// ---------------------------------------------------------
//
void CWmListBox::ConstructL(
const TRect& aRect,
const CCoeControl* aParent,
TInt aFlags )
{
CEikFormattedCellListBox::ConstructL( aParent, aFlags );
SetContainerWindowL( *aParent );
// set model point to the widgets array
Model()->SetItemTextArray( &iVisibleWidgetArray );
Model()->SetOwnershipType( ELbmDoesNotOwnItemArray );
// set empty-text to null
View()->SetListEmptyTextL( KNullDesC );
SetRect( aRect );
}
// ---------------------------------------------------------
// CWmListBox::WidgetData
// ---------------------------------------------------------
//
CWmWidgetData* CWmListBox::WidgetData()
{
TInt index = CurrentListBoxItemIndex();
return (index>=0 ? iVisibleWidgetArray[index] : NULL);
}
// ---------------------------------------------------------
// CWmListBox::WidgetData
// ---------------------------------------------------------
//
CWmWidgetData& CWmListBox::WidgetData( TInt aItemIndex, TBool aIgnoreSearchIndex )
{
return *iVisibleWidgetArray[ RealIndex( aItemIndex, aIgnoreSearchIndex ) ];
}
// ---------------------------------------------------------
// CWmListBox::AddWidgetDataL
// ---------------------------------------------------------
//
void CWmListBox::AddWidgetDataL( CWmWidgetData* aWidgetData,
TBool aRedraw )
{
if ( aWidgetData )
{
aWidgetData->SetObserver( this );
iVisibleWidgetArray.InsertInOrderAllowRepeatsL( aWidgetData,
SortOrder(EStoredOrder) );
if ( aRedraw ) { HandleItemAdditionL(); }
}
}
// ---------------------------------------------------------
// CWmListBox::RemoveWidgetData
// ---------------------------------------------------------
//
void CWmListBox::RemoveWidgetData( TInt aItemIndex, TBool aIgnoreSearchIndex )
{
TInt realIndex = RealIndex( aItemIndex, aIgnoreSearchIndex );
TBool current = ( aItemIndex == CurrentItemIndex() );
// remove widget data
CWmWidgetData* data = iVisibleWidgetArray[realIndex];
iVisibleWidgetArray.Remove( realIndex );
// Remove item from order array
for ( TInt i = 0; i < iOrderDataArray.Count(); i++ )
{
CWmWidgetOrderData* order = iOrderDataArray[i];
if ( order->EqualsTo( data->Uid(), data->PublisherId() ) )
{
iOrderDataArray.Remove( i );
delete order;
order = NULL;
break;
}
}
if ( aIgnoreSearchIndex )
{
// reorganise
TRAP_IGNORE(
AknListBoxUtils::HandleItemRemovalAndPositionHighlightL(
this, realIndex, current ) );
}
// delete now
delete data;
data = NULL;
}
// ---------------------------------------------------------
// CWmListBox::RedrawItem
// ---------------------------------------------------------
//
void CWmListBox::RedrawItem( TInt aItemIndex )
{
if ( aItemIndex >= 0 &&
aItemIndex < Model()->NumberOfItems() )
{
View()->DrawItem( aItemIndex );
}
}
// ---------------------------------------------------------
// CWmListBox::SetSortOrderL
// ---------------------------------------------------------
//
void CWmListBox::DoSortToVisibleArray( TSortOrder aOrder )
{
// now sort the existing data
iVisibleWidgetArray.Sort( SortOrder( aOrder ) );
DrawNow();
}
// ---------------------------------------------------------
// CWmListBox::CreateItemDrawerL
// ---------------------------------------------------------
//
void CWmListBox::CreateItemDrawerL()
{
CFormattedCellListBoxData* cellData = CFormattedCellListBoxData::NewL();
CleanupStack::PushL( cellData );
iItemDrawer = CWmListItemDrawer::NewL(
iWmPlugin,
Model(),
iEikonEnv->DenseFont(),
cellData,
this );
CleanupStack::Pop(); // cellData
}
// ---------------------------------------------------------
// CWmListBox::HandleLayoutChanged
// ---------------------------------------------------------
//
void CWmListBox::HandleLayoutChanged()
{
iLogoSize = TSize( 0, 0);
iLogoSize = LogoSize();
for ( TInt i=0; i<iVisibleWidgetArray.Count(); i++)
{
iVisibleWidgetArray[i]->UpdateLogo( iLogoSize, EFalse );
}
}
// ---------------------------------------------------------
// CWmListBox::HandleWidgetDataChanged
// ---------------------------------------------------------
//
void CWmListBox::HandleWidgetDataChanged( CWmWidgetData* aWidgetData )
{
if ( !iFindPaneIsVisible )
{
// spontaneous change in the model. Cause table to redraw
TInt index = iVisibleWidgetArray.Find( aWidgetData );
if ( index >= 0 )
{
// redraw item.
RedrawItem( RealIndex( index ) );
}
}
else
{
// redraw everything
Parent()->DrawDeferred();
}
}
// ---------------------------------------------------------
// CWmListBox::SortOrder
// ---------------------------------------------------------
//
TLinearOrder<CWmWidgetData> CWmListBox::SortOrder( TSortOrder aOrder )
{
if ( aOrder == EStoredOrder )
{
return TLinearOrder<CWmWidgetData>(
CWmWidgetData::CompareByPersistentWidgetOrder );
}
else
{
return TLinearOrder<CWmWidgetData>(
CWmWidgetData::CompareByName );
}
}
// ---------------------------------------------------------
// CWmListBox::CurrentListBoxItemIndex
// ---------------------------------------------------------
//
TInt CWmListBox::CurrentListBoxItemIndex()
{
TInt index( KErrNotFound );
if ( Model()->NumberOfItems() > 0 )
{
index = CurrentItemIndex();
}
return RealIndex( index );
}
// ---------------------------------------------------------
// CWmListBox::RealIndex
// ---------------------------------------------------------
//
TInt CWmListBox::RealIndex( TInt aIndex, TBool aIgnoreSearchIndex )
{
TInt realIndex = aIndex;
if ( ( iFindPaneIsVisible && aIndex >= 0 ) && !aIgnoreSearchIndex )
{
realIndex = static_cast<CAknFilteredTextListBoxModel*>(Model())->Filter()
->FilteredItemIndex( aIndex );
}
return realIndex;
}
// ---------------------------------------------------------
// CWmListBox::SizeChanged
// ---------------------------------------------------------
//
void CWmListBox::SizeChanged()
{
CEikFormattedCellListBox::SizeChanged();
CWmListItemDrawer* itemDrawer =
static_cast <CWmListItemDrawer*>( iItemDrawer );
if ( itemDrawer )
{
itemDrawer->UpdateItemHeight();
}
}
// ---------------------------------------------------------
// CWmListBox::Draw
// ---------------------------------------------------------
//
void CWmListBox::Draw( const TRect& aRect ) const
{
CWindowGc& gc = SystemGc();
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
AknsDrawUtils::Background( skin, cc, this, gc, Rect() );
CEikFormattedCellListBox::Draw( aRect );
}
// ---------------------------------------------------------
// CWmListBox::LogoSize
// ---------------------------------------------------------
//
TSize CWmListBox::LogoSize()
{
TSize size( iLogoSize );
if ( size.iWidth == 0 || size.iHeight == 0 )
{
TAknLayoutRect rowLayoutRect;
rowLayoutRect.LayoutRect( Rect(),
AknLayoutScalable_Apps::listrow_wgtman_pane().LayoutLine() );
TAknLayoutRect logoLayoutRect;
logoLayoutRect.LayoutRect( rowLayoutRect.Rect(),
AknLayoutScalable_Apps::listrow_wgtman_pane_g1().LayoutLine() );
size = logoLayoutRect.Rect().Size();
iLogoSize = size;
}
return size;
}
// ---------------------------------------------------------
// CWmListBox::DefaultLogo
// ---------------------------------------------------------
//
const CFbsBitmap* CWmListBox::DefaultLogo()
{
CWmListItemDrawer* itemDrawer =
static_cast <CWmListItemDrawer*>( iItemDrawer );
if ( itemDrawer )
{
return itemDrawer->DefaultLogoImage();
}
return NULL;
}
// ---------------------------------------------------------
// CWmListBox::DefaultMask
// ---------------------------------------------------------
//
const CFbsBitmap* CWmListBox::DefaultMask()
{
CWmListItemDrawer* itemDrawer =
static_cast <CWmListItemDrawer*>( iItemDrawer );
if ( itemDrawer )
{
return itemDrawer->DefaultLogoMask();
}
return NULL;
}
// ---------------------------------------------------------
// CWmListBox::SortOrderToOrderData
// ---------------------------------------------------------
//
TLinearOrder<CWmWidgetOrderData> CWmListBox::SortOrderToOrderData( TSortOrder aOrder )
{
if ( aOrder == EStoredOrder )
{
return TLinearOrder<CWmWidgetOrderData>(
CWmWidgetOrderData::CompareByPersistentWidgetOrder );
}
else
{
return TLinearOrder<CWmWidgetOrderData>(
CWmWidgetOrderData::CompareByName );
}
}
// ---------------------------------------------------------
// CWmListBox::SetSortOrderToOrderDataL
// ---------------------------------------------------------
//
void CWmListBox::DoSortToOrderData( TSortOrder aOrder )
{
iOrderDataArray.Sort( SortOrderToOrderData( aOrder ) );
}
// ---------------------------------------------------------
// CWmListBox::AddWidgetDataL
// ---------------------------------------------------------
//
void CWmListBox::AddOrderDataL( CWmWidgetOrderData* aOrderData )
{
if ( aOrderData )
{
iOrderDataArray.InsertInOrderAllowRepeatsL( aOrderData,
SortOrderToOrderData( EStoredOrder ) );
}
}
// ---------------------------------------------------------
// CWmListBox::OrderData
// ---------------------------------------------------------
//
CWmWidgetOrderData* CWmListBox::OrderData( TInt aItemIndex )
{
return iOrderDataArray[ aItemIndex ];
}
// End of File