Chciałbym przesłać do zaopiniowania programik, który moim zdaniem świetnie pasowałby do Linux'a.
Jest on napisany w oparciu o bibl. curses i służy do łatwej budowy menu wyboru w skryptach.
Nazywa się win3 i zwraca do shell'a wartość będącą numerem wybranego przez użytkownika skryptu wiersza.
Odczytując status ostatnio wykonanej operacji wiemy jakie pole w menu wybrał użytkownik i możemy
wykonać odpowiedni program (np. następne podmenu). Pierwszym parametrem programu jest tytuł menu,
a następne parametry - to pola menu.
 
Wywołanie: win3 <tytuł> <tekst pola menu> [<tekst pola menu> [<tekst pola menu>] ... ]
Przykład: win3 "Zarządzanie systemem" "Liczba użytkowników" "Liczba procesów" etc. etc.
Kod źródlany:
 
#include <curses.h>
 
WINDOW *w1, *s1;
int wys, szer, lg_poz, Od, Do, oznaczony=1, menu_od, menu_do, menu_pom, raz=1;
int indeks[100];
int nadwyzka_linii=0;
int menu_ost=1;
 
struct wiersze
  {
   char tresc[500];
   int lwersow;
   int poz;
   int nrgory;
   int nrdolu;
  } index[100];
 
 
 
void analiza(int argc, char *argv[])
{
int i, pom=0, pom1=0, j, k;
 
 index[1].poz=0;
  
 for(i=1; i<argc; i++)
 {
  strcpy(index[i].tresc, argv[i+1]);
 

  index[i].lwersow=1;
  
  pom=strlen(index[i].tresc);
 
  if((pom+3)%77!=0)
  {
   strcat(index[i].tresc, "\n");
   pom++;
  };
 
  if(pom+3>77)
   index[i].lwersow++;
  if(pom+3>154)
   index[i].lwersow++;
  if(pom+3>231)
   index[i].lwersow++;
  if(pom+3>308)
   index[i].lwersow++;
  if(pom+3>385)
   index[i].lwersow++;
 
 
  if(i<argc-1)
  {
   pom1+=index[i].lwersow;
   index[i+1].poz=pom1;
  };
 };
  
 
 for(i=1; i<argc; i++)
 {
  pom=i;
  pom1=0;
  while(pom1<=20 && pom<=argc)
  {
   pom1+=index[pom].lwersow;
   pom++;
  };
   index[i].nrdolu=pom-2;
 };
 
 for(i=argc-1; i>0; i--)
 {
  pom1=0;
  pom=i;
  while(pom1<=20 && pom>0)
  {
   pom1+=index[pom].lwersow;
   pom--;
  };
  index[i].nrgory=pom+2;
 };
 
return;
};
 
void zm_index(int ile)
{
 int i;
 for(i=1; i<=Do; i++)
  index[i].poz+=ile;
 return;
};
 
void oznacz(int kt)
{
 char pom[500];
 
 strcpy(pom, index[oznaczony].tresc);
 if(pom[strlen(pom)-1]=='\n')
  pom[strlen(pom)-1]='\0';
 
 mvwprintw(s1, index[oznaczony].poz, 0, "%d.", oznaczony);
 mvwprintw(s1, index[oznaczony].poz, 3, "%s", pom);
 wattron(s1, A_REVERSE);
 mvwprintw(s1, index[kt].poz, 0, "%d.", kt);
 
 strcpy(pom, index[kt].tresc);
 if(pom[strlen(pom)-1]=='\n')
  pom[strlen(pom)-1]='\0';
 
 mvwprintw(s1, index[kt].poz, 3, "%s", pom);
 wattroff(s1, A_REVERSE);
 oznaczony=kt;
 
return;
};
 
void menu(int o, int d)
{
 int i;
 menu_od=o;
 menu_do=d;
 for(i=o; i<=d; i++)
 {
  if(i<10)
   wprintw(s1, "%d. ", i);
  else
   wprintw(s1, "%d.", i);
  wprintw(s1, "%s", index[i].tresc);
 };
 

 if(raz)
 {
  oznacz(1);
  raz=0;
 };
 return;
};
 
okno(WINDOW *w, int line, int col)
{
 int l, c;
 wattron(w, A_ALTCHARSET);
// wattron(w, A_BOLD);
 
 wprintw(w, "l");
 
 for(c=2; c<col; c++)
  wprintw(w, "q");
 
 wprintw(w, "k");
 
 for(l=2; l<line; l++)
  for(c=1; c<=col; c++)
  {
   if(c==1)
    wprintw(w, "x");
   if(c==col)
    wprintw(w, "x");
   if(c>1&&c<col)
    wprintw(w, " ");
  };
  
 wprintw(w, "m");
 for(c=2; c<col; c++)
        wprintw(w, "q");
 
 wprintw(w, "j");
 
 wattroff(w, A_ALTCHARSET);
// wattroff(w, A_BOLD);
};
 
int szerokosc(int argc, char *argv[])
{
 int i, max=0;
 for(i=1; i<argc; i++)
 {
  if(strlen(argv[i+1])+3>max)
   max=strlen(argv[i+1])+3;
 };
 if(max>76)
  return 79;
 else
  return max+3;
};
 
int wysokosc(int argc, char *argv[])
{
 int i, wys=0;
 for(i=1; i<argc; i++)
 {
/*
  indeks[i]=i+nadwyzka_linii-1;
  if(strlen(argv[i+1])+3>77)
  {
   wys++;
   nadwyzka_linii++;
  }
  if(strlen(argv[i+1]+3)>154)
  {
   wys++;
   nadwyzka_linii++;
  }
  if(strlen(argv[i+1])+3>231)
  {
   wys++;
   nadwyzka_linii++;
  }
  if(strlen(argv[i+1])+3>308)
  {
   wys++;
   nadwyzka_linii++;
  }
  if(strlen(argv[i+1])+3>385)
  {
   wys++;
   nadwyzka_linii++;
  }
   wys++;
*/
 
 wys+=index[i].lwersow;
 
 };
 
 
 if(wys>20)
  return 22;
 else
  return wys+2;
};
 
serv_input()
{
 while(1)
 {
  switch(wgetch(s1))
  {
   case 0: break;
   case 10:
   case KEY_F(16):return; break;
   case KEY_NPAGE:
   case KEY_RIGHT: if(oznaczony==menu_do && oznaczony < Do)
       {
        werase(s1);
        zm_index(0-index[menu_do].poz);
        menu(menu_do, index[menu_do].nrdolu);
        oznacz(menu_od);
        wrefresh(s1);
       }
       else
        oznacz(menu_do);
       break;
   case KEY_DOWN : if(oznaczony < Do)
       {
//        if(index[oznaczony].poz+index[oznaczony].lwersow-1==19)
        if(oznaczony==menu_do)
        {
         werase(s1);
         zm_index(-index[oznaczony+1].lwersow);
         zm_index(0-index[index[oznaczony+1].nrgory].poz);
         menu(index[oznaczony+1].nrgory, oznaczony+1);
  
        /*
         if(index[oznaczony+1].lwersow >= index[menu_od].lwersow)
         {
          zm_index(-index[index[oznaczony+1].nrgory].lwersow);
          menu(index[oznaczony+1].nrgory, index[index[oznaczony+1].nrgory].nrdolu);
         }
         else
         {
          zm_index(-index[index[menu_do+1].nrgory].lwersow);
          menu(index[menu_do+1].nrgory, index[index[menu_do+1].nrgory].nrdolu);
         };
        */
        };
        oznacz(oznaczony+1);
         wrefresh(s1);
       };
       break;
   case KEY_PPAGE:
   case KEY_LEFT: if(oznaczony==menu_od && oznaczony > Od)
                            {
                                werase(s1);
        if(oznaczony==2||oznaczony==1)
        {
         zm_index(0-index[1].poz);
                                    menu(1, index[1].nrdolu);
        }
        else
        {
                                 zm_index(0-index[index[menu_od].nrgory].poz);
                                 menu(index[menu_od].nrgory, index[index[menu_od].nrgory].nrdolu);
        };
                                oznacz(menu_do);
                                wrefresh(s1);
                            }
                            else
        oznacz(menu_od);
         break;
   case KEY_UP : if(oznaczony>1)
                            {
                                if(index[oznaczony].poz==0)
                                {
                                    werase(s1);
         zm_index(index[oznaczony-1].lwersow);
//         zm_index(index[oznaczony-1
         menu(oznaczony-1, index[oznaczony-1].nrdolu);
 
       /*  
         if(index[oznaczony-1].lwersow >= index[menu_do].lwersow)
         {
           zm_index(index[oznaczony-1].lwersow);
          menu(oznaczony-1, index[oznaczony-1].nrdolu);
         }
         else
         {
          zm_index(index[menu_do].lwersow);
                                     menu(index[menu_do-1].nrgory, index[index[menu_do-1].nrgory].nrdolu);
         };
       */
         
                                    wrefresh(s1);
                                };
                            oznacz(oznaczony-1);
                            };
 
       break;
  };
 };
 
return;
};
 
int main(int argc, char *argv[])
{
 
int i, j, pom, k;
char tytul[500];
 
if(argc<=2)
{
 fprintf(stderr, "Użyj: %s <tytul> <parametr> [<parametr> [<parametr>]...]\n", argv[0]);
 exit(-1);
};
 
 strcpy(tytul, argv[1]);
 if(strlen(tytul)>79)
 {
     fprintf(stderr, "Użyj: %s w tytule do 80 znaków\n", argv[0]);
  sleep(2);
     exit(-1);
 };
 

 initscr();
 
 argc--;
 Do=argc-1;
 
 attron(A_BOLD);
 
 printw(" %s\n", tytul);
 
 attroff(A_BOLD);
 
 refresh();
 
 analiza(argc, argv);
 

 wys=wysokosc(argc, argv);
 szer=szerokosc(argc, argv);
 lg_poz=40-(szer/2);
 
 w1=newwin(wys, szer, 1, lg_poz);
 s1=subwin(w1, wys-2, szer-2, 2, lg_poz+1);
 
 leaveok(s1, TRUE);
 leaveok(w1, TRUE);
// scrollok(s1, TRUE);
 noecho();
 cbreak();
 keypad(s1,TRUE);
 
 okno(w1,wys, szer);
 
// if(index[argc-1].poz+index[argc-1].lwersow-1>20)
  menu(1, index[1].nrdolu);
// else
//  menu(1, index[1].nrdolu+1);
 
 wrefresh(w1);
 wrefresh(s1);
 
 serv_input();
 
 endwin();
 
exit(oznaczony);
};
 
P.S.
    Pisałem pod Digital Unixem, ale pod Linuxem też powinien chodzić.
    Jeżeli taki program przydałby się w Linux'ie, to nie mam nic przeciwko, abyście go poprawili i
    udostępnili.
    pzdr
        Maciej Pogonowski

Reply via email to