IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

[Source][C][SDL]Demander une chaîne de caractère à l'utilisateur


Sujet :

Contribuez

  1. #1
    Futur Membre du Club
    Profil pro
    Lycéen
    Inscrit en
    Mai 2009
    Messages
    5
    Détails du profil
    Informations personnelles :
    Âge : 29
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Mai 2009
    Messages : 5
    Points : 6
    Points
    6
    Par défaut [Source][C][SDL]Demander une chaîne de caractère à l'utilisateur
    Bonjour,

    Dans le cadre de mon projet, j'ai dû créer un système permettant de simuler une zone de texte avec la SDL. Comme je l'ai fini, je vous le propose ici, afin que vous puissiez l'utiliser dans vos projets. Je suis ouvert à tout commentaire !

    Prérequis
    Avoir installé la SDL, SDL_Image et SDL_TTF.

    Installation
    Ajoutez ces deux fichiers à votre projet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    /*
    zonetexte.c
    Par Rayman3640
    Rôle : permettre au créateur de simuler des zones de texte avec la SDL
    */
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_ttf.h>
    #include <SDL/SDL_image.h>
    #include "zonetexte.h"
     
    void lireDonneeZoneTexte(SDL_Surface *surface, TTF_Font *police, char *chaineEntree, char *introductionInitiale, char *texteDePreremplissage, long nombreDeCaracteresMaximal)
    {
    	int continuer = 1, majuscule = 0;
    	char introduction[100] = "", chaineFinale[100] = "";
    	SDL_Surface *texte, *barre = NULL;
    	SDL_Color noir = {0,0,0};
    	SDL_Rect positionTexte;
    	long positionCaractere = 0; 
    	SDL_Event event;
    	barre = IMG_Load("Curseur.png");
    	detecterErreurs(surface,barre,police,chaineEntree,texteDePreremplissage,nombreDeCaracteresMaximal);
    	strcpy(introduction,introductionInitiale);
    	strcpy(chaineEntree,texteDePreremplissage);
    	positionCaractere = strlen(chaineEntree);
    	SDL_FillRect(surface,NULL,SDL_MapRGB(surface->format,255,255,255));
    	SDL_EnableKeyRepeat(100,100);
    	SDL_Flip(surface);
    	while(continuer)
    	{
    		SDL_WaitEvent(&event);
    		switch(event.type)
    		{
    			case SDL_QUIT:
    				continuer = 0;
    				break;
    			case SDL_KEYDOWN:
    				lireCaractereZoneTexte(event,&majuscule,chaineEntree,&positionCaractere,&continuer,nombreDeCaracteresMaximal);
    				strcat(introduction,chaineEntree);
    				strcpy(chaineFinale,introduction);
    				strcpy(introduction,introductionInitiale);
    				break;
    		}
    		if(strlen(chaineFinale) <= 0)
    		{
    			strcat(introduction,chaineEntree);
    			strcpy(chaineFinale,introduction);
    			strcpy(introduction,introductionInitiale);
    		}
    		texte = TTF_RenderUTF8_Solid(police,chaineFinale,noir);
    		positionTexte.x = 0;
    		positionTexte.y = 0;
    		SDL_BlitSurface(texte,NULL,surface,&positionTexte);
    		blitterCurseur(chaineFinale,&positionTexte,police,introduction,chaineEntree,surface,barre, positionCaractere);
    		SDL_Flip(surface);
    		SDL_FillRect(surface,NULL,SDL_MapRGB(surface->format,255,255,255));
    	}
    	SDL_FreeSurface(texte);
    	SDL_FreeSurface(barre);
     
    }
     
    void detecterErreurs(SDL_Surface *surface, SDL_Surface *barre, TTF_Font *police, char *chaineEntree, char *texteDePreremplissage, long nombreDeCaracteresMaximal)
    {
    	if(surface == NULL)
    	{
    		fprintf(stderr,"Le pointeur sur surface vaut NULL, donc le texte ne peut pas être affiché à l'écran.\n");
    		exit(EXIT_FAILURE);
    	}
    	if(barre == NULL)
    	{
    		fprintf(stderr,"Erreur lors de l'ouverture de l'image Curseur.png: %s\n",SDL_GetError());
    		exit(EXIT_FAILURE);
    	}
    	if(police == NULL)
    	{
    		fprintf(stderr,"Le pointeur sur police vaut NULL, donc aucune police ne peut être ouverte.\n");
    		exit(EXIT_FAILURE);
    	}
    	if(chaineEntree == NULL)
    	{
    		fprintf(stderr,"La chaîne entrée vaut NULL, donc l'utilisateur ne peut rentrer aucune chaîne.\n");
    		exit(EXIT_FAILURE);
    	}
    	if(nombreDeCaracteresMaximal < 1)
    	{
    		fprintf(stderr,"La taille maximale est nulle, donc l'utilisateur ne peut entrer aucune chaîne.\n");
    		exit(EXIT_FAILURE);
    	}
    	if(texteDePreremplissage != NULL && strlen(texteDePreremplissage) > nombreDeCaracteresMaximal)
    	{
    		fprintf(stderr,"Le nombre de caractères du texte de préremplissage est supérieur au nombre de caractères maximal.\n");
    		exit(EXIT_FAILURE);
    	}
     
    }
     
    void blitterCurseur(char *chaineFinale, SDL_Rect *positionTexte, TTF_Font *police, char *introduction, char *chaineEntree, SDL_Surface *surface, SDL_Surface *barre, long positionCaractere)
    {
    	int longueurSurfaceTexte = 0, longueurSurfaceTexte2 = 0, longueurSurfaceTexte3 = 0, largeurSurfaceTexte = 0;
    	SDL_Rect positionBarre;
    	if(strlen(chaineFinale) > 0)
    	{
    		positionBarre.x = positionTexte->x;
    		if(TTF_SizeUTF8(police,introduction,&longueurSurfaceTexte,&largeurSurfaceTexte) == 0)
    		{
    			positionBarre.x += longueurSurfaceTexte;
    			longueurSurfaceTexte = 0;
    		}
    		if(TTF_SizeUTF8(police,chaineEntree,&longueurSurfaceTexte2,&largeurSurfaceTexte) == 0)
    		{
    			if(TTF_SizeUTF8(police,&chaineEntree[positionCaractere],&longueurSurfaceTexte3,&largeurSurfaceTexte) == 0)
    			{
    				longueurSurfaceTexte = longueurSurfaceTexte2 - longueurSurfaceTexte3;
    			}
    			positionBarre.x += longueurSurfaceTexte;
    		}
    		positionBarre.y = positionTexte->y;
    		SDL_BlitSurface(barre,NULL,surface,&positionBarre);
    	}
     
    }
     
    void lireCaractereZoneTexte(SDL_Event event, int *majuscule, char *chaine, long *positionCaractere, int *continuer, long nombreDeCaracteresMaximal)
    {
    	char caractereEntre = 0;
    	int lettreEntree = 0, diminuerPositionCaractere = 1;
    	long i = 0;
    	if(event.key.keysym.mod & KMOD_SHIFT)
    	{
    		*majuscule = 1;
    	}
    	else
    	{
    		*majuscule = 0;
    	}
    	switch(event.key.keysym.sym)
    	{
    		case SDLK_LEFT:
    			if(*positionCaractere > 0)
    				*positionCaractere -= 1;
    			break;
    		case SDLK_RIGHT:
    			if(*positionCaractere < strlen(chaine))
    				*positionCaractere += 1;
    			break;
    		case SDLK_BACKSPACE:
    			if(*positionCaractere > 0)
    			{
    				for(i = *positionCaractere - 1; i < strlen(chaine); i++)
    				{
    					if(i > -1)
    						chaine[i] = chaine[i+1];
    					else
    						diminuerPositionCaractere = 0;
    				}
    				if(diminuerPositionCaractere)
    					*positionCaractere -= 1;
    				else
    					*positionCaractere = 1;
    			}
    			break;
    		case SDLK_ESCAPE:
    			*continuer = 0;
    			break;
    		case SDLK_RETURN:
    			*continuer = 0;
    			break;
    		default:
    			break;
    	}
    	detecterLettre(event,&lettreEntree,&caractereEntre,majuscule);
    	if(lettreEntree == 1 && strlen(chaine) <= nombreDeCaracteresMaximal)
    	{
    		insererCaractereDansChaine(*positionCaractere,chaine,caractereEntre);
    		*positionCaractere += 1;
    	}
    }
     
    void detecterLettre(SDL_Event event, int *lettreEntree, char *caractereEntre, int *majuscule)
    {
    	long i = 0;
    	for(i = 0; i < 26; i++) //Lettres sans accents minuscules et majuscules
    	{
    		if(event.key.keysym.sym == SDLK_a + i)
    		{
    			entrerLettre(lettreEntree,65 + i,caractereEntre);
    			if(!(*majuscule))
    			{
    				*caractereEntre += 32;
    			}
    			break;
    		}
    	}
    	for(i = 0; i < 27; i++)
    	{
    		if(event.key.keysym.sym == SDLK_AMPERSAND + i)
    		{
    			entrerLettre(lettreEntree,38 + i,caractereEntre);
    		}
    	}
    	for(i = 0; i < 5; i++)
    	{
    		if(event.key.keysym.sym == SDLK_SPACE + i)
    		{
    			entrerLettre(lettreEntree,32 + i,caractereEntre);
    		}
    	}
    	switch(event.key.keysym.sym) //Caractères spéciaux
    	{
    		case SDLK_BACKSLASH:
    			entrerLettre(lettreEntree,92,caractereEntre);
    			break;
    		default:
    			break;
    	}
    	for(i = 0; i < 10; i++)
    	{
    		if(event.key.keysym.sym == SDLK_KP0 + i) //Nombres du pavé numérique
    		{
    			entrerLettre(lettreEntree,48 + i,caractereEntre);
    		}
    	}
     
    }
     
    void entrerLettre(int *lettreEntree, long numeroCaractere, char *caractere)
    {
    	if(!(*lettreEntree))
    	{
    		*lettreEntree = 1;
    		*caractere = numeroCaractere;
    	}
    }
     
    void insererCaractereDansChaine(long positionCaractere, char *chaine, char caractereAInserer)
    {
    	char chaine2[100] = "";
    	strcpy(chaine2,&chaine[positionCaractere]);
    	chaine[positionCaractere] = caractereAInserer;
    	strcpy(&chaine[positionCaractere+1],chaine2);
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    /*
    zonetexte.h
    Par Rayman3640
    Rôle : définir les fonctions utilisées par le fichier de lecture de chaînes au clavier
    */
     
    #ifndef DEF_ZONETEXTE
    	#define DEF_ZONETEXTE
    	#include <SDL/SDL.h>
    	void lireDonneeZoneTexte(SDL_Surface *surface, TTF_Font *police, char *chaineEntree, char *introductionInitiale, char *texteDePreremplissage, long nombreDeCaracteresMaximal);
    	void detecterErreurs(SDL_Surface *surface, SDL_Surface *barre, TTF_Font *police, char *chaineEntree, char *texteDePreremplissage, long nombreDeCaracteresMaximal);
    	void lireCaractereZoneTexte(SDL_Event event, int *majuscule, char *chaine, long *positionCaractere, int *continuer, long nombreDeCaracteresMaximal);
    	void entrerLettre(int *lettreEntree, long numeroCaractere, char *caractere);
    	void insererCaractereDansChaine(long positionCaractere, char *chaine, char caractereAInserer);
    	void blitterCurseur(char *chaineFinale, SDL_Rect *positionTexte, TTF_Font *police, char *introduction, char *chaineEntree, SDL_Surface *surface, SDL_Surface *barre, long positionCaractere);
    	void detecterLettre(SDL_Event event, int *lettreEntree, char *caractereEntre, int *majuscule);
     
    #endif
    Ensuite, dans le même dossier que vos sources, ajoutez cette image, que vous nommerez Curseur.png

    Utilisation
    Pour récupérer une chaîne de caractères, utilisez la fonction lireDonneeZoneTexte, qui fonctionne comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void lireDonneeZoneTexte(SDL_Surface *surface, TTF_Font *police, char *chaineEntree, char *introductionInitiale, char *texteDePreremplissage, long nombreDeCaracteresMaximal);
    • SDL_Surface *surface est le pointeur sur la surface où le texte doit être écrit
    • TTF_Font *police est la police à utiliser
    • char *chaineEntree est la chaîne qui contiendra ce qu'à entré l'utilisateur
    • char *introductionInitiale est le texte affiché avant la zone de texte (par exemple "NOM: " ou encore "Adresse: "),
    • char *texteDePreremplissage est le texte mis par défaut dans la zone de texte
    • long nombreDeCaracteresMaximal est le nombre maximal de caractères que l'utilisateur peut taper (attention, le caractère /0 ne doit pas être inclus dans le nombre)


    N'oubliez pas d'inclure zonetexte.h !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #include "zonetexte.h"
    Exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_ttf.h>
    #include <SDL/SDL_image.h>
    #include "zonetexte.h"
     
    int main(int argc, char *argv[])
    {
    	SDL_Surface *ecran = NULL;
    	int continuer = 1; 
    	char chaine[100] = "";
    	TTF_Font *police = NULL;
    	if(SDL_Init(SDL_INIT_VIDEO) == -1)
    	{
    		fprintf(stderr,"Erreur lors de l'initialisation de la SDL : %s\n",SDL_GetError());		
    		exit(EXIT_FAILURE);
    	}
    	if(TTF_Init() == -1)
    	{
    		fprintf(stderr,"Erreur lors de l'initialisation de SDL_TTF : %s\n",TTF_GetError());		
    		exit(EXIT_FAILURE);
    	}
    	police = TTF_OpenFont("RostockKaligraph.ttf",40);
    	if(police == NULL)
    	{
    		fprintf(stderr,"Erreur police : %s",TTF_GetError());
    		exit(EXIT_FAILURE);
    	}
     	ecran = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE);
    	SDL_WM_SetCaption("Demander une chaîne de caractères à l'utilisateur", NULL);
    	SDL_FillRect(ecran,NULL,SDL_MapRGB(ecran->format,255,255,255));
    	SDL_Flip(ecran);
    	while (continuer)
    	{
    		lireDonneeZoneTexte(ecran,police,chaine,"Mon site préféré : ","Le Site du Zer0",99);
    		continuer = 0;
        	}
    	TTF_CloseFont(police);
    	TTF_Quit();
        	SDL_Quit();
        	return EXIT_SUCCESS;
    }
    Remarques
    • J'espère que l'implémentation se fera sans problème, car je n'ai pas essayé mon système séparément de mon projet.
    • Pour faire une lettre majuscule, je n'ai pas réussi à utiliser le KMOD_CAPS, il faut donc faire Shift + Lettre à mettre en majuscule.
    • Je n'ai pas mis une grande variété de caractères (c'est long et chiant à faire ! :p ) : seulement les lettres (sans accents), les chiffres et quelques autres caractères. Mais si vous le désirez, vous pouvez modifier la fonction detecterLettre pour cela.

  2. #2
    Expert éminent
    Avatar de raptor70
    Inscrit en
    Septembre 2005
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Septembre 2005
    Messages : 3 173
    Points : 6 812
    Points
    6 812
    Par défaut
    Nous allons regarder ce que donne ton code ... pour voir si nous pouvons l'intégrer à notre page Sources SDL et voir si il ne fait pas doublon avec des codes déjà existant

    en tout cas
    Mes Tutos DirectX, OpenGL, 3D : http://raptor.developpez.com/

  3. #3
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 597
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 597
    Points : 7 832
    Points
    7 832
    Par défaut
    Alors ça donne quoi ? Cet exemple n'a pas d'openGL.
    Tout ce que je peux dire, c'est qu'il y a des fautes d'orthographe à corriger si on prend ce texte.
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    J'ose me permettre deux petites remarques ( malgré que je n'ai pas fait de test ):

    Les fonctions qui sont définies dans le .h ne sont pas toutes obligaotires ( dans le sens, il y en a que l'on pourrait enlevé ). Je dis cela, car il ne me semble pas nécessaire de les rendre utilie, et donc, de juste les définir en entête du .c suffirai ( comme ça, l'utilisateur ne voit plus qu'une seule fonction ( celle à utiliser ) )

    Et, quid du const correctness?

    Et, j'en rajoute une , cela ne serai pas limité à la saisie de chaine de caractère de 100 caractères, maximum?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 597
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 597
    Points : 7 832
    Points
    7 832
    Par défaut
    Bonsoir

    Après une relecture et un peu de tests, j'ai modifé le code. J'ai aussi repéré le problème des chaînes de plus de 100 caractères comme là dit LittleWhite. Je n'ai plus de warning lors des compilations.

    Il me restera au moins à vérifier "const correctness" que je n'ai pas remarqué en une lecture simple.

    Comme je n'ai pas tout vu et testé, je ne pense pas que ce soit mon dernier mot

    zonetexte.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    /*
    zonetexte.c
    Par Rayman3640 et Troumad
    Rôle : permettre au créateur de simuler des zones de texte avec la SDL
    */
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL.h>
    #include <SDL_ttf.h>
    #include <SDL_image.h>
    #include "include.h"
     
    void lireDonneeZoneTexte(SDL_Surface *surface, TTF_Font *police, char *chaineEntree, char *introductionInitiale, char *texteDePreremplissage, unsigned long nombreDeCaracteresMaximal)
    {
    	int continuer = 1, majuscule = 0;
    	SDL_Surface *texte, *barre = NULL;
    	SDL_Color noir = {0,0,0,0}; // 4ème champ inutilisé, mais présent tout de même : évite un warning.
    	SDL_Color blanc = {255,255,255,0}; // 4ème champ inutilisé, mais présent tout de même : évite un warning.
    	SDL_Rect positionTexte;
    	unsigned long positionCaractere = 0;
    	SDL_Event event;
        SDL_Rect bas_blanc;
     
     
        SDL_FillRect(surface,NULL,SDL_MapRGB(surface->format,0,0,0));
    	texte = TTF_RenderUTF8_Solid(police,introductionInitiale,blanc);
    	positionTexte.x = 0;
    	positionTexte.y = 0;
    	SDL_BlitSurface(texte,NULL,surface,&positionTexte);
    	positionTexte.y = texte->h +10;
    	bas_blanc.y=positionTexte.y-5;
    	bas_blanc.h=480-bas_blanc.y;
    	bas_blanc.x=0;
    	bas_blanc.w=640;
     
    	SDL_FillRect(surface,&bas_blanc,65535);
     
    	barre = IMG_Load("Curseur.png");
    	detecterErreurs(surface,barre,police,chaineEntree,texteDePreremplissage,nombreDeCaracteresMaximal);
    	//strcpy(introduction,introductionInitiale);
    	strcpy(chaineEntree,texteDePreremplissage);
    	positionCaractere = strlen(chaineEntree);
    	//SDL_FillRect(surface,NULL,SDL_MapRGB(surface->format,255,255,0));
    	SDL_EnableKeyRepeat(100,100);
    	SDL_Flip(surface);
    	while(continuer)
    	{
    		SDL_WaitEvent(&event);
    		switch(event.type)
    		{
    			case SDL_QUIT:
    				continuer = 0;
    				break;
    			case SDL_KEYDOWN:
    				lireCaractereZoneTexte(event,&majuscule,chaineEntree,&positionCaractere,&continuer,nombreDeCaracteresMaximal);
    				break;
    		}
    		texte = TTF_RenderUTF8_Solid(police,chaineEntree,noir);
    		SDL_BlitSurface(texte,NULL,surface,&positionTexte);
    		blitterCurseur(&positionTexte,police,chaineEntree,surface,barre, positionCaractere);
    		SDL_Flip(surface);
        	SDL_FillRect(surface,&bas_blanc,65535);
    		//SDL_FillRect(surface,NULL,SDL_MapRGB(surface->format,255,255,0));
    	}
    	SDL_FreeSurface(texte);
    	SDL_FreeSurface(barre);
     
    }
     
    void detecterErreurs(SDL_Surface *surface, SDL_Surface *barre, TTF_Font *police, char *chaineEntree, char *texteDePreremplissage, unsigned long nombreDeCaracteresMaximal)
    {
    	if(surface == NULL)
    	{
    		fprintf(stderr,"Le pointeur sur surface vaut NULL, donc le texte ne peut pas être affiché à l'écran.\n");
    		exit(EXIT_FAILURE);
    	}
    	if(barre == NULL)
    	{
    		fprintf(stderr,"Erreur lors de l'ouverture de l'image Curseur.png: %s\n",SDL_GetError());
    		exit(EXIT_FAILURE);
    	}
    	if(police == NULL)
    	{
    		fprintf(stderr,"Le pointeur sur police vaut NULL, donc aucune police ne peut être ouverte.\n");
    		exit(EXIT_FAILURE);
    	}
    	if(chaineEntree == NULL)
    	{
    		fprintf(stderr,"La chaîne entrée vaut NULL, donc l'utilisateur ne peut rentrer aucune chaîne.\n");
    		exit(EXIT_FAILURE);
    	}
    	if(nombreDeCaracteresMaximal < 1)
    	{
    		fprintf(stderr,"La taille maximale est nulle, donc l'utilisateur ne peut entrer aucune chaîne.\n");
    		exit(EXIT_FAILURE);
    	}
    	if(texteDePreremplissage != NULL && strlen(texteDePreremplissage) > nombreDeCaracteresMaximal)
    	{
    		fprintf(stderr,"Le nombre de caractères du texte de préremplissage est supérieur au nombre de caractères maximal.\n");
    		exit(EXIT_FAILURE);
    	}
     
    }
     
    void blitterCurseur(SDL_Rect *positionTexte, TTF_Font *police, char *chaineEntree, SDL_Surface *surface, SDL_Surface *barre, unsigned long positionCaractere)
    {
    	int longueurSurfaceTexte = 0, longueurSurfaceTexte2 = 0, longueurSurfaceTexte3 = 0, largeurSurfaceTexte = 0;
    	SDL_Rect positionBarre;
    	if(strlen(chaineEntree) > 0)
    	{
    		positionBarre.x = positionTexte->x;
    		if(TTF_SizeUTF8(police,chaineEntree,&longueurSurfaceTexte2,&largeurSurfaceTexte) == 0)
    		{
    			if(TTF_SizeUTF8(police,&chaineEntree[positionCaractere],&longueurSurfaceTexte3,&largeurSurfaceTexte) == 0)
    			{
    				longueurSurfaceTexte = longueurSurfaceTexte2 - longueurSurfaceTexte3;
    			}
    			positionBarre.x += longueurSurfaceTexte;
    		}
    		positionBarre.y = positionTexte->y;
    		SDL_BlitSurface(barre,NULL,surface,&positionBarre);
    	}
     
    }
     
    void lireCaractereZoneTexte(SDL_Event event, int *majuscule, char *chaine, unsigned long *positionCaractere, int *continuer, unsigned long nombreDeCaracteresMaximal)
    {
    	char caractereEntre = 0;
    	int lettreEntree = 0, diminuerPositionCaractere = 1;
    	unsigned long i = 0;
    	if(event.key.keysym.mod & KMOD_SHIFT)
    	{
    		*majuscule = 1;
    	}
    	else
    	{
    		*majuscule = 0;
    	}
    	if (event.key.keysym.mod & KMOD_CAPS)
    	 *majuscule=!*majuscule.
    	switch(event.key.keysym.sym)
    	{
    		case SDLK_LEFT:
    			if(*positionCaractere > 0)
    				*positionCaractere -= 1;
    			break;
    		case SDLK_RIGHT:
    			if(*positionCaractere < strlen(chaine))
    				*positionCaractere += 1;
    			break;
    		case SDLK_BACKSPACE:
    			//if(*positionCaractere > 0)
    			{
    			    if (*positionCaractere==0)
    			    {
    			        diminuerPositionCaractere = 0;
    			        i=0;
    			    }
    			    else i=*positionCaractere-1;
    				while( i < strlen(chaine))
    				{
    					chaine[i] = chaine[i+1];
                        i++;
    				}
    				if(diminuerPositionCaractere)
    					*positionCaractere-=1;
    				else
    					*positionCaractere=0;
    			}
    			break;
    		case SDLK_ESCAPE:
    			*continuer = 0;
    			break;
    		case SDLK_RETURN:
    			*continuer = 0;
    			break;
    		default:
    			break;
    	}
    	detecterLettre(event,&lettreEntree,&caractereEntre,majuscule);
    	if(lettreEntree == 1 && strlen(chaine) <= nombreDeCaracteresMaximal)
    	{
    		insererCaractereDansChaine(*positionCaractere,chaine,caractereEntre);
    		*positionCaractere += 1;
    	}
    }
     
    void detecterLettre(SDL_Event event, int *lettreEntree, char *caractereEntre, int *majuscule)
    {
    	long i = 0;
    	for(i = 0; i < 26; i++) //Lettres sans accents minuscules et majuscules
    	{
    		if(event.key.keysym.sym == SDLK_a + i)
    		{
    			entrerLettre(lettreEntree,65 + i,caractereEntre);
    			if(!(*majuscule))
    			{
    				*caractereEntre += 32;
    			}
    			break;
    		}
    	}
    	for(i = 0; i < 27; i++)
    	{
    		if(event.key.keysym.sym == SDLK_AMPERSAND + i)
    		{
    			entrerLettre(lettreEntree,38 + i,caractereEntre);
    		}
    	}
    	for(i = 0; i < 5; i++)
    	{
    		if(event.key.keysym.sym == SDLK_SPACE + i)
    		{
    			entrerLettre(lettreEntree,32 + i,caractereEntre);
    		}
    	}
    	switch(event.key.keysym.sym) //Caractères spéciaux
    	{
    		case SDLK_BACKSLASH:
    			entrerLettre(lettreEntree,92,caractereEntre);
    			break;
    		default:
    			break;
    	}
    	for(i = 0; i < 10; i++)
    	{
    		if(event.key.keysym.sym == SDLK_KP0 + i) //Nombres du pavé numérique
    		{
    			entrerLettre(lettreEntree,'0' + i,caractereEntre);
    		}
    	}
     
    }
     
    void entrerLettre(int *lettreEntree, unsigned long numeroCaractere, char *caractere)
    {
    	if(!(*lettreEntree))
    	{
    		*lettreEntree = 1;
    		*caractere = numeroCaractere;
    	}
    }
     
    void insererCaractereDansChaine(unsigned long positionCaractere, char *chaine, char caractereAInserer)
    {
    	char * chaine2;
     
    	chaine2=(char *)malloc(strlen(chaine)+2); // insertion au début d'une chaîne aussi grande que souhaitée
    	strcpy(chaine2,&chaine[positionCaractere]);
    	chaine[positionCaractere] = caractereAInserer;
    	strcpy(&chaine[positionCaractere+1],chaine2);
    }
    et include.h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /* fichier zonetexte.c*/
     
    #ifndef DEF_ZONETEXTE
        #define DEF_ZONETEXTE
        #include <SDL/SDL.h>
        void lireDonneeZoneTexte(SDL_Surface *surface, TTF_Font *police, char *chaineEntree, char *introductionInitiale, char *texteDePreremplissage, unsigned long nombreDeCaracteresMaximal);
        void detecterErreurs(SDL_Surface *surface, SDL_Surface *barre, TTF_Font *police, char *chaineEntree, char *texteDePreremplissage, unsigned long nombreDeCaracteresMaximal);
        void lireCaractereZoneTexte(SDL_Event event, int *majuscule, char *chaine, unsigned long *positionCaractere, int *continuer, unsigned long nombreDeCaracteresMaximal);
        void entrerLettre(int *lettreEntree, unsigned long numeroCaractere, char *caractere);
        void insererCaractereDansChaine(unsigned long positionCaractere, char *chaine, char caractereAInserer);
        void blitterCurseur(char *chaineFinale, SDL_Rect *positionTexte, TTF_Font *police, char *chaineEntree, SDL_Surface *surface, SDL_Surface *barre, unsigned long positionCaractere);
        void detecterLettre(SDL_Event event, int *lettreEntree, char *caractereEntre, int *majuscule);
     
    #endif
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  6. #6
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 597
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 597
    Points : 7 832
    Points
    7 832
    Par défaut
    Je ne peux pas éditer mon message précédent !
    Je vois qu'il y a une erreur dans void lireCaractereZoneTexte, j'ai mis un . à la place d'un ; :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	if (event.key.keysym.mod & KMOD_CAPS)
    	 *majuscule=!*majuscule;
    Et une autre dans le .h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void blitterCurseur(SDL_Rect *positionTexte, TTF_Font *police, char *chaineEntree, SDL_Surface *surface, SDL_Surface *barre, unsigned long positionCaractere);
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

  7. #7
    Rédacteur/Modérateur
    Avatar de troumad
    Homme Profil pro
    Enseignant
    Inscrit en
    Novembre 2003
    Messages
    5 597
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 5 597
    Points : 7 832
    Points
    7 832
    Par défaut
    Je travaille encore dessus !
    Citation Envoyé par Rayman3640 Voir le message
    • J'espère que l'implémentation se fera sans problème, car je n'ai pas essayé mon système séparément de mon projet.
    • Pour faire une lettre majuscule, je n'ai pas réussi à utiliser le KMOD_CAPS, il faut donc faire Shift + Lettre à mettre en majuscule.
    • Je n'ai pas mis une grande variété de caractères (c'est long et chiant à faire ! :p ) : seulement les lettres (sans accents), les chiffres et quelques autres caractères. Mais si vous le désirez, vous pouvez modifier la fonction detecterLettre pour cela.
    Le premier point, c'est sans problème.
    Le second a déjà été corrigé dans ma version précédente
    Le troisième, je complète, mais j'ai encore des points à approfondir ! Avec isprint( event.key.keysym.unicode ) je rajoute plein de possibilité et je simplifie le code. Mais, je ne récupère pas les letres accentuées, ni le çÇ

    nb : j'aimerai pouvoir modifier mon post avec mon programme pour ne pas surcharger le forum avec les nouvelles versions !
    Modérateur Mageia/Mandriva Linux
    Amicalement VOOotre
    Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
    Mes tutoriels : xrandr, algorigramme et C, xml et gtk...

Discussions similaires

  1. Réponses: 8
    Dernier message: 12/02/2013, 01h08
  2. Réponses: 8
    Dernier message: 15/07/2006, 18h59
  3. [Debutant(e)] Analyse d'une chaîne de caractères
    Par maire106 dans le forum Langage
    Réponses: 6
    Dernier message: 22/03/2004, 15h04
  4. Inverser une chaîne de caractères
    Par DBBB dans le forum Assembleur
    Réponses: 2
    Dernier message: 30/03/2003, 11h09
  5. Réponses: 3
    Dernier message: 09/05/2002, 01h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo