14c8945a0SNathan Whitehorn /*
2*a96ef450SBaptiste Daroussin * $Id: buttons.c,v 1.106 2021/01/17 17:03:16 tom Exp $
34c8945a0SNathan Whitehorn *
44c8945a0SNathan Whitehorn * buttons.c -- draw buttons, e.g., OK/Cancel
54c8945a0SNathan Whitehorn *
6*a96ef450SBaptiste Daroussin * Copyright 2000-2020,2021 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)
32f4f33ea0SBaptiste Daroussin #define CHR_BUTTON (!dialog_state.plain_buttons)
334c8945a0SNathan Whitehorn
344c8945a0SNathan Whitehorn static void
center_label(char * buffer,int longest,const char * label)354c8945a0SNathan Whitehorn center_label(char *buffer, int longest, const char *label)
364c8945a0SNathan Whitehorn {
374c8945a0SNathan Whitehorn int len = dlg_count_columns(label);
38*a96ef450SBaptiste Daroussin int right = 0;
394c8945a0SNathan Whitehorn
404c8945a0SNathan Whitehorn *buffer = 0;
414c8945a0SNathan Whitehorn if (len < longest) {
42*a96ef450SBaptiste Daroussin int 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
string_to_char(const char ** stringp)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 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);
69*a96ef450SBaptiste Daroussin
704c8945a0SNathan Whitehorn if ((int) len > 0 && len <= have) {
71*a96ef450SBaptiste Daroussin size_t check;
72*a96ef450SBaptiste Daroussin
734c8945a0SNathan Whitehorn memset(&state, 0, sizeof(state));
744c8945a0SNathan Whitehorn memset(cmp2, 0, sizeof(cmp2));
754c8945a0SNathan Whitehorn check = mbrtowc(cmp2, string, len, &state);
764c8945a0SNathan Whitehorn if ((int) check <= 0)
774c8945a0SNathan Whitehorn cmp2[0] = 0;
784c8945a0SNathan Whitehorn *stringp += len;
794c8945a0SNathan Whitehorn } else {
804c8945a0SNathan Whitehorn cmp2[0] = UCH(*string);
814c8945a0SNathan Whitehorn *stringp += 1;
824c8945a0SNathan Whitehorn }
834c8945a0SNathan Whitehorn result = cmp2[0];
844c8945a0SNathan Whitehorn #else
854c8945a0SNathan Whitehorn const char *string = *stringp;
864c8945a0SNathan Whitehorn result = UCH(*string);
874c8945a0SNathan Whitehorn *stringp += 1;
884c8945a0SNathan Whitehorn #endif
894c8945a0SNathan Whitehorn return result;
904c8945a0SNathan Whitehorn }
914c8945a0SNathan Whitehorn
922a3e3873SBaptiste Daroussin static size_t
count_labels(const char ** labels)932a3e3873SBaptiste Daroussin count_labels(const char **labels)
942a3e3873SBaptiste Daroussin {
952a3e3873SBaptiste Daroussin size_t result = 0;
962a3e3873SBaptiste Daroussin if (labels != 0) {
972a3e3873SBaptiste Daroussin while (*labels++ != 0) {
982a3e3873SBaptiste Daroussin ++result;
992a3e3873SBaptiste Daroussin }
1002a3e3873SBaptiste Daroussin }
1012a3e3873SBaptiste Daroussin return result;
1022a3e3873SBaptiste Daroussin }
1032a3e3873SBaptiste Daroussin
1042a3e3873SBaptiste Daroussin /*
1052a3e3873SBaptiste Daroussin * Check if the latest key should be added to the hotkey list.
1062a3e3873SBaptiste Daroussin */
1072a3e3873SBaptiste Daroussin static int
was_hotkey(int this_key,int * used_keys,size_t next)1082a3e3873SBaptiste Daroussin was_hotkey(int this_key, int *used_keys, size_t next)
1092a3e3873SBaptiste Daroussin {
1102a3e3873SBaptiste Daroussin int result = FALSE;
1112a3e3873SBaptiste Daroussin
1122a3e3873SBaptiste Daroussin if (next != 0) {
1132a3e3873SBaptiste Daroussin size_t n;
1142a3e3873SBaptiste Daroussin for (n = 0; n < next; ++n) {
1152a3e3873SBaptiste Daroussin if (used_keys[n] == this_key) {
1162a3e3873SBaptiste Daroussin result = TRUE;
1172a3e3873SBaptiste Daroussin break;
1182a3e3873SBaptiste Daroussin }
1192a3e3873SBaptiste Daroussin }
1202a3e3873SBaptiste Daroussin }
1212a3e3873SBaptiste Daroussin return result;
1222a3e3873SBaptiste Daroussin }
1232a3e3873SBaptiste Daroussin
1242a3e3873SBaptiste Daroussin /*
1252a3e3873SBaptiste Daroussin * Determine the hot-keys for a set of button-labels. Normally these are
1262a3e3873SBaptiste Daroussin * the first uppercase character in each label. However, if more than one
1272a3e3873SBaptiste Daroussin * button has the same first-uppercase, then we will (attempt to) look for
1282a3e3873SBaptiste Daroussin * an alternate.
1292a3e3873SBaptiste Daroussin *
1302a3e3873SBaptiste Daroussin * This allocates data which must be freed by the caller.
1312a3e3873SBaptiste Daroussin */
1322a3e3873SBaptiste Daroussin static int *
get_hotkeys(const char ** labels)1332a3e3873SBaptiste Daroussin get_hotkeys(const char **labels)
1342a3e3873SBaptiste Daroussin {
1352a3e3873SBaptiste Daroussin int *result = 0;
1362a3e3873SBaptiste Daroussin size_t count = count_labels(labels);
1372a3e3873SBaptiste Daroussin
1382a3e3873SBaptiste Daroussin if ((result = dlg_calloc(int, count + 1)) != 0) {
139*a96ef450SBaptiste Daroussin size_t n;
140*a96ef450SBaptiste Daroussin
1412a3e3873SBaptiste Daroussin for (n = 0; n < count; ++n) {
1422a3e3873SBaptiste Daroussin const char *label = labels[n];
1432a3e3873SBaptiste Daroussin const int *indx = dlg_index_wchars(label);
1442a3e3873SBaptiste Daroussin int limit = dlg_count_wchars(label);
1452a3e3873SBaptiste Daroussin int i;
1462a3e3873SBaptiste Daroussin
1472a3e3873SBaptiste Daroussin for (i = 0; i < limit; ++i) {
1482a3e3873SBaptiste Daroussin int first = indx[i];
1492a3e3873SBaptiste Daroussin int check = UCH(label[first]);
1502a3e3873SBaptiste Daroussin #ifdef USE_WIDE_CURSES
1512a3e3873SBaptiste Daroussin int last = indx[i + 1];
1522a3e3873SBaptiste Daroussin if ((last - first) != 1) {
1532a3e3873SBaptiste Daroussin const char *temp = (label + first);
1542a3e3873SBaptiste Daroussin check = string_to_char(&temp);
1552a3e3873SBaptiste Daroussin }
1562a3e3873SBaptiste Daroussin #endif
1572a3e3873SBaptiste Daroussin if (dlg_isupper(check) && !was_hotkey(check, result, n)) {
1582a3e3873SBaptiste Daroussin result[n] = check;
1592a3e3873SBaptiste Daroussin break;
1602a3e3873SBaptiste Daroussin }
1612a3e3873SBaptiste Daroussin }
1622a3e3873SBaptiste Daroussin }
1632a3e3873SBaptiste Daroussin }
1642a3e3873SBaptiste Daroussin return result;
1652a3e3873SBaptiste Daroussin }
1662a3e3873SBaptiste Daroussin
167f4f33ea0SBaptiste Daroussin typedef enum {
168f4f33ea0SBaptiste Daroussin sFIND_KEY = 0
169f4f33ea0SBaptiste Daroussin ,sHAVE_KEY = 1
170f4f33ea0SBaptiste Daroussin ,sHAD_KEY = 2
171f4f33ea0SBaptiste Daroussin } HOTKEY;
172f4f33ea0SBaptiste Daroussin
1734c8945a0SNathan Whitehorn /*
1744c8945a0SNathan Whitehorn * Print a button
1754c8945a0SNathan Whitehorn */
1764c8945a0SNathan Whitehorn static void
print_button(WINDOW * win,char * label,int hotkey,int y,int x,int selected)1772a3e3873SBaptiste Daroussin print_button(WINDOW *win, char *label, int hotkey, int y, int x, int selected)
1784c8945a0SNathan Whitehorn {
1794c8945a0SNathan Whitehorn int i;
180f4f33ea0SBaptiste Daroussin HOTKEY state = sFIND_KEY;
1814c8945a0SNathan Whitehorn const int *indx = dlg_index_wchars(label);
1824c8945a0SNathan Whitehorn int limit = dlg_count_wchars(label);
1834c8945a0SNathan Whitehorn chtype key_attr = (selected
1844c8945a0SNathan Whitehorn ? button_key_active_attr
1854c8945a0SNathan Whitehorn : button_key_inactive_attr);
1864c8945a0SNathan Whitehorn chtype label_attr = (selected
1874c8945a0SNathan Whitehorn ? button_label_active_attr
1884c8945a0SNathan Whitehorn : button_label_inactive_attr);
1894c8945a0SNathan Whitehorn
1904c8945a0SNathan Whitehorn (void) wmove(win, y, x);
191f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected
1924c8945a0SNathan Whitehorn ? button_active_attr
1934c8945a0SNathan Whitehorn : button_inactive_attr);
1944c8945a0SNathan Whitehorn (void) waddstr(win, "<");
195f4f33ea0SBaptiste Daroussin dlg_attrset(win, label_attr);
1964c8945a0SNathan Whitehorn for (i = 0; i < limit; ++i) {
1972a3e3873SBaptiste Daroussin int check;
1984c8945a0SNathan Whitehorn int first = indx[i];
1994c8945a0SNathan Whitehorn int last = indx[i + 1];
2004c8945a0SNathan Whitehorn
2014c8945a0SNathan Whitehorn switch (state) {
202f4f33ea0SBaptiste Daroussin case sFIND_KEY:
2032a3e3873SBaptiste Daroussin check = UCH(label[first]);
2044c8945a0SNathan Whitehorn #ifdef USE_WIDE_CURSES
2054c8945a0SNathan Whitehorn if ((last - first) != 1) {
2064c8945a0SNathan Whitehorn const char *temp = (label + first);
2072a3e3873SBaptiste Daroussin check = string_to_char(&temp);
2084c8945a0SNathan Whitehorn }
2094c8945a0SNathan Whitehorn #endif
2102a3e3873SBaptiste Daroussin if (check == hotkey) {
211f4f33ea0SBaptiste Daroussin dlg_attrset(win, key_attr);
212f4f33ea0SBaptiste Daroussin state = sHAVE_KEY;
2134c8945a0SNathan Whitehorn }
2144c8945a0SNathan Whitehorn break;
215f4f33ea0SBaptiste Daroussin case sHAVE_KEY:
216f4f33ea0SBaptiste Daroussin dlg_attrset(win, label_attr);
217f4f33ea0SBaptiste Daroussin state = sHAD_KEY;
218f4f33ea0SBaptiste Daroussin break;
219f4f33ea0SBaptiste Daroussin default:
2204c8945a0SNathan Whitehorn break;
2214c8945a0SNathan Whitehorn }
2224c8945a0SNathan Whitehorn waddnstr(win, label + first, last - first);
2234c8945a0SNathan Whitehorn }
224f4f33ea0SBaptiste Daroussin dlg_attrset(win, selected
2254c8945a0SNathan Whitehorn ? button_active_attr
2264c8945a0SNathan Whitehorn : button_inactive_attr);
2274c8945a0SNathan Whitehorn (void) waddstr(win, ">");
228*a96ef450SBaptiste Daroussin if (!dialog_vars.cursor_off_label) {
229f4f33ea0SBaptiste Daroussin (void) wmove(win, y, x + ((int) (strspn) (label, " ")) + 1);
2304c8945a0SNathan Whitehorn }
231*a96ef450SBaptiste Daroussin }
2324c8945a0SNathan Whitehorn
2334c8945a0SNathan Whitehorn /*
2344c8945a0SNathan Whitehorn * Count the buttons in the list.
2354c8945a0SNathan Whitehorn */
2364c8945a0SNathan Whitehorn int
dlg_button_count(const char ** labels)2374c8945a0SNathan Whitehorn dlg_button_count(const char **labels)
2384c8945a0SNathan Whitehorn {
2394c8945a0SNathan Whitehorn int result = 0;
2404c8945a0SNathan Whitehorn while (*labels++ != 0)
2414c8945a0SNathan Whitehorn ++result;
2424c8945a0SNathan Whitehorn return result;
2434c8945a0SNathan Whitehorn }
2444c8945a0SNathan Whitehorn
2454c8945a0SNathan Whitehorn /*
2464c8945a0SNathan Whitehorn * Compute the size of the button array in columns. Return the total number of
2474c8945a0SNathan Whitehorn * columns in *length, and the longest button's columns in *longest
2484c8945a0SNathan Whitehorn */
2494c8945a0SNathan Whitehorn void
dlg_button_sizes(const char ** labels,int vertical,int * longest,int * length)2504c8945a0SNathan Whitehorn dlg_button_sizes(const char **labels,
2514c8945a0SNathan Whitehorn int vertical,
2524c8945a0SNathan Whitehorn int *longest,
2534c8945a0SNathan Whitehorn int *length)
2544c8945a0SNathan Whitehorn {
2554c8945a0SNathan Whitehorn int n;
2564c8945a0SNathan Whitehorn
2574c8945a0SNathan Whitehorn *length = 0;
2584c8945a0SNathan Whitehorn *longest = 0;
2594c8945a0SNathan Whitehorn for (n = 0; labels[n] != 0; n++) {
2604c8945a0SNathan Whitehorn if (vertical) {
2614c8945a0SNathan Whitehorn *length += 1;
2624c8945a0SNathan Whitehorn *longest = 1;
2634c8945a0SNathan Whitehorn } else {
2644c8945a0SNathan Whitehorn int len = dlg_count_columns(labels[n]);
2654c8945a0SNathan Whitehorn if (len > *longest)
2664c8945a0SNathan Whitehorn *longest = len;
2674c8945a0SNathan Whitehorn *length += len;
2684c8945a0SNathan Whitehorn }
2694c8945a0SNathan Whitehorn }
2704c8945a0SNathan Whitehorn /*
2714c8945a0SNathan Whitehorn * If we can, make all of the buttons the same size. This is only optional
2724c8945a0SNathan Whitehorn * for buttons laid out horizontally.
2734c8945a0SNathan Whitehorn */
2744c8945a0SNathan Whitehorn if (*longest < 6 - (*longest & 1))
2754c8945a0SNathan Whitehorn *longest = 6 - (*longest & 1);
2764c8945a0SNathan Whitehorn if (!vertical)
2774c8945a0SNathan Whitehorn *length = *longest * n;
2784c8945a0SNathan Whitehorn }
2794c8945a0SNathan Whitehorn
2804c8945a0SNathan Whitehorn /*
2814c8945a0SNathan Whitehorn * Compute the size of the button array.
2824c8945a0SNathan Whitehorn */
2834c8945a0SNathan Whitehorn int
dlg_button_x_step(const char ** labels,int limit,int * gap,int * margin,int * step)2844c8945a0SNathan Whitehorn dlg_button_x_step(const char **labels, int limit, int *gap, int *margin, int *step)
2854c8945a0SNathan Whitehorn {
2864c8945a0SNathan Whitehorn int count = dlg_button_count(labels);
2874c8945a0SNathan Whitehorn int longest;
2884c8945a0SNathan Whitehorn int length;
2892a3e3873SBaptiste Daroussin int result;
2904c8945a0SNathan Whitehorn
2912a3e3873SBaptiste Daroussin *margin = 0;
2922a3e3873SBaptiste Daroussin if (count != 0) {
293*a96ef450SBaptiste Daroussin int unused;
294*a96ef450SBaptiste Daroussin int used;
295*a96ef450SBaptiste Daroussin
2964c8945a0SNathan Whitehorn dlg_button_sizes(labels, FALSE, &longest, &length);
2974c8945a0SNathan Whitehorn used = (length + (count * 2));
2984c8945a0SNathan Whitehorn unused = limit - used;
2994c8945a0SNathan Whitehorn
3004c8945a0SNathan Whitehorn if ((*gap = unused / (count + 3)) <= 0) {
3014c8945a0SNathan Whitehorn if ((*gap = unused / (count + 1)) <= 0)
3024c8945a0SNathan Whitehorn *gap = 1;
3034c8945a0SNathan Whitehorn *margin = *gap;
3044c8945a0SNathan Whitehorn } else {
3054c8945a0SNathan Whitehorn *margin = *gap * 2;
3064c8945a0SNathan Whitehorn }
3074c8945a0SNathan Whitehorn *step = *gap + (used + count - 1) / count;
3082a3e3873SBaptiste Daroussin result = (*gap > 0) && (unused >= 0);
3092a3e3873SBaptiste Daroussin } else {
3102a3e3873SBaptiste Daroussin result = 0;
3112a3e3873SBaptiste Daroussin }
3122a3e3873SBaptiste Daroussin return result;
3134c8945a0SNathan Whitehorn }
3144c8945a0SNathan Whitehorn
3154c8945a0SNathan Whitehorn /*
3164c8945a0SNathan Whitehorn * Make sure there is enough space for the buttons
3174c8945a0SNathan Whitehorn */
3184c8945a0SNathan Whitehorn void
dlg_button_layout(const char ** labels,int * limit)3194c8945a0SNathan Whitehorn dlg_button_layout(const char **labels, int *limit)
3204c8945a0SNathan Whitehorn {
3214c8945a0SNathan Whitehorn int gap, margin, step;
3224c8945a0SNathan Whitehorn
3234c8945a0SNathan Whitehorn if (labels != 0 && dlg_button_count(labels)) {
324*a96ef450SBaptiste Daroussin int width = 1;
325*a96ef450SBaptiste Daroussin
3264c8945a0SNathan Whitehorn while (!dlg_button_x_step(labels, width, &gap, &margin, &step))
3274c8945a0SNathan Whitehorn ++width;
3284c8945a0SNathan Whitehorn width += (4 * MARGIN);
3294c8945a0SNathan Whitehorn if (width > COLS)
3304c8945a0SNathan Whitehorn width = COLS;
3314c8945a0SNathan Whitehorn if (width > *limit)
3324c8945a0SNathan Whitehorn *limit = width;
3334c8945a0SNathan Whitehorn }
3344c8945a0SNathan Whitehorn }
3354c8945a0SNathan Whitehorn
3364c8945a0SNathan Whitehorn /*
3374c8945a0SNathan Whitehorn * Print a list of buttons at the given position.
3384c8945a0SNathan Whitehorn */
3394c8945a0SNathan Whitehorn void
dlg_draw_buttons(WINDOW * win,int y,int x,const char ** labels,int selected,int vertical,int limit)3404c8945a0SNathan Whitehorn dlg_draw_buttons(WINDOW *win,
3414c8945a0SNathan Whitehorn int y, int x,
3424c8945a0SNathan Whitehorn const char **labels,
3434c8945a0SNathan Whitehorn int selected,
3444c8945a0SNathan Whitehorn int vertical,
3454c8945a0SNathan Whitehorn int limit)
3464c8945a0SNathan Whitehorn {
3477a1c0d96SNathan Whitehorn chtype save = dlg_get_attrs(win);
3484c8945a0SNathan Whitehorn int step = 0;
3494c8945a0SNathan Whitehorn int length;
3504c8945a0SNathan Whitehorn int longest;
3514c8945a0SNathan Whitehorn int final_x;
3524c8945a0SNathan Whitehorn int final_y;
3534c8945a0SNathan Whitehorn int gap;
3544c8945a0SNathan Whitehorn int margin;
3554c8945a0SNathan Whitehorn size_t need;
3564c8945a0SNathan Whitehorn
3574c8945a0SNathan Whitehorn dlg_mouse_setbase(getbegx(win), getbegy(win));
3584c8945a0SNathan Whitehorn
3594c8945a0SNathan Whitehorn getyx(win, final_y, final_x);
3604c8945a0SNathan Whitehorn
3614c8945a0SNathan Whitehorn dlg_button_sizes(labels, vertical, &longest, &length);
3624c8945a0SNathan Whitehorn
3634c8945a0SNathan Whitehorn if (vertical) {
3644c8945a0SNathan Whitehorn y += 1;
3654c8945a0SNathan Whitehorn step = 1;
3664c8945a0SNathan Whitehorn } else {
3674c8945a0SNathan Whitehorn dlg_button_x_step(labels, limit, &gap, &margin, &step);
3684c8945a0SNathan Whitehorn x += margin;
3694c8945a0SNathan Whitehorn }
3704c8945a0SNathan Whitehorn
3714c8945a0SNathan Whitehorn /*
3724c8945a0SNathan Whitehorn * Allocate a buffer big enough for any label.
3734c8945a0SNathan Whitehorn */
3744c8945a0SNathan Whitehorn need = (size_t) longest;
3752a3e3873SBaptiste Daroussin if (need != 0) {
376*a96ef450SBaptiste Daroussin char *buffer;
377*a96ef450SBaptiste Daroussin int n;
3782a3e3873SBaptiste Daroussin int *hotkeys = get_hotkeys(labels);
379*a96ef450SBaptiste Daroussin
3802a3e3873SBaptiste Daroussin assert_ptr(hotkeys, "dlg_draw_buttons");
3812a3e3873SBaptiste Daroussin
3824c8945a0SNathan Whitehorn for (n = 0; labels[n] != 0; ++n) {
3834c8945a0SNathan Whitehorn need += strlen(labels[n]) + 1;
3844c8945a0SNathan Whitehorn }
3854c8945a0SNathan Whitehorn buffer = dlg_malloc(char, need);
3864c8945a0SNathan Whitehorn assert_ptr(buffer, "dlg_draw_buttons");
3874c8945a0SNathan Whitehorn
3884c8945a0SNathan Whitehorn /*
3894c8945a0SNathan Whitehorn * Draw the labels.
3904c8945a0SNathan Whitehorn */
3914c8945a0SNathan Whitehorn for (n = 0; labels[n] != 0; n++) {
3924c8945a0SNathan Whitehorn center_label(buffer, longest, labels[n]);
3934c8945a0SNathan Whitehorn mouse_mkbutton(y, x, dlg_count_columns(buffer), n);
394f4f33ea0SBaptiste Daroussin print_button(win, buffer,
395f4f33ea0SBaptiste Daroussin CHR_BUTTON ? hotkeys[n] : -1,
396f4f33ea0SBaptiste Daroussin y, x,
3974c8945a0SNathan Whitehorn (selected == n) || (n == 0 && selected < 0));
3984c8945a0SNathan Whitehorn if (selected == n)
3994c8945a0SNathan Whitehorn getyx(win, final_y, final_x);
4004c8945a0SNathan Whitehorn
4014c8945a0SNathan Whitehorn if (vertical) {
4024c8945a0SNathan Whitehorn if ((y += step) > limit)
4034c8945a0SNathan Whitehorn break;
4044c8945a0SNathan Whitehorn } else {
4054c8945a0SNathan Whitehorn if ((x += step) > limit)
4064c8945a0SNathan Whitehorn break;
4074c8945a0SNathan Whitehorn }
4084c8945a0SNathan Whitehorn }
4094c8945a0SNathan Whitehorn (void) wmove(win, final_y, final_x);
4104c8945a0SNathan Whitehorn wrefresh(win);
411f4f33ea0SBaptiste Daroussin dlg_attrset(win, save);
4124c8945a0SNathan Whitehorn free(buffer);
4132a3e3873SBaptiste Daroussin free(hotkeys);
4142a3e3873SBaptiste Daroussin }
4154c8945a0SNathan Whitehorn }
4164c8945a0SNathan Whitehorn
4174c8945a0SNathan Whitehorn /*
4184c8945a0SNathan Whitehorn * Match a given character against the beginning of the string, ignoring case
4194c8945a0SNathan Whitehorn * of the given character. The matching string must begin with an uppercase
4204c8945a0SNathan Whitehorn * character.
4214c8945a0SNathan Whitehorn */
4224c8945a0SNathan Whitehorn int
dlg_match_char(int ch,const char * string)4234c8945a0SNathan Whitehorn dlg_match_char(int ch, const char *string)
4244c8945a0SNathan Whitehorn {
425*a96ef450SBaptiste Daroussin if (!dialog_vars.no_hot_list) {
4264c8945a0SNathan Whitehorn if (string != 0) {
4274c8945a0SNathan Whitehorn int cmp2 = string_to_char(&string);
4284c8945a0SNathan Whitehorn #ifdef USE_WIDE_CURSES
4294c8945a0SNathan Whitehorn wint_t cmp1 = dlg_toupper(ch);
4304c8945a0SNathan Whitehorn if (cmp2 != 0 && (wchar_t) cmp1 == (wchar_t) dlg_toupper(cmp2)) {
4314c8945a0SNathan Whitehorn return TRUE;
4324c8945a0SNathan Whitehorn }
4334c8945a0SNathan Whitehorn #else
4344c8945a0SNathan Whitehorn if (ch > 0 && ch < 256) {
4354c8945a0SNathan Whitehorn if (dlg_toupper(ch) == dlg_toupper(cmp2))
4364c8945a0SNathan Whitehorn return TRUE;
4374c8945a0SNathan Whitehorn }
4384c8945a0SNathan Whitehorn #endif
4394c8945a0SNathan Whitehorn }
440*a96ef450SBaptiste Daroussin }
4414c8945a0SNathan Whitehorn return FALSE;
4424c8945a0SNathan Whitehorn }
4434c8945a0SNathan Whitehorn
4444c8945a0SNathan Whitehorn /*
4454c8945a0SNathan Whitehorn * Find the first uppercase character in the label, which we may use for an
4464c8945a0SNathan Whitehorn * abbreviation.
4474c8945a0SNathan Whitehorn */
4484c8945a0SNathan Whitehorn int
dlg_button_to_char(const char * label)4494c8945a0SNathan Whitehorn dlg_button_to_char(const char *label)
4504c8945a0SNathan Whitehorn {
4514c8945a0SNathan Whitehorn int cmp = -1;
4524c8945a0SNathan Whitehorn
4534c8945a0SNathan Whitehorn while (*label != 0) {
454*a96ef450SBaptiste Daroussin int ch = string_to_char(&label);
455*a96ef450SBaptiste Daroussin if (dlg_isupper(ch)) {
456*a96ef450SBaptiste Daroussin cmp = ch;
4574c8945a0SNathan Whitehorn break;
4584c8945a0SNathan Whitehorn }
4594c8945a0SNathan Whitehorn }
4604c8945a0SNathan Whitehorn return cmp;
4614c8945a0SNathan Whitehorn }
4624c8945a0SNathan Whitehorn
4634c8945a0SNathan Whitehorn /*
4644c8945a0SNathan Whitehorn * Given a list of button labels, and a character which may be the abbreviation
4654c8945a0SNathan Whitehorn * for one, find it, if it exists. An abbreviation will be the first character
4664c8945a0SNathan Whitehorn * which happens to be capitalized in the label.
4674c8945a0SNathan Whitehorn */
4684c8945a0SNathan Whitehorn int
dlg_char_to_button(int ch,const char ** labels)4694c8945a0SNathan Whitehorn dlg_char_to_button(int ch, const char **labels)
4704c8945a0SNathan Whitehorn {
4712a3e3873SBaptiste Daroussin int result = DLG_EXIT_UNKNOWN;
4722a3e3873SBaptiste Daroussin
4734c8945a0SNathan Whitehorn if (labels != 0) {
4742a3e3873SBaptiste Daroussin int *hotkeys = get_hotkeys(labels);
4754c8945a0SNathan Whitehorn
4764c8945a0SNathan Whitehorn ch = (int) dlg_toupper(dlg_last_getc());
4772a3e3873SBaptiste Daroussin
4782a3e3873SBaptiste Daroussin if (hotkeys != 0) {
479*a96ef450SBaptiste Daroussin int j;
480*a96ef450SBaptiste Daroussin
4814c8945a0SNathan Whitehorn for (j = 0; labels[j] != 0; ++j) {
4822a3e3873SBaptiste Daroussin if (ch == hotkeys[j]) {
4834c8945a0SNathan Whitehorn dlg_flush_getc();
4842a3e3873SBaptiste Daroussin result = j;
4852a3e3873SBaptiste Daroussin break;
4864c8945a0SNathan Whitehorn }
4874c8945a0SNathan Whitehorn }
4882a3e3873SBaptiste Daroussin free(hotkeys);
4894c8945a0SNathan Whitehorn }
4902a3e3873SBaptiste Daroussin }
4912a3e3873SBaptiste Daroussin
4922a3e3873SBaptiste Daroussin return result;
4934c8945a0SNathan Whitehorn }
4944c8945a0SNathan Whitehorn
4954c8945a0SNathan Whitehorn static const char *
my_yes_label(void)4964c8945a0SNathan Whitehorn my_yes_label(void)
4974c8945a0SNathan Whitehorn {
4984c8945a0SNathan Whitehorn return (dialog_vars.yes_label != NULL)
4994c8945a0SNathan Whitehorn ? dialog_vars.yes_label
5004c8945a0SNathan Whitehorn : _("Yes");
5014c8945a0SNathan Whitehorn }
5024c8945a0SNathan Whitehorn
5034c8945a0SNathan Whitehorn static const char *
my_no_label(void)5044c8945a0SNathan Whitehorn my_no_label(void)
5054c8945a0SNathan Whitehorn {
5064c8945a0SNathan Whitehorn return (dialog_vars.no_label != NULL)
5074c8945a0SNathan Whitehorn ? dialog_vars.no_label
5084c8945a0SNathan Whitehorn : _("No");
5094c8945a0SNathan Whitehorn }
5104c8945a0SNathan Whitehorn
5114c8945a0SNathan Whitehorn static const char *
my_ok_label(void)5124c8945a0SNathan Whitehorn my_ok_label(void)
5134c8945a0SNathan Whitehorn {
5144c8945a0SNathan Whitehorn return (dialog_vars.ok_label != NULL)
5154c8945a0SNathan Whitehorn ? dialog_vars.ok_label
5164c8945a0SNathan Whitehorn : _("OK");
5174c8945a0SNathan Whitehorn }
5184c8945a0SNathan Whitehorn
5194c8945a0SNathan Whitehorn static const char *
my_cancel_label(void)5204c8945a0SNathan Whitehorn my_cancel_label(void)
5214c8945a0SNathan Whitehorn {
5224c8945a0SNathan Whitehorn return (dialog_vars.cancel_label != NULL)
5234c8945a0SNathan Whitehorn ? dialog_vars.cancel_label
5244c8945a0SNathan Whitehorn : _("Cancel");
5254c8945a0SNathan Whitehorn }
5264c8945a0SNathan Whitehorn
5274c8945a0SNathan Whitehorn static const char *
my_exit_label(void)5284c8945a0SNathan Whitehorn my_exit_label(void)
5294c8945a0SNathan Whitehorn {
5304c8945a0SNathan Whitehorn return (dialog_vars.exit_label != NULL)
5314c8945a0SNathan Whitehorn ? dialog_vars.exit_label
5324c8945a0SNathan Whitehorn : _("EXIT");
5334c8945a0SNathan Whitehorn }
5344c8945a0SNathan Whitehorn
5354c8945a0SNathan Whitehorn static const char *
my_extra_label(void)5364c8945a0SNathan Whitehorn my_extra_label(void)
5374c8945a0SNathan Whitehorn {
5384c8945a0SNathan Whitehorn return (dialog_vars.extra_label != NULL)
5394c8945a0SNathan Whitehorn ? dialog_vars.extra_label
5404c8945a0SNathan Whitehorn : _("Extra");
5414c8945a0SNathan Whitehorn }
5424c8945a0SNathan Whitehorn
5434c8945a0SNathan Whitehorn static const char *
my_help_label(void)5444c8945a0SNathan Whitehorn my_help_label(void)
5454c8945a0SNathan Whitehorn {
5464c8945a0SNathan Whitehorn return (dialog_vars.help_label != NULL)
5474c8945a0SNathan Whitehorn ? dialog_vars.help_label
5484c8945a0SNathan Whitehorn : _("Help");
5494c8945a0SNathan Whitehorn }
5504c8945a0SNathan Whitehorn
5514c8945a0SNathan Whitehorn /*
5524c8945a0SNathan Whitehorn * Return a list of button labels.
5534c8945a0SNathan Whitehorn */
5544c8945a0SNathan Whitehorn const char **
dlg_exit_label(void)5554c8945a0SNathan Whitehorn dlg_exit_label(void)
5564c8945a0SNathan Whitehorn {
5574c8945a0SNathan Whitehorn const char **result;
558682c9e0fSNathan Whitehorn DIALOG_VARS save;
5594c8945a0SNathan Whitehorn
5604c8945a0SNathan Whitehorn if (dialog_vars.extra_button) {
561682c9e0fSNathan Whitehorn dlg_save_vars(&save);
562682c9e0fSNathan Whitehorn dialog_vars.nocancel = TRUE;
5634c8945a0SNathan Whitehorn result = dlg_ok_labels();
564682c9e0fSNathan Whitehorn dlg_restore_vars(&save);
5654c8945a0SNathan Whitehorn } else {
5664c8945a0SNathan Whitehorn static const char *labels[3];
5674c8945a0SNathan Whitehorn int n = 0;
5684c8945a0SNathan Whitehorn
569682c9e0fSNathan Whitehorn if (!dialog_vars.nook)
5704c8945a0SNathan Whitehorn labels[n++] = my_exit_label();
5714c8945a0SNathan Whitehorn if (dialog_vars.help_button)
5724c8945a0SNathan Whitehorn labels[n++] = my_help_label();
573682c9e0fSNathan Whitehorn if (n == 0)
574682c9e0fSNathan Whitehorn labels[n++] = my_exit_label();
5754c8945a0SNathan Whitehorn labels[n] = 0;
5764c8945a0SNathan Whitehorn
5774c8945a0SNathan Whitehorn result = labels;
5784c8945a0SNathan Whitehorn }
5794c8945a0SNathan Whitehorn return result;
5804c8945a0SNathan Whitehorn }
5814c8945a0SNathan Whitehorn
5824c8945a0SNathan Whitehorn /*
5834c8945a0SNathan Whitehorn * Map the given button index for dlg_exit_label() into our exit-code.
5844c8945a0SNathan Whitehorn */
5854c8945a0SNathan Whitehorn int
dlg_exit_buttoncode(int button)5864c8945a0SNathan Whitehorn dlg_exit_buttoncode(int button)
5874c8945a0SNathan Whitehorn {
588682c9e0fSNathan Whitehorn int result;
589682c9e0fSNathan Whitehorn DIALOG_VARS save;
590682c9e0fSNathan Whitehorn
591682c9e0fSNathan Whitehorn dlg_save_vars(&save);
592682c9e0fSNathan Whitehorn dialog_vars.nocancel = TRUE;
593682c9e0fSNathan Whitehorn
594682c9e0fSNathan Whitehorn result = dlg_ok_buttoncode(button);
595682c9e0fSNathan Whitehorn
596682c9e0fSNathan Whitehorn dlg_restore_vars(&save);
597682c9e0fSNathan Whitehorn
598682c9e0fSNathan Whitehorn return result;
5994c8945a0SNathan Whitehorn }
6004c8945a0SNathan Whitehorn
601*a96ef450SBaptiste Daroussin static const char **
finish_ok_label(const char ** labels,int n)602*a96ef450SBaptiste Daroussin finish_ok_label(const char **labels, int n)
603*a96ef450SBaptiste Daroussin {
604*a96ef450SBaptiste Daroussin if (n == 0) {
605*a96ef450SBaptiste Daroussin labels[n++] = my_ok_label();
606*a96ef450SBaptiste Daroussin dialog_vars.nook = FALSE;
607*a96ef450SBaptiste Daroussin dlg_trace_msg("# ignore --nook, since at least one button is needed\n");
608*a96ef450SBaptiste Daroussin }
609*a96ef450SBaptiste Daroussin
610*a96ef450SBaptiste Daroussin labels[n] = NULL;
611*a96ef450SBaptiste Daroussin return labels;
612*a96ef450SBaptiste Daroussin }
613*a96ef450SBaptiste Daroussin
614*a96ef450SBaptiste Daroussin /*
615*a96ef450SBaptiste Daroussin * Return a list of button labels for the OK (no Cancel) group, used in msgbox
616*a96ef450SBaptiste Daroussin * and progressbox.
617*a96ef450SBaptiste Daroussin */
6184c8945a0SNathan Whitehorn const char **
dlg_ok_label(void)6194c8945a0SNathan Whitehorn dlg_ok_label(void)
6204c8945a0SNathan Whitehorn {
6212a3e3873SBaptiste Daroussin static const char *labels[4];
6224c8945a0SNathan Whitehorn int n = 0;
6234c8945a0SNathan Whitehorn
624*a96ef450SBaptiste Daroussin if (!dialog_vars.nook)
6254c8945a0SNathan Whitehorn labels[n++] = my_ok_label();
6262a3e3873SBaptiste Daroussin if (dialog_vars.extra_button)
6272a3e3873SBaptiste Daroussin labels[n++] = my_extra_label();
6284c8945a0SNathan Whitehorn if (dialog_vars.help_button)
6294c8945a0SNathan Whitehorn labels[n++] = my_help_label();
630*a96ef450SBaptiste Daroussin
631*a96ef450SBaptiste Daroussin return finish_ok_label(labels, n);
6324c8945a0SNathan Whitehorn }
6334c8945a0SNathan Whitehorn
6344c8945a0SNathan Whitehorn /*
635*a96ef450SBaptiste Daroussin * Return a list of button labels for the OK/Cancel group, used in most widgets
636*a96ef450SBaptiste Daroussin * that select an option or data.
6374c8945a0SNathan Whitehorn */
6384c8945a0SNathan Whitehorn const char **
dlg_ok_labels(void)6394c8945a0SNathan Whitehorn dlg_ok_labels(void)
6404c8945a0SNathan Whitehorn {
6414c8945a0SNathan Whitehorn static const char *labels[5];
6424c8945a0SNathan Whitehorn int n = 0;
6434c8945a0SNathan Whitehorn
6444c8945a0SNathan Whitehorn if (!dialog_vars.nook)
6454c8945a0SNathan Whitehorn labels[n++] = my_ok_label();
6464c8945a0SNathan Whitehorn if (dialog_vars.extra_button)
6474c8945a0SNathan Whitehorn labels[n++] = my_extra_label();
6484c8945a0SNathan Whitehorn if (!dialog_vars.nocancel)
6494c8945a0SNathan Whitehorn labels[n++] = my_cancel_label();
6504c8945a0SNathan Whitehorn if (dialog_vars.help_button)
6514c8945a0SNathan Whitehorn labels[n++] = my_help_label();
652*a96ef450SBaptiste Daroussin
653*a96ef450SBaptiste Daroussin return finish_ok_label(labels, n);
6544c8945a0SNathan Whitehorn }
6554c8945a0SNathan Whitehorn
6564c8945a0SNathan Whitehorn /*
6574c8945a0SNathan Whitehorn * Map the given button index for dlg_ok_labels() into our exit-code
6584c8945a0SNathan Whitehorn */
6594c8945a0SNathan Whitehorn int
dlg_ok_buttoncode(int button)6604c8945a0SNathan Whitehorn dlg_ok_buttoncode(int button)
6614c8945a0SNathan Whitehorn {
6624c8945a0SNathan Whitehorn int result = DLG_EXIT_ERROR;
6634c8945a0SNathan Whitehorn int n = !dialog_vars.nook;
6644c8945a0SNathan Whitehorn
6654c8945a0SNathan Whitehorn if (!dialog_vars.nook && (button <= 0)) {
6664c8945a0SNathan Whitehorn result = DLG_EXIT_OK;
6674c8945a0SNathan Whitehorn } else if (dialog_vars.extra_button && (button == n++)) {
6684c8945a0SNathan Whitehorn result = DLG_EXIT_EXTRA;
6694c8945a0SNathan Whitehorn } else if (!dialog_vars.nocancel && (button == n++)) {
6704c8945a0SNathan Whitehorn result = DLG_EXIT_CANCEL;
6714c8945a0SNathan Whitehorn } else if (dialog_vars.help_button && (button == n)) {
6724c8945a0SNathan Whitehorn result = DLG_EXIT_HELP;
6734c8945a0SNathan Whitehorn }
674*a96ef450SBaptiste Daroussin DLG_TRACE(("# dlg_ok_buttoncode(%d) = %d:%s\n",
675*a96ef450SBaptiste Daroussin button, result, dlg_exitcode2s(result)));
6764c8945a0SNathan Whitehorn return result;
6774c8945a0SNathan Whitehorn }
6784c8945a0SNathan Whitehorn
6794c8945a0SNathan Whitehorn /*
6804c8945a0SNathan Whitehorn * Given that we're using dlg_ok_labels() to list buttons, find the next index
6814c8945a0SNathan Whitehorn * in the list of buttons. The 'extra' parameter if negative provides a way to
6824c8945a0SNathan Whitehorn * enumerate extra active areas on the widget.
6834c8945a0SNathan Whitehorn */
6844c8945a0SNathan Whitehorn int
dlg_next_ok_buttonindex(int current,int extra)6854c8945a0SNathan Whitehorn dlg_next_ok_buttonindex(int current, int extra)
6864c8945a0SNathan Whitehorn {
6874c8945a0SNathan Whitehorn int result = current + 1;
6884c8945a0SNathan Whitehorn
6894c8945a0SNathan Whitehorn if (current >= 0
6904c8945a0SNathan Whitehorn && dlg_ok_buttoncode(result) < 0)
6914c8945a0SNathan Whitehorn result = extra;
6924c8945a0SNathan Whitehorn return result;
6934c8945a0SNathan Whitehorn }
6944c8945a0SNathan Whitehorn
6954c8945a0SNathan Whitehorn /*
6964c8945a0SNathan Whitehorn * Similarly, find the previous button index.
6974c8945a0SNathan Whitehorn */
6984c8945a0SNathan Whitehorn int
dlg_prev_ok_buttonindex(int current,int extra)6994c8945a0SNathan Whitehorn dlg_prev_ok_buttonindex(int current, int extra)
7004c8945a0SNathan Whitehorn {
7014c8945a0SNathan Whitehorn int result = current - 1;
7024c8945a0SNathan Whitehorn
7034c8945a0SNathan Whitehorn if (result < extra) {
7044c8945a0SNathan Whitehorn for (result = 0; dlg_ok_buttoncode(result + 1) >= 0; ++result) {
7054c8945a0SNathan Whitehorn ;
7064c8945a0SNathan Whitehorn }
7074c8945a0SNathan Whitehorn }
7084c8945a0SNathan Whitehorn return result;
7094c8945a0SNathan Whitehorn }
7104c8945a0SNathan Whitehorn
7114c8945a0SNathan Whitehorn /*
7124c8945a0SNathan Whitehorn * Find the button-index for the "OK" or "Cancel" button, according to
7134c8945a0SNathan Whitehorn * whether --defaultno is given. If --nocancel was given, we always return
7142a3e3873SBaptiste Daroussin * the index for the first button (usually "OK" unless --nook was used).
7154c8945a0SNathan Whitehorn */
7164c8945a0SNathan Whitehorn int
dlg_defaultno_button(void)7174c8945a0SNathan Whitehorn dlg_defaultno_button(void)
7184c8945a0SNathan Whitehorn {
7194c8945a0SNathan Whitehorn int result = 0;
7204c8945a0SNathan Whitehorn
7214c8945a0SNathan Whitehorn if (dialog_vars.defaultno && !dialog_vars.nocancel) {
7224c8945a0SNathan Whitehorn while (dlg_ok_buttoncode(result) != DLG_EXIT_CANCEL)
7234c8945a0SNathan Whitehorn ++result;
7244c8945a0SNathan Whitehorn }
725f4f33ea0SBaptiste Daroussin DLG_TRACE(("# dlg_defaultno_button() = %d\n", result));
7262a3e3873SBaptiste Daroussin return result;
7272a3e3873SBaptiste Daroussin }
7282a3e3873SBaptiste Daroussin
7292a3e3873SBaptiste Daroussin /*
7302a3e3873SBaptiste Daroussin * Find the button-index for a button named with --default-button. If the
7312a3e3873SBaptiste Daroussin * option was not specified, or if the selected button does not exist, return
7322a3e3873SBaptiste Daroussin * the index of the first button (usually "OK" unless --nook was used).
7332a3e3873SBaptiste Daroussin */
7342a3e3873SBaptiste Daroussin int
dlg_default_button(void)7352a3e3873SBaptiste Daroussin dlg_default_button(void)
7362a3e3873SBaptiste Daroussin {
7372a3e3873SBaptiste Daroussin int result = 0;
7382a3e3873SBaptiste Daroussin
7392a3e3873SBaptiste Daroussin if (dialog_vars.default_button >= 0) {
740*a96ef450SBaptiste Daroussin int i, n;
741*a96ef450SBaptiste Daroussin
7422a3e3873SBaptiste Daroussin for (i = 0; (n = dlg_ok_buttoncode(i)) >= 0; i++) {
7432a3e3873SBaptiste Daroussin if (n == dialog_vars.default_button) {
7442a3e3873SBaptiste Daroussin result = i;
7452a3e3873SBaptiste Daroussin break;
7462a3e3873SBaptiste Daroussin }
7472a3e3873SBaptiste Daroussin }
7482a3e3873SBaptiste Daroussin }
749f4f33ea0SBaptiste Daroussin DLG_TRACE(("# dlg_default_button() = %d\n", result));
7504c8945a0SNathan Whitehorn return result;
7514c8945a0SNathan Whitehorn }
7524c8945a0SNathan Whitehorn
7534c8945a0SNathan Whitehorn /*
7544c8945a0SNathan Whitehorn * Return a list of buttons for Yes/No labels.
7554c8945a0SNathan Whitehorn */
7564c8945a0SNathan Whitehorn const char **
dlg_yes_labels(void)7574c8945a0SNathan Whitehorn dlg_yes_labels(void)
7584c8945a0SNathan Whitehorn {
7594c8945a0SNathan Whitehorn const char **result;
7604c8945a0SNathan Whitehorn
7614c8945a0SNathan Whitehorn if (dialog_vars.extra_button) {
7624c8945a0SNathan Whitehorn result = dlg_ok_labels();
7634c8945a0SNathan Whitehorn } else {
7644c8945a0SNathan Whitehorn static const char *labels[4];
7654c8945a0SNathan Whitehorn int n = 0;
7664c8945a0SNathan Whitehorn
7674c8945a0SNathan Whitehorn labels[n++] = my_yes_label();
7684c8945a0SNathan Whitehorn labels[n++] = my_no_label();
7694c8945a0SNathan Whitehorn if (dialog_vars.help_button)
7704c8945a0SNathan Whitehorn labels[n++] = my_help_label();
7714c8945a0SNathan Whitehorn labels[n] = 0;
7724c8945a0SNathan Whitehorn
7734c8945a0SNathan Whitehorn result = labels;
7744c8945a0SNathan Whitehorn }
7754c8945a0SNathan Whitehorn
7764c8945a0SNathan Whitehorn return result;
7774c8945a0SNathan Whitehorn }
7784c8945a0SNathan Whitehorn
7794c8945a0SNathan Whitehorn /*
7804c8945a0SNathan Whitehorn * Map the given button index for dlg_yes_labels() into our exit-code.
7814c8945a0SNathan Whitehorn */
7824c8945a0SNathan Whitehorn int
dlg_yes_buttoncode(int button)7834c8945a0SNathan Whitehorn dlg_yes_buttoncode(int button)
7844c8945a0SNathan Whitehorn {
7854c8945a0SNathan Whitehorn int result = DLG_EXIT_ERROR;
7864c8945a0SNathan Whitehorn
7874c8945a0SNathan Whitehorn if (dialog_vars.extra_button) {
7884c8945a0SNathan Whitehorn result = dlg_ok_buttoncode(button);
7894c8945a0SNathan Whitehorn } else if (button == 0) {
7904c8945a0SNathan Whitehorn result = DLG_EXIT_OK;
7914c8945a0SNathan Whitehorn } else if (button == 1) {
7924c8945a0SNathan Whitehorn result = DLG_EXIT_CANCEL;
7934c8945a0SNathan Whitehorn } else if (button == 2 && dialog_vars.help_button) {
7944c8945a0SNathan Whitehorn result = DLG_EXIT_HELP;
7954c8945a0SNathan Whitehorn }
7964c8945a0SNathan Whitehorn
7974c8945a0SNathan Whitehorn return result;
7984c8945a0SNathan Whitehorn }
7994c8945a0SNathan Whitehorn
8004c8945a0SNathan Whitehorn /*
8014c8945a0SNathan Whitehorn * Return the next index in labels[];
8024c8945a0SNathan Whitehorn */
8034c8945a0SNathan Whitehorn int
dlg_next_button(const char ** labels,int button)8044c8945a0SNathan Whitehorn dlg_next_button(const char **labels, int button)
8054c8945a0SNathan Whitehorn {
8062a3e3873SBaptiste Daroussin if (button < -1)
8072a3e3873SBaptiste Daroussin button = -1;
8082a3e3873SBaptiste Daroussin
8092a3e3873SBaptiste Daroussin if (labels[button + 1] != 0) {
8104c8945a0SNathan Whitehorn ++button;
8112a3e3873SBaptiste Daroussin } else {
8124c8945a0SNathan Whitehorn button = MIN_BUTTON;
8132a3e3873SBaptiste Daroussin }
8144c8945a0SNathan Whitehorn return button;
8154c8945a0SNathan Whitehorn }
8164c8945a0SNathan Whitehorn
8174c8945a0SNathan Whitehorn /*
8184c8945a0SNathan Whitehorn * Return the previous index in labels[];
8194c8945a0SNathan Whitehorn */
8204c8945a0SNathan Whitehorn int
dlg_prev_button(const char ** labels,int button)8214c8945a0SNathan Whitehorn dlg_prev_button(const char **labels, int button)
8224c8945a0SNathan Whitehorn {
8232a3e3873SBaptiste Daroussin if (button > MIN_BUTTON) {
8244c8945a0SNathan Whitehorn --button;
8252a3e3873SBaptiste Daroussin } else {
8262a3e3873SBaptiste Daroussin if (button < -1)
8272a3e3873SBaptiste Daroussin button = -1;
8282a3e3873SBaptiste Daroussin
8294c8945a0SNathan Whitehorn while (labels[button + 1] != 0)
8304c8945a0SNathan Whitehorn ++button;
8314c8945a0SNathan Whitehorn }
8324c8945a0SNathan Whitehorn return button;
8334c8945a0SNathan Whitehorn }
834