Chapitre 15
Les dialogues

Le widget dialogue est très simple et n’est en fait qu’une fenêtre avec quelques éléments préemballés pour vous. Sont inclus dans le widget une fenêtre, une vbox et une action_area.

Une widget dialogue crée une fenêtre et regroupe une vbox dans le haut qui contient un séparateur et dessous une HBox appelée action_area. Pour créer une boîte de dialogue :

$dialog = Gtk2::Dialog->new();  
$dialog = Gtk2::Dialog->new($titre,$parent,$flags...);  
$dialog = Gtk2::Dialog->new_with_buttons($titre,$parent,$flags...);
Les deux dernières formes sont équivalentes et présentent l’avantage de déclarer le titre, les propriétés de la fenêtre, de placer les boutons en une seule étape.

Pour avoir accès aux différents aires de la boîte de dialogue, on utilisera $dialog->vbox et $dialog->action_area.

$label = Gtk2::Label->new("Les boîtes de dialogue sont sympas !");  
$dialog->vbox->pack_start( $label, TRUE, TRUE, 0 );  
$label->show();

Si vous désirez une fenêtre modale (qui gèle l’application tant que l’utilisateur n’aura pas fermé la fenêtre de dialogue), il suffit d’utiliser la méthode set_modal dont la fenêtre de dialogue hérite de Gtk2::Window. Vous pouvez également la déclarer modale lors de l’appel de la méthode new, en utilisant le flag 'modal'.

Que vous ajoutiez des boutons avec la méthode new_with_buttons, add_buttons, add_buttons ou add_action_widget, cliquer sur le bouton émettra un signal “réponse” avec un identifiant que vous spécifierez. Gtk2-Perl n’a pas de comportement prédéfini en fonction de la réponse, c’est vous qui devez le définir. Pour des raisons de commodité, vous pouvez utiliser les identifiant définis dans Gtk2::ReponseType. Si une fenêtre de dialogue reçoit un évènement delete-event, le signal “reponse” sera émis avec l’identifiant 'none' (sauf dans le cas de run détaillé ci-dessous). Pour afficher un simple message vous pouvez utilisez par exemple le code suivant, même si dans la réalité vous utiliserez plutôt Gtk2::MessageDialog :

sub simple_message {  
   my $message = shift ;  
   my $dialog = Gtk2::Dialog->new ('Message' , $fenetre_principale,  
                                   'destroy-with-parent',  
                                   'gtk-ok' => 'none' );  
   my $label = Gtk2::Label->new($message);  
   $dialog->vbox->add($label);  
   ### Pour être sûr que la fenêtre de dialogue soit détruite après  
   ### le click de l'utilisateur  
   $dialog->signal_connect (response => sub {$_[0]->destroy;});  
 
   $dialog->show_all;  
}

Les identifiants définis dans Gtk2::ReponseType sont :

'none'  
'reject'  
'accept'  
'delete-event'  
'ok'  
'cancel'  
'close'  
'yes'  
'no'  
'apply'  
'help'

Si vous voulez bloquer le déroulement du programme, c’est-à-dire que vous désirez avoir la réponse de la fenêtre de dialogue avant de continuer à parcourir le code, vous devez appeler $dialog->run();. Cette fonction déclenche une boucle et en sort quand l’utilisateur clique sur un bouton. Elle renvoit de plus l’identifiant du bouton cliqué. Durant run, le comportement par défaut de delete-event est changé. Si la fenêtre de dialogue reçoit l’évènement delete-event, celle-ci ne sera pas détruit comme d’habitude mais run retournera 'delete-event'.

run appelle pour vous $dialog->show(), mais ne vous dispense pas de montrer tous les enfants contenus dans la fenêtre. Pendant run la fenêtre sera modale. Et enfin, une fois que run a retourné une valeur, vous êtes responsable du sort de la fenêtre dialogue. Exemple d’utilisation dans le cas d’une demande de validation :

if ('accept' eq $dialog->run) {  
       faire quelque chose... }  
   else {  
       ne rien faire ...}  
 
  # destruction de la fenêtre de dialogue  
  $dialog->destroy();  
}

Si on veut ajouter à posteriori un ou plusieurs boutons à la fenêtre de dialogue :

$dialog->add_button($texte,$reponse_id);  
$dialog->add_buttons($texte1=>$reponse_id1, $texte2=>$reponse_id2,...);
Chaque nouveau bouton est ajouté à la droite des autres. $response_id est bien entendu l’identifiant de la réponse. $texte peut être une chaîne de caractères arbitraires ou bien un élément stock.

Pour rendre un bouton sensible ou non :

$dialog->set_response_sensitive($reponse_id,$valeur_booléenne);

Boîtes de messages

Les boîtes de messages sont des boîtes de dialogue prédéfinies. Elles permettent d’afficher un message à côté d’un icône. Pour créer une boîte de message :

my $dialog = Gtk2::MessageDialog->new ($fenetre_parente,  
                                       $flags,$type,$bouton,..  
                                       $message);  
Le principe de fonctionnement est exactement le même que pour les fenêtres de dialogues. L’intérêt est ici de vous faire économiser du code et d’assurer une certaine homogénéité pour les applications Gtk2-Perl. Les quatres types de fenêtres sont :
'info'  
'question'  
'error'  
'warning'

exemple

Une exemple pour illustrer des différents types de fenêtres de messages.

info erreur question warning

# !/usr/bin/perl -w

use strict ;
use Gtk2 ’-init’ ;
use constant TRUE => 1 ;
use constant FALSE => 0 ;


my $window = new Gtk2::Window(’toplevel’ ) ;
$window->set_border_width( 15 ) ;
$window->set_title(’Salut les boutons !’ ) ;
$window->signal_connect( ’delete_event’ , sub {Gtk2->main_quit() ;}) ;

my $box = Gtk2::HBox->new(FALSE,10 ) ;
$window->add($box) ;

### Liste des différents types de fenêtres de dialogue
my @liste =(’info’ ,’error’ ,’warning’ ,’question’ ) ;
### On lance ensuite un constructeur de boutons
foreach (@liste) {
creer_bouton($_) ;
}

# On montre la boîte
$box->show ;

# On montre la fenêtre
$window->show() ;

# On lance la boucle principale.
Gtk2->main ;


### La fonction de rappel qui est appelé quand on a cliqué sur un bouton.
sub rappel{
my ($widget,$type)=@_ ;
my $dialog = Gtk2::MessageDialog->new ($window,
[qw/modal destroy-with-parent/],
$type,
’ok’ ,
”Une boîte de dialogue de type : $type ” ) ;
# On ajoute un nouveau bouton à la boîte de dialogue. On associe à ce bouton
# l’identifiant ’cancel’
$dialog->add_button(”Salut !” ,’cancel’ ) ;

# Si l’utilisateur clique sur le bouton ”Salut”, on lui répond poliment
if (’cancel’ eq $dialog->run) {
my $dialog2 = Gtk2::Dialog->new (”Bonjour !” , $dialog,
[qw/modal destroy-with-parent/],
’gtk-ok’ =>’ok’ ) ;
my $label = Gtk2::Label->new(”Comment vas-tu ?” ) ;
$dialog2->vbox->add($label) ;
$label->show() ;

$dialog2->run() ;
# le code est bloqué là tant que l’utilisateur ne clique pas sur un bouton
$dialog2->destroy ;
}
$dialog->destroy ;
}

### Cette fonction crée les différents boutons
sub creer_bouton {
my $texte = shift ;
my $button = Gtk2::Button->new($texte) ;
$button->signal_connect( ’clicked’ , \&rappel, $texte ) ;
$box->pack_start($button,TRUE,TRUE,5 ) ;
$button->show ;
}

Dialogue de sélection de fichiers

Créer une boîte de dialogue de sélection de fichiers

Cette boîte de dialogue est un moyen simple et rapide pour que l’utilisateur choisisse un nom de fichier. Elle est complète avec les boutons Ok, Cancel et Help. C’est donc un moyen simple d’économiser du temps de programmation. Pour créer une nouvelle boîte de dialogue :

$file_dialog =  Gtk2::FileSelection->new( $title );

Utiliser un nom de fichier

Pour déclarer le nom de fichier, par exemple pour accéder à un répertoire spécifique ou donner un nom de fichier par défaut, on utilise :

$file_dialog->set_filename( $filename );
Pour prendre le texte que l’utilisateur a entré ou sur lequel il a cliqué, utilisez ;
$file_dialog->get_filename();
Vous pouvez utiliser un filtre de fichier dans le répertoire courant à l’aide de :
$file_dialog->complete( $pattern );
Si un fichier correspond, il apparaîtra dans l’entrée texte de la boîte de dialogue. Si un ensemble de fichiers correspond au filtre alors la liste des fichiers ne contiendra que ceux-là. Un exemple de filtre : *.txt ou gtk*.

Opérations sur les fichiers

La boîte de dialogue de sélection de fichiers peut montrer des boutons d’opérations sur les fichiers :

$file_dialog->show_fileop_buttons();
ou bien les cacher avec :
$file_dialog->hide_fileop_buttons();

Les widgets de dialogue

Vous pouvez aussi accéder aux widgets contenus dans le widget de sélection de fichiers. Il s’agit de :

dir_list  
file_list  
selection_entry  
selection_text  
main_vbox  
ok_button  
cancel_button  
help_button
Vous utiliserez certainement les boutons, Ok, Cancel et Help en signalant leurs utilisations.

Exemple

fileselection

# !/usr/bin/perl -w

use strict ;
use Gtk2 ’-init’ ;
use constant TRUE => 1 ;
use constant FALSE => 0 ;

# Crée un nouveau widget de sélection de fichiers
my $file_dialog = Gtk2::FileSelection->new( ”Sélection de fichier” ) ;
$file_dialog->signal_connect( ”destroy” , sub { Gtk2->main_quit() ; } ) ;
# Connecte le bouton ok à la fonction file_ok_sel
$file_dialog->ok_button->signal_connect( ”clicked” ,
\&file_ok_sel,
$file_dialog ) ;

# Connecte le bouton cancel à la fonction qui détruit le widget
$file_dialog->cancel_button->signal_connect( ”clicked” ,
sub { Gtk2->main_quit() ; } ) ;

# éclare une nom de fichier, comme quand on veut sauver un fichier
$file_dialog->set_filename( ”penguin.png” ) ;
$file_dialog->show() ;

main Gtk2 ;

# Récupère le nom du fichier et l’imprime sur la console
sub file_ok_sel {
my ( $widget, $file_selection ) = @_ ;
my $file = $file_selection->get_filename() ;
print( ”$file\n” ) ;
}

La sélection des couleurs

Le widget de sélection de couleurs est, ce n’est pas surprenant, un widget pour sélectionner les couleurs de manière interactive. Ce widget composé laisse l’utilisateur choisir une couleur en manipulant les triplés RGB ( Rouge, Vert, Bleu ) ou HVS ( Teinte, Saturation, Valeur). On le fait soit en ajustant chacune des valeurs avec un curseur ou avec une entrée texte soit en pointant sur la couleur désirée dans le cercle de teinte-saturation et dans la barre de valeur.

Le widget de sélection de couleurs n’émet qu’un seul signal color_changed qui est émis si la couleur courante du widget change ou quand l’utilisateur la change ou si elle est choisie explicitement à l’aide de la fonction selection_set_color().

Regardons ce que le widget de sélection de couleurs nous propose. Le widget existe sous deux moutures : Gtk2::ColorSelection et Gtk2::ColorSelectionDialog.

$color = Gtk2::ColorSelection->new();
Vous n’utiliserez probablement jamais ce constructeur directement. Il crée juste un widget de sélection de couleurs orphelin que vous aurez à parenter vous-même. Le widget de sélection de couleurs hérite du widget VBox.
$color = Gtk2::ColorSelectionDialog->new($titre);
C’est le constructeur le plus commun. Il crée une fenêtre de dialogue de sélection de couleur. Elle est composée d’un cadre contenant un widget de sélection de couleurs, un séparateur horizontal, une HBox avec trois boutons, Ok, Annuler et Aide. Vous pouvez atteindre ces boutons en accédant aux widgets ok_button, cancel_button et help_button dans la structure du widget de sélection de couleurs. ( i.e., $colordialog->ok_button ).
$colordialog->set_update_policy ( $policy );
Cette fonction déclare la politique de mise à jour. La politique par défaut est 'continuous' qui signifie que la couleur courante est mise à jour continuellement quand l’utilisateur prend le curseur, clique sur la souris, se déplace dans le cercle de teinte-saturation ou la barre de valeur. Si vous rencontrez des problèmes de performance, n’hésitez pas à choisir 'discontinuous' ou 'delayed'.
$colordialog->set_has_opacity ( $use_opacity);
Le widget de sélection de couleurs supporte le réglage de l’opacité d’une couleur ( également connu comme courbe alpha ). Ce n’est pas disponible par défaut. Appeler cette fonction avec une valeur de $use_opacity permet l’opacité. De même, une valeur fausse rend l’opacité indisponible.
$colordialog->set_current_color ( $color );
Déclarer explicitement la couleur courante en appelant cette fonction avec comme argument une référence vers un Gtk::Gdk::Color. Pour déclarer l’opacité (le canal alpha), vous devez utiliser :
$colordialog->set_current_alpha ( $alpha );
$alpha devrait être une valeur comprise entre 0 (complètement transparent) et 65636 (complètement opaque).
$colordialog->get_current_color();  
$colordialog->get_current_alpha();
Quand vous voulez vous renseigner sur la couleur actuelle et la canal alpha, typiquement quand vous avez reçu le signal color_changed, vous pouvez utiliser ces fonction.

Exemple

colorselection

# !/usr/bin/perl -w

use constant FALSE => 0 ;
use constant TRUE => 1 ;

use Gtk2 ’-init’ ;

my $window = undef ;
my $da ;
my $color ;


$color = Gtk2::Gdk::Color->new (0 , 65535 , 0 ) ;

$window = Gtk2::Window->new ;
$window->set_title (”Sélection de couleurs” ) ;

$window->signal_connect (destroy => sub { $window = undef }) ;

$window->set_border_width (8 ) ;

my $vbox = Gtk2::VBox->new (FALSE, 8 ) ;
$vbox->set_border_width (8 ) ;
$window->add ($vbox) ;

#
# Crée une zone de dessin
#

my $frame = Gtk2::Frame->new ;
$frame->set_shadow_type (’in’ ) ;
$vbox->pack_start ($frame, TRUE, TRUE, 0 ) ;

$da = Gtk2::DrawingArea->new ;
# déclare une taille minimale
$da->set_size_request (200 , 200 ) ;
# déclare la couleur
$da->modify_bg (’normal’ , $color) ;
$frame->add ($da) ;

my $alignment = Gtk2::Alignment->new (1.0 , 0.5 , 0.0 , 0.0 ) ;

my $button = Gtk2::Button->new_with_mnemonic (”_Changer la couleur ci-dessus” ) ;
$alignment->add ($button) ;

$vbox->pack_start ($alignment, FALSE, FALSE, 0 ) ;

$button->signal_connect (clicked => \&change_color_callback) ;

$window->show_all ;

Gtk2->main ;

sub change_color_callback {
my $button = shift ;

my $dialog = Gtk2::ColorSelectionDialog->new (”Changement de couleur” ) ;

$dialog->set_transient_for ($window) ;

my $colorsel = $dialog->colorsel ;

$colorsel->set_previous_color ($color) ;
$colorsel->set_current_color ($color) ;
$colorsel->set_has_palette (TRUE) ;

my $response = $dialog->run ;

if ($response eq ’ok’ ) {
$color = $colorsel->get_current_color ;

$da->modify_bg (’normal’ , $color) ;
}
$dialog->destroy ;
}

#Copyright (C) 2003 by the gtk2-perl team (see the file AUTHORS for the full list)

Dialogue de sélection de police

Il s’agit d’une boîte de dialogue qui permet à l’utilisateur de choisir une police et un style de police à l’aide du widget préconçu FontSelectionDialog . La fonction suivante crée un widget de sélection de police :

$font_dialog = Gtk2::FontSelectionDialog->new($titre);
Pour obtenir la police sélectionnée dans la boîte de dialogue :
$font = $font_dialog->get_font();
$font sera alors une objet Gtk2::Gdk::Font.

Pour obtenir le nom de la police courante :

$font_dialog->get_font_name();
Pour déclarer la police sélectionnée dans la boîte de dialogue :
font_dialog->set_font_name($font_name);
Ou $font_name est un chaîne de caractères avec le nom de la police à charger. Cette fonction retourne une valeur vraie si la police a été trouvée ou fausse si ce n’est pas la cas. Vous pouvez changer le texte d’aperçu grâce à :
$font_dialog->set_preview_text($texte);
ou bien le récupérer à l’aide de :
$font_dialog->get_preview_text($texte);

Exemple

fontselection

# !/usr/bin/perl -w

use strict ;
use Gtk2 ’-init’ ;
use constant TRUE => 1 ;
use constant FALSE => 0 ;

# Crée un nouveau widget de sélection de fichiers
my $font_dialog = Gtk2::FontSelectionDialog->new( ”Sélection de police” ) ;
$font_dialog->signal_connect( ”destroy” , sub { Gtk2->main_quit() ; } ) ;
# Connecte le bouton ok à la fonction font_ok_sel
$font_dialog->ok_button->signal_connect( ”clicked” ,
\&font_ok_sel,
$font_dialog ) ;

# Connecte le bouton cancel à la fonction qui détruit le widget
$font_dialog->cancel_button->signal_connect( ”clicked” ,
sub { Gtk2->main_quit() ; } ) ;


$font_dialog->show() ;

main Gtk2 ;

# Récupère le nom de la police et l’imprime sur la console
sub font_ok_sel {
my ( $widget, $font_selection ) = @_ ;
my $font = $font_selection->get_font_name() ;
print( ”$font\n” ) ;
}