📄 apmenu.c
字号:
/***** MENU 控制程序 1997/10**** 外部调用方法: **** int Do_menu(w, menu_bar, menu_proc, nitem, nproc, y0, x0, ** if_show_anywhere)**** return: (1) jym of selected menuitem ** (2) exec the proc define in menu_proc ***/#include "./apmenu.h"static int Max_item;static int Max_proc;/***** MENU 的外部调用接口** 参数: y0,x0: 主菜单栏的位置** if_show_anywhere 退出菜单后是否在屏幕上保留主菜单栏** = 0 不保留** st_color: 菜单颜色 , IF st_color == NULL , put default value***/int Do_menu(w, menu_bar, menu_proc, nitem, nproc, st_color, y0, x0, if_show_anywhere)WINDOW *w; MENU_ITEM menu_bar[]; MENU_PROC menu_proc[]; int nitem; /**********MENU_ITEM结构数组的个数***********/int nproc; /**********MENU_PROC结构数组的个数***********/MENU_COLOR *st_color;int y0; int x0; int if_show_anywhere; { struct PAGE_DEFINE *pp; int i=0,j=0; int level=1; int y[5],x[5]; int width,height; int Maxcount; char code[6]="\0\0\0\0\0\0"; SAVESCR *Scr[5]; char BarText[256],MainMenuBarText[256]; int result[5]={1,1,1,1,1}; int flags=0; char Acckey[256],MainAcckey[256]; if ( st_color == (MENU_COLOR *)NULL ) { LS_FC=LT_WHITE; /***** 子菜单:选中项FONTCOLOR*******/ LS_BC=RED; /***** 子菜单:选中项BACKCOLOR*******/ L_FC=BLUE; /***** 子菜单:非选中项FONTCOLOR*****/ L_BC=WHITE; /***** 子菜单:非选中项BACKCOLOR*****/ MS_FC=BLUE; /***** 主菜单:选中项FONTCOLOR*******/ MS_BC=CYAN; /***** 主菜单:选中项BACKCOLOR*******/ M_FC=LT_WHITE; /***** 主菜单:非选中项FONTCOLOR*****/ M_BC=BLUE; /***** 主菜单:非选中项BACKCOLOR*****/ } else { if ( st_color->ls_fc == -1 ) LS_FC = LT_WHITE; else LS_FC = st_color->ls_fc; if ( st_color->ls_bc == -1 ) LS_BC=RED; else LS_BC = st_color->ls_bc; if ( st_color->l_fc == -1 ) L_FC=BLUE; else L_FC = st_color->l_fc; if ( st_color->l_bc == -1 ) L_BC=WHITE; else L_BC = st_color->l_bc; if ( st_color->ms_fc == -1 ) MS_FC=BLUE; else MS_FC = st_color->ms_fc; if ( st_color->ms_bc == -1 ) MS_BC=CYAN; else MS_BC = st_color->ms_bc; if ( st_color->m_fc == -1 ) M_FC=LT_WHITE; else M_FC = st_color->m_fc; if ( st_color->m_bc == -1 ) M_BC=BLUE; else M_BC = st_color->m_bc; } Max_item= nitem; Max_proc= nproc; Getmenuarg(menu_bar,y0,x0,code,level,MainMenuBarText,MainAcckey,&height,&width,&y[0],&x[0],&Maxcount); /*** 返回不保存屏幕 ***/ if(if_show_anywhere) Scr[0]=(SAVESCR *)Saverect(w,1,80,y0,x0); wsetcolor(w,M_BC,M_BC); while(1){ /******* show mainmenu *************/ result[0] = Menu( w, y0, x0, MainMenuBarText, MainAcckey, result[0], flags); if(result[0] == 0) { Menu( w, y0, x0, MainMenuBarText, Acckey, 0, -1); break; } if(flags==0){ /******* the first show mainmenu *******/ code[level-1] = (char)(result[0]+48); level++; } while(1){ /********** show sub_level menu **********/ if(level==2)flags = 1; else flags = 2; Getmenuarg(menu_bar, y0,x0,code,level,BarText,Acckey,&height,&width,&y[level-1],&x[level-1],&Maxcount); Scr[level-1]= (SAVESCR *)Saverect( w, height+4,width+8,y[level-1],x[level-1]); wsetcolor(w,7,0); result[level-1] = Menu( w, y[level-1], x[level-1], BarText, Acckey , 1, flags); if(result[level-1] ==-1){ if(result[0] != Maxcount+1 ) result[0]++; else result[0] = 1; code[level-1-1]=(char)(result[0]+48); flags=-1; Putrect(w,y[level-1],x[level-1],Scr[level-1]); Free(Scr[level-1]); break; } if(result[level-1] ==-2){ if(result[0] != 1 ) result[0]--; else result[0] = Maxcount+1; code[level-1-1]=(char)(result[0]+48); flags=-1; Putrect(w,y[level-1],x[level-1],Scr[level-1]); Free(Scr[level-1]); break; } if(result[level-1] == 0) { Putrect(w,y[level-1],x[level-1],Scr[level-1]); Free(Scr[level-1]); if(level!=2){ Putrect(w,y[level-2],x[level-2],Scr[level-2]); Free(Scr[level-2]); } level--; code[level-1]='\0'; flags=0; if(level==1){ flags=0; break; } } else { if(if_sub_menu(menu_bar,code,level,result[level-1])){ code[level-1] = (char)(48+result[level-1]); level ++; } else { code[level-1]=(char)(48+result[level-1]); /*** release all memory *****/ for(i=level-1;i>=1;i--){ Putrect(w,y[i],x[i],Scr[i]); Free(Scr[i]); } if(if_show_anywhere){ Putrect(w,y0,x0,Scr[0]); Free(Scr[0]); } else Menu( w, y0, x0, MainMenuBarText, Acckey, 0, -1); /*** 直接运行程序, 返回交易码 ***/ /* i=0; while(1){ if(strcmp(code,menu_proc[i].code)==0){ (*menu_proc[i].itemproc)(); break; } if(i==Max_proc) break; else i++; } */ return atoi(code); } } } } if(if_show_anywhere){ Putrect(w,y0,x0,Scr[0]); Free(Scr[0]); } return FALSE; /**** return FALSE means return without select ***/} /***** 获取菜单数组的各个参数*****/int Getmenuarg( menu_bar, y0, x0, code, level, str, acc, loc_height, loc_width, loc_y,loc_x,num)MENU_ITEM menu_bar[]; int y0;int x0;char *code;int level;char *str;char *acc;int *loc_height; int *loc_width;int *loc_y;int *loc_x;int *num;{ int i=0,j=0,n=0,l=0,k=0; int width,height,y=y0,x=x0; char code_tmp[6]="\0\0\0\0\0\0"; char ch[256]; /******* get item name text ************/ i=0; while(1){ if(i==Max_item){str[0]='\0';break;} if(level==1){ if(*(menu_bar[i].code)==*("0")){ strcpy(str,menu_bar[i].itemname); strcpy(acc,menu_bar[i].acckey); break; } } else if(strcmp(code,menu_bar[i].code)==0){ strcpy(str,menu_bar[i].itemname); strcpy(acc,menu_bar[i].acckey); break; } i++; } /*** get width and num ****/ i=0;j=0;n=0; while(1){ if(str[i]=='~') { n++; if(k<j) k=j; j=-1; } if(str[i]=='\0'){ if(k<j) k=j; break; } i++;j++; } *loc_height=n+1+2;*loc_width=k+2; if(level==1){ *loc_y=y0; *loc_x=x0; *loc_width=strlen(str); *loc_height=1; *num =n; return TRUE; } /*** get location :x and y . ****/ j=0;i=0;k=0; for(i=0;i<level-1;i++){ /* get the location in the main menu */ if(i==0){ k=0; while(1){ if(i==Max_item)break; if(strcmp("0",menu_bar[k].code)==0){ strcpy(ch,menu_bar[k].itemname); break; } else k++; } k=0; while(1){ if(j==((int)code[0]-48)-1)break; if(ch[k]=='~')j++; k++; } y=y0+1;x=x+k; } else{ strncpy(code_tmp,code,i); k=0; while(1){ if(i==Max_item)break; if(strcmp(code_tmp,menu_bar[k].code)==0){ strcpy(ch,menu_bar[k].itemname); break; } else k++; } j=0;k=0;l=0; while(1){ if(ch[k]=='~') { if(l<j) l=j; j=-1; } if(ch[k]=='\0'){ if(l<j) l=j; break; } k++;j++; }/* get the maxlen in menu item text. */ y=y+(int)code[i]-48; x=x+l+3; } } *loc_y=y;*loc_x=x; return TRUE;}/***** 判断是否有下一层菜单*****/int if_sub_menu(menu_bar, code,level,num)MENU_ITEM menu_bar[];char *code;int level;int num;{ int i=0,j; char ch[6]="\0\0\0\0\0\0"; strcpy(ch,code); ch[level-1]=(char)(num+48); while(1){ /*if(i>=sizeof(menu_bar)/CODE_STRUCT_SIZE)break; */ if(i==Max_item)break; if(strcmp(menu_bar[i].code,ch)==0)return TRUE; i++; } return FALSE;}/***** 根据 (menuitem) 显示菜单栏 ( flags = 1 ||flags = 2 )** 和弹出菜单 ( flags = 0 ||flags = -1 )*****/int Menu( w, y, x, menuitem, acc, initnum, flags)WINDOW *w;int y;int x;char *menuitem;char *acc; int initnum;int flags;{ int num=1,i=0,j=0,k=0,m=0,n=0,z,len; int tFlags; /***** tFlags=1:支持颜色 else 终端类型 ****/ char item[256]; char ch; char s[256]; int color,shadow_color; int keynum= 0; int Return=initnum; int Maxlen=0; int bkcolor = M_BC; unsigned char c; tFlags = is_terminal(); if(menuitem[0] == '\0') return 0; while(1){ if(menuitem[i]=='~') { num++; if(Maxlen<j) Maxlen=j; j=-1; } if(menuitem[i]=='\0'){ if(Maxlen<j) Maxlen=j; break; } i++;j++; } /*************** num * Maxlen ******************** ******** flags=1:vertical and have left and right return ********* flags=2:vertical and not left and right ********* flags=0:horizonal and getch() ********* flags=-1:horizonal and not wait ******************************************************/ if(flags==0||flags==-1){ i=0;/* if(bkcolor==YELLOW||bkcolor==LT_WHITE)color=BLUE; else color=YELLOW;*/ if(bkcolor==M_FC)color=(15-M_FC); else color=M_FC; while(1){ if(menuitem[i]=='\0')break; i++; } /* to reduce flush when move menu bar */ if(flags!=-1) { if( tFlags != 1 ) { wstandout( w ); for(m=x;m<x+i+1;m++) mvwaddstr( w, y,m," " ); wstandend( w ); } else { Clear( w, 0, i, y, x, bkcolor ); } } do{ i=0;j=0;k=1; wsetcolor(w,color,bkcolor); while(1){ if(menuitem[i]=='~'||menuitem[i]=='\0'){ /*item[j]=' ';*/ item[j]='\0'; if(Return==k){ wsetcolor(w,MS_FC,MS_BC); mvwaddstr(w,y,x+i-strlen(item),item); wsetcolor(w,color,bkcolor); } else { if( tFlags != 1 ) { wstandout( w ); mvwaddstr(w,y,x+i- strlen(item),item); wstandend( w ); } else mvwaddstr(w,y,x+i- strlen(item),item); } wrefresh(w); if ( menuitem[i] =='~' ){j=-1;k++;} else if( menuitem[i]=='\x0' )break; }/* else if (menuitem[i]=='\0'){ item[j]='\0'; if(Return==k){ if(bkcolor==LT_WHITE) wsetcolor(w,RED,LT_CYAN); else wsetcolor(w,RED,LT_WHITE); mvwaddstr(w,y,x+i-strlen(item),item); wsetcolor(w,color,bkcolor); } else mvwaddstr(w,y,x+i-strlen(item),item); wrefresh(w); break; }*/ else item[j]=menuitem[i]; i++;j++; } if(flags==0) keynum=getch(); else keynum=Key_enter; if(keynum==Key_esc) { if(getch()==91) ch=getch(); if(ch==Key_left){ if(Return==1)Return=num; else Return--; } if(ch==Key_right){ if(Return==num)Return=1; else Return++; } if(keynum==Key_end){ Return=0; break; } } if(keynum==Key_backspace){ Return=0; break; } else { for(i=0;i<num;i++){ ch=acc[i]; if(toupper(keynum)==toupper((int)acc[i])){ Return = i+1; flags = -1; } } } } while( keynum!=Key_enter); } else { /************* if flag is 1 **************************/ if(bkcolor==L_BC) color=15-L_BC; else color=L_BC; if( tFlags != 1 ) { wstandout( w ); for(m=y;m<=(y+num+1);m++)for(n=x;n<(x+Maxlen+2);n++) mvwaddch(w,m,n,' '); wstandend( w ); } else { Clear(w,num+1,Maxlen+2,y,x,color); } if (MENUSHADOW == 1 ) { /********* draw the shadow ********/ if(bkcolor==GRAY)shadow_color=BLACK; else shadow_color=GRAY; wsetcolor(w,7,shadow_color); for(i=0;i<Maxlen+2;i++) s[i]=mvwinch(w,y+num+2,x+2+i); s[i]='\0'; mvwaddstr(w,y+num+2,x+2,s); for(i=1;i<num+3;i++){ s[0]=(char)mvwinch(w,y+i,x+Maxlen+2); s[1]=(char)mvwinch(w,y+i,x+Maxlen+3); s[2]='\0'; mvwaddstr(w,y+i,x+Maxlen+2,s); } } do{ i=0;j=0;k=1; wsetcolor(w,L_FC,color); while(1){ if(menuitem[i]=='~'||menuitem[i]=='\x0'){ item[j]='\0'; if(Return==k){ wsetcolor(w,LS_FC,LS_BC); mvwaddstr(w,y+k,x," "); mvwaddstr(w,y+k,x+1,item); len=strlen(item); for(z=0;z<=(Maxlen-len);z++) mvwaddstr(w,y+k,x+1+z+len," "); wsetcolor(w,L_FC,color); } else { if( tFlags != 1 ) { wstandout( w ); mvwaddstr(w,y+k,x," "); mvwaddstr(w,y+k,x+1,item); len=strlen(item); for(z=0;z<=(Maxlen-len);z++) mvwaddstr(w,y+k,x+1+z+len," "); wstandend( w ); } else { mvwaddstr(w,y+k,x," "); mvwaddstr(w,y+k,x+1,item); len=strlen(item); for(z=0;z<=(Maxlen-len);z++) mvwaddstr(w,y+k,x+1+z+len," "); } } wrefresh(w); if ( menuitem[i] =='~' ){j=-1;k++;} else if( menuitem[i]=='\x0' ) { break; } }/* else if (menuitem[i]=='\0'){ item[j]='\0'; if(Return==k){ wsetcolor(w,RED,LT_WHITE); mvwaddstr(w,y+k,x+1,item); wsetcolor(w,LT_WHITE,color); } else { if( tFlags != 1 ) { wstandout( w ); mvwaddstr(w,y+k,x+1,item); wstandend( w ); } else mvwaddstr(w,y+k,x+1,item); } wrefresh(w); break; }*/ else item[j]=menuitem[i]; i++;j++; } if(flags != -1)keynum=getch(); else keynum=Key_enter; if(keynum==Key_esc){ if(getch()==91) ch=getch(); if(ch==Key_up){ if(Return==1)Return=num; else Return--; } if(ch==Key_down){ if(Return==num)Return=1; else Return++; } if(keynum==Key_end){ Return=0; break; } if(flags==1){ if(ch==Key_left){ Return=-2; break; } if(ch==Key_right){ Return=-1; break; } } } if(keynum==Key_backspace){ Return=0; break;} else { for(i=0;i<num;i++){ ch=acc[i]; if(toupper(keynum)==toupper((int)acc[i])){ Return = i+1; flags = -1; } } } } while( keynum!=Key_enter); } /************* if flag is 1 **************************/ return Return; }/***** 获取菜单数组的菜单内容并显示出来,** 用于未进入菜单时的界面设计*****/int Show_Mainmenu( menu_bar,w, y, x , st_color )MENU_ITEM menu_bar[];WINDOW *w;int y;int x;MENU_COLOR *st_color;{ int color; char str[256]; int i=0,j=0; int tFlags; /***** tFlags=1:支持颜色 else 终端类型 ****/ tFlags = is_terminal(); tFlags = 0; if ( st_color == (MENU_COLOR *)NULL ) { M_FC=LT_WHITE; /***** 主菜单:非选中项FONTCOLOR*****/ M_BC=BLUE; /***** 主菜单:非选中项BACKCOLOR*****/ } else { if ( st_color->m_fc == -1 ) M_FC=LT_WHITE; else M_FC = st_color->m_fc; if ( st_color->m_bc == -1 ) M_BC=BLUE; else M_BC = st_color->m_bc; } while( 1 ) { if( menu_bar[i].level == 1) break; else i++; } strcpy( str, menu_bar[i].itemname ); while(1){ if ( str[j]=='\x0' )break; if ( str[j]=='~' )str[j]=' '; j++; } if( tFlags ==1 ) wstandout( w ); wsetcolor( w, M_FC, M_BC ); mvwaddstr( w, y, x, str ); if( tFlags ==1 ) wstandend( w ); wrefresh ( w ); return TRUE;}/****/Init_menu_color( st_color ) MENU_COLOR *st_color;{ st_color->ls_fc = -1 ; st_color->ls_bc = -1 ; st_color->l_fc = -1 ; st_color->l_bc = -1 ; st_color->ms_fc = -1 ; st_color->ms_bc = -1 ; st_color->m_fc = -1 ; st_color->m_bc = -1 ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -