Linux基于CURSES库下的二维菜单

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


 

运行结果截图

                    



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值