您的位置:首页 > 运维架构 > Linux

Linux基于CURSES库下的二维菜单

2012-11-16 19:58 148 查看
2012-05-09 22:35

 

/*编译命令:gcc  -o  3  3.c  -lcurses
使用方法:键盘方向键:→:显示子菜单;←:关闭子菜单;↑:选择上一个菜单;↓:选择下一个菜单
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <curses.h>

#define menu_item_number 7   /*菜单项目数*/
#define menu_left_margin 4   /*菜单项目左边空白*/
#define menu_child_number 7  /*子菜单项目数*/

char menu[menu_item_number][60]=//菜单文本
{"m1\0", "m2\0", "m3\0","m4\0", "m5\0", "m6\0", "Exit\0"};

char menu_child[menu_child_number][60]=//子菜单文本菜单文本
{"c1\0", "c2\0", "c3\0","c4\0", "c5\0", "c6\0", "c7\0"};

int menu_pos[menu_item_number][2]=
{{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9}};

int menu_pos_two[menu_child_number][2]=
{{4,4},{4,5},{4,6},{4,7},{4,8},{4,9},{4,10}};

void initial() /* 自定开启 curses 函式*/
{
initscr();
cbreak();
nonl();
echo();
intrflush(stdscr,FALSE);
keypad(stdscr,TRUE);
refresh();
}

/*显示主菜单:参数1:当前选中菜单;参数2:是否显示子菜单*/
void menu_display(int selected_index,int ShowChild)
{
int i;
move (1,menu_left_margin);
printw ("实训3:二维菜单");

for (i=0; i<menu_item_number; i++)
{
//如果显示子菜单,并且已经超过当前菜单,则必须多移动子菜单的项目数
if(ShowChild !=0 && i>selected_index)
move (menu_pos[i][1]+ menu_child_number, menu_pos[i][0]+menu_left_margin);
else
move (menu_pos[i][1], menu_pos[i][0]+menu_left_margin);
if (ShowChild ==0  && i== selected_index)
{
attron(A_REVERSE); /* 开启反白模式*/
printw ("%s", menu[i]); /* 输出反白字元  addstr(menu[i]);*/
attroff(A_REVERSE); /* 关闭反白模式*/
}
else
printw ("%s", menu[i]); /* 输出反白字元, addstr(menu[i]); */
}
}

/*显示子菜单函数;参数1:当前选中子菜单,参数2:当前选中父菜单*/
void menu_display_child(int selected_Child_index,int CurrentSelect)
{
int i;
for (i=0; i<menu_child_number; i++)
{    /* 移动游标至现在位置(原定位置+当前父菜单)*/
move (menu_pos_two[i][1]+CurrentSelect, menu_pos_two[i][0]+menu_left_margin);
if ( i== selected_Child_index)
{
attron(A_REVERSE); /* 开启反白模式*/
printw ("%s", menu_child[i]); /* 输出反白字元  addstr(menu[i]);*/
attroff(A_REVERSE); /* 关闭反白模式*/
}
else
printw ("%s", menu_child[i]); /* 输出反白字元, addstr(menu[i]); */
}
}

int main()
{
int ch; /* 宣告 ch 为整数,配合 getch()使用 */
int selected_index = 0;//选中父菜单,默认为第一个
int selected_Child_index = 0;//选中的子菜单,默认为第一个
int show_Child=0;//是否显示子菜单,默认不显示
initial(); /* 调用 initial(), 启动 curses模式, */

menu_display(selected_index,show_Child);

while(1) { /* 以无限循环不断等待输入*/
ch=getch(); /* 等待自键盘输入字元*/
switch(ch) /* 判断输入字元为何*/
{
case KEY_LEFT: /* 判断是否"←"键被按下*/
clear();
show_Child=0;
menu_display(selected_index,show_Child);
break;
case KEY_UP:   /* 判断是否"↑"键被按下*/
if(show_Child==0)//如果没有显示子菜单,则在主菜单中循环
{
--selected_index;
if (selected_index < 0)
selected_index=menu_item_number-1;
menu_display(selected_index,0);
}
else//如果显示子菜单则在子菜单中循环
{
--selected_Child_index;
if (selected_Child_index < 0)
selected_Child_index=menu_child_number-1;
menu_display_child(selected_Child_index,selected_index);

}
break;
case KEY_RIGHT:   /* 判断是否"→"键被按下*/
if(selected_index!=(menu_item_number-1))//如果不是选中最后一个Exit菜单
{
clear();
show_Child=1;
menu_display(selected_index,show_Child);
if (selected_Child_index >= menu_child_number)
selected_Child_index=0;
menu_display_child(0,selected_index);
}
break;
case KEY_DOWN:  /* 判断是否"↓"键被按下*/
if(show_Child==0)//如果没有显示子菜单,则在主菜单中循环
{
++selected_index;
if (selected_index >= menu_item_number)
selected_index=0;
menu_display(selected_index,0);
}
else//如果显示子菜单则在子菜单中循环
{
++selected_Child_index;
if (selected_Child_index >= menu_child_number)
selected_Child_index=0;
menu_display_child(selected_Child_index,selected_index);
}
break;
case '\r': /* 判断是否 ENTER 键被按下*/
clear();
switch(selected_index)//菜单对应处理函数
{
case 0: break;
case 1: break;
case 2: break;
case 3: break;
case 4: break;
case 5: break;
default:
endwin();
exit(0);
}
printw(" Press any to continue...");
getch();
clear();
menu_display(selected_index,0);
break;
case 27: /* 判断是否[ESC]键被按下*/
endwin(); /* 结束此程式*/
exit(1); /* 结束 curses 模式*/
default:
break;
}
}
}


 

运行结果截图



                    

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C LINUX