Home | History | Annotate | Download | only in lxdialog
      1 /*
      2  *  inputbox.c -- implements the input box
      3  *
      4  *  ORIGINAL AUTHOR: Savio Lam (lam836 (at) cs.cuhk.hk)
      5  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap (at) cfw.com)
      6  *
      7  *  This program is free software; you can redistribute it and/or
      8  *  modify it under the terms of the GNU General Public License
      9  *  as published by the Free Software Foundation; either version 2
     10  *  of the License, or (at your option) any later version.
     11  *
     12  *  This program is distributed in the hope that it will be useful,
     13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  *  GNU General Public License for more details.
     16  *
     17  *  You should have received a copy of the GNU General Public License
     18  *  along with this program; if not, write to the Free Software
     19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     20  */
     21 
     22 #include "dialog.h"
     23 
     24 char dialog_input_result[MAX_LEN + 1];
     25 
     26 /*
     27  *  Print the termination buttons
     28  */
     29 static void print_buttons(WINDOW * dialog, int height, int width, int selected)
     30 {
     31 	int x = width / 2 - 11;
     32 	int y = height - 2;
     33 
     34 	print_button(dialog, "  Ok  ", y, x, selected == 0);
     35 	print_button(dialog, " Help ", y, x + 14, selected == 1);
     36 
     37 	wmove(dialog, y, x + 1 + 14 * selected);
     38 	wrefresh(dialog);
     39 }
     40 
     41 /*
     42  * Display a dialog box for inputing a string
     43  */
     44 int dialog_inputbox(const char *title, const char *prompt, int height, int width,
     45                     const char *init)
     46 {
     47 	int i, x, y, box_y, box_x, box_width;
     48 	int input_x = 0, scroll = 0, key = 0, button = -1;
     49 	char *instr = dialog_input_result;
     50 	WINDOW *dialog;
     51 
     52 	if (!init)
     53 		instr[0] = '\0';
     54 	else
     55 		strcpy(instr, init);
     56 
     57 do_resize:
     58 	if (getmaxy(stdscr) <= (height - 2))
     59 		return -ERRDISPLAYTOOSMALL;
     60 	if (getmaxx(stdscr) <= (width - 2))
     61 		return -ERRDISPLAYTOOSMALL;
     62 
     63 	/* center dialog box on screen */
     64 	x = (COLS - width) / 2;
     65 	y = (LINES - height) / 2;
     66 
     67 	draw_shadow(stdscr, y, x, height, width);
     68 
     69 	dialog = newwin(height, width, y, x);
     70 	keypad(dialog, TRUE);
     71 
     72 	draw_box(dialog, 0, 0, height, width,
     73 		 dlg.dialog.atr, dlg.border.atr);
     74 	wattrset(dialog, dlg.border.atr);
     75 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
     76 	for (i = 0; i < width - 2; i++)
     77 		waddch(dialog, ACS_HLINE);
     78 	wattrset(dialog, dlg.dialog.atr);
     79 	waddch(dialog, ACS_RTEE);
     80 
     81 	print_title(dialog, title, width);
     82 
     83 	wattrset(dialog, dlg.dialog.atr);
     84 	print_autowrap(dialog, prompt, width - 2, 1, 3);
     85 
     86 	/* Draw the input field box */
     87 	box_width = width - 6;
     88 	getyx(dialog, y, x);
     89 	box_y = y + 2;
     90 	box_x = (width - box_width) / 2;
     91 	draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
     92 		 dlg.border.atr, dlg.dialog.atr);
     93 
     94 	print_buttons(dialog, height, width, 0);
     95 
     96 	/* Set up the initial value */
     97 	wmove(dialog, box_y, box_x);
     98 	wattrset(dialog, dlg.inputbox.atr);
     99 
    100 	input_x = strlen(instr);
    101 
    102 	if (input_x >= box_width) {
    103 		scroll = input_x - box_width + 1;
    104 		input_x = box_width - 1;
    105 		for (i = 0; i < box_width - 1; i++)
    106 			waddch(dialog, instr[scroll + i]);
    107 	} else {
    108 		waddstr(dialog, instr);
    109 	}
    110 
    111 	wmove(dialog, box_y, box_x + input_x);
    112 
    113 	wrefresh(dialog);
    114 
    115 	while (key != KEY_ESC) {
    116 		key = wgetch(dialog);
    117 
    118 		if (button == -1) {	/* Input box selected */
    119 			switch (key) {
    120 			case TAB:
    121 			case KEY_UP:
    122 			case KEY_DOWN:
    123 				break;
    124 			case KEY_LEFT:
    125 				continue;
    126 			case KEY_RIGHT:
    127 				continue;
    128 			case KEY_BACKSPACE:
    129 			case 127:
    130 				if (input_x || scroll) {
    131 					wattrset(dialog, dlg.inputbox.atr);
    132 					if (!input_x) {
    133 						scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
    134 						wmove(dialog, box_y, box_x);
    135 						for (i = 0; i < box_width; i++)
    136 							waddch(dialog,
    137 							       instr[scroll + input_x + i] ?
    138 							       instr[scroll + input_x + i] : ' ');
    139 						input_x = strlen(instr) - scroll;
    140 					} else
    141 						input_x--;
    142 					instr[scroll + input_x] = '\0';
    143 					mvwaddch(dialog, box_y, input_x + box_x, ' ');
    144 					wmove(dialog, box_y, input_x + box_x);
    145 					wrefresh(dialog);
    146 				}
    147 				continue;
    148 			default:
    149 				if (key < 0x100 && isprint(key)) {
    150 					if (scroll + input_x < MAX_LEN) {
    151 						wattrset(dialog, dlg.inputbox.atr);
    152 						instr[scroll + input_x] = key;
    153 						instr[scroll + input_x + 1] = '\0';
    154 						if (input_x == box_width - 1) {
    155 							scroll++;
    156 							wmove(dialog, box_y, box_x);
    157 							for (i = 0; i < box_width - 1; i++)
    158 								waddch(dialog, instr [scroll + i]);
    159 						} else {
    160 							wmove(dialog, box_y, input_x++ + box_x);
    161 							waddch(dialog, key);
    162 						}
    163 						wrefresh(dialog);
    164 					} else
    165 						flash();	/* Alarm user about overflow */
    166 					continue;
    167 				}
    168 			}
    169 		}
    170 		switch (key) {
    171 		case 'O':
    172 		case 'o':
    173 			delwin(dialog);
    174 			return 0;
    175 		case 'H':
    176 		case 'h':
    177 			delwin(dialog);
    178 			return 1;
    179 		case KEY_UP:
    180 		case KEY_LEFT:
    181 			switch (button) {
    182 			case -1:
    183 				button = 1;	/* Indicates "Cancel" button is selected */
    184 				print_buttons(dialog, height, width, 1);
    185 				break;
    186 			case 0:
    187 				button = -1;	/* Indicates input box is selected */
    188 				print_buttons(dialog, height, width, 0);
    189 				wmove(dialog, box_y, box_x + input_x);
    190 				wrefresh(dialog);
    191 				break;
    192 			case 1:
    193 				button = 0;	/* Indicates "OK" button is selected */
    194 				print_buttons(dialog, height, width, 0);
    195 				break;
    196 			}
    197 			break;
    198 		case TAB:
    199 		case KEY_DOWN:
    200 		case KEY_RIGHT:
    201 			switch (button) {
    202 			case -1:
    203 				button = 0;	/* Indicates "OK" button is selected */
    204 				print_buttons(dialog, height, width, 0);
    205 				break;
    206 			case 0:
    207 				button = 1;	/* Indicates "Cancel" button is selected */
    208 				print_buttons(dialog, height, width, 1);
    209 				break;
    210 			case 1:
    211 				button = -1;	/* Indicates input box is selected */
    212 				print_buttons(dialog, height, width, 0);
    213 				wmove(dialog, box_y, box_x + input_x);
    214 				wrefresh(dialog);
    215 				break;
    216 			}
    217 			break;
    218 		case ' ':
    219 		case '\n':
    220 			delwin(dialog);
    221 			return (button == -1 ? 0 : button);
    222 		case 'X':
    223 		case 'x':
    224 			key = KEY_ESC;
    225 			break;
    226 		case KEY_ESC:
    227 			key = on_key_esc(dialog);
    228 			break;
    229 		case KEY_RESIZE:
    230 			delwin(dialog);
    231 			on_key_resize();
    232 			goto do_resize;
    233 		}
    234 	}
    235 
    236 	delwin(dialog);
    237 	return KEY_ESC;		/* ESC pressed */
    238 }
    239