Archived:How to customize a list box using Symbian C++
Article Metadata
Compatibility
Article
Overview
How to customize a list box?
Description
Developers may want to customize a list box according to their requirements. An example of such customization would be to remove the dotted column line from a double style list box.
Solution
Override the existing list box and item drawer methods by providing a custom implementation.
Below is a simplified example for customizing a double number style list box.
The header file should have the following declarations:
class CDSListItemDrawer : public CFormattedCellListBoxItemDrawer
{
public:
CDSListItemDrawer( MTextListBoxModel* aTextListBoxModel,
const CFont* aFont,
CFormattedCellListBoxData* aFormattedCellData );
void DrawItemText( TInt aItemIndex, const TRect &aActualItemRect,
TBool aItemIsCurrent, TBool aViewIsEmphasized,
TBool aItemIsSelected) const;
void SetColour( const TRgb& aTextForeground,
const TRgb& aTextBackground,
const TRgb& aHighlightForeground,
const TRgb& aHighlightBackground );
private: // data
TRgb iTextForegroundColour;
TRgb iTextBackgroundColour;
TRgb iHighlightForegroundColour;
TRgb iHighlightBackgroundColour;
const CFont* iPersistentFont;
CFormattedCellListBoxData* iCellData;
TInt iScrollOffset;
};
/*******************************************************************/
// A list box class whose only responsibility is to look after a CDSListItemDrawer.
class CDSListBox : public CAknDoubleNumberStyleListBox
{
public:
CDSListBox( const CFont* aFont,
CFormattedCellListBoxData* aFormattedCellListBoxData );
void SetScrollFrame();
void FindCellSize();
protected:
virtual void CreateItemDrawerL();
virtual CListBoxView* MakeViewClassInstanceL();
private:
const CFont* iFont;
CFormattedCellListBoxData* iFormattedCellListBoxData;
};
/****************************************************************/
The .cpp source file should have the following implementation.
CDSListItemDrawer::CDSListItemDrawer( MTextListBoxModel* aTextListBoxModel,
const CFont* aFont,
CFormattedCellListBoxData* aFormatedCellData )
: CFormattedCellListBoxItemDrawer( aTextListBoxModel, aFont, aFormatedCellData ),
iPersistentFont( aFont )
{
}
void CDSListItemDrawer::DrawItemText( TInt aItemIndex,
const TRect &aItemTextRect,
TBool aItemIsCurrent,
TBool aViewIsEmphasized,
TBool aItemIsSelected) const
{
Gc()->SetBrushStyle( CGraphicsContext::ESolidBrush );
Gc()->SetBrushColor( KRgbWhite );
Gc()->Clear( aItemTextRect );
TPtrC itemText = iModel->ItemText( aItemIndex );
TInt textLength = itemText.Length();
TInt tabPosition1 = itemText.Locate( '\t' );
TInt tabPosition2 = itemText.Mid(tabPosition1+1).Locate( '\t' );
const CFont* font = Font( aItemIndex );
Gc()->SetPenStyle( CGraphicsContext::ESolidPen );
Gc()->SetBrushStyle( CGraphicsContext::ESolidBrush );
TRgb textColour;
TRgb bgColour;
if ( aItemIsCurrent )
{
textColour = iHighlightForegroundColour;
bgColour = iHighlightBackgroundColour;
}
else
{
textColour = iTextForegroundColour;
bgColour = iTextBackgroundColour;
}
Gc()->UseFont( iPersistentFont );
// Set the item's background.
Gc()->SetBrushStyle( CGraphicsContext::ESolidBrush );
Gc()->SetBrushColor( bgColour );
Gc()->SetPenColor( textColour );
TRect textRect( TPoint( aItemTextRect.iTl.iX, (aItemTextRect.iTl.iY-10) ),
aItemTextRect.iBr );
textRect.iBr.iY -= aItemTextRect.Height() / 2;
if ( !font )
{
font = CEikonEnv::Static()->LegendFont();
}
Gc()->UseFont(font);
TInt baseline = ( textRect.iBr.iY
- textRect.iTl.iY
- font->HeightInPixels() ) / 2 + font->AscentInPixels();
Gc()->DrawText( itemText.Mid( 0,tabPosition1 ),
textRect, baseline-20, CGraphicsContext::ELeft);
Gc()->DrawText( itemText.Mid( tabPosition1+1, tabPosition2 - tabPosition1 ),
textRect, baseline, CGraphicsContext::ELeft, 0);
font = CCoeEnv::Static()->NormalFont();
Gc()->UseFont(font);
textRect.Move( 0, aItemTextRect.Height() / 2 );
baseline = ( textRect.iBr.iY
- textRect.iTl.iY
- font->HeightInPixels() ) / 2 + font->AscentInPixels();
Gc()->DrawText( itemText.Mid( tabPosition2,textLength-tabPosition2 ),
textRect, baseline, CGraphicsContext::ELeft, 1);
}
void CDSListItemDrawer::SetColour( const TRgb& aTextForeground,
const TRgb& aTextBackground,
const TRgb& aHighlightForeground,
const TRgb& aHighlightBackground)
{
iTextForegroundColour = aTextForeground;
iTextBackgroundColour = aTextBackground;
iHighlightForegroundColour = aHighlightForeground;
iHighlightBackgroundColour = aHighlightBackground;
iBackColor = iTextBackgroundColour;
}
CDSListBox::CDSListBox( const CFont* aFont,
CFormattedCellListBoxData* aFormattedCellListBoxData )
{
iFont = aFont;
iFormattedCellListBoxData=aFormattedCellListBoxData;
}
void CDSListBox::CreateItemDrawerL()
{
iItemDrawer = new (ELeave) CDSListItemDrawer(
Model(),
iFont,
iFormattedCellListBoxData );
}
CListBoxView* CDSListBox::MakeViewClassInstanceL()
{
return new (ELeave) CListBoxView();
}
void CDSListBox::SetScrollFrame()
{
}
void CDSListBox::FindCellSize()
{
}
/******************************************************************/
The calling function from a CCoeControl should contain:
SetExtentToWholeScreen(); // Drawing it to the whole screen
iTextForegroundColour = KRgbGreen;
iTextBackgroundColour = KRgbRed;
iHighlightForegroundColour = KRgbWhite;
iHighlightBackgroundColour = KRgbBlue;
iListItems = new (ELeave) CDesC16ArrayFlat( 2 );
const CFont *font;
_LIT( KTextFont, "LatinBold13" );
CFont* myFont;
CFormattedCellListBoxData* myFormattedCellListBoxData;
CGraphicsDevice* screenDevice = CEikonEnv::Static()->ScreenDevice();
TFontSpec textFontSpec( KTextFont, 200 );
screenDevice->GetNearestFontInTwips( myFont,textFontSpec );
myFormattedCellListBoxData = CFormattedCellListBoxData::NewL();
iListBox1 = new (ELeave) CDSListBox( myFont, myFormattedCellListBoxData );
iListBox1->ConstructL( this, 0 );
iListBox1->SetRect( TRect( 0, 0, 3000, 3000 ) );
CDSListItemDrawer* drawer = (CDSListItemDrawer*) iListBox1->View()->ItemDrawer();
drawer->SetColour( iTextForegroundColour,
iTextBackgroundColour,
iHighlightForegroundColour,
iHighlightBackgroundColour );
CColumnListBoxData* columnData=CColumnListBoxData::NewL();
columnData->SetControl( iListBox1 );
TInt columnSize;
columnData->ColumnWidthPixel( columnSize );
_LIT( KListItemFormat, "%d\t%S\t%S" );
_LIT( KName1, "Name11" );
_LIT( KContactNo,"123" );
_LIT( KName2,"Name22" );
_LIT( KContactNo2,"789" );
TBuf<40> item;
MDesCArray* itemList = iListBox1->Model()->ItemTextArray();
CDesCArray* itemArray = (CDesCArray*) itemList;
TBuf<30> NameBuf;
TBuf<30> ConBuf;
// add first item in the array
NameBuf.Copy( KName1 );
ConBuf.Copy( KContactNo );
TInt id = 1;
item.Format( KListItemFormat, id, &NameBuf, &ConBuf );
itemArray->AppendL( item );
// add second item in the array
NameBuf.Zero();
ConBuf.Zero();
NameBuf.Copy( KName2 );
ConBuf.Copy( KContactNo2 );
item.Format( KListItemFormat, id, &NameBuf, &ConBuf );
itemArray->AppendL( item );
NameBuf.Zero();
ConBuf.Zero();
iListBox1->SetRect( TRect( TPoint( 0,0 ),
TPoint( 20000, 20000 )) );
iListBox1->ActivateL();
iListBox1->HandleItemAdditionL();
DrawNow();
NOTE:
This is just an example and not the complete code. In order to customize the grid, the coordinates need to be calculated correctly and the position of every item such as text, icons, highlight, etc. should be taken care of - this requires a lot of work.


(no comments yet)