Attention : la commande make depend du fichier Makefile situé dans le répertoire courant. Ce fichier definit les options de compilation et les librairies adéquates pour générer un programme Motif sous un système d'exploitation donné. Le Makefile courant est conçu pour produire des exécutables sous SunOS5 (alias Solaris2).
Remarques:
Regarder le fichier label.c. On remarquera qu'il y a création de 3 widgets :
Noter que box et message sont "managés". (il faut "manager" les widgets les rendre actifs et les faire apparaître a l'écran).
Un fois les widgets crées, ils sont réalisés physiquement (par XtRealizeWidget) puis l'application entre dans la boucle infinie de gestion des événements.
Compiler et exécuter le programme "label". Quel est le message affiché ?
Attention : ne pas confondre les VARIABLES C qui pointent sur les widgets (valeur renvoyée par les fonctions XmCreateXXX) avec le NOMS des widgets (2eme argument des fonctions XmCreateXXX). Les premiers sont des pointeurs alors que les second sont des chaînes de caractères servant à désigner les widgets dans les Fichiers de Ressources.
Compléter le fichier pushbutton.c comme suit :
Utiliser la fonction XtAddCallback (faire "man XtAddCallback") avec XmNactivateCallback en guise de "callback_name"
Note : XmNactivateCallback ==> fonctions de callback appelées quand on "active" le bouton, c'est-à-dire quand on clique dessus avec le bouton 1 de la souris ou que l'on frappe la touche SPACE lorsque le widget "a le focus".
Compiler et exécuter le programme pushbutton.
Les fichiers de ressources permettent de spécifier la valeur des ressources des widgets sans modifier le code C. Les spécifications sont de la forme :
appli.widget1.widget2. .... widgetN.ressource : valeurAvec :
De plus : * = joker qui évite de préciser les widgets intermédiaires.
Exemples :
*box.message.labelString : Hello New World *button.labelString : Click and Die!! les lignes commençant par ! sont des commentaires
*background : red *box*foreground : blue *message.background : green *XmPushButton.background : pinkRemarque : Comme le montre la dernière ligne, on peut également spécifier des classes de widgets. On peut ainsi modifier globalement tous les objets d'une même classe, sans avoir à les spécifier individuellement.
Exercice :
Créer un fichier de ressources pour les programmes label et pushbutton en vous inspirant des exemples précédents. Ce fichier devra obligatoirement :
Relancer les programmes label et pushbutton après création du fichier de ressources. Essayer diverses variantes (sans oublier de relancer les programmes après chaque modification du fichier de ressources).
Comment faire pour que les ressources des widgets des programmes label et pushbutton aient des valeurs différentes ?
Remarques :
Le fichier .Xdefaults permet également d'initialiser des ressources. Contrairement au cas précédent, ce fichier est commun à toutes les applications quelle que soit leur classe.
Le principe est le même que précédemment sauf que :
Exemples :
XMdemos*message.labelString : Message defini dans .Xdefaults pushbutton*message.labelString : Message juste pour l'application "xmbutton" pushbutton*button.labelString : Adieu \n Monde \n Cruel...Remarques :
Les listes d'arguments (ou ArgLists) permettent d'initialiser ou de modifier les valeurs des ressources dans le fichier C. Leur utilisation est plus complexe (que celle des fichiers de ressource) car les valeurs des ressources doivent alors être explicitement converties en un type adéquat (Par exemple, les chaînes de caractères C doivent être converties en chaînes de caractères Motif (de type XmString), les noms de couleurs doivent être convertis en valeurs de type Pixel, etc ...)
Le programme arglist.c montre comment initialiser les ressources du Label message pour lui faire afficher un texte en noir sur fond blanc. Noter que :
Remarque : Noter l'utilisation de la fonction XmStringCreateLocalized pour transformer des chaînes de caractères normales en chaînes de caractères Motif (de type XmString). On aurait également pu utiliser les fonctions XmStringCreate ou XmStringCreateLtoR qui ont des fonctionnalités légèrement différentes (ces fonctions permettent de créer des chaînes Motif mélangeant plusieurs polices de caractères). Enfin, la fonction XmStringFree permet de récupérer la place mémoire allouée à la chaîne Motif quand on n'en a plus besoin.
Compilez et exécutez arglist.c.
Les étapes précédentes ont montré comment spécifier les valeurs des ressources :
Dans les deux cas les ressources sont définies à l'initialisation, c'est-à-dire de manière "statique". Cet exercice propose de les modifier de manière dynamique, c'est-à-dire en cours d'exécution du programme.
Le programme dynarg.c crée 3 widgets : un Label pour afficher un message, un bouton pour terminer l'application et un troisième bouton qui aura pour fonction de faire alterner les couleurs du "foreground" et du "background" du Label.
Comme précédemment, le texte du Label est affiché en noir sur fond blanc, mais ceci est réalisé d'une manière différente : le Label est d'abord crée puis ses resources sont modifiées dynamiquement au moyen de la fonction XtVaSetValues. On remarque que :
Remarques
Exercices
En vous inspirant de ce qui précède, rajoutez une fonction de callback qui alterne les couleurs du Bouton xchange quand on clique dessus (ie. qui échange les valeurs de son foreground et de son background)
Encore plus fort ! : faire la même chose mais en échangeant cette fois les couleurs du Label message et sans utiliser de variable globale (aide : regarder le manuel de la fonction XtAddCallback ou ... le cours).
Cet exemple montre comment modifier les ressources d'un Geometry Manager de classe RowColumn afin de disposer verticalement, horizontalement ou matriciellement les widgets qu'il contient.
Le programme orientation.c crée un Label et 5 PushButtons.
Les 4 derniers boutons appellent des fonctions de callback qui changent dynamiquement certaines ressources du widget box, lequel est un manager de type RowColumn.
Cet exemple montre :
Compilez et exécutez le programme addobj. Celui-ci comprend initialement:
Cliquez sur les boutons small et big. Que se passe-t'il ? Changez la taille de la fenêtre à l'aide de la souris puis faites de même que précédemment. Que constatez-vous ? Cliquez maintenant sur le bouton add plusieurs fois. Même chose sur remove.
Examinez le code source à partir de la fonction main en faisant attention aux points suivants :
Un MessageDialog sert à afficher un message important tel que : message d'erreur, question, avertissement, information, etc ... Ce type de boîte de dialogue comprend :
Les MessageDialogs sont crées au moyen des fonctions Motif XmCreateXXXDialog avec XXX = Message, Error, Information, Question, Warning et Working. Toutes ces fonctions créent des boîtes de dialogue identiques au pixmap près. Dans tous les cas l'objet crée est un Manager particulier de classe XmMessageBox (voir manuel Motif).
Les principales ressources des MessageDialogs sont:
De même que précédemment, les valeurs des ressources XmNxxxString sont des XmStrings (i.e. des chaînes de caractères Motif) qui sont créées au moyen des fonctions XmStringCreate... (et que l'on peut avantageusement spécifier dans les fallbacks (voir exercice précédent) ou dans les fichiers de ressources).
Les callbacks s'ajoutent aux boutons OK, Cancel et Help de la même façon que précédemment (c'est-à-dire à l'aide de la fonction XtAddCallback mais avec les "callback_names" adéquats).
Les boîtes de dialogues sont géneralement des objets éphémères ("transient" en anglais) qui n'apparaissent à l'écran que de manière temporaire (par exemple pour signaler une erreur, demander confirmation d'une commande, etc ...). Pour faire apparaître un Dialog, on utilise la fonction XtManageChild (comme pour les autres widgets). Inversement, la fonction XtUnmanageChild permet de faire disparaître un Dialogue. La ressource XmNautoUmanage entraine une disparition implicite quand on clique sur les boutons OK ou Cancel du dialogue.
Exemple : Compilez et exécutez le programme dialog.c. On remarquera :
Ce programme utilise les mêmes "fonctions utiles" que l'exemple précédent. La boîte de dialogue est créée une seule fois en même temps que les autres widgets et n'est jamais détruite. Elle est initialement invisible (i.e. pas managée) et n'apparaît que lorsque l'on clique sur le bouton open. Ce bouton appelle la fonction de callback OpenDialogCB, une nouvelle "fonction utile" que l'on pourra réutiliser ailleurs.
Exercice :
Rajouter un QuestionDialog demandant à l'utilisateur de confirmer
lorsque l'on clique sur le bouton quit (i.e. cliquer sur quit
ouvrira ce dialogue de confirmation (au lieu de sortir directement)
et il faudra alors cliquer sur le bouton "OK" de ce dialogue pour terminer
l'application).
Remarque: il faudra utiliser 2 fonctions de callback,
l'une pour ouvrir le QuestionDialog et l'autre pour terminer l'application.
L'objet crée est un Manager particulier de classe XmSelectionBox dans les deux premiers cas et XmFileSelectionBox dans le dernier cas. Ces dialogues n'ont pas de ressources XmNmessageString ni XmNsymbolPixmap. Les PromptDialogs ont par contre les ressources suivantes:
Exemple : Compilez et exécutez le programme promptdialog. Ce programme montre comment récupérer une chaîne de caractères depuis un PromptDialog.
Regardez comment la fonction de callback GetAndSetTextCB récupère le texte tapé par l'utilisateur. Le 3eme argument (ou "call_data") de cette fonction pointe vers une structure dépendante du PromptDialog (c'est-à-dire du widget qui a appelé cette fonction). Cette structure comprend entre-autres un champ value qui contient le texte entré par l'utilisateur (pour savoir ce que contient cette structure, voir manuel de XmSelectionBox). Comme d'habitude, ce texte est stocké sous forme de XmString qu'il faut éventuellement convertir en String standard au moyen de la fonction XmStringGetLtoR,
Remarques:
Le programme modaldialog.c est semblable au précédent sauf que:
Examinez le code source:
Attention : cette fonction ne peut pas être utilisée dans tous les cas. On est par exemple obligé d'utiliser la fonction XmCreatePromptDialog pour créer un PromptDialog car ce widget n'est pas une classe à part entière mais une variante de la classe XmSelectionBox.
Exercices :
Remarques :
Remarque : modifier dynamiquement les ressources XmNx, XmNy et XmNdefaultPosition du PromptDialog. Noter que XmNdefaultPosition doit valoir False sinon le dialog est positionné automatiquement par le Window Manager sans tenir compte des valeurs de XmNx et de XmNy.
Ceci s'apparente au programme "label.c".
Cependant on crée maintenant un Pixmap qui peut être vu comme un masque de points. Il y a différentes façons de créer un Pixmap, nous utilisons ici la fonction XmGetPixmap qui prends en argument un nom de fichier au format xbm (format bitmap) , ainsi que les couleurs d'avant et d'arrière-plan du dessin.
Les fichiers au format xbm peuvent être créés par le programme bitmap
Compiler et exécuter le programme "pixmap".