14c8945a0SNathan Whitehorn /*
2*a96ef450SBaptiste Daroussin * $Id: menubox.c,v 1.171 2020/11/23 21:03:11 tom Exp $
34c8945a0SNathan Whitehorn *
44c8945a0SNathan Whitehorn * menubox.c -- implements the menu box
54c8945a0SNathan Whitehorn *
6*a96ef450SBaptiste Daroussin * Copyright 2000-2019,2020 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
27*a96ef450SBaptiste Daroussin #include <dlg_internals.h>
284c8945a0SNathan Whitehorn #include <dlg_keys.h>
294c8945a0SNathan Whitehorn
304c8945a0SNathan Whitehorn typedef enum {
314c8945a0SNathan Whitehorn Unselected = 0,
324c8945a0SNathan Whitehorn Selected,
334c8945a0SNathan Whitehorn Editing
344c8945a0SNathan Whitehorn } Mode;
354c8945a0SNathan Whitehorn
362a3e3873SBaptiste Daroussin typedef struct {
372a3e3873SBaptiste Daroussin /* the outer-window */
382a3e3873SBaptiste Daroussin WINDOW *dialog;
392a3e3873SBaptiste Daroussin int box_y;
402a3e3873SBaptiste Daroussin int box_x;
412a3e3873SBaptiste Daroussin int tag_x;
422a3e3873SBaptiste Daroussin int item_x;
432a3e3873SBaptiste Daroussin int menu_height;
442a3e3873SBaptiste Daroussin int menu_width;
452a3e3873SBaptiste Daroussin /* the inner-window */
462a3e3873SBaptiste Daroussin WINDOW *menu;
472a3e3873SBaptiste Daroussin DIALOG_LISTITEM *items;
482a3e3873SBaptiste Daroussin int item_no;
492a3e3873SBaptiste Daroussin } ALL_DATA;
502a3e3873SBaptiste Daroussin
514c8945a0SNathan Whitehorn #define MIN_HIGH (1 + (5 * MARGIN))
524c8945a0SNathan Whitehorn
534c8945a0SNathan Whitehorn #define INPUT_ROWS 3 /* rows per inputmenu entry */
544c8945a0SNathan Whitehorn
554c8945a0SNathan Whitehorn #define RowHeight(i) (is_inputmenu ? ((i) * INPUT_ROWS) : ((i) * 1))
564c8945a0SNathan Whitehorn #define ItemToRow(i) (is_inputmenu ? ((i) * INPUT_ROWS + 1) : (i))
574c8945a0SNathan Whitehorn #define RowToItem(i) (is_inputmenu ? ((i) / INPUT_ROWS + 0) : (i))
584c8945a0SNathan Whitehorn
594c8945a0SNathan Whitehorn /*
604c8945a0SNathan Whitehorn * Print menu item
614c8945a0SNathan Whitehorn */
624c8945a0SNathan Whitehorn static void
print_item(ALL_DATA * data,WINDOW * win,DIALOG_LISTITEM * item,int choice,Mode selected,bool is_inputmenu)632a3e3873SBaptiste Daroussin print_item(ALL_DATA * data,
642a3e3873SBaptiste Daroussin WINDOW *win,
652a3e3873SBaptiste Daroussin DIALOG_LISTITEM * item,
664c8945a0SNathan Whitehorn int choice,
674c8945a0SNathan Whitehorn Mode selected,
684c8945a0SNathan Whitehorn bool is_inputmenu)
694c8945a0SNathan Whitehorn {
707a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win);
712a3e3873SBaptiste Daroussin int climit = (data->item_x - data->tag_x - GUTTER);
722a3e3873SBaptiste Daroussin int my_width = data->menu_width;
732a3e3873SBaptiste Daroussin int my_x = data->item_x;
744c8945a0SNathan Whitehorn int my_y = ItemToRow(choice);
752a3e3873SBaptiste Daroussin bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
762a3e3873SBaptiste Daroussin bool first = TRUE;
774c8945a0SNathan Whitehorn chtype bordchar;
782a3e3873SBaptiste Daroussin const char *show = (dialog_vars.no_items
792a3e3873SBaptiste Daroussin ? item->name
802a3e3873SBaptiste Daroussin : item->text);
814c8945a0SNathan Whitehorn
824c8945a0SNathan Whitehorn switch (selected) {
834c8945a0SNathan Whitehorn default:
844c8945a0SNathan Whitehorn case Unselected:
854c8945a0SNathan Whitehorn bordchar = item_attr;
864c8945a0SNathan Whitehorn break;
874c8945a0SNathan Whitehorn case Selected:
884c8945a0SNathan Whitehorn bordchar = item_selected_attr;
894c8945a0SNathan Whitehorn break;
904c8945a0SNathan Whitehorn case Editing:
914c8945a0SNathan Whitehorn bordchar = dialog_attr;
924c8945a0SNathan Whitehorn break;
934c8945a0SNathan Whitehorn }
944c8945a0SNathan Whitehorn
954c8945a0SNathan Whitehorn /* Clear 'residue' of last item and mark current current item */
964c8945a0SNathan Whitehorn if (is_inputmenu) {
97*a96ef450SBaptiste Daroussin int n;
98*a96ef450SBaptiste Daroussin
99f4f33ea0SBaptiste Daroussin dlg_attrset(win, (selected != Unselected) ? item_selected_attr : item_attr);
1004c8945a0SNathan Whitehorn for (n = my_y - 1; n < my_y + INPUT_ROWS - 1; n++) {
1014c8945a0SNathan Whitehorn wmove(win, n, 0);
1024c8945a0SNathan Whitehorn wprintw(win, "%*s", my_width, " ");
1034c8945a0SNathan Whitehorn }
1044c8945a0SNathan Whitehorn } else {
105f4f33ea0SBaptiste Daroussin dlg_attrset(win, menubox_attr);
1064c8945a0SNathan Whitehorn wmove(win, my_y, 0);
1074c8945a0SNathan Whitehorn wprintw(win, "%*s", my_width, " ");
1084c8945a0SNathan Whitehorn }
1094c8945a0SNathan Whitehorn
1102a3e3873SBaptiste Daroussin /* highlight first char of the tag to be special */
1112a3e3873SBaptiste Daroussin if (both) {
1122a3e3873SBaptiste Daroussin (void) wmove(win, my_y, data->tag_x);
1132a3e3873SBaptiste Daroussin dlg_print_listitem(win, item->name, climit, first, selected);
1142a3e3873SBaptiste Daroussin first = FALSE;
1152a3e3873SBaptiste Daroussin }
1164c8945a0SNathan Whitehorn
1174c8945a0SNathan Whitehorn /* Draw the input field box (only for inputmenu) */
1184c8945a0SNathan Whitehorn (void) wmove(win, my_y, my_x);
1194c8945a0SNathan Whitehorn if (is_inputmenu) {
1204c8945a0SNathan Whitehorn my_width -= 1;
1212a3e3873SBaptiste Daroussin dlg_draw_box(win, my_y - 1, my_x, INPUT_ROWS, my_width - my_x - data->tag_x,
1224c8945a0SNathan Whitehorn bordchar,
1234c8945a0SNathan Whitehorn bordchar);
1244c8945a0SNathan Whitehorn my_width -= 1;
1254c8945a0SNathan Whitehorn ++my_x;
1264c8945a0SNathan Whitehorn }
1274c8945a0SNathan Whitehorn
1284c8945a0SNathan Whitehorn /* print actual item */
1294c8945a0SNathan Whitehorn wmove(win, my_y, my_x);
1302a3e3873SBaptiste Daroussin dlg_print_listitem(win, show, my_width - my_x, first, selected);
1314c8945a0SNathan Whitehorn
1324c8945a0SNathan Whitehorn if (selected) {
1332a3e3873SBaptiste Daroussin dlg_item_help(item->help);
1344c8945a0SNathan Whitehorn }
135f4f33ea0SBaptiste Daroussin dlg_attrset(win, save);
1364c8945a0SNathan Whitehorn }
1374c8945a0SNathan Whitehorn
1384c8945a0SNathan Whitehorn /*
1394c8945a0SNathan Whitehorn * Allow the user to edit the text of a menu entry.
1404c8945a0SNathan Whitehorn */
1414c8945a0SNathan Whitehorn static int
input_menu_edit(ALL_DATA * data,DIALOG_LISTITEM * items,int choice,char ** resultp)1422a3e3873SBaptiste Daroussin input_menu_edit(ALL_DATA * data,
1434c8945a0SNathan Whitehorn DIALOG_LISTITEM * items,
1444c8945a0SNathan Whitehorn int choice,
1454c8945a0SNathan Whitehorn char **resultp)
1464c8945a0SNathan Whitehorn {
1472a3e3873SBaptiste Daroussin chtype save = dlg_get_attrs(data->menu);
1484c8945a0SNathan Whitehorn char *result;
1494c8945a0SNathan Whitehorn int offset = 0;
1504c8945a0SNathan Whitehorn int key = 0, fkey = 0;
151f4f33ea0SBaptiste Daroussin bool first = TRUE;
1524c8945a0SNathan Whitehorn /* see above */
1534c8945a0SNathan Whitehorn bool is_inputmenu = TRUE;
1544c8945a0SNathan Whitehorn int y = ItemToRow(choice);
1554c8945a0SNathan Whitehorn int code = TRUE;
1564c8945a0SNathan Whitehorn int max_len = dlg_max_input(MAX((int) strlen(items->text) + 1, MAX_LEN));
1574c8945a0SNathan Whitehorn
1584c8945a0SNathan Whitehorn result = dlg_malloc(char, (size_t) max_len);
1594c8945a0SNathan Whitehorn assert_ptr(result, "input_menu_edit");
1604c8945a0SNathan Whitehorn
1614c8945a0SNathan Whitehorn /* original item is used to initialize the input string. */
1624c8945a0SNathan Whitehorn result[0] = '\0';
1634c8945a0SNathan Whitehorn strcpy(result, items->text);
1644c8945a0SNathan Whitehorn
1652a3e3873SBaptiste Daroussin print_item(data, data->menu, items, choice, Editing, TRUE);
1664c8945a0SNathan Whitehorn
1674c8945a0SNathan Whitehorn /* taken out of inputbox.c - but somewhat modified */
1684c8945a0SNathan Whitehorn for (;;) {
169*a96ef450SBaptiste Daroussin if (!first) {
170*a96ef450SBaptiste Daroussin int check = DLG_EXIT_UNKNOWN;
1712a3e3873SBaptiste Daroussin key = dlg_mouse_wgetch(data->menu, &fkey);
172*a96ef450SBaptiste Daroussin if (dlg_result_key(key, fkey, &check)) {
173*a96ef450SBaptiste Daroussin if (check == DLG_EXIT_CANCEL) {
174*a96ef450SBaptiste Daroussin code = FALSE;
175*a96ef450SBaptiste Daroussin break;
176*a96ef450SBaptiste Daroussin } else {
177*a96ef450SBaptiste Daroussin flash();
178*a96ef450SBaptiste Daroussin }
179*a96ef450SBaptiste Daroussin }
180*a96ef450SBaptiste Daroussin }
1814c8945a0SNathan Whitehorn if (dlg_edit_string(result, &offset, key, fkey, first)) {
1822a3e3873SBaptiste Daroussin dlg_show_string(data->menu, result, offset, inputbox_attr,
1832a3e3873SBaptiste Daroussin y,
1842a3e3873SBaptiste Daroussin data->item_x + 1,
1852a3e3873SBaptiste Daroussin data->menu_width - data->item_x - 3,
1864c8945a0SNathan Whitehorn FALSE, first);
1874c8945a0SNathan Whitehorn first = FALSE;
1884c8945a0SNathan Whitehorn } else if (key == ESC || key == TAB) {
1894c8945a0SNathan Whitehorn code = FALSE;
1904c8945a0SNathan Whitehorn break;
1914c8945a0SNathan Whitehorn } else {
1924c8945a0SNathan Whitehorn break;
1934c8945a0SNathan Whitehorn }
1944c8945a0SNathan Whitehorn }
1952a3e3873SBaptiste Daroussin print_item(data, data->menu, items, choice, Selected, TRUE);
196f4f33ea0SBaptiste Daroussin dlg_attrset(data->menu, save);
1974c8945a0SNathan Whitehorn
1984c8945a0SNathan Whitehorn *resultp = result;
1994c8945a0SNathan Whitehorn return code;
2004c8945a0SNathan Whitehorn }
2014c8945a0SNathan Whitehorn
2024c8945a0SNathan Whitehorn static int
handle_button(int code,DIALOG_LISTITEM * items,int choice)2034c8945a0SNathan Whitehorn handle_button(int code, DIALOG_LISTITEM * items, int choice)
2044c8945a0SNathan Whitehorn {
205febdb468SDevin Teske char *help_result;
206febdb468SDevin Teske
2074c8945a0SNathan Whitehorn switch (code) {
2084c8945a0SNathan Whitehorn case DLG_EXIT_OK: /* FALLTHRU */
2094c8945a0SNathan Whitehorn case DLG_EXIT_EXTRA:
2104c8945a0SNathan Whitehorn dlg_add_string(items[choice].name);
2114c8945a0SNathan Whitehorn break;
2124c8945a0SNathan Whitehorn case DLG_EXIT_HELP:
213febdb468SDevin Teske dlg_add_help_listitem(&code, &help_result, &items[choice]);
214febdb468SDevin Teske dlg_add_string(help_result);
2154c8945a0SNathan Whitehorn break;
2164c8945a0SNathan Whitehorn }
217*a96ef450SBaptiste Daroussin AddLastKey();
2184c8945a0SNathan Whitehorn return code;
2194c8945a0SNathan Whitehorn }
2204c8945a0SNathan Whitehorn
2212a3e3873SBaptiste Daroussin int
dlg_renamed_menutext(DIALOG_LISTITEM * items,int current,char * newtext)2224c8945a0SNathan Whitehorn dlg_renamed_menutext(DIALOG_LISTITEM * items, int current, char *newtext)
2234c8945a0SNathan Whitehorn {
2244c8945a0SNathan Whitehorn if (dialog_vars.input_result)
2254c8945a0SNathan Whitehorn dialog_vars.input_result[0] = '\0';
2264c8945a0SNathan Whitehorn dlg_add_result("RENAMED ");
2274c8945a0SNathan Whitehorn dlg_add_string(items[current].name);
2284c8945a0SNathan Whitehorn dlg_add_result(" ");
2294c8945a0SNathan Whitehorn dlg_add_string(newtext);
230*a96ef450SBaptiste Daroussin AddLastKey();
2314c8945a0SNathan Whitehorn return DLG_EXIT_EXTRA;
2324c8945a0SNathan Whitehorn }
2334c8945a0SNathan Whitehorn
2342a3e3873SBaptiste Daroussin int
dlg_dummy_menutext(DIALOG_LISTITEM * items,int current,char * newtext)2354c8945a0SNathan Whitehorn dlg_dummy_menutext(DIALOG_LISTITEM * items, int current, char *newtext)
2364c8945a0SNathan Whitehorn {
2374c8945a0SNathan Whitehorn (void) items;
2384c8945a0SNathan Whitehorn (void) current;
2394c8945a0SNathan Whitehorn (void) newtext;
2404c8945a0SNathan Whitehorn return DLG_EXIT_ERROR;
2414c8945a0SNathan Whitehorn }
2424c8945a0SNathan Whitehorn
2432a3e3873SBaptiste Daroussin static void
print_menu(ALL_DATA * data,int choice,int scrollamt,int max_choice,bool is_inputmenu)2442a3e3873SBaptiste Daroussin print_menu(ALL_DATA * data, int choice, int scrollamt, int max_choice, bool is_inputmenu)
2452a3e3873SBaptiste Daroussin {
2462a3e3873SBaptiste Daroussin int i;
2472a3e3873SBaptiste Daroussin
2482a3e3873SBaptiste Daroussin for (i = 0; i < max_choice; i++) {
2492a3e3873SBaptiste Daroussin print_item(data,
2502a3e3873SBaptiste Daroussin data->menu,
2512a3e3873SBaptiste Daroussin &data->items[i + scrollamt],
2522a3e3873SBaptiste Daroussin i,
2532a3e3873SBaptiste Daroussin (i == choice) ? Selected : Unselected,
2542a3e3873SBaptiste Daroussin is_inputmenu);
2552a3e3873SBaptiste Daroussin }
2562a3e3873SBaptiste Daroussin
2572a3e3873SBaptiste Daroussin /* Clean bottom lines */
2582a3e3873SBaptiste Daroussin if (is_inputmenu) {
2592a3e3873SBaptiste Daroussin int spare_lines, x_count;
2602a3e3873SBaptiste Daroussin spare_lines = data->menu_height % INPUT_ROWS;
261f4f33ea0SBaptiste Daroussin dlg_attrset(data->menu, menubox_attr);
2622a3e3873SBaptiste Daroussin for (; spare_lines; spare_lines--) {
2632a3e3873SBaptiste Daroussin wmove(data->menu, data->menu_height - spare_lines, 0);
2642a3e3873SBaptiste Daroussin for (x_count = 0; x_count < data->menu_width;
2652a3e3873SBaptiste Daroussin x_count++) {
2662a3e3873SBaptiste Daroussin waddch(data->menu, ' ');
2672a3e3873SBaptiste Daroussin }
2682a3e3873SBaptiste Daroussin }
2692a3e3873SBaptiste Daroussin }
2702a3e3873SBaptiste Daroussin
2712a3e3873SBaptiste Daroussin (void) wnoutrefresh(data->menu);
2722a3e3873SBaptiste Daroussin
2732a3e3873SBaptiste Daroussin dlg_draw_scrollbar(data->dialog,
2742a3e3873SBaptiste Daroussin scrollamt,
2752a3e3873SBaptiste Daroussin scrollamt,
2762a3e3873SBaptiste Daroussin scrollamt + max_choice,
2772a3e3873SBaptiste Daroussin data->item_no,
2782a3e3873SBaptiste Daroussin data->box_x,
2792a3e3873SBaptiste Daroussin data->box_x + data->menu_width,
2802a3e3873SBaptiste Daroussin data->box_y,
2812a3e3873SBaptiste Daroussin data->box_y + data->menu_height + 1,
2822a3e3873SBaptiste Daroussin menubox_border2_attr,
2832a3e3873SBaptiste Daroussin menubox_border_attr);
2842a3e3873SBaptiste Daroussin }
2852a3e3873SBaptiste Daroussin
2862a3e3873SBaptiste Daroussin static bool
check_hotkey(DIALOG_LISTITEM * items,int choice)2872a3e3873SBaptiste Daroussin check_hotkey(DIALOG_LISTITEM * items, int choice)
2882a3e3873SBaptiste Daroussin {
2892a3e3873SBaptiste Daroussin bool result = FALSE;
2902a3e3873SBaptiste Daroussin
2912a3e3873SBaptiste Daroussin if (dlg_match_char(dlg_last_getc(),
2922a3e3873SBaptiste Daroussin (dialog_vars.no_tags
2932a3e3873SBaptiste Daroussin ? items[choice].text
2942a3e3873SBaptiste Daroussin : items[choice].name))) {
2952a3e3873SBaptiste Daroussin result = TRUE;
2962a3e3873SBaptiste Daroussin }
2972a3e3873SBaptiste Daroussin return result;
2982a3e3873SBaptiste Daroussin }
2992a3e3873SBaptiste Daroussin
3004c8945a0SNathan Whitehorn /*
3014c8945a0SNathan Whitehorn * This is an alternate interface to 'menu' which allows the application
3024c8945a0SNathan Whitehorn * to read the list item states back directly without putting them in the
3034c8945a0SNathan Whitehorn * output buffer.
3044c8945a0SNathan Whitehorn */
3054c8945a0SNathan Whitehorn int
dlg_menu(const char * title,const char * cprompt,int height,int width,int menu_height,int item_no,DIALOG_LISTITEM * items,int * current_item,DIALOG_INPUTMENU rename_menutext)3064c8945a0SNathan Whitehorn dlg_menu(const char *title,
3074c8945a0SNathan Whitehorn const char *cprompt,
3084c8945a0SNathan Whitehorn int height,
3094c8945a0SNathan Whitehorn int width,
3104c8945a0SNathan Whitehorn int menu_height,
3114c8945a0SNathan Whitehorn int item_no,
3124c8945a0SNathan Whitehorn DIALOG_LISTITEM * items,
3134c8945a0SNathan Whitehorn int *current_item,
3144c8945a0SNathan Whitehorn DIALOG_INPUTMENU rename_menutext)
3154c8945a0SNathan Whitehorn {
3164c8945a0SNathan Whitehorn /* *INDENT-OFF* */
3174c8945a0SNathan Whitehorn static DLG_KEYS_BINDING binding[] = {
318682c9e0fSNathan Whitehorn HELPKEY_BINDINGS,
3194c8945a0SNathan Whitehorn ENTERKEY_BINDINGS,
320f4f33ea0SBaptiste Daroussin TOGGLEKEY_BINDINGS,
3214c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
3224c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
3234c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
3244c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
3254c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ),
3264c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ),
3274c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ),
3284c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ),
3294c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ),
3304c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ),
3314c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_FIRST, KEY_HOME ),
3324c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_END ),
3334c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_LL ),
3344c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ),
3354c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ),
3364c8945a0SNathan Whitehorn END_KEYS_BINDING
3374c8945a0SNathan Whitehorn };
3384c8945a0SNathan Whitehorn static DLG_KEYS_BINDING binding2[] = {
3394c8945a0SNathan Whitehorn INPUTSTR_BINDINGS,
340682c9e0fSNathan Whitehorn HELPKEY_BINDINGS,
3414c8945a0SNathan Whitehorn ENTERKEY_BINDINGS,
3424c8945a0SNathan Whitehorn END_KEYS_BINDING
3434c8945a0SNathan Whitehorn };
3444c8945a0SNathan Whitehorn /* *INDENT-ON* */
3454c8945a0SNathan Whitehorn
3464c8945a0SNathan Whitehorn #ifdef KEY_RESIZE
347f4f33ea0SBaptiste Daroussin int old_LINES = LINES;
348f4f33ea0SBaptiste Daroussin int old_COLS = COLS;
3494c8945a0SNathan Whitehorn int old_height = height;
3504c8945a0SNathan Whitehorn int old_width = width;
3514c8945a0SNathan Whitehorn #endif
3522a3e3873SBaptiste Daroussin ALL_DATA all;
3532a3e3873SBaptiste Daroussin int i, j, x, y, cur_x, cur_y;
354*a96ef450SBaptiste Daroussin int fkey;
3552a3e3873SBaptiste Daroussin int button = dialog_state.visit_items ? -1 : dlg_default_button();
3564c8945a0SNathan Whitehorn int choice = dlg_default_listitem(items);
3574c8945a0SNathan Whitehorn int result = DLG_EXIT_UNKNOWN;
3584c8945a0SNathan Whitehorn int scrollamt = 0;
3592a3e3873SBaptiste Daroussin int max_choice;
3602a3e3873SBaptiste Daroussin int use_width, name_width, text_width, list_width;
3614c8945a0SNathan Whitehorn WINDOW *dialog, *menu;
362f4f33ea0SBaptiste Daroussin char *prompt = 0;
3634c8945a0SNathan Whitehorn const char **buttons = dlg_ok_labels();
3642a3e3873SBaptiste Daroussin bool is_inputmenu = ((rename_menutext != 0)
3652a3e3873SBaptiste Daroussin && (rename_menutext != dlg_dummy_menutext));
3662a3e3873SBaptiste Daroussin
367f4f33ea0SBaptiste Daroussin DLG_TRACE(("# menubox args:\n"));
368f4f33ea0SBaptiste Daroussin DLG_TRACE2S("title", title);
369f4f33ea0SBaptiste Daroussin DLG_TRACE2S("message", cprompt);
370f4f33ea0SBaptiste Daroussin DLG_TRACE2N("height", height);
371f4f33ea0SBaptiste Daroussin DLG_TRACE2N("width", width);
372f4f33ea0SBaptiste Daroussin DLG_TRACE2N("lheight", menu_height);
373f4f33ea0SBaptiste Daroussin DLG_TRACE2N("llength", item_no);
374f4f33ea0SBaptiste Daroussin /* FIXME dump the items[][] too */
375f4f33ea0SBaptiste Daroussin DLG_TRACE2N("rename", rename_menutext != 0);
376f4f33ea0SBaptiste Daroussin
377f4f33ea0SBaptiste Daroussin dialog_state.plain_buttons = TRUE;
378f4f33ea0SBaptiste Daroussin
3792a3e3873SBaptiste Daroussin all.items = items;
3802a3e3873SBaptiste Daroussin all.item_no = item_no;
3814c8945a0SNathan Whitehorn
3824c8945a0SNathan Whitehorn dlg_does_output();
3834c8945a0SNathan Whitehorn
3844c8945a0SNathan Whitehorn #ifdef KEY_RESIZE
3854c8945a0SNathan Whitehorn retry:
3864c8945a0SNathan Whitehorn #endif
3874c8945a0SNathan Whitehorn
388f4f33ea0SBaptiste Daroussin prompt = dlg_strclone(cprompt);
389f4f33ea0SBaptiste Daroussin dlg_tab_correct_str(prompt);
390f4f33ea0SBaptiste Daroussin
3912a3e3873SBaptiste Daroussin all.menu_height = menu_height;
3922a3e3873SBaptiste Daroussin use_width = dlg_calc_list_width(item_no, items) + 10;
3932a3e3873SBaptiste Daroussin use_width = MAX(26, use_width);
3942a3e3873SBaptiste Daroussin if (all.menu_height == 0) {
3954c8945a0SNathan Whitehorn /* calculate height without items (4) */
3962a3e3873SBaptiste Daroussin dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
3972a3e3873SBaptiste Daroussin dlg_calc_listh(&height, &all.menu_height, item_no);
3984c8945a0SNathan Whitehorn } else {
3992a3e3873SBaptiste Daroussin dlg_auto_size(title, prompt,
4002a3e3873SBaptiste Daroussin &height, &width,
4012a3e3873SBaptiste Daroussin MIN_HIGH + all.menu_height, use_width);
4024c8945a0SNathan Whitehorn }
4034c8945a0SNathan Whitehorn dlg_button_layout(buttons, &width);
4044c8945a0SNathan Whitehorn dlg_print_size(height, width);
4054c8945a0SNathan Whitehorn dlg_ctl_size(height, width);
4064c8945a0SNathan Whitehorn
4074c8945a0SNathan Whitehorn x = dlg_box_x_ordinate(width);
4084c8945a0SNathan Whitehorn y = dlg_box_y_ordinate(height);
4094c8945a0SNathan Whitehorn
4104c8945a0SNathan Whitehorn dialog = dlg_new_window(height, width, y, x);
4112a3e3873SBaptiste Daroussin all.dialog = dialog;
4122a3e3873SBaptiste Daroussin
4134c8945a0SNathan Whitehorn dlg_register_window(dialog, "menubox", binding);
4144c8945a0SNathan Whitehorn dlg_register_buttons(dialog, "menubox", buttons);
4154c8945a0SNathan Whitehorn
4164c8945a0SNathan Whitehorn dlg_mouse_setbase(x, y);
4174c8945a0SNathan Whitehorn
4182a3e3873SBaptiste Daroussin dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
4192a3e3873SBaptiste Daroussin dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
4204c8945a0SNathan Whitehorn dlg_draw_title(dialog, title);
4214c8945a0SNathan Whitehorn
422f4f33ea0SBaptiste Daroussin dlg_attrset(dialog, dialog_attr);
4234c8945a0SNathan Whitehorn dlg_print_autowrap(dialog, prompt, height, width);
4244c8945a0SNathan Whitehorn
4252a3e3873SBaptiste Daroussin all.menu_width = width - 6;
4264c8945a0SNathan Whitehorn getyx(dialog, cur_y, cur_x);
4272a3e3873SBaptiste Daroussin all.box_y = cur_y + 1;
4282a3e3873SBaptiste Daroussin all.box_x = (width - all.menu_width) / 2 - 1;
4294c8945a0SNathan Whitehorn
4304c8945a0SNathan Whitehorn /*
4314c8945a0SNathan Whitehorn * After displaying the prompt, we know how much space we really have.
4324c8945a0SNathan Whitehorn * Limit the list to avoid overwriting the ok-button.
4334c8945a0SNathan Whitehorn */
4342a3e3873SBaptiste Daroussin all.menu_height = height - MIN_HIGH - cur_y;
4352a3e3873SBaptiste Daroussin if (all.menu_height <= 0)
4362a3e3873SBaptiste Daroussin all.menu_height = 1;
4374c8945a0SNathan Whitehorn
4384c8945a0SNathan Whitehorn /* Find out maximal number of displayable items at once. */
4392a3e3873SBaptiste Daroussin max_choice = MIN(all.menu_height,
4404c8945a0SNathan Whitehorn RowHeight(item_no));
4414c8945a0SNathan Whitehorn if (is_inputmenu)
4424c8945a0SNathan Whitehorn max_choice /= INPUT_ROWS;
4434c8945a0SNathan Whitehorn
4444c8945a0SNathan Whitehorn /* create new window for the menu */
4452a3e3873SBaptiste Daroussin menu = dlg_sub_window(dialog, all.menu_height, all.menu_width,
4462a3e3873SBaptiste Daroussin y + all.box_y + 1,
4472a3e3873SBaptiste Daroussin x + all.box_x + 1);
4482a3e3873SBaptiste Daroussin all.menu = menu;
4492a3e3873SBaptiste Daroussin
4504c8945a0SNathan Whitehorn dlg_register_window(menu, "menu", binding2);
4514c8945a0SNathan Whitehorn dlg_register_buttons(menu, "menu", buttons);
4524c8945a0SNathan Whitehorn
4534c8945a0SNathan Whitehorn /* draw a box around the menu items */
4542a3e3873SBaptiste Daroussin dlg_draw_box(dialog,
4552a3e3873SBaptiste Daroussin all.box_y, all.box_x,
4562a3e3873SBaptiste Daroussin all.menu_height + 2, all.menu_width + 2,
4572a3e3873SBaptiste Daroussin menubox_border_attr, menubox_border2_attr);
4584c8945a0SNathan Whitehorn
4594c8945a0SNathan Whitehorn name_width = 0;
4604c8945a0SNathan Whitehorn text_width = 0;
4614c8945a0SNathan Whitehorn
4624c8945a0SNathan Whitehorn /* Find length of longest item to center menu *
4634c8945a0SNathan Whitehorn * only if --menu was given, using --inputmenu *
4644c8945a0SNathan Whitehorn * won't be centered. */
4654c8945a0SNathan Whitehorn for (i = 0; i < item_no; i++) {
4664c8945a0SNathan Whitehorn name_width = MAX(name_width, dlg_count_columns(items[i].name));
4674c8945a0SNathan Whitehorn text_width = MAX(text_width, dlg_count_columns(items[i].text));
4684c8945a0SNathan Whitehorn }
4694c8945a0SNathan Whitehorn
4704c8945a0SNathan Whitehorn /* If the name+text is wider than the list is allowed, then truncate
4714c8945a0SNathan Whitehorn * one or both of them. If the name is no wider than 30% of the list,
4724c8945a0SNathan Whitehorn * leave it intact.
4734c8945a0SNathan Whitehorn *
4744c8945a0SNathan Whitehorn * FIXME: the gutter width and name/list ratio should be configurable.
4754c8945a0SNathan Whitehorn */
4762a3e3873SBaptiste Daroussin use_width = (all.menu_width - GUTTER);
4772a3e3873SBaptiste Daroussin if (dialog_vars.no_tags) {
4782a3e3873SBaptiste Daroussin list_width = MIN(use_width, text_width);
4792a3e3873SBaptiste Daroussin } else if (dialog_vars.no_items) {
4802a3e3873SBaptiste Daroussin list_width = MIN(use_width, name_width);
4812a3e3873SBaptiste Daroussin } else {
4822a3e3873SBaptiste Daroussin if (text_width >= 0
4832a3e3873SBaptiste Daroussin && name_width >= 0
4842a3e3873SBaptiste Daroussin && use_width > 0
4852a3e3873SBaptiste Daroussin && text_width + name_width > use_width) {
4864c8945a0SNathan Whitehorn int need = (int) (0.30 * use_width);
4874c8945a0SNathan Whitehorn if (name_width > need) {
4884c8945a0SNathan Whitehorn int want = (int) (use_width
4894c8945a0SNathan Whitehorn * ((double) name_width)
4904c8945a0SNathan Whitehorn / (text_width + name_width));
4914c8945a0SNathan Whitehorn name_width = (want > need) ? want : need;
4924c8945a0SNathan Whitehorn }
4934c8945a0SNathan Whitehorn text_width = use_width - name_width;
4944c8945a0SNathan Whitehorn }
4952a3e3873SBaptiste Daroussin list_width = (text_width + name_width);
4962a3e3873SBaptiste Daroussin }
4974c8945a0SNathan Whitehorn
4982a3e3873SBaptiste Daroussin all.tag_x = (is_inputmenu
4994c8945a0SNathan Whitehorn ? 0
5002a3e3873SBaptiste Daroussin : (use_width - list_width) / 2);
5012a3e3873SBaptiste Daroussin all.item_x = ((dialog_vars.no_tags
5022a3e3873SBaptiste Daroussin ? 0
5032a3e3873SBaptiste Daroussin : (dialog_vars.no_items
5042a3e3873SBaptiste Daroussin ? 0
5052a3e3873SBaptiste Daroussin : (GUTTER + name_width)))
5062a3e3873SBaptiste Daroussin + all.tag_x);
5074c8945a0SNathan Whitehorn
5084c8945a0SNathan Whitehorn if (choice - scrollamt >= max_choice) {
5094c8945a0SNathan Whitehorn scrollamt = choice - (max_choice - 1);
5104c8945a0SNathan Whitehorn choice = max_choice - 1;
5114c8945a0SNathan Whitehorn }
5124c8945a0SNathan Whitehorn
5132a3e3873SBaptiste Daroussin print_menu(&all, choice, scrollamt, max_choice, is_inputmenu);
5144c8945a0SNathan Whitehorn
5154c8945a0SNathan Whitehorn /* register the new window, along with its borders */
5162a3e3873SBaptiste Daroussin dlg_mouse_mkbigregion(all.box_y + 1, all.box_x,
5172a3e3873SBaptiste Daroussin all.menu_height + 2, all.menu_width + 2,
5184c8945a0SNathan Whitehorn KEY_MAX, 1, 1, 1 /* by lines */ );
5194c8945a0SNathan Whitehorn
5204c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
5214c8945a0SNathan Whitehorn
5222a3e3873SBaptiste Daroussin dlg_trace_win(dialog);
523*a96ef450SBaptiste Daroussin
5244c8945a0SNathan Whitehorn while (result == DLG_EXIT_UNKNOWN) {
525*a96ef450SBaptiste Daroussin int key, found;
526*a96ef450SBaptiste Daroussin
5274c8945a0SNathan Whitehorn if (button < 0) /* --visit-items */
5282a3e3873SBaptiste Daroussin wmove(dialog,
5292a3e3873SBaptiste Daroussin all.box_y + ItemToRow(choice) + 1,
5302a3e3873SBaptiste Daroussin all.box_x + all.tag_x + 1);
5314c8945a0SNathan Whitehorn
5324c8945a0SNathan Whitehorn key = dlg_mouse_wgetch(dialog, &fkey);
533*a96ef450SBaptiste Daroussin if (dlg_result_key(key, fkey, &result)) {
534*a96ef450SBaptiste Daroussin if (!dlg_button_key(result, &button, &key, &fkey))
5354c8945a0SNathan Whitehorn break;
536*a96ef450SBaptiste Daroussin }
5374c8945a0SNathan Whitehorn
5384c8945a0SNathan Whitehorn found = FALSE;
5394c8945a0SNathan Whitehorn if (fkey) {
5404c8945a0SNathan Whitehorn /*
5414c8945a0SNathan Whitehorn * Allow a mouse-click on a box to switch selection to that box.
5424c8945a0SNathan Whitehorn * Handling a button click is a little more complicated, since we
5434c8945a0SNathan Whitehorn * push a KEY_ENTER back onto the input stream so we'll put the
5444c8945a0SNathan Whitehorn * cursor at the right place before handling the "keypress".
5454c8945a0SNathan Whitehorn */
5464c8945a0SNathan Whitehorn if (key >= DLGK_MOUSE(KEY_MAX)) {
5474c8945a0SNathan Whitehorn key -= DLGK_MOUSE(KEY_MAX);
5484c8945a0SNathan Whitehorn i = RowToItem(key);
5494c8945a0SNathan Whitehorn if (i < max_choice) {
5504c8945a0SNathan Whitehorn found = TRUE;
5514c8945a0SNathan Whitehorn } else {
5524c8945a0SNathan Whitehorn beep();
5534c8945a0SNathan Whitehorn continue;
5544c8945a0SNathan Whitehorn }
5554c8945a0SNathan Whitehorn } else if (is_DLGK_MOUSE(key)
5564c8945a0SNathan Whitehorn && dlg_ok_buttoncode(key - M_EVENT) >= 0) {
5574c8945a0SNathan Whitehorn button = (key - M_EVENT);
5584c8945a0SNathan Whitehorn ungetch('\n');
5594c8945a0SNathan Whitehorn continue;
5604c8945a0SNathan Whitehorn }
5614c8945a0SNathan Whitehorn } else {
5624c8945a0SNathan Whitehorn /*
5634c8945a0SNathan Whitehorn * Check if key pressed matches first character of any item tag in
5644c8945a0SNathan Whitehorn * list. If there is more than one match, we will cycle through
5654c8945a0SNathan Whitehorn * each one as the same key is pressed repeatedly.
5664c8945a0SNathan Whitehorn */
5674c8945a0SNathan Whitehorn if (button < 0 || !dialog_state.visit_items) {
5684c8945a0SNathan Whitehorn for (j = scrollamt + choice + 1; j < item_no; j++) {
5692a3e3873SBaptiste Daroussin if (check_hotkey(items, j)) {
5704c8945a0SNathan Whitehorn found = TRUE;
5714c8945a0SNathan Whitehorn i = j - scrollamt;
5724c8945a0SNathan Whitehorn break;
5734c8945a0SNathan Whitehorn }
5744c8945a0SNathan Whitehorn }
5754c8945a0SNathan Whitehorn if (!found) {
5764c8945a0SNathan Whitehorn for (j = 0; j <= scrollamt + choice; j++) {
5772a3e3873SBaptiste Daroussin if (check_hotkey(items, j)) {
5784c8945a0SNathan Whitehorn found = TRUE;
5794c8945a0SNathan Whitehorn i = j - scrollamt;
5804c8945a0SNathan Whitehorn break;
5814c8945a0SNathan Whitehorn }
5824c8945a0SNathan Whitehorn }
5834c8945a0SNathan Whitehorn }
5844c8945a0SNathan Whitehorn if (found)
5854c8945a0SNathan Whitehorn dlg_flush_getc();
5864c8945a0SNathan Whitehorn } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
5874c8945a0SNathan Whitehorn button = j;
5884c8945a0SNathan Whitehorn ungetch('\n');
5894c8945a0SNathan Whitehorn continue;
5904c8945a0SNathan Whitehorn }
5914c8945a0SNathan Whitehorn
5924c8945a0SNathan Whitehorn /*
5934c8945a0SNathan Whitehorn * A single digit (1-9) positions the selection to that line in the
5944c8945a0SNathan Whitehorn * current screen.
5954c8945a0SNathan Whitehorn */
5964c8945a0SNathan Whitehorn if (!found
5974c8945a0SNathan Whitehorn && (key <= '9')
5984c8945a0SNathan Whitehorn && (key > '0')
5994c8945a0SNathan Whitehorn && (key - '1' < max_choice)) {
6004c8945a0SNathan Whitehorn found = TRUE;
6014c8945a0SNathan Whitehorn i = key - '1';
6024c8945a0SNathan Whitehorn }
6034c8945a0SNathan Whitehorn }
6044c8945a0SNathan Whitehorn
6054c8945a0SNathan Whitehorn if (!found && fkey) {
6064c8945a0SNathan Whitehorn found = TRUE;
6074c8945a0SNathan Whitehorn switch (key) {
6084c8945a0SNathan Whitehorn case DLGK_PAGE_FIRST:
6094c8945a0SNathan Whitehorn i = -scrollamt;
6104c8945a0SNathan Whitehorn break;
6114c8945a0SNathan Whitehorn case DLGK_PAGE_LAST:
6124c8945a0SNathan Whitehorn i = item_no - 1 - scrollamt;
6134c8945a0SNathan Whitehorn break;
6144c8945a0SNathan Whitehorn case DLGK_MOUSE(KEY_PPAGE):
6154c8945a0SNathan Whitehorn case DLGK_PAGE_PREV:
6164c8945a0SNathan Whitehorn if (choice)
6174c8945a0SNathan Whitehorn i = 0;
6184c8945a0SNathan Whitehorn else if (scrollamt != 0)
6194c8945a0SNathan Whitehorn i = -MIN(scrollamt, max_choice);
6204c8945a0SNathan Whitehorn else
6214c8945a0SNathan Whitehorn continue;
6224c8945a0SNathan Whitehorn break;
6234c8945a0SNathan Whitehorn case DLGK_MOUSE(KEY_NPAGE):
6244c8945a0SNathan Whitehorn case DLGK_PAGE_NEXT:
6254c8945a0SNathan Whitehorn i = MIN(choice + max_choice, item_no - scrollamt - 1);
6264c8945a0SNathan Whitehorn break;
6274c8945a0SNathan Whitehorn case DLGK_ITEM_PREV:
6284c8945a0SNathan Whitehorn i = choice - 1;
6294c8945a0SNathan Whitehorn if (choice == 0 && scrollamt == 0)
6304c8945a0SNathan Whitehorn continue;
6314c8945a0SNathan Whitehorn break;
6324c8945a0SNathan Whitehorn case DLGK_ITEM_NEXT:
6334c8945a0SNathan Whitehorn i = choice + 1;
6344c8945a0SNathan Whitehorn if (scrollamt + choice >= item_no - 1)
6354c8945a0SNathan Whitehorn continue;
6364c8945a0SNathan Whitehorn break;
6374c8945a0SNathan Whitehorn default:
6384c8945a0SNathan Whitehorn found = FALSE;
6394c8945a0SNathan Whitehorn break;
6404c8945a0SNathan Whitehorn }
6414c8945a0SNathan Whitehorn }
6424c8945a0SNathan Whitehorn
6434c8945a0SNathan Whitehorn if (found) {
6444c8945a0SNathan Whitehorn if (i != choice) {
6454c8945a0SNathan Whitehorn getyx(dialog, cur_y, cur_x);
6464c8945a0SNathan Whitehorn if (i < 0 || i >= max_choice) {
6474c8945a0SNathan Whitehorn if (i < 0) {
6484c8945a0SNathan Whitehorn scrollamt += i;
6494c8945a0SNathan Whitehorn choice = 0;
6504c8945a0SNathan Whitehorn } else {
6514c8945a0SNathan Whitehorn choice = max_choice - 1;
6524c8945a0SNathan Whitehorn scrollamt += (i - max_choice + 1);
6534c8945a0SNathan Whitehorn }
6542a3e3873SBaptiste Daroussin print_menu(&all, choice, scrollamt, max_choice, is_inputmenu);
6554c8945a0SNathan Whitehorn } else {
6564c8945a0SNathan Whitehorn choice = i;
6572a3e3873SBaptiste Daroussin print_menu(&all, choice, scrollamt, max_choice, is_inputmenu);
6584c8945a0SNathan Whitehorn (void) wmove(dialog, cur_y, cur_x);
6594c8945a0SNathan Whitehorn wrefresh(dialog);
6604c8945a0SNathan Whitehorn }
6614c8945a0SNathan Whitehorn }
6624c8945a0SNathan Whitehorn continue; /* wait for another key press */
6634c8945a0SNathan Whitehorn }
6644c8945a0SNathan Whitehorn
6654c8945a0SNathan Whitehorn if (fkey) {
6664c8945a0SNathan Whitehorn switch (key) {
6674c8945a0SNathan Whitehorn case DLGK_FIELD_PREV:
6684c8945a0SNathan Whitehorn button = dlg_prev_button(buttons, button);
6694c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
6704c8945a0SNathan Whitehorn FALSE, width);
6714c8945a0SNathan Whitehorn break;
672*a96ef450SBaptiste Daroussin
6734c8945a0SNathan Whitehorn case DLGK_FIELD_NEXT:
6744c8945a0SNathan Whitehorn button = dlg_next_button(buttons, button);
6754c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
6764c8945a0SNathan Whitehorn FALSE, width);
6774c8945a0SNathan Whitehorn break;
678*a96ef450SBaptiste Daroussin
679f4f33ea0SBaptiste Daroussin case DLGK_TOGGLE:
6804c8945a0SNathan Whitehorn case DLGK_ENTER:
681*a96ef450SBaptiste Daroussin case DLGK_LEAVE:
682*a96ef450SBaptiste Daroussin result = ((key == DLGK_LEAVE)
683*a96ef450SBaptiste Daroussin ? dlg_ok_buttoncode(button)
684*a96ef450SBaptiste Daroussin : dlg_enter_buttoncode(button));
6854c8945a0SNathan Whitehorn
6864c8945a0SNathan Whitehorn /*
6874c8945a0SNathan Whitehorn * If dlg_menu() is called from dialog_menu(), we want to
6882a3e3873SBaptiste Daroussin * capture the results into dialog_vars.input_result.
6894c8945a0SNathan Whitehorn */
6904c8945a0SNathan Whitehorn if (result == DLG_EXIT_ERROR) {
6914c8945a0SNathan Whitehorn result = DLG_EXIT_UNKNOWN;
6924c8945a0SNathan Whitehorn } else if (is_inputmenu
6934c8945a0SNathan Whitehorn || rename_menutext == dlg_dummy_menutext) {
6944c8945a0SNathan Whitehorn result = handle_button(result,
6954c8945a0SNathan Whitehorn items,
6964c8945a0SNathan Whitehorn scrollamt + choice);
6974c8945a0SNathan Whitehorn }
6984c8945a0SNathan Whitehorn
6994c8945a0SNathan Whitehorn /*
7004c8945a0SNathan Whitehorn * If we have a rename_menutext function, interpret the Extra
7014c8945a0SNathan Whitehorn * button as a request to rename the menu's text. If that
7024c8945a0SNathan Whitehorn * function doesn't return "Unknown", we will exit from this
7034c8945a0SNathan Whitehorn * function. Usually that is done for dialog_menu(), so the
7044c8945a0SNathan Whitehorn * shell script can use the updated value. If it does return
7054c8945a0SNathan Whitehorn * "Unknown", update the list item only. A direct caller of
7064c8945a0SNathan Whitehorn * dlg_menu() can free the renamed value - we cannot.
7074c8945a0SNathan Whitehorn */
7084c8945a0SNathan Whitehorn if (is_inputmenu && result == DLG_EXIT_EXTRA) {
7094c8945a0SNathan Whitehorn char *tmp;
7104c8945a0SNathan Whitehorn
7112a3e3873SBaptiste Daroussin if (input_menu_edit(&all,
7124c8945a0SNathan Whitehorn &items[scrollamt + choice],
7134c8945a0SNathan Whitehorn choice,
7144c8945a0SNathan Whitehorn &tmp)) {
7154c8945a0SNathan Whitehorn result = rename_menutext(items, scrollamt + choice, tmp);
7164c8945a0SNathan Whitehorn if (result == DLG_EXIT_UNKNOWN) {
7174c8945a0SNathan Whitehorn items[scrollamt + choice].text = tmp;
7184c8945a0SNathan Whitehorn } else {
7194c8945a0SNathan Whitehorn free(tmp);
7204c8945a0SNathan Whitehorn }
7214c8945a0SNathan Whitehorn } else {
7224c8945a0SNathan Whitehorn result = DLG_EXIT_UNKNOWN;
7232a3e3873SBaptiste Daroussin print_item(&all,
7242a3e3873SBaptiste Daroussin menu,
7254c8945a0SNathan Whitehorn &items[scrollamt + choice],
7264c8945a0SNathan Whitehorn choice,
7274c8945a0SNathan Whitehorn Selected,
7284c8945a0SNathan Whitehorn is_inputmenu);
7294c8945a0SNathan Whitehorn (void) wnoutrefresh(menu);
7304c8945a0SNathan Whitehorn free(tmp);
7314c8945a0SNathan Whitehorn }
7324c8945a0SNathan Whitehorn
7334c8945a0SNathan Whitehorn if (result == DLG_EXIT_UNKNOWN) {
7344c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0,
7354c8945a0SNathan Whitehorn buttons, button, FALSE, width);
7364c8945a0SNathan Whitehorn }
7374c8945a0SNathan Whitehorn }
7384c8945a0SNathan Whitehorn break;
7394c8945a0SNathan Whitehorn #ifdef KEY_RESIZE
7404c8945a0SNathan Whitehorn case KEY_RESIZE:
741f4f33ea0SBaptiste Daroussin dlg_will_resize(dialog);
7424c8945a0SNathan Whitehorn /* reset data */
743f4f33ea0SBaptiste Daroussin resizeit(height, LINES);
744f4f33ea0SBaptiste Daroussin resizeit(width, COLS);
745f4f33ea0SBaptiste Daroussin free(prompt);
746*a96ef450SBaptiste Daroussin _dlg_resize_cleanup(dialog);
747f4f33ea0SBaptiste Daroussin /* repaint */
7484c8945a0SNathan Whitehorn goto retry;
7494c8945a0SNathan Whitehorn #endif
7504c8945a0SNathan Whitehorn default:
7514c8945a0SNathan Whitehorn flash();
7524c8945a0SNathan Whitehorn break;
7534c8945a0SNathan Whitehorn }
7544c8945a0SNathan Whitehorn }
7554c8945a0SNathan Whitehorn }
7564c8945a0SNathan Whitehorn
7574c8945a0SNathan Whitehorn dlg_mouse_free_regions();
7584c8945a0SNathan Whitehorn dlg_unregister_window(menu);
7594c8945a0SNathan Whitehorn dlg_del_window(dialog);
7604c8945a0SNathan Whitehorn free(prompt);
7614c8945a0SNathan Whitehorn
7624c8945a0SNathan Whitehorn *current_item = scrollamt + choice;
763*a96ef450SBaptiste Daroussin
764*a96ef450SBaptiste Daroussin DLG_TRACE2N("current", *current_item);
7654c8945a0SNathan Whitehorn return result;
7664c8945a0SNathan Whitehorn }
7674c8945a0SNathan Whitehorn
7684c8945a0SNathan Whitehorn /*
7694c8945a0SNathan Whitehorn * Display a menu for choosing among a number of options
7704c8945a0SNathan Whitehorn */
7714c8945a0SNathan Whitehorn int
dialog_menu(const char * title,const char * cprompt,int height,int width,int menu_height,int item_no,char ** items)7724c8945a0SNathan Whitehorn dialog_menu(const char *title,
7734c8945a0SNathan Whitehorn const char *cprompt,
7744c8945a0SNathan Whitehorn int height,
7754c8945a0SNathan Whitehorn int width,
7764c8945a0SNathan Whitehorn int menu_height,
7774c8945a0SNathan Whitehorn int item_no,
7784c8945a0SNathan Whitehorn char **items)
7794c8945a0SNathan Whitehorn {
7804c8945a0SNathan Whitehorn int result;
7814c8945a0SNathan Whitehorn int choice;
7822a3e3873SBaptiste Daroussin int i, j;
7834c8945a0SNathan Whitehorn DIALOG_LISTITEM *listitems;
7844c8945a0SNathan Whitehorn
7854c8945a0SNathan Whitehorn listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
7864c8945a0SNathan Whitehorn assert_ptr(listitems, "dialog_menu");
7874c8945a0SNathan Whitehorn
7882a3e3873SBaptiste Daroussin for (i = j = 0; i < item_no; ++i) {
7892a3e3873SBaptiste Daroussin listitems[i].name = items[j++];
7902a3e3873SBaptiste Daroussin listitems[i].text = (dialog_vars.no_items
7912a3e3873SBaptiste Daroussin ? dlg_strempty()
7922a3e3873SBaptiste Daroussin : items[j++]);
7934c8945a0SNathan Whitehorn listitems[i].help = ((dialog_vars.item_help)
7942a3e3873SBaptiste Daroussin ? items[j++]
7954c8945a0SNathan Whitehorn : dlg_strempty());
7964c8945a0SNathan Whitehorn }
7974c8945a0SNathan Whitehorn dlg_align_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no);
7984c8945a0SNathan Whitehorn
7994c8945a0SNathan Whitehorn result = dlg_menu(title,
8004c8945a0SNathan Whitehorn cprompt,
8014c8945a0SNathan Whitehorn height,
8024c8945a0SNathan Whitehorn width,
8034c8945a0SNathan Whitehorn menu_height,
8044c8945a0SNathan Whitehorn item_no,
8054c8945a0SNathan Whitehorn listitems,
8064c8945a0SNathan Whitehorn &choice,
8072a3e3873SBaptiste Daroussin (dialog_vars.input_menu
8082a3e3873SBaptiste Daroussin ? dlg_renamed_menutext
8092a3e3873SBaptiste Daroussin : dlg_dummy_menutext));
8104c8945a0SNathan Whitehorn
8114c8945a0SNathan Whitehorn dlg_free_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no);
8124c8945a0SNathan Whitehorn free(listitems);
8134c8945a0SNathan Whitehorn return result;
8144c8945a0SNathan Whitehorn }
815