]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs_gui/form.c
a97e3ba93159506f2e2190f448ba42f0c93e28ef
[z.facultad/75.06/emufs.git] / emufs_gui / form.c
1
2 #include "form.h"
3
4 /** Libera la memoria ocupada por un widget
5  *
6  *  \param w Widget a liberar
7  */
8 static void widget_free(t_Widget *w);
9 /** Crea un nuevo campo de entrada de texto
10  *
11  *  \param tipo Debe ser INPUT
12  *  \param nombre Nombre del control (también usada como etiqueta).
13  *  \param max Cantidad máxima de caracteres.
14  *  \param defecto Valor inicial del campo.
15  */
16 static t_Widget *widget_input_create(t_Campo tipo, const char *nombre, unsigned int max, const char *defecto);
17 /** Crea un nuevo RADIO Group
18  *
19  *  \param tipo Debe ser RADIO
20  *  \param nombre Nombre del campo
21  *  \param max Cantidad de opciones
22  *  \param valores Texto separado con comas con las opciones
23  */
24 static t_Widget *widget_radio_create(t_Campo tipo, const char *nombre, unsigned int max, const char *valores);
25 /** Ejecuta una consulta sobre un INPUT
26  *
27  *  Permite ingresar texto en el INPUT hasta que se presiona ENTER
28  */
29 static int form_input(WINDOW *win, int x, int y, t_Widget *w);
30 /** Ejecuta una consulta sobre un RADIO
31  *
32  *  Permite seleccionar una de las múltiples opciones del control.
33  *  Para seleccionar se utilizan las feclas <- y -> y ENTER
34  *  para aceptar.
35  */
36 static int form_radio(WINDOW *win, int x, int y, t_Widget *w);
37
38 t_Form *form_crear(WINDOW *win)
39 {
40         t_Form *tmp = (t_Form *)malloc(sizeof(t_Form));
41         tmp->primero = tmp->ultimo = NULL;
42         tmp->win = win;
43
44         /* TODO : El error se debe verificar afuera? */
45         return tmp;
46 }
47
48 int form_destruir(t_Form *f)
49 {
50         t_Widget *tmp = f->primero;
51
52         while (tmp) {
53                 f->primero = f->primero->sig;
54                 tmp->destruir(tmp);
55                 tmp = f->primero;
56         }
57         free(f);
58         return 1;
59 }
60
61 void form_agregar_widget(t_Form *f, t_Campo tipo, const char *nombre, unsigned int max, const char *defecto)
62 {
63         t_Widget *tmp = NULL;
64
65         /* Creo el nuevo widget segun el tipo */
66         switch (tipo) {
67                 case INPUT:
68                         tmp = widget_input_create(tipo, nombre, max, defecto);
69                 break;
70                 case RADIO:
71                         tmp = widget_radio_create(tipo, nombre, max, defecto);
72         }
73
74         /* Si se creo wl widget, lo agrego al formulario al final */
75         if (tmp) {
76                 if (f->primero == NULL) {
77                         f->primero = f->ultimo = tmp;
78                 } else {
79                         f->ultimo->sig = tmp;
80                         f->ultimo = tmp;
81                 }
82         }
83 }
84
85 void form_ejecutar(t_Form *f, int x, int y)
86 {
87         int offset = 0, my_y, salida;
88         t_Widget *tmp = f->primero;
89         my_y = y-1;
90         /* Pongo las etiquetas de los campos, y me fijo el mayor offset */
91         while (tmp) {
92                 my_y++;
93                 if (strlen(tmp->nombre) > offset)
94                         offset = strlen(tmp->nombre);
95
96                 tmp = tmp->sig;
97         }
98         /* Agrego el ": " al offset*/
99         offset += 2;
100
101         tmp = f->primero;
102         my_y = y-1;
103         while (tmp) {
104                 ++my_y;
105                 mvwaddstr(f->win, my_y, x, tmp->nombre);
106                 waddch(f->win, ':');
107                 waddch(f->win, ' ');
108                 mvwaddstr(f->win, my_y, x+offset, tmp->valor);
109                 tmp = tmp->sig;
110         }
111         wrefresh(f->win);
112
113         tmp = f->primero;
114         my_y = y-1;
115         while (tmp) {
116                 ++my_y;
117                 wmove(f->win, my_y, x+offset);
118                 salida = tmp->ejecutar(f->win, x+offset, my_y, tmp);
119                 wrefresh(f->win);
120                 tmp = tmp->sig;
121         }
122 }
123
124 int form_obtener_valor_int(t_Form *f, const char *widget)
125 {
126         /* TODO : verificar errores */
127         return atoi(form_obtener_valor_char(f, widget));
128 }
129
130 float form_obtener_valor_float(t_Form *f, const char *widget)
131 {
132         /* TODO : verificar errores */
133         return atof(form_obtener_valor_char(f, widget));
134 }
135
136 char *form_obtener_valor_char(t_Form *f, const char *widget)
137 {
138         /* Busco el widget */
139         t_Widget *tmp = f->primero;
140         while (tmp) {
141                 if (strcmp(widget, tmp->nombre) == 0) {
142                         switch (tmp->tipo) {
143                                 case INPUT:
144                                         return tmp->valor;
145                                 case RADIO:
146                                         return tmp->opciones[tmp->actual];
147                         }
148                 }
149                 tmp = tmp->sig;
150         }
151         /* No hay nada. TODO : Retornar NULL? */
152         return "";
153 }
154
155 t_Widget *widget_input_create(t_Campo tipo, const char *nombre, unsigned int max, const char *defecto)
156 {
157         t_Widget *tmp = (t_Widget *)malloc(sizeof(t_Widget));
158
159         tmp->tipo = tipo;
160         tmp->nombre = (char *)malloc(sizeof(char)*(strlen(nombre)+1));
161         strcpy(tmp->nombre, nombre);
162
163         tmp->max = max;
164         tmp->valor = (char *)malloc(sizeof(char)*(max+1));
165         tmp->valor[0] = '\0';
166         strncpy(tmp->valor, defecto, max);
167
168         tmp->sig = NULL;
169
170         tmp->ejecutar = form_input;
171         tmp->destruir = widget_free;
172         return tmp;
173 }
174
175 t_Widget *widget_radio_create(t_Campo tipo, const char *nombre, unsigned int max, const char *valores)
176 {
177         int ini, fin, actual;
178         t_Widget *tmp = (t_Widget *)malloc(sizeof(t_Widget));
179
180         tmp->tipo = tipo;
181         tmp->nombre = (char *)malloc(sizeof(char)*(strlen(nombre)+1));
182         strcpy(tmp->nombre, nombre);
183
184         tmp->max = max;
185         tmp->opciones = (char **)malloc(sizeof(char*)*(max));
186         /* Parseo VALOR separado por comas */
187         actual = ini = 0;
188         fin = ini+1;
189         tmp->sig = NULL;
190         while (valores[fin] != '\0') {
191                 if (valores[fin] == ',') {
192                         tmp->opciones[actual] = (char *)malloc(sizeof(char)*(fin-ini+1));
193                         strncpy(tmp->opciones[actual], valores+ini, fin-ini);
194                         tmp->opciones[actual][fin-ini] = '\0';
195                         ini = fin+1;
196                         fin = ini+1;
197                         actual++;
198                 } else {
199                         fin++;
200                 }
201         }
202         /* Me queda el ultimo elemento */
203         tmp->opciones[actual] = (char *)malloc(sizeof(char)*(fin-ini+1));
204         strncpy(tmp->opciones[actual], valores+ini, fin-ini);
205         tmp->opciones[actual][fin-ini] = '\0';
206
207         tmp->ejecutar = form_radio;
208         tmp->destruir = widget_free;
209         return tmp;
210 }
211
212 void widget_free(t_Widget *w)
213 {
214         int i;
215         free(w->nombre);
216         switch (w->tipo) {
217                 case INPUT:
218                         free(w->valor);
219                 break;
220                 case RADIO:
221                         for(i=0; i<w->max; i++)
222                                 free(w->opciones[i]);
223                         free(w->opciones);
224         }
225         free(w);
226 }
227
228 int form_input(WINDOW *win, int x, int y, t_Widget *w)
229 {
230         char *tmp = w->valor;
231         int current = 0, c;
232         mvwaddstr(win, y, x, w->valor);
233         curs_set(1);
234         while ((*tmp) != '\0') {
235                 tmp++;
236                 current++;
237         }
238
239         wrefresh(win);
240         while ((c=getch()) != 13) {
241                 /* Verifico si se apreto basckspace */
242                 if (c == KEY_BACKSPACE) {
243                         if (current > 0) {
244                                 w->valor[current--] = '\0';
245                         }
246                         wmove(win, y, x+current);
247                         waddch(win, ' ');
248                         /* Este va para dejar el cursor bien, ya que addch mueve el cursor*/
249                         wmove(win, y, x+current);
250                         wrefresh(win);
251                         continue;
252                 }
253                 /* Si no entra mas, ignoro toda entrada */
254                 if (current >= w->max) continue;
255
256                 wmove(win, y, x+current);
257                 waddch(win, c);
258                 w->valor[current++] = c;
259                 wrefresh(win);
260         }
261         /* Cierro el string con el \0 */
262         w->valor[current+1] = '\0';
263
264         /* Retorno la tecla con la que se salio. */
265         /* De esa forma, ESC pasa al campo anterios. ENTER al siguiente */
266         return c;
267 }
268
269 int form_radio(WINDOW *win, int x, int y, t_Widget *w)
270 {
271         /* Por ahora solo pongo las cosas y me voy */
272         int i, actual, _x, c;
273         /* Array de posiciones para las Xs */
274         int xs[100]; /* TODO : Dinamizar!! */
275
276         curs_set(0);
277         wmove(win, y, x);
278         _x = x;
279         for(i=0; i<w->max; i++) {
280                 waddch(win, '('); _x++;
281                 waddch(win, ' '); xs[i] = _x; _x++;
282                 waddch(win, ')'); _x++;
283                 waddstr(win, w->opciones[i]); _x += strlen(w->opciones[i]);
284                 waddch(win, ' '); _x++;
285         }
286
287         actual = 0;
288         wmove(win, y, xs[actual]);
289         waddch(win, 'X');
290
291         wrefresh(win);
292         while ((c=getch()) != 13) {
293                 if (c == KEY_LEFT) {
294                         wmove(win, y, xs[actual]);
295                         waddch(win, ' ');       
296                         actual--;
297                         if (actual < 0) actual = 0;
298                         wmove(win, y, xs[actual]);
299                         waddch(win, 'X');       
300                 }
301                 if (c == KEY_RIGHT) {
302                         wmove(win, y, xs[actual]);
303                         waddch(win, ' ');       
304                         actual++;
305                         if (actual >= w->max) actual = w->max-1;
306                         wmove(win, y, xs[actual]);
307                         waddch(win, 'X');       
308                 }
309                 wrefresh(win);
310         }
311
312         w->actual = actual;
313         curs_set(1);
314         return 0;
315 }
316