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, int hotkey)
     /* [previous][next][first][last][top][bottom][index][help] */
  31 {
  32     int i, j;
  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     if (hotkey) {
  44         wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
  45         mvwaddch(win, choice, item_x+j, item[j]);
  46     }
  47 }
  48 
  49 /*
  50  * Print the scroll indicators.
  51  */
  52 static void
  53 print_arrows (WINDOW * win, int choice, int item_no, int scroll,
     /* [previous][next][first][last][top][bottom][index][help] */
  54                 int y, int x, int height)
  55 {
  56     wmove(win, y, x);
  57 
  58     if (scroll > 0) {
  59         wattrset (win, uarrow_attr);
  60         waddch (win, ACS_UARROW);
  61         waddstr (win, "(-)");
  62     }
  63     else {
  64         wattrset (win, menubox_attr);
  65         waddch (win, ACS_HLINE);
  66         waddch (win, ACS_HLINE);
  67         waddch (win, ACS_HLINE);
  68         waddch (win, ACS_HLINE);
  69     }
  70 
  71    y = y + height + 1;
  72    wmove(win, y, x);
  73 
  74    if ((height < item_no) && (scroll + choice < item_no - 1)) {
  75         wattrset (win, darrow_attr);
  76         waddch (win, ACS_DARROW);
  77         waddstr (win, "(+)");
  78     }
  79     else {
  80         wattrset (win, menubox_border_attr);
  81         waddch (win, ACS_HLINE);
  82         waddch (win, ACS_HLINE);
  83         waddch (win, ACS_HLINE);
  84         waddch (win, ACS_HLINE);
  85    }
  86 }
  87 
  88 /*
  89  * Display the termination buttons.
  90  */
  91 static void
  92 print_buttons (WINDOW *win, int height, int width,
     /* [previous][next][first][last][top][bottom][index][help] */
  93                 int okval, int exitval, int cancelval)
  94 {
  95     int x = width / 2 - 16;
  96     int y = height - 2;
  97 
  98     print_button (win, "Select", y, x, okval);
  99     print_button (win, " Exit ", y, x + 12, exitval);
 100     print_button (win, " Help ", y, x + 24, cancelval);
 101 
 102     wrefresh (win);
 103 }
 104 
 105 /*
 106  * Display a menu for choosing among a number of options
 107  */
 108 int
 109 dialog_menu (const char *title, const char *prompt, int height, int width,
     /* [previous][next][first][last][top][bottom][index][help] */
 110                 int menu_height, const char *current, int item_no,
 111                 const char * const * items)
 112 
 113 {
 114     int i, j, x, y, cur_x, cur_y, box_x, box_y;
 115     int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
 116     WINDOW *dialog, *menu;
 117 
 118     max_choice = MIN (menu_height, item_no);
 119 
 120     /* center dialog box on screen */
 121     x = (COLS - width) / 2;
 122     y = (LINES - height) / 2;
 123 
 124     draw_shadow (stdscr, y, x, height, width);
 125 
 126     dialog = newwin (height, width, y, x);
 127     keypad (dialog, TRUE);
 128 
 129     draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
 130     wattrset (dialog, border_attr);
 131     mvwaddch (dialog, height - 3, 0, ACS_LTEE);
 132     for (i = 0; i < width - 2; i++)
 133         waddch (dialog, ACS_HLINE);
 134     wattrset (dialog, dialog_attr);
 135     waddch (dialog, ACS_RTEE);
 136 
 137     if (title != NULL) {
 138         wattrset (dialog, title_attr);
 139         mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
 140         waddstr (dialog, (char *)title);
 141         waddch (dialog, ' ');
 142     }
 143 
 144     wattrset (dialog, dialog_attr);
 145     print_autowrap (dialog, prompt, width - 2, 1, 3);
 146 
 147     menu_width = width - 6;
 148     getyx (dialog, cur_y, cur_x);
 149     box_y = height - menu_height - 5;
 150     box_x = (width - menu_width) / 2 - 1;
 151 
 152     /* create new window for the menu */
 153     menu = subwin (dialog, menu_height, menu_width,
 154                 y + box_y + 1, x + box_x + 1);
 155     keypad (menu, TRUE);
 156 
 157     /* draw a box around the menu items */
 158     draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
 159               menubox_border_attr, menubox_attr);
 160 
 161     /*
 162      * Find length of longest item in order to center menu.
 163      * Set 'choice' to default item. 
 164      */
 165     item_x = 0;
 166     for (i = 0; i < item_no; i++) {
 167         item_x = MAX (item_x, strlen (items[i * 2 + 1]) + 2);
 168         if (strcmp(current, items[i*2]) == 0) choice = i;
 169     }
 170 
 171     item_x = (menu_width - item_x) / 2;
 172 
 173     if (choice >= max_choice){
 174         scroll = first_item = choice - max_choice + 1;
 175         choice = max_choice-1;
 176     }
 177 
 178     /* Print the menu */
 179     for (i=0; i < max_choice; i++) {
 180         print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
 181                     (items[(first_item + i)*2][0] != ':'));
 182     }
 183 
 184     wnoutrefresh (menu);
 185 
 186     print_arrows(dialog, choice, item_no, scroll,
 187                  box_y, box_x+item_x+1, menu_height);
 188 
 189     print_buttons (dialog, height, width, TRUE, FALSE, FALSE);
 190 
 191     while (key != ESC) {
 192         key = wgetch (dialog);
 193 
 194         for (i = choice+1; i < max_choice; i++) {
 195                 j = first_alpha(items[(scroll+i)*2+1]);
 196                 if (toupper(key) == toupper(items[(scroll+i)*2+1][j]))
 197                         break;
 198         }
 199         if (i == max_choice)
 200                 for (i = 0; i < max_choice; i++) {
 201                         j = first_alpha(items[(scroll+i)*2+1]);
 202                         if (toupper(key) == toupper(items[(scroll+i)*2+1][j]))
 203                                 break;
 204                 }
 205 
 206         if (i < max_choice || key == KEY_UP || key == KEY_DOWN || key == '-' || key == '+') {
 207             if (key == KEY_UP || key == '-') {
 208                 if (choice == 0) {
 209                     if (scroll) {
 210 
 211                         /* Scroll menu down */
 212                         getyx (dialog, cur_y, cur_x);
 213 
 214                         if (menu_height > 1) {
 215                             /* De-highlight current first item */
 216                             print_item (menu, items[scroll*2+1], 0, FALSE,
 217                                         (items[scroll*2][0] != ':'));
 218                             scrollok (menu, TRUE);
 219                             wscrl (menu, -1);
 220                             scrollok (menu, FALSE);
 221                         }
 222                         scroll--;
 223                         print_item (menu, items[scroll * 2 + 1], 0, TRUE,
 224                                    (items[scroll*2][0] != ':'));
 225                         wnoutrefresh (menu);
 226 
 227                         print_arrows(dialog, choice, item_no, scroll,
 228                                         box_y, box_x+item_x+1, menu_height);
 229 
 230                         wmove (dialog, cur_y, cur_x);
 231                     }
 232                     continue;   /* wait for another key press */
 233                 } else
 234                     i = choice - 1;
 235             } else if (key == KEY_DOWN || key == '+')
 236                 if (choice == max_choice - 1) {
 237                     if (scroll + choice < item_no - 1) {
 238                         /* Scroll menu up */
 239                         getyx (dialog, cur_y, cur_x);
 240                         if (menu_height > 1) {
 241                             /* De-highlight current last item */
 242                             print_item (menu, items[(scroll + max_choice - 1)
 243                                            * 2 + 1], max_choice - 1, FALSE,
 244                                            (items[(scroll+max_choice-1)*2][0] != ':'));
 245                             scrollok (menu, TRUE);
 246                             scroll (menu);
 247                             scrollok (menu, FALSE);
 248                         }
 249                         scroll++;
 250                         print_item (menu, items[(scroll+max_choice-1)*2+1],
 251                                     max_choice-1, TRUE,
 252                                     (items[(scroll+max_choice-1)*2][0] != ':'));
 253 
 254                         wnoutrefresh (menu);
 255 
 256                         print_arrows(dialog, choice, item_no, scroll,
 257                                         box_y, box_x+item_x+1, menu_height);
 258 
 259                         wmove (dialog, cur_y, cur_x);
 260                         wrefresh (dialog);
 261                     }
 262                     continue;   /* wait for another key press */
 263                 } else
 264                     i = choice + 1;
 265 
 266             if (i != choice) {
 267                 /* De-highlight current item */
 268                 getyx (dialog, cur_y, cur_x);   /* Save cursor position */
 269                 print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
 270                                 (items[(scroll+choice)*2][0] != ':'));
 271 
 272                 /* Highlight new item */
 273                 choice = i;
 274                 print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
 275                                 (items[(scroll+choice)*2][0] != ':'));
 276                 wnoutrefresh (menu);
 277                 wmove (dialog, cur_y, cur_x);
 278                 wrefresh (dialog);
 279             }
 280             continue;           /* wait for another key press */
 281         }
 282 
 283         switch (key) {
 284         case TAB:
 285         case KEY_LEFT:
 286         case KEY_RIGHT:
 287             switch (button) {
 288             case 0:
 289                 button = 1;
 290                 print_buttons(dialog, height, width, FALSE, TRUE, FALSE);
 291                 break;
 292             case 1:
 293                 button = 2;
 294                 print_buttons(dialog, height, width, FALSE, FALSE, TRUE);
 295                 break;
 296             case 2:
 297                 button = 0;
 298                 print_buttons(dialog, height, width, TRUE, FALSE, FALSE);
 299                 break;
 300             }
 301             wrefresh (dialog);
 302             break;
 303         case ' ':
 304         case 'S':
 305         case 's':
 306             delwin (dialog);
 307             fprintf(stderr, items[(scroll + choice) * 2]);
 308             return 0;
 309         case 'H':
 310         case 'h':
 311         case '?':
 312             button = 2;
 313         case '\n':
 314             delwin (dialog);
 315             if (button == 2) 
 316                 fprintf(stderr, "\"%s\" %s", 
 317                         items[(scroll + choice) * 2 + 1] +
 318                         first_alpha(items[(scroll + choice) * 2 + 1]),
 319                         items[(scroll + choice) * 2]);
 320             else
 321                 fprintf(stderr, items[(scroll + choice) * 2]);
 322 
 323             return button;
 324         case 'E':
 325         case 'e':
 326         case 'X':
 327         case 'x':
 328             key = ESC;
 329         case ESC:
 330             break;
 331         }
 332     }
 333 
 334     delwin (dialog);
 335     return -1;                  /* ESC pressed */
 336 }

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