Building custom widgets with the Zinzala SDK - page 5

Shared object contents

Each skin-shared object must provide a function through which a given resource can be retrieved. A simple tUint16 is enough to identify each resource defined in the C++ file we have created from the graphics:

const tBitmapResource *gResources[] = { &kRscBitmapBackground, &kRscBitmapDimmed, &kRscBitmapNormal, &kRscBitmapPressed, &kRscBitmapAnimate1, &kRscBitmapAnimate2, &kRscBitmapAnimate3, &kRscBitmapForwardN, &kRscBitmapForwardD, &kRscBitmapPauseN, &kRscBitmapPauseD, &kRscBitmapPlayN, &kRscBitmapPlayD, &kRscBitmapBackwardN, &kRscBitmapBackwardD, &kRscBitmapStopN, &kRscBitmapStopD }; tUint16 kResourcesCount = 17; extern "C" const tBitmapResource *GetResource(tUint16 aResourceID) { if(aResourceID < kResourcesCount) return gResources[aResourceID]; else return NULL; }

The array gResources contains a pointer to each graphic resource that we created earlier. The function GetResource() accesses the array and returns a resource from a position in the array.

You may have a look at the skin C++ file.

Loading the shared object

To load and access the skin-shared object, we are now going to derive the class cAddOn and add to it a method that will retrieve the resource when given a resource ID. It will simply use the GetResource() function defined in every skin-shared object.

Here's the declaration of the class:

class cDSkin : public cAddOn { public: cDSkin(const tChar *aPath); const tBitmapResource &GetResourceL(tSkinResource aResource); private: const tBitmapResource *(*iFunction)(tUint16 aResourceID); };

The member data iFunction will be set in the constructor to point to the shared object function we implemented earlier. The method GetResourceL() relies on it to get the tBitmapResource associated with the requested resource. Note that if the resource doesn't exist in the skin, this method will throw an exception. This is implied by the L, as in Leave, that is added to the end of its name. This is a common practice in Symbian. The name convention allows developers to easily recognize which methods can throw an exception.

The type tSkinResource defines all the resources that should be accessible from any skin:

enum tSkinResource { eResBackground = 0, eResDimmed, eResNormal, eResPressed, eResAnimate1, eResAnimate2, eResAnimate3, eResForwardN, eResForwardD, eResPauseN, eResPauseD, eResPlayN, eResPlayD, eResBackwardN, eResBackwardD, eResStopN, eResStopD };

Here's the code of the class constructor:

cDSkin::cDSkin(const tChar *aPath) : cAddOn(aPath) { if(!iFault) { iFunction = (const tBitmapResource *(*)(tUint16 aResourceID))Find("GetResource"); if(!iFunction) iFault = kErrNotFound; } }

If the skin-shared object is correctly loaded, the data member iFault will be kErrNone (whose value is 0). We can then use the method cAddOn::Find() to find the function GetResource() implemented in the shared object. If we cannot find it, iFault will indicate the error. It is the responsibility of the calling code to check the validity of the cDSkin object. Because we have used extern "C" when defining the function GetResource(), we don't have to deal with mangled name.

The method GetResourceL() shows how the resource will be retrieved from the shared object:

const tBitmapResource &cDSkin::GetResourceL(tSkinResource aResource) { if(!iFault) { const tBitmapResource *lRes; lRes = (*iFunction)((tUint16)aResource); if(lRes) return *lRes; else throw uException(kErrNotFound,"cDSkin::GetResourceL"); } else throw uException(iFault,"cDSkin::GetResourceL"); }

If the skin is not valid or if we cannot find the specified skin, an exception will be raised. The class uException is the basic exception class in the Zinzala SDK. It takes an error code and a string indicating where the exception was raised as its arguments.

You may have a look at the complete header and C++ files if you like.

Print version

All content © 2004-2007, hexaZen - Vancouver BC, Canada