xref: /dragonfly/contrib/dialog/pause.c (revision a8e38dc0)
15382d832SPeter Avalos /*
2*a8e38dc0SAntonio Huete Jimenez  *  $Id: pause.c,v 1.49 2022/04/03 22:38:16 tom Exp $
35382d832SPeter Avalos  *
45382d832SPeter Avalos  *  pause.c -- implements the pause dialog
55382d832SPeter Avalos  *
6*a8e38dc0SAntonio Huete Jimenez  *  Copyright 2004-2020,2022	Thomas E. Dickey
75382d832SPeter Avalos  *
85382d832SPeter Avalos  *  This program is free software; you can redistribute it and/or modify
95382d832SPeter Avalos  *  it under the terms of the GNU Lesser General Public License, version 2.1
105382d832SPeter Avalos  *  as published by the Free Software Foundation.
115382d832SPeter Avalos  *
125382d832SPeter Avalos  *  This program is distributed in the hope that it will be useful, but
135382d832SPeter Avalos  *  WITHOUT ANY WARRANTY; without even the implied warranty of
145382d832SPeter Avalos  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
155382d832SPeter Avalos  *  Lesser General Public License for more details.
165382d832SPeter Avalos  *
175382d832SPeter Avalos  *  You should have received a copy of the GNU Lesser General Public
185382d832SPeter Avalos  *  License along with this program; if not, write to
195382d832SPeter Avalos  *	Free Software Foundation, Inc.
205382d832SPeter Avalos  *	51 Franklin St., Fifth Floor
215382d832SPeter Avalos  *	Boston, MA 02110, USA.
225382d832SPeter Avalos  *
235382d832SPeter Avalos  *  This is adapted from source contributed by
245382d832SPeter Avalos  *	Yura Kalinichenko
255382d832SPeter Avalos  */
265382d832SPeter Avalos 
27*a8e38dc0SAntonio Huete Jimenez #include <dlg_internals.h>
285382d832SPeter Avalos #include <dlg_keys.h>
295382d832SPeter Avalos 
305382d832SPeter Avalos #define MY_TIMEOUT 50
315382d832SPeter Avalos 
325382d832SPeter Avalos #define MIN_HIGH (4)
335382d832SPeter Avalos #define MIN_WIDE (10 + 2 * (2 + MARGIN))
345382d832SPeter Avalos #define BTN_HIGH (1 + 2 * MARGIN)
355382d832SPeter Avalos 
365382d832SPeter Avalos /*
375382d832SPeter Avalos  * This is like gauge, but can be interrupted.
385382d832SPeter Avalos  *
395382d832SPeter Avalos  * A pause box displays a meter along the bottom of the box.  The meter
405382d832SPeter Avalos  * indicates how many seconds remain until the end of the pause.  The pause
415382d832SPeter Avalos  * exits when timeout is reached (status OK) or the user presses:
425382d832SPeter Avalos  *   OK button (status OK)
435382d832SPeter Avalos  *   CANCEL button (status CANCEL)
445382d832SPeter Avalos  *   Esc key (status ESC)
455382d832SPeter Avalos  *
465382d832SPeter Avalos  */
475382d832SPeter Avalos int
dialog_pause(const char * title,const char * cprompt,int height,int width,int seconds)485382d832SPeter Avalos dialog_pause(const char *title,
495382d832SPeter Avalos 	     const char *cprompt,
505382d832SPeter Avalos 	     int height,
515382d832SPeter Avalos 	     int width,
525382d832SPeter Avalos 	     int seconds)
535382d832SPeter Avalos {
545382d832SPeter Avalos     /* *INDENT-OFF* */
555382d832SPeter Avalos     static DLG_KEYS_BINDING binding[] = {
565382d832SPeter Avalos 	HELPKEY_BINDINGS,
575382d832SPeter Avalos 	ENTERKEY_BINDINGS,
585382d832SPeter Avalos 	TRAVERSE_BINDINGS,
595382d832SPeter Avalos 	END_KEYS_BINDING
605382d832SPeter Avalos     };
615382d832SPeter Avalos     /* *INDENT-ON* */
625382d832SPeter Avalos 
635382d832SPeter Avalos #ifdef KEY_RESIZE
645382d832SPeter Avalos     int old_height = height;
655382d832SPeter Avalos     int old_width = width;
665382d832SPeter Avalos #endif
675382d832SPeter Avalos 
685382d832SPeter Avalos     int i, x, y, step;
695382d832SPeter Avalos     int button = dlg_default_button();
705382d832SPeter Avalos     int seconds_orig;
715382d832SPeter Avalos     WINDOW *dialog;
725382d832SPeter Avalos     const char **buttons = dlg_ok_labels();
735382d832SPeter Avalos     bool have_buttons = (dlg_button_count(buttons) != 0);
745382d832SPeter Avalos     bool first;
755940c9abSDaniel Fojt     int key, fkey;
765382d832SPeter Avalos     int result = DLG_EXIT_UNKNOWN;
775382d832SPeter Avalos     int button_high = (have_buttons ? BTN_HIGH : MARGIN);
785382d832SPeter Avalos     int gauge_y;
795940c9abSDaniel Fojt     char *prompt;
805382d832SPeter Avalos     int save_timeout = dialog_vars.timeout_secs;
815382d832SPeter Avalos 
825940c9abSDaniel Fojt     DLG_TRACE(("# pause args:\n"));
835940c9abSDaniel Fojt     DLG_TRACE2S("title", title);
845940c9abSDaniel Fojt     DLG_TRACE2S("message", cprompt);
855940c9abSDaniel Fojt     DLG_TRACE2N("height", height);
865940c9abSDaniel Fojt     DLG_TRACE2N("width", width);
875940c9abSDaniel Fojt     DLG_TRACE2N("seconds", seconds);
885382d832SPeter Avalos 
895940c9abSDaniel Fojt     curs_set(0);
905382d832SPeter Avalos 
915382d832SPeter Avalos     seconds_orig = (seconds > 0) ? seconds : 1;
92*a8e38dc0SAntonio Huete Jimenez     dialog_vars.pause_secs = seconds_orig;
93*a8e38dc0SAntonio Huete Jimenez     dialog_vars.timeout_secs = 0;
945382d832SPeter Avalos 
955382d832SPeter Avalos #ifdef KEY_RESIZE
965382d832SPeter Avalos   retry:
975382d832SPeter Avalos #endif
985382d832SPeter Avalos 
995940c9abSDaniel Fojt     prompt = dlg_strclone(cprompt);
1005940c9abSDaniel Fojt     dlg_tab_correct_str(prompt);
1015940c9abSDaniel Fojt 
1025382d832SPeter Avalos     if (have_buttons) {
1035382d832SPeter Avalos 	dlg_auto_size(title, prompt, &height, &width,
1045382d832SPeter Avalos 		      MIN_HIGH,
1055382d832SPeter Avalos 		      MIN_WIDE);
1065382d832SPeter Avalos 	dlg_button_layout(buttons, &width);
1075382d832SPeter Avalos     } else {
1085382d832SPeter Avalos 	dlg_auto_size(title, prompt, &height, &width,
1095382d832SPeter Avalos 		      MIN_HIGH + MARGIN - BTN_HIGH,
1105382d832SPeter Avalos 		      MIN_WIDE);
1115382d832SPeter Avalos     }
1125382d832SPeter Avalos     gauge_y = height - button_high - (1 + 2 * MARGIN);
1135382d832SPeter Avalos     dlg_print_size(height, width);
1145382d832SPeter Avalos     dlg_ctl_size(height, width);
1155382d832SPeter Avalos 
1165382d832SPeter Avalos     /* center dialog box on screen */
1175382d832SPeter Avalos     x = dlg_box_x_ordinate(width);
1185382d832SPeter Avalos     y = dlg_box_y_ordinate(height);
1195382d832SPeter Avalos 
1205382d832SPeter Avalos     dialog = dlg_new_window(height, width, y, x);
1215382d832SPeter Avalos     dlg_register_window(dialog, "pause", binding);
1225382d832SPeter Avalos     dlg_register_buttons(dialog, "pause", buttons);
1235382d832SPeter Avalos 
1245382d832SPeter Avalos     dlg_mouse_setbase(x, y);
1255382d832SPeter Avalos     nodelay(dialog, TRUE);
1265382d832SPeter Avalos 
1275382d832SPeter Avalos     first = TRUE;
1285382d832SPeter Avalos     do {
1295382d832SPeter Avalos 	(void) werase(dialog);
1305382d832SPeter Avalos 	dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
1315382d832SPeter Avalos 
1325382d832SPeter Avalos 	dlg_draw_title(dialog, title);
1335382d832SPeter Avalos 	dlg_draw_helpline(dialog, FALSE);
1345382d832SPeter Avalos 
1355940c9abSDaniel Fojt 	dlg_attrset(dialog, dialog_attr);
1365382d832SPeter Avalos 	dlg_print_autowrap(dialog, prompt, height, width);
1375382d832SPeter Avalos 
1385382d832SPeter Avalos 	dlg_draw_box2(dialog,
1395382d832SPeter Avalos 		      gauge_y, 2 + MARGIN,
1405382d832SPeter Avalos 		      2 + MARGIN, width - 2 * (2 + MARGIN),
1415382d832SPeter Avalos 		      dialog_attr,
1425382d832SPeter Avalos 		      border_attr,
1435382d832SPeter Avalos 		      border2_attr);
1445382d832SPeter Avalos 
1455382d832SPeter Avalos 	/*
1465382d832SPeter Avalos 	 * Clear the area for the progress bar by filling it with spaces
1475382d832SPeter Avalos 	 * in the title-attribute, and write the percentage with that
1485382d832SPeter Avalos 	 * attribute.
1495382d832SPeter Avalos 	 */
1505382d832SPeter Avalos 	(void) wmove(dialog, gauge_y + MARGIN, 4);
1515940c9abSDaniel Fojt 	dlg_attrset(dialog, title_attr);
1525382d832SPeter Avalos 
1535382d832SPeter Avalos 	for (i = 0; i < (width - 2 * (3 + MARGIN)); i++)
1545382d832SPeter Avalos 	    (void) waddch(dialog, ' ');
1555382d832SPeter Avalos 
1565382d832SPeter Avalos 	(void) wmove(dialog, gauge_y + MARGIN, (width / 2) - 2);
1575382d832SPeter Avalos 	(void) wprintw(dialog, "%3d", seconds);
1585382d832SPeter Avalos 
1595382d832SPeter Avalos 	/*
1605382d832SPeter Avalos 	 * Now draw a bar in reverse, relative to the background.
1615382d832SPeter Avalos 	 * The window attribute was useful for painting the background,
1625382d832SPeter Avalos 	 * but requires some tweaks to reverse it.
1635382d832SPeter Avalos 	 */
1645382d832SPeter Avalos 	x = (seconds * (width - 2 * (3 + MARGIN))) / seconds_orig;
1655382d832SPeter Avalos 	if ((title_attr & A_REVERSE) != 0) {
1665940c9abSDaniel Fojt 	    dlg_attroff(dialog, A_REVERSE);
1675382d832SPeter Avalos 	} else {
1685940c9abSDaniel Fojt 	    dlg_attrset(dialog, A_REVERSE);
1695382d832SPeter Avalos 	}
1705382d832SPeter Avalos 	(void) wmove(dialog, gauge_y + MARGIN, 4);
1715382d832SPeter Avalos 	for (i = 0; i < x; i++) {
1725382d832SPeter Avalos 	    chtype ch = winch(dialog);
1735382d832SPeter Avalos 	    if (title_attr & A_REVERSE) {
1745382d832SPeter Avalos 		ch &= ~A_REVERSE;
1755382d832SPeter Avalos 	    }
1765382d832SPeter Avalos 	    (void) waddch(dialog, ch);
1775382d832SPeter Avalos 	}
1785382d832SPeter Avalos 
1795382d832SPeter Avalos 	mouse_mkbutton(height - 2, width / 2 - 4, 6, '\n');
1805382d832SPeter Avalos 	if (have_buttons) {
1815382d832SPeter Avalos 	    dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
1825382d832SPeter Avalos 	    dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
1835382d832SPeter Avalos 	}
1845382d832SPeter Avalos 	if (first) {
1855382d832SPeter Avalos 	    (void) wrefresh(dialog);
1865382d832SPeter Avalos 	    dlg_trace_win(dialog);
1875382d832SPeter Avalos 	    first = FALSE;
1885382d832SPeter Avalos 	}
1895382d832SPeter Avalos 
1905382d832SPeter Avalos 	for (step = 0;
1915382d832SPeter Avalos 	     (result == DLG_EXIT_UNKNOWN) && (step < 1000);
1925382d832SPeter Avalos 	     step += MY_TIMEOUT) {
1935382d832SPeter Avalos 
1945382d832SPeter Avalos 	    napms(MY_TIMEOUT);
1955382d832SPeter Avalos 	    key = dlg_mouse_wgetch_nowait(dialog, &fkey);
1965382d832SPeter Avalos 	    if (key == ERR) {
1975382d832SPeter Avalos 		;		/* ignore errors in nodelay mode */
1985940c9abSDaniel Fojt 	    } else if (dlg_result_key(key, fkey, &result)) {
1995940c9abSDaniel Fojt 		if (!dlg_button_key(result, &button, &key, &fkey))
2005382d832SPeter Avalos 		    break;
2015382d832SPeter Avalos 	    }
2025382d832SPeter Avalos 
2035382d832SPeter Avalos 	    switch (key) {
2045382d832SPeter Avalos #ifdef KEY_RESIZE
2055382d832SPeter Avalos 	    case KEY_RESIZE:
2065940c9abSDaniel Fojt 		dlg_will_resize(dialog);
2075940c9abSDaniel Fojt 		height = old_height;
2085940c9abSDaniel Fojt 		width = old_width;
2095940c9abSDaniel Fojt 		free(prompt);
2105940c9abSDaniel Fojt 		_dlg_resize_cleanup(dialog);
2115382d832SPeter Avalos 		goto retry;
2125382d832SPeter Avalos #endif
2135382d832SPeter Avalos 	    case DLGK_FIELD_NEXT:
2145382d832SPeter Avalos 		button = dlg_next_button(buttons, button);
2155382d832SPeter Avalos 		if (button < 0)
2165382d832SPeter Avalos 		    button = 0;
2175382d832SPeter Avalos 		dlg_draw_buttons(dialog,
2185382d832SPeter Avalos 				 height - 2, 0,
2195382d832SPeter Avalos 				 buttons, button,
2205382d832SPeter Avalos 				 FALSE, width);
2215382d832SPeter Avalos 		break;
2225382d832SPeter Avalos 	    case DLGK_FIELD_PREV:
2235382d832SPeter Avalos 		button = dlg_prev_button(buttons, button);
2245382d832SPeter Avalos 		if (button < 0)
2255382d832SPeter Avalos 		    button = 0;
2265382d832SPeter Avalos 		dlg_draw_buttons(dialog,
2275382d832SPeter Avalos 				 height - 2, 0,
2285382d832SPeter Avalos 				 buttons, button,
2295382d832SPeter Avalos 				 FALSE, width);
2305382d832SPeter Avalos 		break;
2315382d832SPeter Avalos 	    case DLGK_ENTER:
2325382d832SPeter Avalos 		result = dlg_enter_buttoncode(button);
2335382d832SPeter Avalos 		break;
234*a8e38dc0SAntonio Huete Jimenez 	    case DLGK_LEAVE:
235*a8e38dc0SAntonio Huete Jimenez 		result = dlg_ok_buttoncode(button);
236*a8e38dc0SAntonio Huete Jimenez 		break;
2375382d832SPeter Avalos 	    case ERR:
2385382d832SPeter Avalos 		break;
2395382d832SPeter Avalos 	    default:
2405382d832SPeter Avalos 		if (is_DLGK_MOUSE(key)) {
2415382d832SPeter Avalos 		    result = dlg_ok_buttoncode(key - M_EVENT);
2425382d832SPeter Avalos 		    if (result < 0)
2435382d832SPeter Avalos 			result = DLG_EXIT_OK;
2445382d832SPeter Avalos 		}
2455382d832SPeter Avalos 		break;
2465382d832SPeter Avalos 	    }
2475382d832SPeter Avalos 	}
2485382d832SPeter Avalos     } while ((result == DLG_EXIT_UNKNOWN) && (seconds-- > 0));
2495940c9abSDaniel Fojt     dlg_add_last_key(-1);
2505382d832SPeter Avalos 
2515382d832SPeter Avalos     curs_set(1);
2525382d832SPeter Avalos     dlg_mouse_free_regions();
2535382d832SPeter Avalos     dlg_del_window(dialog);
2545382d832SPeter Avalos     free(prompt);
2555382d832SPeter Avalos 
2565382d832SPeter Avalos     dialog_vars.timeout_secs = save_timeout;
2575382d832SPeter Avalos 
2585382d832SPeter Avalos     return ((result == DLG_EXIT_UNKNOWN) ? DLG_EXIT_OK : result);
2595382d832SPeter Avalos }
260