Using windows

Disko comes with its own idea of window management, to keep it simple in aproach and to generate usage constraints that seem feasible to us. This section deals with the different window types and how they should be used properly.

To download the code for this tutorial, fetch it from the git-repository by issuing:

git clone git://www.diskohq.org/disko-tutorials.git

Then you can follow this part by having a look at the tutorials firststeps/04 folder.

Window stack

Disko knows three types of Windows. RootWindow, MainWindow and PopupWindow. Each type is treated differently within disko. These window types have a fixed Z-order. The management and placement is automatically dealt with by the window manager. window stack

The RootWindow ist the lowest type of window. On top of this window can reside a MainWindow. The PopupWindow can reside above a RootWindow and/or a MainWindow. Only one RootWindow and MainWindow can be shown on the screen at the same time. If another RootWindow is to be shown, the current one is removed by the window manager. The same goes for the MainWindow type. PopupWindows do not displace each other, but they have only a short lifetime, as they are removed automatically from the screen after a certain timeout is reached.

The RootWindow should be used for one of the applications main functions. In a mediacenter application there are some functions that make very little sense to be used together. Watching TV and listening to some music at the same time would not go very well together. Using RootWindows would at least ensure that you can't see both functions at the same time. The playback though has to be "manually" stopped on window removal.

The MainWindow is used when a main function could be safely combined with some extra functionality. Looking at the mediacenter application again, this could be reading the weather report during a commercial while watching TV. You would expect, that this could be done while TV is running. The MainWindow would be placed above the "TV" - Rootwindow, and would be removed on users demand, or when another "extra" function is called, like the stock market news.

The PopupWindow is used when information is presented to the user. That could be the notification that a new email arrived, or an alert that a specific TV-show or whatever occured. The information-lifetime is bound to the PopupWindow. It will close on users demand, or when its defined timeout is reached.

Disko supports a special RootWindow. This is the background window which will be displayed if no other RootWindow is shown. To configure the background window you have to insert a class with name="background_rootwindow" and type="rootwindow" into your theme.xml file like this:

<mmstheme name="default">
    <class
           name      = "background_rootwindow"
           type      = "rootwindow"
           alignment = "center"
           w         = "100%"
           h         = "100%"
           bgcolor   = "#ff0000ff"
           opacity   = "255"
    />
</mmstheme>

This defines a red background window.

To see the window management in action, you can have a look at Morphine.TV, which is a mediacenter application built on top of the disko framework.

Child windows

ChildWindows are windows that reside within other windows. They could be a part of a RootWindow, a MainWindow or a PopupWindow. This window type offers a free placement and movement unlike the relative fixed widget structures. For example when there is a need of replacing a widget on the screen by another one. Another example could be a playlist that is replaced by a visualization during music playback. child windows

The window placement is normally definend in a dialog XML-file, but could be set at runtime as well. Each window can be individually shown/hidden by the program, to decide which window should be shown in case that they should be used at the same spot.

An example

In this example we will load and show four windows. Two of them are RootWindows, which will displace each other when they are shown. The other two windows (window2 and window4) are MainWindows. The last one (window4) displays several child windows in an show/hide sequence.

As we do not use some of the other disko facilities mmsInit() is still be used to just initialize the window manager and the input manager so we can correctly stop our application.

mmsInit(MMSINIT_WINDOWS, argc, argv, "./diskorc.xml",
        "Disko Tutorial: firststeps/04", "DT: firststeps/04");

We are using four DialogManager objects to handle the different windows.

// one dialog manager for each window loaded from xml
MMSDialogManager dm;
MMSDialogManager dm2;
MMSDialogManager dm3;
MMSDialogManager dm4;

// load the windows
MMSWindow *window  = dm.loadDialog("./root.xml");
MMSWindow *window2 = dm2.loadDialog("./main.xml");
MMSWindow *window3 = dm3.loadDialog("./root2.xml");
MMSWindow *window4 = dm4.loadDialog("./main2.xml");

// start show sequence of the main/root windows
window->show();
sleep(2);
window2->show();
sleep(2);
window3->show();
sleep(2);

If everything went well, you will see a gray picture (window). After 2 seconds a window (window2) should fade in. Another 2 seconds later the gray picture should be replaced by a blue one (window will be hidden and window3 will be shown). screenshot

At last the program shows the window4 which includes four child windows. With a show/hide sequence different show/hide actions will be presented.

window4->show();
sleep(2);

// now we get access to the child windows of the window4
MMSChildWindow *childwin1 = dynamic_cast<MMSChildWindow*>(
		window4->searchForWindow("childwin1"));
MMSChildWindow *childwin2 = dynamic_cast<MMSChildWindow*>(
		window4->searchForWindow("childwin2"));
MMSChildWindow *childwin3 = dynamic_cast<MMSChildWindow*>(
		window4->searchForWindow("childwin3"));
MMSChildWindow *childwin4 = dynamic_cast<MMSChildWindow*>(
		window4->searchForWindow("childwin4"));

// until user press <ctrl+c> or <power> button on the remote control
while (1) {
    childwin1->hide();
    sleep(2);
    childwin1->show();
    sleep(2);
    childwin2->hide();
    sleep(2);
    childwin2->show();
    sleep(2);
    childwin3->hide();
    sleep(2);
    childwin3->show();
    sleep(2);
    childwin4->show();
    sleep(2);
    childwin4->hide();
    sleep(2);
}

return 0;