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