⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menu.c

📁 linux内核
💻 C
📖 第 1 页 / 共 3 页
字号:
	  break;	case PAGEDN:	  for (i=0; i < 5; i++) curr = next_visible(menu,curr+1);          first = calc_first_late(menu,curr);	  break;	case PAGEUP:	  for (i=0; i < 5; i++) curr = prev_visible(menu,curr-1);          first = calc_first_early(menu,curr);	  break;	case UPARROW:	  curr = prev_visible(menu,curr-1);          if (curr < first) first = calc_first_early(menu,curr);	  break;	case DNARROW:	  curr = next_visible(menu,curr+1);          if (! isvisible(menu,first,curr))                first = calc_first_late(menu,curr);	  break;	case LTARROW:	case ESCAPE:	  return NULL;	  break;	case RTARROW:	case ENTERA:	case ENTERB:	  if (ci->action == OPT_INACTIVE) break;	  if (ci->action == OPT_SEP) break;	  return ci;	  break;	default:	  // Check if this is a shortcut key	  if (((asc >= 'A') && (asc <= 'Z')) ||	      ((asc >= 'a') && (asc <= 'z')) ||	      ((asc >= '0') && (asc <= '9')))          {	    tmp = find_shortcut(menu,asc,curr);            if ((tmp > curr) && (! isvisible(menu,first,tmp)))                  first = calc_first_late(menu,tmp);            if (tmp < curr)                first = calc_first_early(menu,tmp);            curr = tmp;          }          else {            if (ms->keys_handler) // Call extra keys handler               ms->keys_handler(ms,menu->items[curr],(scan << 8) | asc);          }	  break;        }      // Update status line      gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);      cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage);      printmenuitem(menu->items[curr]->status,ms->statusattr);    }  return NULL; // Should never come here}/* Handle one menu */pt_menuitem getmenuoption(pt_menu menu, uchar top, uchar left, uchar startopt)     // Return item chosen or NULL if ESC was hit.{  int curr,i,first,tmp;  uchar asc,scan;  uchar numitems;  pt_menuitem ci; // Current item  t_handler_return hr; // Return value of handler      numitems = calc_visible(menu,0);  // Setup status line  gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);  cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage);  // Initialise current menu item      curr = next_visible(menu,startopt);  gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);  cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,1);  gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);  printmenuitem(menu->items[curr]->status,ms->statusattr);  first = calc_first_early(menu,curr);  while (1) // Forever    {      printmenu(menu,curr,top,left,first);      ci = menu->items[curr];      asc = getch(&scan);      switch (scan)        {	case HOMEKEY:	  curr = next_visible(menu,0);          first = calc_first_early(menu,curr);	  break;	case ENDKEY:	  curr = prev_visible(menu,numitems-1);          first = calc_first_late(menu,curr);	  break;	case PAGEDN:	  for (i=0; i < 5; i++) curr = next_visible(menu,curr+1);          first = calc_first_late(menu,curr);	  break;	case PAGEUP:	  for (i=0; i < 5; i++) curr = prev_visible(menu,curr-1);          first = calc_first_early(menu,curr);	  break;	case UPARROW:	  curr = prev_visible(menu,curr-1);          if (curr < first) first = calc_first_early(menu,curr);	  break;	case DNARROW:	  curr = next_visible(menu,curr+1);          if (! isvisible(menu,first,curr))                first = calc_first_late(menu,curr);	  break;	case LTARROW:	case ESCAPE:	  return NULL;	  break;	case RTARROW:	case ENTERA:	case ENTERB:	  if (ci->action == OPT_INACTIVE) break;	  if (ci->action == OPT_CHECKBOX) break;	  if (ci->action == OPT_SEP) break;	  if (ci->action == OPT_EXITMENU) return NULL; // As if we hit Esc          // If we are going into a radio menu, dont call handler, return ci          if (ci->action == OPT_RADIOMENU) return ci;          if (ci->handler != NULL) // Do we have a handler          {             hr = ci->handler(ms,ci);               if (hr.refresh) // Do we need to refresh             {                // Cleanup menu using old number of items                cleanupmenu(menu,top,left,numitems);                 // Recalculate the number of items                numitems = calc_visible(menu,0);                // Reprint the menu                printmenu(menu,curr,top,left,first);             }             if (hr.valid) return ci;           }          else return ci;	  break;	case SPACEKEY:          if (ci->action != OPT_CHECKBOX) break;          ci->itemdata.checked = !ci->itemdata.checked;          if (ci->handler != NULL) // Do we have a handler          {             hr = ci->handler(ms,ci);               if (hr.refresh) // Do we need to refresh             {                // Cleanup menu using old number of items                cleanupmenu(menu,top,left,numitems);                 // Recalculate the number of items                numitems = calc_visible(menu,0);                // Reprint the menu                printmenu(menu,curr,top,left,first);             }          }          break;	default:	  // Check if this is a shortcut key	  if (((asc >= 'A') && (asc <= 'Z')) ||	      ((asc >= 'a') && (asc <= 'z')) ||	      ((asc >= '0') && (asc <= '9')))          {	    tmp = find_shortcut(menu,asc,curr);            if ((tmp > curr) && (! isvisible(menu,first,tmp)))                  first = calc_first_late(menu,tmp);            if (tmp < curr)                first = calc_first_early(menu,tmp);            curr = tmp;          }          else {            if (ms->keys_handler) // Call extra keys handler               ms->keys_handler(ms,menu->items[curr],(scan << 8) | asc);          }	  break;        }      // Update status line      gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage);      cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage);      printmenuitem(menu->items[curr]->status,ms->statusattr);    }  return NULL; // Should never come here}/* Handle the entire system of menu's. */pt_menuitem runmenusystem(uchar top, uchar left, pt_menu cmenu, uchar startopt, uchar menutype)     /*      * cmenu      *    Which menu should be currently displayed      * top,left      *    What is the position of the top,left corner of the menu      * startopt      *    which menu item do I start with      * menutype      *    NORMALMENU or RADIOMENU      *      * Return Value:      *    Returns a pointer to the final item chosen, or NULL if nothing chosen.      */{  pt_menuitem opt,choice;  uchar startat,mt;  uchar row,col;  if (cmenu == NULL) return NULL; startover:  // Set the menu height  cmenu->menuheight = ms->maxrow - top-3;  if (cmenu->menuheight > ms->maxmenuheight)      cmenu->menuheight = ms->maxmenuheight;  if (menutype == NORMALMENU)    opt = getmenuoption(cmenu,top,left,startopt);  else // menutype == RADIOMENU    opt = getradiooption(cmenu,top,left,startopt);  if (opt == NULL)    {      // User hit Esc      cleanupmenu(cmenu,top,left,calc_visible(cmenu,0));      return NULL;    }  // Are we done with the menu system?  if ((opt->action != OPT_SUBMENU) && (opt->action != OPT_RADIOMENU))     {      cleanupmenu(cmenu,top,left,calc_visible(cmenu,0));      return opt; // parent cleanup other menus    }  // Either radiomenu or submenu  // Do we have a valid menu number? The next hack uses the fact that   // itemdata.submenunum = itemdata.radiomenunum (since enum data type)  if (opt->itemdata.submenunum >= ms->nummenus) // This is Bad....    {      gotoxy(12,12,ms->menupage); // Middle of screen      csprint("ERROR: Invalid submenu requested.",0x07);      cleanupmenu(cmenu,top,left,calc_visible(cmenu,0));      return NULL; // Pretend user hit esc    }  // Call recursively for submenu  // Position the submenu below the current item,  // covering half the current window (horizontally)  row = ms->menus[(unsigned int)opt->itemdata.submenunum]->row;  col = ms->menus[(unsigned int)opt->itemdata.submenunum]->col;  if (row == 0xFF) row = top+opt->index+2;  if (col == 0xFF) col = left+3+(cmenu->menuwidth >> 1);  mt = (opt->action == OPT_SUBMENU ? NORMALMENU : RADIOMENU );  startat = 0;  if ((opt->action == OPT_RADIOMENU) && (opt->data != NULL))    startat = ((t_menuitem *)opt->data)->index;  choice = runmenusystem(row, col,			 ms->menus[(unsigned int)opt->itemdata.submenunum],			 startat, mt );  if (opt->action == OPT_RADIOMENU)    {      if (choice != NULL) opt->data = (void *)choice; // store choice in data field      if (opt->handler != NULL) opt->handler(ms,opt);        choice = NULL; // Pretend user hit esc    }  if (choice==NULL) // User hit Esc in submenu    {      // Startover      startopt = opt->index;      goto startover;    }  else    {      cleanupmenu(cmenu,top,left,calc_visible(cmenu,0));      return choice;    }}/* User Callable functions */pt_menuitem showmenus(uchar startmenu){  pt_menuitem rv;  uchar oldpage,tpos;  // Setup screen for menusystem  oldpage = getdisppage();  setdisppage(ms->menupage);  cls();  clearwindow(ms->minrow, ms->mincol, ms->maxrow, ms->maxcol, 	      ms->menupage, ms->fillchar, ms->fillattr);  tpos = (ms->numcols - strlen(ms->title) - 1) >> 1; // center it on line      gotoxy(ms->minrow,ms->mincol,ms->menupage);  cprint(ms->tfillchar,ms->titleattr,ms->numcols,ms->menupage);  gotoxy(ms->minrow,ms->mincol+tpos,ms->menupage);  csprint(ms->title,ms->titleattr);  cursoroff(); // Doesn't seem to work?  // Go, main menu cannot be a radio menu   rv = runmenusystem(ms->minrow+MENUROW, ms->mincol+MENUCOL, 		     ms->menus[(unsigned int)startmenu], 0, NORMALMENU);  // Hide the garbage we left on the screen  cursoron();  if (oldpage == ms->menupage) cls(); else setdisppage(oldpage);  // Return user choice  return rv;}pt_menusystem init_menusystem(const char *title){  int i;      ms = NULL;  ms = (pt_menusystem) malloc(sizeof(t_menusystem));  if (ms == NULL) return NULL;  ms->nummenus = 0;  // Initialise all menu pointers  for (i=0; i < MAXMENUS; i++) ms->menus[i] = NULL;       ms->title = (char *)malloc(TITLELEN+1);   if (title == NULL)    strcpy(ms->title,TITLESTR); // Copy string  else strcpy(ms->title,title);  // Timeout settings  ms->tm_stepsize = TIMEOUTSTEPSIZE;  ms->tm_numsteps = TIMEOUTNUMSTEPS;  ms->normalattr[NOHLITE] = NORMALATTR;   ms->normalattr[HLITE] = NORMALHLITE;  ms->reverseattr[NOHLITE] = REVERSEATTR;  ms->reverseattr[HLITE] = REVERSEHLITE;  ms->inactattr[NOHLITE] = INACTATTR;  ms->inactattr[HLITE] = INACTHLITE;  ms->revinactattr[NOHLITE] = REVINACTATTR;  ms->revinactattr[HLITE] = REVINACTHLITE;  ms->statusattr[NOHLITE] = STATUSATTR;  ms->statusattr[HLITE] = STATUSHLITE;  ms->statline = STATLINE;  ms->tfillchar= TFILLCHAR;  ms->titleattr= TITLEATTR;      ms->fillchar = FILLCHAR;  ms->fillattr = FILLATTR;  ms->spacechar= SPACECHAR;  ms->shadowattr = SHADOWATTR;  ms->menupage = MENUPAGE; // Usually no need to change this at all  // Initialise all handlers  ms->handler = NULL;  ms->keys_handler = NULL;   ms->ontimeout=NULL; // No timeout handler  // Setup ACTION_{,IN}VALID  ACTION_VALID.valid=1;  ACTION_VALID.refresh=0;  ACTION_INVALID.valid = 0;  ACTION_INVALID.refresh = 0;  // Figure out the size of the screen we are in now.  // By default we use the whole screen for our menu  ms->minrow = ms->mincol = 0;  ms->numcols = getnumcols();  ms->numrows = getnumrows();  ms->maxcol = ms->numcols - 1;  ms->maxrow = ms->numrows - 1;  // How many entries per menu can we display at a time  ms->maxmenuheight = ms->maxrow - ms->minrow - 3;  if (ms->maxmenuheight > MAXMENUHEIGHT)       ms->maxmenuheight= MAXMENUHEIGHT;   // Set up the look of the box  set_box_type(MENUBOXTYPE);  return ms;}void set_normal_attr(uchar normal, uchar selected, uchar inactivenormal, uchar inactiveselected){  if (normal != 0xFF)           ms->normalattr[0]   = normal;  if (selected != 0xFF)         ms->reverseattr[0]  = selected;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -