/* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2007 Adrien Destugues Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud) Grafx2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. Grafx2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Grafx2; if not, see or write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // // Ce fichier contient la gestion du moteur // #include #include #include #include "const.h" #include "struct.h" #include "global.h" #include "graph.h" #include "divers.h" #include "special.h" #include "boutons.h" #include "operatio.h" #include "shade.h" #include "erreurs.h" #include "sdlscreen.h" #include "windows.h" #include "brush.h" #include "input.h" // we need this as global short Old_MX = -1; short Old_MY = -1; //---------- Annuler les effets des modes de dessin (sauf la grille) --------- // Variables mémorisants les anciens effets byte Shade_Mode_avant_annulation; byte Quick_shade_Mode_avant_annulation; byte Stencil_Mode_avant_annulation; byte Trame_Mode_avant_annulation; byte Colorize_Mode_avant_annulation; byte Smooth_Mode_avant_annulation; byte Tiling_Mode_avant_annulation; fonction_effet Fonction_effet_avant_annulation; byte* Fond_fenetre[8]; void Annuler_les_effets(void) { Shade_Mode_avant_annulation=Shade_Mode; Shade_Mode=0; Quick_shade_Mode_avant_annulation=Quick_shade_Mode; Quick_shade_Mode=0; Stencil_Mode_avant_annulation=Stencil_Mode; Stencil_Mode=0; Trame_Mode_avant_annulation=Trame_Mode; Trame_Mode=0; Colorize_Mode_avant_annulation=Colorize_Mode; Colorize_Mode=0; Smooth_Mode_avant_annulation=Smooth_Mode; Smooth_Mode=0; Tiling_Mode_avant_annulation=Tiling_Mode; Tiling_Mode=0; Fonction_effet_avant_annulation=Fonction_effet; Fonction_effet=Aucun_effet; } //----------------- Restaurer les effets des modes de dessin ----------------- void Restaurer_les_effets(void) { Shade_Mode =Shade_Mode_avant_annulation; Quick_shade_Mode=Quick_shade_Mode_avant_annulation; Stencil_Mode =Stencil_Mode_avant_annulation; Trame_Mode =Trame_Mode_avant_annulation; Colorize_Mode =Colorize_Mode_avant_annulation; Smooth_Mode =Smooth_Mode_avant_annulation; Tiling_Mode =Tiling_Mode_avant_annulation; Fonction_effet =Fonction_effet_avant_annulation; } char * TITRE_BOUTON[NB_BOUTONS]= { "Paintbrush choice ", "Adjust picture / Effects", "Freehand draw. / Toggle ", "Splines / Toggle ", "Lines / Toggle ", "Spray / Menu ", "Floodfill / Replace col.", "Polylines / Polyforms ", "Polyfill / Filled Pforms", "Empty rectangles ", "Filled rectangles ", "Empty circles / ellipses", "Filled circles / ellips.", "Grad. rectangles ", "Gradation menu ", "Grad. spheres / ellipses", "Brush grab. / Restore ", "Lasso / Restore brush ", "Brush effects ", "Drawing modes (effects) ", "Text ", "Magnify mode / Menu ", "Pipette / Invert colors ", "Screen size / Safe. res.", "Go / Copy to other page ", "Save as / Save ", "Load / Re-load ", "Settings ", "Clear / with backcolor ", "Help / Statistics ", "Undo / Redo ", "Kill current page ", "Quit ", "Palette editor ", "Scroll pal. left / Fast ", "Scroll pal. right / Fast", "Color #" , "Hide tool bar " }; // Sauvegarde un bloc (généralement l'arrière-plan d'une fenêtre) void Sauve_fond(byte **Buffer, int Pos_X, int Pos_Y, int Largeur, int Hauteur) { int Indice; if(*Buffer != NULL) DEBUG("WARNING : Buffer already allocated !!!",0); *Buffer=(byte *) malloc(Largeur*Menu_Facteur_X*Hauteur*Menu_Facteur_Y*Pixel_width); for (Indice=0; Indice<(Hauteur*Menu_Facteur_Y); Indice++) Lire_ligne(Pos_X,Pos_Y+Indice,Largeur*Menu_Facteur_X,(*Buffer)+((int)Indice*Largeur*Menu_Facteur_X*Pixel_width)); } // Restaure de ce que la fenêtre cachait void Restaure_fond(byte *Buffer, int Pos_X, int Pos_Y, int Largeur, int Hauteur) { int Indice; for (Indice=0; Indice=Bouton[Numero].Decalage_X) && (Pos_Y>=Bouton[Numero].Decalage_Y) && (Pos_X<=Bouton[Numero].Decalage_X+Bouton[Numero].Largeur) && (Pos_Y<=Bouton[Numero].Decalage_Y+Bouton[Numero].Hauteur)) return Numero; break; case FORME_BOUTON_TRIANGLE_HAUT_GAUCHE: if ((Pos_X>=Bouton[Numero].Decalage_X) && (Pos_Y>=Bouton[Numero].Decalage_Y) && (Pos_X+Pos_Y-(short)Bouton[Numero].Decalage_Y-(short)Bouton[Numero].Decalage_X<=Bouton[Numero].Largeur)) return Numero; break; case FORME_BOUTON_TRIANGLE_BAS_DROITE: if ((Pos_X<=Bouton[Numero].Decalage_X+Bouton[Numero].Largeur) && (Pos_Y<=Bouton[Numero].Decalage_Y+Bouton[Numero].Hauteur) && (Pos_X+Pos_Y-(short)Bouton[Numero].Decalage_Y-(short)Bouton[Numero].Decalage_X>=Bouton[Numero].Largeur)) return Numero; break; } } return -1; } void Tracer_cadre_de_bouton_du_menu(byte Numero,byte Enfonce) { byte Couleur_Haut_gauche; byte Couleur_Bas_droite; byte Couleur_Diagonale; word Debut_X; word Debut_Y; word Fin_X; word Fin_Y; word Pos_X; word Pos_Y; Debut_X=Bouton[Numero].Decalage_X; Debut_Y=Bouton[Numero].Decalage_Y; Fin_X =Debut_X+Bouton[Numero].Largeur; Fin_Y =Debut_Y+Bouton[Numero].Hauteur; if (!Enfonce) { Couleur_Haut_gauche=CM_Blanc; Couleur_Bas_droite=CM_Fonce; Couleur_Diagonale=CM_Clair; } else { Couleur_Haut_gauche=CM_Fonce; Couleur_Bas_droite=CM_Noir; Couleur_Diagonale=CM_Fonce; } switch(Bouton[Numero].Forme) { case FORME_BOUTON_SANS_CADRE : break; case FORME_BOUTON_RECTANGLE : // On colorie le point haut droit Pixel_dans_menu(Fin_X,Debut_Y,Couleur_Diagonale); BLOCK_MENU[Debut_Y][Fin_X]=Couleur_Diagonale; // On colorie le point bas gauche Pixel_dans_menu(Debut_X,Fin_Y,Couleur_Diagonale); BLOCK_MENU[Fin_Y][Debut_X]=Couleur_Diagonale; // On colorie la partie haute for (Pos_X=Debut_X;Pos_X<=Fin_X-1;Pos_X++) { Pixel_dans_menu(Pos_X,Debut_Y,Couleur_Haut_gauche); BLOCK_MENU[Debut_Y][Pos_X]=Couleur_Haut_gauche; } for (Pos_Y=Debut_Y+1;Pos_Y<=Fin_Y-1;Pos_Y++) { // On colorie la partie gauche Pixel_dans_menu(Debut_X,Pos_Y,Couleur_Haut_gauche); BLOCK_MENU[Pos_Y][Debut_X]=Couleur_Haut_gauche; // On colorie la partie droite Pixel_dans_menu(Fin_X,Pos_Y,Couleur_Bas_droite); BLOCK_MENU[Pos_Y][Fin_X]=Couleur_Bas_droite; } // On colorie la partie basse for (Pos_X=Debut_X+1;Pos_X<=Fin_X;Pos_X++) { Pixel_dans_menu(Pos_X,Fin_Y,Couleur_Bas_droite); BLOCK_MENU[Fin_Y][Pos_X]=Couleur_Bas_droite; } break; case FORME_BOUTON_TRIANGLE_HAUT_GAUCHE: // On colorie le point haut droit Pixel_dans_menu(Fin_X,Debut_Y,Couleur_Diagonale); BLOCK_MENU[Debut_Y][Fin_X]=Couleur_Diagonale; // On colorie le point bas gauche Pixel_dans_menu(Debut_X,Fin_Y,Couleur_Diagonale); BLOCK_MENU[Fin_Y][Debut_X]=Couleur_Diagonale; // On colorie le coin haut gauche for (Pos_X=0;Pos_XSPECIAL_CLICK_RIGHT) switch(Indice_Touche) { case SPECIAL_SCROLL_UP : // Scroll up if (Loupe_Mode) Scroller_loupe(0,-(Loupe_Hauteur>>2)); else Scroller_ecran(0,-(Hauteur_ecran>>3)); Touche=0; break; case SPECIAL_SCROLL_DOWN : // Scroll down if (Loupe_Mode) Scroller_loupe(0,(Loupe_Hauteur>>2)); else Scroller_ecran(0,(Hauteur_ecran>>3)); Touche=0; break; case SPECIAL_SCROLL_LEFT : // Scroll left if (Loupe_Mode) Scroller_loupe(-(Loupe_Largeur>>2),0); else Scroller_ecran(-(Largeur_ecran>>3),0); Touche=0; break; case SPECIAL_SCROLL_RIGHT : // Scroll right if (Loupe_Mode) Scroller_loupe((Loupe_Largeur>>2),0); else Scroller_ecran((Largeur_ecran>>3),0); Touche=0; break; case SPECIAL_SCROLL_UP_FAST : // Scroll up faster if (Loupe_Mode) Scroller_loupe(0,-(Loupe_Hauteur>>1)); else Scroller_ecran(0,-(Hauteur_ecran>>2)); Touche=0; break; case SPECIAL_SCROLL_DOWN_FAST : // Scroll down faster if (Loupe_Mode) Scroller_loupe(0,(Loupe_Hauteur>>1)); else Scroller_ecran(0,(Hauteur_ecran>>2)); Touche=0; break; case SPECIAL_SCROLL_LEFT_FAST : // Scroll left faster if (Loupe_Mode) Scroller_loupe(-(Loupe_Largeur>>1),0); else Scroller_ecran(-(Largeur_ecran>>2),0); Touche=0; break; case SPECIAL_SCROLL_RIGHT_FAST : // Scroll right faster if (Loupe_Mode) Scroller_loupe((Loupe_Largeur>>1),0); else Scroller_ecran((Largeur_ecran>>2),0); Touche=0; break; case SPECIAL_SCROLL_UP_SLOW : // Scroll up slower if (Loupe_Mode) Scroller_loupe(0,-1); else Scroller_ecran(0,-1); Touche=0; break; case SPECIAL_SCROLL_DOWN_SLOW : // Scroll down slower if (Loupe_Mode) Scroller_loupe(0,1); else Scroller_ecran(0,1); Touche=0; break; case SPECIAL_SCROLL_LEFT_SLOW : // Scroll left slower if (Loupe_Mode) Scroller_loupe(-1,0); else Scroller_ecran(-1,0); Touche=0; break; case SPECIAL_SCROLL_RIGHT_SLOW : // Scroll right slower if (Loupe_Mode) Scroller_loupe(1,0); else Scroller_ecran(1,0); Touche=0; break; case SPECIAL_NEXT_FORECOLOR : // Next foreground color Special_Next_forecolor(); Touche=0; break; case SPECIAL_PREVIOUS_FORECOLOR : // Previous foreground color Special_Previous_forecolor(); Touche=0; break; case SPECIAL_NEXT_BACKCOLOR : // Next background color Special_Next_backcolor(); Touche=0; break; case SPECIAL_PREVIOUS_BACKCOLOR : // Previous background color Special_Previous_backcolor(); Touche=0; break; case SPECIAL_RETRECIR_PINCEAU: // Rétrécir le pinceau Retrecir_pinceau(); Touche=0; break; case SPECIAL_GROSSIR_PINCEAU: // Grossir le pinceau Grossir_pinceau(); Touche=0; break; case SPECIAL_NEXT_USER_FORECOLOR : // Next user-defined foreground color Message_Non_disponible(); // !!! TEMPORAIRE !!! //Special_Next_user_forecolor(); Touche=0; break; case SPECIAL_PREVIOUS_USER_FORECOLOR : // Previous user-defined foreground color Message_Non_disponible(); // !!! TEMPORAIRE !!! //Special_Previous_user_forecolor(); Touche=0; break; case SPECIAL_NEXT_USER_BACKCOLOR : // Next user-defined background color Message_Non_disponible(); // !!! TEMPORAIRE !!! //Special_Next_user_backcolor(); Touche=0; break; case SPECIAL_PREVIOUS_USER_BACKCOLOR : // Previous user-defined background color Message_Non_disponible(); // !!! TEMPORAIRE !!! //Special_Previous_user_backcolor(); Touche=0; break; case SPECIAL_SHOW_HIDE_CURSOR : // Show / Hide cursor Effacer_curseur(); Cacher_curseur=!Cacher_curseur; Afficher_curseur(); Touche=0; break; case SPECIAL_PINCEAU_POINT : // Paintbrush = "." Effacer_curseur(); Pinceau_Forme=FORME_PINCEAU_ROND; Modifier_pinceau(1,1); Changer_la_forme_du_pinceau(FORME_PINCEAU_ROND); Afficher_curseur(); Touche=0; break; case SPECIAL_DESSIN_CONTINU : // Continuous freehand drawing Enclencher_bouton(BOUTON_DESSIN,A_GAUCHE); // ATTENTION CE TRUC EST MOCHE ET VA MERDER SI ON SE MET A UTILISER DES BOUTONS POPUPS while (Operation_en_cours!=OPERATION_DESSIN_CONTINU) Enclencher_bouton(BOUTON_DESSIN,A_DROITE); Touche=0; break; case SPECIAL_FLIP_X : // Flip X Effacer_curseur(); Flip_X_LOWLEVEL(); Afficher_curseur(); Touche=0; break; case SPECIAL_FLIP_Y : // Flip Y Effacer_curseur(); Flip_Y_LOWLEVEL(); Afficher_curseur(); Touche=0; break; case SPECIAL_ROTATE_90 : // 90° brush rotation Effacer_curseur(); Rotate_90_deg(); Afficher_curseur(); Touche=0; break; case SPECIAL_ROTATE_180 : // 180° brush rotation Effacer_curseur(); if (Brosse_Hauteur&1) { // Brosse de hauteur impaire Flip_X_LOWLEVEL(); Flip_Y_LOWLEVEL(); } else Rotate_180_deg_LOWLEVEL(); Brosse_Decalage_X=(Brosse_Largeur>>1); Brosse_Decalage_Y=(Brosse_Hauteur>>1); Afficher_curseur(); Touche=0; break; case SPECIAL_STRETCH : // Stretch brush Effacer_curseur(); Demarrer_pile_operation(OPERATION_ETIRER_BROSSE); Afficher_curseur(); Touche=0; break; case SPECIAL_DISTORT : // Distort brush Message_Non_disponible(); // !!! TEMPORAIRE !!! Touche=0; break; case SPECIAL_ROTATE_ANY_ANGLE : // Rotate brush by any angle Effacer_curseur(); Demarrer_pile_operation(OPERATION_TOURNER_BROSSE); Afficher_curseur(); Touche=0; break; case SPECIAL_OUTLINE : // Outline brush Effacer_curseur(); Outline_brush(); Afficher_curseur(); Touche=0; break; case SPECIAL_NIBBLE : // Nibble brush Effacer_curseur(); Nibble_brush(); Afficher_curseur(); Touche=0; break; case SPECIAL_GET_BRUSH_COLORS : // Get colors from brush Get_colors_from_brush(); Touche=0; break; case SPECIAL_RECOLORIZE_BRUSH : // Recolorize brush Effacer_curseur(); Remap_brosse(); Afficher_curseur(); Touche=0; break; case SPECIAL_LOAD_BRUSH : Load_picture(0); Touche=0; break; case SPECIAL_SAVE_BRUSH : Save_picture(0); Touche=0; break; case SPECIAL_ZOOM_IN : // Zoom in Zoom(+1); Touche=0; break; case SPECIAL_ZOOM_OUT : // Zoom out Zoom(-1); Touche=0; break; case SPECIAL_CENTER_ATTACHMENT : // Center brush attachment Effacer_curseur(); Brosse_Decalage_X=(Brosse_Largeur>>1); Brosse_Decalage_Y=(Brosse_Hauteur>>1); Afficher_curseur(); Touche=0; break; case SPECIAL_TOP_LEFT_ATTACHMENT : // Top-left brush attachment Effacer_curseur(); Brosse_Decalage_X=0; Brosse_Decalage_Y=0; Afficher_curseur(); Touche=0; break; case SPECIAL_TOP_RIGHT_ATTACHMENT : // Top-right brush attachment Effacer_curseur(); Brosse_Decalage_X=(Brosse_Largeur-1); Brosse_Decalage_Y=0; Afficher_curseur(); Touche=0; break; case SPECIAL_BOTTOM_LEFT_ATTACHMENT : // Bottom-left brush attachment Effacer_curseur(); Brosse_Decalage_X=0; Brosse_Decalage_Y=(Brosse_Hauteur-1); Afficher_curseur(); Touche=0; break; case SPECIAL_BOTTOM_RIGHT_ATTACHMENT : // Bottom right brush attachment Effacer_curseur(); Brosse_Decalage_X=(Brosse_Largeur-1); Brosse_Decalage_Y=(Brosse_Hauteur-1); Afficher_curseur(); Touche=0; break; case SPECIAL_EXCLUDE_COLORS_MENU : // Exclude colors menu Menu_Tag_couleurs("Tag colors to exclude",Exclude_color,&Temp,1, NULL); Touche=0; break; case SPECIAL_INVERT_SIEVE : Inverser_trame(); Touche=0; break; case SPECIAL_SHADE_MODE : Bouton_Shade_Mode(); Touche=0; break; case SPECIAL_SHADE_MENU : Bouton_Shade_Menu(); Touche=0; break; case SPECIAL_QUICK_SHADE_MODE : Bouton_Quick_shade_Mode(); Touche=0; break; case SPECIAL_QUICK_SHADE_MENU : Bouton_Quick_shade_Menu(); Touche=0; break; case SPECIAL_STENCIL_MODE : Bouton_Stencil_Mode(); Touche=0; break; case SPECIAL_STENCIL_MENU : Bouton_Menu_Stencil(); Touche=0; break; case SPECIAL_MASK_MODE : Bouton_Mask_Mode(); Touche=0; break; case SPECIAL_MASK_MENU : Bouton_Mask_Menu(); Touche=0; break; case SPECIAL_GRID_MODE : Bouton_Snap_Mode(); Touche=0; break; case SPECIAL_GRID_MENU : Bouton_Menu_Grille(); Touche=0; break; case SPECIAL_SIEVE_MODE : Bouton_Trame_Mode(); Touche=0; break; case SPECIAL_SIEVE_MENU : Bouton_Trame_Menu(); Touche=0; break; case SPECIAL_COLORIZE_MODE : Bouton_Colorize_Mode(); Touche=0; break; case SPECIAL_COLORIZE_MENU : Bouton_Colorize_Menu(); Touche=0; break; case SPECIAL_SMOOTH_MODE : Bouton_Smooth_Mode(); Touche=0; break; case SPECIAL_SMOOTH_MENU : Bouton_Smooth_Menu(); Touche=0; break; case SPECIAL_SMEAR_MODE : Bouton_Smear_Mode(); Touche=0; break; case SPECIAL_TILING_MODE : Bouton_Tiling_Mode(); Touche=0; break; case SPECIAL_TILING_MENU : Bouton_Tiling_Menu(); Touche=0; break; default : // Gestion des touches de raccourci de bouton: // Pour chaque bouton Bouton_Touche=-1; for (Indice_bouton=0;Indice_bouton=SPECIAL_SHADE_MODE) && (Indice_Touche<=SPECIAL_TILING_MENU)) { Effacer_curseur(); Tracer_cadre_de_bouton_du_menu(BOUTON_EFFETS, (Shade_Mode||Quick_shade_Mode||Colorize_Mode||Smooth_Mode||Tiling_Mode||Smear_Mode||Stencil_Mode||Mask_Mode||Trame_Mode||Snap_Mode)); Afficher_curseur(); } } } else Wait_VBL(); // S'il n'y a pas d'évènement, on ne gère pas tout ça et on attend un peu. La partie en dessous doit être exécutée quand // même pour les trucs asynchrones, par exemple le spray. // Gestion de la souris Curseur_dans_menu=(Mouse_Y>=Menu_Ordonnee) || ( (Loupe_Mode) && (Mouse_X>=Principal_Split) && (Mouse_X=Menu_Ordonnee) { if (Indice_bouton>=0) { Enclencher_bouton(Indice_bouton,Mouse_K); Indice_bouton_precedent=-1; } } else if (Loupe_Mode) Deplacer_Split(); } } // we need to refresh that one as we may come from a sub window Curseur_dans_menu=(Mouse_Y>=Menu_Ordonnee) || ( (Loupe_Mode) && (Mouse_X>=Principal_Split) && (Mouse_X>1; Fenetre_Pos_Y=(Hauteur_ecran-(Hauteur*Menu_Facteur_Y))>>1; // Sauvegarde de ce que la fenêtre remplace Sauve_fond(&(Fond_fenetre[Fenetre-1]), Fenetre_Pos_X, Fenetre_Pos_Y, Largeur, Hauteur); // Fenêtre grise Block(Fenetre_Pos_X+(Menu_Facteur_X<<1),Fenetre_Pos_Y+(Menu_Facteur_Y<<1),(Largeur-4)*Menu_Facteur_X,(Hauteur-4)*Menu_Facteur_Y,CM_Clair); // -- Cadre de la fenêtre ----- --- -- - - // Cadre noir puis en relief Fenetre_Afficher_cadre_mono(0,0,Largeur,Hauteur,CM_Noir); Fenetre_Afficher_cadre_bombe(1,1,Largeur-2,Hauteur-2); // Barre sous le titre Block(Fenetre_Pos_X+(Menu_Facteur_X<<3),Fenetre_Pos_Y+(11*Menu_Facteur_Y),(Largeur-16)*Menu_Facteur_X,Menu_Facteur_Y,CM_Fonce); Block(Fenetre_Pos_X+(Menu_Facteur_X<<3),Fenetre_Pos_Y+(12*Menu_Facteur_Y),(Largeur-16)*Menu_Facteur_X,Menu_Facteur_Y,CM_Blanc); Print_dans_fenetre((Largeur-(strlen(Titre)<<3))>>1,3,Titre,CM_Noir,CM_Clair); if (Fenetre == 1) { Menu_visible_avant_fenetre=Menu_visible; Menu_visible=0; Menu_Ordonnee_avant_fenetre=Menu_Ordonnee; Menu_Ordonnee=Hauteur_ecran; Forme_curseur_avant_fenetre=Forme_curseur; Forme_curseur=FORME_CURSEUR_FLECHE; Cacher_pinceau_avant_fenetre=Cacher_pinceau; Cacher_pinceau=1; } // Initialisation des listes de boutons de la fenêtre Fenetre_Liste_boutons_normal =NULL; Fenetre_Liste_boutons_palette =NULL; Fenetre_Liste_boutons_scroller=NULL; Fenetre_Liste_boutons_special =NULL; Nb_boutons_fenetre =0; } //----------------------- Fermer une fenêtre d'options ----------------------- void Fermer_fenetre(void) // Lors de l'appel à cette procedure, la souris doit être affichée. // En sortie de cette procedure, la souris est effacée. { struct Fenetre_Bouton_normal * Temp1; struct Fenetre_Bouton_palette * Temp2; struct Fenetre_Bouton_scroller * Temp3; struct Fenetre_Bouton_special * Temp4; Effacer_curseur(); while (Fenetre_Liste_boutons_normal) { Temp1=Fenetre_Liste_boutons_normal->Next; free(Fenetre_Liste_boutons_normal); Fenetre_Liste_boutons_normal=Temp1; } while (Fenetre_Liste_boutons_palette) { Temp2=Fenetre_Liste_boutons_palette->Next; free(Fenetre_Liste_boutons_palette); Fenetre_Liste_boutons_palette=Temp2; } while (Fenetre_Liste_boutons_scroller) { Temp3=Fenetre_Liste_boutons_scroller->Next; free(Fenetre_Liste_boutons_scroller); Fenetre_Liste_boutons_scroller=Temp3; } while (Fenetre_Liste_boutons_special) { Temp4=Fenetre_Liste_boutons_special->Next; free(Fenetre_Liste_boutons_special); Fenetre_Liste_boutons_special=Temp4; } if (Fenetre != 1) { // Restore de ce que la fenêtre cachait Restaure_fond(Fond_fenetre[Fenetre-1], Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur, Fenetre_Hauteur); Fond_fenetre[Fenetre-1]=NULL; UpdateRect(Fenetre_Pos_X,Fenetre_Pos_Y,Fenetre_Largeur*Menu_Facteur_X,Fenetre_Hauteur*Menu_Facteur_Y); Fenetre--; } else { free(Fond_fenetre[Fenetre-1]); Fond_fenetre[Fenetre-1]=NULL; Fenetre--; Cacher_pinceau=Cacher_pinceau_avant_fenetre; Calculer_coordonnees_pinceau(); Menu_Ordonnee=Menu_Ordonnee_avant_fenetre; Menu_visible=Menu_visible_avant_fenetre; Forme_curseur=Forme_curseur_avant_fenetre; Afficher_ecran(); Afficher_menu(); } Touche=0; Mouse_K=0; Old_MX = -1; Old_MY = -1; } //---------------- Dessiner un bouton normal dans une fenêtre ---------------- void Fenetre_Dessiner_bouton_normal(word Pos_X,word Pos_Y,word Largeur,word Hauteur, char * Titre,byte Lettre_soulignee,byte Clickable) { byte Couleur_titre; word Pos_texte_X,Pos_texte_Y; if (Clickable) { Fenetre_Afficher_cadre_bombe(Pos_X,Pos_Y,Largeur,Hauteur); Fenetre_Afficher_cadre_general(Pos_X-1,Pos_Y-1,Largeur+2,Hauteur+2,CM_Noir,CM_Noir,CM_Fonce,CM_Fonce,CM_Fonce); Couleur_titre=CM_Noir; } else { Fenetre_Afficher_cadre_bombe(Pos_X,Pos_Y,Largeur,Hauteur); Fenetre_Afficher_cadre_mono(Pos_X-1,Pos_Y-1,Largeur+2,Hauteur+2,CM_Clair); Couleur_titre=CM_Fonce; } Pos_texte_X=Pos_X+( (Largeur-(strlen(Titre)<<3)+1) >>1 ); Pos_texte_Y=Pos_Y+((Hauteur-7)>>1); Print_dans_fenetre(Pos_texte_X,Pos_texte_Y,Titre,Couleur_titre,CM_Clair); if (Lettre_soulignee) Block(Fenetre_Pos_X+((Pos_texte_X+((Lettre_soulignee-1)<<3))*Menu_Facteur_X), Fenetre_Pos_Y+((Pos_texte_Y+8)*Menu_Facteur_Y), Menu_Facteur_X<<3,Menu_Facteur_Y,CM_Fonce); } // -- Bouton normal enfoncé dans la fenêtre -- void Fenetre_Enfoncer_bouton_normal(word Pos_X,word Pos_Y,word Largeur,word Hauteur) { Fenetre_Afficher_cadre_general(Pos_X,Pos_Y,Largeur,Hauteur,CM_Fonce,CM_Noir,CM_Fonce,CM_Fonce,CM_Noir); UpdateRect(Fenetre_Pos_X+Pos_X*Menu_Facteur_X, Fenetre_Pos_Y+Pos_Y*Menu_Facteur_Y, Largeur*Menu_Facteur_X, Hauteur*Menu_Facteur_Y); } // -- Bouton normal désenfoncé dans la fenêtre -- void Fenetre_Desenfoncer_bouton_normal(word Pos_X,word Pos_Y,word Largeur,word Hauteur) { Fenetre_Afficher_cadre_bombe(Pos_X,Pos_Y,Largeur,Hauteur); UpdateRect(Fenetre_Pos_X+Pos_X*Menu_Facteur_X, Fenetre_Pos_Y+Pos_Y*Menu_Facteur_Y, Largeur*Menu_Facteur_X, Hauteur*Menu_Facteur_Y); } //--------------- Dessiner un bouton palette dans une fenêtre ---------------- void Fenetre_Dessiner_bouton_palette(word Pos_X,word Pos_Y) { word Couleur; for (Couleur=0; Couleur<=255; Couleur++) Block( Fenetre_Pos_X+((((Couleur >> 4)*10)+Pos_X+6)*Menu_Facteur_X),Fenetre_Pos_Y+((((Couleur & 15)*5)+Pos_Y+3)*Menu_Facteur_Y),Menu_Facteur_X*5,Menu_Facteur_Y*5,Couleur); Fenetre_Afficher_cadre(Pos_X,Pos_Y,164,86); } // -------------------- Effacer les TAGs sur les palette --------------------- // Cette fonct° ne sert plus que lorsqu'on efface les tags dans le menu Spray. void Fenetre_Effacer_tags(void) { word Origine_X; word Origine_Y; word Pos_X; word Pos_fenetre_X; //word Pos_fenetre_Y; Origine_X=Fenetre_Pos_X+(Fenetre_Liste_boutons_palette->Pos_X+3)*Menu_Facteur_X; Origine_Y=Fenetre_Pos_Y+(Fenetre_Liste_boutons_palette->Pos_Y+3)*Menu_Facteur_Y; for (Pos_X=0,Pos_fenetre_X=Origine_X;Pos_X<16;Pos_X++,Pos_fenetre_X+=(Menu_Facteur_X*10)) Block(Pos_fenetre_X,Origine_Y,Menu_Facteur_X*3,Menu_Facteur_Y*80,CM_Clair); UpdateRect(Origine_X,Origine_Y,ToWinL(160),ToWinH(80)); } // ---- Tracer les TAGs sur les palettes du menu Palette ou du menu Shade ---- void Tagger_intervalle_palette(byte Debut,byte Fin) { word Origine_X; word Origine_Y; //word Pos_X; word Pos_Y; //word Pos_fenetre_X; word Pos_fenetre_Y; word Indice; // On efface les anciens TAGs for (Indice=0;Indice<=Debut;Indice++) Block(Fenetre_Pos_X+(Fenetre_Liste_boutons_palette->Pos_X+3+((Indice>>4)*10))*Menu_Facteur_X, Fenetre_Pos_Y+(Fenetre_Liste_boutons_palette->Pos_Y+3+((Indice&15)* 5))*Menu_Facteur_Y, Menu_Facteur_X*3,Menu_Facteur_Y*5,CM_Clair); for (Indice=Fin;Indice<256;Indice++) Block(Fenetre_Pos_X+(Fenetre_Liste_boutons_palette->Pos_X+3+((Indice>>4)*10))*Menu_Facteur_X, Fenetre_Pos_Y+(Fenetre_Liste_boutons_palette->Pos_Y+3+((Indice&15)* 5))*Menu_Facteur_Y, Menu_Facteur_X*3,Menu_Facteur_Y*5,CM_Clair); // On affiche le 1er TAG Origine_X=(Fenetre_Liste_boutons_palette->Pos_X+3)+(Debut>>4)*10; Origine_Y=(Fenetre_Liste_boutons_palette->Pos_Y+3)+(Debut&15)* 5; for (Pos_Y=0,Pos_fenetre_Y=Origine_Y ;Pos_Y<5;Pos_Y++,Pos_fenetre_Y++) Pixel_dans_fenetre(Origine_X ,Pos_fenetre_Y,CM_Noir); for (Pos_Y=0,Pos_fenetre_Y=Origine_Y+1;Pos_Y<3;Pos_Y++,Pos_fenetre_Y++) Pixel_dans_fenetre(Origine_X+1,Pos_fenetre_Y,CM_Noir); Pixel_dans_fenetre(Origine_X+2,Origine_Y+2,CM_Noir); if (Debut!=Fin) { // On complète le 1er TAG Pixel_dans_fenetre(Origine_X+1,Origine_Y+4,CM_Noir); // On affiche le 2ème TAG Origine_X=(Fenetre_Liste_boutons_palette->Pos_X+3)+(Fin>>4)*10; Origine_Y=(Fenetre_Liste_boutons_palette->Pos_Y+3)+(Fin&15)* 5; for (Pos_Y=0,Pos_fenetre_Y=Origine_Y; Pos_Y<5; Pos_Y++,Pos_fenetre_Y++) Pixel_dans_fenetre(Origine_X ,Pos_fenetre_Y,CM_Noir); for (Pos_Y=0,Pos_fenetre_Y=Origine_Y; Pos_Y<4; Pos_Y++,Pos_fenetre_Y++) Pixel_dans_fenetre(Origine_X+1,Pos_fenetre_Y,CM_Noir); Pixel_dans_fenetre(Origine_X+2,Origine_Y+2,CM_Noir); // On TAG toutes les couleurs intermédiaires for (Indice=Debut+1;IndicePos_X+3+((Indice>>4)*10))*Menu_Facteur_X, Fenetre_Pos_Y+(Fenetre_Liste_boutons_palette->Pos_Y+3+((Indice&15)* 5))*Menu_Facteur_Y, Menu_Facteur_X*2,Menu_Facteur_Y*5,CM_Noir); // On efface l'éventuelle pointe d'une ancienne extrémité de l'intervalle Pixel_dans_fenetre(Fenetre_Liste_boutons_palette->Pos_X+5+((Indice>>4)*10), Fenetre_Liste_boutons_palette->Pos_Y+5+((Indice&15)* 5), CM_Clair); } } UpdateRect(ToWinX(Fenetre_Liste_boutons_palette->Pos_X+3),ToWinY(Fenetre_Liste_boutons_palette->Pos_Y+3),ToWinL(12*16),ToWinH(5*16)); } //------------------ Dessiner un scroller dans une fenêtre ------------------- void Calculer_hauteur_curseur_jauge(struct Fenetre_Bouton_scroller * Enreg) { if (Enreg->Nb_elements>Enreg->Nb_visibles) { Enreg->Hauteur_curseur=(Enreg->Nb_visibles*(Enreg->Hauteur-24))/Enreg->Nb_elements; if (!(Enreg->Hauteur_curseur)) Enreg->Hauteur_curseur=1; } else { Enreg->Hauteur_curseur=Enreg->Hauteur-24; } } void Fenetre_Dessiner_jauge(struct Fenetre_Bouton_scroller * Enreg) { word Position_curseur_jauge; Position_curseur_jauge=Enreg->Pos_Y+12; Block(Fenetre_Pos_X+(Enreg->Pos_X*Menu_Facteur_X), Fenetre_Pos_Y+(Position_curseur_jauge*Menu_Facteur_Y), 11*Menu_Facteur_X,(Enreg->Hauteur-24)*Menu_Facteur_Y,CM_Noir/*CM_Fonce*/); if (Enreg->Nb_elements>Enreg->Nb_visibles) Position_curseur_jauge+=Round_div(Enreg->Position*(Enreg->Hauteur-24-Enreg->Hauteur_curseur),Enreg->Nb_elements-Enreg->Nb_visibles); Block(Fenetre_Pos_X+(Enreg->Pos_X*Menu_Facteur_X), Fenetre_Pos_Y+(Position_curseur_jauge*Menu_Facteur_Y), 11*Menu_Facteur_X,Enreg->Hauteur_curseur*Menu_Facteur_Y,CM_Clair/*CM_Blanc*/); UpdateRect(Fenetre_Pos_X+(Enreg->Pos_X*Menu_Facteur_X), Fenetre_Pos_Y+Enreg->Pos_Y*Menu_Facteur_Y, 11*Menu_Facteur_X,(Enreg->Hauteur)*Menu_Facteur_Y); } void Fenetre_Dessiner_bouton_scroller(struct Fenetre_Bouton_scroller * Enreg) { Fenetre_Afficher_cadre_general(Enreg->Pos_X-1,Enreg->Pos_Y-1,13,Enreg->Hauteur+2,CM_Noir,CM_Noir,CM_Fonce,CM_Fonce,CM_Fonce); Fenetre_Afficher_cadre_mono(Enreg->Pos_X-1,Enreg->Pos_Y+11,13,Enreg->Hauteur-22,CM_Noir); Fenetre_Afficher_cadre_bombe(Enreg->Pos_X,Enreg->Pos_Y,11,11); Fenetre_Afficher_cadre_bombe(Enreg->Pos_X,Enreg->Pos_Y+Enreg->Hauteur-11,11,11); Print_dans_fenetre(Enreg->Pos_X+2,Enreg->Pos_Y+2,"\030",CM_Noir,CM_Clair); Print_dans_fenetre(Enreg->Pos_X+2,Enreg->Pos_Y+Enreg->Hauteur-9,"\031",CM_Noir,CM_Clair); Fenetre_Dessiner_jauge(Enreg); } //--------------- Dessiner une zone de saisie dans une fenêtre --------------- void Fenetre_Dessiner_bouton_saisie(word Pos_X,word Pos_Y,word Largeur_en_caracteres) { Fenetre_Afficher_cadre_creux(Pos_X,Pos_Y,(Largeur_en_caracteres<<3)+3,11); } //------------ Modifier le contenu (caption) d'une zone de saisie ------------ void Fenetre_Contenu_bouton_saisie(struct Fenetre_Bouton_special * Enreg, char * Contenu) { Print_dans_fenetre_limite(Enreg->Pos_X+2,Enreg->Pos_Y+2,Contenu,Enreg->Largeur/8,CM_Noir,CM_Clair); } //------------ Effacer le contenu (caption) d'une zone de saisie ------------ void Fenetre_Effacer_bouton_saisie(struct Fenetre_Bouton_special * Enreg) { Block((Enreg->Pos_X+2)*Menu_Facteur_X+Fenetre_Pos_X,(Enreg->Pos_Y+2)*Menu_Facteur_Y+Fenetre_Pos_Y,(Enreg->Largeur/8)*8*Menu_Facteur_X,8*Menu_Facteur_Y,CM_Clair); UpdateRect((Enreg->Pos_X+2)*Menu_Facteur_X+Fenetre_Pos_X,(Enreg->Pos_Y+2)*Menu_Facteur_Y+Fenetre_Pos_Y,Enreg->Largeur/8*8*Menu_Facteur_X,8*Menu_Facteur_Y); } //------ Rajout d'un bouton à la liste de ceux présents dans la fenêtre ------ struct Fenetre_Bouton_normal * Fenetre_Definir_bouton_normal(word Pos_X, word Pos_Y, word Largeur, word Hauteur, char * Titre, byte Lettre_soulignee, byte Clickable, word Raccourci) { struct Fenetre_Bouton_normal * Temp=NULL; Nb_boutons_fenetre++; if (Clickable) { Temp=(struct Fenetre_Bouton_normal *)malloc(sizeof(struct Fenetre_Bouton_normal)); Temp->Numero =Nb_boutons_fenetre; Temp->Pos_X =Pos_X; Temp->Pos_Y =Pos_Y; Temp->Largeur =Largeur; Temp->Hauteur =Hauteur; Temp->Raccourci=Raccourci; Temp->Repetable=0; Temp->Next=Fenetre_Liste_boutons_normal; Fenetre_Liste_boutons_normal=Temp; } Fenetre_Dessiner_bouton_normal(Pos_X,Pos_Y,Largeur,Hauteur,Titre,Lettre_soulignee,Clickable); return Temp; } //------ Rajout d'un bouton à la liste de ceux présents dans la fenêtre ------ struct Fenetre_Bouton_normal * Fenetre_Definir_bouton_repetable(word Pos_X, word Pos_Y, word Largeur, word Hauteur, char * Titre, byte Lettre_soulignee, byte Clickable, word Raccourci) { struct Fenetre_Bouton_normal * Temp=NULL; Nb_boutons_fenetre++; if (Clickable) { Temp=(struct Fenetre_Bouton_normal *)malloc(sizeof(struct Fenetre_Bouton_normal)); Temp->Numero =Nb_boutons_fenetre; Temp->Pos_X =Pos_X; Temp->Pos_Y =Pos_Y; Temp->Largeur =Largeur; Temp->Hauteur =Hauteur; Temp->Raccourci=Raccourci; Temp->Repetable=1; Temp->Next=Fenetre_Liste_boutons_normal; Fenetre_Liste_boutons_normal=Temp; } Fenetre_Dessiner_bouton_normal(Pos_X,Pos_Y,Largeur,Hauteur,Titre,Lettre_soulignee,Clickable); return Temp; } struct Fenetre_Bouton_palette * Fenetre_Definir_bouton_palette(word Pos_X, word Pos_Y) { struct Fenetre_Bouton_palette * Temp; Temp=(struct Fenetre_Bouton_palette *)malloc(sizeof(struct Fenetre_Bouton_palette)); Temp->Numero =++Nb_boutons_fenetre; Temp->Pos_X =Pos_X; Temp->Pos_Y =Pos_Y; Temp->Next=Fenetre_Liste_boutons_palette; Fenetre_Liste_boutons_palette=Temp; Fenetre_Dessiner_bouton_palette(Pos_X,Pos_Y); return Temp; } struct Fenetre_Bouton_scroller * Fenetre_Definir_bouton_scroller(word Pos_X, word Pos_Y, word Hauteur, word Nb_elements, word Nb_elements_visibles, word Position_initiale) { struct Fenetre_Bouton_scroller * Temp; Temp=(struct Fenetre_Bouton_scroller *)malloc(sizeof(struct Fenetre_Bouton_scroller)); Temp->Numero =++Nb_boutons_fenetre; Temp->Pos_X =Pos_X; Temp->Pos_Y =Pos_Y; Temp->Hauteur =Hauteur; Temp->Nb_elements =Nb_elements; Temp->Nb_visibles =Nb_elements_visibles; Temp->Position =Position_initiale; Calculer_hauteur_curseur_jauge(Temp); Temp->Next=Fenetre_Liste_boutons_scroller; Fenetre_Liste_boutons_scroller=Temp; Fenetre_Dessiner_bouton_scroller(Temp); return Temp; } struct Fenetre_Bouton_special * Fenetre_Definir_bouton_special(word Pos_X,word Pos_Y,word Largeur,word Hauteur) { struct Fenetre_Bouton_special * Temp; Temp=(struct Fenetre_Bouton_special *)malloc(sizeof(struct Fenetre_Bouton_special)); Temp->Numero =++Nb_boutons_fenetre; Temp->Pos_X =Pos_X; Temp->Pos_Y =Pos_Y; Temp->Largeur =Largeur; Temp->Hauteur =Hauteur; Temp->Next=Fenetre_Liste_boutons_special; Fenetre_Liste_boutons_special=Temp; return Temp; } struct Fenetre_Bouton_special * Fenetre_Definir_bouton_saisie(word Pos_X,word Pos_Y,word Largeur_en_caracteres) { struct Fenetre_Bouton_special *Temp; Temp=Fenetre_Definir_bouton_special(Pos_X,Pos_Y,(Largeur_en_caracteres<<3)+3,11); Fenetre_Dessiner_bouton_saisie(Pos_X,Pos_Y,Largeur_en_caracteres); return Temp; } //----------------------- Ouverture d'un pop-up ----------------------- void Ouvrir_popup(word Pos_X, word Pos_Y, word Largeur,word Hauteur) // Lors de l'appel à cette procédure, la souris doit être affichée. // En sortie de cette procedure, la souris est effacée. // Note : les pop-ups sont gérés comme s'ils étaient des sous-fenêtres, ils ont donc leur propre boucle d'évènements et tout, on peut ajouter des widgets dedans, ... // Les différences sont surtout graphiques : // -Possibilité de préciser la position XY // -Pas de titre // -Pas de cadre en relief mais seulement un plat, et il est blanc au lieu de noir. { Effacer_curseur(); Fenetre++; Fenetre_Largeur=Largeur; Fenetre_Hauteur=Hauteur; Fenetre_Pos_X=Pos_X*Menu_Facteur_X; Fenetre_Pos_Y=Pos_Y*Menu_Facteur_X; // Sauvegarde de ce que la fenêtre remplace Sauve_fond(&(Fond_fenetre[Fenetre-1]), Fenetre_Pos_X, Fenetre_Pos_Y, Largeur*Menu_Facteur_X, Hauteur*Menu_Facteur_X); // Fenêtre grise Block(Fenetre_Pos_X+(Menu_Facteur_X),Fenetre_Pos_Y+(Menu_Facteur_Y),(Largeur-2)*Menu_Facteur_X,(Hauteur-2)*Menu_Facteur_Y,CM_Clair); // Cadre noir puis en relief Fenetre_Afficher_cadre_mono(0,0,Largeur,Hauteur,CM_Blanc); if (Fenetre == 1) { Menu_visible_avant_fenetre=Menu_visible; Menu_visible=0; Menu_Ordonnee_avant_fenetre=Menu_Ordonnee; Menu_Ordonnee=Hauteur_ecran; Forme_curseur_avant_fenetre=Forme_curseur; Forme_curseur=FORME_CURSEUR_FLECHE; Cacher_pinceau_avant_fenetre=Cacher_pinceau; Cacher_pinceau=1; } // Initialisation des listes de boutons de la fenêtre Fenetre_Liste_boutons_normal =NULL; Fenetre_Liste_boutons_palette =NULL; Fenetre_Liste_boutons_scroller=NULL; Fenetre_Liste_boutons_special =NULL; Nb_boutons_fenetre =0; } //----------------------- Fermer une fenêtre d'options ----------------------- void Fermer_popup(void) // Lors de l'appel à cette procedure, la souris doit être affichée. // En sortie de cette procedure, la souris est effacée. { struct Fenetre_Bouton_normal * Temp1; struct Fenetre_Bouton_palette * Temp2; struct Fenetre_Bouton_scroller * Temp3; struct Fenetre_Bouton_special * Temp4; Effacer_curseur(); while (Fenetre_Liste_boutons_normal) { Temp1=Fenetre_Liste_boutons_normal->Next; free(Fenetre_Liste_boutons_normal); Fenetre_Liste_boutons_normal=Temp1; } while (Fenetre_Liste_boutons_palette) { Temp2=Fenetre_Liste_boutons_palette->Next; free(Fenetre_Liste_boutons_palette); Fenetre_Liste_boutons_palette=Temp2; } while (Fenetre_Liste_boutons_scroller) { Temp3=Fenetre_Liste_boutons_scroller->Next; free(Fenetre_Liste_boutons_scroller); Fenetre_Liste_boutons_scroller=Temp3; } while (Fenetre_Liste_boutons_special) { Temp4=Fenetre_Liste_boutons_special->Next; free(Fenetre_Liste_boutons_special); Fenetre_Liste_boutons_special=Temp4; } if (Fenetre != 1) { // Restore de ce que la fenêtre cachait Restaure_fond(Fond_fenetre[Fenetre-1], Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur, Fenetre_Hauteur); Fond_fenetre[Fenetre-1]=NULL; UpdateRect(Fenetre_Pos_X,Fenetre_Pos_Y,Fenetre_Largeur*Menu_Facteur_X,Fenetre_Hauteur*Menu_Facteur_Y); Fenetre--; } else { free(Fond_fenetre[Fenetre-1]); Fenetre--; Cacher_pinceau=Cacher_pinceau_avant_fenetre; Calculer_coordonnees_pinceau(); Menu_Ordonnee=Menu_Ordonnee_avant_fenetre; Menu_visible=Menu_visible_avant_fenetre; Forme_curseur=Forme_curseur_avant_fenetre; Afficher_ecran(); Afficher_menu(); } Touche=0; Mouse_K=0; Old_MX = -1; Old_MY = -1; } ////////////////////////////////////////////////////////////////////////////// // // // Mini-MOTEUR utilisé dans les fenêtres (menus des boutons...) // // // ////////////////////////////////////////////////////////////////////////////// // -- Indique si on a cliqué dans une zone définie par deux points extremes -- byte Fenetre_click_dans_zone(short Debut_X,short Debut_Y,short Fin_X,short Fin_Y) { short Pos_X,Pos_Y; Pos_X=((short)Mouse_X-Fenetre_Pos_X)/Menu_Facteur_X; Pos_Y=((short)Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y; return ((Pos_X>=Debut_X) && (Pos_Y>=Debut_Y) && (Pos_X<=Fin_X) && (Pos_Y<=Fin_Y)); } // --- Attend que l'on clique dans la palette pour renvoyer la couleur choisie // ou bien renvoie -1 si on a annulé l'action pas click-droit ou Escape ------ short Attendre_click_dans_palette(struct Fenetre_Bouton_palette * Enreg) { short Debut_X=Enreg->Pos_X+5; short Debut_Y=Enreg->Pos_Y+3; short Fin_X =Enreg->Pos_X+160; short Fin_Y =Enreg->Pos_Y+82; byte Couleur_choisie; byte Ancien_Cacher_curseur; byte Ancien_Loupe_Mode; Effacer_curseur(); Ancien_Cacher_curseur=Cacher_curseur; Ancien_Loupe_Mode=Loupe_Mode; Loupe_Mode=0; Cacher_curseur=0; Forme_curseur=FORME_CURSEUR_CIBLE; Afficher_curseur(); for (;;) { while(!Get_input())Wait_VBL(); if (Mouse_K==A_GAUCHE) { if (Fenetre_click_dans_zone(Debut_X,Debut_Y,Fin_X,Fin_Y)) { Effacer_curseur(); Couleur_choisie=(((Mouse_X-Fenetre_Pos_X)/Menu_Facteur_X)-(Enreg->Pos_X+2)) / 10 * 16 + (((Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y)-(Enreg->Pos_Y+3)) / 5; Forme_curseur=FORME_CURSEUR_FLECHE; Cacher_curseur=Ancien_Cacher_curseur; Loupe_Mode=Ancien_Loupe_Mode; Afficher_curseur(); return Couleur_choisie; } if ((Mouse_X=Fenetre_Pos_X+(Fenetre_Largeur*Menu_Facteur_X)) || (Mouse_Y>=Fenetre_Pos_Y+(Fenetre_Hauteur*Menu_Facteur_Y)) ) { Effacer_curseur(); Couleur_choisie=Lit_pixel(Mouse_X,Mouse_Y); Forme_curseur=FORME_CURSEUR_FLECHE; Cacher_curseur=Ancien_Cacher_curseur; Loupe_Mode=Ancien_Loupe_Mode; Afficher_curseur(); return Couleur_choisie; } } if ((Mouse_K==A_DROITE) || (Touche==TOUCHE_ESC)) { Effacer_curseur(); Forme_curseur=FORME_CURSEUR_FLECHE; Cacher_curseur=Ancien_Cacher_curseur; Loupe_Mode=Ancien_Loupe_Mode; Afficher_curseur(); return -1; } } } // -------------- Récupération d'une couleur derrière un menu ---------------- void Recuperer_couleur_derriere_fenetre(byte * Couleur, byte * Click) { short Largeur=Fenetre_Largeur*Menu_Facteur_X; short Hauteur=Fenetre_Hauteur*Menu_Facteur_Y; short Ancien_X=-1; short Ancien_Y=-1; short Indice; short A,B,C,D; // Variables temporaires et multitâches... byte * Buffer; char Chaine[25]; byte Cacher_curseur_avant_recuperation; if ((Buffer=(byte *) malloc(Largeur*Hauteur))) { Effacer_curseur(); Cacher_curseur_avant_recuperation=Cacher_curseur; Cacher_curseur=0; for (Indice=0; IndiceLargeur_ecran-Largeur) { Nouveau_X=Largeur_ecran-Largeur; Dx = Mouse_X - Nouveau_X; } Nouveau_Y=Mouse_Y-Dy; if (Nouveau_Y<0) { Nouveau_Y=0; Dy = Mouse_Y; } if (Nouveau_Y>Hauteur_ecran-Hauteur) { Nouveau_Y=Hauteur_ecran-Hauteur; Dy = Mouse_Y - Nouveau_Y; } if ((Nouveau_X!=Ancien_X) || (Nouveau_Y!=Ancien_Y)) { Effacer_curseur(); Ligne_horizontale_XOR(Ancien_X,Ancien_Y,Largeur); Ligne_verticale_XOR(Ancien_X,Ancien_Y+1,Hauteur-2); Ligne_verticale_XOR(Ancien_X+Largeur-1,Ancien_Y+1,Hauteur-2); Ligne_horizontale_XOR(Ancien_X,Ancien_Y+Hauteur-1,Largeur); Ligne_horizontale_XOR(Nouveau_X,Nouveau_Y,Largeur); Ligne_verticale_XOR(Nouveau_X,Nouveau_Y+1,Hauteur-2); Ligne_verticale_XOR(Nouveau_X+Largeur-1,Nouveau_Y+1,Hauteur-2); Ligne_horizontale_XOR(Nouveau_X,Nouveau_Y+Hauteur-1,Largeur); Afficher_curseur(); UpdateRect(Ancien_X,Ancien_Y,Largeur,Hauteur); UpdateRect(Nouveau_X,Nouveau_Y,Largeur,Hauteur); } } Effacer_curseur(); Ligne_horizontale_XOR(Nouveau_X,Nouveau_Y,Largeur); Ligne_verticale_XOR(Nouveau_X,Nouveau_Y+1,Hauteur-2); Ligne_verticale_XOR(Nouveau_X+Largeur-1,Nouveau_Y+1,Hauteur-2); Ligne_horizontale_XOR(Nouveau_X,Nouveau_Y+Hauteur-1,Largeur); if ((Nouveau_X!=Fenetre_Pos_X) || (Nouveau_Y!=Fenetre_Pos_Y)) { A=Menu_Ordonnee; Menu_Ordonnee=Menu_Ordonnee_avant_fenetre; B=Menu_visible; Menu_visible=Menu_visible_avant_fenetre; //Afficher_ecran(); //Afficher_menu(); Menu_Ordonnee=A; Menu_visible=B; // Sauvegarde du contenu actuel de la fenêtre Sauve_fond(&Buffer, Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur, Fenetre_Hauteur); // Restore de ce que la fenêtre cachait Restaure_fond(Fond_fenetre[Fenetre-1], Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur, Fenetre_Hauteur); Fond_fenetre[Fenetre-1] = NULL; // Sauvegarde de ce que la fenêtre remplace Sauve_fond(&(Fond_fenetre[Fenetre-1]), Nouveau_X, Nouveau_Y, Fenetre_Largeur, Fenetre_Hauteur); // Raffichage de la fenêtre Restaure_fond(Buffer, Nouveau_X, Nouveau_Y, Fenetre_Largeur, Fenetre_Hauteur); Buffer = NULL; // Mise à jour du rectangle englobant UpdateRect( (Nouveau_X>Fenetre_Pos_X)?Fenetre_Pos_X:Nouveau_X, (Nouveau_Y>Fenetre_Pos_Y)?Fenetre_Pos_Y:Nouveau_Y, ((Nouveau_X>Fenetre_Pos_X)?(Nouveau_X-Fenetre_Pos_X):(Fenetre_Pos_X-Nouveau_X)) + Fenetre_Largeur*Menu_Facteur_X, ((Nouveau_Y>Fenetre_Pos_Y)?(Nouveau_Y-Fenetre_Pos_Y):(Fenetre_Pos_Y-Nouveau_Y)) + Fenetre_Hauteur*Menu_Facteur_Y); Fenetre_Pos_X=Nouveau_X; Fenetre_Pos_Y=Nouveau_Y; } else { // Update pour effacer le rectangle XOR UpdateRect(Fenetre_Pos_X, Fenetre_Pos_Y, Fenetre_Largeur*Menu_Facteur_X, Fenetre_Hauteur*Menu_Facteur_Y); } Forme_curseur=FORME_CURSEUR_FLECHE; Afficher_curseur(); } // --- Renvoie le numéro du bouton clicke (-1:hors de la fenêtre, 0:aucun) --- short Fenetre_Numero_bouton_clicke(void) { struct Fenetre_Bouton_normal * Temp1; struct Fenetre_Bouton_palette * Temp2; struct Fenetre_Bouton_scroller * Temp3; struct Fenetre_Bouton_special * Temp4; //long Hauteur_Curseur_jauge; long Hauteur_maxi_jauge; Fenetre_Attribut1=Mouse_K; // Test du click sur les boutons normaux for (Temp1=Fenetre_Liste_boutons_normal; Temp1; Temp1=Temp1->Next) { if (Fenetre_click_dans_zone(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Pos_X+Temp1->Largeur-1,Temp1->Pos_Y+Temp1->Hauteur-1)) { if (Temp1->Repetable) { Effacer_curseur(); Fenetre_Enfoncer_bouton_normal(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Largeur,Temp1->Hauteur); Afficher_curseur(); Tempo_jauge((Mouse_K==1)? Config.Valeur_tempo_jauge_gauche : Config.Valeur_tempo_jauge_droite); Effacer_curseur(); Fenetre_Desenfoncer_bouton_normal(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Largeur,Temp1->Hauteur); Afficher_curseur(); return Temp1->Numero; } while(1) { Effacer_curseur(); Fenetre_Enfoncer_bouton_normal(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Largeur,Temp1->Hauteur); Afficher_curseur(); while (Fenetre_click_dans_zone(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Pos_X+Temp1->Largeur-1,Temp1->Pos_Y+Temp1->Hauteur-1)) { if(!Get_input()) Wait_VBL(); if (!Mouse_K) { Effacer_curseur(); Fenetre_Desenfoncer_bouton_normal(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Largeur,Temp1->Hauteur); Afficher_curseur(); return Temp1->Numero; } } Effacer_curseur(); Fenetre_Desenfoncer_bouton_normal(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Largeur,Temp1->Hauteur); Afficher_curseur(); while (!(Fenetre_click_dans_zone(Temp1->Pos_X,Temp1->Pos_Y,Temp1->Pos_X+Temp1->Largeur-1,Temp1->Pos_Y+Temp1->Hauteur-1))) { if(!Get_input()) Wait_VBL(); if (!Mouse_K) return 0; } } } } // Test du click sur les zones "palette" for (Temp2=Fenetre_Liste_boutons_palette; Temp2; Temp2=Temp2->Next) { if (Fenetre_click_dans_zone(Temp2->Pos_X+5,Temp2->Pos_Y+3,Temp2->Pos_X+160,Temp2->Pos_Y+82)) { // On stocke dans Attribut2 le numero de couleur cliqué Fenetre_Attribut2 = (((Mouse_X-Fenetre_Pos_X)/Menu_Facteur_X)-(Temp2->Pos_X+2)) / 10 * 16 + (((Mouse_Y-Fenetre_Pos_Y)/Menu_Facteur_Y)-(Temp2->Pos_Y+3)) / 5; return Temp2->Numero; } } // Test du click sur les barres de défilement for (Temp3=Fenetre_Liste_boutons_scroller; Temp3; Temp3=Temp3->Next) { if (Fenetre_click_dans_zone(Temp3->Pos_X,Temp3->Pos_Y,Temp3->Pos_X+10,Temp3->Pos_Y+Temp3->Hauteur-1)) { // Bouton flèche Haut if (Fenetre_click_dans_zone(Temp3->Pos_X,Temp3->Pos_Y,Temp3->Pos_X+10,Temp3->Pos_Y+10)) { Effacer_curseur(); Fenetre_Enfoncer_bouton_normal(Temp3->Pos_X,Temp3->Pos_Y,11,11); if (Temp3->Position) { Temp3->Position--; Fenetre_Attribut1=1; Fenetre_Attribut2=Temp3->Position; Fenetre_Dessiner_jauge(Temp3); } else Fenetre_Attribut1=0; Afficher_curseur(); Tempo_jauge((Mouse_K==1)? Config.Valeur_tempo_jauge_gauche : Config.Valeur_tempo_jauge_droite); Effacer_curseur(); Fenetre_Desenfoncer_bouton_normal(Temp3->Pos_X,Temp3->Pos_Y,11,11); Afficher_curseur(); } else // Bouton flèche Bas if (Fenetre_click_dans_zone(Temp3->Pos_X,Temp3->Pos_Y+Temp3->Hauteur-11,Temp3->Pos_X+10,Temp3->Pos_Y+Temp3->Hauteur-1)) { Effacer_curseur(); Fenetre_Enfoncer_bouton_normal(Temp3->Pos_X,Temp3->Pos_Y+Temp3->Hauteur-11,11,11); if (Temp3->Position+Temp3->Nb_visiblesNb_elements) { Temp3->Position++; Fenetre_Attribut1=2; Fenetre_Attribut2=Temp3->Position; Fenetre_Dessiner_jauge(Temp3); } else Fenetre_Attribut1=0; Afficher_curseur(); Tempo_jauge((Mouse_K==1)? Config.Valeur_tempo_jauge_gauche : Config.Valeur_tempo_jauge_droite); Effacer_curseur(); Fenetre_Desenfoncer_bouton_normal(Temp3->Pos_X,Temp3->Pos_Y+Temp3->Hauteur-11,11,11); Afficher_curseur(); } else // Jauge if (Fenetre_click_dans_zone(Temp3->Pos_X,Temp3->Pos_Y+12,Temp3->Pos_X+10,Temp3->Pos_Y+Temp3->Hauteur-13)) { if (Temp3->Nb_elements>Temp3->Nb_visibles) { // S'il y a la place de faire scroller le curseur: Hauteur_maxi_jauge=(Temp3->Hauteur-24); // Fenetre_Attribut2 reçoit la position dans la jauge correspondant au click Fenetre_Attribut2 =(Mouse_Y-Fenetre_Pos_Y) / Menu_Facteur_Y; Fenetre_Attribut2-=(Temp3->Pos_Y+12+((Temp3->Hauteur_curseur-1)>>1)); Fenetre_Attribut2*=(Temp3->Nb_elements-Temp3->Nb_visibles); if (Fenetre_Attribut2<0) Fenetre_Attribut2=0; else { Fenetre_Attribut2 =Round_div(Fenetre_Attribut2,Hauteur_maxi_jauge-Temp3->Hauteur_curseur); if (Fenetre_Attribut2+Temp3->Nb_visibles>Temp3->Nb_elements) Fenetre_Attribut2=Temp3->Nb_elements-Temp3->Nb_visibles; } // Si le curseur de la jauge bouge: if (Temp3->Position!=Fenetre_Attribut2) { Temp3->Position=Fenetre_Attribut2; Fenetre_Attribut1=3; Effacer_curseur(); Fenetre_Dessiner_jauge(Temp3); Afficher_curseur(); } else // Si le curseur de la jauge ne bouge pas: Fenetre_Attribut1=0; } else // S'il n'y a pas la place de bouger le curseur de la jauge: Fenetre_Attribut1=0; } else // Le click se situe dans la zone de la jauge mais n'est sur aucune // des 3 parties importantes de la jauge Fenetre_Attribut1=0; return (Fenetre_Attribut1)? Temp3->Numero : 0; } } // Test du click sur une zone spéciale for (Temp4=Fenetre_Liste_boutons_special; Temp4; Temp4=Temp4->Next) { if (Fenetre_click_dans_zone(Temp4->Pos_X,Temp4->Pos_Y,Temp4->Pos_X+Temp4->Largeur-1,Temp4->Pos_Y+Temp4->Hauteur-1)) return Temp4->Numero; } return 0; } short Fenetre_Numero_bouton_touche(void) { struct Fenetre_Bouton_normal * Temp; if (Touche & MOD_SHIFT) Fenetre_Attribut1=A_DROITE; else Fenetre_Attribut1=A_GAUCHE; // On fait une première recherche Temp=Fenetre_Liste_boutons_normal; while (Temp!=NULL) { if (Temp->Raccourci==Touche) { Effacer_curseur(); Fenetre_Enfoncer_bouton_normal(Temp->Pos_X,Temp->Pos_Y,Temp->Largeur,Temp->Hauteur); Afficher_curseur(); Tempo_jauge(Config.Valeur_tempo_jauge_droite); Effacer_curseur(); Fenetre_Desenfoncer_bouton_normal(Temp->Pos_X,Temp->Pos_Y,Temp->Largeur,Temp->Hauteur); Afficher_curseur(); return Temp->Numero; } Temp=Temp->Next; } // Si la recherche n'a pas été fructueuse ET que l'utilisateur appuyait sur // , on regarde si un bouton ne pourrait pas réagir comme si // n'était pas appuyé. if (Fenetre_Attribut1==A_DROITE) { Temp=Fenetre_Liste_boutons_normal; while (Temp!=NULL) { if (Temp->Raccourci==(Touche&0x0FFF)) return Temp->Numero; Temp=Temp->Next; } } return 0; } short Fenetre_Bouton_clicke(void) { short Bouton; if(!Get_input())Wait_VBL(); // Gestion des clicks if (Mouse_K) { if ((Mouse_X=Fenetre_Pos_X+(Fenetre_Largeur*Menu_Facteur_X)) || (Mouse_Y>=Fenetre_Pos_Y+(Fenetre_Hauteur*Menu_Facteur_Y))) return -1; else { if (Mouse_Y < Fenetre_Pos_Y+(12*Menu_Facteur_Y)) Deplacer_fenetre(Mouse_X-Fenetre_Pos_X,Mouse_Y-Fenetre_Pos_Y); else return Fenetre_Numero_bouton_clicke(); } } // Gestion des touches if (Touche) { Bouton=Fenetre_Numero_bouton_touche(); if (Bouton) { Touche=0; return Bouton; } } return 0; } //int Moteur_Dernier_bouton_clicke; //int Moteur_Type_dernier_bouton_clicke; // Fonction qui sert à remapper les parties sauvegardées derriere les // fenetres ouvertes. C'est utilisé par exemple par la fenetre de palette // Qui remappe des couleurs, afin de propager les changements. void Remappe_fond_fenetres(byte * Table_de_conversion, int Min_Y, int Max_Y) { int Indice_fenetre; byte* EDI; int dx,cx; for (Indice_fenetre=0; Indice_fenetreMax_Y) return; if (dx+Pile_Fenetre_Pos_Y[Indice_fenetre]0;cx--) { *EDI = Table_de_conversion[*EDI]; EDI ++; } } } }