www.pudn.com > test11.rar > hello_plugs_menu.c, change:2008-07-31,size:4619b
// file: menu.c // // Convenient framework for menu-driven programs #include "excalibur.h" #include "hello_plugs_menu.h" void r_menu_add_title(int menu_number,char *title,r_menu_proc proc); void r_menu_add_link(int menu_number,int link_number); void r_menu_run(void); #define k_menu_count 100 typedef struct { int menu_number; // what menu a member of char *title; // text of menu r_menu_proc proc; // what routine to call int link_number; // (context for proc) ...or what submenu to go to } s_menu_item; typedef struct { s_menu_item item[k_menu_count]; int item_count; r_menu_proc idle_proc; } s_menu_globals; static s_menu_globals g; // {0} of course static void r_shared_menu_add(int menu_number, char *title,r_menu_proc proc,int link_number) { s_menu_item *m; m = &g.item[g.item_count++]; m->menu_number = menu_number; m->title = title; m->proc = proc; m->link_number = link_number; } // ----------------------------- // r_menu_add_item adds an entry to menu_number. // the first (index 0) thing added to any menu is // assumed to be its title. The proc gets called just // after printing the title, for header info, if any. void r_menu_add_item(int menu_number,char *title,r_menu_proc proc,int context) { r_shared_menu_add(menu_number,title,proc,context); } void r_menu_add_link(int menu_number,int link_number) { r_shared_menu_add(menu_number,0,0,link_number); } static void idle_menu(void) { if(g.idle_proc) (g.idle_proc)(0); } int r_get_char(void) { int c; while((c = nr_uart_rxchar(0)) < 0) idle_menu(); return c; } static s_menu_item *find_menu_item(int menu_number,int menu_index) { s_menu_item *m; int i; m = g.item; for(i = 0; i < g.item_count; i++) { if(m->menu_number == menu_number) { if(menu_index-- == 0) return m; } m++; } return 0; } static char *get_menu_title(int menu_number,int menu_index) { s_menu_item *m; m = find_menu_item(menu_number,menu_index); if(m) return m->title; else return 0; } void r_menu_run(void) { int menu_number = 0; // current menu number int menu_index; char *s; int c; s_menu_item *m; do_menu: // Print the current menu choices printf("\n\n\n----------------------------\n"); m = find_menu_item(menu_number,0); s = m->title; s = s ? s : "(missing title)"; printf("%s\n\n",s); if(m->proc) (m->proc)(0); menu_index = 1; while((m = find_menu_item(menu_number,menu_index)) != 0) { int is_link; is_link = 0; s = m->title; if(!s) // submenu gets menu title... { s = get_menu_title(m->link_number,0); is_link = 1; } printf(" %c: %s%s\n",menu_index + 'a' - 1,s,is_link ? "..." : ""); menu_index++; } printf("\n q: Main Menu\n"); printf("\n\n -----> "); // Wait for user menu choice c = r_get_char(); if(c >= 'A' && c <= 'Z') c += 'a' - 'A'; if(c >= 32 & c <= 127) printf("%c\n",c); if(c == 'q') { menu_number = 0; goto do_menu; } c = c - 'a' + 1; m = find_menu_item(menu_number,c); if(m) { if(m->proc) { (m->proc)(m->link_number); } else if(m->link_number) { menu_number = m->link_number; } } goto do_menu; } void r_menu_set_idler(r_menu_proc idle_proc) { g.idle_proc = idle_proc; g.item_count = 0; } //--------------------------------------------------- // User Input Routines void r_strcpy(char *src, char *dst) { do { *dst++ = *src; } while (*src++); } // string length max is presumed to be 64 int r_input_string(char *prompt, char *default_value, char *value_inout) { int char_position; int done; int c; char v[64]; int result; // value blank, and default exists? use it. if(value_inout[0] == 0 && default_value) r_strcpy(default_value, value_inout); // print user prompt printf("%s: [%s] ",prompt,value_inout); // receive chars until return done = 0; char_position = 0; while(!done) { c = r_get_char(); if(c == 27) // ESC to cancel return -1; if(c >= 0x20 && c <= 0x7e) { printf("%c",c); v[char_position++] = c; } else if(c == 8) // backspace { if(char_position) { printf("%c%c%c",8,' ',8); char_position--; } } else if(c == 10) // linefeed == done done = 1; } v[char_position++] = 0; printf("\n"); // string not blank? replace old value with it if(v[0]) r_strcpy(v,value_inout); return 0; }