//### HEADER ### #ifndef CFENETRE_H #define CFENETRE_H #include "tasklib.h" #include "ccomserie.h" #include #include "chaine.h" #include "campex.h" class CFenetre : public CChaine { //attributs public: CAmpex *io; protected: char *texte, *attTexte, *cadre, *attCadre; unsigned char pX, pY; //position (valeurs absolues) private: unsigned char tX, tY; //dimensions (valeurs absolues) char *zoneCouverte, *zoneAffichee; // dessins de la fenêtre avant et après affichage bool affiche; CFenetre *mere; CFenetre *filles; bool (*evFunc)(char,CFenetre); //méthodes public: CFenetre *boutons(void); void initCanal(CAmpex *io); bool setText(char * txt, char *attr=0); //détermine un texte ou le supprime bool setCadre(char * Cadre, char *attr=0); //détermine un cadre ou le supprime void getText(char *Texte, char *attr=0); // retourne le texte, vaut 0 si echec (texte trop petite, par ex) void getCadre(char *Cadre, char *attr=0); // retourne le cadre, vaut 0 si echec (cadre trop petite, par ex) void deplacer(short x, short y=0); // déplacement relatif à la fenêtre mère void positioner(short x=-1, short y=-1); // position relative à la fenêtre mère void positioner(unsigned char x=0xFF, unsigned char y=0xFF); // position absolue void dimensionner(unsigned char x=0xFF, unsigned char y=0xFF); bool afficher(void); void effacer(void); virtual char gesEvent(void); CFenetre(CFenetre *mere=0); void gesEvent(bool (*callback)(char,CFenetre)=0); virtual ~CFenetre(); protected: private: }; #endif // CFENETRE_H //### SOURCE ### #include "fenetre.h" CFenetre::CFenetre(CFenetre *mere) :CChaine() { //ctor this->mere=mere; filles=0; affiche=0; texte=0; attTexte=0; cadre=0; attCadre=0; } CFenetre::~CFenetre() { //dtor if(affiche) { io->deplace(pX, pY); for(unsigned char y=pY;yattribut(zoneCouverte[((x-pX)+(y-pY)*tX)<<1]); //envoie les attributs io->ecrire(zoneCouverte[(((x-pX)+(y-pY)*tX)<<1)+1]); //envoie les caractères } } if(zoneCouverte) delete zoneCouverte; if(zoneAffichee) delete zoneAffichee; if(cadre) delete cadre; if(cadre) delete attCadre; if(texte) delete texte; if(cadre) delete attTexte; delete filles; } bool CFenetre::afficher(void) { unsigned char x,y; if(!(zoneCouverte && zoneAffichee) && affiche)// si une memoire n'est pas reservee ou que la fenetre est affichée return false; //enregistre la zone qui va être écrasée io->deplace(pX, pY); for(y=pY;ylitAtt(zoneCouverte[((x-pX)+(y-pY)*tX)<<1]); //lit l'attribut io->lire(zoneCouverte[(((x-pX)+(y-pY)*tX)<<1)+1]); //lit le caractère } //dessine la fenêtre à partir des éléments possédés for(y=0;ydeplace(pX, pY); for(y=pY;yecrAtt(zoneAffichee[((x-pX)+(y-pY)*tX)<<1]); //envoie l'attribut io->ecrire(zoneAffichee[(((x-pX)+(y-pY)*tX)<<1)+1]); //envoie le caractère } affiche=true; return true; } void CFenetre::effacer(void) { int y,x=0; if(!affiche)// si la fenetre n'est pas affichée return; io->deplace(pX, pY); for(y=pY;yecrireChaine for(x=pX;xecrAtt(zoneCouverte[((x-pX)+(y-pY)*tX)<<1]); //envoie l'attribut io->ecrire(zoneCouverte[(((x-pX)+(y-pY)*tX)<<1)+1]); //envoie le caractère } } affiche=false; } bool CFenetre::setText(char * txt, char *attr) //détermine un texte ou le supprime { // texte if(texte) delete texte; texte=0; texte=new char[strlen(txt)]; if(!texte) return false; strcpy(texte,txt); //attributs du texte if(attTexte) delete attTexte; attTexte=0; if(attr) { attTexte=new char[strlen(attr)]; if(!attTexte) return false; strcpy(attTexte,attr); } return true; } bool CFenetre::setCadre(char * Cadre, char *attr) //détermine un cadre ou le supprime { // cadre if(cadre) delete cadre; cadre=0; cadre=new char[strlen(Cadre)]; if(!cadre) return false; strcpy(cadre,Cadre); //attributs du cadre if(attCadre) delete attCadre; attCadre=0; if(attr) { attCadre=new char[strlen(attr)]; if(!attCadre) return false; strcpy(attCadre,attr); } return true; } void CFenetre::getText(char *Texte, char *attr) // retourne le texte, vaut 0 si echec (texte trop petite, par ex) { if(Texte) delete Texte; Texte=new char[strlen(texte)]; strcpy(Texte,texte); if(attTexte && attr) { delete attr; attr=new char[strlen(attTexte)]; strcpy(attr, attTexte); } } void CFenetre::getCadre(char *Cadre, char *attr) // retourne le cadre, vaut 0 si echec (cadre trop petite, par ex) { if(Cadre) delete Cadre; Cadre=new char[strlen(cadre)]; strcpy(Cadre,cadre); if(attCadre && attr) { delete attr; attr=new char[strlen(attCadre)]; strcpy(attr, attCadre); } } void CFenetre::deplacer(short x, short y) // déplacement relatif à la fenêtre mère { bool ancienAff=affiche; effacer(); if(x) pX+=x; if(y) pY+=y; if(ancienAff) afficher(); } void CFenetre::positioner(short x, short y) // position relative à la fenêtre mère { bool ancienAff=affiche; effacer(); if(mere) { if(x!=-1) pX=mere->pX+x; if(y!=-1) pY=mere->pY+y; } if(ancienAff) afficher(); } void CFenetre::positioner(unsigned char x, unsigned char y) // position absolue { bool ancienAff=affiche; effacer(); if(x!=0xFF) pX=x; if(y!=0xFF) pY=y; if(ancienAff) afficher(); } void CFenetre::dimensionner(unsigned char x, unsigned char y) { bool ancienAff=affiche; effacer(); if(x!=0xFF) tX=x; if(y!=0xFF) tY=y; if(zoneCouverte) delete zoneCouverte; if(zoneAffichee) delete zoneAffichee; zoneCouverte=new char[(tX*tY)<<1]; zoneAffichee=new char[(tX*tY)<<1]; if(ancienAff) afficher(); } inline CFenetre *CFenetre::boutons(void) { return filles; } inline void CFenetre::initCanal(CAmpex *io) { this->io=io; } inline void CFenetre::gesEvent(bool (*callback)(char,CFenetre)) { char car; if(callback) evFunc=callback; do { while(!io->lireCar(&car)) taskDelay(1); } while(evFunc(car,this)); }