0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 #include "dialog.h"
0047
0048 static int menu_width, item_x;
0049
0050
0051
0052
0053 static void do_print_item(WINDOW * win, const char *item, int line_y,
0054 int selected, int hotkey)
0055 {
0056 int j;
0057 char *menu_item = malloc(menu_width + 1);
0058
0059 strncpy(menu_item, item, menu_width - item_x);
0060 menu_item[menu_width - item_x] = '\0';
0061 j = first_alpha(menu_item, "YyNnMmHh");
0062
0063
0064 wattrset(win, dlg.menubox.atr);
0065 wmove(win, line_y, 0);
0066 #if OLD_NCURSES
0067 {
0068 int i;
0069 for (i = 0; i < menu_width; i++)
0070 waddch(win, ' ');
0071 }
0072 #else
0073 wclrtoeol(win);
0074 #endif
0075 wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
0076 mvwaddstr(win, line_y, item_x, menu_item);
0077 if (hotkey) {
0078 wattrset(win, selected ? dlg.tag_key_selected.atr
0079 : dlg.tag_key.atr);
0080 mvwaddch(win, line_y, item_x + j, menu_item[j]);
0081 }
0082 if (selected) {
0083 wmove(win, line_y, item_x + 1);
0084 }
0085 free(menu_item);
0086 wrefresh(win);
0087 }
0088
0089 #define print_item(index, choice, selected) \
0090 do { \
0091 item_set(index); \
0092 do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
0093 } while (0)
0094
0095
0096
0097
0098 static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
0099 int height)
0100 {
0101 int cur_y, cur_x;
0102
0103 getyx(win, cur_y, cur_x);
0104
0105 wmove(win, y, x);
0106
0107 if (scroll > 0) {
0108 wattrset(win, dlg.uarrow.atr);
0109 waddch(win, ACS_UARROW);
0110 waddstr(win, "(-)");
0111 } else {
0112 wattrset(win, dlg.menubox.atr);
0113 waddch(win, ACS_HLINE);
0114 waddch(win, ACS_HLINE);
0115 waddch(win, ACS_HLINE);
0116 waddch(win, ACS_HLINE);
0117 }
0118
0119 y = y + height + 1;
0120 wmove(win, y, x);
0121 wrefresh(win);
0122
0123 if ((height < item_no) && (scroll + height < item_no)) {
0124 wattrset(win, dlg.darrow.atr);
0125 waddch(win, ACS_DARROW);
0126 waddstr(win, "(+)");
0127 } else {
0128 wattrset(win, dlg.menubox_border.atr);
0129 waddch(win, ACS_HLINE);
0130 waddch(win, ACS_HLINE);
0131 waddch(win, ACS_HLINE);
0132 waddch(win, ACS_HLINE);
0133 }
0134
0135 wmove(win, cur_y, cur_x);
0136 wrefresh(win);
0137 }
0138
0139
0140
0141
0142 static void print_buttons(WINDOW * win, int height, int width, int selected)
0143 {
0144 int x = width / 2 - 28;
0145 int y = height - 2;
0146
0147 print_button(win, "Select", y, x, selected == 0);
0148 print_button(win, " Exit ", y, x + 12, selected == 1);
0149 print_button(win, " Help ", y, x + 24, selected == 2);
0150 print_button(win, " Save ", y, x + 36, selected == 3);
0151 print_button(win, " Load ", y, x + 48, selected == 4);
0152
0153 wmove(win, y, x + 1 + 12 * selected);
0154 wrefresh(win);
0155 }
0156
0157
0158 static void do_scroll(WINDOW *win, int *scroll, int n)
0159 {
0160
0161 scrollok(win, TRUE);
0162 wscrl(win, n);
0163 scrollok(win, FALSE);
0164 *scroll = *scroll + n;
0165 wrefresh(win);
0166 }
0167
0168
0169
0170
0171 int dialog_menu(const char *title, const char *prompt,
0172 const void *selected, int *s_scroll)
0173 {
0174 int i, j, x, y, box_x, box_y;
0175 int height, width, menu_height;
0176 int key = 0, button = 0, scroll = 0, choice = 0;
0177 int first_item = 0, max_choice;
0178 WINDOW *dialog, *menu;
0179
0180 do_resize:
0181 height = getmaxy(stdscr);
0182 width = getmaxx(stdscr);
0183 if (height < MENUBOX_HEIGTH_MIN || width < MENUBOX_WIDTH_MIN)
0184 return -ERRDISPLAYTOOSMALL;
0185
0186 height -= 4;
0187 width -= 5;
0188 menu_height = height - 10;
0189
0190 max_choice = MIN(menu_height, item_count());
0191
0192
0193 x = (getmaxx(stdscr) - width) / 2;
0194 y = (getmaxy(stdscr) - height) / 2;
0195
0196 draw_shadow(stdscr, y, x, height, width);
0197
0198 dialog = newwin(height, width, y, x);
0199 keypad(dialog, TRUE);
0200
0201 draw_box(dialog, 0, 0, height, width,
0202 dlg.dialog.atr, dlg.border.atr);
0203 wattrset(dialog, dlg.border.atr);
0204 mvwaddch(dialog, height - 3, 0, ACS_LTEE);
0205 for (i = 0; i < width - 2; i++)
0206 waddch(dialog, ACS_HLINE);
0207 wattrset(dialog, dlg.dialog.atr);
0208 wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
0209 waddch(dialog, ACS_RTEE);
0210
0211 print_title(dialog, title, width);
0212
0213 wattrset(dialog, dlg.dialog.atr);
0214 print_autowrap(dialog, prompt, width - 2, 1, 3);
0215
0216 menu_width = width - 6;
0217 box_y = height - menu_height - 5;
0218 box_x = (width - menu_width) / 2 - 1;
0219
0220
0221 menu = subwin(dialog, menu_height, menu_width,
0222 y + box_y + 1, x + box_x + 1);
0223 keypad(menu, TRUE);
0224
0225
0226 draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
0227 dlg.menubox_border.atr, dlg.menubox.atr);
0228
0229 if (menu_width >= 80)
0230 item_x = (menu_width - 70) / 2;
0231 else
0232 item_x = 4;
0233
0234
0235 item_foreach()
0236 if (selected && (selected == item_data()))
0237 choice = item_n();
0238
0239 scroll = *s_scroll;
0240 if ((scroll <= choice) && (scroll + max_choice > choice) &&
0241 (scroll >= 0) && (scroll + max_choice <= item_count())) {
0242 first_item = scroll;
0243 choice = choice - scroll;
0244 } else {
0245 scroll = 0;
0246 }
0247 if ((choice >= max_choice)) {
0248 if (choice >= item_count() - max_choice / 2)
0249 scroll = first_item = item_count() - max_choice;
0250 else
0251 scroll = first_item = choice - max_choice / 2;
0252 choice = choice - scroll;
0253 }
0254
0255
0256 for (i = 0; i < max_choice; i++) {
0257 print_item(first_item + i, i, i == choice);
0258 }
0259
0260 wnoutrefresh(menu);
0261
0262 print_arrows(dialog, item_count(), scroll,
0263 box_y, box_x + item_x + 1, menu_height);
0264
0265 print_buttons(dialog, height, width, 0);
0266 wmove(menu, choice, item_x + 1);
0267 wrefresh(menu);
0268
0269 while (key != KEY_ESC) {
0270 key = wgetch(menu);
0271
0272 if (key < 256 && isalpha(key))
0273 key = tolower(key);
0274
0275 if (strchr("ynmh", key))
0276 i = max_choice;
0277 else {
0278 for (i = choice + 1; i < max_choice; i++) {
0279 item_set(scroll + i);
0280 j = first_alpha(item_str(), "YyNnMmHh");
0281 if (key == tolower(item_str()[j]))
0282 break;
0283 }
0284 if (i == max_choice)
0285 for (i = 0; i < max_choice; i++) {
0286 item_set(scroll + i);
0287 j = first_alpha(item_str(), "YyNnMmHh");
0288 if (key == tolower(item_str()[j]))
0289 break;
0290 }
0291 }
0292
0293 if (item_count() != 0 &&
0294 (i < max_choice ||
0295 key == KEY_UP || key == KEY_DOWN ||
0296 key == '-' || key == '+' ||
0297 key == KEY_PPAGE || key == KEY_NPAGE)) {
0298
0299 print_item(scroll + choice, choice, FALSE);
0300
0301 if (key == KEY_UP || key == '-') {
0302 if (choice < 2 && scroll) {
0303
0304 do_scroll(menu, &scroll, -1);
0305
0306 print_item(scroll, 0, FALSE);
0307 } else
0308 choice = MAX(choice - 1, 0);
0309
0310 } else if (key == KEY_DOWN || key == '+') {
0311 print_item(scroll+choice, choice, FALSE);
0312
0313 if ((choice > max_choice - 3) &&
0314 (scroll + max_choice < item_count())) {
0315
0316 do_scroll(menu, &scroll, 1);
0317
0318 print_item(scroll+max_choice - 1,
0319 max_choice - 1, FALSE);
0320 } else
0321 choice = MIN(choice + 1, max_choice - 1);
0322
0323 } else if (key == KEY_PPAGE) {
0324 scrollok(menu, TRUE);
0325 for (i = 0; (i < max_choice); i++) {
0326 if (scroll > 0) {
0327 do_scroll(menu, &scroll, -1);
0328 print_item(scroll, 0, FALSE);
0329 } else {
0330 if (choice > 0)
0331 choice--;
0332 }
0333 }
0334
0335 } else if (key == KEY_NPAGE) {
0336 for (i = 0; (i < max_choice); i++) {
0337 if (scroll + max_choice < item_count()) {
0338 do_scroll(menu, &scroll, 1);
0339 print_item(scroll+max_choice-1,
0340 max_choice - 1, FALSE);
0341 } else {
0342 if (choice + 1 < max_choice)
0343 choice++;
0344 }
0345 }
0346 } else
0347 choice = i;
0348
0349 print_item(scroll + choice, choice, TRUE);
0350
0351 print_arrows(dialog, item_count(), scroll,
0352 box_y, box_x + item_x + 1, menu_height);
0353
0354 wnoutrefresh(dialog);
0355 wrefresh(menu);
0356
0357 continue;
0358 }
0359
0360 switch (key) {
0361 case KEY_LEFT:
0362 case TAB:
0363 case KEY_RIGHT:
0364 button = ((key == KEY_LEFT ? --button : ++button) < 0)
0365 ? 4 : (button > 4 ? 0 : button);
0366
0367 print_buttons(dialog, height, width, button);
0368 wrefresh(menu);
0369 break;
0370 case ' ':
0371 case 's':
0372 case 'y':
0373 case 'n':
0374 case 'm':
0375 case '/':
0376 case 'h':
0377 case '?':
0378 case 'z':
0379 case '\n':
0380
0381 *s_scroll = scroll;
0382 delwin(menu);
0383 delwin(dialog);
0384 item_set(scroll + choice);
0385 item_set_selected(1);
0386 switch (key) {
0387 case 'h':
0388 case '?':
0389 return 2;
0390 case 's':
0391 case 'y':
0392 return 5;
0393 case 'n':
0394 return 6;
0395 case 'm':
0396 return 7;
0397 case ' ':
0398 return 8;
0399 case '/':
0400 return 9;
0401 case 'z':
0402 return 10;
0403 case '\n':
0404 return button;
0405 }
0406 return 0;
0407 case 'e':
0408 case 'x':
0409 key = KEY_ESC;
0410 break;
0411 case KEY_ESC:
0412 key = on_key_esc(menu);
0413 break;
0414 case KEY_RESIZE:
0415 on_key_resize();
0416 delwin(menu);
0417 delwin(dialog);
0418 goto do_resize;
0419 }
0420 }
0421 delwin(menu);
0422 delwin(dialog);
0423 return key;
0424 }