1*4c8945a0SNathan Whitehorn /* 2*4c8945a0SNathan Whitehorn * $Id: pause.c,v 1.22 2010/04/28 00:29:50 tom Exp $ 3*4c8945a0SNathan Whitehorn * 4*4c8945a0SNathan Whitehorn * pause.c -- implements the pause dialog 5*4c8945a0SNathan Whitehorn * 6*4c8945a0SNathan Whitehorn * Copyright 2004-2009,2010 Thomas E. Dickey 7*4c8945a0SNathan Whitehorn * 8*4c8945a0SNathan Whitehorn * This program is free software; you can redistribute it and/or modify 9*4c8945a0SNathan Whitehorn * it under the terms of the GNU Lesser General Public License, version 2.1 10*4c8945a0SNathan Whitehorn * as published by the Free Software Foundation. 11*4c8945a0SNathan Whitehorn * 12*4c8945a0SNathan Whitehorn * This program is distributed in the hope that it will be useful, but 13*4c8945a0SNathan Whitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 14*4c8945a0SNathan Whitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*4c8945a0SNathan Whitehorn * Lesser General Public License for more details. 16*4c8945a0SNathan Whitehorn * 17*4c8945a0SNathan Whitehorn * You should have received a copy of the GNU Lesser General Public 18*4c8945a0SNathan Whitehorn * License along with this program; if not, write to 19*4c8945a0SNathan Whitehorn * Free Software Foundation, Inc. 20*4c8945a0SNathan Whitehorn * 51 Franklin St., Fifth Floor 21*4c8945a0SNathan Whitehorn * Boston, MA 02110, USA. 22*4c8945a0SNathan Whitehorn * 23*4c8945a0SNathan Whitehorn * This is adapted from source contributed by 24*4c8945a0SNathan Whitehorn * Yura Kalinichenko 25*4c8945a0SNathan Whitehorn */ 26*4c8945a0SNathan Whitehorn 27*4c8945a0SNathan Whitehorn #include <dialog.h> 28*4c8945a0SNathan Whitehorn #include <dlg_keys.h> 29*4c8945a0SNathan Whitehorn 30*4c8945a0SNathan Whitehorn #define MY_TIMEOUT 50 31*4c8945a0SNathan Whitehorn 32*4c8945a0SNathan Whitehorn #define MIN_HIGH (4) 33*4c8945a0SNathan Whitehorn #define MIN_WIDE (10 + 2 * (2 + MARGIN)) 34*4c8945a0SNathan Whitehorn #define BTN_HIGH (1 + 2 * MARGIN) 35*4c8945a0SNathan Whitehorn 36*4c8945a0SNathan Whitehorn /* 37*4c8945a0SNathan Whitehorn * This is like gauge, but can be interrupted. 38*4c8945a0SNathan Whitehorn * 39*4c8945a0SNathan Whitehorn * A pause box displays a meter along the bottom of the box. The meter 40*4c8945a0SNathan Whitehorn * indicates how many seconds remain until the end of the pause. The pause 41*4c8945a0SNathan Whitehorn * exits when timeout is reached (status OK) or the user presses: 42*4c8945a0SNathan Whitehorn * OK button (status OK) 43*4c8945a0SNathan Whitehorn * CANCEL button (status CANCEL) 44*4c8945a0SNathan Whitehorn * Esc key (status ESC) 45*4c8945a0SNathan Whitehorn * 46*4c8945a0SNathan Whitehorn */ 47*4c8945a0SNathan Whitehorn int 48*4c8945a0SNathan Whitehorn dialog_pause(const char *title, 49*4c8945a0SNathan Whitehorn const char *cprompt, 50*4c8945a0SNathan Whitehorn int height, 51*4c8945a0SNathan Whitehorn int width, 52*4c8945a0SNathan Whitehorn int seconds) 53*4c8945a0SNathan Whitehorn { 54*4c8945a0SNathan Whitehorn /* *INDENT-OFF* */ 55*4c8945a0SNathan Whitehorn static DLG_KEYS_BINDING binding[] = { 56*4c8945a0SNathan Whitehorn ENTERKEY_BINDINGS, 57*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_ENTER, ' ' ), 58*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_DOWN ), 59*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), 60*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), 61*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_UP ), 62*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), 63*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), 64*4c8945a0SNathan Whitehorn END_KEYS_BINDING 65*4c8945a0SNathan Whitehorn }; 66*4c8945a0SNathan Whitehorn /* *INDENT-ON* */ 67*4c8945a0SNathan Whitehorn 68*4c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 69*4c8945a0SNathan Whitehorn int old_height = height; 70*4c8945a0SNathan Whitehorn int old_width = width; 71*4c8945a0SNathan Whitehorn #endif 72*4c8945a0SNathan Whitehorn 73*4c8945a0SNathan Whitehorn int i, x, y, step; 74*4c8945a0SNathan Whitehorn int button = 0; 75*4c8945a0SNathan Whitehorn int seconds_orig; 76*4c8945a0SNathan Whitehorn WINDOW *dialog; 77*4c8945a0SNathan Whitehorn const char **buttons = dlg_ok_labels(); 78*4c8945a0SNathan Whitehorn bool have_buttons = (dlg_button_count(buttons) != 0); 79*4c8945a0SNathan Whitehorn int key = 0, fkey; 80*4c8945a0SNathan Whitehorn int result = DLG_EXIT_UNKNOWN; 81*4c8945a0SNathan Whitehorn int button_high = (have_buttons ? BTN_HIGH : MARGIN); 82*4c8945a0SNathan Whitehorn int guage_y; 83*4c8945a0SNathan Whitehorn char *prompt = dlg_strclone(cprompt); 84*4c8945a0SNathan Whitehorn 85*4c8945a0SNathan Whitehorn curs_set(0); 86*4c8945a0SNathan Whitehorn 87*4c8945a0SNathan Whitehorn dlg_tab_correct_str(prompt); 88*4c8945a0SNathan Whitehorn 89*4c8945a0SNathan Whitehorn seconds_orig = (seconds > 0) ? seconds : 1; 90*4c8945a0SNathan Whitehorn 91*4c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 92*4c8945a0SNathan Whitehorn retry: 93*4c8945a0SNathan Whitehorn height = old_height; 94*4c8945a0SNathan Whitehorn width = old_width; 95*4c8945a0SNathan Whitehorn #endif 96*4c8945a0SNathan Whitehorn 97*4c8945a0SNathan Whitehorn if (have_buttons) { 98*4c8945a0SNathan Whitehorn dlg_auto_size(title, prompt, &height, &width, 99*4c8945a0SNathan Whitehorn MIN_HIGH, 100*4c8945a0SNathan Whitehorn MIN_WIDE); 101*4c8945a0SNathan Whitehorn dlg_button_layout(buttons, &width); 102*4c8945a0SNathan Whitehorn } else { 103*4c8945a0SNathan Whitehorn dlg_auto_size(title, prompt, &height, &width, 104*4c8945a0SNathan Whitehorn MIN_HIGH + MARGIN - BTN_HIGH, 105*4c8945a0SNathan Whitehorn MIN_WIDE); 106*4c8945a0SNathan Whitehorn } 107*4c8945a0SNathan Whitehorn guage_y = height - button_high - (1 + 2 * MARGIN); 108*4c8945a0SNathan Whitehorn dlg_print_size(height, width); 109*4c8945a0SNathan Whitehorn dlg_ctl_size(height, width); 110*4c8945a0SNathan Whitehorn 111*4c8945a0SNathan Whitehorn /* center dialog box on screen */ 112*4c8945a0SNathan Whitehorn x = dlg_box_x_ordinate(width); 113*4c8945a0SNathan Whitehorn y = dlg_box_y_ordinate(height); 114*4c8945a0SNathan Whitehorn 115*4c8945a0SNathan Whitehorn dialog = dlg_new_window(height, width, y, x); 116*4c8945a0SNathan Whitehorn dlg_register_window(dialog, "pause", binding); 117*4c8945a0SNathan Whitehorn dlg_register_buttons(dialog, "pause", buttons); 118*4c8945a0SNathan Whitehorn 119*4c8945a0SNathan Whitehorn dlg_mouse_setbase(x, y); 120*4c8945a0SNathan Whitehorn nodelay(dialog, TRUE); 121*4c8945a0SNathan Whitehorn 122*4c8945a0SNathan Whitehorn do { 123*4c8945a0SNathan Whitehorn (void) werase(dialog); 124*4c8945a0SNathan Whitehorn dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 125*4c8945a0SNathan Whitehorn 126*4c8945a0SNathan Whitehorn dlg_draw_title(dialog, title); 127*4c8945a0SNathan Whitehorn 128*4c8945a0SNathan Whitehorn wattrset(dialog, dialog_attr); 129*4c8945a0SNathan Whitehorn dlg_print_autowrap(dialog, prompt, height, width); 130*4c8945a0SNathan Whitehorn 131*4c8945a0SNathan Whitehorn dlg_draw_box(dialog, 132*4c8945a0SNathan Whitehorn guage_y, 2 + MARGIN, 133*4c8945a0SNathan Whitehorn 2 + MARGIN, width - 2 * (2 + MARGIN), 134*4c8945a0SNathan Whitehorn dialog_attr, 135*4c8945a0SNathan Whitehorn border_attr); 136*4c8945a0SNathan Whitehorn 137*4c8945a0SNathan Whitehorn /* 138*4c8945a0SNathan Whitehorn * Clear the area for the progress bar by filling it with spaces 139*4c8945a0SNathan Whitehorn * in the title-attribute, and write the percentage with that 140*4c8945a0SNathan Whitehorn * attribute. 141*4c8945a0SNathan Whitehorn */ 142*4c8945a0SNathan Whitehorn (void) wmove(dialog, guage_y + MARGIN, 4); 143*4c8945a0SNathan Whitehorn wattrset(dialog, title_attr); 144*4c8945a0SNathan Whitehorn 145*4c8945a0SNathan Whitehorn for (i = 0; i < (width - 2 * (3 + MARGIN)); i++) 146*4c8945a0SNathan Whitehorn (void) waddch(dialog, ' '); 147*4c8945a0SNathan Whitehorn 148*4c8945a0SNathan Whitehorn (void) wmove(dialog, guage_y + MARGIN, (width / 2) - 2); 149*4c8945a0SNathan Whitehorn (void) wprintw(dialog, "%3d", seconds); 150*4c8945a0SNathan Whitehorn 151*4c8945a0SNathan Whitehorn /* 152*4c8945a0SNathan Whitehorn * Now draw a bar in reverse, relative to the background. 153*4c8945a0SNathan Whitehorn * The window attribute was useful for painting the background, 154*4c8945a0SNathan Whitehorn * but requires some tweaks to reverse it. 155*4c8945a0SNathan Whitehorn */ 156*4c8945a0SNathan Whitehorn x = (seconds * (width - 2 * (3 + MARGIN))) / seconds_orig; 157*4c8945a0SNathan Whitehorn if ((title_attr & A_REVERSE) != 0) { 158*4c8945a0SNathan Whitehorn wattroff(dialog, A_REVERSE); 159*4c8945a0SNathan Whitehorn } else { 160*4c8945a0SNathan Whitehorn wattrset(dialog, A_REVERSE); 161*4c8945a0SNathan Whitehorn } 162*4c8945a0SNathan Whitehorn (void) wmove(dialog, guage_y + MARGIN, 4); 163*4c8945a0SNathan Whitehorn for (i = 0; i < x; i++) { 164*4c8945a0SNathan Whitehorn chtype ch = winch(dialog); 165*4c8945a0SNathan Whitehorn if (title_attr & A_REVERSE) { 166*4c8945a0SNathan Whitehorn ch &= ~A_REVERSE; 167*4c8945a0SNathan Whitehorn } 168*4c8945a0SNathan Whitehorn (void) waddch(dialog, ch); 169*4c8945a0SNathan Whitehorn } 170*4c8945a0SNathan Whitehorn 171*4c8945a0SNathan Whitehorn mouse_mkbutton(height - 2, width / 2 - 4, 6, '\n'); 172*4c8945a0SNathan Whitehorn if (have_buttons) { 173*4c8945a0SNathan Whitehorn dlg_draw_bottom_box(dialog); 174*4c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); 175*4c8945a0SNathan Whitehorn } 176*4c8945a0SNathan Whitehorn (void) wrefresh(dialog); 177*4c8945a0SNathan Whitehorn 178*4c8945a0SNathan Whitehorn for (step = 0; 179*4c8945a0SNathan Whitehorn (result == DLG_EXIT_UNKNOWN) && (step < 1000); 180*4c8945a0SNathan Whitehorn step += MY_TIMEOUT) { 181*4c8945a0SNathan Whitehorn 182*4c8945a0SNathan Whitehorn napms(MY_TIMEOUT); 183*4c8945a0SNathan Whitehorn key = dlg_mouse_wgetch_nowait(dialog, &fkey); 184*4c8945a0SNathan Whitehorn if (key == ERR) { 185*4c8945a0SNathan Whitehorn ; /* ignore errors in nodelay mode */ 186*4c8945a0SNathan Whitehorn } else { 187*4c8945a0SNathan Whitehorn if (dlg_result_key(key, fkey, &result)) 188*4c8945a0SNathan Whitehorn break; 189*4c8945a0SNathan Whitehorn } 190*4c8945a0SNathan Whitehorn 191*4c8945a0SNathan Whitehorn switch (key) { 192*4c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 193*4c8945a0SNathan Whitehorn case KEY_RESIZE: 194*4c8945a0SNathan Whitehorn dlg_clear(); /* fill the background */ 195*4c8945a0SNathan Whitehorn dlg_del_window(dialog); /* delete this window */ 196*4c8945a0SNathan Whitehorn refresh(); /* get it all onto the terminal */ 197*4c8945a0SNathan Whitehorn goto retry; 198*4c8945a0SNathan Whitehorn #endif 199*4c8945a0SNathan Whitehorn case DLGK_FIELD_NEXT: 200*4c8945a0SNathan Whitehorn button = dlg_next_button(buttons, button); 201*4c8945a0SNathan Whitehorn if (button < 0) 202*4c8945a0SNathan Whitehorn button = 0; 203*4c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, 204*4c8945a0SNathan Whitehorn height - 2, 0, 205*4c8945a0SNathan Whitehorn buttons, button, 206*4c8945a0SNathan Whitehorn FALSE, width); 207*4c8945a0SNathan Whitehorn break; 208*4c8945a0SNathan Whitehorn case DLGK_FIELD_PREV: 209*4c8945a0SNathan Whitehorn button = dlg_prev_button(buttons, button); 210*4c8945a0SNathan Whitehorn if (button < 0) 211*4c8945a0SNathan Whitehorn button = 0; 212*4c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, 213*4c8945a0SNathan Whitehorn height - 2, 0, 214*4c8945a0SNathan Whitehorn buttons, button, 215*4c8945a0SNathan Whitehorn FALSE, width); 216*4c8945a0SNathan Whitehorn break; 217*4c8945a0SNathan Whitehorn case DLGK_ENTER: 218*4c8945a0SNathan Whitehorn /* Do not use dlg_exit_buttoncode() since we want to return 219*4c8945a0SNathan Whitehorn * a cancel rather than ok if the timeout has not expired. 220*4c8945a0SNathan Whitehorn */ 221*4c8945a0SNathan Whitehorn result = button ? DLG_EXIT_CANCEL : DLG_EXIT_OK; 222*4c8945a0SNathan Whitehorn break; 223*4c8945a0SNathan Whitehorn case DLGK_MOUSE(0): 224*4c8945a0SNathan Whitehorn result = DLG_EXIT_OK; 225*4c8945a0SNathan Whitehorn break; 226*4c8945a0SNathan Whitehorn case DLGK_MOUSE(1): 227*4c8945a0SNathan Whitehorn result = DLG_EXIT_CANCEL; 228*4c8945a0SNathan Whitehorn break; 229*4c8945a0SNathan Whitehorn case ERR: 230*4c8945a0SNathan Whitehorn break; 231*4c8945a0SNathan Whitehorn default: 232*4c8945a0SNathan Whitehorn result = DLG_EXIT_OK; 233*4c8945a0SNathan Whitehorn break; 234*4c8945a0SNathan Whitehorn } 235*4c8945a0SNathan Whitehorn } 236*4c8945a0SNathan Whitehorn } while ((result == DLG_EXIT_UNKNOWN) && (seconds-- > 0)); 237*4c8945a0SNathan Whitehorn 238*4c8945a0SNathan Whitehorn nodelay(dialog, FALSE); 239*4c8945a0SNathan Whitehorn curs_set(1); 240*4c8945a0SNathan Whitehorn dlg_mouse_free_regions(); 241*4c8945a0SNathan Whitehorn dlg_del_window(dialog); 242*4c8945a0SNathan Whitehorn free(prompt); 243*4c8945a0SNathan Whitehorn return ((result == DLG_EXIT_UNKNOWN) ? DLG_EXIT_OK : result); 244*4c8945a0SNathan Whitehorn } 245