14c8945a0SNathan Whitehorn /* 2*682c9e0fSNathan Whitehorn * $Id: buttons.c,v 1.86 2011/06/28 10:46:46 tom Exp $ 34c8945a0SNathan Whitehorn * 44c8945a0SNathan Whitehorn * buttons.c -- draw buttons, e.g., OK/Cancel 54c8945a0SNathan Whitehorn * 67a1c0d96SNathan Whitehorn * Copyright 2000-2010,2011 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 314c8945a0SNathan Whitehorn #define MIN_BUTTON (dialog_state.visit_items ? -1 : 0) 324c8945a0SNathan Whitehorn 334c8945a0SNathan Whitehorn static void 344c8945a0SNathan Whitehorn center_label(char *buffer, int longest, const char *label) 354c8945a0SNathan Whitehorn { 364c8945a0SNathan Whitehorn int len = dlg_count_columns(label); 374c8945a0SNathan Whitehorn int left = 0, right = 0; 384c8945a0SNathan Whitehorn 394c8945a0SNathan Whitehorn *buffer = 0; 404c8945a0SNathan Whitehorn if (len < longest) { 414c8945a0SNathan Whitehorn left = (longest - len) / 2; 424c8945a0SNathan Whitehorn right = (longest - len - left); 434c8945a0SNathan Whitehorn if (left > 0) 444c8945a0SNathan Whitehorn sprintf(buffer, "%*s", left, " "); 454c8945a0SNathan Whitehorn } 464c8945a0SNathan Whitehorn strcat(buffer, label); 474c8945a0SNathan Whitehorn if (right > 0) 484c8945a0SNathan Whitehorn sprintf(buffer + strlen(buffer), "%*s", right, " "); 494c8945a0SNathan Whitehorn } 504c8945a0SNathan Whitehorn 514c8945a0SNathan Whitehorn /* 524c8945a0SNathan Whitehorn * Parse a multibyte character out of the string, set it past the parsed 534c8945a0SNathan Whitehorn * character. 544c8945a0SNathan Whitehorn */ 554c8945a0SNathan Whitehorn static int 564c8945a0SNathan Whitehorn string_to_char(const char **stringp) 574c8945a0SNathan Whitehorn { 584c8945a0SNathan Whitehorn int result; 594c8945a0SNathan Whitehorn #ifdef USE_WIDE_CURSES 604c8945a0SNathan Whitehorn const char *string = *stringp; 614c8945a0SNathan Whitehorn size_t have = strlen(string); 624c8945a0SNathan Whitehorn size_t check; 634c8945a0SNathan Whitehorn size_t len; 644c8945a0SNathan Whitehorn wchar_t cmp2[2]; 654c8945a0SNathan Whitehorn mbstate_t state; 664c8945a0SNathan Whitehorn 674c8945a0SNathan Whitehorn memset(&state, 0, sizeof(state)); 684c8945a0SNathan Whitehorn len = mbrlen(string, have, &state); 694c8945a0SNathan Whitehorn if ((int) len > 0 && len <= have) { 704c8945a0SNathan Whitehorn memset(&state, 0, sizeof(state)); 714c8945a0SNathan Whitehorn memset(cmp2, 0, sizeof(cmp2)); 724c8945a0SNathan Whitehorn check = mbrtowc(cmp2, string, len, &state); 734c8945a0SNathan Whitehorn if ((int) check <= 0) 744c8945a0SNathan Whitehorn cmp2[0] = 0; 754c8945a0SNathan Whitehorn *stringp += len; 764c8945a0SNathan Whitehorn } else { 774c8945a0SNathan Whitehorn cmp2[0] = UCH(*string); 784c8945a0SNathan Whitehorn *stringp += 1; 794c8945a0SNathan Whitehorn } 804c8945a0SNathan Whitehorn result = cmp2[0]; 814c8945a0SNathan Whitehorn #else 824c8945a0SNathan Whitehorn const char *string = *stringp; 834c8945a0SNathan Whitehorn result = UCH(*string); 844c8945a0SNathan Whitehorn *stringp += 1; 854c8945a0SNathan Whitehorn #endif 864c8945a0SNathan Whitehorn return result; 874c8945a0SNathan Whitehorn } 884c8945a0SNathan Whitehorn 894c8945a0SNathan Whitehorn /* 904c8945a0SNathan Whitehorn * Print a button 914c8945a0SNathan Whitehorn */ 924c8945a0SNathan Whitehorn static void 934c8945a0SNathan Whitehorn print_button(WINDOW *win, char *label, int y, int x, int selected) 944c8945a0SNathan Whitehorn { 954c8945a0SNathan Whitehorn int i; 964c8945a0SNathan Whitehorn int state = 0; 974c8945a0SNathan Whitehorn const int *indx = dlg_index_wchars(label); 984c8945a0SNathan Whitehorn int limit = dlg_count_wchars(label); 994c8945a0SNathan Whitehorn chtype key_attr = (selected 1004c8945a0SNathan Whitehorn ? button_key_active_attr 1014c8945a0SNathan Whitehorn : button_key_inactive_attr); 1024c8945a0SNathan Whitehorn chtype label_attr = (selected 1034c8945a0SNathan Whitehorn ? button_label_active_attr 1044c8945a0SNathan Whitehorn : button_label_inactive_attr); 1054c8945a0SNathan Whitehorn 1064c8945a0SNathan Whitehorn (void) wmove(win, y, x); 1074c8945a0SNathan Whitehorn wattrset(win, selected 1084c8945a0SNathan Whitehorn ? button_active_attr 1094c8945a0SNathan Whitehorn : button_inactive_attr); 1104c8945a0SNathan Whitehorn (void) waddstr(win, "<"); 1114c8945a0SNathan Whitehorn wattrset(win, label_attr); 1124c8945a0SNathan Whitehorn for (i = 0; i < limit; ++i) { 1134c8945a0SNathan Whitehorn int first = indx[i]; 1144c8945a0SNathan Whitehorn int last = indx[i + 1]; 1154c8945a0SNathan Whitehorn 1164c8945a0SNathan Whitehorn switch (state) { 1174c8945a0SNathan Whitehorn case 0: 1184c8945a0SNathan Whitehorn #ifdef USE_WIDE_CURSES 1194c8945a0SNathan Whitehorn if ((last - first) != 1) { 1204c8945a0SNathan Whitehorn const char *temp = (label + first); 1214c8945a0SNathan Whitehorn int cmp = string_to_char(&temp); 1224c8945a0SNathan Whitehorn if (dlg_isupper(cmp)) { 1234c8945a0SNathan Whitehorn wattrset(win, key_attr); 1244c8945a0SNathan Whitehorn state = 1; 1254c8945a0SNathan Whitehorn } 1264c8945a0SNathan Whitehorn break; 1274c8945a0SNathan Whitehorn } 1284c8945a0SNathan Whitehorn #endif 1294c8945a0SNathan Whitehorn if (dlg_isupper(UCH(label[first]))) { 1304c8945a0SNathan Whitehorn wattrset(win, key_attr); 1314c8945a0SNathan Whitehorn state = 1; 1324c8945a0SNathan Whitehorn } 1334c8945a0SNathan Whitehorn break; 1344c8945a0SNathan Whitehorn case 1: 1354c8945a0SNathan Whitehorn wattrset(win, label_attr); 1364c8945a0SNathan Whitehorn state = 2; 1374c8945a0SNathan Whitehorn break; 1384c8945a0SNathan Whitehorn } 1394c8945a0SNathan Whitehorn waddnstr(win, label + first, last - first); 1404c8945a0SNathan Whitehorn } 1414c8945a0SNathan Whitehorn wattrset(win, selected 1424c8945a0SNathan Whitehorn ? button_active_attr 1434c8945a0SNathan Whitehorn : button_inactive_attr); 1444c8945a0SNathan Whitehorn (void) waddstr(win, ">"); 1454c8945a0SNathan Whitehorn (void) wmove(win, y, x + ((int) strspn(label, " ")) + 1); 1464c8945a0SNathan Whitehorn } 1474c8945a0SNathan Whitehorn 1484c8945a0SNathan Whitehorn /* 1494c8945a0SNathan Whitehorn * Count the buttons in the list. 1504c8945a0SNathan Whitehorn */ 1514c8945a0SNathan Whitehorn int 1524c8945a0SNathan Whitehorn dlg_button_count(const char **labels) 1534c8945a0SNathan Whitehorn { 1544c8945a0SNathan Whitehorn int result = 0; 1554c8945a0SNathan Whitehorn while (*labels++ != 0) 1564c8945a0SNathan Whitehorn ++result; 1574c8945a0SNathan Whitehorn return result; 1584c8945a0SNathan Whitehorn } 1594c8945a0SNathan Whitehorn 1604c8945a0SNathan Whitehorn /* 1614c8945a0SNathan Whitehorn * Compute the size of the button array in columns. Return the total number of 1624c8945a0SNathan Whitehorn * columns in *length, and the longest button's columns in *longest 1634c8945a0SNathan Whitehorn */ 1644c8945a0SNathan Whitehorn void 1654c8945a0SNathan Whitehorn dlg_button_sizes(const char **labels, 1664c8945a0SNathan Whitehorn int vertical, 1674c8945a0SNathan Whitehorn int *longest, 1684c8945a0SNathan Whitehorn int *length) 1694c8945a0SNathan Whitehorn { 1704c8945a0SNathan Whitehorn int n; 1714c8945a0SNathan Whitehorn 1724c8945a0SNathan Whitehorn *length = 0; 1734c8945a0SNathan Whitehorn *longest = 0; 1744c8945a0SNathan Whitehorn for (n = 0; labels[n] != 0; n++) { 1754c8945a0SNathan Whitehorn if (vertical) { 1764c8945a0SNathan Whitehorn *length += 1; 1774c8945a0SNathan Whitehorn *longest = 1; 1784c8945a0SNathan Whitehorn } else { 1794c8945a0SNathan Whitehorn int len = dlg_count_columns(labels[n]); 1804c8945a0SNathan Whitehorn if (len > *longest) 1814c8945a0SNathan Whitehorn *longest = len; 1824c8945a0SNathan Whitehorn *length += len; 1834c8945a0SNathan Whitehorn } 1844c8945a0SNathan Whitehorn } 1854c8945a0SNathan Whitehorn /* 1864c8945a0SNathan Whitehorn * If we can, make all of the buttons the same size. This is only optional 1874c8945a0SNathan Whitehorn * for buttons laid out horizontally. 1884c8945a0SNathan Whitehorn */ 1894c8945a0SNathan Whitehorn if (*longest < 6 - (*longest & 1)) 1904c8945a0SNathan Whitehorn *longest = 6 - (*longest & 1); 1914c8945a0SNathan Whitehorn if (!vertical) 1924c8945a0SNathan Whitehorn *length = *longest * n; 1934c8945a0SNathan Whitehorn } 1944c8945a0SNathan Whitehorn 1954c8945a0SNathan Whitehorn /* 1964c8945a0SNathan Whitehorn * Compute the size of the button array. 1974c8945a0SNathan Whitehorn */ 1984c8945a0SNathan Whitehorn int 1994c8945a0SNathan Whitehorn dlg_button_x_step(const char **labels, int limit, int *gap, int *margin, int *step) 2004c8945a0SNathan Whitehorn { 2014c8945a0SNathan Whitehorn int count = dlg_button_count(labels); 2024c8945a0SNathan Whitehorn int longest; 2034c8945a0SNathan Whitehorn int length; 2044c8945a0SNathan Whitehorn int unused; 2054c8945a0SNathan Whitehorn int used; 2064c8945a0SNathan Whitehorn 2074c8945a0SNathan Whitehorn if (count == 0) 2084c8945a0SNathan Whitehorn return 0; 2094c8945a0SNathan Whitehorn dlg_button_sizes(labels, FALSE, &longest, &length); 2104c8945a0SNathan Whitehorn used = (length + (count * 2)); 2114c8945a0SNathan Whitehorn unused = limit - used; 2124c8945a0SNathan Whitehorn 2134c8945a0SNathan Whitehorn if ((*gap = unused / (count + 3)) <= 0) { 2144c8945a0SNathan Whitehorn if ((*gap = unused / (count + 1)) <= 0) 2154c8945a0SNathan Whitehorn *gap = 1; 2164c8945a0SNathan Whitehorn *margin = *gap; 2174c8945a0SNathan Whitehorn } else { 2184c8945a0SNathan Whitehorn *margin = *gap * 2; 2194c8945a0SNathan Whitehorn } 2204c8945a0SNathan Whitehorn *step = *gap + (used + count - 1) / count; 2214c8945a0SNathan Whitehorn return (*gap > 0) && (unused >= 0); 2224c8945a0SNathan Whitehorn } 2234c8945a0SNathan Whitehorn 2244c8945a0SNathan Whitehorn /* 2254c8945a0SNathan Whitehorn * Make sure there is enough space for the buttons 2264c8945a0SNathan Whitehorn */ 2274c8945a0SNathan Whitehorn void 2284c8945a0SNathan Whitehorn dlg_button_layout(const char **labels, int *limit) 2294c8945a0SNathan Whitehorn { 2304c8945a0SNathan Whitehorn int width = 1; 2314c8945a0SNathan Whitehorn int gap, margin, step; 2324c8945a0SNathan Whitehorn 2334c8945a0SNathan Whitehorn if (labels != 0 && dlg_button_count(labels)) { 2344c8945a0SNathan Whitehorn while (!dlg_button_x_step(labels, width, &gap, &margin, &step)) 2354c8945a0SNathan Whitehorn ++width; 2364c8945a0SNathan Whitehorn width += (4 * MARGIN); 2374c8945a0SNathan Whitehorn if (width > COLS) 2384c8945a0SNathan Whitehorn width = COLS; 2394c8945a0SNathan Whitehorn if (width > *limit) 2404c8945a0SNathan Whitehorn *limit = width; 2414c8945a0SNathan Whitehorn } 2424c8945a0SNathan Whitehorn } 2434c8945a0SNathan Whitehorn 2444c8945a0SNathan Whitehorn /* 2454c8945a0SNathan Whitehorn * Print a list of buttons at the given position. 2464c8945a0SNathan Whitehorn */ 2474c8945a0SNathan Whitehorn void 2484c8945a0SNathan Whitehorn dlg_draw_buttons(WINDOW *win, 2494c8945a0SNathan Whitehorn int y, int x, 2504c8945a0SNathan Whitehorn const char **labels, 2514c8945a0SNathan Whitehorn int selected, 2524c8945a0SNathan Whitehorn int vertical, 2534c8945a0SNathan Whitehorn int limit) 2544c8945a0SNathan Whitehorn { 2557a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win); 2564c8945a0SNathan Whitehorn int n; 2574c8945a0SNathan Whitehorn int step = 0; 2584c8945a0SNathan Whitehorn int length; 2594c8945a0SNathan Whitehorn int longest; 2604c8945a0SNathan Whitehorn int final_x; 2614c8945a0SNathan Whitehorn int final_y; 2624c8945a0SNathan Whitehorn int gap; 2634c8945a0SNathan Whitehorn int margin; 2644c8945a0SNathan Whitehorn size_t need; 2654c8945a0SNathan Whitehorn char *buffer; 2664c8945a0SNathan Whitehorn 2674c8945a0SNathan Whitehorn dlg_mouse_setbase(getbegx(win), getbegy(win)); 2684c8945a0SNathan Whitehorn 2694c8945a0SNathan Whitehorn getyx(win, final_y, final_x); 2704c8945a0SNathan Whitehorn 2714c8945a0SNathan Whitehorn dlg_button_sizes(labels, vertical, &longest, &length); 2724c8945a0SNathan Whitehorn 2734c8945a0SNathan Whitehorn if (vertical) { 2744c8945a0SNathan Whitehorn y += 1; 2754c8945a0SNathan Whitehorn step = 1; 2764c8945a0SNathan Whitehorn } else { 2774c8945a0SNathan Whitehorn dlg_button_x_step(labels, limit, &gap, &margin, &step); 2784c8945a0SNathan Whitehorn x += margin; 2794c8945a0SNathan Whitehorn } 2804c8945a0SNathan Whitehorn 2814c8945a0SNathan Whitehorn /* 2824c8945a0SNathan Whitehorn * Allocate a buffer big enough for any label. 2834c8945a0SNathan Whitehorn */ 2844c8945a0SNathan Whitehorn need = (size_t) longest; 2854c8945a0SNathan Whitehorn for (n = 0; labels[n] != 0; ++n) { 2864c8945a0SNathan Whitehorn need += strlen(labels[n]) + 1; 2874c8945a0SNathan Whitehorn } 2884c8945a0SNathan Whitehorn buffer = dlg_malloc(char, need); 2894c8945a0SNathan Whitehorn assert_ptr(buffer, "dlg_draw_buttons"); 2904c8945a0SNathan Whitehorn 2914c8945a0SNathan Whitehorn /* 2924c8945a0SNathan Whitehorn * Draw the labels. 2934c8945a0SNathan Whitehorn */ 2944c8945a0SNathan Whitehorn for (n = 0; labels[n] != 0; n++) { 2954c8945a0SNathan Whitehorn center_label(buffer, longest, labels[n]); 2964c8945a0SNathan Whitehorn mouse_mkbutton(y, x, dlg_count_columns(buffer), n); 2974c8945a0SNathan Whitehorn print_button(win, buffer, y, x, 2984c8945a0SNathan Whitehorn (selected == n) || (n == 0 && selected < 0)); 2994c8945a0SNathan Whitehorn if (selected == n) 3004c8945a0SNathan Whitehorn getyx(win, final_y, final_x); 3014c8945a0SNathan Whitehorn 3024c8945a0SNathan Whitehorn if (vertical) { 3034c8945a0SNathan Whitehorn if ((y += step) > limit) 3044c8945a0SNathan Whitehorn break; 3054c8945a0SNathan Whitehorn } else { 3064c8945a0SNathan Whitehorn if ((x += step) > limit) 3074c8945a0SNathan Whitehorn break; 3084c8945a0SNathan Whitehorn } 3094c8945a0SNathan Whitehorn } 3104c8945a0SNathan Whitehorn (void) wmove(win, final_y, final_x); 3114c8945a0SNathan Whitehorn wrefresh(win); 3124c8945a0SNathan Whitehorn free(buffer); 3134c8945a0SNathan Whitehorn wattrset(win, save); 3144c8945a0SNathan Whitehorn } 3154c8945a0SNathan Whitehorn 3164c8945a0SNathan Whitehorn /* 3174c8945a0SNathan Whitehorn * Match a given character against the beginning of the string, ignoring case 3184c8945a0SNathan Whitehorn * of the given character. The matching string must begin with an uppercase 3194c8945a0SNathan Whitehorn * character. 3204c8945a0SNathan Whitehorn */ 3214c8945a0SNathan Whitehorn int 3224c8945a0SNathan Whitehorn dlg_match_char(int ch, const char *string) 3234c8945a0SNathan Whitehorn { 3244c8945a0SNathan Whitehorn if (string != 0) { 3254c8945a0SNathan Whitehorn int cmp2 = string_to_char(&string); 3264c8945a0SNathan Whitehorn #ifdef USE_WIDE_CURSES 3274c8945a0SNathan Whitehorn wint_t cmp1 = dlg_toupper(ch); 3284c8945a0SNathan Whitehorn if (cmp2 != 0 && (wchar_t) cmp1 == (wchar_t) dlg_toupper(cmp2)) { 3294c8945a0SNathan Whitehorn return TRUE; 3304c8945a0SNathan Whitehorn } 3314c8945a0SNathan Whitehorn #else 3324c8945a0SNathan Whitehorn if (ch > 0 && ch < 256) { 3334c8945a0SNathan Whitehorn if (dlg_toupper(ch) == dlg_toupper(cmp2)) 3344c8945a0SNathan Whitehorn return TRUE; 3354c8945a0SNathan Whitehorn } 3364c8945a0SNathan Whitehorn #endif 3374c8945a0SNathan Whitehorn } 3384c8945a0SNathan Whitehorn return FALSE; 3394c8945a0SNathan Whitehorn } 3404c8945a0SNathan Whitehorn 3414c8945a0SNathan Whitehorn /* 3424c8945a0SNathan Whitehorn * Find the first uppercase character in the label, which we may use for an 3434c8945a0SNathan Whitehorn * abbreviation. 3444c8945a0SNathan Whitehorn */ 3454c8945a0SNathan Whitehorn int 3464c8945a0SNathan Whitehorn dlg_button_to_char(const char *label) 3474c8945a0SNathan Whitehorn { 3484c8945a0SNathan Whitehorn int cmp = -1; 3494c8945a0SNathan Whitehorn 3504c8945a0SNathan Whitehorn while (*label != 0) { 3514c8945a0SNathan Whitehorn cmp = string_to_char(&label); 3524c8945a0SNathan Whitehorn if (dlg_isupper(cmp)) { 3534c8945a0SNathan Whitehorn break; 3544c8945a0SNathan Whitehorn } 3554c8945a0SNathan Whitehorn } 3564c8945a0SNathan Whitehorn return cmp; 3574c8945a0SNathan Whitehorn } 3584c8945a0SNathan Whitehorn 3594c8945a0SNathan Whitehorn /* 3604c8945a0SNathan Whitehorn * Given a list of button labels, and a character which may be the abbreviation 3614c8945a0SNathan Whitehorn * for one, find it, if it exists. An abbreviation will be the first character 3624c8945a0SNathan Whitehorn * which happens to be capitalized in the label. 3634c8945a0SNathan Whitehorn */ 3644c8945a0SNathan Whitehorn int 3654c8945a0SNathan Whitehorn dlg_char_to_button(int ch, const char **labels) 3664c8945a0SNathan Whitehorn { 3674c8945a0SNathan Whitehorn if (labels != 0) { 3684c8945a0SNathan Whitehorn int j; 3694c8945a0SNathan Whitehorn 3704c8945a0SNathan Whitehorn ch = (int) dlg_toupper(dlg_last_getc()); 3714c8945a0SNathan Whitehorn for (j = 0; labels[j] != 0; ++j) { 3724c8945a0SNathan Whitehorn int cmp = dlg_button_to_char(labels[j]); 3734c8945a0SNathan Whitehorn if (ch == cmp) { 3744c8945a0SNathan Whitehorn dlg_flush_getc(); 3754c8945a0SNathan Whitehorn return j; 3764c8945a0SNathan Whitehorn } 3774c8945a0SNathan Whitehorn } 3784c8945a0SNathan Whitehorn } 3794c8945a0SNathan Whitehorn return DLG_EXIT_UNKNOWN; 3804c8945a0SNathan Whitehorn } 3814c8945a0SNathan Whitehorn 3824c8945a0SNathan Whitehorn static const char * 3834c8945a0SNathan Whitehorn my_yes_label(void) 3844c8945a0SNathan Whitehorn { 3854c8945a0SNathan Whitehorn return (dialog_vars.yes_label != NULL) 3864c8945a0SNathan Whitehorn ? dialog_vars.yes_label 3874c8945a0SNathan Whitehorn : _("Yes"); 3884c8945a0SNathan Whitehorn } 3894c8945a0SNathan Whitehorn 3904c8945a0SNathan Whitehorn static const char * 3914c8945a0SNathan Whitehorn my_no_label(void) 3924c8945a0SNathan Whitehorn { 3934c8945a0SNathan Whitehorn return (dialog_vars.no_label != NULL) 3944c8945a0SNathan Whitehorn ? dialog_vars.no_label 3954c8945a0SNathan Whitehorn : _("No"); 3964c8945a0SNathan Whitehorn } 3974c8945a0SNathan Whitehorn 3984c8945a0SNathan Whitehorn static const char * 3994c8945a0SNathan Whitehorn my_ok_label(void) 4004c8945a0SNathan Whitehorn { 4014c8945a0SNathan Whitehorn return (dialog_vars.ok_label != NULL) 4024c8945a0SNathan Whitehorn ? dialog_vars.ok_label 4034c8945a0SNathan Whitehorn : _("OK"); 4044c8945a0SNathan Whitehorn } 4054c8945a0SNathan Whitehorn 4064c8945a0SNathan Whitehorn static const char * 4074c8945a0SNathan Whitehorn my_cancel_label(void) 4084c8945a0SNathan Whitehorn { 4094c8945a0SNathan Whitehorn return (dialog_vars.cancel_label != NULL) 4104c8945a0SNathan Whitehorn ? dialog_vars.cancel_label 4114c8945a0SNathan Whitehorn : _("Cancel"); 4124c8945a0SNathan Whitehorn } 4134c8945a0SNathan Whitehorn 4144c8945a0SNathan Whitehorn static const char * 4154c8945a0SNathan Whitehorn my_exit_label(void) 4164c8945a0SNathan Whitehorn { 4174c8945a0SNathan Whitehorn return (dialog_vars.exit_label != NULL) 4184c8945a0SNathan Whitehorn ? dialog_vars.exit_label 4194c8945a0SNathan Whitehorn : _("EXIT"); 4204c8945a0SNathan Whitehorn } 4214c8945a0SNathan Whitehorn 4224c8945a0SNathan Whitehorn static const char * 4234c8945a0SNathan Whitehorn my_extra_label(void) 4244c8945a0SNathan Whitehorn { 4254c8945a0SNathan Whitehorn return (dialog_vars.extra_label != NULL) 4264c8945a0SNathan Whitehorn ? dialog_vars.extra_label 4274c8945a0SNathan Whitehorn : _("Extra"); 4284c8945a0SNathan Whitehorn } 4294c8945a0SNathan Whitehorn 4304c8945a0SNathan Whitehorn static const char * 4314c8945a0SNathan Whitehorn my_help_label(void) 4324c8945a0SNathan Whitehorn { 4334c8945a0SNathan Whitehorn return (dialog_vars.help_label != NULL) 4344c8945a0SNathan Whitehorn ? dialog_vars.help_label 4354c8945a0SNathan Whitehorn : _("Help"); 4364c8945a0SNathan Whitehorn } 4374c8945a0SNathan Whitehorn 4384c8945a0SNathan Whitehorn /* 4394c8945a0SNathan Whitehorn * Return a list of button labels. 4404c8945a0SNathan Whitehorn */ 4414c8945a0SNathan Whitehorn const char ** 4424c8945a0SNathan Whitehorn dlg_exit_label(void) 4434c8945a0SNathan Whitehorn { 4444c8945a0SNathan Whitehorn const char **result; 445*682c9e0fSNathan Whitehorn DIALOG_VARS save; 4464c8945a0SNathan Whitehorn 4474c8945a0SNathan Whitehorn if (dialog_vars.extra_button) { 448*682c9e0fSNathan Whitehorn dlg_save_vars(&save); 449*682c9e0fSNathan Whitehorn dialog_vars.nocancel = TRUE; 4504c8945a0SNathan Whitehorn result = dlg_ok_labels(); 451*682c9e0fSNathan Whitehorn dlg_restore_vars(&save); 4524c8945a0SNathan Whitehorn } else { 4534c8945a0SNathan Whitehorn static const char *labels[3]; 4544c8945a0SNathan Whitehorn int n = 0; 4554c8945a0SNathan Whitehorn 456*682c9e0fSNathan Whitehorn if (!dialog_vars.nook) 4574c8945a0SNathan Whitehorn labels[n++] = my_exit_label(); 4584c8945a0SNathan Whitehorn if (dialog_vars.help_button) 4594c8945a0SNathan Whitehorn labels[n++] = my_help_label(); 460*682c9e0fSNathan Whitehorn if (n == 0) 461*682c9e0fSNathan Whitehorn labels[n++] = my_exit_label(); 4624c8945a0SNathan Whitehorn labels[n] = 0; 4634c8945a0SNathan Whitehorn 4644c8945a0SNathan Whitehorn result = labels; 4654c8945a0SNathan Whitehorn } 4664c8945a0SNathan Whitehorn return result; 4674c8945a0SNathan Whitehorn } 4684c8945a0SNathan Whitehorn 4694c8945a0SNathan Whitehorn /* 4704c8945a0SNathan Whitehorn * Map the given button index for dlg_exit_label() into our exit-code. 4714c8945a0SNathan Whitehorn */ 4724c8945a0SNathan Whitehorn int 4734c8945a0SNathan Whitehorn dlg_exit_buttoncode(int button) 4744c8945a0SNathan Whitehorn { 475*682c9e0fSNathan Whitehorn int result; 476*682c9e0fSNathan Whitehorn DIALOG_VARS save; 477*682c9e0fSNathan Whitehorn 478*682c9e0fSNathan Whitehorn dlg_save_vars(&save); 479*682c9e0fSNathan Whitehorn dialog_vars.nocancel = TRUE; 480*682c9e0fSNathan Whitehorn 481*682c9e0fSNathan Whitehorn result = dlg_ok_buttoncode(button); 482*682c9e0fSNathan Whitehorn 483*682c9e0fSNathan Whitehorn dlg_restore_vars(&save); 484*682c9e0fSNathan Whitehorn 485*682c9e0fSNathan Whitehorn return result; 4864c8945a0SNathan Whitehorn } 4874c8945a0SNathan Whitehorn 4884c8945a0SNathan Whitehorn const char ** 4894c8945a0SNathan Whitehorn dlg_ok_label(void) 4904c8945a0SNathan Whitehorn { 4914c8945a0SNathan Whitehorn static const char *labels[3]; 4924c8945a0SNathan Whitehorn int n = 0; 4934c8945a0SNathan Whitehorn 4944c8945a0SNathan Whitehorn labels[n++] = my_ok_label(); 4954c8945a0SNathan Whitehorn if (dialog_vars.help_button) 4964c8945a0SNathan Whitehorn labels[n++] = my_help_label(); 4974c8945a0SNathan Whitehorn labels[n] = 0; 4984c8945a0SNathan Whitehorn return labels; 4994c8945a0SNathan Whitehorn } 5004c8945a0SNathan Whitehorn 5014c8945a0SNathan Whitehorn /* 5024c8945a0SNathan Whitehorn * Return a list of button labels for the OK/Cancel group. 5034c8945a0SNathan Whitehorn */ 5044c8945a0SNathan Whitehorn const char ** 5054c8945a0SNathan Whitehorn dlg_ok_labels(void) 5064c8945a0SNathan Whitehorn { 5074c8945a0SNathan Whitehorn static const char *labels[5]; 5084c8945a0SNathan Whitehorn int n = 0; 5094c8945a0SNathan Whitehorn 5104c8945a0SNathan Whitehorn if (!dialog_vars.nook) 5114c8945a0SNathan Whitehorn labels[n++] = my_ok_label(); 5124c8945a0SNathan Whitehorn if (dialog_vars.extra_button) 5134c8945a0SNathan Whitehorn labels[n++] = my_extra_label(); 5144c8945a0SNathan Whitehorn if (!dialog_vars.nocancel) 5154c8945a0SNathan Whitehorn labels[n++] = my_cancel_label(); 5164c8945a0SNathan Whitehorn if (dialog_vars.help_button) 5174c8945a0SNathan Whitehorn labels[n++] = my_help_label(); 5184c8945a0SNathan Whitehorn labels[n] = 0; 5194c8945a0SNathan Whitehorn return labels; 5204c8945a0SNathan Whitehorn } 5214c8945a0SNathan Whitehorn 5224c8945a0SNathan Whitehorn /* 5234c8945a0SNathan Whitehorn * Map the given button index for dlg_ok_labels() into our exit-code 5244c8945a0SNathan Whitehorn */ 5254c8945a0SNathan Whitehorn int 5264c8945a0SNathan Whitehorn dlg_ok_buttoncode(int button) 5274c8945a0SNathan Whitehorn { 5284c8945a0SNathan Whitehorn int result = DLG_EXIT_ERROR; 5294c8945a0SNathan Whitehorn int n = !dialog_vars.nook; 5304c8945a0SNathan Whitehorn 5314c8945a0SNathan Whitehorn if (!dialog_vars.nook && (button <= 0)) { 5324c8945a0SNathan Whitehorn result = DLG_EXIT_OK; 5334c8945a0SNathan Whitehorn } else if (dialog_vars.extra_button && (button == n++)) { 5344c8945a0SNathan Whitehorn result = DLG_EXIT_EXTRA; 5354c8945a0SNathan Whitehorn } else if (!dialog_vars.nocancel && (button == n++)) { 5364c8945a0SNathan Whitehorn result = DLG_EXIT_CANCEL; 5374c8945a0SNathan Whitehorn } else if (dialog_vars.help_button && (button == n)) { 5384c8945a0SNathan Whitehorn result = DLG_EXIT_HELP; 5394c8945a0SNathan Whitehorn } 5404c8945a0SNathan Whitehorn return result; 5414c8945a0SNathan Whitehorn } 5424c8945a0SNathan Whitehorn 5434c8945a0SNathan Whitehorn /* 5444c8945a0SNathan Whitehorn * Given that we're using dlg_ok_labels() to list buttons, find the next index 5454c8945a0SNathan Whitehorn * in the list of buttons. The 'extra' parameter if negative provides a way to 5464c8945a0SNathan Whitehorn * enumerate extra active areas on the widget. 5474c8945a0SNathan Whitehorn */ 5484c8945a0SNathan Whitehorn int 5494c8945a0SNathan Whitehorn dlg_next_ok_buttonindex(int current, int extra) 5504c8945a0SNathan Whitehorn { 5514c8945a0SNathan Whitehorn int result = current + 1; 5524c8945a0SNathan Whitehorn 5534c8945a0SNathan Whitehorn if (current >= 0 5544c8945a0SNathan Whitehorn && dlg_ok_buttoncode(result) < 0) 5554c8945a0SNathan Whitehorn result = extra; 5564c8945a0SNathan Whitehorn return result; 5574c8945a0SNathan Whitehorn } 5584c8945a0SNathan Whitehorn 5594c8945a0SNathan Whitehorn /* 5604c8945a0SNathan Whitehorn * Similarly, find the previous button index. 5614c8945a0SNathan Whitehorn */ 5624c8945a0SNathan Whitehorn int 5634c8945a0SNathan Whitehorn dlg_prev_ok_buttonindex(int current, int extra) 5644c8945a0SNathan Whitehorn { 5654c8945a0SNathan Whitehorn int result = current - 1; 5664c8945a0SNathan Whitehorn 5674c8945a0SNathan Whitehorn if (result < extra) { 5684c8945a0SNathan Whitehorn for (result = 0; dlg_ok_buttoncode(result + 1) >= 0; ++result) { 5694c8945a0SNathan Whitehorn ; 5704c8945a0SNathan Whitehorn } 5714c8945a0SNathan Whitehorn } 5724c8945a0SNathan Whitehorn return result; 5734c8945a0SNathan Whitehorn } 5744c8945a0SNathan Whitehorn 5754c8945a0SNathan Whitehorn /* 5764c8945a0SNathan Whitehorn * Find the button-index for the "OK" or "Cancel" button, according to 5774c8945a0SNathan Whitehorn * whether --defaultno is given. If --nocancel was given, we always return 5784c8945a0SNathan Whitehorn * the index for "OK". 5794c8945a0SNathan Whitehorn */ 5804c8945a0SNathan Whitehorn int 5814c8945a0SNathan Whitehorn dlg_defaultno_button(void) 5824c8945a0SNathan Whitehorn { 5834c8945a0SNathan Whitehorn int result = 0; 5844c8945a0SNathan Whitehorn 5854c8945a0SNathan Whitehorn if (dialog_vars.defaultno && !dialog_vars.nocancel) { 5864c8945a0SNathan Whitehorn while (dlg_ok_buttoncode(result) != DLG_EXIT_CANCEL) 5874c8945a0SNathan Whitehorn ++result; 5884c8945a0SNathan Whitehorn } 5894c8945a0SNathan Whitehorn return result; 5904c8945a0SNathan Whitehorn } 5914c8945a0SNathan Whitehorn 5924c8945a0SNathan Whitehorn /* 5934c8945a0SNathan Whitehorn * Return a list of buttons for Yes/No labels. 5944c8945a0SNathan Whitehorn */ 5954c8945a0SNathan Whitehorn const char ** 5964c8945a0SNathan Whitehorn dlg_yes_labels(void) 5974c8945a0SNathan Whitehorn { 5984c8945a0SNathan Whitehorn const char **result; 5994c8945a0SNathan Whitehorn 6004c8945a0SNathan Whitehorn if (dialog_vars.extra_button) { 6014c8945a0SNathan Whitehorn result = dlg_ok_labels(); 6024c8945a0SNathan Whitehorn } else { 6034c8945a0SNathan Whitehorn static const char *labels[4]; 6044c8945a0SNathan Whitehorn int n = 0; 6054c8945a0SNathan Whitehorn 6064c8945a0SNathan Whitehorn labels[n++] = my_yes_label(); 6074c8945a0SNathan Whitehorn labels[n++] = my_no_label(); 6084c8945a0SNathan Whitehorn if (dialog_vars.help_button) 6094c8945a0SNathan Whitehorn labels[n++] = my_help_label(); 6104c8945a0SNathan Whitehorn labels[n] = 0; 6114c8945a0SNathan Whitehorn 6124c8945a0SNathan Whitehorn result = labels; 6134c8945a0SNathan Whitehorn } 6144c8945a0SNathan Whitehorn 6154c8945a0SNathan Whitehorn return result; 6164c8945a0SNathan Whitehorn } 6174c8945a0SNathan Whitehorn 6184c8945a0SNathan Whitehorn /* 6194c8945a0SNathan Whitehorn * Map the given button index for dlg_yes_labels() into our exit-code. 6204c8945a0SNathan Whitehorn */ 6214c8945a0SNathan Whitehorn int 6224c8945a0SNathan Whitehorn dlg_yes_buttoncode(int button) 6234c8945a0SNathan Whitehorn { 6244c8945a0SNathan Whitehorn int result = DLG_EXIT_ERROR; 6254c8945a0SNathan Whitehorn 6264c8945a0SNathan Whitehorn if (dialog_vars.extra_button) { 6274c8945a0SNathan Whitehorn result = dlg_ok_buttoncode(button); 6284c8945a0SNathan Whitehorn } else if (button == 0) { 6294c8945a0SNathan Whitehorn result = DLG_EXIT_OK; 6304c8945a0SNathan Whitehorn } else if (button == 1) { 6314c8945a0SNathan Whitehorn result = DLG_EXIT_CANCEL; 6324c8945a0SNathan Whitehorn } else if (button == 2 && dialog_vars.help_button) { 6334c8945a0SNathan Whitehorn result = DLG_EXIT_HELP; 6344c8945a0SNathan Whitehorn } 6354c8945a0SNathan Whitehorn 6364c8945a0SNathan Whitehorn return result; 6374c8945a0SNathan Whitehorn } 6384c8945a0SNathan Whitehorn 6394c8945a0SNathan Whitehorn /* 6404c8945a0SNathan Whitehorn * Return the next index in labels[]; 6414c8945a0SNathan Whitehorn */ 6424c8945a0SNathan Whitehorn int 6434c8945a0SNathan Whitehorn dlg_next_button(const char **labels, int button) 6444c8945a0SNathan Whitehorn { 6454c8945a0SNathan Whitehorn if (labels[button + 1] != 0) 6464c8945a0SNathan Whitehorn ++button; 6474c8945a0SNathan Whitehorn else 6484c8945a0SNathan Whitehorn button = MIN_BUTTON; 6494c8945a0SNathan Whitehorn return button; 6504c8945a0SNathan Whitehorn } 6514c8945a0SNathan Whitehorn 6524c8945a0SNathan Whitehorn /* 6534c8945a0SNathan Whitehorn * Return the previous index in labels[]; 6544c8945a0SNathan Whitehorn */ 6554c8945a0SNathan Whitehorn int 6564c8945a0SNathan Whitehorn dlg_prev_button(const char **labels, int button) 6574c8945a0SNathan Whitehorn { 6584c8945a0SNathan Whitehorn if (button > MIN_BUTTON) 6594c8945a0SNathan Whitehorn --button; 6604c8945a0SNathan Whitehorn else { 6614c8945a0SNathan Whitehorn while (labels[button + 1] != 0) 6624c8945a0SNathan Whitehorn ++button; 6634c8945a0SNathan Whitehorn } 6644c8945a0SNathan Whitehorn return button; 6654c8945a0SNathan Whitehorn } 666