next up previous contents
suivant: Les barres de défilements monter: Les widgets précédent: Les labels   Table des matières


Sous-sections

Les widgets de réglage et d'échelle

Les réglages

GTK possède plusieurs widgets qui peuvent être ajustés visuellement par l'utilisateur à l'aide de la souris ou du clavier, comme le widget range. Il y a aussi quelques widgets qui mettent à disposition des portions ajustables pour une plus grande surface de données comme les widgets texte et viewport.

Évidemment, une application a besoin d'être capable de réagir aux changements que l'utilisateur fait aux widget range. Une manière de le faire serait que chaque widget émette son propre type de signal quand son réglage change et même passe la nouvelle valeur au gestionnaire de signal, ou lui demande de regarder à l'intérieur des données du widget afin de s'informer de la valeur. Vous pouvez aussi vouloir connecter les réglages de plusieurs widgets ensembles afin que les réglages de l'un règle les autres. L'exemple le plus simple de ce phénomène est de connecter une barre de défilement à une zone de texte ou à un ``panning viewport''. Si chaque widget possède son propre moyen de déclarer ou de récupérer la valeur du réglage alors le programmeur doit écrire leurs propres gestionnaires de signal pour faire la traduction entre la sortie du signal d'un widget et l'entrée d'une autre fonction déclarant les réglages.

GTK résout ce problème en utilisant l'objet Adjustment qui n'est pas vraiment un widget mais un moyen pour les widgets de stocker et de passer des informations de réglages sous une forme concise et flexible. L'usage le plus évident de l'Adjustment est de stocker les paramètres de configuration et les valeurs des widgets ``échelles'' comme les barres de défilement et les contrôles d'échelle. Quoi qu'il en soit, puisque les Adjustments sont dérivés de la classe Objet, ils possèdent des pouvoirs spéciaux supérieurs à ceux des structures de données normales. Plus important, ils peuvent émettre des signaux tout comme les widgets, et ces signaux peuvent être utilisés non seulement pour permettre à vos programmes de réagir aux entrées utilisateurs sur certains widgets réglables mais également pour propager les valeurs des réglages de manière transparente entre les widgets réglables. Malheureusement, les réglages peuvent être difficiles à comprendre, c'est pourquoi il est possible que vous ne voyiez pas bien le rôle des réglages avant d'avoir vu les widgets qui les utilisent comme les barres de progression, les viewport, les barres de défilement.

Créer des Ajustements ( réglages )

Beaucoup de widgets qui utilisent les objets de réglage le font automatiquement mais dans certains cas que nous verrons plus loin, vous devrez les créer vous même avec :

L'argument $value est la valeur initiale que vos voulez donner à vos réglages, correspondant habituellement au point le plus haut et le plus à gauche du widget réglable.

L'argument lower spécifie la valeur la plus basse que le réglage peut prendre.

L'argument $step_increment spécifie le plus petit des deux incréments avec lequel l'utilisateur peut changer la valeur alors que page_increment est le plus grand.

L'argument $page_size correspond correspond habituellement à la zone visible d'un widget.

L'argument $upper est utilisé pour représenter les coordonnées du point le plus au fond et le plus à droite dans l'enfant du widget ``paning''. Par conséquent, ce n'est pas toujours la plus grande valeur que $value puisse prendre puisque $page_size est en général non nul.

Utiliser les réglages : la manière facile

Les widgets réglables peuvent être grossièrement divisés entre ceux qui utilisent et nécessitent des unités spécifiques pour ces valeurs et ceux qui les traitent comme des nombres arbitraires. Le second groupe inclut les widgets range ( les barres de défilements, les échelles, les barres de progression et les boutons spins). Ces widgets sont tous typiquement ajustés directement par l'utilisateur à l'aide du clavier ou de la souris. Ils traiteront les valeurs lower et upper du réglage comme une intervalle à l'intérieur duquel on peut manipuler la valeur du réglage. Par défaut, ils ne modifieront que la valeur du réglage.

L'autre groupe comprend les widgets texte, viewport, listes composées et le fenêtre défilable. Ce sont des widgets typiquement ajustés ``indirectement'' à l'aide de barres de défilement. Alors que les widgets qui utilisent des réglages peuvent ou bien créer les leurs, ou bien utiliser ceux fournis, vous voudrez en général laisser cette catégorie de widget créer ses propres réglages. Habituellement, ils refuseront finalement toutes les valeurs, sauf la $value elle-même, que vous leurs donner mais les résultats sont en général indéfinis ( ce qui signifie que vous aurez à lire les codes sources et ils peuvent être différents de widget à widget ).

Maintenant vous pensez probablement, puisque les widgets texte et viewport insistent sur le fait du déclarer tout sauf la valeur de leur réglage alors que les barres de défilement ne toucheront qu'à cette valeur, que si vous partagez un réglage entre une barre de défilement et un widget texte, la manipulation de la barre de défilement ajustera automatiquement le widget texte ! Et bien oui ! Juste avec :

Les réglages internes

OK, vous vous dîtes, c'est bien ! Mais que se passe-t-il si vous voulez créer votre propre gestionnaire pour répondre quand l'utilisateur règle un widget range ou un bouton spin ? Et comment on obtient-on la valeur de réglage pour ces gestionnaires ? En Gtk-Perl, vous utiliserez :

ou adjustment_name est au choix :

Puisque, quand vous déclarez la valeur d'un réglage, vous voulez généralement que ce changement soit répété à tous les widgets qui utilisent ce réglage, GTK fournit la fonction suivante :

Comme mentionné précédemment, les réglages sont capables d'émettre des signaux. C'est bien sûr la raison pour laquelle les mises à jour se produisent automatiquement quand vous partagez un objet Adjustment entre une barre de défilement et tout autre widget réglable ; tous les widgets réglables connectent des gestionnaires de signaux à leur signal d'ajustement 'value_changed', autant que le peut votre programme.

Les divers widgets qui utilisent l'objet Adjustment émettront ce signal sur un réglage à partir du moment ou il change sa valeur. Cela se produit à la fois quand l'entrée utilisateur oblige le curseur à glisser sur le widget range, aussi bien que quand le programme change explicitement la valeur par un set_value(). Ainsi, par exemple, si vous utilisez un widget échelle et que vous voulez changer l'angle de rotation d'une image, quelques soient ces changements de valeurs, vous créerez un rappel comme celui-ci :

et vous le connectez au réglage du widget échelle comme ceci :

Que se passe-t-il quand un widget reconfigure les champs upper et lower de ses réglages, comme, par exemple, quand l'utilisateur ajoute du texte à un widget texte ? Dans ce cas, il émet le signal 'changed'.

Les widgets range connectent typiquement un gestionnaire pour ce signal ce qui change leur apparence pour refléter ce changement, par exemple la taille du curseur dans la barre de défilement grandira ou rétrécira en proportion inverse de la différence entre les valeurs upper et lower de ses réglages. Vous n'aurez probablement jamais besoin d'attacher un gestionnaire à ce signal sauf si vous écrivez un nouveau type de widget range. Quoi qu'il en soit, si vous changez les valeurs d'un réglage directement, vous devrez émettre ce signal sur lui pour reconfigurer n'importe quel widget qui l'utilise, comme ceci :

Les widgets Range

La catégorie des widgets Range inclut la barre de défilement ``ubiquitous'' et le widget moins commun échelle (scale). Bien que ces deux widgets soient généralement utilisés dans des buts différents, ils sont presque similaires en fonction et en implémentation. Tous les widgets Range partagent un ensemble d'éléments graphiques, chacun possédant sa propre fenêtre X et recevant les évènements. Ils contiennent tous une glissière et un curseur ( parfois appelé ``thumbwheel'' dans d'autres environnements GUI ). Prendre le curseur avec le pointeur de la souris le promène le long de la glissière alors que cliquer dans la glissière avance le curseur en direction du lieu du clic, soit complètement soit d'une quantité fixée dépendant du bouton de la souris utilisé.

Comme mentionné précédemment, tous les widgets Range sont associés à un objet Adjustment à partir duquel ils calculent la longueur du curseur et sa position dans la glissière. Quand l'utilisateur manipule le curseur, le widget range changera la valeur de l'ajustement.

Les fonctions communes

Le widget Range a une gestion interne plutôt compliquée mais comme tous les widgets de la ``classe de base'', cette complexité n'est intéressante que si vous voulez le programmer. Ainsi, presque toutes les fonctions et les signaux qu'il définit, ne sont réellement utilisés qu'en écrivant des widgets dérivés.

La politique de mise à jour d'un widget Range définie à quel point, durant l'interaction de l'utilisateur, il changera le $value de son réglage et émettra le signal $value_changed de ce réglage. Les politiques de mises à jour sont :

'continuous' : c'est le défaut. Le signal value_changed' est émis continuellement même si le curseur n'est bougé que d'une valeur minuscule.

'discontinuous' : le signal 'value_changed' est émis uniquement un fois que le curseur ne bouge plus et que l'utilisateur a relâché le bouton de la souris.

'delayed' : le signal 'value_changed' est émis quand l'utilisateur relâche le bouton de la souris ou si le curseur s'arrête pendant une courte période de temps.

Ces politiques de mise à jour peuvent être déclarées à l'aide de la fonction :

Obtenir et déclarer l'ajustement ``au vol'' se fait par :

$range->get_adjustment() retourne l'ajustement auquel $range est attaché.

set_adjustment() ne fait absolument rien si vous lui passez l'ajustement que Range utilise déjà, sans regarder si vous avez changé l'un des champs ou non. Si vous lui passez un nouvel ajustement, il ôtera la référence à l'ancien, s'il existe ( peut-être en le détruisant ), connectera les signaux appropriés au nouveau et appellera le fonction privée adjustment_changed qui recalculera ( ou du moins est supposée recalculer ) la taille et/ou la position du curseur et le redessinera si nécessaire. Comme mentionné dans la section sur les réglages, si vous souhaitez réutiliser le même ajustement, il vous faudra émettre le signal 'changed' quand vous modifiez sa valeur, à l'aide de :

Souris et clavier

Tous les widgets Range de GTK réagissent aux clics de souris plus ou moins de la même manière. Cliquer avec le bouton 1 dans la glissière fera que le page_increment de l'ajustement sera ajouté ou soustrait à sa value. et que le curseur sera bougé en conséquence. Cliquer sur le bouton 2 dans la glissière fera sauter le curseur jusqu'à l'endroit du clic. Cliquer sur l'une des flèches de la barre de défilement provoquera un changement de la valeur du réglage égal au step_increment. Cela peut prendre un certain temps à maîtriser, mais par défaut, les barres de défilement, tout comme les widgets échelles, peuvent être manipulés au clavier ( état ``focus'') en GTK. Si vous pensez que l'utilisateur sera dérouté, vous pouvez toujours rendre cette option indisponible en invalidant le flag ``focus'' de la barre de défilement.

Les comportements claviers ( qui ne sont bien sûr disponible que si le flag ``focus'' est actif) sont, pour des raisons évidentes, légèrement différents en fonction des widgets Range horizontaux et verticaux. Ils ne sont d'ailleurs pas tout à fait les mêmes selon qu'il s'agisse d'un widget échelle ou d'une barre de défilement, pour des raisons un peu moins évidentes ( peut-être pour éviter la confusion entre les touches pour la barre horizontale et ceux pour la barre verticale dans les fenêtres défilables, qui, chacune, opèrent dans le même domaine).

Tous les widgets Range verticaux peuvent être modifiés à l'aide des flèches vers le haut et vers le bas du clavier, aussi bien qu'avec les touches Page up et Page down. Les flèches montent et descendent le curseur selon le step_increment alors que Page up et Page down le modifie selon le page_increment. L'utilisateur peut aussi déplacer le curseur tout en haut ou tout en bas de la glissière à l'aide du clavier. Avec le widget VScale, c'est fait avec les touches Home et End alors qu'avec VScrollbar c'est fait en tapant Control_Page up et Control_Page down.

Les flèches droite et gauche agissent comme on peut s'y attendre sur le widget Range en bougeant le curseur selon le step_increment. Les touches Home et End bougent le curseur au début ou à la fin de la glissière. Pour le HScale widget, bouger le curseur selon le page_increment se fait à l'aide des touches Control_Right et Control_Left alors que pour le HScrollbar c'est Control_Home et Control_End.

Exemple

Cet exemple crée une fenêtre avec trois widgets Range, tous connectés au même réglage, et un couple de contrôle pour régler quelques uns des paramètres mentionnés ci-dessus dans la section sur les réglages. Ainsi, vous pourrez voir comment ils affectent la manière dont ces widgets fonctionnent pour l'utilisateur.

Range Widget

Vous remarquerez que le programme n'appelle pas signal_connect() pour le 'delete_event', mais seulement pour le signal 'destroy'. Cela accomplira tout de même la fonction désirée car un 'delete_event' sans gestionnaire se transformera en signal 'destroy' passé à la fenêtre.


next up previous contents
suivant: Les barres de défilements monter: Les widgets précédent: Les labels   Table des matières
LE BORGNE Patrice 2001-01-11