API description
Skins API provides services for UI controls and applications. These services
consist of:
-
An interface for skin item data object retrieval.
-
An interface for local item definition manipulation.
-
Client-side skin framework (skin instance, control context, data context).
-
Utility functionality (common operations, drawing operations).
To make a UI control (for example, one defined by the application itself)
skin-aware, it may be necessary to modify its drawing code. For example, if
a control clears its background, it must be done using a method provided by
AVKON Skins.
To make a UI control use resources provided by the skins (for example,
bitmaps), the control must be modified so that it retrieves the resources
using AVKON Skins interfaces and reacts properly to the skin change event.
Any container that occupies the full main pane (or pop-up window) needs
to be modified to provide a skin control context. This is done to specify
how layout backgrounds are used by its child controls.
AVKON Skins also provides means to cache skin item data objects and to
control the lifetime of a cached item data object. It is up to the application
(or UI control), whether it will or will not take advantage of these.
Each skin item represents a single resource (i.e., bitmap or application
icon) that can be retrieved using the AVKON Skins interfaces. A skin item
is identified by its identifier.
Item identifiers are common among all skin packages. They are mapped to
concrete resources (skin item data objects) using skin item definitions. Item
definitions for system-wide skin items are stored and managed by Skins Server.
Most applications and components have, however, no reason to do so.
Typically, a UI component needs to obtain or construct an item data object
by providing the corresponding item ID to the AVKON Skins subsystem. An item
data object (or a resource instance extracted from it) is returned to the
caller.
Skins API supports only Symbian skins. If application needs skinning of its
own bitmaps, it has to implement skinning.
Skin drawing
Provides utility methods to perform skin-aware drawing operations, such
as background drawing for a UI control. Contains the following class:
AknsDrawUtils
.
Related APIs
Skin utility
Supports AVKON Skins common operations. AknsUtils provides utility methods
to initialize skins support, retrieve a pointer to the current skin instance
or data context, and to perform other skin-related tasks. Contains the following
class:
AknsUtils
.
Related APIs
Wallpaper utility
A utility class for manipulating the Idle state wallpaper. Contains the
following class:
AknsWallpaperUtils
.
Related APIs
Control context
In order to maintain binary compatibility and to avoid passing additional
parameters to child controls, skins support relies on context information
passed in the control hierarchy using the
MObjectProvider
mechanism.
An overview of the
MObjectProvider
functionality is provided
in Symbian Developer Library.
For example, when the
Background()
method of
AknsDrawUtils
is
called to draw the bitmapped layout background for the control, the object
provider chain is searched for a control context and the nearest one (i.e.,
the control context provided by the nearest parent) is used to specify the
bitmap and layout for drawing. This implies two requirements for controls
and applications:
-
The object provider chain must be solid for every control that needs (or
may need in the future) information from a skin control context. Drawing a
bitmapped layout background is an operation that needs such information.
-
There must be an entity that provides the control context.
The entity that provides the control context is usually the one that represents
the layout element that defines the background to be used. For the status
pane and control pane, the control context is provided by their implementation.
For the main pane, the control context may be provided by the system classes
(for instance, when an AVKON control covering the entire main pane is used),
but in other cases should be provided by the application. The proper place
for this is usually the container that occupies the main pane.
If no control context is found, the drawing operations provided by AVKON
Skins function as the corresponding methods in Symbian OS UI Graphics Utilities.
This ensures backwards compatibility with applications that are not aware
of the skins support even if they use controls that take advantage of AVKON
Skins.
Contains the following classes:
-
CAknsBasicBackgroundControlContext
-
CAknsListBoxBackgroundControlContext
-
CAknsLayeredBackgroundControlContext
-
CAknsFrameBackgroundControlContext
-
CAknsContainerDataContext
Related APIs
-
AknsDrawUtils
-
Background()
-
CAknsBasicBackgroundControlContext
-
CAknsContainerDataContext
-
CAknsFrameBackgroundControlContext
-
CAknsLayeredBackgroundControlContext
-
CAknsListBoxBackgroundControlContext
-
MObjectProvider
Item data
The skin instance takes care of updating cached item data objects when
item definitions change and they are owned (and therefore deleted) by the
skin instance. The caller is responsible for updating independent objects.
If the UI control can be drawn even when the skin instance singleton is
not available (for example, during an AppUi destroyer), it must handle situations
when skin support is not available and
AknsUtils::SkinInstance
returns
NULL
.
Every UI control should also be prepared for error conditions caused by skin
item retrieval and should handle leaves or
NULL
return values
properly.
Contains the following classes:
Related APIs
-
AknsUtils::SkinInstance
-
CAknsAnimationItemData
-
CAknsBitmapItemData
-
CAknsBmpAnimItemData
-
CAknsColorTableItemData
-
CAknsEffectQueueItemData
-
CAknsImageItemData
-
CAknsImageTableItemData
-
CAknsItemData
-
CAknsMaskedBitmapItemData
-
CAknsStringItemData
-
NULL
Use cases
The main use cases of Skins API are:
-
Enabling skin support in application
-
Enabling skin support for a specific control
-
Accessing application skin instance
-
Providing data context and reserving skin item
-
Providing control context and drawing background
-
Accessing item data objects
-
Accessing cached item data objects
-
Creating an icon
-
Setting Idle state wallpaper
-
Using other skin utilities
API class structure
Skins API classes with their inheritance and composition relationships.
Using Skins API
Enabling skin support in an application
Generally, if the entire layout area (i.e. status pane, control pane, main
pane or pop-up window) is drawn by a single AVKON control, which already provides
the necessary parameters, there is no need for significant application changes
at all. Always enable skins in application level. This can be done either
application-wide or on a component-by-component basis:
void CMyAppUi::ConstructL()
{
// Enables skins in all the optionally skin-providing controls in this application
BaseConstructL( EAknEnableSkin );
// …
}
It is also possible to enable skins for a skin providing control, but not
all controls supports this method.
void CMyContainer::ConstructL()
{
// …
// Enables skin for control
iSomeOptSkinAwareCtrl->SetSkinEnabledL( ETrue );
// …
}
Accessing application skin instance
The skins enabled Symbian application framework constructs a singleton object
called a skin instance for every application. It performs several fundamental
operations related to skin support.
Firstly, the skin instance performs skin item lookup and data construction.
This involves querying the item definition from Skins Server and using the
item data factory to construct the item data object.
Secondly, the skin instance maintains the item data cache. If the caller
requests a cached item data object, it is stored in the cache and any skin
change triggers automatic reconstruction.
Thirdly, local item definitions are managed by the skin instance. An application
may set local item definitions that are visible only within its own thread.
In this example, application supports skins, and a pointer to the application’s
skin instance is requested.
void CMyControl::ConstructL()
{
// …
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
// …
}
Providing control context and drawing background
AknsDrawUtils
provides methods to draw a background bitmap
for UI controls. If the application is non-skin-aware (or the control context
specifies that no bitmap can be used), these methods clear the area without
any bitmap..
The container may optionally provide a data context to ensure that skin
items reserved by it and its child controls are released properly when the
container goes out of scope.
To provide data context, the container must override the
MopSupplyObject
method
and own an object implementing the data context interface.
class CMyContainer : public CCoeControl
{
//…
/**
* Pass skin information if needed.
*/
TTypeUid::Ptr MopSupplyObject(TTypeUid aId);
public:
CAknsBasicBackgroundControlContext* iBackground;
//…
};
Creates the control context with a defined background ID.
void CMyContainer::ConstructL(const TRect& aRect )
{
//…
TRect rect(0, 0, 0, 0);
// Temporary rect is passed. Correct rect is set in SizeChanged.
// Create the new context with image: KAknsIIDQsnBgAreaMain, and parent absolute layout is not used.
iBackground = CAknsBasicBackgroundControlContext::NewL(KAknsIIDQsnBgAreaMain, rect, EFalse );
//…
SetRect(aRect);
ActivateL();
}
Modifies the container’s
Draw()
method to draw the background.
void CMyContainer::Draw( )
{
//…
// Drawing skin
if ( iBackground )
{
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
if ( !AknsDrawUtils::Background( skin, iBackground, this, gc, rect) )
{
// The background was not drawn….
}
}
//…
}
Updates the position in container’s
SizeChanged()
method.
void CMyContainer::SizeChanged()
{
//…
if ( iBackground )
{
iBackground->SetRect(Rect());
}
//…
}
MopSupplyObject
must provide a pointer to the control
context, in this example the
CAknsBasicBackgroundControlContext
instance.
TTypeUid::Ptr CMyContainer::MopSupplyObject(TTypeUid aId)
{
if (aId.iUid == MAknsControlContext::ETypeId && iBackground)
{
return MAknsControlContext::SupplyMopObject(aId, iBackground);
}
return CCoeControl::MopSupplyObject(aId);
}
Related APIs
-
AknsDrawUtils
-
CAknsBasicBackgroundControlContext
-
Draw()
-
MopSupplyObject
-
SizeChanged()
Accessing item data objects
Skin item data is constructed and cached if necessary, based on the item
definition available from the local definition list or, if not found there,
the shared memory chunk lookup provided by AVKON Skins Server. A pointer to
the cached item data object is returned to the caller.
In this example scrollbar's top background skin element is accessed. The
returned
CAknsItemData
pointer can be casted for example
to pointer
CAknsMaskedBitmapItemData
in order to get access
to the bitmap objects themselves.
class CMyContainer : public CCoeControl
{
// …
CAknsItemData* iItemData;
// …
}
Accesses the bitmap in skin item data.
// Gets skin item
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
iItemData = skin->CreateUncachedItemDataL( KAknsIIDQsnCpScrollBgTop );
if ( iItemData )
{
// Accesses bitmap objectin skin item
CAknsBitmapItemData* bitmapContex=(CAknsBitmapItemData*)iItemData;
CFbsBitmap* bitmap = bitmapContex->Bitmap();
}
In the case of a bitmap item, the same can be performed with much less
code by using
AknsUtils::CreateBitmapL
.
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
if( skin )
{
iBmp = AknsUtils::CreateBitmapL( KAknsIIDQsnCpScrollBgTop );
}
Related APIs
-
AknsUtils::CreateBitmapL
-
CAknsItemData
-
CAknsMaskedBitmapItemData
Accessing cached item data objects
Utility methods should be used to facilitate, for example, fetching bitmap
type skin item data.
void CMyControl::Draw(const TRect& aRect) const
{
// …
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
CFbsBitmap* bitmap = AknsUtils::GetCachedBitmap( skin, KAknsIIDQsnBgAreaMain );
if( bitmap )
{
// Draw the bitmap.
}
else
{
// Not found or an error occurred. Draw without the bitmap.
}
// …
}
Skin items of the image type (such as bitmaps) can also be drawn directly
using the
AknsDrawUtils::DrawCachedImage
method.
void CMyControl::Draw(const TRect& aRect) const
{
// …
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
AknsDrawUtils::DrawCachedImage( skin, gc, rect, KAknsIIDQsnBgAreaMain );
// …
}
Related APIs
-
AknsDrawUtils::DrawCachedImage
Setting idle state wallpaper
AknsWallpaperUtils::SetIdleWallpaper()
changes the actual
idle state wallpaper. If
KNullDesC
is set as a wallpaper
file name, the method removes the current wallpaper.
_LIT( KWallpaperFile,"c:\\wallpaperimage.jpg" );
User::LeaveIfError( AknsWallpaperUtils::SetIdleWallpaper( KWallpaperFilename, NULL ) );
Related APIs
-
AknsWallpaperUtils::SetIdleWallpaper()
-
KNullDesC
Using other skin utilities
Creates an independent copy by the given item ID, and creates a
CGulIcon
object.
AknIconUtils::SetSize()
must
be called before drawing the bitmap.
CGulIcon* newIcon;
CFbsBitmap *newIconBmp;
CFbsBitmap *newIconMaskBmp;
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
AknsUtils::CreateIconL( skin, KMyBmpIID, newIconBmp, newIconMaskBmp, iconFile, iconIndex, iconMaskIndex );
newIcon = CGulIcon::NewL( newIconBmp, newIconMaskBmp);
A faster method to create a
CGulIcon
object.
CGulIcon* newIcon;
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
newIcon = AknsUtils:: CreateGulIconL( skin, KMyBmpIID, iconFile, iconIndex, iconMaskIndex );
Gets an application icon supporting scalable graphics. This example gets
the icon of the calculator application.
CFbsBitmap* bitmap;
CFbsBitmap* mask;
AknsUtils::CreateAppIconLC(skin, TUid::Uid(0x01FEDCBA), EAknsAppIconTypeContext, bitmap, mask);
// CreateAppIconLC puts both bitmap to stack
CleanupStack::Pop(); // bitmap
CleanupStack::Pop(); // mask
// Sets the size of the bitmap before displaying
TSize size( 100, 100 );
AknIconUtils::SetSize( bitmap, size );
This utility method creates an independent (in terms of instance ownership)
copy of a masked bitmap by the given item ID and applies color-based skinning
to it.
CFbsBitmap* bitmap;
CFbsBitmap* mask;
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
AknsUtils::CreateColorIconL( skin, KMyBmpID, KAknsIIDQsnComponentColors, EAknsCIQsnComponentColorsCG5, bitmap, mask, KAvkonBitmapFile, EMbmAvkonQgn_note_warning, EMbmAvkonQgn_note_warning_mask, KRgbBlack );
// Set the size of the bitmap before displaying
TSize size( 100, 100 );
AknIconUtils::SetSize( iBitmap, size );
This example gets the text color of the main area in the current skin context.
Color groups and indexes can be found in the file
AknsConstants.h
.
MAknsSkinInstance* skin = AknsUtils::SkinInstance();
TRgb color;
AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6 );
Related APIs
-
AknIconUtils::SetSize()
-
CGulIcon
Error handling
Skins API uses standard Symbian OS error reporting mechanism. Possible
panic circumstances and panic codes are indicated in class or method descriptions.
There are also API methods that cannot be allowed to leave, e.g. utility
methods used during drawing operations. These methods either fail silently
or return an error value as specified in their documentation in C++ header
file comments.
Memory overhead
A skin instance object is allocated for every application thread. This
causes minor heap consumption, estimated to be approximately 100 bytes per
application thread. In addition, local item definitions and cached item data
objects demand heap causing variable heap consumption depending on the size
and number of objects allocated. The application should consider deleting
bitmaps when no longer needed.
Limitations of the API
Skins API supports only Symbian skins. If application needs skinning of its
own bitmaps, it has to implement skinning. Local item definitions should not
be used. Clients should not create instances of item data classes.