pause.c revision 220749
1217309Snwhitehorn/* 2220749Snwhitehorn * $Id: pause.c,v 1.26 2011/01/18 10:16:33 tom Exp $ 3217309Snwhitehorn * 4217309Snwhitehorn * pause.c -- implements the pause dialog 5217309Snwhitehorn * 6220749Snwhitehorn * Copyright 2004-2010,2011 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[] = { 56217309Snwhitehorn ENTERKEY_BINDINGS, 57217309Snwhitehorn DLG_KEYS_DATA( DLGK_ENTER, ' ' ), 58217309Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_DOWN ), 59217309Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), 60217309Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), 61217309Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_UP ), 62217309Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), 63217309Snwhitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), 64217309Snwhitehorn END_KEYS_BINDING 65217309Snwhitehorn }; 66217309Snwhitehorn /* *INDENT-ON* */ 67217309Snwhitehorn 68217309Snwhitehorn#ifdef KEY_RESIZE 69217309Snwhitehorn int old_height = height; 70217309Snwhitehorn int old_width = width; 71217309Snwhitehorn#endif 72217309Snwhitehorn 73217309Snwhitehorn int i, x, y, step; 74217309Snwhitehorn int button = 0; 75217309Snwhitehorn int seconds_orig; 76217309Snwhitehorn WINDOW *dialog; 77217309Snwhitehorn const char **buttons = dlg_ok_labels(); 78217309Snwhitehorn bool have_buttons = (dlg_button_count(buttons) != 0); 79217309Snwhitehorn int key = 0, fkey; 80217309Snwhitehorn int result = DLG_EXIT_UNKNOWN; 81217309Snwhitehorn int button_high = (have_buttons ? BTN_HIGH : MARGIN); 82220749Snwhitehorn int gauge_y; 83217309Snwhitehorn char *prompt = dlg_strclone(cprompt); 84217309Snwhitehorn 85217309Snwhitehorn curs_set(0); 86217309Snwhitehorn 87217309Snwhitehorn dlg_tab_correct_str(prompt); 88217309Snwhitehorn 89217309Snwhitehorn seconds_orig = (seconds > 0) ? seconds : 1; 90217309Snwhitehorn 91217309Snwhitehorn#ifdef KEY_RESIZE 92217309Snwhitehorn retry: 93217309Snwhitehorn height = old_height; 94217309Snwhitehorn width = old_width; 95217309Snwhitehorn#endif 96217309Snwhitehorn 97217309Snwhitehorn if (have_buttons) { 98217309Snwhitehorn dlg_auto_size(title, prompt, &height, &width, 99217309Snwhitehorn MIN_HIGH, 100217309Snwhitehorn MIN_WIDE); 101217309Snwhitehorn dlg_button_layout(buttons, &width); 102217309Snwhitehorn } else { 103217309Snwhitehorn dlg_auto_size(title, prompt, &height, &width, 104217309Snwhitehorn MIN_HIGH + MARGIN - BTN_HIGH, 105217309Snwhitehorn MIN_WIDE); 106217309Snwhitehorn } 107220749Snwhitehorn gauge_y = height - button_high - (1 + 2 * MARGIN); 108217309Snwhitehorn dlg_print_size(height, width); 109217309Snwhitehorn dlg_ctl_size(height, width); 110217309Snwhitehorn 111217309Snwhitehorn /* center dialog box on screen */ 112217309Snwhitehorn x = dlg_box_x_ordinate(width); 113217309Snwhitehorn y = dlg_box_y_ordinate(height); 114217309Snwhitehorn 115217309Snwhitehorn dialog = dlg_new_window(height, width, y, x); 116217309Snwhitehorn dlg_register_window(dialog, "pause", binding); 117217309Snwhitehorn dlg_register_buttons(dialog, "pause", buttons); 118217309Snwhitehorn 119217309Snwhitehorn dlg_mouse_setbase(x, y); 120217309Snwhitehorn nodelay(dialog, TRUE); 121217309Snwhitehorn 122217309Snwhitehorn do { 123217309Snwhitehorn (void) werase(dialog); 124217309Snwhitehorn dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 125217309Snwhitehorn 126217309Snwhitehorn dlg_draw_title(dialog, title); 127217309Snwhitehorn 128217309Snwhitehorn wattrset(dialog, dialog_attr); 129217309Snwhitehorn dlg_print_autowrap(dialog, prompt, height, width); 130217309Snwhitehorn 131217309Snwhitehorn dlg_draw_box(dialog, 132220749Snwhitehorn gauge_y, 2 + MARGIN, 133217309Snwhitehorn 2 + MARGIN, width - 2 * (2 + MARGIN), 134217309Snwhitehorn dialog_attr, 135217309Snwhitehorn border_attr); 136217309Snwhitehorn 137217309Snwhitehorn /* 138217309Snwhitehorn * Clear the area for the progress bar by filling it with spaces 139217309Snwhitehorn * in the title-attribute, and write the percentage with that 140217309Snwhitehorn * attribute. 141217309Snwhitehorn */ 142220749Snwhitehorn (void) wmove(dialog, gauge_y + MARGIN, 4); 143217309Snwhitehorn wattrset(dialog, title_attr); 144217309Snwhitehorn 145217309Snwhitehorn for (i = 0; i < (width - 2 * (3 + MARGIN)); i++) 146217309Snwhitehorn (void) waddch(dialog, ' '); 147217309Snwhitehorn 148220749Snwhitehorn (void) wmove(dialog, gauge_y + MARGIN, (width / 2) - 2); 149217309Snwhitehorn (void) wprintw(dialog, "%3d", seconds); 150217309Snwhitehorn 151217309Snwhitehorn /* 152217309Snwhitehorn * Now draw a bar in reverse, relative to the background. 153217309Snwhitehorn * The window attribute was useful for painting the background, 154217309Snwhitehorn * but requires some tweaks to reverse it. 155217309Snwhitehorn */ 156217309Snwhitehorn x = (seconds * (width - 2 * (3 + MARGIN))) / seconds_orig; 157217309Snwhitehorn if ((title_attr & A_REVERSE) != 0) { 158217309Snwhitehorn wattroff(dialog, A_REVERSE); 159217309Snwhitehorn } else { 160217309Snwhitehorn wattrset(dialog, A_REVERSE); 161217309Snwhitehorn } 162220749Snwhitehorn (void) wmove(dialog, gauge_y + MARGIN, 4); 163217309Snwhitehorn for (i = 0; i < x; i++) { 164217309Snwhitehorn chtype ch = winch(dialog); 165217309Snwhitehorn if (title_attr & A_REVERSE) { 166217309Snwhitehorn ch &= ~A_REVERSE; 167217309Snwhitehorn } 168217309Snwhitehorn (void) waddch(dialog, ch); 169217309Snwhitehorn } 170217309Snwhitehorn 171217309Snwhitehorn mouse_mkbutton(height - 2, width / 2 - 4, 6, '\n'); 172217309Snwhitehorn if (have_buttons) { 173217309Snwhitehorn dlg_draw_bottom_box(dialog); 174217309Snwhitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); 175217309Snwhitehorn } 176217309Snwhitehorn (void) wrefresh(dialog); 177217309Snwhitehorn 178217309Snwhitehorn for (step = 0; 179217309Snwhitehorn (result == DLG_EXIT_UNKNOWN) && (step < 1000); 180217309Snwhitehorn step += MY_TIMEOUT) { 181217309Snwhitehorn 182217309Snwhitehorn napms(MY_TIMEOUT); 183217309Snwhitehorn key = dlg_mouse_wgetch_nowait(dialog, &fkey); 184217309Snwhitehorn if (key == ERR) { 185217309Snwhitehorn ; /* ignore errors in nodelay mode */ 186217309Snwhitehorn } else { 187217309Snwhitehorn if (dlg_result_key(key, fkey, &result)) 188217309Snwhitehorn break; 189217309Snwhitehorn } 190217309Snwhitehorn 191217309Snwhitehorn switch (key) { 192217309Snwhitehorn#ifdef KEY_RESIZE 193217309Snwhitehorn case KEY_RESIZE: 194217309Snwhitehorn dlg_clear(); /* fill the background */ 195217309Snwhitehorn dlg_del_window(dialog); /* delete this window */ 196217309Snwhitehorn refresh(); /* get it all onto the terminal */ 197217309Snwhitehorn goto retry; 198217309Snwhitehorn#endif 199217309Snwhitehorn case DLGK_FIELD_NEXT: 200217309Snwhitehorn button = dlg_next_button(buttons, button); 201217309Snwhitehorn if (button < 0) 202217309Snwhitehorn button = 0; 203217309Snwhitehorn dlg_draw_buttons(dialog, 204217309Snwhitehorn height - 2, 0, 205217309Snwhitehorn buttons, button, 206217309Snwhitehorn FALSE, width); 207217309Snwhitehorn break; 208217309Snwhitehorn case DLGK_FIELD_PREV: 209217309Snwhitehorn button = dlg_prev_button(buttons, button); 210217309Snwhitehorn if (button < 0) 211217309Snwhitehorn button = 0; 212217309Snwhitehorn dlg_draw_buttons(dialog, 213217309Snwhitehorn height - 2, 0, 214217309Snwhitehorn buttons, button, 215217309Snwhitehorn FALSE, width); 216217309Snwhitehorn break; 217217309Snwhitehorn case DLGK_ENTER: 218220749Snwhitehorn result = dlg_ok_buttoncode(button); 219217309Snwhitehorn break; 220217309Snwhitehorn case DLGK_MOUSE(0): 221217309Snwhitehorn result = DLG_EXIT_OK; 222217309Snwhitehorn break; 223217309Snwhitehorn case DLGK_MOUSE(1): 224217309Snwhitehorn result = DLG_EXIT_CANCEL; 225217309Snwhitehorn break; 226217309Snwhitehorn case ERR: 227217309Snwhitehorn break; 228217309Snwhitehorn default: 229217309Snwhitehorn break; 230217309Snwhitehorn } 231217309Snwhitehorn } 232217309Snwhitehorn } while ((result == DLG_EXIT_UNKNOWN) && (seconds-- > 0)); 233217309Snwhitehorn 234217309Snwhitehorn nodelay(dialog, FALSE); 235217309Snwhitehorn curs_set(1); 236217309Snwhitehorn dlg_mouse_free_regions(); 237217309Snwhitehorn dlg_del_window(dialog); 238217309Snwhitehorn free(prompt); 239217309Snwhitehorn return ((result == DLG_EXIT_UNKNOWN) ? DLG_EXIT_OK : result); 240217309Snwhitehorn} 241