root/scripts/lxdialog/menubox.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. print_item
  2. print_arrows
  3. print_buttons
  4. dialog_menu

   1 /*
   2  *  menubox.c -- implements the menu box
   3  *
   4  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
   5  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
   6  *
   7  *  This program is free software; you can redistribute it and/or
   8  *  modify it under the terms of the GNU General Public License
   9  *  as published by the Free Software Foundation; either version 2
  10  *  of the License, or (at your option) any later version.
  11  *
  12  *  This program is distributed in the hope that it will be useful,
  13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  *  GNU General Public License for more details.
  16  *
  17  *  You should have received a copy of the GNU General Public License
  18  *  along with this program; if not, write to the Free Software
  19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20  */
  21 
  22 #include "dialog.h"
  23 
  24 static int menu_width, item_x;
  25 
  26 /*
  27  * Print menu item
  28  */
  29 static void
  30 print_item (WINDOW * win, const char *item, int choice, int selected)
     /* [previous][next][first][last][top][bottom][index][help] */
  31 {
  32     int j, i;
  33 
  34     j = first_alpha(item);
  35 
  36     /* Clear 'residue' of last item */
  37     wattrset (win, menubox_attr);
  38     wmove (win, choice, 0);
  39     for (i = 0; i < menu_width; i++)
  40         waddch (win, ' ');
  41     wattrset (win, selected ? item_selected_attr : item_attr);
  42     mvwaddstr (win, choice, item_x, (char *)item);
  43     wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
  44     mvwaddch(win, choice, item_x+j, item[j]);
  45 }
  46 
  47 /*
  48  * Print the scroll indicators.
  49  */
  50 static void
  51 print_arrows (WINDOW * win, int choice, int item_no, int scroll,
     /* [previous][next][first][last][top][bottom][index][help] */
  52                 int y, int x, int height)
  53 {
  54     wmove(win, y, x);
  55 
  56     if (scroll > 0) {
  57         wattrset (win, uarrow_attr);
  58         waddch (win, ACS_UARROW);
  59         waddstr (win, "(-)");
  60     }
  61     else {
  62         wattrset (win, menubox_attr);
  63         waddch (win, ACS_HLINE);
  64         waddch (win, ACS_HLINE);
  65         waddch (win, ACS_HLINE);
  66         waddch (win, ACS_HLINE);
  67     }
  68 
  69    y = y + height + 1;
  70    wmove(win, y, x);
  71 
  72    if ((height < item_no) && (scroll + choice < item_no - 1)) {
  73         wattrset (win, darrow_attr);
  74         waddch (win, ACS_DARROW);
  75         waddstr (win, "(+)");
  76     }
  77     else {
  78         wattrset (win, menubox_border_attr);
  79         waddch (win, ACS_HLINE);
  80         waddch (win, ACS_HLINE);
  81         waddch (win, ACS_HLINE);
  82         waddch (win, ACS_HLINE);
  83    }
  84 }
  85 
  86 /*
  87  * Display the termination buttons.
  88  */
  89 static void
  90 print_buttons (WINDOW *win, int height, int width,
     /* [previous][next][first][last][top][bottom][index][help] */
  91                 int okval, int exitval, int cancelval)
  92 {
  93     int x = width / 2 - 16;
  94     int y = height - 2;
  95 
  96     print_button (win, "Select", y, x, okval);
  97     print_button (win, " Exit ", y, x + 12, exitval);
  98     print_button (win, " Help ", y, x + 24, cancelval);
  99 
 100     wrefresh (win);
 101 }
 102 
 103 /*
 104  * Display a menu for choosing among a number of options
 105  */
 106 int
 107 dialog_menu (const char *title, const char *prompt, int height, int width,
     /* [previous][next][first][last][top][bottom][index][help] */
 108                 int menu_height, const char *current, int item_no,
 109                 const char * const * items)
 110 
 111 {
 112     int i, j, x, y, cur_x, cur_y, box_x, box_y;
 113     int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
 114     WINDOW *dialog, *menu;
 115 
 116     max_choice = MIN (menu_height, item_no);
 117 
 118     /* center dialog box on screen */
 119     x = (COLS - width) / 2;
 120     y = (LINES - height) / 2;
 121 
 122     draw_shadow (stdscr, y, x, height, width);
 123 
 124     dialog = newwin (height, width, y, x);
 125     keypad (dialog, TRUE);
 126 
 127     draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
 128     wattrset (dialog, border_attr);
 129     mvwaddch (dialog, height - 3, 0, ACS_LTEE);
 130     for (i = 0; i < width - 2; i++)
 131         waddch (dialog, ACS_HLINE);
 132     wattrset (dialog, dialog_attr);
 133     waddch (dialog, ACS_RTEE);
 134 
 135     if (title != NULL) {
 136         wattrset (dialog, title_attr);
 137         mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
 138         waddstr (dialog, (char *)title);
 139         waddch (dialog, ' ');
 140     }
 141 
 142     wattrset (dialog, dialog_attr);
 143     print_autowrap (dialog, prompt, width - 2, 1, 3);
 144 
 145     menu_width = width - 6;
 146     getyx (dialog, cur_y, cur_x);
 147     box_y = height - menu_height - 5;
 148     box_x = (width - menu_width) / 2 - 1;
 149 
 150     /* create new window for the menu */
 151     menu = subwin (dialog, menu_height, menu_width,
 152                 y + box_y + 1, x + box_x + 1);
 153     keypad (menu, TRUE);
 154 
 155     /* draw a box around the menu items */
 156     draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
 157               menubox_border_attr, menubox_attr);
 158 
 159     /*
 160      * Find length of longest item in order to center menu.
 161      * Set 'choice' to default item. 
 162      */
 163     item_x = 0;
 164     for (i = 0; i < item_no; i++) {
 165         item_x = MAX (item_x, strlen (items[i * 2 + 1]) + 2);
 166         if (strcmp(current, items[i*2]) == 0) choice = i;
 167     }
 168 
 169     item_x = (menu_width - item_x) / 2;
 170 
 171     if (choice >= max_choice){
 172         scroll = first_item = choice - max_choice + 1;
 173         choice = max_choice-1;
 174     }
 175 
 176     /* Print the menu */
 177     for (i=0; i < max_choice; i++)
 178         print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice);
 179 
 180     wnoutrefresh (menu);
 181 
 182     print_arrows(dialog, choice, item_no, scroll,
 183                  box_y, box_x+item_x+1, menu_height);
 184 
 185     print_buttons (dialog, height, width, TRUE, FALSE, FALSE);
 186 
 187     while (key != ESC) {
 188         key = wgetch (dialog);
 189 
 190         for (i = choice+1; i < max_choice; i++) {
 191                 j = first_alpha(items[(scroll+i)*2+1]);
 192                 if (toupper(key) == toupper(items[(scroll+i)*2+1][j]))
 193                         break;
 194         }
 195         if (i == max_choice)
 196                 for (i = 0; i < max_choice; i++) {
 197                         j = first_alpha(items[(scroll+i)*2+1]);
 198                         if (toupper(key) == toupper(items[(scroll+i)*2+1][j]))
 199                                 break;
 200                 }
 201 
 202         if (i < max_choice || key == KEY_UP || key == KEY_DOWN || key == '-' || key == '+') {
 203             if (key == KEY_UP || key == '-') {
 204                 if (choice == 0) {
 205                     if (scroll) {
 206 
 207                         /* Scroll menu down */
 208                         getyx (dialog, cur_y, cur_x);
 209 
 210                         if (menu_height > 1) {
 211                             /* De-highlight current first item */
 212                             print_item (menu, items[scroll * 2 + 1],
 213                                         0, FALSE);
 214                             scrollok (menu, TRUE);
 215                             wscrl (menu, -1);
 216                             scrollok (menu, FALSE);
 217                         }
 218                         scroll--;
 219                         print_item (menu, items[scroll * 2 + 1], 0, TRUE);
 220                         wnoutrefresh (menu);
 221 
 222                         print_arrows(dialog, choice, item_no, scroll,
 223                                         box_y, box_x+item_x+1, menu_height);
 224 
 225                         wmove (dialog, cur_y, cur_x);
 226                     }
 227                     continue;   /* wait for another key press */
 228                 } else
 229                     i = choice - 1;
 230             } else if (key == KEY_DOWN || key == '+')
 231                 if (choice == max_choice - 1) {
 232                     if (scroll + choice < item_no - 1) {
 233                         /* Scroll menu up */
 234                         getyx (dialog, cur_y, cur_x);
 235                         if (menu_height > 1) {
 236                             /* De-highlight current last item */
 237                             print_item (menu, items[(scroll + max_choice - 1)
 238                                            * 2 + 1], max_choice - 1, FALSE);
 239                             scrollok (menu, TRUE);
 240                             scroll (menu);
 241                             scrollok (menu, FALSE);
 242                         }
 243                         scroll++;
 244                         print_item (menu, 
 245                                     items[(scroll + max_choice - 1) * 2 + 1],
 246                                     max_choice - 1, TRUE);
 247                         wnoutrefresh (menu);
 248 
 249                         print_arrows(dialog, choice, item_no, scroll,
 250                                         box_y, box_x+item_x+1, menu_height);
 251 
 252                         wmove (dialog, cur_y, cur_x);
 253                         wrefresh (dialog);
 254                     }
 255                     continue;   /* wait for another key press */
 256                 } else
 257                     i = choice + 1;
 258 
 259             if (i != choice) {
 260                 /* De-highlight current item */
 261                 getyx (dialog, cur_y, cur_x);   /* Save cursor position */
 262                 print_item (menu, items[(scroll + choice) * 2 + 1],
 263                                 choice, FALSE);
 264 
 265                 /* Highlight new item */
 266                 choice = i;
 267                 print_item (menu, items[(scroll + choice) * 2 + 1],
 268                                 choice, TRUE);
 269                 wnoutrefresh (menu);
 270                 wmove (dialog, cur_y, cur_x);
 271                 wrefresh (dialog);
 272             }
 273             continue;           /* wait for another key press */
 274         }
 275 
 276         switch (key) {
 277         case TAB:
 278         case KEY_LEFT:
 279         case KEY_RIGHT:
 280             switch (button) {
 281             case 0:
 282                 button = 1;
 283                 print_buttons(dialog, height, width, FALSE, TRUE, FALSE);
 284                 break;
 285             case 1:
 286                 button = 2;
 287                 print_buttons(dialog, height, width, FALSE, FALSE, TRUE);
 288                 break;
 289             case 2:
 290                 button = 0;
 291                 print_buttons(dialog, height, width, TRUE, FALSE, FALSE);
 292                 break;
 293             }
 294             wrefresh (dialog);
 295             break;
 296         case ' ':
 297         case 'S':
 298         case 's':
 299             delwin (dialog);
 300             fprintf(stderr, items[(scroll + choice) * 2]);
 301             return 0;
 302         case 'H':
 303         case 'h':
 304         case '?':
 305             button = 2;
 306         case '\n':
 307             delwin (dialog);
 308             if (button == 2) 
 309                 fprintf(stderr, "\"%s\" %s", 
 310                         items[(scroll + choice) * 2 + 1] +
 311                         first_alpha(items[(scroll + choice) * 2 + 1]),
 312                         items[(scroll + choice) * 2]);
 313             else
 314                 fprintf(stderr, items[(scroll + choice) * 2]);
 315 
 316             return button;
 317         case 'E':
 318         case 'e':
 319         case 'X':
 320         case 'x':
 321             key = ESC;
 322         case ESC:
 323             break;
 324         }
 325     }
 326 
 327     delwin (dialog);
 328     return -1;                  /* ESC pressed */
 329 }

/* [previous][next][first][last][top][bottom][index][help] */