Enable Skin support in your Symbian OS applications

Part I: S60 v2

Nokia has introduced skin support in S60 v2. For various reasons, including compatibility with S60 v1 and thus older devices, this support is not enabled by default: your application will display a not so original white background unless you code it differently.

A nice and user-friendly way to behave is to use the mobile theme skin as a background for your application. Unless very badly documented in the SDK so far, this is not that complex for most applications. Here is an example implementation.

Application UI

The impact in your application UI is quite limited. All you have to do is to enable skins when calling the AppUi base constructor:

// ConstructL is called by the application framework
void CSkinDemoAppUi::ConstructL()
{
 BaseConstructL(EAknEnableSkin);
 ...
}

Application View or Containers

As you may have guessed, the main changes will be in your view and containers. The changes here may vary from simple to rather complex depending on what your are trying to achieve. Unfortunately, the Skin API is not very well documented and everything here is not always compatible in S60 3rd Edition... [1]

First, you need to create a specific context to hold the skin bitmap for your control. Do this by adding the following data member to your view/container class:

CAknsBasicBackgroundControlContext* iBgContext;

And initialize properly in the corresponding ConstructL, initialise a reference to the background bitmap:

#include <AknsDrawUtils.h>
#include <AknsBasicBackgroundControlContext.h>

...

void CSkinDemoAppView::ConstructL()
{
 ...
 iBgContext = CAknsBasicBackgroundControlContext::NewL( KAknsIIDQsnBgAreaMain,aRect,ETrue);
 ...
}

Don't forget to call the corresponding destructor:

void CSkinDemoAppView::~CSkinDemoAppView()
{
 ...
 delete iBgContext;
 ...
}

This context shall be passed to the child controls so that they can redisplay themselves correctly. This is done throgh MOP relationship and you then need to override the MopSupplyObject() primitive as follow:

TTypeUid::Ptr CSkinDemoAppView::MopSupplyObject(TTypeUid aId)
{
 if (iBgContext )
 {
   return MAknsControlContext::SupplyMopObject( aId, iBgContext );
 }
 return CCoeControl::MopSupplyObject(aId);
}

Each control Draw primitive shall now be updated to display the skin as background:

// Draw this application's view to the screen
void CSkinDemoAppView::Draw(const TRect& aRect) const
{
 // Get the standard graphics context
 CWindowGc& gc = SystemGc();
   
 // Redraw the background using the default skin
 MAknsSkinInstance* skin = AknsUtils::SkinInstance();
 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
 AknsDrawUtils::Background( skin, cc, this, gc, aRect );

 ...
}

And finally:

void CSkinDemoAppView::SizeChanged()
{
 if(iBgContext)
 {
   iBgContext->SetRect(Rect());
                if ( &Window() )
                {
                        iBgContext->SetParentPos( PositionRelativeToScreen() );
                }
 }
}

If your control contains a listbox, you can enable skin behind the items by calling:

iListBox->ItemDrawer()->ColumnData()->SetSkinEnabledL(ETrue)

MMP File

And finally, you need to link against the Avkon Skin libraries. Add the following line in your MMP file:

LIBRARY aknskins.lib aknskinsrv.lib

Download

Below you will find two samples project. One simple application created with the Codewarrior wizard without any skin support and its counterpart with skin support added.

SkinDemo.png   SkinDemo.sis
SkinDemo.sis
  SkinDemo.zip
SkinDemo.zip
SkinDemo2.png   SkinDemo2.sis
SkinDemo2.sis
  SkinDemo2.zip
SkinDemo2.zip

[1] But if you have the equivalent for 3rd edition... feel free to mail me so that I can update the page!


Enable Skin support in your Symbian OS applications

Here is some information how to fetch suitable colors through skins aswell.

The different color groups are defined in aknsconstants.h and they are:

KAknsIIDQsnIconColors, KAknsIIDQsnTextColors, KAknsIIDQsnLineColors, KAknsIIDQsnOtherColors and KAknsIIDQsnHighlightColors

All the color groups have corresponding enum, which is used to choose a specific color in the group. Every value in the enum has different purpose, but fortunately every item has atleast some kind of description

Example, how to fetch main area text color through skins library

// Initialize the color to some default value as GetCachedColor(...) won't change it if the colori is not defined in the skin

TRgb color(0,0,0);

GetCachedColor(skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6 );

Additionally, to use skins you probably don't need to link against aknskinsrv.lib at all, but aknskins.lib should be enough.

Also you probably need to take care of KAknsMessageSkinChange in your applications HandleResourceChange function (and refetch the needed information through skins), and in some cases you need to call HandleResourceChange for the subcomponents you might have.

Enable Skin support in your Symbian OS applications

All work exactly. It nice. I would like see my skin in the dialog. I us CEikDialog. How to do it?

Enable Skin support in your Symbian OS applications

Hi. it is worked. Cool. How displey skins in the dialog. I us CEikDialog. Thank you.

Enable Skin support in your Symbian OS applications

Hows that to bring the skins for Menu too.I was able to create the skin support for the cba and grids.but i dont find the bitmap shown in the menus..is there any way to do it. regards

Enable Skin support in your Symbian OS applications

Hi,

What type of iListBox is ? I tried with custom list box but it gave error that ColumnData(),ItemDrawer(), SetSkinEnabled() are not member of that class. which listbox should i use ? thnx in advace.........

Enable Skin support in your Symbian OS applications

Hi..

I want some more information about getting the bitmaps from the skin.

I want to know how to get the bitmaps (say the background image for progress bar, or menu tab from the skin). I tried with ..

colour = (CAknsItemData * )skin->GetCachedItemData (KAknsIIDQsnBgAreaMainFlat ,  EAknsITBitmap    );

if(colour)
{
   CAknsBitmapItemData* colourData = static_cast<CAknsBitmapItemData*>(colour);
   CFbsBitmap *bitmp =  colourData->Bitmap();
}
is this correct??

do anyone have a list of available(minimum ) bitmaps in the skin. When i run this application on different skins it always shows a blank image.. i dont know wether it is working properly or not...please clarify my doubts.

Enable Skin support in your Symbian OS applications

hi eric, please update this post S60 3rd edition.

Enable Skin support in your Symbian OS applications

The code described in the post works for 3rd Edition.

Skins and S60 3rd Edition

Hi I just tested your code with Nokia n80 (S60 3rd ed., Symbian 9.1 phone) - everything you write in your article works perfectly fine :-D I don't even have to call a special method for Listbox to work with skins (probably it's active by default). Doesn't work by CEikLabel, though. Probably not meant to be skinned? I don't know yet. Anyway, thanx a lot for the hints :-) Bye