X-Git-Url: https://git.llucax.com/z.facultad/75.06/emufs.git/blobdiff_plain/3e797d5e792af787f3a0d6c2568ca7d728e43860..b895e90078501c60e2ea5e92a15a614b50306606:/gui/form.c diff --git a/gui/form.c b/gui/form.c index 45ce6e7..21e7d48 100644 --- a/gui/form.c +++ b/gui/form.c @@ -1,9 +1,39 @@ #include "form.h" - -static void widget_free(t_Widget *); -static t_Widget *widget_create(t_Campo tipo, const char *nombre, unsigned int max); + +/** Libera la memoria ocupada por un widget + * + * \param w Widget a liberar + */ +static void widget_free(t_Widget *w); +/** Crea un nuevo campo de entrada de texto + * + * \param tipo Debe ser INPUT + * \param nombre Nombre del control (también usada como etiqueta). + * \param max Cantidad máxima de caracteres. + * \param defecto Valor inicial del campo. + */ +static t_Widget *widget_input_create(t_Campo tipo, const char *nombre, unsigned int max, const char *defecto); +/** Crea un nuevo RADIO Group + * + * \param tipo Debe ser RADIO + * \param nombre Nombre del campo + * \param max Cantidad de opciones + * \param valores Texto separado con comas con las opciones + */ +static t_Widget *widget_radio_create(t_Campo tipo, const char *nombre, unsigned int max, const char *valores); +/** Ejecuta una consulta sobre un INPUT + * + * Permite ingresar texto en el INPUT hasta que se presiona ENTER + */ static int form_input(WINDOW *win, int x, int y, t_Widget *w); +/** Ejecuta una consulta sobre un RADIO + * + * Permite seleccionar una de las múltiples opciones del control. + * Para seleccionar se utilizan las feclas <- y -> y ENTER + * para aceptar. + */ +static int form_radio(WINDOW *win, int x, int y, t_Widget *w); t_Form *form_crear(WINDOW *win) { @@ -21,22 +51,34 @@ int form_destruir(t_Form *f) while (tmp) { f->primero = f->primero->sig; - widget_free(tmp); + tmp->destruir(tmp); tmp = f->primero; } free(f); return 1; } -void form_agregar_widget(t_Form *f, t_Campo tipo, const char *nombre, unsigned int max) +void form_agregar_widget(t_Form *f, t_Campo tipo, const char *nombre, unsigned int max, const char *defecto) { - t_Widget *tmp = widget_create(tipo, nombre, max); + t_Widget *tmp = NULL; + + /* Creo el nuevo widget segun el tipo */ + switch (tipo) { + case INPUT: + tmp = widget_input_create(tipo, nombre, max, defecto); + break; + case RADIO: + tmp = widget_radio_create(tipo, nombre, max, defecto); + } - if (f->primero == NULL) { - f->primero = f->ultimo = tmp; - } else { - f->ultimo->sig = tmp; - f->ultimo = tmp; + /* Si se creo wl widget, lo agrego al formulario al final */ + if (tmp) { + if (f->primero == NULL) { + f->primero = f->ultimo = tmp; + } else { + f->ultimo->sig = tmp; + f->ultimo = tmp; + } } } @@ -48,26 +90,35 @@ void form_ejecutar(t_Form *f, int x, int y) /* Pongo las etiquetas de los campos, y me fijo el mayor offset */ while (tmp) { my_y++; - mvwaddstr(f->win, my_y, x, tmp->nombre); - waddch(f->win, ':'); if (strlen(tmp->nombre) > offset) offset = strlen(tmp->nombre); tmp = tmp->sig; } - /* Agrego el : */ - ++offset; - x += offset; + /* Agrego el ": " al offset*/ + offset += 2; + + tmp = f->primero; + my_y = y-1; + while (tmp) { + ++my_y; + mvwaddstr(f->win, my_y, x, tmp->nombre); + waddch(f->win, ':'); + waddch(f->win, ' '); + mvwaddstr(f->win, my_y, x+offset, tmp->valor); + tmp = tmp->sig; + } + wrefresh(f->win); tmp = f->primero; my_y = y-1; while (tmp) { ++my_y; - wmove(f->win, my_y, x); - salida = form_input(f->win, x, my_y, tmp); + wmove(f->win, my_y, x+offset); + salida = tmp->ejecutar(f->win, x+offset, my_y, tmp); + wrefresh(f->win); tmp = tmp->sig; } - mvwaddstr(f->win, 0, 0, "SALI"); } char *form_obtener_valor(t_Form *f, const char *widget) @@ -76,7 +127,12 @@ char *form_obtener_valor(t_Form *f, const char *widget) t_Widget *tmp = f->primero; while (tmp) { if (strcmp(widget, tmp->nombre) == 0) { - return tmp->valor; + switch (tmp->tipo) { + case INPUT: + return tmp->valor; + case RADIO: + return tmp->opciones[tmp->actual]; + } } tmp = tmp->sig; } @@ -84,8 +140,7 @@ char *form_obtener_valor(t_Form *f, const char *widget) return ""; } - -t_Widget *widget_create(t_Campo tipo, const char *nombre, unsigned int max) +t_Widget *widget_input_create(t_Campo tipo, const char *nombre, unsigned int max, const char *defecto) { t_Widget *tmp = (t_Widget *)malloc(sizeof(t_Widget)); @@ -96,16 +151,65 @@ t_Widget *widget_create(t_Campo tipo, const char *nombre, unsigned int max) tmp->max = max; tmp->valor = (char *)malloc(sizeof(char)*(max+1)); tmp->valor[0] = '\0'; + strncpy(tmp->valor, defecto, max); tmp->sig = NULL; + tmp->ejecutar = form_input; + tmp->destruir = widget_free; + return tmp; +} + +t_Widget *widget_radio_create(t_Campo tipo, const char *nombre, unsigned int max, const char *valores) +{ + int ini, fin, actual; + t_Widget *tmp = (t_Widget *)malloc(sizeof(t_Widget)); + + tmp->tipo = tipo; + tmp->nombre = (char *)malloc(sizeof(char)*(strlen(nombre)+1)); + strcpy(tmp->nombre, nombre); + + tmp->max = max; + tmp->opciones = (char **)malloc(sizeof(char*)*(max)); + /* Parseo VALOR separado por comas */ + actual = ini = 0; + fin = ini+1; + tmp->sig = NULL; + while (valores[fin] != '\0') { + if (valores[fin] == ',') { + tmp->opciones[actual] = (char *)malloc(sizeof(char)*(fin-ini+1)); + strncpy(tmp->opciones[actual], valores+ini, fin-ini); + tmp->opciones[actual][fin-ini] = '\0'; + ini = fin+1; + fin = ini+1; + actual++; + } else { + fin++; + } + } + /* Me queda el ultimo elemento */ + tmp->opciones[actual] = (char *)malloc(sizeof(char)*(fin-ini+1)); + strncpy(tmp->opciones[actual], valores+ini, fin-ini); + tmp->opciones[actual][fin-ini] = '\0'; + + tmp->ejecutar = form_radio; + tmp->destruir = widget_free; return tmp; } void widget_free(t_Widget *w) { + int i; free(w->nombre); - free(w->valor); + switch (w->tipo) { + case INPUT: + free(w->valor); + break; + case RADIO: + for(i=0; imax; i++) + free(w->opciones[i]); + free(w->opciones); + } free(w); } @@ -114,12 +218,13 @@ int form_input(WINDOW *win, int x, int y, t_Widget *w) char *tmp = w->valor; int current = 0, c; mvwaddstr(win, y, x, w->valor); - + curs_set(1); while ((*tmp) != '\0') { tmp++; current++; } + wrefresh(win); while ((c=getch()) != 13) { /* Verifico si se apreto basckspace */ if (c == KEY_BACKSPACE) { @@ -130,6 +235,7 @@ int form_input(WINDOW *win, int x, int y, t_Widget *w) waddch(win, ' '); /* Este va para dejar el cursor bien, ya que addch mueve el cursor*/ wmove(win, y, x+current); + wrefresh(win); continue; } /* Si no entra mas, ignoro toda entrada */ @@ -138,6 +244,7 @@ int form_input(WINDOW *win, int x, int y, t_Widget *w) wmove(win, y, x+current); waddch(win, c); w->valor[current++] = c; + wrefresh(win); } /* Cierro el string con el \0 */ w->valor[current+1] = '\0'; @@ -146,3 +253,52 @@ int form_input(WINDOW *win, int x, int y, t_Widget *w) /* De esa forma, ESC pasa al campo anterios. ENTER al siguiente */ return c; } + +int form_radio(WINDOW *win, int x, int y, t_Widget *w) +{ + /* Por ahora solo pongo las cosas y me voy */ + int i, actual, _x, c; + /* Array de posiciones para las Xs */ + int xs[100]; /* TODO : Dinamizar!! */ + + curs_set(0); + wmove(win, y, x); + _x = x; + for(i=0; imax; i++) { + waddch(win, '('); _x++; + waddch(win, ' '); xs[i] = _x; _x++; + waddch(win, ')'); _x++; + waddstr(win, w->opciones[i]); _x += strlen(w->opciones[i]); + waddch(win, ' '); _x++; + } + + actual = 0; + wmove(win, y, xs[actual]); + waddch(win, 'X'); + + wrefresh(win); + while ((c=getch()) != 13) { + if (c == KEY_LEFT) { + wmove(win, y, xs[actual]); + waddch(win, ' '); + actual--; + if (actual < 0) actual = 0; + wmove(win, y, xs[actual]); + waddch(win, 'X'); + } + if (c == KEY_RIGHT) { + wmove(win, y, xs[actual]); + waddch(win, ' '); + actual++; + if (actual >= w->max) actual = w->max-1; + wmove(win, y, xs[actual]); + waddch(win, 'X'); + } + wrefresh(win); + } + + w->actual = actual; + curs_set(1); + return 0; +} +