Object +-- Widget +-- Container +-- List
Le widget Liste est conçu pour agir comme un conteneur vertical pour des widgets qui devraient être du type élément de liste (ListItem). Un widget Liste possède sa propre fenêtre pour recevoir les évènements et sa propre couleur de fond qui est généralement blanche.
Afin de ne pas vous perturber, une Liste (majuscule) fait référence à un widget Gtk::List alors qu'une liste (minuscule) fait référence à une liste Perl ( et ce qui peut aussi y faire référence, quoique de manière grossière, comme les rangées).
Il y a deux champs dans la définition d'une structure d'un widget Liste qui
seront d'un grand intérêt pour nous : Il y a selection et selection_mode.
La champs selection d'une Liste est une liste de tous les éléments qui
sont actuellement sélectionnés ou une liste vide si la sélection est vide. Ainsi
pour en apprendre plus sur la sélection courante, nous lisons le champs selection
mais nous ne le modifions pas car les champs internes sont maintenus par les
fonctions de Liste.
Le champs selection_mode d'une Liste détermine les facilités de sélection
d'une Liste et par conséquent les contenus du champs de sélection. Le selection_mode
peut être :
'single' - La sélection est soit vide soit sa liste ne contient qu'un
seul élément sélectionné.
'browse' - La sélection est vide si la liste ne contient aucun widget
ou seulement des insensibles, autrement il contient une liste avec un élément.
'multiple' - La sélection est vide si aucun des éléments n'est sélectionné
ou bien une liste de tous les items sélectionnés.
'extended' - La sélection est toujours vide.
Le défaut est 'multiple'.
Le signal 'selection changed' sera invoqué si le champs de selection
de la Liste a changé. Cela arrive quand un enfant de la Liste est sélectionné
ou désélectionné.
Le signal 'select_child' est invoqué un enfant de la Liste est sur le
point d'être sélectionné. Cela arrive principalement quand on appelle select_item(),
select_child(), quand on appuie sur les boutons et parfois c'est déclenché
indirectement en d'autres occasions quand des enfants sont ajoutés ou enlevés
de la Liste.
Le signal 'unselect_child' est invoqué quand un enfant de la Liste est
sur le point d'être désélectionné. Cela arrive principalement quand on appelle
unselect_item(), unselect_child(), quand on appuie sur les boutons
et parfois c'est déclenché indirectement en d'autres occasions quand des enfants
sont ajoutés ou enlevés de la Liste.
Pour créer une Liste :
$list = new Gtk::List();
Les éléments sont ajoutés à la Liste en utilisant :
$list->insert_items( @items, $position );
Ou @items est la liste des éléments à ajouter et $position est
la position de départ des éléments.
On peut ajouter des éléments à la fin de la Liste ou au début avec les fonctions :
$list->append_items( @items ); $list->prepend_items( @items );
Pour enlever des éléments de la Liste :
$list->remove_items( @items );
Ou @items est la liste des éléments à enlever.
Vous pouvez également enlever un ensemble d'éléments avec :
$list->clear_items( $start, $end );
Les éléments peuvent être sélectionnés par :
$list->select_item( $index ); $list->select_child( $child );
Cela invoquera également soit le signal 'select_item' soit le signal
'select_child' sur l'élément de la liste.
On désélectionne de la même manière :
$list->unselect_item( $index ); $list->unselect_child( $child );
Si vous voulez l'index pour un enfant de la Liste, utilisez :
$index = $list->child_position( $child );
Si une erreur se produit, une valeur -1 est retournée.
On peut choisir le mode de sélection à l'aide de :
$list->set_selection_mode( $mode );
Ou mode peut être 'single', 'browse', 'multiple', 'extended'.
Object +-- Widget +-- Container +-- Bin +-- Item +-- ListItem
Les widgets ListItem sont conçus pour agir comme des conteneurs ayant un enfant et fournissant des fonctions de sélection/désélection tout comme le widget List l'exige d'eux pour ses enfants.
Un ListItem possède sa propre fenêtre pour recevoir les évènements et sa propre couleur de fond qui est habituellement blanche.
Comme il est directement dérivé d'un Item, il peut être traité comme tel. Pour
plus de données la dessus, voir la section sur les Items. Habituellement un
ListItem possède juste un label pour identifier un nom de fichier dans un Liste,
c'est pourquoi la fonction bien pratique new_with_label() est fourni.
Le même effet peut être obtenu en créant un Label à part entière, déclarant
ses alignements à xalign=0 et yalign=0.5 avec une addition sous-jacente de conteneur
au ListItem.
Comme personne n'est obligé d'ajouter un GtkLabel à un GtkListItem, vous pouvez également ajouter une GtkVBox ou une GtkArrow, etc, au GtkItem.
Pour créer un ListItem, appeler l'une des fonctions suivantes :
$item = new Gtk::ListItem(); $item = new Gtk::ListItem( $label );
Si vous passez une chaîne en argument, cela crée une ListItem avec un Label comme seul enfant du ListItem.
Pour sélectionner un ListItem :
$item->select();
Cette méthode émettra le signal 'select' sur le ListItem.
La désélection fonctionne de la même manière :
$item->deselect();
L'exemple suivant montrera les changements de sélection d'une liste et vous laissera ``arrêter'' une liste d'items et les placer en prison en les sélectionnant avec le bouton droit de la souris.
#!/usr/bin/perl -wuse Gtk;
use strict;
init Gtk;
my $false = 0;
my $true = 1;
my $separator;
my $window;
my $vbox;
my $scrolled_window;
my $frame;
my $gtklist;
my $button;
my $list_item;
my @dlist = ();
my $i;
my $buffer;
$window = new Gtk::Window( 'toplevel' );
$window->set_title( "List Example" );
$window->signal_connect( 'destroy', sub { Gtk->exit( 0 ); } );
# A l'intérieur de la fenêtre on a besoin d'une boîte pour ranger les
# widgets verticalement
$vbox = new Gtk::VBox( $false, 5 );
$vbox->set_border_width( 5 );
$window->add( $vbox );
$vbox->show();
# Ceci est une fenêtre défilable pour y placer le widget List
$scrolled_window = new Gtk::ScrolledWindow( undef, undef );
$scrolled_window->set_usize( 250, 150 );
$vbox->add( $scrolled_window );
$scrolled_window->show();
# Crée un widget List. Connecte la fonction sigh_print_selection()
# au signal "selection_changed" de la List pour imprimer les items
# sélectionnés chaque fois que la sélection a changé.
$gtklist = new Gtk::List();
$scrolled_window->add_with_viewport( $gtklist );
$gtklist->show();
$gtklist->signal_connect( 'selection_changed', \&sigh_print_selection );
#Nous créons une prison pour y placer une liste d'items;)
$frame = new Gtk::Frame( "Prison" );
$frame->set_usize( 200, 50 );
$frame->set_border_width( 5 );
$frame->set_shadow_type( 'out' );
$vbox->add( $frame );
$frame->show();
# Connecte le sigh_button_event() à la List, qui déclenchera
# l'arrestation des items de la liste.
$gtklist->signal_connect( 'button_release_event', \&sigh_button_event, $frame );
# Crée un séparateur
$separator = new Gtk::HSeparator();
$vbox->add( $separator );
$separator->show();
# Enfin crée un bouton et connecte son signal ``cliqué'' à la destruction
# de la fenêtre.
$button = new Gtk::Button( "Close" );
$vbox->add( $button );
$button->show();
$button->signal_connect( 'clicked', sub { $window->destroy(); } );
# Maintenant, nous créons 5 éléments de liste, chacun ayant son propre label
# et nous les ajoutons à la List à l'aide de la fonction add().
for $i ( 0..4 ) { my $label; my $string; $buffer = "ListItemContainer with Label #" . $i; $label = new Gtk::Label( $buffer ); $list_item = new Gtk::ListItem(); $list_item->add( $label ); $label->show(); $gtklist->add( $list_item ); $list_item->show(); $string = $label->get(); }
# Ici, nous créons 5 autres Labels, cette fois on envoie le Label à la fonction
# new().
for $i ( 5..9 ) { $buffer = "List Item with Label $i"; $list_item = new Gtk::ListItem( $buffer ); @dlist = ( $list_item, @dlist ); $list_item->show(); }
$gtklist->append_items( @dlist );
# Enfin, on veut voir la fenêtre, n'est-ce-pas ? ;)
$window->show();
# Déclenche la boucle Gtk
main Gtk;
exit( 0 );
### Routines
# Ceci est le gestionnaire de signal connecté au bouton pressé/relâché
# de la List.
sub sigh_button_event { my ( $gtklist, $frame, $event ) = @_; # Nous faisons seulement quelque chose cela si le troisième # (le plus à droite) est relâché if ( ( defined( $event->{ 'type' } ) ) and ( defined( $event->{ 'button' } ) ) and ( $event->{ 'type' } eq 'button_release' ) and ( $event->{ 'button' } == 3 ) ) { my @dlist = (); my $new_prisoner; my $list_item; # Rapporte la liste actuellement sélectionnée # qui sera notre prochain prisonnier. @dlist = $gtklist->selection; $new_prisoner = $dlist[ 0 ] if ( @dlist ); # Cherche les items de la liste déjà prisonniers, nous les # replacerons dans la liste. foreach $list_item ( $frame->children() ) { $list_item->reparent( $gtklist ); } # Si nous avons un nouveau prisonnier, on l'enlève de la liste et on # le place dans le cadre ``Prison''. Nous devons d'abord le # désélectionner. Je ne sais pourquoi, j'ai reçu une erreur de # valeur non initialisée durant cette section de code, bien que # cela fonctionne. if ( defined( $new_prisoner ) ) { $gtklist->unselect_child( $new_prisoner ); $new_prisoner->reparent( $frame ); } } }
# C'est le gestionnaire qui est appelé si le widget List émet le signal
# "selection_changed"
sub sigh_print_selection { my ( $gtklist ) = @_; my @dlist; my $list_item; # Rapporte l'item de la liste actuellement sélectionné qui sera # notre prochain prisonnier @dlist = $gtklist->selection; # Si aucun des items n'est sélectionné, il n'y a rien d'autre à # faire que de le dire à l'utilisateur. unless ( defined( @dlist ) ) { print "Selection cleared\n"; return; } }