14c8945a0SNathan Whitehorn /* 2*f4f33ea0SBaptiste Daroussin * $Id: buttons.c,v 1.99 2018/06/18 22:11:16 tom Exp $ 34c8945a0SNathan Whitehorn * 44c8945a0SNathan Whitehorn * buttons.c -- draw buttons, e.g., OK/Cancel 54c8945a0SNathan Whitehorn * 6*f4f33ea0SBaptiste Daroussin * Copyright 2000-2017,2018 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 License, version 2.1 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 244c8945a0SNathan Whitehorn #include <dialog.h> 254c8945a0SNathan Whitehorn #include <dlg_keys.h> 264c8945a0SNathan Whitehorn 274c8945a0SNathan Whitehorn #ifdef NEED_WCHAR_H 284c8945a0SNathan Whitehorn #include <wchar.h> 294c8945a0SNathan Whitehorn #endif 304c8945a0SNathan Whitehorn 312a3e3873SBaptiste Daroussin #define MIN_BUTTON (-dialog_state.visit_cols) 32*f4f33ea0SBaptiste Daroussin #define CHR_BUTTON (!dialog_state.plain_buttons) 334c8945a0SNathan Whitehorn 344c8945a0SNathan Whitehorn static void 354c8945a0SNathan Whitehorn center_label(char *buffer, int longest, const char *label) 364c8945a0SNathan Whitehorn { 374c8945a0SNathan Whitehorn int len = dlg_count_columns(label); 384c8945a0SNathan Whitehorn int left = 0, right = 0; 394c8945a0SNathan Whitehorn 404c8945a0SNathan Whitehorn *buffer = 0; 414c8945a0SNathan Whitehorn if (len < longest) { 424c8945a0SNathan Whitehorn left = (longest - len) / 2; 434c8945a0SNathan Whitehorn right = (longest - len - left); 444c8945a0SNathan Whitehorn if (left > 0) 454c8945a0SNathan Whitehorn sprintf(buffer, "%*s", left, " "); 464c8945a0SNathan Whitehorn } 474c8945a0SNathan Whitehorn strcat(buffer, label); 484c8945a0SNathan Whitehorn if (right > 0) 494c8945a0SNathan Whitehorn sprintf(buffer + strlen(buffer), "%*s", right, " "); 504c8945a0SNathan Whitehorn } 514c8945a0SNathan Whitehorn 524c8945a0SNathan Whitehorn /* 534c8945a0SNathan Whitehorn * Parse a multibyte character out of the string, set it past the parsed 544c8945a0SNathan Whitehorn * character. 554c8945a0SNathan Whitehorn */ 564c8945a0SNathan Whitehorn static int 574c8945a0SNathan Whitehorn string_to_char(const char **stringp) 584c8945a0SNathan Whitehorn { 594c8945a0SNathan Whitehorn int result; 604c8945a0SNathan Whitehorn #ifdef USE_WIDE_CURSES 614c8945a0SNathan Whitehorn const char *string = *stringp; 624c8945a0SNathan Whitehorn size_t have = strlen(string); 634c8945a0SNathan Whitehorn size_t check; 644c8945a0SNathan Whitehorn size_t len; 654c8945a0SNathan Whitehorn wchar_t cmp2[2]; 664c8945a0SNathan Whitehorn mbstate_t state; 674c8945a0SNathan Whitehorn 684c8945a0SNathan Whitehorn memset(&state, 0, sizeof(state)); 694c8945a0SNathan Whitehorn len = mbrlen(string, have, &state); 704c8945a0SNathan Whitehorn if ((int) len > 0 && len <= have) { 714c8945a0SNathan Whitehorn memset(&state, 0, sizeof(state)); 724c8945a0SNathan Whitehorn memset(cmp2, 0, sizeof(cmp2)); 734c8945a0SNathan Whitehorn check = mbrtowc(cmp2, string, len, &state); 744c8945a0SNathan Whitehorn if ((int) check <= 0) 754c8945a0SNathan Whitehorn cmp2[0] = 0; 764c8945a0SNathan Whitehorn *stringp += len; 774c8945a0SNathan Whitehorn } else { 784c8945a0SNathan Whitehorn cmp2[0] = UCH(*string); 794c8945a0SNathan Whitehorn *stringp += 1; 804c8945a0SNathan Whitehorn } 814c8945a0SNathan Whitehorn result = cmp2[0]; 824c8945a0SNathan Whitehorn #else 834c8945a0SNathan Whitehorn const char *string = *stringp; 844c8945a0SNathan Whitehorn result = UCH(*string); 854c8945a0SNathan Whitehorn *stringp += 1; 864c8945a0SNathan Whitehorn #endif 874c8945a0SNathan Whitehorn return result; 884c8945a0SNathan Whitehorn } 894c8945a0SNathan Whitehorn 902a3e3873SBaptiste Daroussin static size_t 912a3e3873SBaptiste Daroussin count_labels(const char **labels) 922a3e3873SBaptiste Daroussin { 932a3e3873SBaptiste Daroussin size_t result = 0; 942a3e3873SBaptiste Daroussin if (labels != 0) { 952a3e3873SBaptiste Daroussin while (*labels++ != 0) { 962a3e3873SBaptiste Daroussin ++result; 972a3e3873SBaptiste Daroussin } 982a3e3873SBaptiste Daroussin } 992a3e3873SBaptiste Daroussin return result; 1002a3e3873SBaptiste Daroussin } 1012a3e3873SBaptiste Daroussin 1022a3e3873SBaptiste Daroussin /* 1032a3e3873SBaptiste Daroussin * Check if the latest key should be added to the hotkey list. 1042a3e3873SBaptiste Daroussin */ 1052a3e3873SBaptiste Daroussin static int 1062a3e3873SBaptiste Daroussin was_hotkey(int this_key, int *used_keys, size_t next) 1072a3e3873SBaptiste Daroussin { 1082a3e3873SBaptiste Daroussin int result = FALSE; 1092a3e3873SBaptiste Daroussin 1102a3e3873SBaptiste Daroussin if (next != 0) { 1112a3e3873SBaptiste Daroussin size_t n; 1122a3e3873SBaptiste Daroussin for (n = 0; n < next; ++n) { 1132a3e3873SBaptiste Daroussin if (used_keys[n] == this_key) { 1142a3e3873SBaptiste Daroussin result = TRUE; 1152a3e3873SBaptiste Daroussin break; 1162a3e3873SBaptiste Daroussin } 1172a3e3873SBaptiste Daroussin } 1182a3e3873SBaptiste Daroussin } 1192a3e3873SBaptiste Daroussin return result; 1202a3e3873SBaptiste Daroussin } 1212a3e3873SBaptiste Daroussin 1222a3e3873SBaptiste Daroussin /* 1232a3e3873SBaptiste Daroussin * Determine the hot-keys for a set of button-labels. Normally these are 1242a3e3873SBaptiste Daroussin * the first uppercase character in each label. However, if more than one 1252a3e3873SBaptiste Daroussin * button has the same first-uppercase, then we will (attempt to) look for 1262a3e3873SBaptiste Daroussin * an alternate. 1272a3e3873SBaptiste Daroussin * 1282a3e3873SBaptiste Daroussin * This allocates data which must be freed by the caller. 1292a3e3873SBaptiste Daroussin */ 1302a3e3873SBaptiste Daroussin static int * 1312a3e3873SBaptiste Daroussin get_hotkeys(const char **labels) 1322a3e3873SBaptiste Daroussin { 1332a3e3873SBaptiste Daroussin int *result = 0; 1342a3e3873SBaptiste Daroussin size_t count = count_labels(labels); 1352a3e3873SBaptiste Daroussin size_t n; 1362a3e3873SBaptiste Daroussin 1372a3e3873SBaptiste Daroussin if ((result = dlg_calloc(int, count + 1)) != 0) { 1382a3e3873SBaptiste Daroussin for (n = 0; n < count; ++n) { 1392a3e3873SBaptiste Daroussin const char *label = labels[n]; 1402a3e3873SBaptiste Daroussin const int *indx = dlg_index_wchars(label); 1412a3e3873SBaptiste Daroussin int limit = dlg_count_wchars(label); 1422a3e3873SBaptiste Daroussin int i; 1432a3e3873SBaptiste Daroussin 1442a3e3873SBaptiste Daroussin for (i = 0; i < limit; ++i) { 1452a3e3873SBaptiste Daroussin int first = indx[i]; 1462a3e3873SBaptiste Daroussin int check = UCH(label[first]); 1472a3e3873SBaptiste Daroussin #ifdef USE_WIDE_CURSES 1482a3e3873SBaptiste Daroussin int last = indx[i + 1]; 1492a3e3873SBaptiste Daroussin if ((last - first) != 1) { 1502a3e3873SBaptiste Daroussin const char *temp = (label + first); 1512a3e3873SBaptiste Daroussin check = string_to_char(&temp); 1522a3e3873SBaptiste Daroussin } 1532a3e3873SBaptiste Daroussin #endif 1542a3e3873SBaptiste Daroussin if (dlg_isupper(check) && !was_hotkey(check, result, n)) { 1552a3e3873SBaptiste Daroussin result[n] = check; 1562a3e3873SBaptiste Daroussin break; 1572a3e3873SBaptiste Daroussin } 1582a3e3873SBaptiste Daroussin } 1592a3e3873SBaptiste Daroussin } 1602a3e3873SBaptiste Daroussin } 1612a3e3873SBaptiste Daroussin return result; 1622a3e3873SBaptiste Daroussin } 1632a3e3873SBaptiste Daroussin 164*f4f33ea0SBaptiste Daroussin typedef enum { 165*f4f33ea0SBaptiste Daroussin sFIND_KEY = 0 166*f4f33ea0SBaptiste Daroussin ,sHAVE_KEY = 1 167*f4f33ea0SBaptiste Daroussin ,sHAD_KEY = 2 168*f4f33ea0SBaptiste Daroussin } HOTKEY; 169*f4f33ea0SBaptiste Daroussin 1704c8945a0SNathan Whitehorn /* 1714c8945a0SNathan Whitehorn * Print a button 1724c8945a0SNathan Whitehorn */ 1734c8945a0SNathan Whitehorn static void 1742a3e3873SBaptiste Daroussin print_button(WINDOW *win, char *label, int hotkey, int y, int x, int selected) 1754c8945a0SNathan Whitehorn { 1764c8945a0SNathan Whitehorn int i; 177*f4f33ea0SBaptiste Daroussin HOTKEY state = sFIND_KEY; 1784c8945a0SNathan Whitehorn const int *indx = dlg_index_wchars(label); 1794c8945a0SNathan Whitehorn int limit = dlg_count_wchars(label); 1804c8945a0SNathan Whitehorn chtype key_attr = (selected 1814c8945a0SNathan Whitehorn ? button_key_active_attr 1824c8945a0SNathan Whitehorn : button_key_inactive_attr); 1834c8945a0SNathan Whitehorn chtype label_attr = (selected 1844c8945a0SNathan Whitehorn ? button_label_active_attr 1854c8945a0SNathan Whitehorn : button_label_inactive_attr); 1864c8945a0SNathan Whitehorn 1874c8945a0SNathan Whitehorn (void) wmove(win, y, x); 188*f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected 1894c8945a0SNathan Whitehorn ? button_active_attr 1904c8945a0SNathan Whitehorn : button_inactive_attr); 1914c8945a0SNathan Whitehorn (void) waddstr(win, "<"); 192*f4f33ea0SBaptiste Daroussin dlg_attrset(win, label_attr); 1934c8945a0SNathan Whitehorn for (i = 0; i < limit; ++i) { 1942a3e3873SBaptiste Daroussin int check; 1954c8945a0SNathan Whitehorn int first = indx[i]; 1964c8945a0SNathan Whitehorn int last = indx[i + 1]; 1974c8945a0SNathan Whitehorn 1984c8945a0SNathan Whitehorn switch (state) { 199*f4f33ea0SBaptiste Daroussin case sFIND_KEY: 2002a3e3873SBaptiste Daroussin check = UCH(label[first]); 2014c8945a0SNathan Whitehorn #ifdef USE_WIDE_CURSES 2024c8945a0SNathan Whitehorn if ((last - first) != 1) { 2034c8945a0SNathan Whitehorn const char *temp = (label + first); 2042a3e3873SBaptiste Daroussin check = string_to_char(&temp); 2054c8945a0SNathan Whitehorn } 2064c8945a0SNathan Whitehorn #endif 2072a3e3873SBaptiste Daroussin if (check == hotkey) { 208*f4f33ea0SBaptiste Daroussin dlg_attrset(win, key_attr); 209*f4f33ea0SBaptiste Daroussin state = sHAVE_KEY; 2104c8945a0SNathan Whitehorn } 2114c8945a0SNathan Whitehorn break; 212*f4f33ea0SBaptiste Daroussin case sHAVE_KEY: 213*f4f33ea0SBaptiste Daroussin dlg_attrset(win, label_attr); 214*f4f33ea0SBaptiste Daroussin state = sHAD_KEY; 215*f4f33ea0SBaptiste Daroussin break; 216*f4f33ea0SBaptiste Daroussin default: 2174c8945a0SNathan Whitehorn break; 2184c8945a0SNathan Whitehorn } 2194c8945a0SNathan Whitehorn waddnstr(win, label + first, last - first); 2204c8945a0SNathan Whitehorn } 221*f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected 2224c8945a0SNathan Whitehorn ? button_active_attr 2234c8945a0SNathan Whitehorn : button_inactive_attr); 2244c8945a0SNathan Whitehorn (void) waddstr(win, ">"); 225*f4f33ea0SBaptiste Daroussin (void) wmove(win, y, x + ((int) (strspn) (label, " ")) + 1); 2264c8945a0SNathan Whitehorn } 2274c8945a0SNathan Whitehorn 2284c8945a0SNathan Whitehorn /* 2294c8945a0SNathan Whitehorn * Count the buttons in the list. 2304c8945a0SNathan Whitehorn */ 2314c8945a0SNathan Whitehorn int 2324c8945a0SNathan Whitehorn dlg_button_count(const char **labels) 2334c8945a0SNathan Whitehorn { 2344c8945a0SNathan Whitehorn int result = 0; 2354c8945a0SNathan Whitehorn while (*labels++ != 0) 2364c8945a0SNathan Whitehorn ++result; 2374c8945a0SNathan Whitehorn return result; 2384c8945a0SNathan Whitehorn } 2394c8945a0SNathan Whitehorn 2404c8945a0SNathan Whitehorn /* 2414c8945a0SNathan Whitehorn * Compute the size of the button array in columns. Return the total number of 2424c8945a0SNathan Whitehorn * columns in *length, and the longest button's columns in *longest 2434c8945a0SNathan Whitehorn */ 2444c8945a0SNathan Whitehorn void 2454c8945a0SNathan Whitehorn dlg_button_sizes(const char **labels, 2464c8945a0SNathan Whitehorn int vertical, 2474c8945a0SNathan Whitehorn int *longest, 2484c8945a0SNathan Whitehorn int *length) 2494c8945a0SNathan Whitehorn { 2504c8945a0SNathan Whitehorn int n; 2514c8945a0SNathan Whitehorn 2524c8945a0SNathan Whitehorn *length = 0; 2534c8945a0SNathan Whitehorn *longest = 0; 2544c8945a0SNathan Whitehorn for (n = 0; labels[n] != 0; n++) { 2554c8945a0SNathan Whitehorn if (vertical) { 2564c8945a0SNathan Whitehorn *length += 1; 2574c8945a0SNathan Whitehorn *longest = 1; 2584c8945a0SNathan Whitehorn } else { 2594c8945a0SNathan Whitehorn int len = dlg_count_columns(labels[n]); 2604c8945a0SNathan Whitehorn if (len > *longest) 2614c8945a0SNathan Whitehorn *longest = len; 2624c8945a0SNathan Whitehorn *length += len; 2634c8945a0SNathan Whitehorn } 2644c8945a0SNathan Whitehorn } 2654c8945a0SNathan Whitehorn /* 2664c8945a0SNathan Whitehorn * If we can, make all of the buttons the same size. This is only optional 2674c8945a0SNathan Whitehorn * for buttons laid out horizontally. 2684c8945a0SNathan Whitehorn */ 2694c8945a0SNathan Whitehorn if (*longest < 6 - (*longest & 1)) 2704c8945a0SNathan Whitehorn *longest = 6 - (*longest & 1); 2714c8945a0SNathan Whitehorn if (!vertical) 2724c8945a0SNathan Whitehorn *length = *longest * n; 2734c8945a0SNathan Whitehorn } 2744c8945a0SNathan Whitehorn 2754c8945a0SNathan Whitehorn /* 2764c8945a0SNathan Whitehorn * Compute the size of the button array. 2774c8945a0SNathan Whitehorn */ 2784c8945a0SNathan Whitehorn int 2794c8945a0SNathan Whitehorn dlg_button_x_step(const char **labels, int limit, int *gap, int *margin, int *step) 2804c8945a0SNathan Whitehorn { 2814c8945a0SNathan Whitehorn int count = dlg_button_count(labels); 2824c8945a0SNathan Whitehorn int longest; 2834c8945a0SNathan Whitehorn int length; 2844c8945a0SNathan Whitehorn int unused; 2854c8945a0SNathan Whitehorn int used; 2862a3e3873SBaptiste Daroussin int result; 2874c8945a0SNathan Whitehorn 2882a3e3873SBaptiste Daroussin *margin = 0; 2892a3e3873SBaptiste Daroussin if (count != 0) { 2904c8945a0SNathan Whitehorn dlg_button_sizes(labels, FALSE, &longest, &length); 2914c8945a0SNathan Whitehorn used = (length + (count * 2)); 2924c8945a0SNathan Whitehorn unused = limit - used; 2934c8945a0SNathan Whitehorn 2944c8945a0SNathan Whitehorn if ((*gap = unused / (count + 3)) <= 0) { 2954c8945a0SNathan Whitehorn if ((*gap = unused / (count + 1)) <= 0) 2964c8945a0SNathan Whitehorn *gap = 1; 2974c8945a0SNathan Whitehorn *margin = *gap; 2984c8945a0SNathan Whitehorn } else { 2994c8945a0SNathan Whitehorn *margin = *gap * 2; 3004c8945a0SNathan Whitehorn } 3014c8945a0SNathan Whitehorn *step = *gap + (used + count - 1) / count; 3022a3e3873SBaptiste Daroussin result = (*gap > 0) && (unused >= 0); 3032a3e3873SBaptiste Daroussin } else { 3042a3e3873SBaptiste Daroussin result = 0; 3052a3e3873SBaptiste Daroussin } 3062a3e3873SBaptiste Daroussin return result; 3074c8945a0SNathan Whitehorn } 3084c8945a0SNathan Whitehorn 3094c8945a0SNathan Whitehorn /* 3104c8945a0SNathan Whitehorn * Make sure there is enough space for the buttons 3114c8945a0SNathan Whitehorn */ 3124c8945a0SNathan Whitehorn void 3134c8945a0SNathan Whitehorn dlg_button_layout(const char **labels, int *limit) 3144c8945a0SNathan Whitehorn { 3154c8945a0SNathan Whitehorn int width = 1; 3164c8945a0SNathan Whitehorn int gap, margin, step; 3174c8945a0SNathan Whitehorn 3184c8945a0SNathan Whitehorn if (labels != 0 && dlg_button_count(labels)) { 3194c8945a0SNathan Whitehorn while (!dlg_button_x_step(labels, width, &gap, &margin, &step)) 3204c8945a0SNathan Whitehorn ++width; 3214c8945a0SNathan Whitehorn width += (4 * MARGIN); 3224c8945a0SNathan Whitehorn if (width > COLS) 3234c8945a0SNathan Whitehorn width = COLS; 3244c8945a0SNathan Whitehorn if (width > *limit) 3254c8945a0SNathan Whitehorn *limit = width; 3264c8945a0SNathan Whitehorn } 3274c8945a0SNathan Whitehorn } 3284c8945a0SNathan Whitehorn 3294c8945a0SNathan Whitehorn /* 3304c8945a0SNathan Whitehorn * Print a list of buttons at the given position. 3314c8945a0SNathan Whitehorn */ 3324c8945a0SNathan Whitehorn void 3334c8945a0SNathan Whitehorn dlg_draw_buttons(WINDOW *win, 3344c8945a0SNathan Whitehorn int y, int x, 3354c8945a0SNathan Whitehorn const char **labels, 3364c8945a0SNathan Whitehorn int selected, 3374c8945a0SNathan Whitehorn int vertical, 3384c8945a0SNathan Whitehorn int limit) 3394c8945a0SNathan Whitehorn { 3407a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win); 3414c8945a0SNathan Whitehorn int n; 3424c8945a0SNathan Whitehorn int step = 0; 3434c8945a0SNathan Whitehorn int length; 3444c8945a0SNathan Whitehorn int longest; 3454c8945a0SNathan Whitehorn int final_x; 3464c8945a0SNathan Whitehorn int final_y; 3474c8945a0SNathan Whitehorn int gap; 3484c8945a0SNathan Whitehorn int margin; 3494c8945a0SNathan Whitehorn size_t need; 3504c8945a0SNathan Whitehorn char *buffer; 3514c8945a0SNathan Whitehorn 3524c8945a0SNathan Whitehorn dlg_mouse_setbase(getbegx(win), getbegy(win)); 3534c8945a0SNathan Whitehorn 3544c8945a0SNathan Whitehorn getyx(win, final_y, final_x); 3554c8945a0SNathan Whitehorn 3564c8945a0SNathan Whitehorn dlg_button_sizes(labels, vertical, &longest, &length); 3574c8945a0SNathan Whitehorn 3584c8945a0SNathan Whitehorn if (vertical) { 3594c8945a0SNathan Whitehorn y += 1; 3604c8945a0SNathan Whitehorn step = 1; 3614c8945a0SNathan Whitehorn } else { 3624c8945a0SNathan Whitehorn dlg_button_x_step(labels, limit, &gap, &margin, &step); 3634c8945a0SNathan Whitehorn x += margin; 3644c8945a0SNathan Whitehorn } 3654c8945a0SNathan Whitehorn 3664c8945a0SNathan Whitehorn /* 3674c8945a0SNathan Whitehorn * Allocate a buffer big enough for any label. 3684c8945a0SNathan Whitehorn */ 3694c8945a0SNathan Whitehorn need = (size_t) longest; 3702a3e3873SBaptiste Daroussin if (need != 0) { 3712a3e3873SBaptiste Daroussin int *hotkeys = get_hotkeys(labels); 3722a3e3873SBaptiste Daroussin assert_ptr(hotkeys, "dlg_draw_buttons"); 3732a3e3873SBaptiste Daroussin 3744c8945a0SNathan Whitehorn for (n = 0; labels[n] != 0; ++n) { 3754c8945a0SNathan Whitehorn need += strlen(labels[n]) + 1; 3764c8945a0SNathan Whitehorn } 3774c8945a0SNathan Whitehorn buffer = dlg_malloc(char, need); 3784c8945a0SNathan Whitehorn assert_ptr(buffer, "dlg_draw_buttons"); 3794c8945a0SNathan Whitehorn 3804c8945a0SNathan Whitehorn /* 3814c8945a0SNathan Whitehorn * Draw the labels. 3824c8945a0SNathan Whitehorn */ 3834c8945a0SNathan Whitehorn for (n = 0; labels[n] != 0; n++) { 3844c8945a0SNathan Whitehorn center_label(buffer, longest, labels[n]); 3854c8945a0SNathan Whitehorn mouse_mkbutton(y, x, dlg_count_columns(buffer), n); 386*f4f33ea0SBaptiste Daroussin print_button(win, buffer, 387*f4f33ea0SBaptiste Daroussin CHR_BUTTON ? hotkeys[n] : -1, 388*f4f33ea0SBaptiste Daroussin y, x, 3894c8945a0SNathan Whitehorn (selected == n) || (n == 0 && selected < 0)); 3904c8945a0SNathan Whitehorn if (selected == n) 3914c8945a0SNathan Whitehorn getyx(win, final_y, final_x); 3924c8945a0SNathan Whitehorn 3934c8945a0SNathan Whitehorn if (vertical) { 3944c8945a0SNathan Whitehorn if ((y += step) > limit) 3954c8945a0SNathan Whitehorn break; 3964c8945a0SNathan Whitehorn } else { 3974c8945a0SNathan Whitehorn if ((x += step) > limit) 3984c8945a0SNathan Whitehorn break; 3994c8945a0SNathan Whitehorn } 4004c8945a0SNathan Whitehorn } 4014c8945a0SNathan Whitehorn (void) wmove(win, final_y, final_x); 4024c8945a0SNathan Whitehorn wrefresh(win); 403*f4f33ea0SBaptiste Daroussin dlg_attrset(win, save); 4044c8945a0SNathan Whitehorn free(buffer); 4052a3e3873SBaptiste Daroussin free(hotkeys); 4062a3e3873SBaptiste Daroussin } 4074c8945a0SNathan Whitehorn } 4084c8945a0SNathan Whitehorn 4094c8945a0SNathan Whitehorn /* 4104c8945a0SNathan Whitehorn * Match a given character against the beginning of the string, ignoring case 4114c8945a0SNathan Whitehorn * of the given character. The matching string must begin with an uppercase 4124c8945a0SNathan Whitehorn * character. 4134c8945a0SNathan Whitehorn */ 4144c8945a0SNathan Whitehorn int 4154c8945a0SNathan Whitehorn dlg_match_char(int ch, const char *string) 4164c8945a0SNathan Whitehorn { 4174c8945a0SNathan Whitehorn if (string != 0) { 4184c8945a0SNathan Whitehorn int cmp2 = string_to_char(&string); 4194c8945a0SNathan Whitehorn #ifdef USE_WIDE_CURSES 4204c8945a0SNathan Whitehorn wint_t cmp1 = dlg_toupper(ch); 4214c8945a0SNathan Whitehorn if (cmp2 != 0 && (wchar_t) cmp1 == (wchar_t) dlg_toupper(cmp2)) { 4224c8945a0SNathan Whitehorn return TRUE; 4234c8945a0SNathan Whitehorn } 4244c8945a0SNathan Whitehorn #else 4254c8945a0SNathan Whitehorn if (ch > 0 && ch < 256) { 4264c8945a0SNathan Whitehorn if (dlg_toupper(ch) == dlg_toupper(cmp2)) 4274c8945a0SNathan Whitehorn return TRUE; 4284c8945a0SNathan Whitehorn } 4294c8945a0SNathan Whitehorn #endif 4304c8945a0SNathan Whitehorn } 4314c8945a0SNathan Whitehorn return FALSE; 4324c8945a0SNathan Whitehorn } 4334c8945a0SNathan Whitehorn 4344c8945a0SNathan Whitehorn /* 4354c8945a0SNathan Whitehorn * Find the first uppercase character in the label, which we may use for an 4364c8945a0SNathan Whitehorn * abbreviation. 4374c8945a0SNathan Whitehorn */ 4384c8945a0SNathan Whitehorn int 4394c8945a0SNathan Whitehorn dlg_button_to_char(const char *label) 4404c8945a0SNathan Whitehorn { 4414c8945a0SNathan Whitehorn int cmp = -1; 4424c8945a0SNathan Whitehorn 4434c8945a0SNathan Whitehorn while (*label != 0) { 4444c8945a0SNathan Whitehorn cmp = string_to_char(&label); 4454c8945a0SNathan Whitehorn if (dlg_isupper(cmp)) { 4464c8945a0SNathan Whitehorn break; 4474c8945a0SNathan Whitehorn } 4484c8945a0SNathan Whitehorn } 4494c8945a0SNathan Whitehorn return cmp; 4504c8945a0SNathan Whitehorn } 4514c8945a0SNathan Whitehorn 4524c8945a0SNathan Whitehorn /* 4534c8945a0SNathan Whitehorn * Given a list of button labels, and a character which may be the abbreviation 4544c8945a0SNathan Whitehorn * for one, find it, if it exists. An abbreviation will be the first character 4554c8945a0SNathan Whitehorn * which happens to be capitalized in the label. 4564c8945a0SNathan Whitehorn */ 4574c8945a0SNathan Whitehorn int 4584c8945a0SNathan Whitehorn dlg_char_to_button(int ch, const char **labels) 4594c8945a0SNathan Whitehorn { 4602a3e3873SBaptiste Daroussin int result = DLG_EXIT_UNKNOWN; 4612a3e3873SBaptiste Daroussin 4624c8945a0SNathan Whitehorn if (labels != 0) { 4632a3e3873SBaptiste Daroussin int *hotkeys = get_hotkeys(labels); 4644c8945a0SNathan Whitehorn int j; 4654c8945a0SNathan Whitehorn 4664c8945a0SNathan Whitehorn ch = (int) dlg_toupper(dlg_last_getc()); 4672a3e3873SBaptiste Daroussin 4682a3e3873SBaptiste Daroussin if (hotkeys != 0) { 4694c8945a0SNathan Whitehorn for (j = 0; labels[j] != 0; ++j) { 4702a3e3873SBaptiste Daroussin if (ch == hotkeys[j]) { 4714c8945a0SNathan Whitehorn dlg_flush_getc(); 4722a3e3873SBaptiste Daroussin result = j; 4732a3e3873SBaptiste Daroussin break; 4744c8945a0SNathan Whitehorn } 4754c8945a0SNathan Whitehorn } 4762a3e3873SBaptiste Daroussin free(hotkeys); 4774c8945a0SNathan Whitehorn } 4782a3e3873SBaptiste Daroussin } 4792a3e3873SBaptiste Daroussin 4802a3e3873SBaptiste Daroussin return result; 4814c8945a0SNathan Whitehorn } 4824c8945a0SNathan Whitehorn 4834c8945a0SNathan Whitehorn static const char * 4844c8945a0SNathan Whitehorn my_yes_label(void) 4854c8945a0SNathan Whitehorn { 4864c8945a0SNathan Whitehorn return (dialog_vars.yes_label != NULL) 4874c8945a0SNathan Whitehorn ? dialog_vars.yes_label 4884c8945a0SNathan Whitehorn : _("Yes"); 4894c8945a0SNathan Whitehorn } 4904c8945a0SNathan Whitehorn 4914c8945a0SNathan Whitehorn static const char * 4924c8945a0SNathan Whitehorn my_no_label(void) 4934c8945a0SNathan Whitehorn { 4944c8945a0SNathan Whitehorn return (dialog_vars.no_label != NULL) 4954c8945a0SNathan Whitehorn ? dialog_vars.no_label 4964c8945a0SNathan Whitehorn : _("No"); 4974c8945a0SNathan Whitehorn } 4984c8945a0SNathan Whitehorn 4994c8945a0SNathan Whitehorn static const char * 5004c8945a0SNathan Whitehorn my_ok_label(void) 5014c8945a0SNathan Whitehorn { 5024c8945a0SNathan Whitehorn return (dialog_vars.ok_label != NULL) 5034c8945a0SNathan Whitehorn ? dialog_vars.ok_label 5044c8945a0SNathan Whitehorn : _("OK"); 5054c8945a0SNathan Whitehorn } 5064c8945a0SNathan Whitehorn 5074c8945a0SNathan Whitehorn static const char * 5084c8945a0SNathan Whitehorn my_cancel_label(void) 5094c8945a0SNathan Whitehorn { 5104c8945a0SNathan Whitehorn return (dialog_vars.cancel_label != NULL) 5114c8945a0SNathan Whitehorn ? dialog_vars.cancel_label 5124c8945a0SNathan Whitehorn : _("Cancel"); 5134c8945a0SNathan Whitehorn } 5144c8945a0SNathan Whitehorn 5154c8945a0SNathan Whitehorn static const char * 5164c8945a0SNathan Whitehorn my_exit_label(void) 5174c8945a0SNathan Whitehorn { 5184c8945a0SNathan Whitehorn return (dialog_vars.exit_label != NULL) 5194c8945a0SNathan Whitehorn ? dialog_vars.exit_label 5204c8945a0SNathan Whitehorn : _("EXIT"); 5214c8945a0SNathan Whitehorn } 5224c8945a0SNathan Whitehorn 5234c8945a0SNathan Whitehorn static const char * 5244c8945a0SNathan Whitehorn my_extra_label(void) 5254c8945a0SNathan Whitehorn { 5264c8945a0SNathan Whitehorn return (dialog_vars.extra_label != NULL) 5274c8945a0SNathan Whitehorn ? dialog_vars.extra_label 5284c8945a0SNathan Whitehorn : _("Extra"); 5294c8945a0SNathan Whitehorn } 5304c8945a0SNathan Whitehorn 5314c8945a0SNathan Whitehorn static const char * 5324c8945a0SNathan Whitehorn my_help_label(void) 5334c8945a0SNathan Whitehorn { 5344c8945a0SNathan Whitehorn return (dialog_vars.help_label != NULL) 5354c8945a0SNathan Whitehorn ? dialog_vars.help_label 5364c8945a0SNathan Whitehorn : _("Help"); 5374c8945a0SNathan Whitehorn } 5384c8945a0SNathan Whitehorn 5394c8945a0SNathan Whitehorn /* 5404c8945a0SNathan Whitehorn * Return a list of button labels. 5414c8945a0SNathan Whitehorn */ 5424c8945a0SNathan Whitehorn const char ** 5434c8945a0SNathan Whitehorn dlg_exit_label(void) 5444c8945a0SNathan Whitehorn { 5454c8945a0SNathan Whitehorn const char **result; 546682c9e0fSNathan Whitehorn DIALOG_VARS save; 5474c8945a0SNathan Whitehorn 5484c8945a0SNathan Whitehorn if (dialog_vars.extra_button) { 549682c9e0fSNathan Whitehorn dlg_save_vars(&save); 550682c9e0fSNathan Whitehorn dialog_vars.nocancel = TRUE; 5514c8945a0SNathan Whitehorn result = dlg_ok_labels(); 552682c9e0fSNathan Whitehorn dlg_restore_vars(&save); 5534c8945a0SNathan Whitehorn } else { 5544c8945a0SNathan Whitehorn static const char *labels[3]; 5554c8945a0SNathan Whitehorn int n = 0; 5564c8945a0SNathan Whitehorn 557682c9e0fSNathan Whitehorn if (!dialog_vars.nook) 5584c8945a0SNathan Whitehorn labels[n++] = my_exit_label(); 5594c8945a0SNathan Whitehorn if (dialog_vars.help_button) 5604c8945a0SNathan Whitehorn labels[n++] = my_help_label(); 561682c9e0fSNathan Whitehorn if (n == 0) 562682c9e0fSNathan Whitehorn labels[n++] = my_exit_label(); 5634c8945a0SNathan Whitehorn labels[n] = 0; 5644c8945a0SNathan Whitehorn 5654c8945a0SNathan Whitehorn result = labels; 5664c8945a0SNathan Whitehorn } 5674c8945a0SNathan Whitehorn return result; 5684c8945a0SNathan Whitehorn } 5694c8945a0SNathan Whitehorn 5704c8945a0SNathan Whitehorn /* 5714c8945a0SNathan Whitehorn * Map the given button index for dlg_exit_label() into our exit-code. 5724c8945a0SNathan Whitehorn */ 5734c8945a0SNathan Whitehorn int 5744c8945a0SNathan Whitehorn dlg_exit_buttoncode(int button) 5754c8945a0SNathan Whitehorn { 576682c9e0fSNathan Whitehorn int result; 577682c9e0fSNathan Whitehorn DIALOG_VARS save; 578682c9e0fSNathan Whitehorn 579682c9e0fSNathan Whitehorn dlg_save_vars(&save); 580682c9e0fSNathan Whitehorn dialog_vars.nocancel = TRUE; 581682c9e0fSNathan Whitehorn 582682c9e0fSNathan Whitehorn result = dlg_ok_buttoncode(button); 583682c9e0fSNathan Whitehorn 584682c9e0fSNathan Whitehorn dlg_restore_vars(&save); 585682c9e0fSNathan Whitehorn 586682c9e0fSNathan Whitehorn return result; 5874c8945a0SNathan Whitehorn } 5884c8945a0SNathan Whitehorn 5894c8945a0SNathan Whitehorn const char ** 5904c8945a0SNathan Whitehorn dlg_ok_label(void) 5914c8945a0SNathan Whitehorn { 5922a3e3873SBaptiste Daroussin static const char *labels[4]; 5934c8945a0SNathan Whitehorn int n = 0; 5944c8945a0SNathan Whitehorn 5954c8945a0SNathan Whitehorn labels[n++] = my_ok_label(); 5962a3e3873SBaptiste Daroussin if (dialog_vars.extra_button) 5972a3e3873SBaptiste Daroussin labels[n++] = my_extra_label(); 5984c8945a0SNathan Whitehorn if (dialog_vars.help_button) 5994c8945a0SNathan Whitehorn labels[n++] = my_help_label(); 6004c8945a0SNathan Whitehorn labels[n] = 0; 6014c8945a0SNathan Whitehorn return labels; 6024c8945a0SNathan Whitehorn } 6034c8945a0SNathan Whitehorn 6044c8945a0SNathan Whitehorn /* 6054c8945a0SNathan Whitehorn * Return a list of button labels for the OK/Cancel group. 6064c8945a0SNathan Whitehorn */ 6074c8945a0SNathan Whitehorn const char ** 6084c8945a0SNathan Whitehorn dlg_ok_labels(void) 6094c8945a0SNathan Whitehorn { 6104c8945a0SNathan Whitehorn static const char *labels[5]; 6114c8945a0SNathan Whitehorn int n = 0; 6124c8945a0SNathan Whitehorn 6134c8945a0SNathan Whitehorn if (!dialog_vars.nook) 6144c8945a0SNathan Whitehorn labels[n++] = my_ok_label(); 6154c8945a0SNathan Whitehorn if (dialog_vars.extra_button) 6164c8945a0SNathan Whitehorn labels[n++] = my_extra_label(); 6174c8945a0SNathan Whitehorn if (!dialog_vars.nocancel) 6184c8945a0SNathan Whitehorn labels[n++] = my_cancel_label(); 6194c8945a0SNathan Whitehorn if (dialog_vars.help_button) 6204c8945a0SNathan Whitehorn labels[n++] = my_help_label(); 6214c8945a0SNathan Whitehorn labels[n] = 0; 6224c8945a0SNathan Whitehorn return labels; 6234c8945a0SNathan Whitehorn } 6244c8945a0SNathan Whitehorn 6254c8945a0SNathan Whitehorn /* 6264c8945a0SNathan Whitehorn * Map the given button index for dlg_ok_labels() into our exit-code 6274c8945a0SNathan Whitehorn */ 6284c8945a0SNathan Whitehorn int 6294c8945a0SNathan Whitehorn dlg_ok_buttoncode(int button) 6304c8945a0SNathan Whitehorn { 6314c8945a0SNathan Whitehorn int result = DLG_EXIT_ERROR; 6324c8945a0SNathan Whitehorn int n = !dialog_vars.nook; 6334c8945a0SNathan Whitehorn 6344c8945a0SNathan Whitehorn if (!dialog_vars.nook && (button <= 0)) { 6354c8945a0SNathan Whitehorn result = DLG_EXIT_OK; 6364c8945a0SNathan Whitehorn } else if (dialog_vars.extra_button && (button == n++)) { 6374c8945a0SNathan Whitehorn result = DLG_EXIT_EXTRA; 6384c8945a0SNathan Whitehorn } else if (!dialog_vars.nocancel && (button == n++)) { 6394c8945a0SNathan Whitehorn result = DLG_EXIT_CANCEL; 6404c8945a0SNathan Whitehorn } else if (dialog_vars.help_button && (button == n)) { 6414c8945a0SNathan Whitehorn result = DLG_EXIT_HELP; 6424c8945a0SNathan Whitehorn } 643*f4f33ea0SBaptiste Daroussin DLG_TRACE(("# dlg_ok_buttoncode(%d) = %d\n", button, result)); 6444c8945a0SNathan Whitehorn return result; 6454c8945a0SNathan Whitehorn } 6464c8945a0SNathan Whitehorn 6474c8945a0SNathan Whitehorn /* 6484c8945a0SNathan Whitehorn * Given that we're using dlg_ok_labels() to list buttons, find the next index 6494c8945a0SNathan Whitehorn * in the list of buttons. The 'extra' parameter if negative provides a way to 6504c8945a0SNathan Whitehorn * enumerate extra active areas on the widget. 6514c8945a0SNathan Whitehorn */ 6524c8945a0SNathan Whitehorn int 6534c8945a0SNathan Whitehorn dlg_next_ok_buttonindex(int current, int extra) 6544c8945a0SNathan Whitehorn { 6554c8945a0SNathan Whitehorn int result = current + 1; 6564c8945a0SNathan Whitehorn 6574c8945a0SNathan Whitehorn if (current >= 0 6584c8945a0SNathan Whitehorn && dlg_ok_buttoncode(result) < 0) 6594c8945a0SNathan Whitehorn result = extra; 6604c8945a0SNathan Whitehorn return result; 6614c8945a0SNathan Whitehorn } 6624c8945a0SNathan Whitehorn 6634c8945a0SNathan Whitehorn /* 6644c8945a0SNathan Whitehorn * Similarly, find the previous button index. 6654c8945a0SNathan Whitehorn */ 6664c8945a0SNathan Whitehorn int 6674c8945a0SNathan Whitehorn dlg_prev_ok_buttonindex(int current, int extra) 6684c8945a0SNathan Whitehorn { 6694c8945a0SNathan Whitehorn int result = current - 1; 6704c8945a0SNathan Whitehorn 6714c8945a0SNathan Whitehorn if (result < extra) { 6724c8945a0SNathan Whitehorn for (result = 0; dlg_ok_buttoncode(result + 1) >= 0; ++result) { 6734c8945a0SNathan Whitehorn ; 6744c8945a0SNathan Whitehorn } 6754c8945a0SNathan Whitehorn } 6764c8945a0SNathan Whitehorn return result; 6774c8945a0SNathan Whitehorn } 6784c8945a0SNathan Whitehorn 6794c8945a0SNathan Whitehorn /* 6804c8945a0SNathan Whitehorn * Find the button-index for the "OK" or "Cancel" button, according to 6814c8945a0SNathan Whitehorn * whether --defaultno is given. If --nocancel was given, we always return 6822a3e3873SBaptiste Daroussin * the index for the first button (usually "OK" unless --nook was used). 6834c8945a0SNathan Whitehorn */ 6844c8945a0SNathan Whitehorn int 6854c8945a0SNathan Whitehorn dlg_defaultno_button(void) 6864c8945a0SNathan Whitehorn { 6874c8945a0SNathan Whitehorn int result = 0; 6884c8945a0SNathan Whitehorn 6894c8945a0SNathan Whitehorn if (dialog_vars.defaultno && !dialog_vars.nocancel) { 6904c8945a0SNathan Whitehorn while (dlg_ok_buttoncode(result) != DLG_EXIT_CANCEL) 6914c8945a0SNathan Whitehorn ++result; 6924c8945a0SNathan Whitehorn } 693*f4f33ea0SBaptiste Daroussin DLG_TRACE(("# dlg_defaultno_button() = %d\n", result)); 6942a3e3873SBaptiste Daroussin return result; 6952a3e3873SBaptiste Daroussin } 6962a3e3873SBaptiste Daroussin 6972a3e3873SBaptiste Daroussin /* 6982a3e3873SBaptiste Daroussin * Find the button-index for a button named with --default-button. If the 6992a3e3873SBaptiste Daroussin * option was not specified, or if the selected button does not exist, return 7002a3e3873SBaptiste Daroussin * the index of the first button (usually "OK" unless --nook was used). 7012a3e3873SBaptiste Daroussin */ 7022a3e3873SBaptiste Daroussin int 7032a3e3873SBaptiste Daroussin dlg_default_button(void) 7042a3e3873SBaptiste Daroussin { 7052a3e3873SBaptiste Daroussin int i, n; 7062a3e3873SBaptiste Daroussin int result = 0; 7072a3e3873SBaptiste Daroussin 7082a3e3873SBaptiste Daroussin if (dialog_vars.default_button >= 0) { 7092a3e3873SBaptiste Daroussin for (i = 0; (n = dlg_ok_buttoncode(i)) >= 0; i++) { 7102a3e3873SBaptiste Daroussin if (n == dialog_vars.default_button) { 7112a3e3873SBaptiste Daroussin result = i; 7122a3e3873SBaptiste Daroussin break; 7132a3e3873SBaptiste Daroussin } 7142a3e3873SBaptiste Daroussin } 7152a3e3873SBaptiste Daroussin } 716*f4f33ea0SBaptiste Daroussin DLG_TRACE(("# dlg_default_button() = %d\n", result)); 7174c8945a0SNathan Whitehorn return result; 7184c8945a0SNathan Whitehorn } 7194c8945a0SNathan Whitehorn 7204c8945a0SNathan Whitehorn /* 7214c8945a0SNathan Whitehorn * Return a list of buttons for Yes/No labels. 7224c8945a0SNathan Whitehorn */ 7234c8945a0SNathan Whitehorn const char ** 7244c8945a0SNathan Whitehorn dlg_yes_labels(void) 7254c8945a0SNathan Whitehorn { 7264c8945a0SNathan Whitehorn const char **result; 7274c8945a0SNathan Whitehorn 7284c8945a0SNathan Whitehorn if (dialog_vars.extra_button) { 7294c8945a0SNathan Whitehorn result = dlg_ok_labels(); 7304c8945a0SNathan Whitehorn } else { 7314c8945a0SNathan Whitehorn static const char *labels[4]; 7324c8945a0SNathan Whitehorn int n = 0; 7334c8945a0SNathan Whitehorn 7344c8945a0SNathan Whitehorn labels[n++] = my_yes_label(); 7354c8945a0SNathan Whitehorn labels[n++] = my_no_label(); 7364c8945a0SNathan Whitehorn if (dialog_vars.help_button) 7374c8945a0SNathan Whitehorn labels[n++] = my_help_label(); 7384c8945a0SNathan Whitehorn labels[n] = 0; 7394c8945a0SNathan Whitehorn 7404c8945a0SNathan Whitehorn result = labels; 7414c8945a0SNathan Whitehorn } 7424c8945a0SNathan Whitehorn 7434c8945a0SNathan Whitehorn return result; 7444c8945a0SNathan Whitehorn } 7454c8945a0SNathan Whitehorn 7464c8945a0SNathan Whitehorn /* 7474c8945a0SNathan Whitehorn * Map the given button index for dlg_yes_labels() into our exit-code. 7484c8945a0SNathan Whitehorn */ 7494c8945a0SNathan Whitehorn int 7504c8945a0SNathan Whitehorn dlg_yes_buttoncode(int button) 7514c8945a0SNathan Whitehorn { 7524c8945a0SNathan Whitehorn int result = DLG_EXIT_ERROR; 7534c8945a0SNathan Whitehorn 7544c8945a0SNathan Whitehorn if (dialog_vars.extra_button) { 7554c8945a0SNathan Whitehorn result = dlg_ok_buttoncode(button); 7564c8945a0SNathan Whitehorn } else if (button == 0) { 7574c8945a0SNathan Whitehorn result = DLG_EXIT_OK; 7584c8945a0SNathan Whitehorn } else if (button == 1) { 7594c8945a0SNathan Whitehorn result = DLG_EXIT_CANCEL; 7604c8945a0SNathan Whitehorn } else if (button == 2 && dialog_vars.help_button) { 7614c8945a0SNathan Whitehorn result = DLG_EXIT_HELP; 7624c8945a0SNathan Whitehorn } 7634c8945a0SNathan Whitehorn 7644c8945a0SNathan Whitehorn return result; 7654c8945a0SNathan Whitehorn } 7664c8945a0SNathan Whitehorn 7674c8945a0SNathan Whitehorn /* 7684c8945a0SNathan Whitehorn * Return the next index in labels[]; 7694c8945a0SNathan Whitehorn */ 7704c8945a0SNathan Whitehorn int 7714c8945a0SNathan Whitehorn dlg_next_button(const char **labels, int button) 7724c8945a0SNathan Whitehorn { 7732a3e3873SBaptiste Daroussin if (button < -1) 7742a3e3873SBaptiste Daroussin button = -1; 7752a3e3873SBaptiste Daroussin 7762a3e3873SBaptiste Daroussin if (labels[button + 1] != 0) { 7774c8945a0SNathan Whitehorn ++button; 7782a3e3873SBaptiste Daroussin } else { 7794c8945a0SNathan Whitehorn button = MIN_BUTTON; 7802a3e3873SBaptiste Daroussin } 7814c8945a0SNathan Whitehorn return button; 7824c8945a0SNathan Whitehorn } 7834c8945a0SNathan Whitehorn 7844c8945a0SNathan Whitehorn /* 7854c8945a0SNathan Whitehorn * Return the previous index in labels[]; 7864c8945a0SNathan Whitehorn */ 7874c8945a0SNathan Whitehorn int 7884c8945a0SNathan Whitehorn dlg_prev_button(const char **labels, int button) 7894c8945a0SNathan Whitehorn { 7902a3e3873SBaptiste Daroussin if (button > MIN_BUTTON) { 7914c8945a0SNathan Whitehorn --button; 7922a3e3873SBaptiste Daroussin } else { 7932a3e3873SBaptiste Daroussin if (button < -1) 7942a3e3873SBaptiste Daroussin button = -1; 7952a3e3873SBaptiste Daroussin 7964c8945a0SNathan Whitehorn while (labels[button + 1] != 0) 7974c8945a0SNathan Whitehorn ++button; 7984c8945a0SNathan Whitehorn } 7994c8945a0SNathan Whitehorn return button; 8004c8945a0SNathan Whitehorn } 801