From: Ricardo Markiewicz Date: Tue, 30 Mar 2004 04:52:10 +0000 (+0000) Subject: * Agrego manejo de formulario generico utilizando NCurses X-Git-Tag: svn_import_r684~676 X-Git-Url: https://git.llucax.com/z.facultad/75.06/emufs.git/commitdiff_plain/3e797d5e792af787f3a0d6c2568ca7d728e43860?ds=sidebyside * Agrego manejo de formulario generico utilizando NCurses * Viene con EJEMPLO! --- diff --git a/gui/Makefile b/gui/Makefile new file mode 100644 index 0000000..cab2129 --- /dev/null +++ b/gui/Makefile @@ -0,0 +1,7 @@ +CFLAGS=-Wall +LDFLAGS=-lncurses + +all: gui + +gui: form.c gui.c + diff --git a/gui/form.c b/gui/form.c new file mode 100644 index 0000000..45ce6e7 --- /dev/null +++ b/gui/form.c @@ -0,0 +1,148 @@ + +#include "form.h" + +static void widget_free(t_Widget *); +static t_Widget *widget_create(t_Campo tipo, const char *nombre, unsigned int max); +static int form_input(WINDOW *win, int x, int y, t_Widget *w); + +t_Form *form_crear(WINDOW *win) +{ + t_Form *tmp = (t_Form *)malloc(sizeof(t_Form)); + tmp->primero = tmp->ultimo = NULL; + tmp->win = win; + + /* TODO : El error se debe verificar afuera? */ + return tmp; +} + +int form_destruir(t_Form *f) +{ + t_Widget *tmp = f->primero; + + while (tmp) { + f->primero = f->primero->sig; + widget_free(tmp); + tmp = f->primero; + } + free(f); + return 1; +} + +void form_agregar_widget(t_Form *f, t_Campo tipo, const char *nombre, unsigned int max) +{ + t_Widget *tmp = widget_create(tipo, nombre, max); + + if (f->primero == NULL) { + f->primero = f->ultimo = tmp; + } else { + f->ultimo->sig = tmp; + f->ultimo = tmp; + } +} + +void form_ejecutar(t_Form *f, int x, int y) +{ + int offset = 0, my_y, salida; + t_Widget *tmp = f->primero; + my_y = y-1; + /* 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; + + 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); + tmp = tmp->sig; + } + mvwaddstr(f->win, 0, 0, "SALI"); +} + +char *form_obtener_valor(t_Form *f, const char *widget) +{ + /* Busco el widget */ + t_Widget *tmp = f->primero; + while (tmp) { + if (strcmp(widget, tmp->nombre) == 0) { + return tmp->valor; + } + tmp = tmp->sig; + } + /* No hay nada. TODO : Retornar NULL? */ + return ""; +} + + +t_Widget *widget_create(t_Campo tipo, const char *nombre, unsigned int max) +{ + 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->valor = (char *)malloc(sizeof(char)*(max+1)); + tmp->valor[0] = '\0'; + + tmp->sig = NULL; + + return tmp; +} + +void widget_free(t_Widget *w) +{ + free(w->nombre); + free(w->valor); + free(w); +} + +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); + + while ((*tmp) != '\0') { + tmp++; + current++; + } + + while ((c=getch()) != 13) { + /* Verifico si se apreto basckspace */ + if (c == KEY_BACKSPACE) { + if (current > 0) { + w->valor[current--] = '\0'; + } + wmove(win, y, x+current); + waddch(win, ' '); + /* Este va para dejar el cursor bien, ya que addch mueve el cursor*/ + wmove(win, y, x+current); + continue; + } + /* Si no entra mas, ignoro toda entrada */ + if (current >= w->max) continue; + + wmove(win, y, x+current); + waddch(win, c); + w->valor[current++] = c; + } + /* Cierro el string con el \0 */ + w->valor[current+1] = '\0'; + + /* Retorno la tecla con la que se salio. */ + /* De esa forma, ESC pasa al campo anterios. ENTER al siguiente */ + return c; +} diff --git a/gui/form.h b/gui/form.h new file mode 100644 index 0000000..2d2bf71 --- /dev/null +++ b/gui/form.h @@ -0,0 +1,36 @@ +/* Manejo de Formularios con CURSES */ + +#ifndef _FORM_H_ +#define _FORM_H_ + +#include +#include +#include + +typedef enum {INPUT} t_Campo; + +typedef struct _elem_ { + char *nombre; /* nombre del widget */ + t_Campo tipo; /* tipo */ + char *valor; /* valor actual */ + unsigned int max; /*tamaƱo maximo */ + struct _elem_ *sig; /* siguiente en la lista de foco */ +} t_Widget; + +typedef struct _form_ { + t_Widget *primero, *ultimo; /* puntero a widgets */ + WINDOW *win; +} t_Form; + +/* Inicializa un formulario */ +t_Form *form_crear(WINDOW *win); +/* Libera un formulario */ +int form_destruir(t_Form *); +/* Agrega un nuevo campo */ +void form_agregar_widget(t_Form *, t_Campo tipo, const char *nombre, unsigned int max); +/* Ejecuta una entrada del formulario */ +void form_ejecutar(t_Form *, int x, int y); +char *form_obtener_valor(t_Form *, const char *widget); + +#endif + diff --git a/gui/gui.c b/gui/gui.c new file mode 100644 index 0000000..8d1da94 --- /dev/null +++ b/gui/gui.c @@ -0,0 +1,85 @@ + +#include +#include +#include +#include +#include + +#include "form.h" + +static void finish(int sig); + +/** Simula un TextField + * + * \param win Ventana + * \param x Posicion en X + * \param y Posicion en Y + * \param w Cantidad maxima de caracteres. + * \param s Destino donde guardar + */ + +int main(int argc, char *argv[]) +{ + /* initialize your non-curses data structures here */ + WINDOW *mainwin; + t_Form *form; + + signal(SIGINT, finish); /* arrange interrupts to terminate */ + mainwin = initscr(); /* initialize the curses library */ + keypad(stdscr, TRUE); /* enable keyboard mapping */ + nonl(); /* tell curses not to do NL->CR/NL on output */ + cbreak(); /* take input chars one at a time, no wait for \n */ + noecho(); /* don't echo input */ + + if (has_colors()) { + start_color(); + /* Simple color assignment, often all we need. */ + init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK); + init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK); + init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK); + init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK); + init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK); + init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK); + init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK); + init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK); + } + + /* Ventana, caracter para linea vertical, caracter para linea horizontal*/ + box(mainwin, ACS_VLINE, ACS_HLINE); + /* Ventana, Y, X, Texto */ + mvwaddstr(mainwin, 2, 10, "Ejemplo de Formulario"); + + /* Creo el formulario */ + form = form_crear(mainwin); + form_agregar_widget(form, INPUT, "Nombre", 15); + form_agregar_widget(form, INPUT, "Padron", 5); + form_agregar_widget(form, INPUT, "Datos", 30); + + form_ejecutar(form, 10, 10); + + + delwin(mainwin); + endwin(); + + /* Imprimo los datos! */ + printf("Datos Ingresados : \n"); + printf("\tNombre : %s\n", form_obtener_valor(form, "Nombre")); + printf("\tPadron : %s\n", form_obtener_valor(form, "Padron")); + printf("\tDatos : %s\n", form_obtener_valor(form, "Datos")); + + /* Libero el formulario */ + form_destruir(form); + return 0; +} + + + +static void finish(int sig) +{ + endwin(); + + /* do your non-curses wrapup here */ + + exit(0); +} +