Suivez-nous sur X

|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : E - Mousemove et Painter
(Article écrit par Olivier Adam - septembre 1998)
|
|
Les litanies du E, langage des langages
Bon bon bon bon bon, j'espère que vous avez passé de bonnes vacances, et que vous
vous êtes déliés les doigts. En effet, on va continuer d'approfondir le concept de
programmation objet, toujours à l'aide de EasyGUI, parce que la notion de plugin (module) permet
d'implémenter ses propres fonctions, sous forme de modules réutilisables, et par emboîtement
on peut envisager des interfaces très complexes.
L'exemple de cet article est un petit programme de dessin (painter).
Il n'intègre qu'un seul outil de dessin, d'une part parce qu'il faut savoir rester humble ;-)
et d'autre part parce que je vous propose un atelier de travaux pratiques : si vous trouvez
mieux que ma solution, communiquez-moi vos sources, si vous créez un objet susceptible d'être
intégré au painter, je le teste et je l'ajoute à l'interface ! Dernière étape, je joins votre
module à la distribution suivante. Ceci jusqu'à ce que le painter soit terminé. Les .e et .m sont
fournis ainsi que les exécutables, de manière à pouvoir juger de l'avancée des travaux.
Quant aux droits d'auteur ou autres merderies, on s'en balance (c'est clair) : tout est
entièrement domaine public, l'argent ne devant pas être un obstacle à l'avancée de la
connaissance.
Notre projet est donc divisé en modules :
- Mousemove.e : traque les mouvements de la souris, dès lors que la fenêtre à laquelle
appartient ce module est active.
- Painter_plugin.e : le painter proprement dit, n'est encore qu'une surface sur laquelle
on peut dessiner. Il est fortement inspiré de l'exemple fourni avec EasyGUI...
- Painter.e : l'exécutable, qui contient l'interface intégrant nos objets.
- Painter_rev : module de Bumpee qui donne un numéro de version.
Exemple :
ram:> version painter full
rend : painter 1.0 (22/08/98)
Quant au fonctionnement, il est enfantin et les sources sont commentées lorsque c'est
nécessaire. Afin de ne pas mâcher complètement le travail, je n'ai pas commenté le module
mousemove, mais j'espère que vous avez compris. En somme, c'est en forgeant que l'on devient
forgeron.
Pour tuer dans l'oeuf toute polémique :
- "Pourquoi tu veux pas nous apprendre comment on fait pour MUI ?"
- "Parce que je déteste MUI : c'est lourd de voir des dizaines de bibliothèques ouvertes rien
que pour faire des pov' z'interfaces, mais plus grâve, ça laisse des "locks" sur les programmes
(on peut plus les effacer : erreur, objet en utilisation). Donc pas de MUI... On peut faire mieux
avec intuition.library et GadTools.
Source mousemove.e
OPT MODULE
OPT OSVERSION=37
OPT EXPORT
MODULE 'tools/EasyGUI',
'intuition/intuition'
OBJECT mousemove OF plugin
mx,old_mx
my,old_my
ENDOBJECT
PROC min_size(ta,fh) OF mousemove IS 0,0
PROC will_resize() OF mousemove IS FALSE
PROC render(ta,x,y,xs,ys,w:PTR TO window) OF mousemove IS EMPTY
PROC message_test(imsg:PTR TO intuimessage,w:PTR TO window) OF mousemove
self.mx:=imsg.mousex
self.my:=imsg.mousey
self.old_mx:=self.mx
self.old_my:=self.my
ENDPROC imsg.class=IDCMP_INTUITICKS
PROC message_action(class,qual,code,win) OF mousemove IS TRUE
|
Source painter.e
->©Adam98
-> use our plugin
OPT OSVERSION=37 -> pas avant ! testé sur A1230-IV
OPT PREPROCESS -> pour le numéro de version (bumpee)
MODULE 'graphics/text', -> sont dans Emodules :
'intuition/intuition',
'intuition/screens',
'tools/EasyGUI',
'*painter_plugin', -> sont dans notre répertoire
'*mousemove',
'*painter_rev' -> bumpee ! peut être mis en commentaire
-> globales, car utilisées par plusieurs fonctions ou procédures
DEF mouse:PTR TO mousemove,plug:PTR TO painter,t
->programme proprement dit :
PROC main() HANDLE
DEF depth,
s:PTR TO screen,
di:PTR TO drawinfo
-> profondeur de l'écran nécessaire pour PALETTE
s:=LockPubScreen(NIL) -> on bloque (des fois que) l'écran par défaut
di:=GetScreenDrawInfo(s) -> on stocke la drawinfo de cet écran
depth:=di.depth -> on en extrait la profondeur
FreeScreenDrawInfo(s,di) -> on libère la structure di
UnlockPubScreen(NIL,s) -> on débloque l'écran (ce n'est pas à nous !)
-> l'interface...
easyguiA('painter',
[EQROWS,
[PLUGIN,{m_a},NEW mouse], -> NEW => END !
t:=[TEXT,'',NIL,TRUE,15], -> contiendra les coordonnées de la souris
[BEVEL,[PAINTER,0,NEW plug]], -> notre surface
[PALETTE,{p_a},NIL,depth,3,5,plug.color] -> la palette
],
NIL -> pas de préférences particulières ni de menus
)
EXCEPT DO -> passer par là systématiquement
IF plug THEN END plug
IF mouse THEN END mouse
IF exception THEN WriteF('Error : n°\d, \s\n',exception,exceptioninfo)
IF exception THEN CleanUp(exception)
ENDPROC
-> sous-fonctions de l'interface
PROC p_a(info,col) -> on a cliqué sur la palette
plug.color:=col -> on rafraîchit les données du painter
ENDPROC
PROC m_a(info,m:PTR TO mousemove) -> rafraîchissement des coordonnées
DEF tt[13]:STRING
StringF(tt,'x=\d[4],y=\d[4]',m.mx,m.my)
settext(info,t,tt) -> rafraîchissement du texte
ENDPROC
|
Source painter_plugin.e
-> olivieradam@minitel.net (ASCII only !)
OPT MODULE -> ceci est un module
OPT OSVERSION=37 ->version minimum du système
-> modules objets , CONSTANTES
MODULE 'graphics/text', -> textattr
'intuition/intuition', -> window,intuimessage
'intuition/screens', -> screen
'tools/EasyGUI' -> plugin , PLUGIN
-> notre objet : une surface pouvant être peinte
EXPORT OBJECT painter OF plugin
xm:INT, ->x souris
ym:INT, ->y souris
color:INT ->couleur choisie
ENDOBJECT
EXPORT CONST PAINTER=PLUGIN
-> Les méthodes par défaut :
PROC will_resize() OF painter IS COND_RESIZEX OR COND_RESIZEY
PROC min_size(ta:PTR TO textattr,fh) OF painter IS 100,100 ->taille de 100x100
PROC render(ta:PTR TO textattr,x,y,xs,ys,w:PTR TO window) OF painter IS self.draw(w,0)
PROC message_test(imsg:PTR TO intuimessage,w:PTR TO window) OF painter
-> test automatique de l'interface
DEF x,y
IF (imsg.class=IDCMP_MOUSEBUTTONS) OR (imsg.code=SELECTUP) -> si on a cliqué alors :
x:=imsg.mousex
y:=imsg.mousey
IF (x>=self.x) AND (y>=self.y) AND (x<(self.x+self.xs)) AND (y<(self.y+self.ys))
->et si en plus on a cliqué dans la fenêtre alors :
self.xm:=x-self.x*1000/self.xs ->changement d'échelle
self.ym:=y-self.y*1000/self.ys
RETURN TRUE -> retourne vrai => provoque message_action()
ENDIF
ENDIF
ENDPROC FALSE -> retourne faux => pas de message_action()
-> ici on peut extraire les touches appuyées aussi ex : Amiga Alt Ctrl Help...
PROC message_action(class,qual,code,w:PTR TO window) OF painter
self.draw(w,0) -> dessine l'outil 0 où l'on a cliqué
ENDPROC FALSE
-> méthode perso de dession
PROC draw(w:PTR TO window,pad) OF painter -> le pad est là pour permettre d'ajouter des outils
DEF xm,ym
SELECT pad
CASE 0
xm:=self.xm*self.xs/1000+self.x -> re-changement d'échelle
ym:=self.ym*self.ys/1000+self.y
SetStdRast(w.rport) -> des fois que...
-> ma petite brosse
Line(xm-1,ym,xm+1,ym,self.color)
Line(xm,ym+1,xm,ym-1,self.color)
Plot(self.xm+self.x,self.ym+self.y,self.color)
-> CASE 1 -> autre outil, par exemple : ligne, rond, rectangle...
DEFAULT ; NOP -> outil par défaut, pour ne rien oublier
ENDSELECT
ENDPROC
|
[Télécharger les sources et les exécutables de cet article]
Voilà c'est tout pour cette fois-ci, bon amusement !
|