046. How to run multiple applications in multiple windows - Part 1?

Problem

Suppose we have four modules in an application - Sales, Purchase, Inventory and Finance. You would like to run these four modules in multiple windows as shown below:

How to run multiple applications in multiple windows - Part 1?


Solution

There are many ways to set up multiple applications to run in multiple windows in php gtk.

The solution presented here make use of GtkDialog. Note that a GtkDialog is a subclass of GtkWindow. So by nature, it is a GtkWindow and can do everything that a GtkWindow can do.

Here are the steps:

  • Create each application or module in a GtkDialog of its own.
  • Store the ID of each dialog somewhere.
  • As long as you don't destroy the dialog, each dialog will be happily living in a window of its own.
  • You can hide or show each application by using $dialog->hide_all() or $dialog->show_all().
  • When user wants to switch to a different application, you activate the desired application by using $dialog->run().

Sample Code

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
60   
61   
<?php

$modules = array("sales", "purchase", "inventory", "finance"); // names of the modules
foreach($modules as $module) {
    $apps[$module] = setup_app($module); // note 1
}
$apps['sales']->show_all(); // show the first module
$apps['sales']->run(); // let's go!

// setup_app
function setup_app($module) {
    $dialog = new GtkDialog($module, null, Gtk::DIALOG_MODAL);
    $dialog->set_position(Gtk::WIN_POS_CENTER_ALWAYS);
    $dialog->set_size_request(400, 200);
    $top_area = $dialog->vbox;
    $top_area->pack_start(new GtkLabel("this is $module module"));
    $top_area->pack_start(new GtkLabel()); // used to "force" the button to stay at bottom
    show_buttons($top_area, $module); // shows the buttons at bottom of windows
    $dialog->set_has_separator(false);
    return $dialog; // returns the ID of the dialog
}

// shows the buttons at bottom of windows
function show_buttons($vbox, $current_module) {
    global $modules;
    $hbox = new GtkHBox();
    $vbox->pack_start($hbox, 0, 0);
    $hbox->pack_start(new GtkLabel());
    foreach($modules as $module) {
        $button = new GtkButton(strtoupper(substr($module,0,1)).substr($module,1)); // cap 1st letter
        $button->set_size_request(80, 32); // makes all button the same size
        if ($module == $current_module) { // sets the color of the respective button
            $button->modify_bg(Gtk::STATE_NORMAL, GdkColor::parse("#95DDFF"));
            $button->modify_bg(Gtk::STATE_ACTIVE, GdkColor::parse("#95DDFF"));
            $button->modify_bg(Gtk::STATE_PRELIGHT, GdkColor::parse("#95DDFF"));
        }
        $hbox->pack_start($button, 0, 0);
        $hbox->pack_start(new GtkLabel());
        $button->connect('clicked', 'on_clicked', $module); // event handler to handle button click
    }
}

// process button click
function on_clicked($button, $activated_module) {
    global $apps, $modules;
    print "button_clicked: $activated_module\n";
    $apps[$activated_module]->show_all(); // show the activated module
    foreach($modules as $module) {
        if ($module!=$activated_module) $apps[$module]->hide_all(); // hide all others
    }
    //foreach($modules as $module) $apps[$module]->show_all(); //note 2
    $apps[$activated_module]->run();
}

?>

Output

As shown above.

 

Explanation

  1. Setup each module in a window (or dialog) of its own. Here we store the ID of each dialog in the global array $apps.
  2. See notes below.

Note

Note that the code above only show one dialog at a time, hiding all the other "inactive" dialogs. That's why you see only one dialog:

Try uncommenting the line labeled note 2 above. Now all the dialogs are visible, though they are sitting on top of each other. You can move the dialog away from each other to get this:

How to run multiple applications in multiple windows - Part 1?

However, please bear in mind that although you can see all four dialog windows now, only one is active at one time. The active dialog will be the last dialog that you execute the command $dialog->run. Once you execute this command, that dialog will take control. All keyboard inputs will only go to this dialog, even though other dialogs are visible.

Also, note that in this version, if you close the window in any of the four modules, the entire application will exit. We will fix this, add also add a main menu in Part 2.

p.s. If you would like to have an object-oriented version of this example using classes, please refer to Application Template 01 - multiple modules in multiple windows.

Related Articles

Add comment


Security code
Refresh