]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - gui/form.c
* BUGFIX : Libero correctamente la memoria de los widgets
[z.facultad/75.06/emufs.git] / gui / form.c
1
2 #include "form.h"
3                 
4 static void widget_free(t_Widget *);
5 static t_Widget *widget_input_create(t_Campo tipo, const char *nombre, unsigned int max);
6 static t_Widget *widget_radio_create(t_Campo tipo, const char *nombre, unsigned int max, const char *valores);
7 static int form_input(WINDOW *win, int x, int y, t_Widget *w);
8 static int form_radio(WINDOW *win, int x, int y, t_Widget *w);
9
10 t_Form *form_crear(WINDOW *win)
11 {
12         t_Form *tmp = (t_Form *)malloc(sizeof(t_Form));
13         tmp->primero = tmp->ultimo = NULL;
14         tmp->win = win;
15
16         /* TODO : El error se debe verificar afuera? */
17         return tmp;
18 }
19
20 int form_destruir(t_Form *f)
21 {
22         t_Widget *tmp = f->primero;
23
24         while (tmp) {
25                 f->primero = f->primero->sig;
26                 widget_free(tmp);
27                 tmp = f->primero;
28         }
29         free(f);
30         return 1;
31 }
32
33 void form_agregar_widget(t_Form *f, t_Campo tipo, const char *nombre, unsigned int max, const char *defecto)
34 {
35         t_Widget *tmp = NULL;
36         
37         switch (tipo) {
38                 case INPUT:
39                         tmp = widget_input_create(tipo, nombre, max);
40                 break;
41                 case RADIO:
42                         tmp = widget_radio_create(tipo, nombre, max, defecto);
43         }
44
45         if (tmp) {
46                 if (f->primero == NULL) {
47                         f->primero = f->ultimo = tmp;
48                 } else {
49                         f->ultimo->sig = tmp;
50                         f->ultimo = tmp;
51                 }
52         }
53 }
54
55 void form_ejecutar(t_Form *f, int x, int y)
56 {
57         int offset = 0, my_y, salida;
58         t_Widget *tmp = f->primero;
59         my_y = y-1;
60         /* Pongo las etiquetas de los campos, y me fijo el mayor offset */
61         while (tmp) {
62                 my_y++;
63                 mvwaddstr(f->win, my_y, x, tmp->nombre);
64                 waddch(f->win, ':');
65                 if (strlen(tmp->nombre) > offset)
66                         offset = strlen(tmp->nombre);
67
68                 tmp = tmp->sig;
69         }
70         /* Agrego el : */
71         ++offset;
72         x += offset;
73
74         tmp = f->primero;
75         my_y = y-1;
76         while (tmp) {
77                 ++my_y;
78                 wmove(f->win, my_y, x);
79                 switch (tmp->tipo) {
80                         case INPUT:
81                                 salida = form_input(f->win, x, my_y, tmp);
82                         break;
83                         case RADIO:
84                                 salida = form_radio(f->win, x, my_y, tmp);
85                 }
86                 tmp = tmp->sig;
87         }
88         mvwaddstr(f->win, 0, 0, "SALI");
89 }
90
91 char *form_obtener_valor(t_Form *f, const char *widget)
92 {
93         /* Busco el widget */
94         t_Widget *tmp = f->primero;
95         while (tmp) {
96                 if (strcmp(widget, tmp->nombre) == 0) {
97                         switch (tmp->tipo) {
98                                 case INPUT:
99                                         return tmp->valor;
100                                 case RADIO:
101                                         return tmp->opciones[tmp->actual];
102                         }
103                 }
104                 tmp = tmp->sig;
105         }
106         /* No hay nada. TODO : Retornar NULL? */
107         return "";
108 }
109
110
111 t_Widget *widget_input_create(t_Campo tipo, const char *nombre, unsigned int max)
112 {
113         t_Widget *tmp = (t_Widget *)malloc(sizeof(t_Widget));
114
115         tmp->tipo = tipo;
116         tmp->nombre = (char *)malloc(sizeof(char)*(strlen(nombre)+1));
117         strcpy(tmp->nombre, nombre);
118
119         tmp->max = max;
120         tmp->valor = (char *)malloc(sizeof(char)*(max+1));
121         tmp->valor[0] = '\0';
122
123         tmp->sig = NULL;
124
125         return tmp;
126 }
127
128 t_Widget *widget_radio_create(t_Campo tipo, const char *nombre, unsigned int max, const char *valores)
129 {
130         int ini, fin, actual;
131         t_Widget *tmp = (t_Widget *)malloc(sizeof(t_Widget));
132
133         tmp->tipo = tipo;
134         tmp->nombre = (char *)malloc(sizeof(char)*(strlen(nombre)+1));
135         strcpy(tmp->nombre, nombre);
136
137         tmp->max = max;
138         tmp->opciones = (char **)malloc(sizeof(char*)*(max));
139         /* Parseo VALOR separado por comas */
140         actual = ini = 0;
141         fin = ini+1;
142         tmp->sig = NULL;
143         while (valores[fin] != '\0') {
144                 if (valores[fin] == ',') {
145                         tmp->opciones[actual] = (char *)malloc(sizeof(char)*(fin-ini+1));
146                         strncpy(tmp->opciones[actual], valores+ini, fin-ini);
147                         tmp->opciones[actual][fin-ini] = '\0';
148                         ini = fin+1;
149                         fin = ini+1;
150                         actual++;
151                 } else {
152                         fin++;
153                 }
154         }
155         /* Me queda el ultimo elemento */
156         tmp->opciones[actual] = (char *)malloc(sizeof(char)*(fin-ini+1));
157         strncpy(tmp->opciones[actual], valores+ini, fin-ini);
158         tmp->opciones[actual][fin-ini] = '\0';
159
160         return tmp;
161 }
162
163 void widget_free(t_Widget *w)
164 {
165         int i;
166         free(w->nombre);
167         switch (w->tipo) {
168                 case INPUT:
169                         free(w->valor);
170                 break;
171                 case RADIO:
172                         for(i=0; i<w->max; i++)
173                                 free(w->opciones[i]);
174                         free(w->opciones);
175         }
176         free(w);
177 }
178
179 int form_input(WINDOW *win, int x, int y, t_Widget *w)
180 {
181         char *tmp = w->valor;
182         int current = 0, c;
183         mvwaddstr(win, y, x, w->valor);
184
185         while ((*tmp) != '\0') {
186                 tmp++;
187                 current++;
188         }
189
190         while ((c=getch()) != 13) {
191                 /* Verifico si se apreto basckspace */
192                 if (c == KEY_BACKSPACE) {
193                         if (current > 0) {
194                                 w->valor[current--] = '\0';
195                         }
196                         wmove(win, y, x+current);
197                         waddch(win, ' ');
198                         /* Este va para dejar el cursor bien, ya que addch mueve el cursor*/
199                         wmove(win, y, x+current);
200                         continue;
201                 }
202                 /* Si no entra mas, ignoro toda entrada */
203                 if (current >= w->max) continue;
204
205                 wmove(win, y, x+current);
206                 waddch(win, c);
207                 w->valor[current++] = c;
208         }
209         /* Cierro el string con el \0 */
210         w->valor[current+1] = '\0';
211
212         /* Retorno la tecla con la que se salio. */
213         /* De esa forma, ESC pasa al campo anterios. ENTER al siguiente */
214         return c;
215 }
216
217 int form_radio(WINDOW *win, int x, int y, t_Widget *w)
218 {
219         /* Por ahora solo pongo las cosas y me voy */
220         int i, actual, _x, c;
221         /* Array de posiciones para las Xs */
222         int xs[100]; /* TODO : Dinamizar!! */
223
224         wmove(win, y, x);
225         _x = x;
226         for(i=0; i<w->max; i++) {
227                 waddch(win, '('); _x++;
228                 waddch(win, ' '); xs[i] = _x; _x++;
229                 waddch(win, ')'); _x++;
230                 waddstr(win, w->opciones[i]); _x += strlen(w->opciones[i]);
231                 waddch(win, ' '); _x++;
232         }
233
234         actual = 0;
235         wmove(win, y, xs[actual]);
236         waddch(win, 'X');
237
238         while ((c=getch()) != 13) {
239                 if (c == KEY_LEFT) {
240                         wmove(win, y, xs[actual]);
241                         waddch(win, ' ');       
242                         actual--;
243                         if (actual < 0) actual = 0;
244                         wmove(win, y, xs[actual]);
245                         waddch(win, 'X');       
246                 }
247                 if (c == KEY_RIGHT) {
248                         wmove(win, y, xs[actual]);
249                         waddch(win, ' ');       
250                         actual++;
251                         if (actual >= w->max) actual = w->max-1;
252                         wmove(win, y, xs[actual]);
253                         waddch(win, 'X');       
254                 }
255         }
256
257         w->actual = actual;
258         return 0;
259 }
260