Si
ce n'est déjà fait, lisez la documentation de Graphic Utilities
2003 afin de vous familiariser avec ces logiciels, que vous allez étendre.
Tout
d'abord, nous allons voir les API assembleur que Graphic Utilities 2003 utilise
pour fonctionner.
Ensuite nous verrons les librairies BASIC que Graphic Utilities 2003 fournit
pour faciliter l'utilisation des API mais aussi et surtout celles qui contiennent
toutes les fonctionnalités communes aux modules de la suite et qui vous
seront très utiles pour créer des plug-ins ou tout autre nouveau
logiciel.
Finalement, nous verrons la structure que doit avoir tout plug-in et quelques
exemples pour pogrammer tout nouveau module ou programme de traitement graphique.
Lire cette page vous permettra aussi de mieux comprendre le code source des
différents modules, si cela vous interesse.
Sommaire
:
API utilisées
Basic
Tools 1.0
PicList
1.0
RunBasic
1.0
ZSTR
0.991
Librairies
fournies
prgmZGU
LZGUS
prgmZGUDT
prgmZGUPLG
prgmZGUPG
prgmZGUST
prgmZGUSTR
prgmZGUVL
Plug-ins
La
librairie prgmZPI
Structure
d'un plug-in
Créer
un plug-in pour GU DrawTools
Créer
un plug-in pour GU ProGui
Nouveaux modules ou programmes
Graphic
Utilities utilise des API en assembleur pour accéder à des fonctions
inexistantes en BASIC. En voici une courte description, dans le cadre de cette
suite.
Pour plus de renseignements sur ces API et pour avoir la dernière version,
officielle et complète, visitez les sites de celles-ci (disponibles aussi
sur mon site).
Basic
Tools 1.0 (michael257257@yahoo.com)
:
J'ai repris deux programmes de Basic Tools : ceux pour activer et désactiver
linversion de la couleur du texte.
ASTUCE : Après un appel à la fonction Menu(), il n'est
pas nécessaire d'appeler le programme de désactivation car cela
est fait automatiquement par la TI.
Asm(prgmZGUIE : Activer l'inversion de la couleur du texte (blanc sur
noir)
Asm(prgmZGUID : Désactiver l'inversion de la couleur du texte
(noir sur blanc)
PicList
1.0 (http://calc.kevtiva.com/
; calc@kevtiva.com) :
Stoque / recalle une image sous forme de liste (et ainsi permettre à
l'utilisateur d'en avoir un très grand nombre (plus de 2000 sur une TI-83
plus Silver Edition) et de les nommer) et a l'avantage de ne requiérire
aucun hacking (donc pas de crash) et de ne prendre que quelques octets de plus
que le format 8xi.
Asm(prgmZGUPL : Copie l'image actuelle dans la liste LBOB.
Un simple appel de LBOB->votre_liste
permettra de stoquer l'image dans une liste personnalisée.
"LISTE":Asm(prgmZGULP : Recalle la liste LLISTE
à l'écran. Cette liste peut être archivée.
ATTENTION : veillez à toujour appeler DispGraph
avant de recaller une liste pour vous assurer que le graph buffer soit initialisé.
VOIR LA LIBRAIRIE : prgmZGUPLG pour une gestion plus simplifiée
et sofistiquée lorsque la liste en question n'est pas connue à
l'avance (lorsque c'est l'utilisateur qui la choisit, par exemple) ou lorsque
l'on souhaite aussi utiliser des pictures normales.
RunBasic
1.0 ZSTR
0.991 (http://clix.to/ti83plus
; okvin@tiscali.se) :
Exécute un programme BASIC dont le nom est dans Ans.
"MONPROG":Asm(prgmZPIRBSIC : Exécute prgmMONPROG.
Remarquez qu'il a le préfixe ZPI (donc, associé à ma librairie
pour les plug-ins) car ce système (de plug-ins) est plus indépendant
de la suite graphique.
ZSTR
0.991 (http://calc.kevtiva.com/
; calc@kevtiva.com) :
Exécute un programme stoqué dans une chaîne.
"PROG"->Str#:#->X:Asm(prgmZGUSTA : Stoquer une chaîne
dans Str# et l'exécute
ATTENTION : Cette API, en version bêta, est buggée et pas
toujours utilisable.
VOIR LES LIBRAIRIES : prgmZGUSTR pour connaître les bugs de cette
API et prgmZGUST (une modification du programme ZST fourni avec cette API) pour
obtenir les caractères """,
"->" et "ENTER".
Cette suite
graphique a nécessité de créer des sous programmes pour
en simplifier la programmation.
Ces sous programmes étant très utiles pour tout programmes graphique,
je vous en livre les secrets pour que vous puissiez les utiliser dans vos programmes
ou plug-ins.
Nous avons également vu ci-dessus que les API avaient leurs limites ou
étaient difficilement employables dasn certains cas : j'ai aussi créé
des librairies permettant de faciliter l'utilisation des API.
Ceci vous permettra de réduire le code que vous devrez produire (pour
vous concentrer plus sur les algorithmes) et permettra aux utilisateurs de cette
formidable suite d'avoir tous les outils en un seul logiciel (si vous créez
des plug-ins) ou d'avoir un tout cohérent (en utilisant les même
fonctions de sélection, etc...).
- Contient toutes les fonctionnalités
pour que l'utilisateur fasse une sélection ou lui proposer un choix de
couleurs.
Ceci présente un double interêt par rapport à deux simples
Input :
Pour l'utilisateur : la sélection sera simple, intuitive et variée
(munuelle, carré, la dernière...). Elle sera également
plus rapide (touches 2, 4, 5, 6 et 8).
Pour le programmeur : tout est géré par la librairie et très
peu de code est à rajouter : meilleur productivité.
- Si vous lancez le programme avec Ans=pi un menu de sélection sera proposé
à l'utilisateur et, s'il a déjà choisit un outil, celui-ci
sera réutilisé automatiquement.
Les options 1 à 5 permettent d'imposer un outils de sélection
(l'utilisateur ne pourra pas en prendre un autre), tandis que l'option 6 rafraichi
les variables A à H avec la dernière sélection.
- L'option Ans=0 lui permet de placer un point. La coordonnée est renvoyée
dans (A,B) mais aussi dans (C,D).
- N'oubliez pas de lancer la librairie avec Ans=9 en début de votre programme
afin d'initialiser la liste utilisée en interne.
- Les outils de sélection renvoient 0 si l'utilisateur a sélectionné
quelque chose, 1 s'il a annulé via [CLEAR] (pour quitter votre outil)
ou 2 s'il a pressé [DEL] (pour reparamétrer votre outil). Si une
sélection a été faite vous aurez les variables A à
D qui contiendront les coordonnées rentrées et E à H les
mêmes mais rangées de façon à ne pas provoquer d'erreur
si vous les utilisez avec une boucle for() ou autre. Sinon ces variables sont
altérées et un appel à UpdateData (option 6) permettra
de retrouver les dernière coordonnées selectionnées. Je
vous propose d'utiliser autant que possible les variables (E,F,G,H) pour que
ce soit clair et cela limitera les risque d'erreurs. Cependant vous aurez surement
besoin d'avoir les coordonnées dans l'ordre choisit par l'utilisateur
(c'est le cas de l'outil LIGNE, qui tracerai toujours une ligne du haut / gauche
vers le bas / droite sinon) : utilisez alors (A,B,C,D).
- Quand aux options Ans=7 ou Ans=8, celles-ci offrent un menu à l'utilisateur
permettant de choisir une couleur, qui est retournée dans Ans (je recommande
de stoquer ce chiffre dans L afin de rester compatible avec d'autres fonctions),
l'option 8 ne proposant pas la couleur INVERSE. Le nombre retourné permet
de l'utiliser directement avec Line()
ou par comparaison avec Pxl-Test()
sans avoir à le modifier.
- Comme la plupart des librairies qui suivront celle-ci renvoi une valeur (dans
Ans) : ne les négligez jamais car, dans ce cas, elle signifient que l'utilisateur
veux quitter votre outil (touche [CLEAR], code de retour Ans=1), le reconfigurer
(ou recommencer la sélection si l'outil n'est pas configurable (choix
de la couleur, etc...)) (touche [DEL], code de retour 2). Certaines fonctions
de la librairie n'utilisent que Ans (pour ne pas altérer les autres variables
que vous utilisez) : c'est le cas des options Ans=7 et Ans=8, elles retourneront
dans Ans la couleur que l'utilisateur a choisit : à vous de stoquer cette
valeur dans la variable qui vous convient le mieux.
Ans | Fonction | Retour (Ans) | Variables de retour | Remarques |
---|---|---|---|---|
pi | Sélection automatique | cf 1 à 5 | cf 1 à 5 | nb->LZGUS(7)
pour pré-sélectionner un outil Si nb=(1,2,3) : continue à utiliser l'outil ([MODE] pour choisir un autre outil) Sinon, affiche un menu à l'utilisateur pour qu'il sélectionne un outil |
0 | Point | 0
: OK 1 : Annulé (CLEAR) 2 : [DEL] pressé |
(A,B)
= (C,D) : Coordonnée Utilise K |
|
1 | Rectangle | (A,B,C,D)
: Coordonnées (E,F,G,H) : NormalisedRect Utilise K (sauf UpdateData) |
(A,B)
: Premier point sélectionné (C,D) : Second point sélectionné (E,F) : Coordonnée haute / gauche (G,H) : Coordonnée basse / droite |
|
2 | Carré | |||
3 | Manuelle | |||
4 | Écran total | 0 : OK | ||
5 | Écran avec bordures | |||
6 | UpdateData | |||
7 | Menu Noir / Blanc / inverse | 0
: Blanc 1 : Noir 2 : Inverse |
Ans->L recommandé | |
8 | Menu Noir / Blanc | |||
9 | Initialiser Sélection | 0 : OK | Toujours lancer en premier dans un programme | |
Sinon | Ans invalide | 3 : Erreur | ||
Toutes
les coordonnées sont fournies en pixels. L'option Ans=-1 est utilisée par la librairie pour demander un point avec [MODE] activé (retourne 3 si pressé). Vous pouvez donc l'utiliser mais il faudra gérer l'appui sur [MODE] en proposant quelque chose de cohérent à l'utilisateur. |
Ceci n'est pas une librairie
mais la liste utilisée en interne par prgmZGU. Cette liste, si elle n'existait
pas, a été créée et initialisée par 9:prgmZGU
: ne l'oubliez pas au début de votre programme sinon ERR:UNDEFINED
risque d'apparaître (ceci n'est pas nécessaire pour un plug-ins
car le module l'aura fait avant vous).
Nous avons vu qu'en utilisant ce dernier avec Ans=pi le dernier outils était
directement pré-sélectionné (d'où gain de rapidité
et de productivité pour l'utilisateur).
Nous avons aussi vu qu'avec Ans=6 les variables étaient rafraichies avec
la dernière sélection.
Et si vous avez déjà utilisé Graphc Utilities vous avez
remarqué que le curseur se remet là où vous l'avez laissé
la dernière fois.
Et bien nous venons de décrire tout ce qui est sauvé dans la liste
LZGUS (la liste
de sélection) !
{
|
A,B,C,D,
|
X,Y,
|
dern.
outil,
|
tmp
|
}
|
---|---|---|---|---|---|
Coord.
|
Pointeur
|
Les quatres première
cases stoquent les coordonnées dernièrement sélectionnées.
Un appel à UpdateData permettra de recalculer E, F, G et H.
Ensuite les dernières coordonnées du pointeur (le petit point
scintillant lors de la sélection) sont stoquées.
Suivit du numéro du dernier outil choisit par l'utilisateur (entre 1
et 5).
Pour finir la dernière case de la liste est réservée à
l'utilisation interne de la librairie et n'est donc pas utilisable.
La structure ainsi connue,
nous pouvont la modifier pour forcer la librairie à avoir un comportement
désiré :
- Ce qui est utilisé par GU DrawTools : au menu principal 1 est mis dans
le dernier outil afin que l'utilisateur ne perde pas de temps à sélectionner
RECTANGLE (ce qu'il faira dans 95% des cas) et, s'il a sélectionné
CARRE ou MANUEL il est vraisemblable qu'il souhaitera réutiliser RECTANGLE
pour le prochain outil.
Dans certains cas, une sélection CARRE sera plus adapté à
un certain outil : il suffira d'écrire 2->LZGUS(7
avant d'utiliser l'outil pour suggérer cette sélection à
l'utilisateur.
ATTENTION : ne pas confondre avec 2:prgmZGU
qui ne suggérera pas un outil de sélection mais l'imposera ! Cela
peut être interessant pour certains outils qui exigent cette forme de
sélection (comme l'outil ROTATION de GU DrawTools).
Cependant, vous ne pouvez mettre qu'un nombre entre 1 et 3 dans cette case de
la liste. En effet, si l'utilisateur (ou vous) choisit 4 (Écran total)
il n'aurait plus la possibilité d'appuyer sur [MODE] pour choisir une
autre forme. Ainsi, si la voit un nombre différent de 1, 2 ou 3 alors
elle affichera un menu.
- Placer le curseur à un endrois précis (plutôt qu'à
la dernière position) ou le centrer (47 en X et 31 en Y) : ceci est utilisé
par GU DrawTools pour l'outil DEPLACER/DUPLIQUER
: l'utilisateur choisit un objet à déplacer / dupliquer et le
curseur est repositionné en haut à gauche de cet objet pour bien
signifier qu'il doit placer la nouvelle position du coin haut / gauche de cet
objet.
- Modifier la dernière sélection : ceci n'a pas grand interêt
(je n'ai pas d'exemple à donner) mais puisque vous pouvez le modifier
rien ne vous en empêche (à la surpise de l'utilisateur qui vous
appliquer à outil à ce qu'il croyait être la dernière
sélection).
Contient tous les principaux
outils de GU DrawTools pour les utiliser dans vos
plug-ins sans les re-coder.
- Avec Ans=0 vous copierez la zone délimitée par (E,F,G,H). Le
presse-papier est stoqué dans Str3 et ses dimentions sont mémorisées
dans LZGUP. Si l'utilisateur veut couper une zone plutôt
que la copier il vous incombe de nétoyer la zone (une petite boucle for()
avec des Line(,,,,0)).
Le format de Str3 est basique : "0"
pour un pixel éteind et "1"
pour un pixel allumé. J'ai choisit une chaîne plutôt qu'une
liste car une liste est trop gourmande en mémoire et avec une chaîne
l'utilisateur a tout le loisir de copier l'écran entièrement.
Voilà : vous pourrez maintenant écrire un plug-ins qui modifiera
le contenu du presse-papier. Attention : si une commande retourne la chaine
complète Ans contiendra aussi cette chaîne (ce qui prendra deux
fois plus de mémoire) et au prochain calcul vous risquez d'obtenir un
ERR:MEMORY. Pour éviter
cela stoquez juste un nombre dans Ans. Ceci peut être fait simplement
via :
"1"+sub(Str3,2,length(Str3)-1
// Opération bidon qui met à 1 le premier
caractère de la chaîne : Ans contiendra alors toute la chaine.
0 // Voilà
: la mémoire se vide d'un seul coup : Ans contenait toute la chaîne
et mainenant elle ne contient plus qu'un nombre (0, soit 12 octets).
- L'option Ans=1 permet de coller ce que contient le presse-papier sur l'écran
en applicant certains filtres. Vous en aurez des exemples en utilisant GU
DrawTools.
Initialisez juste A, B et L contenant le filtre (0 pour aucun filtre).
- Ans=2 permet de dessiner un oval de centre (A,B) et de rayon (X,Y).
La couleur et le remplissage (ou non) sont définits dans L.
- Ans=3 permet de déplacer une zone (E,F,G,H) à l'endrois (A,B).
- Le choix de ces variables est aisément explicable : par exemple vous
appelez pi:prgmZGU pour sélectionner
un objet (attention à gérer les erreur retournées), puis
lancez simplement 0:prgmZGU pour
sélectionner un point de destination. Aucune variable n'est alors à
modifier avant de lancer 4:prgmZGUDT.
Magic, non ?
Ans | Fonction | Variables à initialiser | Variables | Remarques |
---|---|---|---|---|
0 | Copier | (E,F,G,H) : Partie à copier | Retourne
: - PressePapier->Str3 - {G-E,H-F}->LZGUP Utilise A, B, C, D, X, Y, Z, Str0 |
|
1 | Coller | (A,B)
: Coordonée haute / gauche de destination Str3 et LZGUP : Presse papier |
Utilise C, D, E, F, X, Y | L=0
: Normal (Noir / Blanc) L=1 : Fond transparent (Or) L=2 : Blanchir (si source=noir) L=3 : Inverser (si source=noir) (Xor) |
2 | Cercle / oval | (A,B)
: Centre (E,F) : rayons X et Y (Si X=Y : cercle) L : Style |
L= 0 : Utilise X,
Y, theta |
L=0
: Cercle blanc L=1 : Cercle noir L=2 : Cercle inversé L=3 : Disque blanc L=4 : Disque noir L=5 : Disque inversé |
3 | Déplacer / dupliquer | (E,F,G,H)
: Partie à Déplacer / Dupliquer (A,B) : Coordonée haute / gauche de destination |
Utilise C, D, X, Y | L=0
: Dupliquer L=1 : Déplacer |
Tout doit
être fourni en pixels, sauf pour l'outil cercle / oval qui doit être
fourni en points. Ce dernier est en effet indépendant de la configuration graphique et peut être réutilisé par d'autres programmes ou jeux. |
Cette librairie permet de
demander un nom de liste-image, de recaller une image-liste à l'écran
ou de stoquer l'écran dans une liste-image.
En effet, pour stoquer une image-liste il faut faire LBOB->LLIST.
Hors on ne connais pas la liste qu'aura choisi l'utilisateur (d'où l'utilisation
de l'API ZSTR, cf ci-dessous). De plus l'utilisateur peut demander à
enregistrer l'image dans une Pic plutôt que dans une liste.
Cette librairie résout le problème de sauvegarde et de chargement
d'une image ou image-liste et fourni une méthode pour demander où
l'utilisateur veut enregistrer son image.
Vous pourrez donc demander un nom, sauver et à chaque changement re-sauver
sans demander de nom (ce qui est fait dans GU DrawTools)
ou recharger si l'utilisateur le demande, toujours sans redemander un nom.
Pour illustrer ce programme je vous renverrez au source de prgmGUPICLST.
- En clair on appel ".":prgmZGUPLG
pour demander un nom d'image à l'utilisateur puis on regarde s'il n'a
pas annulé pour éventuellement retourner au menu.
À ce stade, Ans contient le nom de l'image (sous la forme #
(pour Pic#) ou une image-liste
L1 à
L6 ou Lle_nom).
Idem pour Str0 qui contient aussi ce nom.
On appel prgmZGUPLG pour sauver
l'image (Ans n'a pas besoin d'être spécifié car il contient
encore le nom : dans GU DrawTools on utilise Str0
pour stoquer ce nom et ainsi sauver l'image avec le même nom : il suffit
de faire Str0:prgmZGUPLG pour
restoquer l'image).
- Le chargement d'une image est similaire : on demande le nom (toujours ".":prgmZGUPLG)
et on fait juste "-"+Ans:prgmZGUPLG
afin de demander le chargement de l'image. La librairie renverra juste le nom
en ayant supprimé le "-"
: ce qui est pratique pour créer une sorte de pipe-line.
- Il est à noter que l'API PicList efface l'écran avant de recaller
une image (il est donc impossible de superposer des images) et pour armoniser
le tout la librairie efface également l'écran avant de recaller
une image Pic#.
Ans | Fonction | Retour (Ans) | Variables | Remarques |
---|---|---|---|---|
"." | Dialogue de demande de nom | Ans=Str0="XXXXX" ="." si annulé / échoué (nom incorrect) |
Vous
devez effacer l'écran vous même et afficher un titre sur la première ligne |
|
"-XXXXX" | Charger | Ans=Str0="XXXXX" | Utilise Str1 | Ans sans le "-" sera stoqué dans Str0 et retourné |
"XXXXX" | Sauver | Ans sera stoqué dans Str0 et retourné | ||
"XXXXX" = 0-9, L1-L6 ou "XXXXX" (nom de 1 à 5 caractères alpha-numériques commençant par une lettre) |
Librairie utilisée
pour GU ProGui : ces appels ont pour fonction de
générer le code adéquate dans Str4 et de dessiner sur l'écran
le résultat.
Cette librairie vous sera très utile si vous faites un plug-ins pour
GU ProGui : vous n'aurez qu'à combiner les
appels à celle-ci, qui générera elle-même le code.
Vous pouvez prendre exemple en éditant cette librairie et en cherchant
la partie de code qui crée
le rectangle aux coins nuls : petites manipulations de variables et on appel
ZGUPG pour dessiner une ligne, etc...
Vous pouvez également avoir besoin de proposer à l'utilisateur
de dessiner librement une partie : ce que vous pourrez faire via le menu de
modélisation.
Ans | Fonction | Variables | Remarques |
---|---|---|---|
pi | Menu MODELISATION | ||
0 | ClrDraw | ||
1 | RecalPic | L : Pic# | |
2 | StorePic | L : Pic# | |
3 | Line | (A,B,C,D) : Coordonnées L : Couleur (0 : Blanc, 1 : Noir) |
|
4 | Horizontal | B : Coordonée Y | |
5 | Vertical | A : Coordonée X | |
6 | Text | L : Police (0 : Petite,
-1 : Grande) (A,B) : Coordonées Str1 : Texte |
"->" sera restoqué dans Str1 |
7 | Pt / Pxl | (A,B) : Coordonées L : Style |
L=0 : Pt-On() L=1 : Pt-Off() L=2 : Pt-Change() L=3 : Pxl-On() L=4 : Pxl-Off() L=5 : Pxl-Change() |
8 | Circle | (A,B) : Coordonées L : Rayon |
|
9 | Rectangle | (A,B,C,D) : Coordonnées M : Forme L : Couleur (0 : Blanc, 1 : Noir) |
M=0 : Rectangle (de
couleur L) M=1 : Rectangle à coins nuls (de couleur L) M=2 : Remplir (en blanc si L=0, en noir si L=1) : Utilise theta M=2 : Inverser si L=2 : Utilise X, Y |
Tout
en pixels (les conversions sont effectuées en interne). Code généré stoqué dans Str4 (doit exister et posséder au moins 1 caractère (souvent ":"). |
Parfois, vous aurrez besoin
de stoquer certains caractères dans une chaîne : les sauts de lignes,
guillemets, ou caractère de stoquage (ce qui a été le cas
pour GU ProGui). Un appel de cette librairie avec
Ans=3 et vous disposeraient de ces trois caractères à portée
de main. Dans un souci d'utiliser le moins de chaines possibles (ressources
rares sur la TI-83 Plus), vous pouvez demander à ne stoquer que l'un
d'entre eux à la fois pour une utilisation ponctuelle.
- Exemple : 1:prgmZGUST et vous
disposez d'un caractère de stoquage dans Str1 !
Ensuite rien de plus simple : Disp "3"+Str1+"A"
: exemple basique mais efficace. Cette lib sert surtout pour GU
ProGui.
Ans | Fonction |
---|---|
0 | """->Str0 |
1 | "->"->Str1 |
2 | "ENTER"->Str2 |
3 | Les trois à la fois |
L'API ZSTR étant
en version bêta, elle ne fonctionne pas et bug : elle s'exécute
puis quitte VOTRE programme.
Pour éviter ce bug je l'ai "encapsulée" dans le programme
ZGUSTR qui appelera ZGUSTA (A pour ASM ou API : l'api proprement dite).
Une fois l'API exécutée elle va provoquer un bug qui faira comme
si on avait mis un Return juste
après l'appel de l'API. D'où l'encapsulation : ce n'est pas grave
de quitter prgmZGUSTR vu qu'il n'y a plus rien à exécuter dedant
: on revient au programme qui a appelé ZGUSTR.
Ce programme stoque aussi Ans dans X et, étant en BASIC, vous n'avez
plus besoin du Asm(). L'appel
devient donc :
"PROG"->Str#:#:prgmZGUSTA : Stoquer une chaîne dans
Str# et l'exécute.
Une dernière chose sur cette API qui m'a donné du fil à
retordre : impossible d'exécuter des boucles ou des tests : votre programme-chaine
devra être linéaire et peu complexe.
Je vous conseille également de mettre votre programme sous la forme ":PROG:"
pour éviter d'autres bugs.
Pour finir, il existe une version bêta 0.0 de ZSTR qui n'a pas ces bugs...
mais en a d'autres qui font qu'elle ne pouvait être utilisée pour
ce projet.
Je ne me rappel plus de ces bugs mais je ne m'y attarde pas dessus : cette API,
en l'état actuel des choses, a le dont de m'énerver mais elle
est nécessaire !
- Un exemple d'utilisation de ce programme se trouve dans ZGUPLG : on stoque
"LBOB->liste_perso"
dans une chaine et on l'exécute, "->"
étant fourni par Str1 (cf le programme ci-dessus) et "liste_perso"
par ce qu'a entré l'utilisateur comme nom de liste-image.
C'est la librairie pour
GU VectorL.
- Avec Ans=0, une boîte de dialogue demandera un nom de liste à
l'utilisateur.
Cette fonction est à peu près la même que celle de prgmZGUPLG,
à la différence que celle-ci n'autorise pas de Pic# car elle est
destinnée uniquement aux listes VectorL.
- Avec Ans=1, la librairie dessine l'objet VectorL contenu dans L1.
Veillez toujours à mettre 0 dans Q car si Q=1 alors l'objet ne sera pas
dessiné mais le code sera produit dans Str4 (si vous désirez faire
des plug-ins pour GU ProGui vous pourrez donc utiliser
cette fonctionnalité).
Voici un petit exemple de code demandant un nom de liste, stoquant cette liste
dans L1 (car la librairie demande que l'objet soit dans
cette liste) et affichant l'objet :
/*
Demander un nom de liste VectorL : */
ClrHome // Effacer l'écran afin d'écrire
le titre de la boître de dialogue soit sur la première ligne
Disp "CHARGER VECTORL: //
Écrit donc ce titre
0:prgmZGUST //
Demande un nom de liste contenant un objet VectorL
If Ans=". //
Si l'utilisateur n'a pas voulu donner de nom ou s'il n'est pas valide
Return //
Alors quitter
/*
Stoquer la liste dont le nom est dans Str0 dans L1 : */
1:prgmZGUST // Sotquer "->"
dans Str1
":"+Str0+Str1+"L1:->Str1
// Équivaut à ":LNOM->L1:",
si l'utilisateur a tappé "LNOM"
comme nom de lise, bien sûr
1:prgmZGUSTR
// On exécute cette chaîne pour stoquer la
liste dans L1, comme le demande la librairie
/*
Dessiner l'objet VectorL : */
DelVar Q //
On veut juste dessiner l'objet, donc on met 0 dans Q
1:prgmZGUVL //
Et on dessine !
- Tandis que Ans=pi n'est utilisé que par l'éditeur afin de demander
un point (en effet cette routine diffère de cette de GU
DrawTools).
Ans | Fonction | Retour (Ans) | Variables | Variables et Remarques |
---|---|---|---|---|
0 | Demande de nom de liste | Ans=Str0="LXXXXX" ="." si annulé / échoué (nom incorrect) |
Vous
devez effacer l'écran vous même et afficher un titre sur la première ligne Notez que le "L" est dans le nom, contrairement à ce que fait prgmZGUPLG |
|
1 | Dessin de l'objet VectorL contenu dans L1 | Utilise
de A à S et theta (A,B,C,D) : Coordonnées |
Q=0
: Dessin Q=1 : Produire code dans Str4 (pour ProGui) |
|
pi | Fonction interne demandant un point dans l'éditeur | N'a aucun sens de l'utiliser | ||
"XXXXX" = L1-L6 ou "XXXXX" (nom de 1 à 5 caractères alpha-numériques commençant par une lettre) |
ZPI n'a pas le préfixe
ZGU car il peut être utilisé par n'importe quel autre programme.
Ainsi, vous pouvez faire un programme de jeu, de traitement de texte, ou traitant
de n'importe quel autre sujet et vouloir lui adjoindre des plug-ins.
En utilisant cette librairie vous n'aurez pas à code ce système
et vous utiliserez la même chaîne de caractères que les programmes
de Graphic Utilities 2003 (à savoir Str9)...
- En tant que développeur d'un programme utilisant des plug-ins, vous
aurrez à initialiser la librairie via l'option Ans="*"
puis à demander l'affichage d'un menu pour que l'utlisateur exécute
un ou plusieurs plug-ins via l'option "?",
où le ? vaut le caractère qui caractérise votre application
(vaut "1" pour GU DrawTools et "2"
pour GU ProGui, à titre d'exemple. Choisissez
donc un autre caractère qui ne sera utilisé par aucune autre application).
- En tant que développeur de plug-ins, vous n'avez qu'à connaître
le caractère qui caractérise l'application à laquelle se
raccrochera votre plug-in et à utiliser la dernière option. Pour
vous, voyez la section suivante.
NOTE : voyez la section suivant pour savoir comment fonctionne cette
librairie et ainsi pouvoir mieux l'utiliser (que vous soyez développeur
d'un logiciel ou d'un plug-in pour un logiciel).
Ans | Fonction | Variables et Remarques |
---|---|---|
"*" | Initialiser ZPI | Initialise
Str9 avec 23 espaces si elle n'existait pas. Determine si elle existe via LZPI. |
"?" | Afficher le menu pour l'application "?" | |
"CHAINE_23" | Installer / Désinstaller un plug-in | cf ci-dessous |
"CHAINE_23" est une chaîne de 23 caractères (pas plus, pas moins) décrivant un plug-in : cf ci-dessous. |
- Avant tout, vous pourriez
vous demander comment fonctionne ce système afin de bien comprendre pourquoi
la structure d'un plug-in doit être comme cela, etc...
Cette librairie utilise en fait la chaîne de caractère Str9 et
la liste LZPI afin de savoir si Str9 a déjà
été initialisée ou pas (c'est sa première utilité)
et si le plug-in doit être installé / désinstallé
(c'est à dire être inséré ou supprimé de Str9,
chaîne utilisé pour construire le menu présentant à
l'utilisateur la liste des plug-ins et le nom des programmes correspondants
qui doivent être lancés) ou exécuté.
- LZPI
contient, comme dit précédemment, une seule case marquant l'état
de la librairie ZPI.
Si cette liste contient {0}, ZPI supposera que Str9 n'existe pas : il la créera
(avec 23 espaces : cf ci-dessous).
Cette liste contiendra {1} la plupart du temps : vos plug-ins en déduiront
alors qu'ils ont été lancé par l'utilisateur (voir la documentation
de Graphic Utilities 2003 pour voir comment les plug-ins sont perçus
et utilisés par l'utilisateur) et qu'ils doivent s'installer ou se désinstaller
(cf ci-dessous pour connaître la structure d'un plug-in). Sinon, la liste
contiendra alors {2} : elle est mise à deux juste avant d'afficher le
menu et sera remise à {1} en quittant le menu listant tous les plug-ins.
Durant le laps de temps où cette liste contient {2}, si votre plug-in
est lançé son code sera exécuté (et non son installation
/ désinstallation), supposant que c'est l'utilisateur qui a choisit ce
plug-in dans le menu. Vous conprendrez mieux en voyant la structure d'un plug-in
ci-dessous.
- Str9 est découpé en tranches de 23 caractères (chaque
"tranche" étant associée à un plug-in pour l'identifier).
Les 23 premiers sont juste des espaces (initialisé lorsque LZPI
contient {0}) et sont utilisé pour remplir le menu lorsqu'il y a moins
de 6 plug-ins (en étudiant le code de prgmZPI, et plus particulièrement
le menu, vous verrez qu'une liste est initialisé, pointant vers les noms
des programmes, et si une entrée du menu est vide le "nom"
factice pointe vers ces espaces).
Voyons maintenant à quoi correspondent ces 23 caractères :
Le premier identifie à quel logiciel le plug-in est rattaché :
"1" pour GU
DrawTools et "2"
pour GU ProGui. Ainsi vous pouvez créer
d'autres logiciels qui utilisereont leurs propres plug-ins (le menu affichera
les votres et pas ceux des autres logiciels). Ce choix est aritraire, vous pouvez
donc choisir "J", comme
vous auriez pu choisir ","
ou "9"... On voit ainsi
l'intérêt de la librairie : en plus de vous passer de coder ce
système il n'utilise qu'une seule chaîne de caractère (Str9)
pour tous les logiciels utilisant des plug-ins.
Les huit caractères suivants sont le nom de votre programme (en fait
de votre plug-in) : commencez-le toujours par theta (choix arbitraire afin d'avoir
tous les plug-ins en fin de liste dans le menu [PRGM], sans pour autant les
confondre avec les sous programmes, commençant pas Z), suivit de deux
ou trois caractères indiquant le nom du logiciel rattaché (là
aussi c'est arbitraire mais il serait préférable de commencer
par thetaDT un plug-in pour GU DrawTools et par
thetaPG un plug-in pour GU ProGui). Si le nom fait
moins de huit caractères mettez des espaces : c'est très important
(ZPI les supprimera au moment de lancer le plug-in).
Finalement, les 14 caractères restants servent à donner un nom
à votre plug-in, lequel paraîtra à l'utilisateur dans le
menu PLUG-IN où il pourra le lancer.
- Tout programme plug-in de n'importe quel logiciel (GU
DrawTools, GU ProGui, ou le votre...) doit
posséder une structure minimale pour être fonctionnel en tant que
plug-in :
PROGRAM:thetaDTPIX
If 1=LZPI(1 // Si on est
en mode installation / désinstallation
Then //
Alors :
"1thetaDTPIX NOM DU
PLUG-IN" // Chaîne décrivant
le plug-in : caractère du logiciel assicié (1 caract), nom du
programme plug-in (8 caract) et nom (14 caract)
prgmZPI //
Lancer l'installation ou la désinstallation : la librairie l'installera
et s'il existe déjà dans la base de donnée (Str9) il le
désinstallera
Return
// Quitter : l'installation (ou la désinstallation) a été
faite
End
/*
On trouvera ici le code du plug-in proprement dit : à vous de jouer ;-)
*/
- Explicons ce code, s'il en est encore besoin : il s'agit du programme thetaDTPIX
(donc un plug-in pour GU DrawTools, celon les critères
définits plus haut). Sa "chaîne descriptive" est "1thetaDTPIX NOM DU
PLUG-IN", ce qui veut bien dire que c'est un
plug-in pour GU DrawTools, que son nom est
thetaDTPIX et que
ce qui apparaîtra dans le menu proposé à l'utilisateur afin
de choisir d'exécuter un plug-in est "NOM DU
PLUG-IN", ce qui fait tout juste 14 caractères (sinon, utiliser
des espaces : très IMPORTANT).
Voilà : vous pouvez créer un plugin !
Compréhension
de GU DrawTools :
- Voyons d'abord comment est conçu GU DrawTools
: il contient un menu principal (Lbl D, pour Drawtools) qui renvoi à
des sous menus (Lbl M pour Manipulations, etc...) qui lui même exécutera
l'outil dont le label est composé de la lettre (M pour Manipulations,
pour reprendre l'exemple précédent) et du chiffre correspondant
à la position de l'outil dans le menu (M5 pour SYMETRIE : menu M, option
5). Bref : ce n'est qu'une convention mais je la trouve bien. Soyons exaustif
en disant que si un outil a besoin de plusieurs labels il peut se nommer avec
cette même lettre et une seconde lettre : on commence à A et on
incrémente au fur et à mesure que les outils en ont besoin (je
n'ai pas fait comme cela dans GU DrawTools mais
j'aurais dû...).
- Lorsque l'on revient au menu principal, on sauvegarde l'image si elle a été
modifiée (variables I différente de 0) pour pouvoir bénéficier
de la fonction d'annulation.
Si elle a été modifiée on met J à 1 (ne pas l'utiliser
dans vos plug-ins) afin de demander à l'utilisateur s'il veut sauver
son image lorsqu'il quittera (ou chargera une autre image). On remet également
1 dans LZGUS(7) afin d'éviter à l'utilisateur
de voir le menu de sélection (il choisira la plupart du temps RECTANGLE).
C'est tout ce que fait le menu principal.
- Il faut juste noter que le nom de l'image-liste est stoqué dans Str2.
Str2 contient "?" si
l'utilisateur n'a toujours pas sauvé la nouvelle image (ne lui a toujours
pas donné de nom). La liste LZGUDTI contient l'image
dernièrement sauvée et LZGUDTA l'image d'annulation.
Voilà pour l'utilisation des variables : en clair si votre outil doit
utiliser des variables prennez K pour stoquer une éventuelle touche (getKey),
L pour stoquer une couleur (recommandé car plusieurs outils demandent
ce paramètre dans L) et les variables de M à Z pour le reste (surtout
pas de A à J car vous risqueriez de modifier le comportement du programme,
rien que pour les variables I et J, les huit première sont bien spur
réservées à la sélection, que vous pouvez modifier
comme il vous faut, un UpdateData les remettra comme lors de la dernière
sélection). Généralement les variables de X à Z
et theta sont utilisées par des libs et peuvent donc être altérées
après un appel à celles-ci : renseignez-vous plus haut.
- Voici une fonction type de GU DrawTools :
Lbl FX //
Le label de début de la fonction : F pour le premier nom du menu contenant
cette fonction et X pour le numéro de la fonction dans ce menu
7:prgmZGU //
Là on demande à l'utilisateur de choisir une couleur...
/* Ici on demandera à l'utilisateur de configurer
d'autres options de l'outil... */
Ans->L //
...et on la stoque dans L
Repeat 0 //
On entre enfin dans la boucle de la fonction qui s'exécutera tant que
l'utilisateur ne quitte pas votr outil
pi:prgmZGU
// L'utilisateur va faire une sélection sous la
forme (A,B,C,D)
If Ans=2 //
S'il veux reconfigurer l'outil on revient au début du code de la fonction,
où il pourra redéfinir la couleur (entre autre)
Goto FX //
Voilà
If Ans:Goto D
// Si Ans contient quelque chose ce ne peut plus être
que 1 : on quitte l'outil pour revenir au menu (label D)
/* On trouvera ici le code de l'outil
proprement dit : à vous de jouer ;-) */
1->I //
Vu qu'on a modifié l'image on met 1 dans I pour indiquer à GU
DrawTools de sauver l'image (pour avoir accès à la fonction d'annulation)
End //
On utilise l'outil tant qu'on veut : l'utilisateur resélectionnera, etc...
Bien sûr, si un outil a besoin d'une sélection en point (comme
l'outil POINT ! ) on met 0 à la place de pi.
Idem : si l'on n'a pas besoin de configurer une couleur on ne le fait pas, mais
incluez toujours les tests des valeurs de retour pour ne pas exécuter
l'outil avec des coordonnées fausses si l'utilisateur a annulé,
revenir à FX même s'il n'y a rien à configurer (cela permettra,
si l'utilisateur a déjà sélectionné un point, de
l'annuler et de recommencer la sélection), etc...
Pour finir : n'oubliez pas de mettre I à 1 si l'image a été
modifiée pour que l'utilisateur ne soit pas perdu lorsqu'il sélectionnera
l'outil Annuler (il est à rappeler qu'il faut repasser par le menu général
de GU DrawTools afin de sauver l'image d'annulation
: si vous ne supportez pas cela recopiez la routine de sauvegarde de l'image
d'annulation : entre Lbl D et
Menu(" DRAW TOOLS ").
Utilisation des variables
: Str3 : temporaire ; Str4 : le code généré ; LZGUPGI
: l'image résultat (modifiée lors du retour au menu MODELISATION).
Vous pouvez utiliser la librairie prgmZGUPG comme décrit ci-dessus...
Je n'ai pas grand chose à dire dessus : voyez le code de cette librairie
pour voir l'implémentation de la MODELISATION et prgmGUPROGUI pour ce
qui est du reste (WORKSPACE, VECTORL...).
Sinon, le système de menus, de labels, etc... se rapproche de ce qui
est utilisé dans GU DrawTools.
Si vous voulez créer
un programme indépendant de la suite (mais utilisant ses librairies)
voici ce qu'il vous faudra faire :
- Initialiser LZGUS par un simple 9:prgmZGU
si vous utiliserez l'outil de sélection.
- Vous pouvez utiliser la librairie de plug-ins, bien sûr...
- Pour avoir d'autres renseignements sur la façon d'implémenter
une fonction, il y a toujours le code source de mes modules...
NOTE : Si vous souhaitez que je commente un module, que j'explique une
fonctionnalité, ou autre... mailez-moi afin d'ajouter cela dans la documentation
pour programmeurs de la version finale.
Si
vous avez fait un plug-in ou un programme grace à mes librairies, merci
de m'en faire part par e-mail (et pour le mettre sur le site si vous voulez).
Merci, et bonne programmation.