444. How to set up menu and toolbars using GtkAction - Part 1?

Problem

If you have followed the previous few articles on GtkAction, in particular How to set up toolbar using GtkAction - Part 2 - add accelerators? and How to set up menu using GtkAction - Part 3 - add accelerators with labels? did they get you excited about using GtkAction?

If you think about it, the menu items and toolbars are actually overlapping in functions. Both allow the users to select some functions. They just appear in different forms

Solution

We use exactly the same techniques as outlined in How to set up toolbar using GtkAction - Part 2 - add accelerators? and How to set up menu using GtkAction - Part 3 - add accelerators with labels?


Sample Code

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   
30   
31   
32   
33   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
53   
54   
55   
56   
57   
58   
59   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
72   
73   
74   
75   
76   
77   
78   
79   
81   
84   
85   
86   
87   
88   
89   
90   
91   
92   
93   
94   
95   
96   
97   
98   
99   
100   
101   
102   
104   
105   
106   
107   
108   
109   
111   
112   
113   
114   
115   
116   
117   
118   
119   
120   
121   
122   
123   
124   
125   
126   
127   
128   
129   
130   
132   
133   
134   
135   
136   
<?php
$window = new GtkWindow();
$window->set_title($argv[0]);
$window->set_size_request(400, 175);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());
$accel_group = new GtkAccelGroup();
$window->add_accel_group($accel_group);
$actiongrp = new GtkActionGroup('toolbar');

// global definitions for both menu and toolbar items
$global_definitions = array( // note 1
'file_new' => '_New|N',
'file_open' => '_Open|O',
'file_close' => '_Close',
'file_save' => '_Save|S',
'file_saveas' => 'Save _As',
'file_quit' => '_Quit',
'edit_cut' => 'Cut|X',
'edit_copy' => 'Copy|C',
'edit_paste' => '_Paste|V',
'edit_selectall' => 'Select All|A',
'edit_undo' => '_Undo|Z',
'edit_redo' => '_Redo|Y',
'<hr>' => '<hr>'
);

// define menu definition
$menu_definition = array( // note 2
    '_File' => array('file_new', 'file_open', 'file_close', '<hr>',
                    'file_save', 'file_saveas', '<hr>', 'file_quit'),
    '_Edit' => array('edit_cut', 'edit_copy', 'edit_paste', '<hr>',
                    'edit_selectall', '<hr>', 'edit_undo', 'edit_redo'),
);

$toolbar_definition = array( // note 3
'toolbar' => array('file_new', 'file_open', 'file_save', '<hr>',
                    'edit_cut', 'edit_copy', 'edit_paste', '<hr>',
                    'edit_undo', 'edit_redo'),
);

setup_action($vbox, $menu_definition); // note 4
setup_action($vbox, $toolbar_definition); // note 5

// display title
$title = new GtkLabel("Set up menus and toolbars using GtkAction - Part 1");
$title->modify_font(new PangoFontDescription("Times New Roman Italic 10"));
$title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
$vbox->pack_start($title);
$vbox->pack_start(new GtkLabel(''));

$window->show_all();
Gtk::main();

function setup_action($vbox, $definition) {
    if (isset($definition['toolbar'])) {
        $toolbar = new GtkToolBar();
        $toolbar->set_show_arrow(false);
        $vbox->pack_start($toolbar, 0, 0);
    } else {
        $menubar = new GtkMenuBar();
        $vbox->pack_start($menubar, 0, 0);
    }

    foreach($definition as $toplevel => $sublevels) {
        if ($toplevel != 'toolbar') {
            $menubar->append($top_menu = new GtkMenuItem($toplevel));
            $menu = new GtkMenu();
            $top_menu->set_submenu($menu);
        }

        foreach($sublevels as $item_id) {
            global $global_definitions;
            $item = $global_definitions[$item_id]; // note 6
            if (strpos("$item", '|') === false) {
                $accel_key = '';
            } else {
                list($item, $accel_key) = explode('|', $item);
            }

            if ($item=='<hr>') {
                if ($toplevel == 'toolbar') {
                    $toolbar->insert(new GtkSeparatorToolItem(), -1);
                } else {
                    $menu->append(new GtkSeparatorMenuItem());
                }
            } else {
                $item2 = str_replace('_', '', $item);
                $item2 = str_replace(' ', '_', $item2);
                $stock_image_name = 'Gtk::STOCK_'.strtoupper($item2);
                $stock_image = '';
                if (defined($stock_image_name))
                $stock_image = constant($stock_image_name);

                $action = new GtkAction($item, $item, '', $stock_image);

                global $accel_group, $actiongrp;
                if ($accel_key!='') {
                    $accel = "<control>$accel_key";
                    $actiongrp->add_action_with_accel($action, $accel);
                    $action->set_accel_group($accel_group);
                    $action->connect_accelerator();
                }

                if ($toplevel == 'toolbar') {
                    $toolitem = $action->create_tool_item();
                    $toolbar->insert($toolitem, -1);
                } else {
                    $menu_item = $action->create_menu_item();
                    $menu->append($menu_item);
                }
                $action->connect('activate', 'on_item_select', $item);
            }
        }
    }
}

// process toolbar
function on_item_select($button, $item) {
    echo "item selected: $item\n";
    if ($item=='_Quit') Gtk::main_quit();
}

?>

Output

As shown above.
 

Explanation

  1. The global definitions for menu and toolbar items.
  2. The menu definition.
  3. The toolbar definition.
  4. First set up the menu.
  5. Then set up the toolbar.
  6. Get the menu/toolbar definition from the global definitions.

Related Links

Add comment


Security code
Refresh