1217309Snwhitehorn/* 2251843Sbapt * $Id: pause.c,v 1.36 2012/07/03 00:01:59 tom Exp $ 3217309Snwhitehorn * 4217309Snwhitehorn * pause.c -- implements the pause dialog 5217309Snwhitehorn * 6251843Sbapt * Copyright 2004-2011,2012 Thomas E. Dickey 7217309Snwhitehorn * 8217309Snwhitehorn * This program is free software; you can redistribute it and/or modify 9217309Snwhitehorn * it under the terms of the GNU Lesser General Public License, version 2.1 10217309Snwhitehorn * as published by the Free Software Foundation. 11217309Snwhitehorn * 12217309Snwhitehorn * This program is distributed in the hope that it will be useful, but 13217309Snwhitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 14217309Snwhitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15217309Snwhitehorn * Lesser General Public License for more details. 16217309Snwhitehorn * 17217309Snwhitehorn * You should have received a copy of the GNU Lesser General Public 18217309Snwhitehorn * License along with this program; if not, write to 19217309Snwhitehorn * Free Software Foundation, Inc. 20217309Snwhitehorn * 51 Franklin St., Fifth Floor 21217309Snwhitehorn * Boston, MA 02110, USA. 22217309Snwhitehorn * 23217309Snwhitehorn * This is adapted from source contributed by 24217309Snwhitehorn * Yura Kalinichenko 25217309Snwhitehorn */ 26217309Snwhitehorn 27217309Snwhitehorn#include <dialog.h> 28217309Snwhitehorn#include <dlg_keys.h> 29217309Snwhitehorn 30217309Snwhitehorn#define MY_TIMEOUT 50 31217309Snwhitehorn 32217309Snwhitehorn#define MIN_HIGH (4) 33217309Snwhitehorn#define MIN_WIDE (10 + 2 * (2 + MARGIN)) 34217309Snwhitehorn#define BTN_HIGH (1 + 2 * MARGIN) 35217309Snwhitehorn 36217309Snwhitehorn/* 37217309Snwhitehorn * This is like gauge, but can be interrupted. 38217309Snwhitehorn * 39217309Snwhitehorn * A pause box displays a meter along the bottom of the box. The meter 40217309Snwhitehorn * indicates how many seconds remain until the end of the pause. The pause 41217309Snwhitehorn * exits when timeout is reached (status OK) or the user presses: 42217309Snwhitehorn * OK button (status OK) 43217309Snwhitehorn * CANCEL button (status CANCEL) 44217309Snwhitehorn * Esc key (status ESC) 45217309Snwhitehorn * 46217309Snwhitehorn */ 47217309Snwhitehornint 48217309Snwhitehorndialog_pause(const char *title, 49217309Snwhitehorn const char *cprompt, 50217309Snwhitehorn int height, 51217309Snwhitehorn int width, 52217309Snwhitehorn int seconds) 53217309Snwhitehorn{ 54217309Snwhitehorn /* *INDENT-OFF* */ 55217309Snwhitehorn static DLG_KEYS_BINDING binding[] = { 56224014Snwhitehorn HELPKEY_BINDINGS, 57217309Snwhitehorn ENTERKEY_BINDINGS, 58251843Sbapt TRAVERSE_BINDINGS, 59217309Snwhitehorn END_KEYS_BINDING 60217309Snwhitehorn }; 61217309Snwhitehorn /* *INDENT-ON* */ 62217309Snwhitehorn 63217309Snwhitehorn#ifdef KEY_RESIZE 64217309Snwhitehorn int old_height = height; 65217309Snwhitehorn int old_width = width; 66217309Snwhitehorn#endif 67217309Snwhitehorn 68217309Snwhitehorn int i, x, y, step; 69251843Sbapt int button = dlg_default_button(); 70217309Snwhitehorn int seconds_orig; 71217309Snwhitehorn WINDOW *dialog; 72217309Snwhitehorn const char **buttons = dlg_ok_labels(); 73217309Snwhitehorn bool have_buttons = (dlg_button_count(buttons) != 0); 74251843Sbapt bool first; 75217309Snwhitehorn int key = 0, fkey; 76217309Snwhitehorn int result = DLG_EXIT_UNKNOWN; 77217309Snwhitehorn int button_high = (have_buttons ? BTN_HIGH : MARGIN); 78220749Snwhitehorn int gauge_y; 79217309Snwhitehorn char *prompt = dlg_strclone(cprompt); 80251843Sbapt int save_timeout = dialog_vars.timeout_secs; 81217309Snwhitehorn 82217309Snwhitehorn curs_set(0); 83217309Snwhitehorn 84217309Snwhitehorn dlg_tab_correct_str(prompt); 85217309Snwhitehorn 86251843Sbapt dialog_vars.timeout_secs = 0; 87217309Snwhitehorn seconds_orig = (seconds > 0) ? seconds : 1; 88217309Snwhitehorn 89217309Snwhitehorn#ifdef KEY_RESIZE 90217309Snwhitehorn retry: 91217309Snwhitehorn height = old_height; 92217309Snwhitehorn width = old_width; 93217309Snwhitehorn#endif 94217309Snwhitehorn 95217309Snwhitehorn if (have_buttons) { 96217309Snwhitehorn dlg_auto_size(title, prompt, &height, &width, 97217309Snwhitehorn MIN_HIGH, 98217309Snwhitehorn MIN_WIDE); 99217309Snwhitehorn dlg_button_layout(buttons, &width); 100217309Snwhitehorn } else { 101217309Snwhitehorn dlg_auto_size(title, prompt, &height, &width, 102217309Snwhitehorn MIN_HIGH + MARGIN - BTN_HIGH, 103217309Snwhitehorn MIN_WIDE); 104217309Snwhitehorn } 105220749Snwhitehorn gauge_y = height - button_high - (1 + 2 * MARGIN); 106217309Snwhitehorn dlg_print_size(height, width); 107217309Snwhitehorn dlg_ctl_size(height, width); 108217309Snwhitehorn 109217309Snwhitehorn /* center dialog box on screen */ 110217309Snwhitehorn x = dlg_box_x_ordinate(width); 111217309Snwhitehorn y = dlg_box_y_ordinate(height); 112217309Snwhitehorn 113217309Snwhitehorn dialog = dlg_new_window(height, width, y, x); 114217309Snwhitehorn dlg_register_window(dialog, "pause", binding); 115217309Snwhitehorn dlg_register_buttons(dialog, "pause", buttons); 116217309Snwhitehorn 117217309Snwhitehorn dlg_mouse_setbase(x, y); 118217309Snwhitehorn nodelay(dialog, TRUE); 119217309Snwhitehorn 120251843Sbapt first = TRUE; 121217309Snwhitehorn do { 122217309Snwhitehorn (void) werase(dialog); 123251843Sbapt dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); 124217309Snwhitehorn 125217309Snwhitehorn dlg_draw_title(dialog, title); 126224014Snwhitehorn dlg_draw_helpline(dialog, FALSE); 127217309Snwhitehorn 128251843Sbapt (void) wattrset(dialog, dialog_attr); 129217309Snwhitehorn dlg_print_autowrap(dialog, prompt, height, width); 130217309Snwhitehorn 131251843Sbapt dlg_draw_box2(dialog, 132251843Sbapt gauge_y, 2 + MARGIN, 133251843Sbapt 2 + MARGIN, width - 2 * (2 + MARGIN), 134251843Sbapt dialog_attr, 135251843Sbapt border_attr, 136251843Sbapt border2_attr); 137217309Snwhitehorn 138217309Snwhitehorn /* 139217309Snwhitehorn * Clear the area for the progress bar by filling it with spaces 140217309Snwhitehorn * in the title-attribute, and write the percentage with that 141217309Snwhitehorn * attribute. 142217309Snwhitehorn */ 143220749Snwhitehorn (void) wmove(dialog, gauge_y + MARGIN, 4); 144251843Sbapt (void) wattrset(dialog, title_attr); 145217309Snwhitehorn 146217309Snwhitehorn for (i = 0; i < (width - 2 * (3 + MARGIN)); i++) 147217309Snwhitehorn (void) waddch(dialog, ' '); 148217309Snwhitehorn 149220749Snwhitehorn (void) wmove(dialog, gauge_y + MARGIN, (width / 2) - 2); 150217309Snwhitehorn (void) wprintw(dialog, "%3d", seconds); 151217309Snwhitehorn 152217309Snwhitehorn /* 153217309Snwhitehorn * Now draw a bar in reverse, relative to the background. 154217309Snwhitehorn * The window attribute was useful for painting the background, 155217309Snwhitehorn * but requires some tweaks to reverse it. 156217309Snwhitehorn */ 157217309Snwhitehorn x = (seconds * (width - 2 * (3 + MARGIN))) / seconds_orig; 158217309Snwhitehorn if ((title_attr & A_REVERSE) != 0) { 159217309Snwhitehorn wattroff(dialog, A_REVERSE); 160217309Snwhitehorn } else { 161251843Sbapt (void) wattrset(dialog, A_REVERSE); 162217309Snwhitehorn } 163220749Snwhitehorn (void) wmove(dialog, gauge_y + MARGIN, 4); 164217309Snwhitehorn for (i = 0; i < x; i++) { 165217309Snwhitehorn chtype ch = winch(dialog); 166217309Snwhitehorn if (title_attr & A_REVERSE) { 167217309Snwhitehorn ch &= ~A_REVERSE; 168217309Snwhitehorn } 169217309Snwhitehorn (void) waddch(dialog, ch); 170217309Snwhitehorn } 171217309Snwhitehorn 172217309Snwhitehorn mouse_mkbutton(height - 2, width / 2 - 4, 6, '\n'); 173217309Snwhitehorn if (have_buttons) { 174251843Sbapt dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); 175217309Snwhitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); 176217309Snwhitehorn } 177251843Sbapt if (first) { 178251843Sbapt (void) wrefresh(dialog); 179251843Sbapt dlg_trace_win(dialog); 180251843Sbapt first = FALSE; 181251843Sbapt } 182217309Snwhitehorn 183217309Snwhitehorn for (step = 0; 184217309Snwhitehorn (result == DLG_EXIT_UNKNOWN) && (step < 1000); 185217309Snwhitehorn step += MY_TIMEOUT) { 186217309Snwhitehorn 187217309Snwhitehorn napms(MY_TIMEOUT); 188217309Snwhitehorn key = dlg_mouse_wgetch_nowait(dialog, &fkey); 189217309Snwhitehorn if (key == ERR) { 190217309Snwhitehorn ; /* ignore errors in nodelay mode */ 191217309Snwhitehorn } else { 192217309Snwhitehorn if (dlg_result_key(key, fkey, &result)) 193217309Snwhitehorn break; 194217309Snwhitehorn } 195217309Snwhitehorn 196217309Snwhitehorn switch (key) { 197217309Snwhitehorn#ifdef KEY_RESIZE 198217309Snwhitehorn case KEY_RESIZE: 199217309Snwhitehorn dlg_clear(); /* fill the background */ 200217309Snwhitehorn dlg_del_window(dialog); /* delete this window */ 201217309Snwhitehorn refresh(); /* get it all onto the terminal */ 202217309Snwhitehorn goto retry; 203217309Snwhitehorn#endif 204217309Snwhitehorn case DLGK_FIELD_NEXT: 205217309Snwhitehorn button = dlg_next_button(buttons, button); 206217309Snwhitehorn if (button < 0) 207217309Snwhitehorn button = 0; 208217309Snwhitehorn dlg_draw_buttons(dialog, 209217309Snwhitehorn height - 2, 0, 210217309Snwhitehorn buttons, button, 211217309Snwhitehorn FALSE, width); 212217309Snwhitehorn break; 213217309Snwhitehorn case DLGK_FIELD_PREV: 214217309Snwhitehorn button = dlg_prev_button(buttons, button); 215217309Snwhitehorn if (button < 0) 216217309Snwhitehorn button = 0; 217217309Snwhitehorn dlg_draw_buttons(dialog, 218217309Snwhitehorn height - 2, 0, 219217309Snwhitehorn buttons, button, 220217309Snwhitehorn FALSE, width); 221217309Snwhitehorn break; 222217309Snwhitehorn case DLGK_ENTER: 223224014Snwhitehorn result = dlg_enter_buttoncode(button); 224217309Snwhitehorn break; 225217309Snwhitehorn case ERR: 226217309Snwhitehorn break; 227217309Snwhitehorn default: 228251843Sbapt if (is_DLGK_MOUSE(key)) { 229251843Sbapt result = dlg_ok_buttoncode(key - M_EVENT); 230251843Sbapt if (result < 0) 231251843Sbapt result = DLG_EXIT_OK; 232251843Sbapt } 233217309Snwhitehorn break; 234217309Snwhitehorn } 235217309Snwhitehorn } 236217309Snwhitehorn } while ((result == DLG_EXIT_UNKNOWN) && (seconds-- > 0)); 237217309Snwhitehorn 238217309Snwhitehorn curs_set(1); 239217309Snwhitehorn dlg_mouse_free_regions(); 240217309Snwhitehorn dlg_del_window(dialog); 241217309Snwhitehorn free(prompt); 242251843Sbapt 243251843Sbapt dialog_vars.timeout_secs = save_timeout; 244251843Sbapt 245217309Snwhitehorn return ((result == DLG_EXIT_UNKNOWN) ? DLG_EXIT_OK : result); 246217309Snwhitehorn} 247