/* Grafx2 - The Ultimate 256-color bitmap paint program Copyright 2008 Yves Rizoud 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. */ /************************************************************************ * * * READLINE (procédure permettant de saisir une chaîne de caractères) * * * ************************************************************************/ #include #include #include "const.h" #include "struct.h" #include "global.h" #include "graph.h" #include "divers.h" #include "erreurs.h" #include "const.h" #include "linux.h" #define COULEUR_TEXTE CM_Noir #define COULEUR_FOND CM_Clair #define COULEUR_TEXTE_CURSEUR CM_Noir #define COULEUR_FOND_CURSEUR CM_Fonce // Suppresion d'un caractère à une certaine POSITION dans une CHAINE. void Supprimer_caractere(char * Chaine, byte Position) { for (;Chaine[Position]!='\0';Position++) Chaine[Position]=Chaine[Position+1]; } void Inserer_caractere(char * Chaine, char Lettre, byte Position) // Insertion d'une LETTRE à une certaine POSITION // dans une CHAINE d'une certaine TAILLE. { char Char_tempo; for (;Lettre!='\0';Position++) { // On mémorise le caractère qui se trouve en "Position" Char_tempo=Chaine[Position]; // On splotch la lettre à insérer Chaine[Position]=Lettre; // On place le caractère mémorisé dans "Lettre" comme nouvelle lettre à insérer Lettre=Char_tempo; } // On termine la chaine Chaine[Position]='\0'; } int CaractereValide(int Caractere) { // Sous Linux: Seul le / est strictement interdit, mais beaucoup // d'autres poseront des problèmes au shell, alors on évite. // Sous Windows : c'est moins grave car le fopen() échouerait de toutes façons. #ifdef __linux__ char CaracteresInterdits[] = {'/', '|', '?', '*', '<', '>'}; #else char CaracteresInterdits[] = {'/', '|', '?', '*', '<', '>', ':', '\\'}; #endif if (Caractere < ' ' || Caractere > 255) return 0; int Position; for (Position=0; PositionTaille_affichee) Offset=Position-Taille_affichee+1; // Formatage d'une partie de la chaine (si trop longue pour tenir) strncpy(Chaine_affichee, Chaine + Offset, Taille_affichee); Chaine_affichee[Taille_affichee]='\0'; if (Offset>0) Chaine_affichee[0]=CARACTERE_TRIANGLE_GAUCHE; if (Taille_affichee + Offset + 1 < Taille ) Chaine_affichee[Taille_affichee-1]=CARACTERE_TRIANGLE_DROIT; Rafficher_toute_la_chaine(Pos_X,Pos_Y,Chaine_affichee,Position - Offset); #ifndef __macosx__ SDL_UpdateRect(Ecran_SDL,Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3)); #endif while ((Touche_lue!=SDLK_RETURN) && (Touche_lue!=SDLK_ESCAPE)) { Touche_lue=Get_key(); switch (Touche_lue) { case SDLK_DELETE : // Suppr. if (Position0) { // Effacement de la chaîne if (Position==Taille) Block(Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3),COULEUR_FOND); Position--; if (Offset > 0 && (Position == 0 || Position < (Offset + 1))) Offset--; goto affichage; } break; case SDLK_RIGHT : // Droite if ((Position Taille_affichee + Offset - 2) //if (Offset + Taille_affichee < Taille_maxi && (Position == Taille || (Position > Taille_affichee + Offset - 2))) if (Chaine_affichee[Position-Offset]==CARACTERE_TRIANGLE_DROIT || Position-Offset>=Taille_affichee) Offset++; goto affichage; } break; case SDLK_HOME : // Home if (Position) { // Effacement de la chaîne if (Position==Taille) Block(Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3),COULEUR_FOND); Position = 0; Offset = 0; goto affichage; } break; case SDLK_END : // End if ((PositionTaille_affichee) Offset=Position-Taille_affichee+1; goto affichage; } break; case SDLK_BACKSPACE : // Backspace : combinaison de gauche + suppr if (Position) { Position--; if (Offset > 0 && (Position == 0 || Position < (Offset + 1))) Offset--; Supprimer_caractere(Chaine,Position); Taille--; // Effacement de la chaîne Block(Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3),COULEUR_FOND); goto affichage; } break; case SDLK_RETURN : break; case SDLK_ESCAPE : // On restaure la chaine initiale strcpy(Chaine,Chaine_initiale); Taille=strlen(Chaine); break; default : if (Taille=' ' && Touche_lue<= 255) Touche_autorisee=1; break; case 1 : // Nombre if ( (Touche_lue>='0') && (Touche_lue<='9') ) Touche_autorisee=1; break; default : // Nom de fichier // On regarde si la touche est autorisée if ( CaractereValide(Touche_lue)) Touche_autorisee=1; } // Fin du "switch(Type_saisie)" // Si la touche était autorisée... if (Touche_autorisee) { // ... alors on l'insère ... Inserer_caractere(Chaine,Touche_lue,Position/*,Taille*/); // ce qui augmente la taille de la chaine Taille++; // et qui risque de déplacer le curseur vers la droite if (Taille=Taille_affichee) Offset++; } // Enfin, on raffiche la chaine goto affichage; } // Fin du test d'autorisation de touche } // Fin du test de place libre break; affichage: Taille=strlen(Chaine); // Formatage d'une partie de la chaine (si trop longue pour tenir) strncpy(Chaine_affichee, Chaine + Offset, Taille_affichee); Chaine_affichee[Taille_affichee]='\0'; if (Offset>0) Chaine_affichee[0]=CARACTERE_TRIANGLE_GAUCHE; if (Taille_affichee + Offset + 0 < Taille ) Chaine_affichee[Taille_affichee-1]=CARACTERE_TRIANGLE_DROIT; Rafficher_toute_la_chaine(Pos_X,Pos_Y,Chaine_affichee,Position - Offset); #ifndef __macosx__ SDL_UpdateRect(Ecran_SDL,Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3)); #endif } // Fin du "switch(Touche_lue)" } // Fin du "while" // Effacement de la chaîne Block(Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3),COULEUR_FOND); // On raffiche la chaine correctement if (Type_saisie==1) { if (Chaine[0]=='\0') { strcpy(Chaine,"0"); Taille=1; } Print_dans_fenetre(Pos_X+((Taille_maxi-Taille)<<3),Pos_Y,Chaine,COULEUR_TEXTE,COULEUR_FOND); } else { Print_dans_fenetre_limite(Pos_X,Pos_Y,Chaine,Taille_affichee,COULEUR_TEXTE,COULEUR_FOND); } #ifndef __macosx__ SDL_UpdateRect(Ecran_SDL,Fenetre_Pos_X+(Pos_X*Menu_Facteur_X),Fenetre_Pos_Y+(Pos_Y*Menu_Facteur_Y), Taille_affichee*(Menu_Facteur_X<<3),(Menu_Facteur_Y<<3)); #endif return (Touche_lue==SDLK_RETURN); }