Chapitre 3
Les boîtes de regroupement

Notre premier hello world n’était composé que d’un bouton placé dans une fenêtre. La fenêtre fait partie de ces widgets qui ne peuvent contenir qu’un seul widget. Pour placer ce dernier à l’intérieur, on utilise l’appel $window->add(). Évidemment, il y peu de chance que l’application que vous voulez créer ne soit composée que d’un unique widget. Heureusement, il existe des conteneurs qui peuvent contenir (c’est mieux !) plus d’un widget. Les boîtes de regroupement que nous avons déjà dans notre hello world un peu plus évolué en font partie.

Théorie des boîtes de regroupement

Le rangement est fait en créant des boîtes puis en regroupant les widgets à l’intérieur. Ces boîtes sont des conteneurs invisibles dans lesquelles on peut regrouper les widgets. Il en existe deux sortes : la boite horizontale et la boîte verticale. En rangeant les widgets dans une boîte horizontale, les objets sont insérés de la gauche vers la droite ou de la droite vers la gauche en fonction de l’appel utilisé. Pour une boîte verticale, le rangement se fait de bas en haut ou vice-versa. Vous pouvez utiliser des combinaisons en rangeant des boîtes à l’intérieur d’autres boîtes, ou à côté afin de produire l’effet désiré.

Pour créer une nouvelle boîte horizontale ou verticale :

$box= Gtk2::HBox->new($homogeneous,$spacing);  
$box= Gtk2::VBox->new($homogeneous,$spacing);

Si $homogeneous est une valeur vraie alors tous les widgets rangés à l’intérieur disposeront du même espace.  $spacing est l’espace en pixels qu’il faut laisser entre les widgets.

Les fonctions suivantes sont utilisées pour placer les objets dans les boîtes :

$box->pack_start($child,$expand,$fill,$padding);  
$box->pack_end($child,$expand,$fill,$padding);

La fonction pack_start() commence à remplir une VBox par le haut et continue vers le bas. Pour une HBox, elle commence par la gauche et continue vers la droite. pack_end() fera le contraire. Ces fonctions nous permettent juste de justifier à droite ou à gauche la position des widgets et peuvent être mélangées pour obtenir l’effet désiré. L’objet ajouté peut-être ou bien un conteneur ou bien un widget. En fait, de nombreux widgets sont eux-même des conteneurs (les boutons par exemple, mais nous n’utilisons en général qu’un label ou un icône à l’intérieur des boutons). Comme vous l’avez peut-être deviné, l’argument  $child est le widget à placer dans la boîte. Enfin $padding est un espace donné en pixel qui entourera l’enfant.

Si l’argument $expand est une valeur vraie alors les widgets seront disposés dans la boîte pour remplir l’espace qui leurs est alloué. Déclarer  $expand comme valeur fausse vous permettra de faire des justifications à droite et à gauche de vos widgets. Noter que déclarer  $expand vraie pour une boîte revient à déclarer  $expand vraie pour chaque widget.

Si l’argument $fill est une valeur vraie alors tout espace vide est alloué aux objets eux-même. Autrement l’espace vide est un emballage dans la boîte autour des objets. Cela a de l’effet uniquement si l’argument $expand est vrai.

En utilisant ces appels, GTK sait où vous voulez placer vos widgets et peut ainsi les redimensionner ou faire d’autres choses sympathiques. Comme vous l’imaginez, cette méthode nous donne une certaine flexibilité quand on crée et place des widgets.

Cas des boîtes homogènes

Vous avez créé une boîte avec une valeur vraie pour l’argument $homogeneous. Par exemple :

$box=new Gtk2::HBox(TRUE,0);  
$box=new Gtk2::VBox(TRUE,0);

Dans ce cas, tous les widgets contenus dans la boîte seront dimensionnés en fonction du plus grand et l’argument $expand$ n’a pas d’intérêt.

Si $fill est une valeur vraie alors tous les widgets contenus ont la même taille et remplissent l’espace qui leurs est alloué.

brHT
Si $fill est une valeur fausse alors les widgets gardent leurs tailles respectives et sont également répartis dans le conteneur.

brHF

Cas des boîtes non homogènes

Vous avez créé une boîte avec une valeur vraie pour l’argument $homogeneous. Par exemple :

$box=new Gtk2::HBox(FALSE,0);  
$box=new Gtk2::VBox(FALSE,0);

Si $expand est une valeur fausse alors la valeur de $fill n’a aucun intérêt. Les widgets auront alors leur propre taille et ne rempliront pas l’espace.

brNHFF
Si $expand est une valeur vraie alors les widgets seront étirés dans la boîte. Si $fill est fausse, alors les widgets gardent leur taille naturelle.

brNHTF
En revanche, si $fill est une valeur vraie alors les widgets remplissent la boîte.

brNHTT

Détails sur les boîtes

Le rangement dans les boîtes peut être déroutant au début. Il y a beaucoup d’options et il n’est pas immédiatement évident de les arranger entre elles. En fait, il y a cinq styles de base différents. Ces cinq styles sont ceux qui sont illustrés ci-dessus.

Commentaire à propos de l’exemple

Chaque ligne de l’exemple contient une boîte horizontale avec plusieurs boutons. L’appel pour ranger est un raccourci pour regrouper chaque bouton dans une boîte. Chaque bouton est placé dans la boîte de la même manière ( les arguments sont passées à la fonction  pack_start()). C’est une forme raccourcie de  pack_start() et de pack_end() qui déclare $expand vraie, $fill vraie et $padding=0.

Ces fonctions sont :

$box->pack_start_defaults($widget);  
$box->pack_end_defaults($widget);
La valeur $homogeneous de la boîte peut être modifiée en utilisant la fonction :
$box->set_homogeneous($homogeneous);

De même pour la valeur $spacing :

$box->set_spacing($spacing);

Si vous voulez déplacer un enfant, utilisez :

$box->reorder_child($child,$position);
$child est le widget à déplacer et $position est la position à changer en partant de 0. Si vous voulez connaître l’ordre actuel, regardez la liste fournie par l’appel à la fonction sur les conteneurs children().

Si vous voulez changer un regroupement d’enfants, vous pouvez utiliser :

$box>set_child_packing($widget,$expand,$fill,$padding,$pack_type);
Les arguments sont les mêmes que pour les fonctions pack_start() et pack_end() à l’exception de $pack_type qui est soit 'start' soit 'end'.

Quelle est la différence entre l’espace ( spacing ), déclaré quand la boîte est créée, et l’emballage ( padding ), déclaré quand les éléments sont rangés ? L’espace est ajouté entre les objets et l’emballage est ajouté de chaque côté de l’objet.