14c8945a0SNathan Whitehorn /* 24c8945a0SNathan Whitehorn * $Id: menubox.c,v 1.118 2010/01/17 22:24:11 tom Exp $ 34c8945a0SNathan Whitehorn * 44c8945a0SNathan Whitehorn * menubox.c -- implements the menu box 54c8945a0SNathan Whitehorn * 64c8945a0SNathan Whitehorn * Copyright 2000-2009,2010 Thomas E. Dickey 74c8945a0SNathan Whitehorn * 84c8945a0SNathan Whitehorn * This program is free software; you can redistribute it and/or modify 94c8945a0SNathan Whitehorn * it under the terms of the GNU Lesser General Public Licens, version 2.1e 104c8945a0SNathan Whitehorn * as published by the Free Software Foundation. 114c8945a0SNathan Whitehorn * 124c8945a0SNathan Whitehorn * This program is distributed in the hope that it will be useful, but 134c8945a0SNathan Whitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 144c8945a0SNathan Whitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 154c8945a0SNathan Whitehorn * Lesser General Public License for more details. 164c8945a0SNathan Whitehorn * 174c8945a0SNathan Whitehorn * You should have received a copy of the GNU Lesser General Public 184c8945a0SNathan Whitehorn * License along with this program; if not, write to 194c8945a0SNathan Whitehorn * Free Software Foundation, Inc. 204c8945a0SNathan Whitehorn * 51 Franklin St., Fifth Floor 214c8945a0SNathan Whitehorn * Boston, MA 02110, USA. 224c8945a0SNathan Whitehorn * 234c8945a0SNathan Whitehorn * An earlier version of this program lists as authors 244c8945a0SNathan Whitehorn * Savio Lam (lam836@cs.cuhk.hk) 254c8945a0SNathan Whitehorn */ 264c8945a0SNathan Whitehorn 274c8945a0SNathan Whitehorn #include <dialog.h> 284c8945a0SNathan Whitehorn #include <dlg_keys.h> 294c8945a0SNathan Whitehorn 304c8945a0SNathan Whitehorn static int menu_width, tag_x, item_x; 314c8945a0SNathan Whitehorn 324c8945a0SNathan Whitehorn typedef enum { 334c8945a0SNathan Whitehorn Unselected = 0, 344c8945a0SNathan Whitehorn Selected, 354c8945a0SNathan Whitehorn Editing 364c8945a0SNathan Whitehorn } Mode; 374c8945a0SNathan Whitehorn 384c8945a0SNathan Whitehorn #define MIN_HIGH (1 + (5 * MARGIN)) 394c8945a0SNathan Whitehorn 404c8945a0SNathan Whitehorn #define INPUT_ROWS 3 /* rows per inputmenu entry */ 414c8945a0SNathan Whitehorn 424c8945a0SNathan Whitehorn #define LLEN(n) ((n) * MENUBOX_TAGS) 434c8945a0SNathan Whitehorn #define ItemName(i) items[LLEN(i)] 444c8945a0SNathan Whitehorn #define ItemText(i) items[LLEN(i) + 1] 454c8945a0SNathan Whitehorn #define ItemHelp(i) items[LLEN(i) + 2] 464c8945a0SNathan Whitehorn 474c8945a0SNathan Whitehorn #define RowHeight(i) (is_inputmenu ? ((i) * INPUT_ROWS) : ((i) * 1)) 484c8945a0SNathan Whitehorn #define ItemToRow(i) (is_inputmenu ? ((i) * INPUT_ROWS + 1) : (i)) 494c8945a0SNathan Whitehorn #define RowToItem(i) (is_inputmenu ? ((i) / INPUT_ROWS + 0) : (i)) 504c8945a0SNathan Whitehorn 514c8945a0SNathan Whitehorn static void 524c8945a0SNathan Whitehorn print_arrows(WINDOW *win, 534c8945a0SNathan Whitehorn int box_x, 544c8945a0SNathan Whitehorn int box_y, 554c8945a0SNathan Whitehorn int scrollamt, 564c8945a0SNathan Whitehorn int max_choice, 574c8945a0SNathan Whitehorn int item_no, 584c8945a0SNathan Whitehorn int menu_height) 594c8945a0SNathan Whitehorn { 604c8945a0SNathan Whitehorn dlg_draw_scrollbar(win, 614c8945a0SNathan Whitehorn scrollamt, 624c8945a0SNathan Whitehorn scrollamt, 634c8945a0SNathan Whitehorn scrollamt + max_choice, 644c8945a0SNathan Whitehorn item_no, 654c8945a0SNathan Whitehorn box_x, 664c8945a0SNathan Whitehorn box_x + menu_width, 674c8945a0SNathan Whitehorn box_y, 684c8945a0SNathan Whitehorn box_y + menu_height + 1, 694c8945a0SNathan Whitehorn menubox_attr, 704c8945a0SNathan Whitehorn menubox_border_attr); 714c8945a0SNathan Whitehorn } 724c8945a0SNathan Whitehorn 734c8945a0SNathan Whitehorn /* 744c8945a0SNathan Whitehorn * Print the tag of a menu-item 754c8945a0SNathan Whitehorn */ 764c8945a0SNathan Whitehorn static void 774c8945a0SNathan Whitehorn print_tag(WINDOW *win, 784c8945a0SNathan Whitehorn DIALOG_LISTITEM * item, 794c8945a0SNathan Whitehorn int choice, 804c8945a0SNathan Whitehorn Mode selected, 814c8945a0SNathan Whitehorn bool is_inputmenu) 824c8945a0SNathan Whitehorn { 834c8945a0SNathan Whitehorn int my_x = item_x; 844c8945a0SNathan Whitehorn int my_y = ItemToRow(choice); 854c8945a0SNathan Whitehorn int tag_width = (my_x - tag_x - GUTTER); 864c8945a0SNathan Whitehorn const int *cols; 874c8945a0SNathan Whitehorn const int *indx; 884c8945a0SNathan Whitehorn int limit; 894c8945a0SNathan Whitehorn int prefix; 904c8945a0SNathan Whitehorn 914c8945a0SNathan Whitehorn cols = dlg_index_columns(item->name); 924c8945a0SNathan Whitehorn indx = dlg_index_wchars(item->name); 934c8945a0SNathan Whitehorn limit = dlg_count_wchars(item->name); 944c8945a0SNathan Whitehorn prefix = (indx[1] - indx[0]); 954c8945a0SNathan Whitehorn 964c8945a0SNathan Whitehorn /* highlight first char of the tag to be special */ 974c8945a0SNathan Whitehorn (void) wmove(win, my_y, tag_x); 984c8945a0SNathan Whitehorn wattrset(win, selected ? tag_key_selected_attr : tag_key_attr); 994c8945a0SNathan Whitehorn if (strlen(item->name) != 0) 1004c8945a0SNathan Whitehorn (void) waddnstr(win, item->name, prefix); 1014c8945a0SNathan Whitehorn /* print rest of the string */ 1024c8945a0SNathan Whitehorn wattrset(win, selected ? tag_selected_attr : tag_attr); 1034c8945a0SNathan Whitehorn if ((int) strlen(item->name) > prefix) { 1044c8945a0SNathan Whitehorn limit = dlg_limit_columns(item->name, tag_width, 1); 1054c8945a0SNathan Whitehorn if (limit > 0) 1064c8945a0SNathan Whitehorn (void) waddnstr(win, item->name + indx[1], indx[limit] - indx[1]); 1074c8945a0SNathan Whitehorn } 1084c8945a0SNathan Whitehorn } 1094c8945a0SNathan Whitehorn 1104c8945a0SNathan Whitehorn /* 1114c8945a0SNathan Whitehorn * Print menu item 1124c8945a0SNathan Whitehorn */ 1134c8945a0SNathan Whitehorn static void 1144c8945a0SNathan Whitehorn print_item(WINDOW *win, 1154c8945a0SNathan Whitehorn DIALOG_LISTITEM * items, 1164c8945a0SNathan Whitehorn int choice, 1174c8945a0SNathan Whitehorn Mode selected, 1184c8945a0SNathan Whitehorn bool is_inputmenu) 1194c8945a0SNathan Whitehorn { 1204c8945a0SNathan Whitehorn chtype save = getattrs(win); 1214c8945a0SNathan Whitehorn int n; 1224c8945a0SNathan Whitehorn int my_width = menu_width; 1234c8945a0SNathan Whitehorn int my_x = item_x; 1244c8945a0SNathan Whitehorn int my_y = ItemToRow(choice); 1254c8945a0SNathan Whitehorn chtype attr = A_NORMAL; 1264c8945a0SNathan Whitehorn chtype textchar; 1274c8945a0SNathan Whitehorn chtype bordchar; 1284c8945a0SNathan Whitehorn 1294c8945a0SNathan Whitehorn switch (selected) { 1304c8945a0SNathan Whitehorn default: 1314c8945a0SNathan Whitehorn case Unselected: 1324c8945a0SNathan Whitehorn textchar = item_attr; 1334c8945a0SNathan Whitehorn bordchar = item_attr; 1344c8945a0SNathan Whitehorn break; 1354c8945a0SNathan Whitehorn case Selected: 1364c8945a0SNathan Whitehorn textchar = item_selected_attr; 1374c8945a0SNathan Whitehorn bordchar = item_selected_attr; 1384c8945a0SNathan Whitehorn break; 1394c8945a0SNathan Whitehorn case Editing: 1404c8945a0SNathan Whitehorn textchar = inputbox_attr; 1414c8945a0SNathan Whitehorn bordchar = dialog_attr; 1424c8945a0SNathan Whitehorn break; 1434c8945a0SNathan Whitehorn } 1444c8945a0SNathan Whitehorn 1454c8945a0SNathan Whitehorn /* Clear 'residue' of last item and mark current current item */ 1464c8945a0SNathan Whitehorn if (is_inputmenu) { 1474c8945a0SNathan Whitehorn wattrset(win, (selected != Unselected) ? item_selected_attr : item_attr); 1484c8945a0SNathan Whitehorn for (n = my_y - 1; n < my_y + INPUT_ROWS - 1; n++) { 1494c8945a0SNathan Whitehorn wmove(win, n, 0); 1504c8945a0SNathan Whitehorn wprintw(win, "%*s", my_width, " "); 1514c8945a0SNathan Whitehorn } 1524c8945a0SNathan Whitehorn } else { 1534c8945a0SNathan Whitehorn wattrset(win, menubox_attr); 1544c8945a0SNathan Whitehorn wmove(win, my_y, 0); 1554c8945a0SNathan Whitehorn wprintw(win, "%*s", my_width, " "); 1564c8945a0SNathan Whitehorn } 1574c8945a0SNathan Whitehorn 1584c8945a0SNathan Whitehorn print_tag(win, items, choice, selected, is_inputmenu); 1594c8945a0SNathan Whitehorn 1604c8945a0SNathan Whitehorn /* Draw the input field box (only for inputmenu) */ 1614c8945a0SNathan Whitehorn (void) wmove(win, my_y, my_x); 1624c8945a0SNathan Whitehorn if (is_inputmenu) { 1634c8945a0SNathan Whitehorn my_width -= 1; 1644c8945a0SNathan Whitehorn dlg_draw_box(win, my_y - 1, my_x, INPUT_ROWS, my_width - my_x - tag_x, 1654c8945a0SNathan Whitehorn bordchar, 1664c8945a0SNathan Whitehorn bordchar); 1674c8945a0SNathan Whitehorn my_width -= 1; 1684c8945a0SNathan Whitehorn ++my_x; 1694c8945a0SNathan Whitehorn } 1704c8945a0SNathan Whitehorn 1714c8945a0SNathan Whitehorn /* print actual item */ 1724c8945a0SNathan Whitehorn wmove(win, my_y, my_x); 1734c8945a0SNathan Whitehorn wattrset(win, textchar); 1744c8945a0SNathan Whitehorn dlg_print_text(win, items->text, my_width - my_x, &attr); 1754c8945a0SNathan Whitehorn 1764c8945a0SNathan Whitehorn if (selected) { 1774c8945a0SNathan Whitehorn dlg_item_help(items->help); 1784c8945a0SNathan Whitehorn } 1794c8945a0SNathan Whitehorn wattrset(win, save); 1804c8945a0SNathan Whitehorn } 1814c8945a0SNathan Whitehorn 1824c8945a0SNathan Whitehorn /* 1834c8945a0SNathan Whitehorn * Allow the user to edit the text of a menu entry. 1844c8945a0SNathan Whitehorn */ 1854c8945a0SNathan Whitehorn static int 1864c8945a0SNathan Whitehorn input_menu_edit(WINDOW *win, 1874c8945a0SNathan Whitehorn DIALOG_LISTITEM * items, 1884c8945a0SNathan Whitehorn int choice, 1894c8945a0SNathan Whitehorn char **resultp) 1904c8945a0SNathan Whitehorn { 1914c8945a0SNathan Whitehorn chtype save = getattrs(win); 1924c8945a0SNathan Whitehorn char *result; 1934c8945a0SNathan Whitehorn int offset = 0; 1944c8945a0SNathan Whitehorn int key = 0, fkey = 0; 1954c8945a0SNathan Whitehorn int first = TRUE; 1964c8945a0SNathan Whitehorn /* see above */ 1974c8945a0SNathan Whitehorn bool is_inputmenu = TRUE; 1984c8945a0SNathan Whitehorn int y = ItemToRow(choice); 1994c8945a0SNathan Whitehorn int code = TRUE; 2004c8945a0SNathan Whitehorn int max_len = dlg_max_input(MAX((int) strlen(items->text) + 1, MAX_LEN)); 2014c8945a0SNathan Whitehorn 2024c8945a0SNathan Whitehorn result = dlg_malloc(char, (size_t) max_len); 2034c8945a0SNathan Whitehorn assert_ptr(result, "input_menu_edit"); 2044c8945a0SNathan Whitehorn 2054c8945a0SNathan Whitehorn /* original item is used to initialize the input string. */ 2064c8945a0SNathan Whitehorn result[0] = '\0'; 2074c8945a0SNathan Whitehorn strcpy(result, items->text); 2084c8945a0SNathan Whitehorn 2094c8945a0SNathan Whitehorn print_item(win, items, choice, Editing, TRUE); 2104c8945a0SNathan Whitehorn 2114c8945a0SNathan Whitehorn /* taken out of inputbox.c - but somewhat modified */ 2124c8945a0SNathan Whitehorn for (;;) { 2134c8945a0SNathan Whitehorn if (!first) 2144c8945a0SNathan Whitehorn key = dlg_mouse_wgetch(win, &fkey); 2154c8945a0SNathan Whitehorn if (dlg_edit_string(result, &offset, key, fkey, first)) { 2164c8945a0SNathan Whitehorn dlg_show_string(win, result, offset, inputbox_attr, 2174c8945a0SNathan Whitehorn y, item_x + 1, menu_width - item_x - 3, 2184c8945a0SNathan Whitehorn FALSE, first); 2194c8945a0SNathan Whitehorn first = FALSE; 2204c8945a0SNathan Whitehorn } else if (key == ESC || key == TAB) { 2214c8945a0SNathan Whitehorn code = FALSE; 2224c8945a0SNathan Whitehorn break; 2234c8945a0SNathan Whitehorn } else { 2244c8945a0SNathan Whitehorn break; 2254c8945a0SNathan Whitehorn } 2264c8945a0SNathan Whitehorn } 2274c8945a0SNathan Whitehorn print_item(win, items, choice, Selected, TRUE); 2284c8945a0SNathan Whitehorn wattrset(win, save); 2294c8945a0SNathan Whitehorn 2304c8945a0SNathan Whitehorn *resultp = result; 2314c8945a0SNathan Whitehorn return code; 2324c8945a0SNathan Whitehorn } 2334c8945a0SNathan Whitehorn 2344c8945a0SNathan Whitehorn static int 2354c8945a0SNathan Whitehorn handle_button(int code, DIALOG_LISTITEM * items, int choice) 2364c8945a0SNathan Whitehorn { 2374c8945a0SNathan Whitehorn switch (code) { 2384c8945a0SNathan Whitehorn case DLG_EXIT_OK: /* FALLTHRU */ 2394c8945a0SNathan Whitehorn case DLG_EXIT_EXTRA: 2404c8945a0SNathan Whitehorn dlg_add_string(items[choice].name); 2414c8945a0SNathan Whitehorn break; 2424c8945a0SNathan Whitehorn case DLG_EXIT_HELP: 2434c8945a0SNathan Whitehorn dlg_add_result("HELP "); 2444c8945a0SNathan Whitehorn if (USE_ITEM_HELP(items[choice].help)) { 2454c8945a0SNathan Whitehorn dlg_add_string(items[choice].help); 2464c8945a0SNathan Whitehorn code = DLG_EXIT_ITEM_HELP; 2474c8945a0SNathan Whitehorn } else { 2484c8945a0SNathan Whitehorn dlg_add_string(items[choice].name); 2494c8945a0SNathan Whitehorn } 2504c8945a0SNathan Whitehorn break; 2514c8945a0SNathan Whitehorn } 2524c8945a0SNathan Whitehorn return code; 2534c8945a0SNathan Whitehorn } 2544c8945a0SNathan Whitehorn 2554c8945a0SNathan Whitehorn static int 2564c8945a0SNathan Whitehorn dlg_renamed_menutext(DIALOG_LISTITEM * items, int current, char *newtext) 2574c8945a0SNathan Whitehorn { 2584c8945a0SNathan Whitehorn if (dialog_vars.input_result) 2594c8945a0SNathan Whitehorn dialog_vars.input_result[0] = '\0'; 2604c8945a0SNathan Whitehorn dlg_add_result("RENAMED "); 2614c8945a0SNathan Whitehorn dlg_add_string(items[current].name); 2624c8945a0SNathan Whitehorn dlg_add_result(" "); 2634c8945a0SNathan Whitehorn dlg_add_string(newtext); 2644c8945a0SNathan Whitehorn return DLG_EXIT_EXTRA; 2654c8945a0SNathan Whitehorn } 2664c8945a0SNathan Whitehorn 2674c8945a0SNathan Whitehorn static int 2684c8945a0SNathan Whitehorn dlg_dummy_menutext(DIALOG_LISTITEM * items, int current, char *newtext) 2694c8945a0SNathan Whitehorn { 2704c8945a0SNathan Whitehorn (void) items; 2714c8945a0SNathan Whitehorn (void) current; 2724c8945a0SNathan Whitehorn (void) newtext; 2734c8945a0SNathan Whitehorn return DLG_EXIT_ERROR; 2744c8945a0SNathan Whitehorn } 2754c8945a0SNathan Whitehorn 2764c8945a0SNathan Whitehorn /* 2774c8945a0SNathan Whitehorn * This is an alternate interface to 'menu' which allows the application 2784c8945a0SNathan Whitehorn * to read the list item states back directly without putting them in the 2794c8945a0SNathan Whitehorn * output buffer. 2804c8945a0SNathan Whitehorn */ 2814c8945a0SNathan Whitehorn int 2824c8945a0SNathan Whitehorn dlg_menu(const char *title, 2834c8945a0SNathan Whitehorn const char *cprompt, 2844c8945a0SNathan Whitehorn int height, 2854c8945a0SNathan Whitehorn int width, 2864c8945a0SNathan Whitehorn int menu_height, 2874c8945a0SNathan Whitehorn int item_no, 2884c8945a0SNathan Whitehorn DIALOG_LISTITEM * items, 2894c8945a0SNathan Whitehorn int *current_item, 2904c8945a0SNathan Whitehorn DIALOG_INPUTMENU rename_menutext) 2914c8945a0SNathan Whitehorn { 2924c8945a0SNathan Whitehorn /* *INDENT-OFF* */ 2934c8945a0SNathan Whitehorn static DLG_KEYS_BINDING binding[] = { 2944c8945a0SNathan Whitehorn ENTERKEY_BINDINGS, 2954c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, ' ' ), 2964c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), 2974c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), 2984c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), 2994c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), 3004c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ), 3014c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), 3024c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ), 3034c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ), 3044c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), 3054c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ), 3064c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_FIRST, KEY_HOME ), 3074c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_END ), 3084c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_LL ), 3094c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), 3104c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ), 3114c8945a0SNathan Whitehorn END_KEYS_BINDING 3124c8945a0SNathan Whitehorn }; 3134c8945a0SNathan Whitehorn static DLG_KEYS_BINDING binding2[] = { 3144c8945a0SNathan Whitehorn INPUTSTR_BINDINGS, 3154c8945a0SNathan Whitehorn ENTERKEY_BINDINGS, 3164c8945a0SNathan Whitehorn END_KEYS_BINDING 3174c8945a0SNathan Whitehorn }; 3184c8945a0SNathan Whitehorn /* *INDENT-ON* */ 3194c8945a0SNathan Whitehorn 3204c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 3214c8945a0SNathan Whitehorn int old_height = height; 3224c8945a0SNathan Whitehorn int old_width = width; 3234c8945a0SNathan Whitehorn #endif 3244c8945a0SNathan Whitehorn int i, j, x, y, cur_x, cur_y, box_x, box_y; 3254c8945a0SNathan Whitehorn int key = 0, fkey; 3264c8945a0SNathan Whitehorn int button = dialog_state.visit_items ? -1 : dlg_defaultno_button(); 3274c8945a0SNathan Whitehorn int choice = dlg_default_listitem(items); 3284c8945a0SNathan Whitehorn int result = DLG_EXIT_UNKNOWN; 3294c8945a0SNathan Whitehorn int scrollamt = 0; 3304c8945a0SNathan Whitehorn int max_choice, min_width; 3314c8945a0SNathan Whitehorn int found; 3324c8945a0SNathan Whitehorn int use_height, use_width, name_width, text_width; 3334c8945a0SNathan Whitehorn WINDOW *dialog, *menu; 3344c8945a0SNathan Whitehorn char *prompt = dlg_strclone(cprompt); 3354c8945a0SNathan Whitehorn const char **buttons = dlg_ok_labels(); 3364c8945a0SNathan Whitehorn bool is_inputmenu = (rename_menutext == dlg_renamed_menutext); 3374c8945a0SNathan Whitehorn 3384c8945a0SNathan Whitehorn dlg_does_output(); 3394c8945a0SNathan Whitehorn dlg_tab_correct_str(prompt); 3404c8945a0SNathan Whitehorn 3414c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 3424c8945a0SNathan Whitehorn retry: 3434c8945a0SNathan Whitehorn #endif 3444c8945a0SNathan Whitehorn 3454c8945a0SNathan Whitehorn use_height = menu_height; 3464c8945a0SNathan Whitehorn if (use_height == 0) { 3474c8945a0SNathan Whitehorn min_width = dlg_calc_list_width(item_no, items) + 10; 3484c8945a0SNathan Whitehorn /* calculate height without items (4) */ 3494c8945a0SNathan Whitehorn dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, MAX(26, min_width)); 3504c8945a0SNathan Whitehorn dlg_calc_listh(&height, &use_height, item_no); 3514c8945a0SNathan Whitehorn } else { 3524c8945a0SNathan Whitehorn dlg_auto_size(title, prompt, &height, &width, MIN_HIGH + use_height, 26); 3534c8945a0SNathan Whitehorn } 3544c8945a0SNathan Whitehorn dlg_button_layout(buttons, &width); 3554c8945a0SNathan Whitehorn dlg_print_size(height, width); 3564c8945a0SNathan Whitehorn dlg_ctl_size(height, width); 3574c8945a0SNathan Whitehorn 3584c8945a0SNathan Whitehorn x = dlg_box_x_ordinate(width); 3594c8945a0SNathan Whitehorn y = dlg_box_y_ordinate(height); 3604c8945a0SNathan Whitehorn 3614c8945a0SNathan Whitehorn dialog = dlg_new_window(height, width, y, x); 3624c8945a0SNathan Whitehorn dlg_register_window(dialog, "menubox", binding); 3634c8945a0SNathan Whitehorn dlg_register_buttons(dialog, "menubox", buttons); 3644c8945a0SNathan Whitehorn 3654c8945a0SNathan Whitehorn dlg_mouse_setbase(x, y); 3664c8945a0SNathan Whitehorn 3674c8945a0SNathan Whitehorn dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 3684c8945a0SNathan Whitehorn dlg_draw_bottom_box(dialog); 3694c8945a0SNathan Whitehorn dlg_draw_title(dialog, title); 3704c8945a0SNathan Whitehorn 3714c8945a0SNathan Whitehorn wattrset(dialog, dialog_attr); 3724c8945a0SNathan Whitehorn dlg_print_autowrap(dialog, prompt, height, width); 3734c8945a0SNathan Whitehorn 3744c8945a0SNathan Whitehorn menu_width = width - 6; 3754c8945a0SNathan Whitehorn getyx(dialog, cur_y, cur_x); 3764c8945a0SNathan Whitehorn box_y = cur_y + 1; 3774c8945a0SNathan Whitehorn box_x = (width - menu_width) / 2 - 1; 3784c8945a0SNathan Whitehorn 3794c8945a0SNathan Whitehorn /* 3804c8945a0SNathan Whitehorn * After displaying the prompt, we know how much space we really have. 3814c8945a0SNathan Whitehorn * Limit the list to avoid overwriting the ok-button. 3824c8945a0SNathan Whitehorn */ 3834c8945a0SNathan Whitehorn if (use_height + MIN_HIGH > height - cur_y) 3844c8945a0SNathan Whitehorn use_height = height - MIN_HIGH - cur_y; 3854c8945a0SNathan Whitehorn if (use_height <= 0) 3864c8945a0SNathan Whitehorn use_height = 1; 3874c8945a0SNathan Whitehorn 3884c8945a0SNathan Whitehorn /* Find out maximal number of displayable items at once. */ 3894c8945a0SNathan Whitehorn max_choice = MIN(use_height, 3904c8945a0SNathan Whitehorn RowHeight(item_no)); 3914c8945a0SNathan Whitehorn if (is_inputmenu) 3924c8945a0SNathan Whitehorn max_choice /= INPUT_ROWS; 3934c8945a0SNathan Whitehorn 3944c8945a0SNathan Whitehorn /* create new window for the menu */ 3954c8945a0SNathan Whitehorn menu = dlg_sub_window(dialog, use_height, menu_width, 3964c8945a0SNathan Whitehorn y + box_y + 1, 3974c8945a0SNathan Whitehorn x + box_x + 1); 3984c8945a0SNathan Whitehorn dlg_register_window(menu, "menu", binding2); 3994c8945a0SNathan Whitehorn dlg_register_buttons(menu, "menu", buttons); 4004c8945a0SNathan Whitehorn 4014c8945a0SNathan Whitehorn /* draw a box around the menu items */ 4024c8945a0SNathan Whitehorn dlg_draw_box(dialog, box_y, box_x, use_height + 2, menu_width + 2, 4034c8945a0SNathan Whitehorn menubox_border_attr, menubox_attr); 4044c8945a0SNathan Whitehorn 4054c8945a0SNathan Whitehorn name_width = 0; 4064c8945a0SNathan Whitehorn text_width = 0; 4074c8945a0SNathan Whitehorn 4084c8945a0SNathan Whitehorn /* Find length of longest item to center menu * 4094c8945a0SNathan Whitehorn * only if --menu was given, using --inputmenu * 4104c8945a0SNathan Whitehorn * won't be centered. */ 4114c8945a0SNathan Whitehorn for (i = 0; i < item_no; i++) { 4124c8945a0SNathan Whitehorn name_width = MAX(name_width, dlg_count_columns(items[i].name)); 4134c8945a0SNathan Whitehorn text_width = MAX(text_width, dlg_count_columns(items[i].text)); 4144c8945a0SNathan Whitehorn } 4154c8945a0SNathan Whitehorn 4164c8945a0SNathan Whitehorn /* If the name+text is wider than the list is allowed, then truncate 4174c8945a0SNathan Whitehorn * one or both of them. If the name is no wider than 30% of the list, 4184c8945a0SNathan Whitehorn * leave it intact. 4194c8945a0SNathan Whitehorn * 4204c8945a0SNathan Whitehorn * FIXME: the gutter width and name/list ratio should be configurable. 4214c8945a0SNathan Whitehorn */ 4224c8945a0SNathan Whitehorn use_width = (menu_width - GUTTER); 4234c8945a0SNathan Whitehorn if (text_width + name_width > use_width) { 4244c8945a0SNathan Whitehorn int need = (int) (0.30 * use_width); 4254c8945a0SNathan Whitehorn if (name_width > need) { 4264c8945a0SNathan Whitehorn int want = (int) (use_width 4274c8945a0SNathan Whitehorn * ((double) name_width) 4284c8945a0SNathan Whitehorn / (text_width + name_width)); 4294c8945a0SNathan Whitehorn name_width = (want > need) ? want : need; 4304c8945a0SNathan Whitehorn } 4314c8945a0SNathan Whitehorn text_width = use_width - name_width; 4324c8945a0SNathan Whitehorn } 4334c8945a0SNathan Whitehorn 4344c8945a0SNathan Whitehorn tag_x = (is_inputmenu 4354c8945a0SNathan Whitehorn ? 0 4364c8945a0SNathan Whitehorn : (use_width - text_width - name_width) / 2); 4374c8945a0SNathan Whitehorn item_x = name_width + tag_x + GUTTER; 4384c8945a0SNathan Whitehorn 4394c8945a0SNathan Whitehorn if (choice - scrollamt >= max_choice) { 4404c8945a0SNathan Whitehorn scrollamt = choice - (max_choice - 1); 4414c8945a0SNathan Whitehorn choice = max_choice - 1; 4424c8945a0SNathan Whitehorn } 4434c8945a0SNathan Whitehorn 4444c8945a0SNathan Whitehorn /* Print the menu */ 4454c8945a0SNathan Whitehorn for (i = 0; i < max_choice; i++) { 4464c8945a0SNathan Whitehorn print_item(menu, 4474c8945a0SNathan Whitehorn &items[i + scrollamt], 4484c8945a0SNathan Whitehorn i, 4494c8945a0SNathan Whitehorn (i == choice) ? Selected : Unselected, 4504c8945a0SNathan Whitehorn is_inputmenu); 4514c8945a0SNathan Whitehorn } 4524c8945a0SNathan Whitehorn (void) wnoutrefresh(menu); 4534c8945a0SNathan Whitehorn 4544c8945a0SNathan Whitehorn /* register the new window, along with its borders */ 4554c8945a0SNathan Whitehorn dlg_mouse_mkbigregion(box_y + 1, box_x, use_height + 2, menu_width + 2, 4564c8945a0SNathan Whitehorn KEY_MAX, 1, 1, 1 /* by lines */ ); 4574c8945a0SNathan Whitehorn 4584c8945a0SNathan Whitehorn print_arrows(dialog, box_x, box_y, scrollamt, max_choice, item_no, use_height); 4594c8945a0SNathan Whitehorn 4604c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); 4614c8945a0SNathan Whitehorn 4624c8945a0SNathan Whitehorn while (result == DLG_EXIT_UNKNOWN) { 4634c8945a0SNathan Whitehorn if (button < 0) /* --visit-items */ 4644c8945a0SNathan Whitehorn wmove(dialog, box_y + ItemToRow(choice) + 1, box_x + tag_x + 1); 4654c8945a0SNathan Whitehorn 4664c8945a0SNathan Whitehorn key = dlg_mouse_wgetch(dialog, &fkey); 4674c8945a0SNathan Whitehorn if (dlg_result_key(key, fkey, &result)) 4684c8945a0SNathan Whitehorn break; 4694c8945a0SNathan Whitehorn 4704c8945a0SNathan Whitehorn found = FALSE; 4714c8945a0SNathan Whitehorn if (fkey) { 4724c8945a0SNathan Whitehorn /* 4734c8945a0SNathan Whitehorn * Allow a mouse-click on a box to switch selection to that box. 4744c8945a0SNathan Whitehorn * Handling a button click is a little more complicated, since we 4754c8945a0SNathan Whitehorn * push a KEY_ENTER back onto the input stream so we'll put the 4764c8945a0SNathan Whitehorn * cursor at the right place before handling the "keypress". 4774c8945a0SNathan Whitehorn */ 4784c8945a0SNathan Whitehorn if (key >= DLGK_MOUSE(KEY_MAX)) { 4794c8945a0SNathan Whitehorn key -= DLGK_MOUSE(KEY_MAX); 4804c8945a0SNathan Whitehorn i = RowToItem(key); 4814c8945a0SNathan Whitehorn if (i < max_choice) { 4824c8945a0SNathan Whitehorn found = TRUE; 4834c8945a0SNathan Whitehorn } else { 4844c8945a0SNathan Whitehorn beep(); 4854c8945a0SNathan Whitehorn continue; 4864c8945a0SNathan Whitehorn } 4874c8945a0SNathan Whitehorn } else if (is_DLGK_MOUSE(key) 4884c8945a0SNathan Whitehorn && dlg_ok_buttoncode(key - M_EVENT) >= 0) { 4894c8945a0SNathan Whitehorn button = (key - M_EVENT); 4904c8945a0SNathan Whitehorn ungetch('\n'); 4914c8945a0SNathan Whitehorn continue; 4924c8945a0SNathan Whitehorn } 4934c8945a0SNathan Whitehorn } else { 4944c8945a0SNathan Whitehorn /* 4954c8945a0SNathan Whitehorn * Check if key pressed matches first character of any item tag in 4964c8945a0SNathan Whitehorn * list. If there is more than one match, we will cycle through 4974c8945a0SNathan Whitehorn * each one as the same key is pressed repeatedly. 4984c8945a0SNathan Whitehorn */ 4994c8945a0SNathan Whitehorn if (button < 0 || !dialog_state.visit_items) { 5004c8945a0SNathan Whitehorn for (j = scrollamt + choice + 1; j < item_no; j++) { 5014c8945a0SNathan Whitehorn if (dlg_match_char(dlg_last_getc(), items[j].name)) { 5024c8945a0SNathan Whitehorn found = TRUE; 5034c8945a0SNathan Whitehorn i = j - scrollamt; 5044c8945a0SNathan Whitehorn break; 5054c8945a0SNathan Whitehorn } 5064c8945a0SNathan Whitehorn } 5074c8945a0SNathan Whitehorn if (!found) { 5084c8945a0SNathan Whitehorn for (j = 0; j <= scrollamt + choice; j++) { 5094c8945a0SNathan Whitehorn if (dlg_match_char(dlg_last_getc(), items[j].name)) { 5104c8945a0SNathan Whitehorn found = TRUE; 5114c8945a0SNathan Whitehorn i = j - scrollamt; 5124c8945a0SNathan Whitehorn break; 5134c8945a0SNathan Whitehorn } 5144c8945a0SNathan Whitehorn } 5154c8945a0SNathan Whitehorn } 5164c8945a0SNathan Whitehorn if (found) 5174c8945a0SNathan Whitehorn dlg_flush_getc(); 5184c8945a0SNathan Whitehorn } else if ((j = dlg_char_to_button(key, buttons)) >= 0) { 5194c8945a0SNathan Whitehorn button = j; 5204c8945a0SNathan Whitehorn ungetch('\n'); 5214c8945a0SNathan Whitehorn continue; 5224c8945a0SNathan Whitehorn } 5234c8945a0SNathan Whitehorn 5244c8945a0SNathan Whitehorn /* 5254c8945a0SNathan Whitehorn * A single digit (1-9) positions the selection to that line in the 5264c8945a0SNathan Whitehorn * current screen. 5274c8945a0SNathan Whitehorn */ 5284c8945a0SNathan Whitehorn if (!found 5294c8945a0SNathan Whitehorn && (key <= '9') 5304c8945a0SNathan Whitehorn && (key > '0') 5314c8945a0SNathan Whitehorn && (key - '1' < max_choice)) { 5324c8945a0SNathan Whitehorn found = TRUE; 5334c8945a0SNathan Whitehorn i = key - '1'; 5344c8945a0SNathan Whitehorn } 5354c8945a0SNathan Whitehorn } 5364c8945a0SNathan Whitehorn 5374c8945a0SNathan Whitehorn if (!found && fkey) { 5384c8945a0SNathan Whitehorn found = TRUE; 5394c8945a0SNathan Whitehorn switch (key) { 5404c8945a0SNathan Whitehorn case DLGK_PAGE_FIRST: 5414c8945a0SNathan Whitehorn i = -scrollamt; 5424c8945a0SNathan Whitehorn break; 5434c8945a0SNathan Whitehorn case DLGK_PAGE_LAST: 5444c8945a0SNathan Whitehorn i = item_no - 1 - scrollamt; 5454c8945a0SNathan Whitehorn break; 5464c8945a0SNathan Whitehorn case DLGK_MOUSE(KEY_PPAGE): 5474c8945a0SNathan Whitehorn case DLGK_PAGE_PREV: 5484c8945a0SNathan Whitehorn if (choice) 5494c8945a0SNathan Whitehorn i = 0; 5504c8945a0SNathan Whitehorn else if (scrollamt != 0) 5514c8945a0SNathan Whitehorn i = -MIN(scrollamt, max_choice); 5524c8945a0SNathan Whitehorn else 5534c8945a0SNathan Whitehorn continue; 5544c8945a0SNathan Whitehorn break; 5554c8945a0SNathan Whitehorn case DLGK_MOUSE(KEY_NPAGE): 5564c8945a0SNathan Whitehorn case DLGK_PAGE_NEXT: 5574c8945a0SNathan Whitehorn i = MIN(choice + max_choice, item_no - scrollamt - 1); 5584c8945a0SNathan Whitehorn break; 5594c8945a0SNathan Whitehorn case DLGK_ITEM_PREV: 5604c8945a0SNathan Whitehorn i = choice - 1; 5614c8945a0SNathan Whitehorn if (choice == 0 && scrollamt == 0) 5624c8945a0SNathan Whitehorn continue; 5634c8945a0SNathan Whitehorn break; 5644c8945a0SNathan Whitehorn case DLGK_ITEM_NEXT: 5654c8945a0SNathan Whitehorn i = choice + 1; 5664c8945a0SNathan Whitehorn if (scrollamt + choice >= item_no - 1) 5674c8945a0SNathan Whitehorn continue; 5684c8945a0SNathan Whitehorn break; 5694c8945a0SNathan Whitehorn default: 5704c8945a0SNathan Whitehorn found = FALSE; 5714c8945a0SNathan Whitehorn break; 5724c8945a0SNathan Whitehorn } 5734c8945a0SNathan Whitehorn } 5744c8945a0SNathan Whitehorn 5754c8945a0SNathan Whitehorn if (found) { 5764c8945a0SNathan Whitehorn if (i != choice) { 5774c8945a0SNathan Whitehorn getyx(dialog, cur_y, cur_x); 5784c8945a0SNathan Whitehorn if (i < 0 || i >= max_choice) { 5794c8945a0SNathan Whitehorn #if defined(NCURSES_VERSION_MAJOR) && NCURSES_VERSION_MAJOR < 5 5804c8945a0SNathan Whitehorn /* 5814c8945a0SNathan Whitehorn * Using wscrl to assist ncurses scrolling is not needed 5824c8945a0SNathan Whitehorn * in version 5.x 5834c8945a0SNathan Whitehorn */ 5844c8945a0SNathan Whitehorn if (i == -1) { 5854c8945a0SNathan Whitehorn if (use_height > 1) { 5864c8945a0SNathan Whitehorn /* De-highlight current first item */ 5874c8945a0SNathan Whitehorn print_item(menu, 5884c8945a0SNathan Whitehorn &items[scrollamt], 5894c8945a0SNathan Whitehorn 0, Unselected, is_inputmenu); 5904c8945a0SNathan Whitehorn scrollok(menu, TRUE); 5914c8945a0SNathan Whitehorn wscrl(menu, -RowHeight(1)); 5924c8945a0SNathan Whitehorn scrollok(menu, FALSE); 5934c8945a0SNathan Whitehorn } 5944c8945a0SNathan Whitehorn scrollamt--; 5954c8945a0SNathan Whitehorn print_item(menu, 5964c8945a0SNathan Whitehorn &items[scrollamt], 5974c8945a0SNathan Whitehorn 0, Selected, is_inputmenu); 5984c8945a0SNathan Whitehorn } else if (i == max_choice) { 5994c8945a0SNathan Whitehorn if (use_height > 1) { 6004c8945a0SNathan Whitehorn /* De-highlight current last item before scrolling up */ 6014c8945a0SNathan Whitehorn print_item(menu, 6024c8945a0SNathan Whitehorn &items[scrollamt + max_choice - 1], 6034c8945a0SNathan Whitehorn max_choice - 1, 6044c8945a0SNathan Whitehorn Unselected, 6054c8945a0SNathan Whitehorn is_inputmenu); 6064c8945a0SNathan Whitehorn scrollok(menu, TRUE); 6074c8945a0SNathan Whitehorn wscrl(menu, RowHeight(1)); 6084c8945a0SNathan Whitehorn scrollok(menu, FALSE); 6094c8945a0SNathan Whitehorn } 6104c8945a0SNathan Whitehorn scrollamt++; 6114c8945a0SNathan Whitehorn print_item(menu, 6124c8945a0SNathan Whitehorn &items[scrollamt + max_choice - 1], 6134c8945a0SNathan Whitehorn max_choice - 1, TRUE, 6144c8945a0SNathan Whitehorn is_inputmenu); 6154c8945a0SNathan Whitehorn } else 6164c8945a0SNathan Whitehorn #endif 6174c8945a0SNathan Whitehorn { 6184c8945a0SNathan Whitehorn if (i < 0) { 6194c8945a0SNathan Whitehorn scrollamt += i; 6204c8945a0SNathan Whitehorn choice = 0; 6214c8945a0SNathan Whitehorn } else { 6224c8945a0SNathan Whitehorn choice = max_choice - 1; 6234c8945a0SNathan Whitehorn scrollamt += (i - max_choice + 1); 6244c8945a0SNathan Whitehorn } 6254c8945a0SNathan Whitehorn for (i = 0; i < max_choice; i++) { 6264c8945a0SNathan Whitehorn print_item(menu, 6274c8945a0SNathan Whitehorn &items[scrollamt + i], 6284c8945a0SNathan Whitehorn i, 6294c8945a0SNathan Whitehorn (i == choice) ? Selected : Unselected, 6304c8945a0SNathan Whitehorn is_inputmenu); 6314c8945a0SNathan Whitehorn } 6324c8945a0SNathan Whitehorn } 6334c8945a0SNathan Whitehorn /* Clean bottom lines */ 6344c8945a0SNathan Whitehorn if (is_inputmenu) { 6354c8945a0SNathan Whitehorn int spare_lines, x_count; 6364c8945a0SNathan Whitehorn spare_lines = use_height % INPUT_ROWS; 6374c8945a0SNathan Whitehorn wattrset(menu, menubox_attr); 6384c8945a0SNathan Whitehorn for (; spare_lines; spare_lines--) { 6394c8945a0SNathan Whitehorn wmove(menu, use_height - spare_lines, 0); 6404c8945a0SNathan Whitehorn for (x_count = 0; x_count < menu_width; 6414c8945a0SNathan Whitehorn x_count++) { 6424c8945a0SNathan Whitehorn waddch(menu, ' '); 6434c8945a0SNathan Whitehorn } 6444c8945a0SNathan Whitehorn } 6454c8945a0SNathan Whitehorn } 6464c8945a0SNathan Whitehorn (void) wnoutrefresh(menu); 6474c8945a0SNathan Whitehorn print_arrows(dialog, 6484c8945a0SNathan Whitehorn box_x, box_y, 6494c8945a0SNathan Whitehorn scrollamt, max_choice, item_no, use_height); 6504c8945a0SNathan Whitehorn } else { 6514c8945a0SNathan Whitehorn /* De-highlight current item */ 6524c8945a0SNathan Whitehorn print_item(menu, 6534c8945a0SNathan Whitehorn &items[scrollamt + choice], 6544c8945a0SNathan Whitehorn choice, 6554c8945a0SNathan Whitehorn Unselected, 6564c8945a0SNathan Whitehorn is_inputmenu); 6574c8945a0SNathan Whitehorn /* Highlight new item */ 6584c8945a0SNathan Whitehorn choice = i; 6594c8945a0SNathan Whitehorn print_item(menu, 6604c8945a0SNathan Whitehorn &items[scrollamt + choice], 6614c8945a0SNathan Whitehorn choice, 6624c8945a0SNathan Whitehorn Selected, 6634c8945a0SNathan Whitehorn is_inputmenu); 6644c8945a0SNathan Whitehorn (void) wnoutrefresh(menu); 6654c8945a0SNathan Whitehorn print_arrows(dialog, 6664c8945a0SNathan Whitehorn box_x, box_y, 6674c8945a0SNathan Whitehorn scrollamt, max_choice, item_no, use_height); 6684c8945a0SNathan Whitehorn (void) wmove(dialog, cur_y, cur_x); 6694c8945a0SNathan Whitehorn wrefresh(dialog); 6704c8945a0SNathan Whitehorn } 6714c8945a0SNathan Whitehorn } 6724c8945a0SNathan Whitehorn continue; /* wait for another key press */ 6734c8945a0SNathan Whitehorn } 6744c8945a0SNathan Whitehorn 6754c8945a0SNathan Whitehorn if (fkey) { 6764c8945a0SNathan Whitehorn switch (key) { 6774c8945a0SNathan Whitehorn case DLGK_FIELD_PREV: 6784c8945a0SNathan Whitehorn button = dlg_prev_button(buttons, button); 6794c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button, 6804c8945a0SNathan Whitehorn FALSE, width); 6814c8945a0SNathan Whitehorn break; 6824c8945a0SNathan Whitehorn case DLGK_FIELD_NEXT: 6834c8945a0SNathan Whitehorn button = dlg_next_button(buttons, button); 6844c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button, 6854c8945a0SNathan Whitehorn FALSE, width); 6864c8945a0SNathan Whitehorn break; 6874c8945a0SNathan Whitehorn case DLGK_ENTER: 6884c8945a0SNathan Whitehorn result = dlg_ok_buttoncode(button); 6894c8945a0SNathan Whitehorn 6904c8945a0SNathan Whitehorn /* 6914c8945a0SNathan Whitehorn * If dlg_menu() is called from dialog_menu(), we want to 6924c8945a0SNathan Whitehorn * capture the results into dialog_vars.input_result, but not 6934c8945a0SNathan Whitehorn * if dlg_menu() is called directly from an application. We 6944c8945a0SNathan Whitehorn * can check this by testing if rename_menutext is the function 6954c8945a0SNathan Whitehorn * pointer owned by dialog_menu(). It would be nicer to have 6964c8945a0SNathan Whitehorn * this logic inside dialog_menu(), but that cannot be done 6974c8945a0SNathan Whitehorn * since we would lose compatibility for the results reported 6984c8945a0SNathan Whitehorn * after input_menu_edit(). 6994c8945a0SNathan Whitehorn */ 7004c8945a0SNathan Whitehorn if (result == DLG_EXIT_ERROR) { 7014c8945a0SNathan Whitehorn result = DLG_EXIT_UNKNOWN; 7024c8945a0SNathan Whitehorn } else if (is_inputmenu 7034c8945a0SNathan Whitehorn || rename_menutext == dlg_dummy_menutext) { 7044c8945a0SNathan Whitehorn result = handle_button(result, 7054c8945a0SNathan Whitehorn items, 7064c8945a0SNathan Whitehorn scrollamt + choice); 7074c8945a0SNathan Whitehorn } 7084c8945a0SNathan Whitehorn 7094c8945a0SNathan Whitehorn /* 7104c8945a0SNathan Whitehorn * If we have a rename_menutext function, interpret the Extra 7114c8945a0SNathan Whitehorn * button as a request to rename the menu's text. If that 7124c8945a0SNathan Whitehorn * function doesn't return "Unknown", we will exit from this 7134c8945a0SNathan Whitehorn * function. Usually that is done for dialog_menu(), so the 7144c8945a0SNathan Whitehorn * shell script can use the updated value. If it does return 7154c8945a0SNathan Whitehorn * "Unknown", update the list item only. A direct caller of 7164c8945a0SNathan Whitehorn * dlg_menu() can free the renamed value - we cannot. 7174c8945a0SNathan Whitehorn */ 7184c8945a0SNathan Whitehorn if (is_inputmenu && result == DLG_EXIT_EXTRA) { 7194c8945a0SNathan Whitehorn char *tmp; 7204c8945a0SNathan Whitehorn 7214c8945a0SNathan Whitehorn if (input_menu_edit(menu, 7224c8945a0SNathan Whitehorn &items[scrollamt + choice], 7234c8945a0SNathan Whitehorn choice, 7244c8945a0SNathan Whitehorn &tmp)) { 7254c8945a0SNathan Whitehorn result = rename_menutext(items, scrollamt + choice, tmp); 7264c8945a0SNathan Whitehorn if (result == DLG_EXIT_UNKNOWN) { 7274c8945a0SNathan Whitehorn items[scrollamt + choice].text = tmp; 7284c8945a0SNathan Whitehorn } else { 7294c8945a0SNathan Whitehorn free(tmp); 7304c8945a0SNathan Whitehorn } 7314c8945a0SNathan Whitehorn } else { 7324c8945a0SNathan Whitehorn result = DLG_EXIT_UNKNOWN; 7334c8945a0SNathan Whitehorn print_item(menu, 7344c8945a0SNathan Whitehorn &items[scrollamt + choice], 7354c8945a0SNathan Whitehorn choice, 7364c8945a0SNathan Whitehorn Selected, 7374c8945a0SNathan Whitehorn is_inputmenu); 7384c8945a0SNathan Whitehorn (void) wnoutrefresh(menu); 7394c8945a0SNathan Whitehorn free(tmp); 7404c8945a0SNathan Whitehorn } 7414c8945a0SNathan Whitehorn 7424c8945a0SNathan Whitehorn if (result == DLG_EXIT_UNKNOWN) { 7434c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, 7444c8945a0SNathan Whitehorn buttons, button, FALSE, width); 7454c8945a0SNathan Whitehorn } 7464c8945a0SNathan Whitehorn } 7474c8945a0SNathan Whitehorn break; 7484c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 7494c8945a0SNathan Whitehorn case KEY_RESIZE: 7504c8945a0SNathan Whitehorn /* reset data */ 7514c8945a0SNathan Whitehorn height = old_height; 7524c8945a0SNathan Whitehorn width = old_width; 7534c8945a0SNathan Whitehorn /* repaint */ 7544c8945a0SNathan Whitehorn dlg_clear(); 7554c8945a0SNathan Whitehorn dlg_del_window(dialog); 7564c8945a0SNathan Whitehorn refresh(); 7574c8945a0SNathan Whitehorn dlg_mouse_free_regions(); 7584c8945a0SNathan Whitehorn goto retry; 7594c8945a0SNathan Whitehorn #endif 7604c8945a0SNathan Whitehorn default: 7614c8945a0SNathan Whitehorn flash(); 7624c8945a0SNathan Whitehorn break; 7634c8945a0SNathan Whitehorn } 7644c8945a0SNathan Whitehorn } 7654c8945a0SNathan Whitehorn } 7664c8945a0SNathan Whitehorn 7674c8945a0SNathan Whitehorn dlg_mouse_free_regions(); 7684c8945a0SNathan Whitehorn dlg_unregister_window(menu); 7694c8945a0SNathan Whitehorn dlg_del_window(dialog); 7704c8945a0SNathan Whitehorn free(prompt); 7714c8945a0SNathan Whitehorn 7724c8945a0SNathan Whitehorn *current_item = scrollamt + choice; 7734c8945a0SNathan Whitehorn return result; 7744c8945a0SNathan Whitehorn } 7754c8945a0SNathan Whitehorn 7764c8945a0SNathan Whitehorn /* 7774c8945a0SNathan Whitehorn * Display a menu for choosing among a number of options 7784c8945a0SNathan Whitehorn */ 7794c8945a0SNathan Whitehorn int 7804c8945a0SNathan Whitehorn dialog_menu(const char *title, 7814c8945a0SNathan Whitehorn const char *cprompt, 7824c8945a0SNathan Whitehorn int height, 7834c8945a0SNathan Whitehorn int width, 7844c8945a0SNathan Whitehorn int menu_height, 7854c8945a0SNathan Whitehorn int item_no, 7864c8945a0SNathan Whitehorn char **items) 7874c8945a0SNathan Whitehorn { 7884c8945a0SNathan Whitehorn int result; 7894c8945a0SNathan Whitehorn int choice; 7904c8945a0SNathan Whitehorn int i; 7914c8945a0SNathan Whitehorn DIALOG_LISTITEM *listitems; 7924c8945a0SNathan Whitehorn 7934c8945a0SNathan Whitehorn listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1); 7944c8945a0SNathan Whitehorn assert_ptr(listitems, "dialog_menu"); 7954c8945a0SNathan Whitehorn 7964c8945a0SNathan Whitehorn for (i = 0; i < item_no; ++i) { 7974c8945a0SNathan Whitehorn listitems[i].name = ItemName(i); 7984c8945a0SNathan Whitehorn listitems[i].text = ItemText(i); 7994c8945a0SNathan Whitehorn listitems[i].help = ((dialog_vars.item_help) 8004c8945a0SNathan Whitehorn ? ItemHelp(i) 8014c8945a0SNathan Whitehorn : dlg_strempty()); 8024c8945a0SNathan Whitehorn } 8034c8945a0SNathan Whitehorn dlg_align_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no); 8044c8945a0SNathan Whitehorn 8054c8945a0SNathan Whitehorn result = dlg_menu(title, 8064c8945a0SNathan Whitehorn cprompt, 8074c8945a0SNathan Whitehorn height, 8084c8945a0SNathan Whitehorn width, 8094c8945a0SNathan Whitehorn menu_height, 8104c8945a0SNathan Whitehorn item_no, 8114c8945a0SNathan Whitehorn listitems, 8124c8945a0SNathan Whitehorn &choice, 8134c8945a0SNathan Whitehorn dialog_vars.input_menu ? dlg_renamed_menutext : dlg_dummy_menutext); 8144c8945a0SNathan Whitehorn 8154c8945a0SNathan Whitehorn dlg_free_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no); 8164c8945a0SNathan Whitehorn free(listitems); 8174c8945a0SNathan Whitehorn return result; 8184c8945a0SNathan Whitehorn } 819