Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 1<br />
(aide à l’apprentissage - Jean Aboudarham)
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 2<br />
Table des matières<br />
I. RAPPELS <strong>IDL</strong> ..................................................................................................................................................... 3<br />
1) PASSAGES DE VALEURS ENTRE PROGRAMMES .................................................................................................... 3<br />
2) LES STRUCTURES............................................................................................................................................... 3<br />
3) QUELQUES RAPPELS DE REGLES D’ECRITURE...................................................................................................... 4<br />
II. PRINCIPE GENERAL DES WIDGETS........................................................................................................... 4<br />
1) GENERALITES.................................................................................................................................................... 4<br />
a) Qu’est-ce qu’un « widg<strong>et</strong> » ?........................................................................................................................ 4<br />
b) Qu’est-ce qu’un « compound widg<strong>et</strong> » ?....................................................................................................... 4<br />
2) HIERARCHIE...................................................................................................................................................... 4<br />
3) LES DIFFERENTS WIDGETS ................................................................................................................................. 5<br />
4) LES CONTROLES ................................................................................................................................................ 6<br />
III. PRATIQUE SIMPLE ....................................................................................................................................... 7<br />
1) LES WIDGETS, LEURS ARGUMENTS DE BASE ET LES STRUCTURES ASSOCIEES....................................................... 8<br />
a) widg<strong>et</strong>_base ................................................................................................................................................. 8<br />
b) widg<strong>et</strong>_button .............................................................................................................................................. 8<br />
c) widg<strong>et</strong>_draw................................................................................................................................................. 9<br />
d) widg<strong>et</strong>_droplist ............................................................................................................................................ 9<br />
e) widg<strong>et</strong>_label................................................................................................................................................. 9<br />
f) widg<strong>et</strong>_list .................................................................................................................................................. 10<br />
g) widg<strong>et</strong>_slider ............................................................................................................................................. 10<br />
h) widg<strong>et</strong>_table............................................................................................................................................... 11<br />
i) widg<strong>et</strong>_text ................................................................................................................................................. 11<br />
2) ROUTINE DE TRAITEMENT DES EVENEMENTS.................................................................................................... 12<br />
a) Widg<strong>et</strong>_control .......................................................................................................................................... 12<br />
b) La gestion des événements ......................................................................................................................... 13<br />
3) TRANSFERT D’ARGUMENTS ............................................................................................................................. 14<br />
4) UN EXEMPLE SIMPLE ....................................................................................................................................... 15<br />
IV. UN PEU DE COMPLEXITE.......................................................................................................................... 18<br />
1) ARGUMENTS COMPLEXES DES WIDGETS ........................................................................................................... 18<br />
a) Mots clés communs à la plupart des widg<strong>et</strong>s .............................................................................................. 18<br />
b) Widg<strong>et</strong>_base............................................................................................................................................... 19<br />
c) Widg<strong>et</strong>_button............................................................................................................................................ 20<br />
d) Widg<strong>et</strong>_draw.............................................................................................................................................. 20<br />
e) widg<strong>et</strong>_label............................................................................................................................................... 20<br />
f) widg<strong>et</strong>_table ............................................................................................................................................... 21<br />
g) widg<strong>et</strong>_text................................................................................................................................................. 21<br />
2) LES COMPOUND WIDGETS ................................................................................................................................ 22<br />
a) cw_bgroup ................................................................................................................................................. 22<br />
b) cw_defroi................................................................................................................................................... 23<br />
c) cw_field...................................................................................................................................................... 23<br />
d) cw_form..................................................................................................................................................... 24<br />
e) cw_fslider................................................................................................................................................... 24<br />
f) cw_pdmenu................................................................................................................................................. 24<br />
g) cw_zoom .................................................................................................................................................... 25<br />
3) REPRISE DE L'EXEMPLE DU DEBUT AVEC UN COMPOUND WIDGET...................................................................... 26<br />
4) WIDGET_INFO.................................................................................................................................................. 27<br />
5) UN EXEMPLE PLUS COMPLET DE WIDGET.......................................................................................................... 28<br />
INDEX ................................................................................................................................................................... 32
I. Rappels <strong>IDL</strong><br />
1) Passages de valeurs entre programmes<br />
Il existe trois façons de passer des arguments entre procédures (ou fonctions) :<br />
• Les arguments, qui sont des noms de variables, déterminés par leur nombre <strong>et</strong> leur position.<br />
Par exemple :<br />
plot,tab Un seul argument : tab. C’est le tableau de points à tracer<br />
plot,val_x,tab Deux arguments : val_x <strong>et</strong> tab. Le 1 er comporte le tableau de valeurs de<br />
l’axe des abcis<strong>ses</strong>, <strong>et</strong> le second le tableau des points à tracer.<br />
• Les mots-clés, sont caractérisés par leur nom auquel est associée une valeur grâce au signe ‘=‘.<br />
Leur position n’a aucune importance.<br />
Par exemple :<br />
tit=‘Tracé de la fonction tab’<br />
plot,tab,title=tit title est un mot-clé<br />
Rappelons que la syntaxe /keyword est équivalente à keyword = 1.<br />
• Les commons s’écrivent sous la forme common suivi d’un espace puis du nom du common<br />
séparé de noms de variables par des virgules. Par exemple :<br />
common mon_com,var1,var2,var3<br />
• Les commons passent de façon instantanée les valeurs des variables entre les programmes, y<br />
compris avec l’instance principale de <strong>IDL</strong> (celle où on peut entrer les commandes en ligne), alors<br />
que les arguments ne se passent qu’au début puis à la fin du programme appelé. Par contre, une<br />
fois qu’il a été déclaré (dans un programme ou en mode interactif), il est impossible de modifier<br />
le contenu d’un common (attention, il s’agit des variables qui le composent : leur nom, leur ordre,<br />
... ; pas du contenu des variables). Il faut alors quitter la <strong>ses</strong>sion <strong>IDL</strong> puis la relancer pour pouvoir<br />
le corriger.<br />
2) Les structures<br />
Les structures sont un format spécial de variable qui perm<strong>et</strong> de mélanger les types <strong>et</strong> les<br />
dimensions au sein d’un même nom. L’avantage est de pouvoir ainsi regrouper des éléments<br />
ayant des points communs ensemble, <strong>et</strong> de pouvoir les transférer entre des modules sous un nom<br />
unique de variable. Une structure se définit soit avec un nom, soit de façon « anonyme » :<br />
a={nom_structure, champ1:val1,champ2,val2,...} ou<br />
a={champ1:val1,champ2,val2,...}<br />
Pour connaître le contenu du champ i de la structure a, il suffit de taper :<br />
print,a.champi<br />
Une structure peut être un tableau. Pour créer un tableau b de 100 éléments de même structure<br />
que la structure a, il faut faire :<br />
b=replicate(a,100) ou, directement :<br />
b=replicate({champ1:val1,champ2:val2,...},100)<br />
Les valeurs des champs vont être soit des variables mi<strong>ses</strong> à 0 ou vides (dans le cas des chaînes de<br />
caractères) - ou directement leur contenu définitif - soit des déclarations de tableau. Par exemple :<br />
a={champ1:0,champ2:0.,champ3:’’,champ4:0L,champ5:strarr(12)}<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 3
Ici, champ1 est un entier, champ2 un réel, champ3 une chaîne de caractères, champ4 un<br />
entier long, champ5 un tableau de chaînes de caractères à 12 éléments.<br />
Si b = replicate(a,100), on peut accéder à la 5 ème structure par :<br />
print,b[4]<br />
On peut également accéder au champ2 de la 6 ème structure par :<br />
print,b[5].champ2<br />
Et on peut accéder à la 3 ème chaîne du champ5 de la 7 ème structure par :<br />
print,b[6].champ5[2]<br />
Pour obtenir le descriptif de la structure, il faut faire :<br />
help,b,/structure<br />
3) Quelques rappels de règles d’écriture<br />
Pour un mot-clé, faire précéder son nom de / équivaut à m<strong>et</strong>tre sa valeur à 1<br />
Les fonctions s’écrivent sous la forme : res = nom_fonction(param)<br />
Les tableaux s’écrivent avec des croch<strong>et</strong>s : tab[i,j]<br />
II. Principe général des widg<strong>et</strong>s<br />
1) Généralités<br />
a) Qu’est-ce qu’un « widg<strong>et</strong> » ?<br />
Un widg<strong>et</strong> est une fonction qui perm<strong>et</strong> de tracer un « obj<strong>et</strong> » graphique <strong>et</strong> de lui associer certaines<br />
actions. Ces obj<strong>et</strong>s graphiques peuvent être du texte, des fenêtres graphiques, des boutons, des<br />
menus, ... Quant aux actions associées, il peut s’agir de n’importe quelle commande <strong>IDL</strong>.<br />
Les widg<strong>et</strong>s perm<strong>et</strong>tent donc de construire des interfaces graphiques de programmes <strong>IDL</strong>, dont<br />
les widg<strong>et</strong>s sont les briques élémentaires.<br />
Leur fonctionnement est cependant légèrement différent de celui des procédures <strong>et</strong> fonctions<br />
standard <strong>IDL</strong>. <strong>IDL</strong> ne gère pas directement les widg<strong>et</strong>s. Ce travail est effectué par l’intermédiaire<br />
d’une procédure (XMANAGER), qui va gérer les interruptions <strong>et</strong> les événements générés par les<br />
widg<strong>et</strong>s pour les envoyer à une routine de traitement.<br />
Le résultat d’un widg<strong>et</strong> (car il s’agit d’une fonction) est un numéro d’identificateur.<br />
b) Qu’est-ce qu’un « compound widg<strong>et</strong> » ?<br />
Un compound widg<strong>et</strong> regroupe les actions de plusieurs widg<strong>et</strong>s de telle façon que sa gestion<br />
apparaisse aussi simple à l’utilisateur que celle d’un widg<strong>et</strong> de base. Par exemple, l’une de ceux<br />
fourni par <strong>IDL</strong> perm<strong>et</strong> de construire un groupe de boutons aussi simplement que si on en créait un<br />
seul.<br />
2) Hiérarchie<br />
La hiérarchie d’un widg<strong>et</strong> est définie par sa décomposition en éléments horizontaux <strong>et</strong> verticaux.<br />
Un widg<strong>et</strong> est formé d’une base qui correspond au cadre extérieur de ce que l’on veut tracer.<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 4
Ensuite, on définit des sous-ba<strong>ses</strong>, en fonction des découpages horizontaux ou verticaux<br />
compl<strong>et</strong>s dont on a besoin. La figure ci-dessous représente un widg<strong>et</strong> dont la base est le cadre.<br />
Il est structuré verticalement : un premier groupe formé de diver<strong>ses</strong> fenêtres <strong>et</strong> de boutons, une<br />
deuxième avec le texte ‘Info’ <strong>et</strong> une fenêtre de texte, <strong>et</strong> un troisième avec le bouton ‘Quitter’.<br />
Le premier groupe est structuré horizontalement : un premier sous groupe est formé du label <strong>et</strong> du<br />
bouton ainsi que du label <strong>et</strong> de la fenêtre ; le deuxième sous-groupe est constitué de boutons, <strong>et</strong> le<br />
troisième sous-groupe d’une fenêtre graphique.<br />
Le premier groupe est lui-même structuré verticalement, ainsi que le second.<br />
Et on décompose ce que l’on veut obtenir ainsi de suite, jusqu’à ne plus avoir besoin de changer<br />
de sens entre horizontal <strong>et</strong> vertical.<br />
3) Les différents widg<strong>et</strong>s<br />
Le nombre de widg<strong>et</strong>s qui existent est très limité. Il y en a 8 qui perm<strong>et</strong>tent de dessiner divers<br />
obj<strong>et</strong>s. Un qui perm<strong>et</strong> de définir les ba<strong>ses</strong> <strong>et</strong> sous-ba<strong>ses</strong>, un qui perm<strong>et</strong> de modifier ou créer des<br />
widg<strong>et</strong>s définis par ailleurs, <strong>et</strong> deux qui jouent un rôle spécial.<br />
Un certain nombre de « dialogues » ressemblent à des widg<strong>et</strong>s, mais leur utilisation est différente.<br />
Les principaux sont<br />
res=dialog_pickfile() <strong>et</strong><br />
res=dialog_message(‘message à afficher’)<br />
La distribution standard d’<strong>IDL</strong> contient enfin 13 compound widg<strong>et</strong>s d’intérêt divers, ainsi qu’un<br />
modèle (« template ») de compound widg<strong>et</strong> destiné à faciliter la création d’une telle fonction.<br />
Nous les verrons plus loin.<br />
Les principaux widg<strong>et</strong>s sont :<br />
widg<strong>et</strong>_base perm<strong>et</strong> de créer une base principale <strong>et</strong> des sous ba<strong>ses</strong><br />
widg<strong>et</strong>_button perm<strong>et</strong> de créer un bouton<br />
widg<strong>et</strong>_draw perm<strong>et</strong> de créer une fenêtre graphique<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 5
widg<strong>et</strong>_droplist affiche l’élément par défaut d’une liste. Quand on clique<br />
dessus, la liste complète apparaît, perm<strong>et</strong>tant une autre sélection qui<br />
remplace la précédente<br />
widg<strong>et</strong>_label affiche un texte statique (un label)<br />
widg<strong>et</strong>_list affiche une fenêtre contenant une liste d’éléments que l’on peut<br />
sélectionner individuellement. Si besoin est, un ascenseur l’accompagne<br />
widg<strong>et</strong>_slider affiche un curseur perm<strong>et</strong>tant de sélectionner une valeur entière entre deux<br />
bornes<br />
widg<strong>et</strong>_table affiche des éléments sous forme d’un tableau<br />
widg<strong>et</strong>_text affiche une fenêtre contenant du texte, soit statique, soit modifiable<br />
4) Les contrôles<br />
La façon dont sont gérés les widg<strong>et</strong>s, comme nous l’avons mentionné plus haut, ne ressemble pas<br />
à ce à quoi on est habitué avec <strong>IDL</strong>.<br />
Chaque widg<strong>et</strong> r<strong>et</strong>ourne des « événements » (‘events’) qu’il va falloir gérer comme on va le voir.<br />
Tout d’abord, une procédure contenant des widg<strong>et</strong>s n’est pas composée de la même façon que les<br />
procédures classiques, elle contient deux parties : l’une qui sert à composer, à l’aide de widg<strong>et</strong>s,<br />
l’interface graphique que l’on désire, <strong>et</strong> l’autre qui sert à interpréter en termes de commandes<br />
<strong>IDL</strong> l’eff<strong>et</strong> des événements renvoyés par les widg<strong>et</strong>s.<br />
Si le nom de la routine principale est ‘toto’, la routine de traitement des événements devra<br />
s’appeler ‘toto_event’. On peut s’affranchir de c<strong>et</strong>te contrainte, mais cela complique les cho<strong>ses</strong>.<br />
L’interface graphique que l’on crée se construit à l’aide d’un widg<strong>et</strong> spécial nommé<br />
widg<strong>et</strong>_control. Puis l’activation de c<strong>et</strong>te interface se fait à l’aide de la procédure<br />
xmanager qui va envoyer la main à un autre widg<strong>et</strong>, widg<strong>et</strong>_event, qui va perm<strong>et</strong>tre de<br />
récupérer <strong>et</strong> de pré-traiter les événements générés par les widg<strong>et</strong>s, avant de les renvoyer dans la<br />
routine de traitement des événements. C<strong>et</strong>te avant-dernière routine, widg<strong>et</strong>_event, est<br />
totalement transparente à l’utilisateur (qui peut l’appeler directement s’il le désire, mais <strong>IDL</strong> ne le<br />
recommande pas), car son nom n’apparaît nulle part de façon visible.<br />
La procédure xmanager, appelée dans la procédure de création de l’interface, perm<strong>et</strong> de gérer<br />
plusieurs interfaces en même temps. Il s’agit en quelque sorte d’une routine de gestion des<br />
interruptions (clic ou déplacement de souris, frappe de clavier).<br />
Quand, à la suite d’un plantage, on veut reprendre la main pour tuer un widg<strong>et</strong> qui reste dans un<br />
état commateux, il faut taper :<br />
xmanager<br />
sans aucun argument.<br />
La forme générale d’une procédure de création d’une interface par widg<strong>et</strong> est la suivante :<br />
pro nom_procédure_event,ev C’est la procédure de traitement des événements. ev<br />
est un élément spécial (une structure caractéristique,<br />
comme on le verra plus loin)<br />
routine de traitement des événements<br />
end<br />
pro nom_procédure, arguments procédure de création de l’interface<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 6
construction de l’interface<br />
widg<strong>et</strong>_control,nom_de_base,/realize on construit l’interface<br />
graphique<br />
xmanager,’nom_procédure’,nom_de_base on active l’interface pour gérer les<br />
interruptions<br />
end<br />
On remarquera que la routine de gestion des événements est placée dans le même fichier que la<br />
routine de création des widg<strong>et</strong>s, en première position. De plus, le nom du fichier doit être le nom<br />
de la routine de création, suivi de l’extension .pro. Dans notre exemple, ce serait<br />
nom_procédure.pro.<br />
Tous les événements renvoyés par les widg<strong>et</strong>s à la routine de traitement d’événements sont des<br />
structures. Et toutes ces structures ont leurs trois premiers champs identiques.<br />
La définition de la structure renvoyée par les widg<strong>et</strong>s commence par :<br />
ev = {id:0L,top:0L,handler:0L, ...}<br />
Le premier élément de c<strong>et</strong>te structure, ev.id, contient l’identificateur du widg<strong>et</strong>, c’est-à-dire un<br />
élément perm<strong>et</strong>tant de l’identifier. Le second, ev.top, contient l’identificateur du widg<strong>et</strong> de<br />
base de plus haut niveau contrôlant c<strong>et</strong>te interface. Le troisième, ev.handler, contient<br />
l’identificateur d’une éventuelle routine d’événements, comme nous le verrons plus loin. Pour<br />
l’instant, seuls les deux premiers champs nous intéressent parmi ces trois champs communs à<br />
tous les widg<strong>et</strong>s.<br />
En ce qui concerne xmanager, on peut lui adjoindre le mot-clé NO_BLOCK que l’on m<strong>et</strong> à 1 afin<br />
de perm<strong>et</strong>tre l’accès à d’autres routines, ou à la ligne de commande d’<strong>IDL</strong> :<br />
xmanager,’nom_procédure_event’,/no_block<br />
Du point de vue du programmeur, la gestion d’une routine contenant des widg<strong>et</strong>s va se faire de la<br />
façon suivante. Les widg<strong>et</strong>s sont créés <strong>et</strong> activés dans la routine principale (via widg<strong>et</strong>_control <strong>et</strong><br />
xmanager), <strong>et</strong>, à chaque fois que l’utilisateur intervient (en cliquant sur un widg<strong>et</strong>, en entrant du<br />
texte, ...), un événement est généré. C<strong>et</strong> événement est intercepté par la routine de gestion des<br />
événements. Nous verrons un peu plus loin la façon dont c<strong>et</strong>te routine récupère les informations<br />
<strong>et</strong> les gère.<br />
III. Pratique simple<br />
Chaque widg<strong>et</strong> dispose d’un certain nombre d’arguments qui vont perm<strong>et</strong>tre de les caractériser au<br />
mieux, <strong>et</strong> génère une structure (l’événement) qui lui est propre, contenant tous les renseignements<br />
utiles à son traitement, en plus des 3 champs mentionnés plus haut. Rappelons que chaque widg<strong>et</strong><br />
est une fonction qui renvoie le numéro d’identification du widg<strong>et</strong>.<br />
Les arguments <strong>et</strong> mots-clés indiqués ci-dessous suffisent à l’utilisation courante de la plupart des<br />
widg<strong>et</strong>s.<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 7
1) Les widg<strong>et</strong>s, leurs arguments de base <strong>et</strong> les structures associées<br />
a) widg<strong>et</strong>_base<br />
Sous sa forme : id = widg<strong>et</strong>_base(), ce widg<strong>et</strong> indique qu’il s’agit de la base de plus haut<br />
niveau, c’est-à-dire le cadre général de l’interface. Si on a :<br />
base=widg<strong>et</strong>_base()<br />
une sous-base de ‘base’ va s’écrire :<br />
ss_base=widg<strong>et</strong>_base(base)<br />
Les mots-clés pouvant accompagner ce widg<strong>et</strong> sont :<br />
/column indique que les éléments dépendant de c<strong>et</strong>te base s’agenceront en<br />
colonne, les uns en dessous des autres<br />
/exclusive indique que la base ne contient que des boutons, <strong>et</strong> qu’un seul d’entre eux<br />
pourra être sélectionné<br />
group_leader=id id contient l’identificateur d’un widg<strong>et</strong> déjà créé qui, s’il est détruit,<br />
entraînera la destruction de tous les widg<strong>et</strong>s dont il est le ‘group_leader’<br />
/nonexclusive indique que la base ne contient que des boutons, <strong>et</strong> que plusieurs d’entre<br />
eux peuvent être sélectionnés simultanément<br />
/row indique que les widg<strong>et</strong>s dépendant de c<strong>et</strong>te base s’agenceront en ligne,<br />
c’est-à-dire les uns à côté des autres<br />
/scroll indique que si la base dépasse la taille disponible, des ascenseurs au bord<br />
perm<strong>et</strong>tront d’en faire défiler les différentes parties<br />
title=chaÎne indique le titre de la base (valable seulement pour la base de plus haut<br />
niveau)<br />
uvalue=val perm<strong>et</strong> de transférer une valeur que l’on pourra simplement récupérer<br />
dans la routine de traitement des événements<br />
Pour l’instant, seuls les 3 premiers champs de la structure d’événement généré sont utiles :<br />
{widg<strong>et</strong>_base, id:0L, top:0L, handler:0L}<br />
b) widg<strong>et</strong>_button<br />
Ce widg<strong>et</strong> contient comme argument obligatoire le nom de la base dans laquelle il se trouve.<br />
Ses principaux mots-clés sont :<br />
group_leader=id cf. widg<strong>et</strong>_base<br />
uvalue=‘texte’ le texte indiqué comme valeur d’utilisateur (user value), dont on verra<br />
plus loin la grande utilité, peut être récupéré dans la routine de traitement<br />
des événements, perm<strong>et</strong>tant ainsi de reconnaître facilement un widg<strong>et</strong><br />
grâce à sa ‘uvalue’<br />
value=‘texte’ le texte indiqué est celui qui s’affiche dans le bouton<br />
units=val la valeur indiquée dans val indique le système d’unités utilisé : 0 =<br />
pixels (valeur par défaut), 1 = inches, 2 = centimètres<br />
xsize=val indique la dimension horizontale du bouton, dans l’unité précisée par<br />
units<br />
ysize=val indique la dimension verticale du bouton, dans l’unité précisée par units<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 8
Structure générée par ce widg<strong>et</strong> :<br />
{widg<strong>et</strong>_button, id:0L, top:0L, handler:0L, select:0}<br />
ev.select vaut 1 si le bouton est appuyé.<br />
c) widg<strong>et</strong>_draw<br />
Ce widg<strong>et</strong> contient comme argument obligatoire le nom de la base dans laquelle il se trouve.<br />
Ses principaux mots-clés sont :<br />
group_leader=id cf widg<strong>et</strong>_base<br />
/scroll perm<strong>et</strong> d’ajouter des ascenseurs si le contenu de la fenêtre est plus grand<br />
qu’elle<br />
units=val cf widg<strong>et</strong>_button<br />
uvalue=‘texte’ cf widg<strong>et</strong>_button<br />
value=var var est une variable qui contiendra le numéro de la fenêtre graphique<br />
ainsi ouverte. Cela perm<strong>et</strong>, si plusieurs fenêtres graphiques sont ouvertes,<br />
de choisir celle que l’on veut avec ws<strong>et</strong>,var<br />
xsize=val cf widg<strong>et</strong>_button<br />
ysize=val cf widg<strong>et</strong>_button<br />
Structure générée par ce widg<strong>et</strong> :<br />
{widg<strong>et</strong>_draw, id:0L, top:0L, handler:0L,type:0, x:0, y:0,<br />
press:0B, release:0B, clicks:0}<br />
Les différents champs se rapportent à des mots-clés que nous n’avons pas encore vus. ils seront<br />
explicités plus loin.<br />
d) widg<strong>et</strong>_droplist<br />
Ce widg<strong>et</strong> contient comme argument obligatoire le nom de la base dans laquelle il se trouve.<br />
Ses principaux mots-clés sont :<br />
group_leader=id cf widg<strong>et</strong>_base<br />
title=‘texte’ perm<strong>et</strong> d’ajouter un titre à la liste déroulante<br />
units=val cf widg<strong>et</strong>_button<br />
uvalue=val cf widg<strong>et</strong>_button<br />
value=str str contient une ‘string’ ou ‘strarr’ contenant les éléments de la liste<br />
xsize=val cf widg<strong>et</strong>_button<br />
Structure générée par ce widg<strong>et</strong> :<br />
{widg<strong>et</strong>_droplist, id:0L, top:0L, handler:0L, index:0L}<br />
index contient l’indice de l’élément de la liste qui a été sélectionné.<br />
e) widg<strong>et</strong>_label<br />
Ce widg<strong>et</strong> contient comme argument obligatoire le nom de la base dans laquelle il se trouve.<br />
Ses principaux mots-clés sont :<br />
group_leader=id cf widg<strong>et</strong>_base<br />
units=val cf widg<strong>et</strong>_button<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 9
value=‘texte’ contient le texte du label à afficher<br />
xsize=val cf widg<strong>et</strong>_button<br />
ysize=val cf widg<strong>et</strong>_button<br />
Aucune structure n’est générée par ce widg<strong>et</strong>.<br />
f) widg<strong>et</strong>_list<br />
Ce widg<strong>et</strong> contient comme argument obligatoire le nom de la base dans laquelle il se trouve.<br />
Ses principaux mots-clés sont :<br />
group_leader=id cf widg<strong>et</strong>_base<br />
/multiple perm<strong>et</strong> de sélectionner plusieurs éléments de la liste<br />
units=val cf widg<strong>et</strong>_button<br />
uvalue=‘texte’ cf widg<strong>et</strong>_button<br />
value=tab contient le tableau de strings formant la liste<br />
xsize=val cf widg<strong>et</strong>_button<br />
ysize=val cf widg<strong>et</strong>_button<br />
Structure générée par ce widg<strong>et</strong> :<br />
{widg<strong>et</strong>_list, id:0L, top:0L, handler:0L,index:0L, clicks:0L}<br />
index contient le numéro de l’élément qui a été sélectionné.<br />
clicks vaut 1 si on a cliqué une fois sur l’élément, 2 s’il s’est agi d’un double clic.<br />
g) widg<strong>et</strong>_slider<br />
Ce widg<strong>et</strong> contient comme argument obligatoire le nom de la base dans laquelle il se trouve.<br />
Ses principaux mots-clés sont :<br />
/drag génère continuement des événements quand on déplace le curseur<br />
group_leader=id cf widg<strong>et</strong>_base<br />
maximum=val valeur maximum du curseur en entiers (défaut = 100)<br />
minimum=val valeur minimum du curseur en entiers (défaut = 0)<br />
title=‘texte’ titre à afficher<br />
units=val cf widg<strong>et</strong>_button<br />
uvalue=‘texte’ cf widg<strong>et</strong>_button<br />
value=val valeur initiale à laquelle se trouve le curseur<br />
/vertical crée un curseur vertical<br />
xsize=val cf widg<strong>et</strong>_button<br />
ysize=val cf widg<strong>et</strong>_button<br />
Structure générée par ce widg<strong>et</strong> :<br />
{widg<strong>et</strong>_slider, id:0L, top:0L, handler:0L, value:0L, drag:0}<br />
value contient la nouvelle valeur du curseur<br />
On peut m<strong>et</strong>tre le champ drag à 0, quand on a utilisé /drag afin que les événements ne soient<br />
générés que quand on relâche le curseur.<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 10
h) widg<strong>et</strong>_table<br />
Ce widg<strong>et</strong> contient comme argument obligatoire le nom de la base dans laquelle il se trouve.<br />
Ses principaux mots-clés sont :<br />
column_labels=‘texte’ perm<strong>et</strong> d’entrer des titres de colonnes (string ou strarr)<br />
column_widths=val définit la largeur des colonnes (scalaire ou tableau)<br />
group_leader=id cf widg<strong>et</strong>_base<br />
/no_headers ne m<strong>et</strong> pas d’en-têtes aux lignes <strong>et</strong> colonnes<br />
row_heights=val définit la hauteur des lignes (scalaire ou tableau)<br />
row_labels=‘string’ perm<strong>et</strong> d’entrer des titres de lignes (string ou strarr)<br />
/scroll perm<strong>et</strong> d’afficher un ascenseur pour faire défiler la partie de la table qui<br />
est hors de la vue<br />
units=val cf widg<strong>et</strong>_button<br />
uvalue=‘texte’ cf widg<strong>et</strong>_button<br />
value=tab tableau de valeurs destiné à emplir la table<br />
xsize=val cf widg<strong>et</strong>_button<br />
ysize=val cf widg<strong>et</strong>_button<br />
/all_events <strong>et</strong> /editable cf tableau ci-dessous pour les combinaisons de ces<br />
deux mots-clés<br />
Mot-clé Eff<strong>et</strong><br />
all_events editable Une entrée change-telle<br />
le contenu du<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 11<br />
widg<strong>et</strong> ?<br />
Type d’action<br />
générant des<br />
événements<br />
0 0 Non Aucun<br />
0 1 Oui Insertion d’une fin de<br />
ligne (carriage r<strong>et</strong>urn)<br />
1 0 Non Tous les événements<br />
1 1 Oui Tous les événements<br />
Structure générée par ce widg<strong>et</strong> :<br />
{widg<strong>et</strong>_table, id:0L, top:0L, handler:0L, type= 0, ...}<br />
Le champ type indique le type de structure renvoyé à l’utilisateur. Cela n’étant pas utile pour<br />
l’instant, nous en parlerons plus loin.<br />
i) widg<strong>et</strong>_text<br />
Ce widg<strong>et</strong> contient comme argument obligatoire le nom de la base dans laquelle il se trouve.<br />
Ses principaux mots-clés sont :<br />
group_leader=id cf widg<strong>et</strong>_base<br />
/scroll cf widg<strong>et</strong>_draw<br />
units=val cf widg<strong>et</strong>_button<br />
uvalue=‘texte’ cf widg<strong>et</strong>_button<br />
value=string texte contenu dans le widg<strong>et</strong><br />
/wrap coupe automatiquement les lignes trop longues
xsize=val cf widg<strong>et</strong>_button<br />
ysize=val cf widg<strong>et</strong>_button<br />
/all_events <strong>et</strong> /editable cf tableau ci-dessous pour les combinaisons de ces<br />
deux mots-clés<br />
Mot-clé Eff<strong>et</strong><br />
all_events editable Une entrée change-t- Type d’action<br />
elle le contenu du générant des<br />
widg<strong>et</strong> ?<br />
événements<br />
0 0 Non Aucun<br />
0 1 Oui Insertion d’une fin de<br />
ligne (carriage r<strong>et</strong>urn)<br />
1 0 Non Tous les événements<br />
1 1 Oui Tous les événements<br />
Structure générée par ce widg<strong>et</strong> :<br />
{widg<strong>et</strong>_list, id:0L, top:0L, handler:0L, type:0, ...}<br />
Le champ type indique le type de structure renvoyé. Nous verrons plus loin les autres champs.<br />
2) Routine de traitement des événements<br />
a) Widg<strong>et</strong>_control<br />
widg<strong>et</strong>_control est un widg<strong>et</strong> spécial comparé aux autres. Tout d’abord, il s’agit d’une<br />
procédure, <strong>et</strong> non pas d’une fonction. Son rôle est de réaliser, gérer <strong>et</strong> détruire les widg<strong>et</strong>s. Il<br />
s’applique à un identificateur de widg<strong>et</strong> :<br />
widg<strong>et</strong>_control,id<br />
suit alors un mot-clé qui va définir les actions de modification du widg<strong>et</strong> dont l’id est indiqué.<br />
Ces mots clés vont perm<strong>et</strong>tre de changer la valeur des mots-clés utilisés lors de la création du<br />
widg<strong>et</strong>.<br />
Les formes de base de widg<strong>et</strong>_control sont :<br />
widg<strong>et</strong>_control,id,/realize construit toute la hiérarchie de widg<strong>et</strong> dont id est<br />
l’élément le plus haut<br />
widg<strong>et</strong>_control,id,/destroy détruit toute la hiérarchie de widg<strong>et</strong> dont id est<br />
l’élément le plus haut<br />
Les principaux mots-clés pouvant accompagner widg<strong>et</strong>_control sont :<br />
all_table_events, ainsi que all_text_events, conjointement avec editable<br />
modifient le type de génération d’événements de widg<strong>et</strong>_table <strong>et</strong> widg<strong>et</strong>_text suivant<br />
les tables indiquées plus haut dans la description de ces widg<strong>et</strong>s.<br />
/append utilisé avec s<strong>et</strong>_value (voir plus loin), perm<strong>et</strong> d’ajouter le texte<br />
courant (défini par s<strong>et</strong>_value) au texte que contient déjà un<br />
widg<strong>et</strong>_text<br />
column_labels=‘texte’ perm<strong>et</strong> de changer les titres de colonnes dans un<br />
widg<strong>et</strong>_table<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 12
column_width=val perm<strong>et</strong> de changer les largeurs de colonnes dans un<br />
widg<strong>et</strong>_table<br />
edit_cell=[x,y] rend éditable la colonne x, ligne y d’une table d’un<br />
widg<strong>et</strong>_table<br />
g<strong>et</strong>_uvalue=var m<strong>et</strong> dans la variable var le contenu de la ‘user value’ uvalue du<br />
widg<strong>et</strong> impliqué<br />
g<strong>et</strong>_value=var m<strong>et</strong> dans la variable var le contenu défini par le mot-clé value du<br />
widg<strong>et</strong> impliqué (voir pour chaque widg<strong>et</strong> le contenu de value)<br />
group_leader=id perm<strong>et</strong> de rattacher le widg<strong>et</strong> courant à une hiérarchie (ainsi, un<br />
même widg<strong>et</strong> peut être rattaché à plusieurs hiérarchies, mais on ne<br />
peut pas le r<strong>et</strong>irer d’une hiérarchie)<br />
/hourglass affiche une p<strong>et</strong>ite montre indiquant que la machine travaille, jusqu’à<br />
ce qu’un nouvel événement soit généré. Utile par exemple quand on<br />
charge un gros fichier de données, pour que l’utilisateur ne croie<br />
pas la machine ‘plantée’<br />
/iconify transforme en icône le widg<strong>et</strong> courant <strong>et</strong> toute sa hiérarchie<br />
(iconify=0 le réagrandit)<br />
map=0 fait disparaître le widg<strong>et</strong> de l’écran, mais il existe toujours. Pour le<br />
faire réapparaître, m<strong>et</strong>tre /map<br />
row_labels=‘texte’ perm<strong>et</strong> de changer les titres de lignes d’un widg<strong>et</strong>_table<br />
row_heights=val perm<strong>et</strong> de changer la hauteur des lignes d’un widg<strong>et</strong>_table<br />
sensitive=0 rend ‘insensible’ un widg<strong>et</strong> <strong>et</strong> sa hiérarchie descendante. Pour le<br />
rendre à nouveau sensible, faire /sensitive<br />
s<strong>et</strong>_button=val si val = 0, désélectionne le bouton, sinon, le sélectionne (peut<br />
dépendre des mots-clés exclusive <strong>et</strong> non_exclusive de<br />
widg<strong>et</strong>_base)<br />
s<strong>et</strong>_text_top_line=val affiche le texte d’un widg<strong>et</strong>_text en commençant par la<br />
ligne val<br />
s<strong>et</strong>_uvalue=‘texte’ change la valeur de uvalue (user value)<br />
s<strong>et</strong>_value=val change le contenu de value du widg<strong>et</strong> impliqué<br />
tlb_s<strong>et</strong>_title=‘texte’ change le titre de la base la plus haute de la hiérarchie<br />
units=val change le type d’unités choisi pour le widg<strong>et</strong> courant<br />
xsize=val change la taille horizontale du widg<strong>et</strong><br />
ysize=val change la taille verticale du widg<strong>et</strong><br />
b) La gestion des événements<br />
La gestion des événements va se faire, comme on l'a vu, dans la routine qui va se trouver en tête<br />
de fichier, du type :<br />
pro nom_de_procédure_event,ev<br />
ev est l'événement engendré par le widg<strong>et</strong> qui a réagi ; <strong>et</strong> c'est grâce à la procédure<br />
widg<strong>et</strong>_control que nous allons pouvoir savoir ce qui s'est passé.<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 13
Le champ ev.id de la structure ev nous donne l’identificateur du widg<strong>et</strong> qui a réagi. Ainsi, on<br />
peut en extraire des informations. L’une des plus utiles que l’on peut espérer récupérer est la<br />
valeur utilisateur du widg<strong>et</strong>, uvalue. Cela se fait de la façon suivante, où var est une variable<br />
quelconque :<br />
widg<strong>et</strong>_control,ev.id,g<strong>et</strong>_uvalue=var<br />
Si on a pris soin de donner une valeur utilisateur explicite <strong>et</strong> différente pour chaque widg<strong>et</strong><br />
utilisé, la lecture de celle-ci nous indique immédiatement quel widg<strong>et</strong> a été sollicité.<br />
Ainsi, en testant c<strong>et</strong>te valeur (grâce à CASE, particulièrement), on peut diriger la gestion des<br />
événements vers telle ou telle partie du programme qui effectuera la tâche assignée au widg<strong>et</strong>.<br />
3) Transfert d’arguments<br />
Il est souvent utile de transférer des arguments (ie des variables) entre la procédure qui crée les<br />
widg<strong>et</strong>s, <strong>et</strong> celle qui gère les événements, ou entre des appels successifs à la routine de gestion<br />
des événements. Ces arguments peuvent être classiquement un numéro de fenêtre associé à<br />
widg<strong>et</strong>_draw, l’identificateur d’un widg<strong>et</strong> dont le contenu peut être modifié en cours de<br />
programme (comme une fenêtre de texte de widg<strong>et</strong>_text, par exemple), ou même des<br />
variables (comme quand on a chargé une image <strong>et</strong> que l’on veut pouvoir en faire une coupe…).<br />
Le problème est qu’après la création de l’interface, la main est passée à xmanager qui gère la<br />
queue des événements, puis à widg<strong>et</strong>_event qui « conditionne » les événements pour aboutir<br />
enfin à la routine de gestion des événements, <strong>et</strong> que ce cycle est permanent entre ces trois<br />
dernières routines. Le transfert d’arguments ou de variables n’est donc pas possible de façon<br />
directe.<br />
Deux solutions existent.<br />
• La première, la plus simple à m<strong>et</strong>tre en œuvre, mais moins « propre » <strong>et</strong> plus lourde, consiste à<br />
utiliser un common qui va se trouver à la fois dans la routine de création <strong>et</strong> dans la routine de<br />
gestion des événements. On y m<strong>et</strong> toutes les variables utiles. Avantage, on a directement sous les<br />
yeux ces variables. Inconvénient, un common qui a été compilé ne peut plus être modifié, ou<br />
alors, il faut quitter <strong>IDL</strong>, le relancer, modifier le contenu du common, <strong>et</strong> re-compiler le<br />
programme.<br />
• L’autre solution consiste à utiliser une valeur utilisateur pour transm<strong>et</strong>tre une structure<br />
contenant toutes les variables utiles. Comme on l’a vu au début de c<strong>et</strong>te section, les valeurs<br />
utilisateur peuvent être utilisées pour identifier les widg<strong>et</strong>s. En ce cas, rien n’empêche d’utiliser<br />
la valeur utilisateur de la base principale. Ou, si celle-ci est déjà utilisée (quand plusieurs<br />
interfaces simultanées sont affichées), créer une sous-base de la base principale à laquelle sera<br />
rattachée toute la hiérarchie :<br />
base=widg<strong>et</strong>_base()<br />
child=widg<strong>et</strong>_base(base,uval=ma_structure)<br />
...<br />
Ainsi, grâce à widg<strong>et</strong>_control, il est possible de récupérer la structure en question.<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 14
4) Un exemple simple<br />
Pour commencer, nous allons étudier un exemple simple de création de widg<strong>et</strong>. Le but est<br />
d’entrer un texte court dans une p<strong>et</strong>ite fenêtre. S’il nous convient, on l’ajoute dans une plus<br />
grande fenêtre au texte existant, sinon, on l’efface <strong>et</strong> rien ne se passe. On peut de plus, bien sûr,<br />
quitter l’application. L’image ci-dessous montre l’aspect de ce que l’on souhaite obtenir :<br />
La p<strong>et</strong>ite fenêtre du haut perm<strong>et</strong> d’entrer le texte (avec un label au-dessus), puis les trois boutons,<br />
perm<strong>et</strong>tant (de gauche à droite respectivement) de valider l’entrée, de l’annuler, <strong>et</strong> de quitter le<br />
logiciel. Enfin, le label ‘Affichage’ surmonte la fenêtre où l’ensemble des textes entrés va<br />
s’afficher.<br />
On remarque que la structure principale de ce widg<strong>et</strong> est en colonne (les éléments sont les uns au<br />
dessus des autres), mais que les boutons ont une structure en ligne.<br />
Voici le listing de c<strong>et</strong>te interface (une procédure appelée exo1.pro), la routine de gestion des<br />
événements précède la procédure de création de l’interface, comme expliqué plus haut :<br />
pro w_exo1_event,ev Routine de traitement des événements<br />
common ex1,txt,wintxt,txt2,txt1 On récupère les valeurs utiles grâce au common<br />
widg<strong>et</strong>_control,ev.id,g<strong>et</strong>_uvalue=uval On récupère la valeur utilisateur du widg<strong>et</strong> qui a réagi<br />
case uval of On teste c<strong>et</strong>te valeur<br />
'u_txt1':<br />
widg<strong>et</strong>_control,ev.id,g<strong>et</strong>_value=txt<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 15<br />
S’il s’agit de la p<strong>et</strong>ite fenêtre de texte, le texte entré<br />
s’accumule l<strong>et</strong>tre après l<strong>et</strong>tre (à cause du mot-clé<br />
/all_events utilisé à la création) dans la variable txt<br />
'u_bu_ok': begin S’il s’agit du bouton OK :<br />
wintxt=wintxt+txt On rajoute au texte contenu dans la grande fenêtre le<br />
contenu de txt<br />
txt='' On rem<strong>et</strong> txt à zéro pour la suite<br />
widg<strong>et</strong>_control,txt1,s<strong>et</strong>_value=txt On efface le contenu de la p<strong>et</strong>ite fenêtre de texte<br />
widg<strong>et</strong>_control,txt2,s<strong>et</strong>_value=wintxt On affiche le nouveau texte de la grande fenêtre<br />
end<br />
'u_bu_eff': begin S’il s’agit du bouton Effacer :<br />
txt='' On vide la variable txt<br />
widg<strong>et</strong>_control,txt1,s<strong>et</strong>_value=txt On efface la p<strong>et</strong>ite fenêtre de texte<br />
end
'u_bu_quit':<br />
widg<strong>et</strong>_control,ev.top,/destroy<br />
S’il s’agit du bouton Quitter, on détruit le widg<strong>et</strong><br />
endcase Fin du test sur la valeur de uval<br />
end Fin de la routine de traitement des événements<br />
pro w_exo1 Début de la routine de création de l’interface<br />
common ex1,txt,wintxt,txt2,txt1 Définition du common contenant toutes les valeurs<br />
qu’il est utile de transférer dans la routine de<br />
traitement des événements<br />
txt='' On initialise à vide le texte de la p<strong>et</strong>ite fenêtre de texte<br />
wintxt='' On initialise à vide le texte de la grande fenêtre de<br />
texte<br />
base=widg<strong>et</strong>_base(/column) On crée la base générale, <strong>ses</strong> “enfants“ seront en une<br />
colonne (les uns en dessous des autres)<br />
lbl1=widg<strong>et</strong>_label(base,value='Entrez un On affiche le label du haut<br />
texte')<br />
txt1=widg<strong>et</strong>_text(base,value='',uvalue= $ On crée la p<strong>et</strong>ite fenêtre de texte, vide, en lui donnant<br />
'u_txt1',xsize=40,ysize=1, $ une dimension fixe (en nombre de caractères), en lui<br />
/editable,/all_events)<br />
donnant une valeur utilisateur, éditable, <strong>et</strong> réagissant à<br />
chaque entrée de caractère (afin d’éviter d’attendre<br />
que la touche ‘R<strong>et</strong>urn’ ou ‘Entrée’ soit utilisée)<br />
b1=widg<strong>et</strong>_base(base,/row) On crée une sous-base en ligne pour les boutons<br />
bu_ok=widg<strong>et</strong>_button(b1,value='OK',uvalue Création du 1<br />
='u_bu_ok')<br />
er bouton avec son contenu <strong>et</strong> sa valeur<br />
utilisateur associée<br />
bu_eff=widg<strong>et</strong>_button(b1,value='Effacer',<br />
uvalue='u_bu_eff')<br />
Création du 2ème bouton<br />
bu_quit=widg<strong>et</strong>_button(b1,value='Quitter'<br />
,uvalue='u_bu_quit')<br />
Création du 3ème bouton<br />
lbl2=widg<strong>et</strong>_label(base,value='Affichage'<br />
)<br />
txt2=widg<strong>et</strong>_text(base,value='',xsize=20,<br />
ysize=5,/wrap,/scroll)<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 16<br />
Création du label de la grande fenêtre de texte<br />
Création de la grande fenêtre de texte (20 caractères<br />
sur 5 lignes), en demandant que les lignes soient<br />
automatiquement coupées entre les mots, <strong>et</strong> qu’un<br />
ascenseur apparaisse si le texte dépasse les 5 lignes<br />
widg<strong>et</strong>_control,base,/realize On construit le widg<strong>et</strong> d’ensemble<br />
xmanager,'w_exo1',base On passe la main pour la gestion des événements<br />
end<br />
On vient de voir une façon de concevoir ce programme en utilisant le common. Voici<br />
maintenant, ci-dessous, rigoureusement le même programme, mais utilisant c<strong>et</strong>te fois-ci le<br />
transfert d’une structure en uvalue de la base principale :<br />
pro w_exo1_1_event,ev Routine de gestion des événements<br />
widg<strong>et</strong>_control,ev.id,g<strong>et</strong>_uvalue=uval On récupère la uvalue du widg<strong>et</strong> qui a réagi<br />
widg<strong>et</strong>_control,ev.top,g<strong>et</strong>_uvalue=struc On récupère la structure mise en uvalue de la base
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 17<br />
principale<br />
case uval of Test sur uval<br />
'u_txt1': begin P<strong>et</strong>ite fenêtre de texte :<br />
widg<strong>et</strong>_control,ev.id,g<strong>et</strong>_value=txt On récupère son contenu<br />
struc.txt=txt On le m<strong>et</strong> dans la structure<br />
widg<strong>et</strong>_control,ev.top,s<strong>et</strong>_uvalue= $ On m<strong>et</strong> la structure corrigée dans uvalue de la base<br />
struc<br />
end<br />
principale<br />
'u_bu_ok': begin Bouton OK :<br />
struc.wintxt=struc.wintxt+struc.txt On ajoute au champ de la structure contenant le texte<br />
de la grande fenêtre le contenu du champ de la<br />
structure contenant le texte de la p<strong>et</strong>ite fenêtre<br />
struc.txt='' On m<strong>et</strong> le champ contenant le texte de la p<strong>et</strong>ite<br />
fenêtre à vide<br />
widg<strong>et</strong>_control,struc.txt1, $ On m<strong>et</strong> dans le widg<strong>et</strong> de la p<strong>et</strong>ite fenêtre (dont l’ID<br />
s<strong>et</strong>_value=struc.txt<br />
est dans struc.txt1) la chaîne vide<br />
widg<strong>et</strong>_control,struc.txt2, $ On affiche la nouvelle chaîne de la grande fenêtre<br />
s<strong>et</strong>_value=struc.wintxt<br />
(dont l’ID est dans struc.txt2)<br />
widg<strong>et</strong>_control,ev.top,s<strong>et</strong>_uvalue= $ On sauvegarde la nouvelle valeur de la structure<br />
struc<br />
end<br />
'u_bu_eff': begin Bouton Effacer :<br />
struc.txt='' On m<strong>et</strong> le champ txt à vide (contenu de la p<strong>et</strong>ite<br />
fenêtre)<br />
widg<strong>et</strong>_control,struc.txt1, $ On remplace le texte de la p<strong>et</strong>ite fenêtre (dont l’ID est<br />
s<strong>et</strong>_value=struc.txt<br />
dans struc.txt1) par le contenu vide de struc.txt<br />
widg<strong>et</strong>_control,ev.top,s<strong>et</strong>_uvalue= $ On sauvegarde la nouvelle valeur de la structure<br />
struc<br />
end<br />
'u_bu_quit': $<br />
widg<strong>et</strong>_control,ev.top,/destroy<br />
endcase Fin du test du uval<br />
end<br />
Bouton Quitter : on détruit le widg<strong>et</strong><br />
pro w_exo1_1 Routine de création de l’interface<br />
struc={txt:'',wintxt:'',txt2:0L,txt1:0L} Définition de la structure contenant tous les éléments<br />
utiles<br />
base=widg<strong>et</strong>_base(/column,uval=struc) On définit la base (par colonne) avec la structure<br />
comme uvalue<br />
lbl1=widg<strong>et</strong>_label(base,value= $<br />
Création du label du haut<br />
'Entrez un texte')<br />
txt1=widg<strong>et</strong>_text(base,value='',uvalue= $ Création de la p<strong>et</strong>ite fenêtre de texte<br />
'u_txt1',xsize=40,ysize=1, $<br />
/editable,/all_events)<br />
b1=widg<strong>et</strong>_base(base,/row) Création de la sous-base (en ligne) pour les boutons<br />
bu_ok=widg<strong>et</strong>_button(b1,value='OK', $ Création du bouton ‘OK’
uvalue='u_bu_ok')<br />
bu_eff=widg<strong>et</strong>_button(b1,value= $<br />
'Effacer', uvalue='u_bu_eff')<br />
bu_quit=widg<strong>et</strong>_button(b1,value= $<br />
'Quitter',uvalue='u_bu_quit')<br />
lbl2=widg<strong>et</strong>_label(base,value= $<br />
'Affichage')<br />
txt2=widg<strong>et</strong>_text(base,value='', $<br />
xsize=20,ysize=5,/wrap,/scroll)<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 18<br />
Création du bouton ‘Effacer’<br />
Création du bouton ‘Quitter’<br />
Création du second label<br />
Création de la grande fenêtre de texte<br />
widg<strong>et</strong>_control,base,/realize Réalisation de l’interface (<strong>et</strong> donc assignation d’ID à<br />
chaque widg<strong>et</strong>)<br />
struc.txt2=txt2 L’ID de la grande fenêtre de texte va dans<br />
struc.txt2<br />
struc.txt1=txt1 L’ID de la p<strong>et</strong>ite fenêtre de texte va dans<br />
struc.txt1<br />
widg<strong>et</strong>_control,base,s<strong>et</strong>_uvalue=struc La structure mise à jour est sauvée dans la uvalue<br />
de la base principale<br />
xmanager,'w_exo1_1',base On passe la main pour la gestion des événements<br />
end<br />
IV. Un peu de complexité<br />
Nous allons maintenant voir quelques autres possibilités liées aux widg<strong>et</strong>s <strong>et</strong> à leur création. Nous<br />
ne les verrons pas toutes, bien sûr, car avant de pouvoir utiliser toutes les options possibles, il est<br />
indispensable d’être déjà bien familiarisé avec l’utilisation standard des widg<strong>et</strong>s.<br />
1) Arguments complexes des widg<strong>et</strong>s<br />
Nous allons examiner quelques mots clés supplémentaires (<strong>et</strong> quelques alternatives à certains que<br />
l’on a déjà vus).<br />
a) Mots clés communs à la plupart des widg<strong>et</strong>s<br />
/no_copy Ce mot clé est l'équivalent de la fonction <strong>IDL</strong><br />
temporary. C'est-à-dire qu'il perm<strong>et</strong> de ne pas<br />
recopier les valeurs de value, mais de les transférer<br />
directement, économisant ainsi de la mémoire<br />
frame=val Donne l'épaisseur du cadre. Attention, la valeur que l'on<br />
donne se réfère au choix d'unité précisé par unit<br />
event_function='nom_fonction' Envoie directement l'événement généré dans la<br />
fonction indiquée. Si c<strong>et</strong>te fonction r<strong>et</strong>ourne une<br />
structure dont les 3 premiers champs sont ID, TOP <strong>et</strong><br />
HANDLER, ce résultat est envoyé comme événement à<br />
la routine de traitement des événements. Sinon, la main<br />
revient à xmanager. Perm<strong>et</strong> donc d'intervenir avant<br />
d'effectuer le traitement (c'est la méthode utilisée,<br />
comme on le verra plus loin, pour créer des compound<br />
widg<strong>et</strong>s)
event_pro='nom_procédure' Envoie directement l'événement généré dans la<br />
procédure indiquée avant de rendre la main à<br />
xmanager. Perm<strong>et</strong> par exemple d'associer un bouton à<br />
la création d'une nouvelle interface<br />
func_g<strong>et</strong>_value='nom_fonction' Quand on lance la commande<br />
widg<strong>et</strong>_control,id,g<strong>et</strong>_value= ..., la<br />
fonction indiquée s'exécute avant de renvoyer le résultat<br />
comme valeur<br />
pro_s<strong>et</strong>_value='nom_procédure' Quand on lance la commande<br />
widg<strong>et</strong>_control,id,s<strong>et</strong>_value=..., la<br />
procédure indiquée s'exécute, ce qui perm<strong>et</strong> de m<strong>et</strong>tre<br />
dans value un nouveau résultat<br />
b) Widg<strong>et</strong>_base<br />
/align_bottom<br />
/align_top<br />
/align_center<br />
/align_left<br />
/align_right<br />
/base_align_bottom<br />
/base_align_top<br />
/base_align_center<br />
/base_align_left<br />
/base_align_right<br />
mbar=var<br />
app_mbar=var<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 19<br />
Ces cinq mots clés perm<strong>et</strong>tent de<br />
définir l'alignement de la base en cours<br />
par rapport à son parent. Les 3 premiers<br />
s'appliquent quand le mot clé /row du<br />
parent est mis, les 3 derniers quand le<br />
mot clé /column a été mis<br />
Identique à la série précédente, mais<br />
s'appliquent aux 'enfants' de la base en<br />
cours<br />
Ne fonctionne que sur la base de plus<br />
haut niveau. Perm<strong>et</strong> de m<strong>et</strong>tre un menu<br />
sur c<strong>et</strong>te base. app_mbar perm<strong>et</strong> sur<br />
Macintosh de remplacer la barre de<br />
menu système. Voir dans la section<br />
suivante, widg<strong>et</strong>_button, son<br />
fonctionnement. Incompatible avec<br />
/modal<br />
/floating Associé à group_leader=id : perm<strong>et</strong> de créer une<br />
base de plus haut niveau flottante, liée au<br />
group_leader indiqué<br />
map=0 ou 1 map=0 rend la base <strong>et</strong> <strong>ses</strong> enfants invisible ; map=1 la<br />
rend visible. Incompatible avec /modal<br />
/modal Perm<strong>et</strong> de créer une base qui contiendra un dialogue<br />
avec des boutons ; associée à un group_leader. Les<br />
boutons pourront être l'acceptation ou l'annulation de ce<br />
qui a été fait dans ce nouveau widg<strong>et</strong>. Une base 'modale'<br />
bloque tous les autres widg<strong>et</strong>s tant qu'elle n'a pas été<br />
détruite
tlb_frame_attr=val Définit les actions possibles sur la base :<br />
1 : ne peut être redimensionnée<br />
2 : supprime l'affichage du menu du système<br />
4 : supprime la barre de titre (sauf sur Mac)<br />
8 : ne peut être fermée<br />
16 : ne peut être déplacée<br />
On peut combiner ces actions en ajoutant les valeurs<br />
indiquées les unes aux autres<br />
c) Widg<strong>et</strong>_button<br />
/align_center<br />
/align_left<br />
/align_right<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 20<br />
Définit le type de justification du texte qui se<br />
trouve dans le bouton (défaut =<br />
/align_center)<br />
/separator Affiche un séparateur dans un menu déroulant<br />
value=tab tab est un tableau à deux dimensions, qui est une<br />
image bitmap. En ce cas, le texte du bouton est<br />
remplacé par l'image formée par tab<br />
/menu indique que le bouton en question est le titre d'un menu<br />
déroulant. Lié aux mots clés mbar <strong>et</strong> app_mbar de<br />
widg<strong>et</strong>_base. Exemple :<br />
base=widg<strong>et</strong>_base(mbar=bar)<br />
menu1=widg<strong>et</strong>_button(bar,value='Menu1',/menu<br />
)<br />
but1=widg<strong>et</strong>_button(menu1,value='Un')<br />
but2=widg<strong>et</strong>_button(menu1,value='Deux')<br />
d) Widg<strong>et</strong>_draw<br />
/motion_events Envoie des événements quand la souris se déplace sur la<br />
fenêtre graphique. Cela crée une structure de la forme :<br />
{widg<strong>et</strong>_draw, id:0L, top:0L,<br />
handler:0L, type:0, x:0, y:0,<br />
press:0B, release:0B, clicks:0}<br />
type = 0 : bouton appuyé, 1 : bouton relâché, 2 :<br />
mouvement, 3 : scrolling, 4 : changement de visibilité.<br />
x <strong>et</strong> y donnent la position en coordonnées de la fenêtre.<br />
clicks =1 si simple clic, =2 si double clic<br />
/button_events Génère des événements quand le bouton de la souris est<br />
cliqué sur la fenêtre graphique.<br />
e) widg<strong>et</strong>_label<br />
/align_center<br />
/align_left<br />
/align_right<br />
Définit le type de justification pour le label
f) widg<strong>et</strong>_table<br />
Suivant le type d'action qui a lieu avec ce widg<strong>et</strong> (dont les possibilités sont définies par<br />
/all_events <strong>et</strong> /editable), la structure renvoyée est différente. On a vu que le champ<br />
ev.type détermine la structure. Nous allons voir quelques-unes de ces structures, les autres<br />
sont à regarder dans la partie widg<strong>et</strong>_table de <strong>IDL</strong> Reference Guide (tome 2) :<br />
• Type = 0 : Insertion d'un caractère<br />
{widg<strong>et</strong>_table_ch, id:0L, top:0L, handler:0L, type:0, offs<strong>et</strong>:0L,<br />
ch:0B, x:0L, y:0L}<br />
offs<strong>et</strong> = position (de 0 à n) du caractère inséré ; ch est sa valeur ASCII, x <strong>et</strong> y sont les<br />
numéros de colonne <strong>et</strong> de ligne de la cellule où l'insertion a lieu.<br />
• Type = 1 : Collé de plusieurs caractères<br />
{widg<strong>et</strong>_table_str, id:0L, top:0L, handler:0L, type:1, offs<strong>et</strong>:0L,<br />
str='', x:0L, y:0L}<br />
offs<strong>et</strong>, x <strong>et</strong> y : même signification que ci-dessus. str = chaîne inserrée.<br />
• Type = 2 : Effacement de texte<br />
{widg<strong>et</strong>_table_del, id:0L, top:0L, handler:0L, type:2, offs<strong>et</strong>:0L,<br />
length:0L,x:0L, y:0L}<br />
offs<strong>et</strong>, x, y : idem. Length = nombre de caractères impliqués dans l'effacement.<br />
• Type = 3 : Sélection de texte<br />
{widg<strong>et</strong>_table_ch, id:0L, top:0L, handler:0L, type:3,<br />
offs<strong>et</strong>:0L,length:0L,x:0L, y:0L}<br />
Mêmes significations que ci-dessus<br />
• Type = 4 : Sélection de cellule<br />
{widg<strong>et</strong>_table_ch, id:0L, top:0L, handler:0L, type:4, sel_left:0L,<br />
sel_top:0L, sel_right:0L, sel_bottom:0L}<br />
sel_left, ... donnent les numéros de cellules (de 0 à n) extrêmes sélectionnées.<br />
• Type = 6 : Changement de hauteur de ligne.<br />
• Type = 7 : Changement de largeur de colonne.<br />
• Type = 8 : erreur dans le format de données entré par l'utilisateur.<br />
g) widg<strong>et</strong>_text<br />
/no_newline Empêche l'insertion automatique d'un r<strong>et</strong>our chariot à la<br />
fin de chaque ligne quand le texte est sur plusieurs<br />
lignes<br />
Suivant le type d'action qui a lieu avec ce widg<strong>et</strong> (dont les possibilités sont définies par<br />
/all_events <strong>et</strong> /editable), la structure renvoyée est différente. On a vu que le champ<br />
ev.type détermine la structure :<br />
• Type = 0 : Insertion d'un caractère<br />
{widg<strong>et</strong>_text_ch, id:0L, top:0L, handler:0L, type:0, offs<strong>et</strong>:0L,<br />
ch:0B}<br />
offs<strong>et</strong> est la position d'insertion (de 0 à n) du caractère, dont le code ASCII est dans ch.<br />
• Type = 1 : Insertion de plusieurs caractères<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 21
{widg<strong>et</strong>_text_ch, id:0L, top:0L, handler:0L, type:1, offs<strong>et</strong>:0L,<br />
str=''}<br />
offs<strong>et</strong> = position d'insertion. str= chaîne à insérer<br />
• Type = 2 : Effacement de texte<br />
{widg<strong>et</strong>_text_ch, id:0L, top:0L, handler:0L, type:2, offs<strong>et</strong>:0L,<br />
length:0L}<br />
offs<strong>et</strong> = position (de 0 à n) du 1 er caractère à effacer. Length = nombre de caractères effacés.<br />
• Type = 3 : Sélection de texte<br />
{widg<strong>et</strong>_text_ch, id:0L, top:0L, handler:0L, type:3, offs<strong>et</strong>:0L,<br />
length:0L}<br />
offs<strong>et</strong> = position du 1 er caractère à sélectionner. Length = nombre de caractères sélectionnés.<br />
2) Les compound widg<strong>et</strong>s<br />
Les compound widg<strong>et</strong>s (appelés ci-après CW) sont des programmes ayant l'apparence d'un<br />
widg<strong>et</strong>, mais regroupant en réalité plusieurs widg<strong>et</strong>s.<br />
Leur utilisation est semblable à celle des widg<strong>et</strong>s standards, <strong>et</strong> ils envoient des événements dont<br />
la structure est semblable à celle des widg<strong>et</strong>s (c'est-à-dire que les trois premiers champs sont id,<br />
top <strong>et</strong> handler).<br />
Les CW sont basés sur l'utilisation de fonction d'interception des événements générés pour les<br />
traiter <strong>et</strong> les décomposer avant de renvoyer l'information utile à l'utilisateur.<br />
Leur nom commence toujours par cw_ <strong>et</strong> on trouvera toute l'information les concernant dans <strong>IDL</strong><br />
Reference Guide (tome 1), à la rubrique de leur nom.<br />
Un utilisateur confirmé des widg<strong>et</strong>s pourra se m<strong>et</strong>tre à créer lui-même des CW au gré de <strong>ses</strong><br />
besoins. L'idée présidant à leur conception est qu'ils forment des regroupements utiles de widg<strong>et</strong>s<br />
que l'on peut utiliser dans des routines différentes comme s'il s'agissait de simple widg<strong>et</strong>s.<br />
Voici un bref descriptif des principaux CW.<br />
a) cw_bgroup<br />
Ce CW perm<strong>et</strong> de créer un groupe de boutons d'une seule commande. Sa forme d'appel est :<br />
id = cw_bgroup(parent, noms)<br />
où parent est l'ID du parent de ce CW, <strong>et</strong> noms est un tableau chaîne de caractères contenant<br />
le nom de chaque bouton. Nous verrons dans la section 3) ci-dessous un exemple d'utilisation de<br />
ce CW.<br />
L'événement ev r<strong>et</strong>ourné par ce CW renvoie entre autres le champ value qui donne, suivant le<br />
mot-clé associé lors de la création, l'indice du bouton, son ID, son nom, ou la valeur utilisateur<br />
correspondante.<br />
Les principaux mots-clés qui lui sont associés sont :<br />
button_uvalue=string_array Tableau contenant les uvalue de chaque bouton. Ce<br />
mot-clé l'emporte toujours sur les mots-clés de la forme<br />
/r<strong>et</strong>urn_xxx<br />
/column m<strong>et</strong> les boutons en colonne<br />
/exclusive identique à widg<strong>et</strong>_base<br />
label_left=txt m<strong>et</strong> un label à gauche du bouton<br />
label_top=txt m<strong>et</strong> un label au dessus du bouton<br />
/nonexclusive identique à widg<strong>et</strong>_base<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 22
<strong>et</strong>urn_id renvoie dans le champ value l'ID du bouton<br />
sélectionné<br />
/r<strong>et</strong>urn_index renvoie dans le champ value l'indice du bouton<br />
sélectionné<br />
/r<strong>et</strong>urn_name renvoie dans le champ value le nom du bouton<br />
sélectionné<br />
/row m<strong>et</strong> les boutons en ligne<br />
/scroll perm<strong>et</strong> d'afficher un ascenseur pour faire apparaître les<br />
boutons hors cadre<br />
b) cw_defroi<br />
Ce CW perm<strong>et</strong> de définir une région d'intérêt (id de la délimiter) sur une image. Il est modal, ce<br />
qui signifie qu'il bloque les autres widg<strong>et</strong>s. Son utilisation se fait sous la forme :<br />
res=cw_defroi(draw)<br />
où draw est l'id du widg<strong>et</strong>_draw où l'on délimite la région. res est un tableau d'indices<br />
définissant la région. On peut ainsi créer un nouveau tableau formé uniquement de la région<br />
choisie par :<br />
new_tab = old_tab(res)<br />
Le widg<strong>et</strong>_draw utilisé doit être accompagné des mots-clés /motion_events <strong>et</strong><br />
/button_events.<br />
c) cw_field<br />
Perm<strong>et</strong> de créer un ensemble formé d'un label plus un champ d'entrée de valeur (texte par défaut)<br />
:<br />
id=cw_field(parent)<br />
Notez que chaque interrogation widg<strong>et</strong>_control, id, g<strong>et</strong>_value=x renvoie le contenu<br />
du champ.<br />
Les principaux mots-clés pouvant lui être associés sont :<br />
/all_events génère un événement à chaque changement du contenu<br />
/r<strong>et</strong>urn_events génère un événement à chaque r<strong>et</strong>our chariot<br />
/column centre le label au-dessus du champ<br />
/floating convertit automatiquement l'entrée en réel<br />
/integer convertit automatiquement l'entrée en entier<br />
/long convertit automatiquement l'entrée en entier long<br />
/string convertit automatiquement l'entrée en chaîne<br />
/noedit rend le champ non éditable<br />
/row m<strong>et</strong> le label à gauche du champ (= défaut)<br />
title=str label (défaut = "Input Field")<br />
uvalue=str valeur utilisateur<br />
value=val contenu initial du champ (automatiquement converti<br />
suivant le type choisi)<br />
L'événement engendré par cw_field a la forme :<br />
ev={id:0L, top:0L, handler:0L, value:'', type:0, update:0}<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 23
value contient le contenu du champ. Type indique le type d'entrée (0 = string, 1 = float, 2 =<br />
interger, 3 = long integer) ; <strong>et</strong> update vaut 0 si rien n'a été modifié, 1 sinon.<br />
d) cw_form<br />
Ce CW perm<strong>et</strong> de créer des formulaires (mélange de texte, champs numériques, boutons, listes <strong>et</strong><br />
listes déroulantes). Son utilisation est relativement complexe suivant ce que l'on désire faire. Se<br />
reporter à <strong>IDL</strong> Reference Guide tome 1 pour plus d'informations.<br />
e) cw_fslider<br />
Crée un curseur perm<strong>et</strong>tant de choisir des valeurs réelles :<br />
id=cw_fslider(parent)<br />
Son utilisation est semblable à celle de widg<strong>et</strong>_slider. Ses principaux mots-clés sont :<br />
/drag cf widg<strong>et</strong>_slider<br />
/edit rend éditable le label du curseur<br />
Maximum = val cf widg<strong>et</strong>_slider<br />
Minimum = val cf widg<strong>et</strong>_slider<br />
Title=str Label du curseur<br />
uvalue=str valeur utilisateur<br />
/vertical cf widg<strong>et</strong>_slider<br />
value=val position initiale du curseur<br />
Le champ ev.value du l'événement engendré renvoie la valeur réelle choisie à l'aide du<br />
curseur.<br />
f) cw_pdmenu<br />
Perm<strong>et</strong> de créer un menu déroulant. ev.value renvoie l'indice du bouton sélectionné, son ID,<br />
son nom ou son nom compl<strong>et</strong>, suivant le mot-clé associé à ce CW.<br />
id = cw_pdmenu(parent,desc)<br />
desc est un tableau chaîne de caractère qui va décrire le menu déroulant. Chacun de <strong>ses</strong><br />
éléments s'écrit sous la forme :<br />
'flag\item_name' (attention, il s'agit d'un backslash)<br />
item_name est l'intitulé du bouton.<br />
flag = 0 Le bouton n'est ni le début ni la fin d'un niveau déroulant<br />
flag = 1 Le bouton est la racine d'un sous menu déroulant (le sous-menu commence avec le<br />
bouton suivant)<br />
flag = 2 Le bouton est le dernier du sous-menu déroulant actuel<br />
flag = 3 Le bouton est le dernier du sous-menu déroulant actuel, mais c'est aussi la racine<br />
d'un sous-menu déroulant.<br />
Exemple :<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 24
Desc=['1\Titre','0\zéro', $<br />
'1\un>','0\aa', $<br />
'0\bb','3\cc','0\0',<br />
$<br />
'2\1','2\deux']<br />
Les principaux mots-clés associés sont :<br />
/mbar Crée le menu déroulant sur la barre de menu. Le parent<br />
doit être la barre de menu de la base la plus haute<br />
/r<strong>et</strong>urn_id renvoie dans ev.value l'ID du bouton sélectionné<br />
/r<strong>et</strong>urn_index renvoie dans ev.value l'indice du bouton sélectionné<br />
/r<strong>et</strong>urn_name renvoie dans ev.value le nom du bouton sélectionné<br />
(cc> par exemple)<br />
/r<strong>et</strong>urn_full_name renvoie dans ev.value le nom compl<strong>et</strong> du bouton<br />
sélectionné (par exemple, pour le bouton '1',<br />
ev.value='Titre.un>.cc.1'). Chaque niveau<br />
de menu est séparé du précédent par un point.<br />
D'autres formes d'utilisation de cd CW existent. Consulter <strong>IDL</strong> Reference Guide, tome 1 pour<br />
plus d'informations.<br />
g) cw_zoom<br />
Affiche deux images : l'originale, <strong>et</strong> une portion zoomée de celle-ci dans une autre fenêtre.<br />
id = cw_zoom(parent)<br />
L'image se charge par :<br />
Widg<strong>et</strong>_control,id,s<strong>et</strong>_value=data<br />
Les principaux mots-clés l'accompagnant sont :<br />
max=val Valeur maximum de zoom (déf = 20), ≥ 1<br />
min=val Valeur minimum de zoom (déf = 1) ≥ 1<br />
sample=val Type d'échantillonnage. Défaut = 0 (bilinéaire) ; ≠ 0<br />
pour une interpolation avec le voisin le plus proche<br />
scale=val valeur entière de facteur d'échelle initial pour le zoom<br />
(défaut = 4) ≥ 1<br />
xsize=val <strong>et</strong> ysize=val Taille en pixels de la fenêtre initiale (défaut = 500x500)<br />
x_zsize=val <strong>et</strong> y_zsize=val Taille en pixels de la fenêtre de zoom (défaut =<br />
250x250)<br />
Pour récupérer l'image zoomée, il faut faire :<br />
widg<strong>et</strong>_control,id,g<strong>et</strong>_value=tab<br />
L'événement engendré par cw_zoom a l'aspect suivant :<br />
ev={zoom_event,id:0L, top:0L, handler:0L, xsize:0L, ysize:0L,<br />
x0:0L, y0:0L, x1:0L, y1:0L}<br />
xsize <strong>et</strong> ysize sont les dimensions de l'image zoomée ; x0 <strong>et</strong> y0 sont les coordonnées du<br />
coin inférieur gauche où commence le zoom ; <strong>et</strong> x1, y1 du coin supérieur droit.<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 25
3) Reprise de l'exemple du début avec un compound widg<strong>et</strong><br />
Voici ci-dessous l'exemple de widg<strong>et</strong> présenté dans le III 4). La série de boutons est ici créée par<br />
le compound widg<strong>et</strong> cw_bgroup.<br />
pro w_exo1_2_event,ev<br />
widg<strong>et</strong>_control,ev.id,g<strong>et</strong>_uvalue=uval<br />
widg<strong>et</strong>_control,ev.top,g<strong>et</strong>_uvalue=struc<br />
case uval of<br />
'u_txt1': begin<br />
widg<strong>et</strong>_control,ev.id,g<strong>et</strong>_value=txt<br />
struc.txt=txt<br />
widg<strong>et</strong>_control,ev.top,s<strong>et</strong>_uvalue=struc<br />
end<br />
'u_butt': begin<br />
val=ev.value<br />
case val of<br />
'u_bu_ok': begin<br />
struc.wintxt=struc.wintxt+struc.txt<br />
struc.txt=''<br />
widg<strong>et</strong>_control,struc.txt1,s<strong>et</strong>_value=struc.txt<br />
widg<strong>et</strong>_control,struc.txt2,s<strong>et</strong>_value=struc.wintxt<br />
widg<strong>et</strong>_control,ev.top,s<strong>et</strong>_uvalue=struc<br />
end<br />
'u_bu_eff': begin<br />
struc.txt=''<br />
widg<strong>et</strong>_control,struc.txt1,s<strong>et</strong>_value=struc.txt<br />
widg<strong>et</strong>_control,ev.top,s<strong>et</strong>_uvalue=struc<br />
end<br />
'u_bu_quit': widg<strong>et</strong>_control,ev.top,/destroy<br />
endcase<br />
end<br />
endcase<br />
end<br />
pro w_exo1_2<br />
struc={txt:'', wintxt:'',txt2:0L, txt1:0L, butt:0L}<br />
base=widg<strong>et</strong>_base(/column,uval=struc)<br />
lbl1=widg<strong>et</strong>_label(base,value='Entrez un texte')<br />
txt1=widg<strong>et</strong>_text(base,value='',uvalue='u_txt1',xsize=40,ysize=1,/editable,/all<br />
_events)<br />
b_val=['OK','Effacer','Quitter']<br />
b_uval=['u_bu_ok','u_bu_eff','u_bu_quit']<br />
butt=cw_bgroup(base,b_val,/row,button_uvalue=b_uval,uvalue='u_butt')<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 26
lbl2=widg<strong>et</strong>_label(base,value='Affichage')<br />
txt2=widg<strong>et</strong>_text(base,value='',xsize=20,ysize=5,/wrap,/scroll)<br />
widg<strong>et</strong>_control,base,/realize<br />
struc.txt2=txt2<br />
struc.txt1=txt1<br />
struc.butt=butt<br />
widg<strong>et</strong>_control,base,s<strong>et</strong>_uvalue=struc<br />
xmanager,'w_exo1_2',base<br />
end<br />
4) widg<strong>et</strong>_info<br />
Ce widg<strong>et</strong> est spécial : son seul but est de fournir des informations sur un widg<strong>et</strong> dont l’ID lui sert<br />
d’argument :<br />
res=widg<strong>et</strong>_info(id)<br />
Voici quelques uns des 46 mots-clés qui peuvent l’accompagner :<br />
Mot-clé Widg<strong>et</strong> concerné Description<br />
/child Tous Renvoie l’ID du 1 er ‘enfant’ (0 si aucun)<br />
/droplist_number Widg<strong>et</strong>_droplist Renvoie le nombre d’éléments dans la liste<br />
/droplist_select Widg<strong>et</strong>_droplist Renvoie le numéro de l’item sélectionné dans la liste<br />
/event_func Tous Renvoie le nom de la fonction d’interception de la<br />
gestion des événements<br />
/event_pro Tous Renvoie le nom de la procédure d’interception de la<br />
gestion des événements<br />
/geom<strong>et</strong>ry Tous Renvoie les dimensions diver<strong>ses</strong> du widg<strong>et</strong> sous<br />
forme d’une structure (cd <strong>IDL</strong> Reference Guide)<br />
/list_number Widg<strong>et</strong>_list Renvoie le nombre d’éléments de la liste<br />
/list_num_visible Widg<strong>et</strong>_list Renvoie le nombre d’éléments visibles dans la<br />
fenêtre<br />
/list_select Widg<strong>et</strong>_list Renvoie le nombre d’éléments sélectionnés dans la<br />
liste (-1 si aucun)<br />
/list_top Widg<strong>et</strong>_list Renvoie le numéro de l’élément du haut visible dans<br />
la fenêtre<br />
/name Tous Renvoie le nom du widg<strong>et</strong> (base, button, draw, ...)<br />
/parent Tous Renvoie l’ID du parent (0 si aucun)<br />
/slider_min_max Widg<strong>et</strong>_slider Renvoie un tableau à 2 éléments dont le premier est<br />
la valeur min du curseur, <strong>et</strong> le second la valeur max<br />
/text_number Widg<strong>et</strong>_text Renvoie le nombre de caractères contenu dans le<br />
widg<strong>et</strong>_text<br />
/unit Tous Renvoie le type d’unités : 0 = pixels, 1 = inches, 2 =<br />
centimètres<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 27
5) Un exemple plus compl<strong>et</strong> de widg<strong>et</strong><br />
Le but de c<strong>et</strong> exemple est de construire une interface perm<strong>et</strong>tant d'effectuer les opérations<br />
suivantes :<br />
Charger un fichier texte, d'extension .lst contenant une série de noms de fichiers précédée du<br />
nombre de fichiers. Sélectionner l'un de ces fichiers, le charger <strong>et</strong> l'afficher. Pouvoir en tracer la<br />
surface, la surface ombrée <strong>et</strong> l'isocontour, sauver le tracé au format jpeg. Puis recommencer avec<br />
un autre fichier. On souhaite de plus qu'une ligne d'informations renseigne sur les opérations en<br />
cours.<br />
Voici l'aspect général que l'on veut donner à l'interface (on l’a déjà vue dans le II) :<br />
On constate tout d'abord que la base générale est organisée en une colonne. Sa partie supérieure<br />
est organisée en ligne dont la partie gauche est en colonne, qui se décompose pour la partie haute<br />
en ligne ; <strong>et</strong> la partie centrale, avec les boutons est en colonne. C'est ainsi que l'on va définir les<br />
ba<strong>ses</strong> nécessaires à la construction de c<strong>et</strong>te interface.<br />
Voici le listing :<br />
pro w_exo2_event,ev ; Routine de traitement des événements<br />
common ex2, lst, txt, w_num,indice,ld,filen,data,jp ; Transfert d'arguments<br />
widg<strong>et</strong>_control,ev.id,g<strong>et</strong>_uvalue=uval ; On récupère la valeur utilisateur<br />
case uval of ; <strong>et</strong> on la teste<br />
'u_but1': begin ; Bouton de chargement fichier texte<br />
fn=dialog_pickfile(filter='*.lst')<br />
if strlen(fn) ne 0 then begin<br />
nb_el=0<br />
openr,lun,fn,/g<strong>et</strong>_lun<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 28
eadf,lun,nb_el<br />
filen=strarr(nb_el)<br />
readf,lun,filen<br />
free_lun,lun<br />
widg<strong>et</strong>_control,lst,s<strong>et</strong>_value=filen ; On affiche dans le widg<strong>et</strong>_list les<br />
; noms de fichiers<br />
endif<br />
end<br />
'u_lst': begin ; Un nom de fichier a été sélectionné<br />
indice=fix(ev.index)<br />
widg<strong>et</strong>_control,txt,s<strong>et</strong>_value='Fichier '+ filen[indice] + ' sélectionné'<br />
; Texte dans la fenêtre d'informations<br />
end<br />
'u_bu_load': begin ; On charge le fichier sélectionné<br />
if indice ne -1 then begin<br />
widg<strong>et</strong>_control,txt,s<strong>et</strong>_value="Chargement en cours"<br />
; Texte dans la fenêtre d'informations<br />
openr,lun,filen[indice],/g<strong>et</strong>_lun<br />
data=intarr(382,286)<br />
readf,lun,data<br />
free_lun,lun<br />
ws<strong>et</strong>,w_num<br />
tvscl,data<br />
ld=1<br />
widg<strong>et</strong>_control,txt,s<strong>et</strong>_value="Chargement terminé"<br />
; Texte dans la fenêtre d'informations<br />
endif<br />
end<br />
'u_bu_sav': begin ; Le bouton 'Save JPEG' est cliqué<br />
if ld then begin<br />
widg<strong>et</strong>_control,txt,s<strong>et</strong>_value="Sauvegarde en cours"<br />
; Texte dans la fenêtre d'informations<br />
ws<strong>et</strong>,w_num<br />
dat=tvrd()<br />
fn='exo2_'+strcompress(string(jp),/remove_all)+'.jpeg'<br />
write_jpeg,fn,dat<br />
jp=jp+1<br />
widg<strong>et</strong>_control,txt,s<strong>et</strong>_value="Fichier "+fn+' sauvé'<br />
; Texte dans la fenêtre d'informations<br />
endif<br />
end<br />
'u_bu_surf': begin ; Le bouton 'Surface' est cliqué<br />
if ld then begin<br />
ws<strong>et</strong>,w_num<br />
surface,data<br />
endif<br />
end<br />
'u_bu_shad': begin ; Le bouton 'Shade_surf' est cliqué<br />
if ld then begin<br />
ws<strong>et</strong>,w_num<br />
shade_surf,data<br />
endif<br />
end<br />
'u_bu_iso': begin ; Le bouton 'Isocontour' est cliqué<br />
if ld then begin<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 29
ws<strong>et</strong>,w_num<br />
image_cont,data<br />
endif<br />
end<br />
'u_bu_quit': widg<strong>et</strong>_control,ev.top,/destroy ; Pour quitter, on détruit la base<br />
; principale<br />
endcase<br />
end<br />
pro w_exo2 ; Routine de création de l'interface<br />
common ex2, lst, txt, w_num,indice,ld,filen,data,jp<br />
; On m<strong>et</strong> en common les données utiles : l'ID du widg<strong>et</strong>_list, l'ID de la fenêtre texte<br />
d'information, le<br />
; numéro de fenêtre (qui n'est pas indispensable puisqu'il n'y en a qu'une), l'indice du fichier<br />
; sélectionné dans la liste de noms de fichiers, un indicateur disant si un fichier est chargé ou non,<br />
la<br />
; liste des noms de fichiers, les données à manipuler quand elles ont été chargées, <strong>et</strong> un compteur<br />
qui<br />
; s'incrémente à mesure des sauvegardes en jpeg afin de ne pas écraser un ancien fichier.<br />
; Initialisation des valeurs<br />
filen=''<br />
indice=-1<br />
ld=0<br />
jp=0<br />
base=widg<strong>et</strong>_base(/column) ; Base de plus haut niveau<br />
b1=widg<strong>et</strong>_base(base,/row) ; Sous-base pour la partie supérieure<br />
b11=widg<strong>et</strong>_base(b1,/column) ; Sous-sous-base pour le haut-gauche<br />
b111=widg<strong>et</strong>_base(b11,/row) ; sous-sous-sous-base pour la 1 ère ligne<br />
lbl1=widg<strong>et</strong>_label(b111,value='Fichier texte')<br />
but1=widg<strong>et</strong>_button(b111,value='Lire',uvalue='u_but1')<br />
lbl2=widg<strong>et</strong>_label(b11,value="Liste d'images")<br />
lst=widg<strong>et</strong>_list(b11,value=filen,uvalue='u_lst',xsize=35,ysize=6)<br />
b12=widg<strong>et</strong>_base(b1,/column) ; Sous-base pour les boutons<br />
bu_load=widg<strong>et</strong>_button(b12,value='Load', uvalue='u_bu_load')<br />
bu_sav=widg<strong>et</strong>_button(b12,value='Save JPEG', uvalue='u_bu_sav')<br />
bu_surf=widg<strong>et</strong>_button(b12,value='Surface',uvalue='u_bu_surf')<br />
bu_shad=widg<strong>et</strong>_button(b12,value='Shade_surf',uvalue='u_bu_shad')<br />
bu_iso=widg<strong>et</strong>_button(b12,value='Isocontour',uvalue='u_bu_iso')<br />
w_gr=widg<strong>et</strong>_draw(b1,uvalue='u_w_gr',xsize=382,ysize=286) ; Fenêtre graphique<br />
b2=widg<strong>et</strong>_base(base,/row) ; Sous-base pour la fenêtre d'informations<br />
lbl3=widg<strong>et</strong>_label(b2,value='Infos')<br />
txt=widg<strong>et</strong>_text(b2,value='',xsize=40,ysize=1)<br />
bu_quit=widg<strong>et</strong>_button(base,value='Quitter',uvalue='u_bu_quit')<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 30
widg<strong>et</strong>_control,base,/realize ; Réalisation du widg<strong>et</strong><br />
widg<strong>et</strong>_control,w_gr,g<strong>et</strong>_value=w_num ; Récupération du numéro de fenêtre graphique<br />
xmanager,'w_exo2',base ; Passage du contrôle à xmanager<br />
end<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 31
no_copy ........................... 18<br />
arguments................................ 3<br />
commons................................. 3<br />
compound widg<strong>et</strong> .................... 4<br />
compound widg<strong>et</strong>s................. 22<br />
cw_bgroup ............................ 22<br />
/column......................... 22<br />
/exclusive .................. 22<br />
/nonexclusive ........... 22<br />
/r<strong>et</strong>urn_id .................. 23<br />
/r<strong>et</strong>urn_index ........... 23<br />
/r<strong>et</strong>urn_name ............. 23<br />
/row................................ 23<br />
/scroll......................... 23<br />
button_uvalue ........... 22<br />
label_left .................. 22<br />
label_top .................... 22<br />
cw_defroi .............................. 23<br />
cw_field ................................ 23<br />
/all_events................ 23<br />
/column......................... 23<br />
/floating .................... 23<br />
/integer....................... 23<br />
/long.............................. 23<br />
/noedit......................... 23<br />
/r<strong>et</strong>urn_events......... 23<br />
/row................................ 23<br />
/string......................... 23<br />
title.............................. 23<br />
Type................................ 24<br />
update ........................... 24<br />
uvalue ........................... 23<br />
value......................... 23,24<br />
cw_form................................ 24<br />
cw_fslider.............................. 24<br />
/drag.............................. 24<br />
/edit.............................. 24<br />
/vertical .................... 24<br />
Maximum......................... 24<br />
Minimum......................... 24<br />
Title.............................. 24<br />
uvalue ........................... 24<br />
value.............................. 24<br />
cw_pdmenu........................... 24<br />
/mbar.............................. 25<br />
/r<strong>et</strong>urn_full_name.. 25<br />
/r<strong>et</strong>urn_id .................. 25<br />
/r<strong>et</strong>urn_index ........... 25<br />
/r<strong>et</strong>urn_name ............. 25<br />
cw_zoom............................... 25<br />
max .................................. 25<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 32<br />
Index<br />
min .................................. 25<br />
sample ........................... 25<br />
scale.............................. 25<br />
x_zsize ......................... 25<br />
x0..................................... 25<br />
x1..................................... 25<br />
xsize.............................. 25<br />
y_zsize ......................... 25<br />
y0..................................... 25<br />
y1..................................... 25<br />
ysize.............................. 25<br />
ev.handler......................... 7<br />
ev.id .................................... 7<br />
ev.top.................................. 7<br />
event_function.............. 18<br />
event_pro ......................... 19<br />
frame .................................. 18<br />
func_g<strong>et</strong>_value.............. 19<br />
gestion des événements.......... 13<br />
help....................................... 4<br />
/structure............................. 4<br />
mots-clés ................................. 3<br />
pro_s<strong>et</strong>_value................ 19<br />
structures................................. 3<br />
template................................... 5<br />
temporary ......................... 18<br />
transfert d’arguments............. 14<br />
widg<strong>et</strong> ..................................... 4<br />
widg<strong>et</strong>_base .............. 5,8,19<br />
/align_bottom ........ Voir<br />
/align_center ........... 19<br />
/align_left................ 19<br />
/align_right.............. 19<br />
/align_top .................. 19<br />
/base_align_bottom 19<br />
/base_align_center 19<br />
/base_align_left .... 19<br />
/base_align_right.. 19<br />
/base_align_top....... 19<br />
/column............................... 8<br />
/exclusive .................... 8<br />
/floating .................... 19<br />
/modal ........................... 19<br />
/nonexclusive ............. 8<br />
/row.................................. 8<br />
/scroll ........................... 8<br />
app_mbar....................... 19<br />
group_leader................ 8<br />
map .................................. 19<br />
mbar................................ 19<br />
title................................ 8<br />
tlb_frame_attr......... 20<br />
uvalue ............................. 8<br />
widg<strong>et</strong>_button.......... 5,8,20<br />
/align_center ........... 20<br />
/align_left................ 20<br />
/align_right.............. 20<br />
/menu.............................. 20<br />
/separator .................. 20<br />
ev.select....................... 9<br />
group_leader................ 8<br />
units................................ 8<br />
uvalue ............................. 8<br />
value........................... 8,20<br />
xsize................................ 8<br />
ysize................................ 8<br />
widg<strong>et</strong>_control........... 6,12<br />
/append ......................... 12<br />
/destroy....................... 12<br />
/hourglass .................. 13<br />
/iconify....................... 13<br />
/realize....................... 12<br />
all_table_events .... 12<br />
all_text_events....... 12<br />
column_labels ........... 12<br />
column_width.............. 13<br />
edit_cell..................... 13<br />
editable....................... 12<br />
g<strong>et</strong>_uvalue .................. 13<br />
g<strong>et</strong>_value..................... 13<br />
group_leader.............. 13<br />
map .................................. 13<br />
row_heights................ 13<br />
row_labels .................. 13<br />
sensitive..................... 13<br />
s<strong>et</strong>_button .................. 13<br />
s<strong>et</strong>_text_top_line .. 13<br />
s<strong>et</strong>_uvalue .................. 13<br />
s<strong>et</strong>_value..................... 13<br />
tlb_s<strong>et</strong>_title ........... 13<br />
units.............................. 13<br />
xsize.............................. 13<br />
ysize.............................. 13<br />
widg<strong>et</strong>_draw............... 5,9,20<br />
/button_events......... 20<br />
/motion_events......... 20<br />
/scroll ........................... 9<br />
group_leader................ 9<br />
units................................ 9<br />
uvalue ............................. 9<br />
value................................ 9<br />
xsize................................ 9
ysize................................ 9<br />
widg<strong>et</strong>_droplist .......... 6,9<br />
group_leader ............... 9<br />
index................................ 9<br />
title................................ 9<br />
units................................ 9<br />
uvalue ............................. 9<br />
value................................ 9<br />
xsize................................ 9<br />
widg<strong>et</strong>_event .................... 6<br />
widg<strong>et</strong>_info ........................... 27<br />
/child ................................ 27<br />
/droplist_numbe................ 27<br />
/droplist_select.................. 27<br />
/event_func....................... 27<br />
/event_pro......................... 27<br />
/geom<strong>et</strong>ry.......................... 27<br />
/list_num_visible .............. 27<br />
/list_number...................... 27<br />
/list_select......................... 27<br />
/list_top............................. 27<br />
/name................................ 27<br />
/parent .............................. 27<br />
/slider_min_max ............... 27<br />
/text_number..................... 27<br />
/unit .................................. 27<br />
widg<strong>et</strong>_label ............ 6,9,20<br />
/align_center ........... 20<br />
/align_left................ 20<br />
/align_right ............. 20<br />
group_leader ............... 9<br />
units................................ 9<br />
value.............................. 10<br />
xsize.............................. 10<br />
<strong>IDL</strong> <strong>et</strong> <strong>ses</strong> widg<strong>et</strong>s 33<br />
ysize.............................. 10<br />
widg<strong>et</strong>_list ................. 6,10<br />
/multiple .................... 10<br />
clicks ........................... 10<br />
group_leader.............. 10<br />
index.............................. 10<br />
units.............................. 10<br />
uvalue ........................... 10<br />
value.............................. 10<br />
xsize.............................. 10<br />
ysize.............................. 10<br />
widg<strong>et</strong>_slider............. 6,10<br />
/drag.............................. 10<br />
/vertical .................... 10<br />
group_leader.............. 10<br />
maximum ......................... 10<br />
minimum ......................... 10<br />
title.............................. 10<br />
units.............................. 10<br />
uvalue ........................... 10<br />
value.............................. 10<br />
xsize.............................. 10<br />
ysize.............................. 10<br />
widg<strong>et</strong>_table .......... 6,11,21<br />
/all_events................ 11<br />
/editable .................... 11<br />
/no_headers................ 11<br />
/scroll ......................... 11<br />
ch..................................... 21<br />
column_labels ........... 11<br />
column_widths ........... 11<br />
group_leader.............. 11<br />
Length ........................... 21<br />
offs<strong>et</strong> ........................... 21<br />
row_heights................ 11<br />
row_labels .................. 11<br />
sel_bottom .................. 21<br />
sel_left....................... 21<br />
sel_right..................... 21<br />
sel_top ......................... 21<br />
str .................................. 21<br />
Type ................................ 21<br />
units.............................. 11<br />
uvalue ........................... 11<br />
value.............................. 11<br />
x 21<br />
xsize.............................. 11<br />
y 21<br />
ysize.............................. 11<br />
widg<strong>et</strong>_text............. 6,11,21<br />
/all_events................ 12<br />
/editable..................... 12<br />
/no_newline................ 21<br />
/scroll ......................... 11<br />
/wrap.............................. 11<br />
ch..................................... 21<br />
group_leader.............. 11<br />
Length ........................... 22<br />
offs<strong>et</strong> ........................... 21<br />
str .................................. 22<br />
Type ................................ 21<br />
units.............................. 11<br />
uvalue ........................... 11<br />
value.............................. 11<br />
xsize.............................. 12<br />
ysize.............................. 12<br />
xmanager ............................. 6