Chapter 8. Gtk2::MessageDialog

Objective

The use of messages that pops up are very common in GUI programming. It can be used to give a warning, informing the user of something, asking the user a simple question, and expecting an answer to that question.

This lesson is a demo, showing the use and capabilities of the Gtk2::MessageDialog class.

Table 8-1. Gtk2 object classes used

Gtk2 Class Name
Gtk2::Window
Gtk2::VBox
Gtk2::Button
Gtk2::HSeparator
Gtk2::Label
Gtk2::MessageDialog

Table 8-2. Special Classes used

Gtk2 Class Name
Glib::MainLoop
Glib::Type

Method of implementation

We will implement the following steps in the program:

  1. Create the main window, adding a Gtk2::VBox containing three buttons, a horizontal separator, and a label.

  2. Utilize the Glib::MainLoop's Glib::Timeout method to make the label in the main window flash.

  3. When the top button is clicked, it will loop through a list of possible Gtk2::MessageDialog types, showing each one.

    The Gtk2::MessageDialog's message will be in plain text. When the user responded to the Gtk2::MessageDialog, the label in the main window will report the kind of response.

  4. When the middle button is clicked, it will again loop through a list of possible Gtk2::MessageDialog types, showing each one.

    The Gtk2::MessageDialog's message will be using Pango Markup text. When the user responded to the Gtk2::MessageDialog, the label in the main window will report the kind of response.

  5. When the bottom button is clicked, it will loop through a list of possible Gtk2::MessageDialog buttons showing each one.

    The Gtk2::MessageDialog's message will be using Pango Markup text. When the user responded to the Gtk2::MessageDialog, the label in the main window will report the kind of response.

The screenshot

Figure 8-1. Gtk2::MessageDialog

8.1. The Code

The program can be found here: 'Message Demo'

  
  1 #! /usr/bin/perl -w
  2 
  3 use strict;
  4 use Glib qw/TRUE FALSE/;
  5 use Gtk2 '-init'; 
  6 
  7 #create a label that may be changed from various places
  8 my $label_feedback;
  9 
 10 #standard window creation, placement, and signal connecting
 11 my $window = Gtk2::Window->new('toplevel');
 12 $window->signal_connect('delete_event' => sub { Gtk2->main_quit; });
 13 $window->set_border_width(5);
 14 $window->set_position('center_always');
 15 
 16 #this vbox will return the bulk of the gui
 17 my $vbox = &ret_vbox();
 18 
 19 #add and show the vbox
 20 $window->add($vbox);
 21 $window->show();
 22 
 23 #create a flasher for the label, we will show or hide it every 1 second
 24 my $flash = 1;
 25 Glib::Timeout->add (1000,sub{ &flash_label() });
 26 
 27 #our main event-loop
 28 Gtk2->main();
 29 
 30 
 31 sub ret_vbox {
 32 
 33 #create a vbox to pack the following widgets
 34 my $vbox = Gtk2::VBox->new(FALSE,5);
 35 
 36 	
 37 	$label_feedback = Gtk2::Label->new();
 38 	$label_feedback->set_markup("<span foreground=\"blue\" size=\"x-large\">Response from Gtk2::Dialog's 'run' method:\n</span><span weight='heavy' size = '20000' foreground = 'forestgreen' style ='italic'> \n</span>");
 39 	
 40 #Label at the bottom of the VBox	
 41 $vbox->pack_end($label_feedback,FALSE,FALSE,4);
 42 #On top of that, a HSeparator
 43 $vbox->pack_end(Gtk2::HSeparator->new(),FALSE,FALSE,4);
 44 
 45 	my $btn_start = Gtk2::Button->new("Show MESSAGE types - Parent = 'undef'");
 46 	#we start an anonymous sub when the button is clicked
 47 	$btn_start->signal_connect('clicked' => sub { 
 48 		#we ask Glib to give a list of values for Gtk2::MessageType.
 49 		#Each value of the list is a hash with keys "name" and "nick",
 50 		#we then use the value of "nick" to specify the type to show.
 51 		foreach my $m_type (Glib::Type->list_values ('Gtk2::MessageType')){
 52 			&show_message_dialog(undef,$m_type->{'nick'},"Message type:\n$m_type->{'nick'}\nNow Showing!\n\n<sub><u>Invoked it by:\n</u><span foreground='SteelBlue'>Gtk2::MessageDialog->new (undef,
 53 					[qw/modal destroy-with-parent/],
 54 					<span foreground='forestgreen'>$m_type->{'nick'},</span>
 55 					'ok',
 56 					\"(Text goes here)\");</span></sub>",'ok');
 57 					
 58 		}
 59 	});
 60 $vbox->pack_start($btn_start,FALSE,FALSE,4);
 61 
 62 	my $btn_markup = Gtk2::Button->new("Show MESSAGE types\n-With Pango Markup-");
 63 	#we start an anonymous sub when the button is clicked
 64 	$btn_markup->signal_connect('clicked' => sub { 
 65 		#we ask Glib to give a list of values for Gtk2::MessageType.
 66 		#Each value of the list is a hash with keys "name" and "nick",
 67 		#we then use the value of "nick" to specify the type to show.
 68 		foreach my $m_type (Glib::Type->list_values ('Gtk2::MessageType')){
 69 			&show_message_dialog($window,$m_type->{'nick'},"<span foreground=\"blue\" size=\"x-large\">Message Type\n</span><span weight='heavy' size = '20000' foreground = 'red' style ='italic'>$m_type->{'nick'}\n</span><sub><tt>Now Showing!\n\n</tt></sub><sub><u>Invoked it by:\n</u><span foreground='SteelBlue'>Gtk2::MessageDialog->new_with_markup (\$window,
 70 					[qw/modal destroy-with-parent/],
 71 					<span foreground='forestgreen' >$m_type->{'nick'},</span>
 72 					'ok',
 73 					\"(markup goes here)\");</span></sub>",'ok');
 74 		
 75 		}
 76 	});
 77 	
 78 $vbox->pack_start($btn_markup,FALSE,FALSE,4);
 79 
 80 my $btn_button_types = Gtk2::Button->new("Show BUTTON types");
 81 
 82 	#we start an anonymous sub when the button is clicked
 83 	$btn_button_types->signal_connect('clicked' => sub { 
 84 		#we ask Glib to give a list of values for Gtk2::ButtonsType.
 85 		#Each value of the list is a hash with keys "name" and "nick",
 86 		#we then use the value of "nick" to specify the button to show.
 87 		foreach my $b_type (Glib::Type->list_values ('Gtk2::ButtonsType')){
 88 			my $b_type_nick = $b_type->{'nick'};
 89 			&show_message_dialog($window,'info',"<span foreground=\"blue\" size=\"x-large\">Button Type\n</span><span weight='heavy' size = '20000' foreground = 'red' style ='italic'>$b_type_nick\n</span><sub><tt><u>Now Showing!\n\n</u></tt></sub><sub><u>Invoked it by:\n</u><span foreground='SteelBlue'>Gtk2::MessageDialog->new_with_markup (\$window,
 90 					[qw/modal destroy-with-parent/],
 91 					'info',
 92 					<span foreground='forestgreen' >\"$b_type_nick\",</span>
 93 					\"(markup goes here)\");</span></sub>",$b_type_nick);
 94 		
 95 		}
 96 	});
 97 	
 98 $vbox->pack_start($btn_button_types,FALSE,FALSE,4);
 99 
100 $vbox->show_all();
101 
102 return $vbox;
103 
104 }
105 
106 sub show_message_dialog {
107 
108 #THIS IS THE MAIN FEATURE OF THE APP:
109 #you tell it what to display, and how to display it
110 #$parent is the parent window, or "undef"
111 #$icon can be one of the following:	a) 'info'
112 #					b) 'warning'
113 #					c) 'error'
114 #					d) 'question'
115 #$text can be pango markup text, or just plain text, IE the message
116 #$button_type can be one of the following: 	a) 'none'
117 #						b) 'ok'
118 #						c) 'close'
119 #						d) 'cancel'
120 #						e) 'yes-no'
121 #						f) 'ok-cancel'
122 
123 my ($parent,$icon,$text,$button_type) = @_;
124  
125 my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
126 					[qw/modal destroy-with-parent/],
127 					$icon,
128 					$button_type,
129 					sprintf "$text");
130 		
131 	#this will typically return certain values depending on the value of $retval.
132 	#in this application, we only change the label's value accordingly								
133 	my $retval = $dialog->run;
134 	$label_feedback->set_markup("<span foreground=\"blue\" size=\"x-large\">Response from Gtk2::Dialog's 'run' method:\n</span><span weight='heavy' size = '20000' foreground = 'forestgreen' style ='italic'>$retval\n</span>");
135 	#destroy the dialog as it comes out of the 'run' loop	
136 	$dialog->destroy;
137 }
138 
139 sub flash_label {
140 #label flasher
141 ($flash)&&($label_feedback->hide());
142 ($flash)||($label_feedback->show());
143 $flash = !($flash);
144 return TRUE;
145 
146 }