xref: /freebsd/contrib/dialog/rangebox.c (revision f4f33ea0c752ff0f9bfad34991d5bbb54e71133d)
12a3e3873SBaptiste Daroussin /*
2*f4f33ea0SBaptiste Daroussin  *  $Id: rangebox.c,v 1.24 2018/06/19 22:57:01 tom Exp $
32a3e3873SBaptiste Daroussin  *
42a3e3873SBaptiste Daroussin  *  rangebox.c -- implements the rangebox dialog
52a3e3873SBaptiste Daroussin  *
6*f4f33ea0SBaptiste Daroussin  *  Copyright 2012-2017,2018	Thomas E. Dickey
72a3e3873SBaptiste Daroussin  *
82a3e3873SBaptiste Daroussin  *  This program is free software; you can redistribute it and/or modify
92a3e3873SBaptiste Daroussin  *  it under the terms of the GNU Lesser General Public License, version 2.1
102a3e3873SBaptiste Daroussin  *  as published by the Free Software Foundation.
112a3e3873SBaptiste Daroussin  *
122a3e3873SBaptiste Daroussin  *  This program is distributed in the hope that it will be useful, but
132a3e3873SBaptiste Daroussin  *  WITHOUT ANY WARRANTY; without even the implied warranty of
142a3e3873SBaptiste Daroussin  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
152a3e3873SBaptiste Daroussin  *  Lesser General Public License for more details.
162a3e3873SBaptiste Daroussin  *
172a3e3873SBaptiste Daroussin  *  You should have received a copy of the GNU Lesser General Public
182a3e3873SBaptiste Daroussin  *  License along with this program; if not, write to
192a3e3873SBaptiste Daroussin  *	Free Software Foundation, Inc.
202a3e3873SBaptiste Daroussin  *	51 Franklin St., Fifth Floor
212a3e3873SBaptiste Daroussin  *	Boston, MA 02110, USA.
222a3e3873SBaptiste Daroussin  */
232a3e3873SBaptiste Daroussin 
242a3e3873SBaptiste Daroussin #include <dialog.h>
252a3e3873SBaptiste Daroussin #include <dlg_keys.h>
262a3e3873SBaptiste Daroussin 
272a3e3873SBaptiste Daroussin #define ONE_HIGH 1
282a3e3873SBaptiste Daroussin 
292a3e3873SBaptiste Daroussin #define MIN_HIGH (ONE_HIGH + 1 + (4 * MARGIN))
302a3e3873SBaptiste Daroussin #define MIN_WIDE (10 + 2 + (2 * MARGIN))
312a3e3873SBaptiste Daroussin 
322a3e3873SBaptiste Daroussin struct _box;
332a3e3873SBaptiste Daroussin 
342a3e3873SBaptiste Daroussin typedef struct _box {
352a3e3873SBaptiste Daroussin     WINDOW *parent;
362a3e3873SBaptiste Daroussin     WINDOW *window;
372a3e3873SBaptiste Daroussin     int x;
382a3e3873SBaptiste Daroussin     int y;
392a3e3873SBaptiste Daroussin     int width;
402a3e3873SBaptiste Daroussin     int height;
412a3e3873SBaptiste Daroussin     int period;
422a3e3873SBaptiste Daroussin     int value;
432a3e3873SBaptiste Daroussin } BOX;
442a3e3873SBaptiste Daroussin 
452a3e3873SBaptiste Daroussin typedef struct {
462a3e3873SBaptiste Daroussin     /* window in which the value and slider are drawn */
472a3e3873SBaptiste Daroussin     WINDOW *window;
482a3e3873SBaptiste Daroussin     int min_value;
492a3e3873SBaptiste Daroussin     int max_value;
502a3e3873SBaptiste Daroussin     /* position and width of the numeric field */
512a3e3873SBaptiste Daroussin     int value_x;
522a3e3873SBaptiste Daroussin     int value_len;
532a3e3873SBaptiste Daroussin     int value_col;
542a3e3873SBaptiste Daroussin     /* position and width of the slider field */
552a3e3873SBaptiste Daroussin     int slide_x;
562a3e3873SBaptiste Daroussin     int slide_y;
572a3e3873SBaptiste Daroussin     int slide_len;
582a3e3873SBaptiste Daroussin     /* current value drawn */
592a3e3873SBaptiste Daroussin     int current;
602a3e3873SBaptiste Daroussin     /* value to add to make slider move by one cell */
612a3e3873SBaptiste Daroussin     int slide_inc;
622a3e3873SBaptiste Daroussin } VALUE;
632a3e3873SBaptiste Daroussin 
642a3e3873SBaptiste Daroussin static int
652a3e3873SBaptiste Daroussin digits_of(int value)
662a3e3873SBaptiste Daroussin {
672a3e3873SBaptiste Daroussin     char temp[80];
682a3e3873SBaptiste Daroussin     sprintf(temp, "%d", value);
692a3e3873SBaptiste Daroussin     return (int) strlen(temp);
702a3e3873SBaptiste Daroussin }
712a3e3873SBaptiste Daroussin 
722a3e3873SBaptiste Daroussin static int
732a3e3873SBaptiste Daroussin digit_of(VALUE * data)
742a3e3873SBaptiste Daroussin {
752a3e3873SBaptiste Daroussin     int col = data->value_col;
762a3e3873SBaptiste Daroussin     int result = 1;
772a3e3873SBaptiste Daroussin 
782a3e3873SBaptiste Daroussin     while (++col < data->value_len) {
792a3e3873SBaptiste Daroussin 	result *= 10;
802a3e3873SBaptiste Daroussin     }
812a3e3873SBaptiste Daroussin     return result;
822a3e3873SBaptiste Daroussin }
832a3e3873SBaptiste Daroussin 
842a3e3873SBaptiste Daroussin static bool
852a3e3873SBaptiste Daroussin set_digit(VALUE * data, int chr)
862a3e3873SBaptiste Daroussin {
872a3e3873SBaptiste Daroussin     bool result = FALSE;
882a3e3873SBaptiste Daroussin     char buffer[80];
892a3e3873SBaptiste Daroussin     long check;
902a3e3873SBaptiste Daroussin     char *next = 0;
912a3e3873SBaptiste Daroussin 
922a3e3873SBaptiste Daroussin     sprintf(buffer, "%*d", data->value_len, data->current);
932a3e3873SBaptiste Daroussin     buffer[data->value_col] = (char) chr;
942a3e3873SBaptiste Daroussin     check = strtol(buffer, &next, 10);
952a3e3873SBaptiste Daroussin     if (next == 0 || *next == '\0') {
962a3e3873SBaptiste Daroussin 	if ((check <= (long) data->max_value) &&
972a3e3873SBaptiste Daroussin 	    (check >= (long) data->min_value)) {
982a3e3873SBaptiste Daroussin 	    result = TRUE;
992a3e3873SBaptiste Daroussin 	    data->current = (int) check;
1002a3e3873SBaptiste Daroussin 	}
1012a3e3873SBaptiste Daroussin     }
1022a3e3873SBaptiste Daroussin 
1032a3e3873SBaptiste Daroussin     return result;
1042a3e3873SBaptiste Daroussin }
1052a3e3873SBaptiste Daroussin 
1062a3e3873SBaptiste Daroussin /*
1072a3e3873SBaptiste Daroussin  * This is similar to the gauge code, but differs in the way the number
1082a3e3873SBaptiste Daroussin  * is displayed, etc.
1092a3e3873SBaptiste Daroussin  */
1102a3e3873SBaptiste Daroussin static void
1112a3e3873SBaptiste Daroussin draw_value(VALUE * data, int value)
1122a3e3873SBaptiste Daroussin {
1132a3e3873SBaptiste Daroussin     if (value != data->current) {
1142a3e3873SBaptiste Daroussin 	WINDOW *win = data->window;
1152a3e3873SBaptiste Daroussin 	int y, x;
1162a3e3873SBaptiste Daroussin 	int n;
1172a3e3873SBaptiste Daroussin 	int ranges = (data->max_value + 1 - data->min_value);
1182a3e3873SBaptiste Daroussin 	int offset = (value - data->min_value);
1192a3e3873SBaptiste Daroussin 	int scaled;
1202a3e3873SBaptiste Daroussin 
1212a3e3873SBaptiste Daroussin 	getyx(win, y, x);
1222a3e3873SBaptiste Daroussin 
1232a3e3873SBaptiste Daroussin 	if (ranges > data->slide_len) {
1242a3e3873SBaptiste Daroussin 	    scaled = (offset + data->slide_inc) / data->slide_inc;
1252a3e3873SBaptiste Daroussin 	} else if (ranges < data->slide_len) {
1262a3e3873SBaptiste Daroussin 	    scaled = (offset + 1) * data->slide_inc;
1272a3e3873SBaptiste Daroussin 	} else {
1282a3e3873SBaptiste Daroussin 	    scaled = offset;
1292a3e3873SBaptiste Daroussin 	}
1302a3e3873SBaptiste Daroussin 
131*f4f33ea0SBaptiste Daroussin 	dlg_attrset(win, gauge_attr);
1322a3e3873SBaptiste Daroussin 	wmove(win, data->slide_y, data->slide_x);
1332a3e3873SBaptiste Daroussin 	for (n = 0; n < data->slide_len; ++n) {
1342a3e3873SBaptiste Daroussin 	    (void) waddch(win, ' ');
1352a3e3873SBaptiste Daroussin 	}
1362a3e3873SBaptiste Daroussin 	wmove(win, data->slide_y, data->value_x);
1372a3e3873SBaptiste Daroussin 	wprintw(win, "%*d", data->value_len, value);
1382a3e3873SBaptiste Daroussin 	if ((gauge_attr & A_REVERSE) != 0) {
139*f4f33ea0SBaptiste Daroussin 	    dlg_attroff(win, A_REVERSE);
1402a3e3873SBaptiste Daroussin 	} else {
141*f4f33ea0SBaptiste Daroussin 	    dlg_attrset(win, A_REVERSE);
1422a3e3873SBaptiste Daroussin 	}
1432a3e3873SBaptiste Daroussin 	wmove(win, data->slide_y, data->slide_x);
1442a3e3873SBaptiste Daroussin 	for (n = 0; n < scaled; ++n) {
1452a3e3873SBaptiste Daroussin 	    chtype ch2 = winch(win);
1462a3e3873SBaptiste Daroussin 	    if (gauge_attr & A_REVERSE) {
1472a3e3873SBaptiste Daroussin 		ch2 &= ~A_REVERSE;
1482a3e3873SBaptiste Daroussin 	    }
1492a3e3873SBaptiste Daroussin 	    (void) waddch(win, ch2);
1502a3e3873SBaptiste Daroussin 	}
151*f4f33ea0SBaptiste Daroussin 	dlg_attrset(win, dialog_attr);
1522a3e3873SBaptiste Daroussin 
1532a3e3873SBaptiste Daroussin 	wmove(win, y, x);
1542a3e3873SBaptiste Daroussin 	data->current = value;
1552a3e3873SBaptiste Daroussin 
156*f4f33ea0SBaptiste Daroussin 	DLG_TRACE(("# drew %d offset %d scaled %d limit %d inc %d\n",
1572a3e3873SBaptiste Daroussin 		   value,
1582a3e3873SBaptiste Daroussin 		   offset,
1592a3e3873SBaptiste Daroussin 		   scaled,
1602a3e3873SBaptiste Daroussin 		   data->slide_len,
161*f4f33ea0SBaptiste Daroussin 		   data->slide_inc));
1622a3e3873SBaptiste Daroussin 
1632a3e3873SBaptiste Daroussin 	dlg_trace_win(win);
1642a3e3873SBaptiste Daroussin     }
1652a3e3873SBaptiste Daroussin }
1662a3e3873SBaptiste Daroussin 
1672a3e3873SBaptiste Daroussin /*
1682a3e3873SBaptiste Daroussin  * Allow the user to select from a range of values, e.g., using a slider.
1692a3e3873SBaptiste Daroussin  */
1702a3e3873SBaptiste Daroussin int
1712a3e3873SBaptiste Daroussin dialog_rangebox(const char *title,
1722a3e3873SBaptiste Daroussin 		const char *cprompt,
1732a3e3873SBaptiste Daroussin 		int height,
1742a3e3873SBaptiste Daroussin 		int width,
1752a3e3873SBaptiste Daroussin 		int min_value,
1762a3e3873SBaptiste Daroussin 		int max_value,
1772a3e3873SBaptiste Daroussin 		int default_value)
1782a3e3873SBaptiste Daroussin {
1792a3e3873SBaptiste Daroussin     /* *INDENT-OFF* */
1802a3e3873SBaptiste Daroussin     static DLG_KEYS_BINDING binding[] = {
1812a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_DELETE_RIGHT,KEY_DC ),
1822a3e3873SBaptiste Daroussin 	HELPKEY_BINDINGS,
1832a3e3873SBaptiste Daroussin 	ENTERKEY_BINDINGS,
184*f4f33ea0SBaptiste Daroussin 	TOGGLEKEY_BINDINGS,
1852a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_FIELD_NEXT, CHR_NEXT ),
1862a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
1872a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
1882a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_FIELD_PREV, CHR_BACKSPACE ),
1892a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_FIELD_PREV, CHR_PREVIOUS ),
1902a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
1912a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
1922a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME),
1932a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_ITEM_LAST,  KEY_END),
1942a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_ITEM_LAST,  KEY_LL ),
1952a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_ITEM_NEXT,  '+'),
1962a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_ITEM_NEXT,  KEY_DOWN),
1972a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_ITEM_PREV,  '-' ),
1982a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_ITEM_PREV,  KEY_UP ),
1992a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_PAGE_NEXT,  KEY_NEXT),
2002a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_PAGE_NEXT,  KEY_NPAGE),
2012a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_PAGE_PREV,  KEY_PPAGE ),
2022a3e3873SBaptiste Daroussin 	DLG_KEYS_DATA( DLGK_PAGE_PREV,  KEY_PREVIOUS ),
2032a3e3873SBaptiste Daroussin 	END_KEYS_BINDING
2042a3e3873SBaptiste Daroussin     };
2052a3e3873SBaptiste Daroussin     /* *INDENT-ON* */
2062a3e3873SBaptiste Daroussin 
2072a3e3873SBaptiste Daroussin #ifdef KEY_RESIZE
2082a3e3873SBaptiste Daroussin     int old_height = height;
2092a3e3873SBaptiste Daroussin     int old_width = width;
2102a3e3873SBaptiste Daroussin #endif
2112a3e3873SBaptiste Daroussin     VALUE data;
2122a3e3873SBaptiste Daroussin     int key = 0, key2, fkey;
2132a3e3873SBaptiste Daroussin     int button;
2142a3e3873SBaptiste Daroussin     int result = DLG_EXIT_UNKNOWN;
2152a3e3873SBaptiste Daroussin     WINDOW *dialog;
2162a3e3873SBaptiste Daroussin     int state = dlg_default_button();
2172a3e3873SBaptiste Daroussin     const char **buttons = dlg_ok_labels();
218*f4f33ea0SBaptiste Daroussin     char *prompt;
2192a3e3873SBaptiste Daroussin     char buffer[MAX_LEN];
2202a3e3873SBaptiste Daroussin     int cur_value = default_value;
2212a3e3873SBaptiste Daroussin     int usable;
2222a3e3873SBaptiste Daroussin     int ranges;
2232a3e3873SBaptiste Daroussin     int yorg, xorg;
2242a3e3873SBaptiste Daroussin 
225*f4f33ea0SBaptiste Daroussin     DLG_TRACE(("# tailbox args:\n"));
226*f4f33ea0SBaptiste Daroussin     DLG_TRACE2S("title", title);
227*f4f33ea0SBaptiste Daroussin     DLG_TRACE2S("message", cprompt);
228*f4f33ea0SBaptiste Daroussin     DLG_TRACE2N("height", height);
229*f4f33ea0SBaptiste Daroussin     DLG_TRACE2N("width", width);
230*f4f33ea0SBaptiste Daroussin     DLG_TRACE2N("minval", min_value);
231*f4f33ea0SBaptiste Daroussin     DLG_TRACE2N("maxval", max_value);
232*f4f33ea0SBaptiste Daroussin     DLG_TRACE2N("default", default_value);
233*f4f33ea0SBaptiste Daroussin 
2342a3e3873SBaptiste Daroussin     if (max_value < min_value)
2352a3e3873SBaptiste Daroussin 	max_value = min_value;
2362a3e3873SBaptiste Daroussin     if (cur_value > max_value)
2372a3e3873SBaptiste Daroussin 	cur_value = max_value;
2382a3e3873SBaptiste Daroussin     if (cur_value < min_value)
2392a3e3873SBaptiste Daroussin 	cur_value = min_value;
2402a3e3873SBaptiste Daroussin 
2412a3e3873SBaptiste Daroussin     dlg_does_output();
2422a3e3873SBaptiste Daroussin 
2432a3e3873SBaptiste Daroussin #ifdef KEY_RESIZE
2442a3e3873SBaptiste Daroussin   retry:
2452a3e3873SBaptiste Daroussin #endif
2462a3e3873SBaptiste Daroussin 
247*f4f33ea0SBaptiste Daroussin     prompt = dlg_strclone(cprompt);
2482a3e3873SBaptiste Daroussin     dlg_auto_size(title, prompt, &height, &width, 0, 0);
249*f4f33ea0SBaptiste Daroussin 
2502a3e3873SBaptiste Daroussin     height += MIN_HIGH;
2512a3e3873SBaptiste Daroussin     if (width < MIN_WIDE)
2522a3e3873SBaptiste Daroussin 	width = MIN_WIDE;
2532a3e3873SBaptiste Daroussin     dlg_button_layout(buttons, &width);
2542a3e3873SBaptiste Daroussin     dlg_print_size(height, width);
2552a3e3873SBaptiste Daroussin     dlg_ctl_size(height, width);
2562a3e3873SBaptiste Daroussin 
2572a3e3873SBaptiste Daroussin     dialog = dlg_new_window(height, width,
2582a3e3873SBaptiste Daroussin 			    yorg = dlg_box_y_ordinate(height),
2592a3e3873SBaptiste Daroussin 			    xorg = dlg_box_x_ordinate(width));
2602a3e3873SBaptiste Daroussin 
2612a3e3873SBaptiste Daroussin     data.window = dialog;
2622a3e3873SBaptiste Daroussin 
2632a3e3873SBaptiste Daroussin     data.min_value = min_value;
2642a3e3873SBaptiste Daroussin     data.max_value = max_value;
2652a3e3873SBaptiste Daroussin 
2662a3e3873SBaptiste Daroussin     usable = (width - 2 - 4 * MARGIN);
2672a3e3873SBaptiste Daroussin     ranges = max_value - min_value + 1;
2682a3e3873SBaptiste Daroussin 
2692a3e3873SBaptiste Daroussin     /*
2702a3e3873SBaptiste Daroussin      * Center the number after allowing for its maximum number of digits.
2712a3e3873SBaptiste Daroussin      */
2722a3e3873SBaptiste Daroussin     data.value_len = digits_of(max_value);
2732a3e3873SBaptiste Daroussin     if (digits_of(min_value) > data.value_len)
2742a3e3873SBaptiste Daroussin 	data.value_len = digits_of(min_value);
2752a3e3873SBaptiste Daroussin     data.value_x = (usable - data.value_len) / 2 + MARGIN;
2762a3e3873SBaptiste Daroussin     data.value_col = data.value_len - 1;
2772a3e3873SBaptiste Daroussin 
2782a3e3873SBaptiste Daroussin     /*
2792a3e3873SBaptiste Daroussin      * The slider is scaled, to try to use the width of the dialog.
2802a3e3873SBaptiste Daroussin      */
2812a3e3873SBaptiste Daroussin     if (ranges > usable) {
2822a3e3873SBaptiste Daroussin 	data.slide_inc = (ranges + usable - 1) / usable;
2832a3e3873SBaptiste Daroussin 	data.slide_len = 1 + ranges / data.slide_inc;
2842a3e3873SBaptiste Daroussin     } else if (ranges < usable) {
2852a3e3873SBaptiste Daroussin 	data.slide_inc = usable / ranges;
2862a3e3873SBaptiste Daroussin 	data.slide_len = ranges * data.slide_inc;
2872a3e3873SBaptiste Daroussin     } else {
2882a3e3873SBaptiste Daroussin 	data.slide_inc = 1;
2892a3e3873SBaptiste Daroussin 	data.slide_len = usable;
2902a3e3873SBaptiste Daroussin     }
2912a3e3873SBaptiste Daroussin     data.slide_x = (usable - data.slide_len) / 2 + MARGIN + 2;
2922a3e3873SBaptiste Daroussin     data.slide_y = height - 5;
2932a3e3873SBaptiste Daroussin 
2942a3e3873SBaptiste Daroussin     data.current = cur_value - 1;
2952a3e3873SBaptiste Daroussin 
2962a3e3873SBaptiste Daroussin     dlg_register_window(dialog, "rangebox", binding);
2972a3e3873SBaptiste Daroussin     dlg_register_buttons(dialog, "rangebox", buttons);
2982a3e3873SBaptiste Daroussin 
2992a3e3873SBaptiste Daroussin     dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
3002a3e3873SBaptiste Daroussin     dlg_mouse_setbase(xorg, yorg);
3012a3e3873SBaptiste Daroussin     dlg_mouse_mkregion(data.slide_y - 1, data.slide_x - 1, 3, usable + 2, 'i');
3022a3e3873SBaptiste Daroussin     dlg_draw_box2(dialog,
3032a3e3873SBaptiste Daroussin 		  height - 6, data.slide_x - MARGIN,
3042a3e3873SBaptiste Daroussin 		  2 + MARGIN, data.slide_len + 2 * MARGIN,
3052a3e3873SBaptiste Daroussin 		  dialog_attr,
3062a3e3873SBaptiste Daroussin 		  border_attr,
3072a3e3873SBaptiste Daroussin 		  border2_attr);
3082a3e3873SBaptiste Daroussin     dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
3092a3e3873SBaptiste Daroussin     dlg_draw_title(dialog, title);
3102a3e3873SBaptiste Daroussin     dlg_draw_helpline(dialog, FALSE);
3112a3e3873SBaptiste Daroussin 
312*f4f33ea0SBaptiste Daroussin     dlg_attrset(dialog, dialog_attr);
3132a3e3873SBaptiste Daroussin     dlg_print_autowrap(dialog, prompt, height, width);
3142a3e3873SBaptiste Daroussin 
3152a3e3873SBaptiste Daroussin     dlg_trace_win(dialog);
3162a3e3873SBaptiste Daroussin     while (result == DLG_EXIT_UNKNOWN) {
3172a3e3873SBaptiste Daroussin 	draw_value(&data, cur_value);
3182a3e3873SBaptiste Daroussin 	button = (state < 0) ? 0 : state;
3192a3e3873SBaptiste Daroussin 	dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
3202a3e3873SBaptiste Daroussin 	if (state < 0) {
3212a3e3873SBaptiste Daroussin 	    data.value_col = data.value_len + state;
3222a3e3873SBaptiste Daroussin 	    wmove(dialog, data.slide_y, data.value_x + data.value_col);
3232a3e3873SBaptiste Daroussin 	}
3242a3e3873SBaptiste Daroussin 
3252a3e3873SBaptiste Daroussin 	key = dlg_mouse_wgetch(dialog, &fkey);
3262a3e3873SBaptiste Daroussin 	if (dlg_result_key(key, fkey, &result))
3272a3e3873SBaptiste Daroussin 	    break;
3282a3e3873SBaptiste Daroussin 
3292a3e3873SBaptiste Daroussin 	if ((key2 = dlg_char_to_button(key, buttons)) >= 0) {
3302a3e3873SBaptiste Daroussin 	    result = key2;
3312a3e3873SBaptiste Daroussin 	} else {
3322a3e3873SBaptiste Daroussin 	    /* handle function-keys */
3332a3e3873SBaptiste Daroussin 	    if (fkey) {
3342a3e3873SBaptiste Daroussin 		switch (key) {
335*f4f33ea0SBaptiste Daroussin 		case DLGK_TOGGLE:
3362a3e3873SBaptiste Daroussin 		case DLGK_ENTER:
3372a3e3873SBaptiste Daroussin 		    result = dlg_ok_buttoncode(button);
3382a3e3873SBaptiste Daroussin 		    break;
3392a3e3873SBaptiste Daroussin 		case DLGK_FIELD_PREV:
3402a3e3873SBaptiste Daroussin 		    if (state < 0 && state > -data.value_len) {
3412a3e3873SBaptiste Daroussin 			--state;
3422a3e3873SBaptiste Daroussin 		    } else {
3432a3e3873SBaptiste Daroussin 			state = dlg_prev_ok_buttonindex(state, -data.value_len);
3442a3e3873SBaptiste Daroussin 		    }
3452a3e3873SBaptiste Daroussin 		    break;
3462a3e3873SBaptiste Daroussin 		case DLGK_FIELD_NEXT:
3472a3e3873SBaptiste Daroussin 		    if (state < 0) {
3482a3e3873SBaptiste Daroussin 			++state;
3492a3e3873SBaptiste Daroussin 		    } else {
3502a3e3873SBaptiste Daroussin 			state = dlg_next_ok_buttonindex(state, -data.value_len);
3512a3e3873SBaptiste Daroussin 		    }
3522a3e3873SBaptiste Daroussin 		    break;
3532a3e3873SBaptiste Daroussin 		case DLGK_ITEM_FIRST:
3542a3e3873SBaptiste Daroussin 		    cur_value = min_value;
3552a3e3873SBaptiste Daroussin 		    break;
3562a3e3873SBaptiste Daroussin 		case DLGK_ITEM_LAST:
3572a3e3873SBaptiste Daroussin 		    cur_value = max_value;
3582a3e3873SBaptiste Daroussin 		    break;
3592a3e3873SBaptiste Daroussin 		case DLGK_ITEM_PREV:
3602a3e3873SBaptiste Daroussin 		    if (state < 0) {
3612a3e3873SBaptiste Daroussin 			cur_value -= digit_of(&data);
3622a3e3873SBaptiste Daroussin 		    } else {
3632a3e3873SBaptiste Daroussin 			cur_value -= 1;
3642a3e3873SBaptiste Daroussin 		    }
3652a3e3873SBaptiste Daroussin 		    if (cur_value < min_value)
3662a3e3873SBaptiste Daroussin 			cur_value = min_value;
3672a3e3873SBaptiste Daroussin 		    break;
3682a3e3873SBaptiste Daroussin 		case DLGK_ITEM_NEXT:
3692a3e3873SBaptiste Daroussin 		    if (state < 0) {
3702a3e3873SBaptiste Daroussin 			cur_value += digit_of(&data);
3712a3e3873SBaptiste Daroussin 		    } else {
3722a3e3873SBaptiste Daroussin 			cur_value += 1;
3732a3e3873SBaptiste Daroussin 		    }
3742a3e3873SBaptiste Daroussin 		    if (cur_value > max_value)
3752a3e3873SBaptiste Daroussin 			cur_value = max_value;
3762a3e3873SBaptiste Daroussin 		    break;
3772a3e3873SBaptiste Daroussin 		case DLGK_PAGE_PREV:
3782a3e3873SBaptiste Daroussin 		    cur_value -= data.slide_inc;
3792a3e3873SBaptiste Daroussin 		    if (cur_value < min_value)
3802a3e3873SBaptiste Daroussin 			cur_value = min_value;
3812a3e3873SBaptiste Daroussin 		    break;
3822a3e3873SBaptiste Daroussin 		case DLGK_PAGE_NEXT:
3832a3e3873SBaptiste Daroussin 		    cur_value += data.slide_inc;
3842a3e3873SBaptiste Daroussin 		    if (cur_value > max_value)
3852a3e3873SBaptiste Daroussin 			cur_value = max_value;
3862a3e3873SBaptiste Daroussin 		    break;
3872a3e3873SBaptiste Daroussin #ifdef KEY_RESIZE
3882a3e3873SBaptiste Daroussin 		case KEY_RESIZE:
389*f4f33ea0SBaptiste Daroussin 		    dlg_will_resize(dialog);
3902a3e3873SBaptiste Daroussin 		    /* reset data */
3912a3e3873SBaptiste Daroussin 		    height = old_height;
3922a3e3873SBaptiste Daroussin 		    width = old_width;
3932a3e3873SBaptiste Daroussin 		    /* repaint */
394*f4f33ea0SBaptiste Daroussin 		    free(prompt);
3952a3e3873SBaptiste Daroussin 		    dlg_clear();
3962a3e3873SBaptiste Daroussin 		    dlg_del_window(dialog);
3972a3e3873SBaptiste Daroussin 		    dlg_mouse_free_regions();
3982a3e3873SBaptiste Daroussin 		    goto retry;
3992a3e3873SBaptiste Daroussin #endif
4002a3e3873SBaptiste Daroussin 		case DLGK_MOUSE('i'):
4012a3e3873SBaptiste Daroussin 		    state = -data.value_len;
4022a3e3873SBaptiste Daroussin 		    break;
4032a3e3873SBaptiste Daroussin 		default:
4042a3e3873SBaptiste Daroussin 		    if (is_DLGK_MOUSE(key)) {
4052a3e3873SBaptiste Daroussin 			result = dlg_ok_buttoncode(key - M_EVENT);
4062a3e3873SBaptiste Daroussin 			if (result < 0)
4072a3e3873SBaptiste Daroussin 			    result = DLG_EXIT_OK;
4082a3e3873SBaptiste Daroussin 		    }
4092a3e3873SBaptiste Daroussin 		    break;
4102a3e3873SBaptiste Daroussin 		}
4112a3e3873SBaptiste Daroussin 	    } else if (isdigit(key) && state < 0) {
4122a3e3873SBaptiste Daroussin 		if (set_digit(&data, key)) {
4132a3e3873SBaptiste Daroussin 		    cur_value = data.current;
4142a3e3873SBaptiste Daroussin 		    data.current--;
4152a3e3873SBaptiste Daroussin 		}
4162a3e3873SBaptiste Daroussin 	    } else {
4172a3e3873SBaptiste Daroussin 		beep();
4182a3e3873SBaptiste Daroussin 	    }
4192a3e3873SBaptiste Daroussin 	}
4202a3e3873SBaptiste Daroussin     }
4212a3e3873SBaptiste Daroussin 
4222a3e3873SBaptiste Daroussin     sprintf(buffer, "%d", cur_value);
4232a3e3873SBaptiste Daroussin     dlg_add_result(buffer);
4242a3e3873SBaptiste Daroussin     dlg_add_separator();
4252a3e3873SBaptiste Daroussin     dlg_add_last_key(-1);
4262a3e3873SBaptiste Daroussin 
4272a3e3873SBaptiste Daroussin     dlg_del_window(dialog);
4282a3e3873SBaptiste Daroussin     dlg_mouse_free_regions();
4292a3e3873SBaptiste Daroussin     free(prompt);
4302a3e3873SBaptiste Daroussin 
4312a3e3873SBaptiste Daroussin     return result;
4322a3e3873SBaptiste Daroussin }
433