058. How to run multiple applications in multiple windows - Part 2?

Solution

We use exactly the same method as we have outlined in Part 1 with the use of GtkDialog.

The main menu is added as another dialog too.

Note the new features in this version:

  • The five modules (including the main menu) each now has different window size.
  • The application now "traps" the window close event. If you close the window in any of the four application modules, the user will be returned to the main menu. The applicatin window is not closed, but only hidden. In Part 1, closing the window will exit the application entirely.
  • You can exit the application by closing the main menu window, or by pressing F12.

Sample Code for PHP GTK

Note: If you have installed php-gtk2 using Gnope Installer on Windows, and if running the sample code below gives you warning that the Symbolic names for keys (e.g. Gdk::KEY_Return) is not defined, you might want to update your php-gtk2 with the latest php-gtk2.dll available here. Simply download the php-gtk2.dll and replace the copy in the folder php-gtk2xt. The latest compilation has put in the Symbolic names for keys listed here.

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
36   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
60   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
74   
75   
76   
81   
82   
84   
86   
87   
88   
89   
90   
91   
92   
93   
94   
95   
96   
97   
98   
99   
100   
101   
102   
103   
104   
105   
106   
107   
108   
109   
<?php
$modules = array("main", "sales", "purchase", "inventory", "finance"); // names of the modules
$module_size = array(array(400,200), array(600,400), array(200,100), array(720,640), array(480,360)); // size of each module window

$i=0;
foreach($modules as $module) {
    $apps[$module] = setup_app($module, $module_size[$i]);
    ++$i;
}
$apps['main']->show_all(); // show the main menu
$apps['main']->run(); // let's go!

// setup_app
function setup_app($module, $window_size) {
    $dialog = new GtkDialog($module, null, Gtk::DIALOG_MODAL);
    $dialog->set_position(Gtk::WIN_POS_CENTER_ALWAYS);
    $dialog->set_size_request($window_size[0], $window_size[1]);
    $top_area = $dialog->vbox;
    if ($module=='main') {
        $top_area->pack_start(new GtkLabel("this is main menu"));
        $top_area->pack_start(new GtkLabel("Press F12 to quit"));
    } else {
        $top_area->pack_start(new GtkLabel("this is $module module"));
        $top_area->pack_start(new GtkLabel("Press F12 to return to main menu"));
        $top_area->pack_start(new GtkLabel("or just close the window"));
    }
    $top_area->pack_start(new GtkLabel()); // used to "force" the button to stay at bottom
    if ($module=='main') show_buttons($top_area, $module); // shows the buttons at bottom of windows
    $dialog->set_has_separator(false);

    $dialog->connect('delete-event', "on_delete_event", $module); // note 1
    $dialog->connect('key-press-event', "on_key", $module); // catch F12

    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) {
        if ($module=='main') continue;
        $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
    }
    $apps[$activated_module]->run();
}

//process window close event
function on_delete_event($widget, $event, $module) {
    global $apps;
    if ($module=='main') { 
// exit app if in main menu
        return false;
    } else { 
// not in main menu
        $apps[$module]->hide(); // hide the module
        $apps['main']->show_all(); // show the main menu
        $apps['main']->run();
        return true;
    }
}


function on_key($widget, $event, $module) {// note 2
    global $apps;
    if ($event->keyval==Gdk::KEY_F12) {
        if ($module=='main') {
            $apps['main']->destroy();
        } else {
            $apps[$module]->hide();
            $apps['main']->show_all(); // show the first module
            $apps['main']->run(); // let's go!
        }
    }
}

?>

Output for PHP GTK

As shown above.

 

Explanation for PHP GTK

  1. When the user clicks window close, the signal GtkWidget::delete-event() is generated.
  2. The event handler function on_key() is exactly doing the same thing as function cf_delete_event() - exit application if in main_menu. Otherwise, return to main menu.

Note

If you would like to have an object-oriented version of this example using classes, please refer to Application Template 02 - multiple modules in multiple window + main menu.

Related Articles

Add comment


Security code
Refresh