The implementation of NewL() is very close to the one we have in the base class. In fact, such methods are always very similar, since their purpose is to create a new object and construct it. The method NewL() from the base class is not really necessary because it is very unlikely that someone will want to use that class without derivating it, but you never know ... :)

I have added the method Reset() to the class. Its purpose is to reset the console to its stopped state:

void cMyConsoleView::Reset()
{
SetState(eStopped);
}

Our implementation of the button callbacks that will be presented, is as simple as it can get. Real world implementations will likely be a bit more complex, although they will perform the same basic actions as here, such as changing the console state:

The cSettings class provides access to the application specific settings, which will be saved and restored each time the application runs. We will use it to save the position of the window on screen. This is not a requirement for any window or application with the Zinzala SDK, but rather a personal preference. I prefer that my window always appears at the last place I left it.

As you might guess by now, our window class will use the two-phase construction idiom. Note, although the SDK provides everything that is needed to use this idiom, it does not force the developer to use it, nor does it enforce the use of exceptions as the means of error handling.

If the base class construction turns out to be a success, we set the title of the window, then specify a 5x5 padding for the widget area. This padding doesn't mean that each widget placed on the window will be surrounded by 5 pixels of empty space. It simply means that there will be an inset of 5 pixels to the window bounds. We also set the background color to white.

// Get position of the window is possible
if(iSettings->HasItem("pos"))
{
iSettings->GetData("pos",eDataBuffer,(char **)&lPos,sizeof(uPoint));
MoveTo(*lPos);
}

If the demo application was already used once, the settings should contain the position of the window on screen. If this is the case, we read that position from the settings and move the window accordingly.

}
}

The instantiation of our console will be placed in the ConstructL() method of the window, as it can throw an exception:

The method Ready() and CloseRequested() are implemented in our class and defined in cWindow. The first one is
called after the window is displayed on screen. We will be using it to set the beat rate of the window, which our console widget needs for the active button animation:

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

The constant kBeatRate is defined as const tUint32 kBeatRate = 150 and is expressed in milliseconds.

When the user asks to close the window, the method CloseRequested() will be executed. If it returns true, the window will be closed, else it will remain open. This is the perfect time for us to save the current position of the window on screen, for future usage:

The first argument of the base class constructor is the name of the application. This name will be used to identify the application if we wanted to send some scripting messages to it. We will come back to that later. The class cSettings from which we instantiate iSettings provides access to the application settings. If something is wrong with it, or if the object cannot be created, the data member iFault of the application will be set to something other than kErrNone.

If you recall the destructor of cDWindow, you may remember that we didn't delete the console widget in it, since the window took care of that. The application class, does not take care of deleting the window for us, so we will need to delete iWindow in it:

Calling the method Save() on the cSettings object will save the last position of the window in the application settings file. Storing data in it, like we did in the method CloseRequested(), does not automatically save the changes to a file.

Before we look into the method Ready(), which is quiet interesting, we first need to talk a bit about how the skin shared object will be loaded and then passed down to the window. When the application is launched, the skin to be used will be passed in the command line argument. We will be using the switch -s for that. The static class sArgs provided by the SDK allows for an easy parsing of the command line. It will be used in the main of the application. Since it is static, we can use it in the Ready() method to get the path of the skin.

Although we have had iSettings since the constructor, we have not loaded the settings file until now. If it is the very first time the application is started, the settings file will not exist. The method Load() will fail, but it doesn't really matter since we will create the file when we save the settings in the application destructor. Now,
we are going to use the method sArgs::Presents() to test if the switch was present on the command line:

Using the class cDSkin presented earlier, we have loaded the shared object containing the skin from the path name retrieved from the value associated with the switch -s. However, it is only after testing the validity of lSkin, will we know if the skin object was loaded correctly:

if(lSkin.IsValid())
{

If the skin was loaded properly, we can go ahead and create the window. Since the window creation can throw an exception, we will be putting it in a try...catch block:

// create & show window
try
{
sCleanupStack::WindL();

Calling the method WindL() is mandatory in the beginning of the block. Its purpose is to prepare the cleanup stack. Note that this method can leave if something is not right. However, since we are already in the try...catch block, it's okay. The creation of the window is no surprise; we use the method NewL(). If there is no exception, the window is ready to go and we simply show it on screen:

iWindow = cDWindow::NewL(iSettings,lSkin);
iWindow->Show();

The last statement inside the try block, must be a call to the method UnWind(). This will un-prepare the cleanup stack and all the objects still present on the stack will be destroyed:

sCleanupStack::UnWind();
} catch (uException &lException) {

If an exception is raised in the try block, we will be displaying the exception information and request the application to terminate:

Once the application object is created, we parse the command line arguments then ask the application to run. Once this is done, we just wait for it to end using the WaitEnd() method. The class sArgs requires a cCan object in order to parse the command line. We create one on the stack.

Throughout this article, we have been using the static class sEnv a couple of times. This is an handy static class which provides access to various useful methods, such as PrintToStream(), LeaveIfError() or ErrorToString(). The latter method transforms an error code into a human readable string.