Building custom widgets with the Zinzala SDK - page 14

Here's the C++ file for the main.

Now that our test application is complete, we can try it out with an alternate skin:

#> ./custom -s ./Skins/Orange/Orange.so

orange animation button

5. Adding scriptability

A key feature of the Zinzala SDK is the ease with which we can add support for application scripting. We will now see how we can use this feature to add support for an on the fly skin change. This will be done while the application is running.

For testing, we will be using the tool yo which is part of the Zinzala library distribution. However, any application can send scripting messages to another application. For example, in the case of the Carrozza layer we discussed earlier, if requested a configuration panel could be sending a message to all the UI applications running in order to change the overall look of the UI. Because this will be done on the fly, there will be no interruption of services. For example, music or movie playback will remain active.

Without any modification to the application, we can already send some messages to it. For example:

#> yo hexaZen/Custom ping got answer in 0.000000 ms cCan::0x8047850 items=0 What = 'zAPo' Context = 0x0 #> yo hexaZen/Custom info got answer in 0.999928 ms cCan::0x8047850 items=6 What = 'zARy' Context = 0x0 Item 'zSDK' have 1 value(s) 0 string (4) '0.8' Item 'Username' have 1 value(s) 0 string (4) 'jlv' Item 'MaxInstances' have 1 value(s) 0 tUint8 (1) 125 Item 'Scripting' have 1 value(s) 0 tUint8 (1) 0 Item 'MaxMSGLength' have 1 value(s) 0 tUint16 (2) 100 Item 'GUIEngine' have 1 value(s) 0 string (7) 'Photon' #> yo hexaZen/Custom list window

However, if we ask the application to use a different skin, it will obviously not work:

#> yo hexaZen/Custom tell window do reskin Orange.so Not allowed

There are 2 reasons for this. By default, scripting is not enabled, and the keyword reskin is unknown to the cWindow class. This can be easily changed. Let's have a look at what needs to be done in order to support the change of a skin on the fly.

cDApplication

Before adding support in the window class, we need to allow scripting at the application level. This is done by modifying the method Ready() as follows:

void cDApplication::Ready() { // Allow scripting AllowScripting(eLocal); // Increase the buffer size for messaging SetBufferLength(250); ... ... ... }

Because the path to the skin to be loaded is going to be included in the scripting message, we need to set the size of the receiving buffer to 250 bytes. The default size is 100 bytes. If we didn't do that, the path could have been truncated. 250 bytes should be enough for most cases.

cDWindow

Next, we are going to add handling for the reskin command. The window should handle this scripting message, then ask each widget to use the new skin. This is what we are going to do.

First, we modify the definition of the cDWindow class:

class cDWindow : public cWindow { public: static cDWindow *NewL(cSettings *aSettings,cDSkin &aSkin); virtual ~cDWindow(); protected: void Ready(); bool CloseRequested(); void ScriptingReceived(cMessage *aMessage,cMessage *aReply); protected: cDWindow(cSettings *aSettings); void ConstructL(cDSkin &aSkin); private: void ReSkinL(const tChar *aSkin); private: cSettings* iSettings; cMyConsoleView* iConsole; };

We have added the methods ScriptingReceived() and ReSkinL(). The first method is inherited from the framework and will be called when the window receives a scripting message. We will be using the second method to perform the change of skin.

Just like in the application class, we need to allow scripting for the window. We modify the method Ready() as follows:

void cDWindow::Ready() { AllowScripting(eLocal); SetBeatRate(kBeatRate); cWindow::Ready(); }

In ScriptingReceived(), we need to detect if the scripting command is do reskin. If it is not, we can pass the scripting message to the base class method and let it deal with it. Here's how the method looks like:

void cDWindow::ScriptingReceived(cMessage *aMessage,cMessage *aReply) { tUint32 lCmd; aReply->SetBool(kScriptItemDone,true); if(!aMessage->GetUint32(kScriptItemCommand,&lCmd)) {

Print version

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