510. How to set up toolbar using GtkAction with custom toolbar icons?

Problem

This is in response to Kovu's post titled "Custom Toolbar Icons (not from stock!)"

He would like to set up a toolbar using GtkAction. However, instead of using the stock images, he would like to set his own toolbar icons (say, from a pix buffer) as shown below.

To see GtkAction in action, click the last two toolbuttons 'Grp 1' and 'Grp 2'. When you click 'Grp 1', the first three tool buttons will be activated. When you click 'Grp 2', the Start and Stop buttons will be activated.

How to set up toolbar using GtkAction with custom toolbar icons?


Solution


Sample Code

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.

 button_start32.gif
 button_stop32.gif
 ball_blue16.png
 ball_green16.png

1   
2   
3   
4   
5   
6   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
20   
21   
22   
23   
24   
25   
26   
28   
29   
30   
31   
32   
33   
34   
35   
37   
39   
40   
41   
42   
43   
44   
46   
47   
48   
49   
50   
51   
52   
53   
54   
55   
60   
61   
66   
68   
69   
71   
72   
73   
74   
75   
77   
78   
79   
80   
81   
82   
84   
85   
86   
87   
88   
89   
90   
92   
94   
95   
96   
97   
98   
99   
100   
101   
102   
103   
104   
<?php
$window = new GtkWindow();
$window->set_title($argv[0]);
$window->set_size_request(400, 200);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

$action_grp = array(); // note 1
$action_grp[0] = new GtkActionGroup("Grp0"); // note 1
$action_grp[1] = new GtkActionGroup("Grp1"); // note 1
$action_grp[2] = new GtkActionGroup("Grp2"); // note 1

// define menu definition
$toolbar_definition = array('New[1]', 'Open[1]', 'Save[1]', '<hr>', // note 2
    'button_start32.gif|Start[2]', 'button_stop32.gif|Stop[2]', '<hr>',
    'ball_blue16.png|Grp 1', 'ball_green16.png|Grp 2');
setup_toolbar($vbox, $toolbar_definition);

// display title
$title = new GtkLabel("     Set up Toolbar using GtkAction\n".
"with your own custom toolbar icons");
$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 toolbar
function setup_toolbar($vbox, $toolbar_definition) {
    $toolbar = new GtkToolBar();
    $vbox->pack_start($toolbar, 0, 0);
    foreach($toolbar_definition as $item) {
        $grp_num = 0;
        if (preg_match('/(.*)\[(\d+)\]$/', $item, $matches)) { // note 3
            $item = $matches[1];
            $grp_num = $matches[2]; // note 3
        }

        if ($item=='<hr>') {
            $toolbar->insert(new GtkSeparatorToolItem(), -1);
        } else {

            $stock_image_name = 'Gtk::STOCK_'.strtoupper($item);

            if (defined($stock_image_name)) {
                $label = $item;
                $img = GtkImage::new_from_stock( // note 4
                constant($stock_image_name), Gtk::ICON_SIZE_BUTTON); 
            } elseif (preg_match('/\.(png|gif|jpg)/', $item)) {
                list($img_name, $label) = explode('|', $item);
                $img=GtkImage::new_from_file($img_name); // note 5
            }

            $img->show();
            $toolbar_item = new GtkToolButton($img, $label); // note 6
            $toolbar->insert($toolbar_item, -1); // note 6

            global $action_grp;
            $action = new GtkAction($label, '_'.$label, '', ''); // note 7
            $action->connect_proxy($toolbar_item); // note 8
            $action->connect('activate', "on_toolbar_button", $label);
            $action_grp[$grp_num]->add_action($action); // note 9

        }
    }
}

// process toolbar
function on_toolbar_button($button, $item) {
    echo "toolbar clicked: $item\n";
    global $action_grp;
    if ($item=='Grp 1') { // note 10
        $action_grp[1]->set_sensitive(true);
        $action_grp[2]->set_sensitive(false);
    } elseif ($item=='Grp 2') { // note 10
        $action_grp[1]->set_sensitive(false);
        $action_grp[2]->set_sensitive(true);
    }
}

?>

Output

As shown above.
 

Explanation

We make use of the code from How to set up toolbar with custom toolbar icons?

What's new here:

  1. For this example, we set up three Action groups. The first three tool buttons (File New, Open and Save) belong to $action_grp[1]. The Start and Stop tool buttons belong to $action_grp[2]. All others belong to $action_grp[0].
  2. This is the toolbar definition. You can intermix stock image with custom images. For custom images, the first part is the image filename, and the second part is the label, delimited by '|'. To designate the action group, add to the end of each tool button definition the group number enclosed in square brackets, e.g. 'New[1]' will place the File-New tool button in $action_grp[1]. 'button_start32.gif|Start[2]' will place the Start button in $action_grp[2].
  3. Note how we retrieve the group number.
  4. Load the stock image.
  5. Load the custom image.
  6. Create a tool button using custom image and insert it into the toolbar.
  7. Create a new action.
  8. Binds the tool button to the action.
  9. Adds the action to the respective action group.
  10. Activate the respective action group depending on which tool button the user clicks.

Note

You might want to compare this with that of How to set up toolbar with custom toolbar icons? to see where are the similarities and differences. It will give you a clearer understanding of how to use GtkAction.

Once you get used to the concept of GtkAction, you'll find that it will help save you a lot of coding when you need to activate and deactivate a bunch of tool buttons or menuitems depending on which state the user is in.

More consistency, less coding, easier maintenance.

Related Links

Add comment


Security code
Refresh