Chapter 17. Gtk2::Toolbar

Objective

Introducing the reader to Gtk2::Toolbar, and how it works.

17.1. Lesson

Modern GUI programs often feature a toolbar. It is convenient to have a place where often used or similar functions are grouped together. Another nice feature of toolbars is that they can be made to detach.

The Gtk+ widget class used to create a toolbar is called Gtk2::Toolbar. A Gtk2::Toolbar can contain instances of a subclass of Gtk2::ToolItem.

The Gtk2::ToolItem is a container widget. It has a few subclasses already created, but, should you require to add a different widget from those available, you can do so by using the Gtk2::Container's 'add' method.

Table 17-1. Available Gtk2::ToolItem subclasses

Gtk2 Class NameUse
Gtk2::SeparatorToolItemThis will give the appearance of a Gtk2::VSeparator inside the toolbar. Toolbar items can be visually grouped by adding instances of Gtk2::SeparatorToolItem to the toolbar. If a Gtk2::SeparatorToolItem has the "expand" property set to TRUE and the "draw" property set to FALSE the effect is to force all following items to the end of the toolbar.
Gtk2::ToolButtonThis is the equivalent of a Gtk2::Button. You can add an image to it, or use stock items.
Gtk2::ToggleToolButtonThis is the equivalent of a Gtk2::ToggleButton. It can be set active or not.
Gtk2::RadioToolButtonThis is the equivalent of a Gtk2::RadioButton. When it gets created, you define a group to which it belongs. At any given instance, only one Gtk2::RadioToolButton belonging to this group can be selected. Group them visually with Gtk2::SeparatorToolItems
Gtk2::MenuToolButtonThis will be used to add sub-menus to the toolbar. Make use of its 'set_menu' method to "attach" a menu to it.

We will create a demo program which incorporates all of these classes, so you can see them in action. The demo program will also feature the adding of a Gtk2::Entry widget to a Gtk2::ToolItem widget.

17.1.1. The Screenshot.

Figure 17-1. Toolbar

17.1.2. The Code.

The program can be found here: 'gtk2_toolbar.pl'

  1 #! /usr/bin/perl -w
  2 
  3 use strict;
  4 use Gtk2 '-init';
  5 use Glib qw/TRUE FALSE/; 
  6 
  7 my $tt = Gtk2::Tooltips->new();
  8 
  9 #standard window creation, placement, and signal connecting
 10 my $window = Gtk2::Window->new('toplevel');
 11 $window->signal_connect('delete_event' => sub { Gtk2->main_quit; });
 12 $window->set_border_width(5);
 13 $window->set_position('center_always');
 14 
 15 #this vbox will return the bulk of the gui
 16 my $vbox = &ret_vbox();
 17 
 18 #add and show the vbox
 19 $window->add($vbox);
 20 $window->show();
 21 
 22 #our main event-loop
 23 Gtk2->main();
 24 
 25 sub ret_vbox {
 26 
 27 my $vbox = Gtk2::VBox->new(FALSE,5);
 28 
 29 	#====================================
 30 	#The handle box helps in creating a detachable toolbar 
 31 	my $hb = Gtk2::HandleBox->new;
 32 	#create a toolbar, and do some initial settings
 33 	my $toolbar = Gtk2::Toolbar->new;
 34 	$toolbar->set_icon_size ('large-toolbar');
 35 	$toolbar->set_show_arrow (FALSE);
 36 	
 37 	#________
 38 	#Create a menu tool button that contains a simple menu.
 39 		my $t_mbtn_edit = Gtk2::MenuToolButton->new_from_stock('gtk-edit');
 40 		$t_mbtn_edit->set_menu (&ret_menu);
 41 					
 42 	$toolbar->insert($t_mbtn_edit,-1);
 43 	
 44 	#________
 45 	#Insert a separator tool item	
 46 	$toolbar->insert(Gtk2::SeparatorToolItem->new ,-1 );
 47 	
 48 	#________
 49 	#Create three radio tool buttons, radio btn "both"	
 50 		my $t_rbtn_both = Gtk2::RadioToolButton->new (undef);
 51 		$t_rbtn_both->set_label ('Both');
 52 		$t_rbtn_both->set_active(TRUE);
 53 		$t_rbtn_both->set_icon_widget (Gtk2::Image->new_from_file('./pix/tux.png'));
 54 		$t_rbtn_both->signal_connect('toggled', \&radio_toggled,$toolbar);
 55 		
 56 	$toolbar->insert($t_rbtn_both,-1); 
 57 	
 58 	#________
 59 	#radio btn "text"	
 60 		my $t_rbtn_text = Gtk2::RadioToolButton->new_from_widget($t_rbtn_both);
 61 		$t_rbtn_text->set_label ('Text');
 62 		$t_rbtn_text->set_icon_widget (Gtk2::Image->new_from_file('./pix/tux.png'));
 63 		$t_rbtn_text->signal_connect('toggled', \&radio_toggled,$toolbar);
 64 						
 65 	$toolbar->insert($t_rbtn_text,-1);
 66 	
 67 	#________
 68 	#radio btn "icon"
 69 		my $t_rbtn_icon = Gtk2::RadioToolButton->new_from_widget($t_rbtn_both);
 70 		$t_rbtn_icon->set_label ('Icons');
 71 		$t_rbtn_icon->set_icon_widget (Gtk2::Image->new_from_file('./pix/tux.png'));
 72 		$t_rbtn_icon->signal_connect('toggled', \&radio_toggled,$toolbar);
 73 		
 74 	$toolbar->insert($t_rbtn_icon,-1);
 75 	
 76 	#________
 77 	#Insert a separator tool item	
 78 	$toolbar->insert(Gtk2::SeparatorToolItem->new ,-1 );
 79 	
 80 	#________
 81 	#Insert a toggle tool button to toggle the "set_show_arrow" property
 82 		my $t_tbtn_arrow = Gtk2::ToggleToolButton->new_from_stock('gtk-go-down');
 83 		$t_tbtn_arrow->set_label ('Show Arrow');
 84 		$t_tbtn_arrow->signal_connect('toggled' => sub {
 85 		
 86 			($t_tbtn_arrow->get_active)&&($toolbar->set_show_arrow (TRUE));
 87 			($t_tbtn_arrow->get_active)||($toolbar->set_show_arrow (FALSE));		
 88 		});
 89 				
 90 	$toolbar->insert($t_tbtn_arrow,-1);
 91 	
 92 	#________
 93 	#Insert a separator tool item
 94 	$toolbar->insert(Gtk2::SeparatorToolItem->new ,-1 );
 95 	
 96 	#________
 97 	#Insert a toggle tool button to toggle the "set_tooltips" property
 98 		my $t_tbtn_tt = Gtk2::ToggleToolButton->new_from_stock('gtk-add');
 99 		$t_tbtn_tt->set_label ('Show Tooltips');
100 		$t_tbtn_tt->set_active(TRUE);
101 		$t_tbtn_tt->set_tooltip ($tt, "Toggle Tooltips on / off", "");
102 		$t_tbtn_tt->signal_connect('toggled' => sub {
103 		
104 			($t_tbtn_tt->get_active)&&($toolbar->set_tooltips (TRUE));
105 			($t_tbtn_tt->get_active)||($toolbar->set_tooltips (FALSE));		
106 		});
107 				
108 	$toolbar->insert($t_tbtn_tt,-1);
109 	
110 	#________
111 	#Insert a separator tool item
112 	$toolbar->insert(Gtk2::SeparatorToolItem->new ,-1 );
113 	#________
114 	#Insert a separator tool item that will be used as an empty space
115 		my $space = Gtk2::SeparatorToolItem->new;
116 		$space->set_draw(FALSE);
117 		$space->set_expand(TRUE);
118 		
119 	$toolbar->insert($space,-1 );
120 	
121 	#________
122 	#Insert a tool item containing an entry widget
123 		my $tool_item = Gtk2::ToolItem->new;
124 			my $ent = Gtk2::Entry->new;
125 		$tool_item->add($ent);
126 	
127 	$toolbar->insert($tool_item,-1);
128 	
129 	#________
130 	#Insert a standard tool button 	
131 		my $t_btn_find = Gtk2::ToolButton->new_from_stock ('gtk-find');
132 		$t_btn_find->set_tooltip ($tt, "Find yourself", "");
133 		
134 	$toolbar->insert($t_btn_find,-1);
135 	$hb->add($toolbar);
136 	#====================================
137 	
138 $vbox->pack_start($hb,FALSE,FALSE,0);
139 
140 	$vbox->show_all();
141 	
142 return $vbox;
143 }
144 
145 sub radio_toggled {
146 
147 	#this sub discovers which radio button is active and 
148 	#sets the toolbar's style accordingly
149 	my($widget,$toolbar) = @_;
150 	if ($widget->get_active){
151 	
152 		my $lbl = $widget->get_label;
153 		
154 		($lbl =~ m/Text/i)&&($toolbar->set_style('text'));
155 		($lbl =~ m/Icon/i)&&($toolbar->set_style('icons'));
156 		($lbl =~ m/Both/i)&&($toolbar->set_style('both'));
157 	
158 	}
159 }
160 
161 sub ret_menu {
162 
163 my $menu_edit = Gtk2::Menu->new();
164 	
165 $menu_edit->append(Gtk2::MenuItem->new('_Cut'));
166 $menu_edit->append(Gtk2::MenuItem->new('C_opy'));
167 $menu_edit->append(Gtk2::MenuItem->new('_Paste'));
168 	
169 $menu_edit->show_all();	
170 return $menu_edit;
171 	
172 }

17.1.3. Points of interest.

  • When you consult the man page of Gtk2::Toolbar, you will notice quite an amount of methods available to append items to it. These are deprecated methods, and should be avoided. The 'insert' method should now be used.

    $toolbar->insert ($item, $pos) 
    	* $item (Gtk2::ToolItem)
     	* $pos (integer)
    If $pos is 0 the item is prepended to the start of the toolbar. If $pos is negative, the item is appended to the end of the toolbar.

  • Gtk2::ToolItem's has its own way to set Gtk2::ToolTips. The standard way to set a tooltip on a widget is:

    $tooltips->set_tip ($widget, $tip_text, $tip_private=undef) 
    	* $widget (Gtk2::Widget)
    	* $tip_text (string)
    	* $tip_private (scalar)
    Gtk2::ToolItem's method is as follows:
    $tool_item->set_tooltip ($tooltips, $tip_text, $tip_private) 
    	* $tooltips (Gtk2::Tooltips)
    	* $tip_text (string)
    	* $tip_private (string)

  • A detachable Gtk2::Toolbar is created by adding it to a Gtk2::HandleBox. A Gtk2::HandleBox is just another container that can be used to pack widgets in to. The difference between it and typical containers is that it can be detached from a parent window (or, in fact, the Gtk2::HandleBox remains in the parent, but it is reduced to a very small rectangle, while all of its contents are reparented to a new freely floating window). It is usually nice to have a detachable toolbar, so these two widgets occur together quite often.

  • To add a space, we use the Gtk2::SeparatorToolItem widget, and use its 'set_draw' method and set the 'draw' property to FALSE. This will make it invisible. We also sets its 'expand' property to TRUE. This will cause it to take up free space.

  • The Gtk2::Toolbar features a style setting which change the appearance of the buttons in the Gtk2::Toolbar. Our demo toggles it via the Gtk2::RadioToolButtons, and gives you a choice between 'icons','text' or 'both'.

  • Setting the 'show_arrow' property of Gtk2::Toolbar to TRUE, will cause the Gtk2::Toolbar widget to shrink when there is not enough space available for it.

    To see it in action, detach the toolbox and toggle the "Show Arrow" button.

  • The 'set_tooltips' method of Gtk2::Toolbar will cause the Gtk2::Toolbar widget to hide or show tooltips belonging to the Gtk2::ToolItem widgets packed into it.

  • The Gtk+ documentation suggest that you should only pack widgets of type Gtk2::ToolItem into a Gtk2::Toolbar. To add a widget not available as a Gtk2::ToolItem subclass, create a Gtk2::ToolItem and the widget you which to add to the Gtk2::Toolbar. Now add the your widget to the Gtk2::ToolItem instance, and insert the Gtk2::ToolItem into the Gtk2::Toolbar.

Note

When you need to create and manage large menu structures, make use of Gtk2::UIManager ( Chapter 18 ). This replaces the deprecated Gtk2::ItemFactory.