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; 
	}