402. How to set up menu with images as menu items - Part 2 - image only?

Problem

Suppose you would like to set up menu with images (e.g. standard .gif, .jpg or .png image files) as menu items. In Part 1, each menu item comprises an image + a label. In this Part 2, each menu item contains only an image (without the label) as shown below

How to set up menu with images as menu items - Part 2 - image only?


Solution


Sample Code

Note: The following image files are required by the sample code below. Please save a copy of the image files and put them in the same directory where you store the sample code.

 square_yellow.jpg
 square_green.jpg
 square_blue.jpg

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
50   
51   
52   
53   
54   
56   
57   
58   
59   
60   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
73   
75   
76   
77   
78   
79   
80   
81   
82   
83   
84   
85   
86   
88   
95   
96   
97   
98   
102   
103   
104   
105   
106   
107   
108   
109   
110   
111   
112   
114   
115   
116   
117   
118   
119   
120   
125   
126   
127   
128   
129   
130   
131   
132   
134   
135   
136   
137   
138   
139   
140   
141   
142   
143   
147   
148   
149   
150   
151   
152   
<?php
$window = new GtkWindow();
$window->set_title($argv[0]);
$window->set_size_request(400, 150);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());
$accel_group = new GtkAccelGroup(); // create a new accelerator
$window->add_accel_group($accel_group); // attach it to the window

// define menu definition
$menu_definition = array(
    '_File' => array('_New|N', '_Open|O', '_Close|C', '<hr>',
                    '_Save|S', 'Save _As','<hr>', '_Quit'),
    '_Edit' => array('Cut|X', 'Copy|C', '_Paste|V', '<hr>',
                    'Select All|A', '<hr>', '_Undo|Z'),
    '_Test' => array('Test_1|1', 'Test_2|2', 'Test_3|3', '<hr>',
                array('Selection 1', 'Selection 2', 'Selection 3'),
                '<hr>', 'Test_4|4'),
    '_Background' => array('Yellow|Y', 'Green|G', 'Blue|B')
);

$image_files = array('Yellow' => 'square_yellow.jpg',
    'Green' => 'square_green.jpg',
    'Blue' => 'square_blue.jpg');
setup_menu($vbox, $menu_definition);

// display title
$title = new GtkLabel("Menu with images as menu items - Part 2 (image only)");
$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();

// setup menu
function setup_menu($vbox, $menus) {
    global $accel_group;
    $menubar = new GtkMenuBar();
    $vbox->pack_start($menubar, 0, 0);
    foreach($menus as $toplevel => $sublevels) {
        $menubar->append($top_menu = new GtkMenuItem($toplevel));
        $menu = new GtkMenu();
        $top_menu->set_submenu($menu);
        foreach($sublevels as $submenu) {
            if (strpos("$submenu", '|') === false) {
                $accel_key = '';
            } else {
                list($submenu, $accel_key) = explode('|', $submenu);
            }

            if (is_array($submenu)) {
                $i=0;
                $radio[0] = null;
                foreach($submenu as $radio_item) {
                    $radio[$i] = new GtkRadioMenuItem($radio[0], $radio_item);
                    $radio[$i]->connect('toggled', "on_toggle");
                    $menu->append($radio[$i]);
                    ++$i;
                }
                $radio[0]->set_active(1); // select the first item
            } else {
                if ($submenu=='<hr>') {
                    $menu->append(new GtkSeparatorMenuItem());
                } else {
                    $submenu2 = str_replace('_', '', $submenu);
                    $submenu2 = str_replace(' ', '_', $submenu2);
                    $stock_image_name = 'Gtk::STOCK_'.strtoupper($submenu2);
                    if (defined($stock_image_name)) {
                        $menu_item = new GtkImageMenuItem(
                                        constant($stock_image_name));
                    } else {
                        if ($toplevel == '_Background') {
                            global $image_files;
                            $image_file = $image_files[$submenu];
                            $menu_item = setup_image_menuitem( 
                                            $submenu, $image_file); // note 1
                        } else {
                            $menu_item = new GtkMenuItem($submenu);
                        }
                    }
                    if ($accel_key!='') {
                        $menu_item->add_accelerator("activate", $accel_group,
                        ord($accel_key), Gdk::CONTROL_MASK, 1);
                    }

                    $menu->append($menu_item);
                    $menu_item->connect('activate', 'on_menu_select');
                }
            }
        }
    }
}

// setup menuitem with background color
function setup_image_menuitem($menuitem_label, $image_file) {
    $menu_item = new GtkMenuItem($menuitem_label);
    $label = $menu_item->child;
    $menu_item->remove($label); // note 2
    $hbox = new GtkHBox();
    $menu_item->add($hbox); // note 3
    $image = GtkImage::new_from_file($image_file); // note 4
    $hbox->pack_start($image, 0); // note 4
    $menu_item->set_data('label', $menuitem_label); // note 5
    return $menu_item;
}

// process radio menu selection
function on_toggle($radio) {
    $label = $radio->child->get_label();
    $active = $radio->get_active();
    echo("radio menu selected: $label\n");
}

// process menu item selection
function on_menu_select($menu_item) {
    if (method_exists($menu_item->child, 'get_label')) {
        $item = $menu_item->child->get_label();
        echo "menu selected: $item\n";
        if ($item=='_Quit') Gtk::main_quit();
    } elseif ($menu_item->child->get_name()=='GtkHBox') {
        $item = $menu_item->get_data('label'); // note 6
        echo "menu item (with image) selected: $item\n";
    }
}

?>

Output

As shown above.
 

Explanation

The above makes use of the code from How to set up menu with images as menu items - Part 1?

What's new here:

  1. Set up image menuitems.
  2. First remove the default GtkLabel.
  3. Then attach a GtkHBox.
  4. Load the image and stuff it into GtkHBox.
  5. Store the label corresponding to the image.
  6. Take note of how we retrieve back the label of the image menuitem.

Related Links

Add comment


Security code
Refresh