kconfig/lxdialog/checklist.c
author Arnaud Lacombe <lacombar@gmail.com>
Tue Aug 03 06:17:51 2010 +0200 (2010-08-03)
changeset 2064 f5ebe8c429dc
parent 1 eeea35fbf182
child 2448 a103abae1560
permissions -rw-r--r--
libc/uClibc: add uClibc 0.9.30.3

This version has been released a couple of month ago, but it never reached
crosstool-ng tree. This may be linked to the fact that the current 0.9.30.2,
once patched, has nothing much different from 0.9.30.3, released.

I'm not including any patch with this upgrade, on purpose.

Signed-off-by: Arnaud Lacombe <lacombar@gmail.com>
     1 /*
     2  *  checklist.c -- implements the checklist box
     3  *
     4  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
     5  *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
     6  *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
     7  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
     8  *
     9  *  This program is free software; you can redistribute it and/or
    10  *  modify it under the terms of the GNU General Public License
    11  *  as published by the Free Software Foundation; either version 2
    12  *  of the License, or (at your option) any later version.
    13  *
    14  *  This program is distributed in the hope that it will be useful,
    15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17  *  GNU General Public License for more details.
    18  *
    19  *  You should have received a copy of the GNU General Public License
    20  *  along with this program; if not, write to the Free Software
    21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    22  */
    23 
    24 #include "dialog.h"
    25 
    26 static int list_width, check_x, item_x;
    27 
    28 /*
    29  * Print list item
    30  */
    31 static void print_item(WINDOW * win, int choice, int selected)
    32 {
    33 	int i;
    34 
    35 	/* Clear 'residue' of last item */
    36 	wattrset(win, dlg.menubox.atr);
    37 	wmove(win, choice, 0);
    38 	for (i = 0; i < list_width; i++)
    39 		waddch(win, ' ');
    40 
    41 	wmove(win, choice, check_x);
    42 	wattrset(win, selected ? dlg.check_selected.atr
    43 		 : dlg.check.atr);
    44 	wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
    45 
    46 	wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
    47 	mvwaddch(win, choice, item_x, item_str()[0]);
    48 	wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
    49 	waddstr(win, (char *)item_str() + 1);
    50 	if (selected) {
    51 		wmove(win, choice, check_x + 1);
    52 		wrefresh(win);
    53 	}
    54 }
    55 
    56 /*
    57  * Print the scroll indicators.
    58  */
    59 static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
    60 	     int y, int x, int height)
    61 {
    62 	wmove(win, y, x);
    63 
    64 	if (scroll > 0) {
    65 		wattrset(win, dlg.uarrow.atr);
    66 		waddch(win, ACS_UARROW);
    67 		waddstr(win, "(-)");
    68 	} else {
    69 		wattrset(win, dlg.menubox.atr);
    70 		waddch(win, ACS_HLINE);
    71 		waddch(win, ACS_HLINE);
    72 		waddch(win, ACS_HLINE);
    73 		waddch(win, ACS_HLINE);
    74 	}
    75 
    76 	y = y + height + 1;
    77 	wmove(win, y, x);
    78 
    79 	if ((height < item_no) && (scroll + choice < item_no - 1)) {
    80 		wattrset(win, dlg.darrow.atr);
    81 		waddch(win, ACS_DARROW);
    82 		waddstr(win, "(+)");
    83 	} else {
    84 		wattrset(win, dlg.menubox_border.atr);
    85 		waddch(win, ACS_HLINE);
    86 		waddch(win, ACS_HLINE);
    87 		waddch(win, ACS_HLINE);
    88 		waddch(win, ACS_HLINE);
    89 	}
    90 }
    91 
    92 /*
    93  *  Display the termination buttons
    94  */
    95 static void print_buttons(WINDOW * dialog, int height, int width, int selected)
    96 {
    97 	int x = width / 2 - 11;
    98 	int y = height - 2;
    99 
   100 	print_button(dialog, gettext("Select"), y, x, selected == 0);
   101 	print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
   102 
   103 	wmove(dialog, y, x + 1 + 14 * selected);
   104 	wrefresh(dialog);
   105 }
   106 
   107 /*
   108  * Display a dialog box with a list of options that can be turned on or off
   109  * in the style of radiolist (only one option turned on at a time).
   110  */
   111 int dialog_checklist(const char *title, const char *prompt, int height,
   112 		     int width, int list_height)
   113 {
   114 	int i, x, y, box_x, box_y;
   115 	int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
   116 	WINDOW *dialog, *list;
   117 
   118 	/* which item to highlight */
   119 	item_foreach() {
   120 		if (item_is_tag('X'))
   121 			choice = item_n();
   122 		if (item_is_selected()) {
   123 			choice = item_n();
   124 			break;
   125 		}
   126 	}
   127 
   128 do_resize:
   129 	if (getmaxy(stdscr) < (height + 6))
   130 		return -ERRDISPLAYTOOSMALL;
   131 	if (getmaxx(stdscr) < (width + 6))
   132 		return -ERRDISPLAYTOOSMALL;
   133 
   134 	max_choice = MIN(list_height, item_count());
   135 
   136 	/* center dialog box on screen */
   137 	x = (COLS - width) / 2;
   138 	y = (LINES - height) / 2;
   139 
   140 	draw_shadow(stdscr, y, x, height, width);
   141 
   142 	dialog = newwin(height, width, y, x);
   143 	keypad(dialog, TRUE);
   144 
   145 	draw_box(dialog, 0, 0, height, width,
   146 		 dlg.dialog.atr, dlg.border.atr);
   147 	wattrset(dialog, dlg.border.atr);
   148 	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
   149 	for (i = 0; i < width - 2; i++)
   150 		waddch(dialog, ACS_HLINE);
   151 	wattrset(dialog, dlg.dialog.atr);
   152 	waddch(dialog, ACS_RTEE);
   153 
   154 	print_title(dialog, title, width);
   155 
   156 	wattrset(dialog, dlg.dialog.atr);
   157 	print_autowrap(dialog, prompt, width - 2, 1, 3);
   158 
   159 	list_width = width - 6;
   160 	box_y = height - list_height - 5;
   161 	box_x = (width - list_width) / 2 - 1;
   162 
   163 	/* create new window for the list */
   164 	list = subwin(dialog, list_height, list_width, y + box_y + 1,
   165 	              x + box_x + 1);
   166 
   167 	keypad(list, TRUE);
   168 
   169 	/* draw a box around the list items */
   170 	draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
   171 	         dlg.menubox_border.atr, dlg.menubox.atr);
   172 
   173 	/* Find length of longest item in order to center checklist */
   174 	check_x = 0;
   175 	item_foreach()
   176 		check_x = MAX(check_x, strlen(item_str()) + 4);
   177 
   178 	check_x = (list_width - check_x) / 2;
   179 	item_x = check_x + 4;
   180 
   181 	if (choice >= list_height) {
   182 		scroll = choice - list_height + 1;
   183 		choice -= scroll;
   184 	}
   185 
   186 	/* Print the list */
   187 	for (i = 0; i < max_choice; i++) {
   188 		item_set(scroll + i);
   189 		print_item(list, i, i == choice);
   190 	}
   191 
   192 	print_arrows(dialog, choice, item_count(), scroll,
   193 		     box_y, box_x + check_x + 5, list_height);
   194 
   195 	print_buttons(dialog, height, width, 0);
   196 
   197 	wnoutrefresh(dialog);
   198 	wnoutrefresh(list);
   199 	doupdate();
   200 
   201 	while (key != KEY_ESC) {
   202 		key = wgetch(dialog);
   203 
   204 		for (i = 0; i < max_choice; i++) {
   205 			item_set(i + scroll);
   206 			if (toupper(key) == toupper(item_str()[0]))
   207 				break;
   208 		}
   209 
   210 		if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
   211 		    key == '+' || key == '-') {
   212 			if (key == KEY_UP || key == '-') {
   213 				if (!choice) {
   214 					if (!scroll)
   215 						continue;
   216 					/* Scroll list down */
   217 					if (list_height > 1) {
   218 						/* De-highlight current first item */
   219 						item_set(scroll);
   220 						print_item(list, 0, FALSE);
   221 						scrollok(list, TRUE);
   222 						wscrl(list, -1);
   223 						scrollok(list, FALSE);
   224 					}
   225 					scroll--;
   226 					item_set(scroll);
   227 					print_item(list, 0, TRUE);
   228 					print_arrows(dialog, choice, item_count(),
   229 						     scroll, box_y, box_x + check_x + 5, list_height);
   230 
   231 					wnoutrefresh(dialog);
   232 					wrefresh(list);
   233 
   234 					continue;	/* wait for another key press */
   235 				} else
   236 					i = choice - 1;
   237 			} else if (key == KEY_DOWN || key == '+') {
   238 				if (choice == max_choice - 1) {
   239 					if (scroll + choice >= item_count() - 1)
   240 						continue;
   241 					/* Scroll list up */
   242 					if (list_height > 1) {
   243 						/* De-highlight current last item before scrolling up */
   244 						item_set(scroll + max_choice - 1);
   245 						print_item(list,
   246 							    max_choice - 1,
   247 							    FALSE);
   248 						scrollok(list, TRUE);
   249 						wscrl(list, 1);
   250 						scrollok(list, FALSE);
   251 					}
   252 					scroll++;
   253 					item_set(scroll + max_choice - 1);
   254 					print_item(list, max_choice - 1, TRUE);
   255 
   256 					print_arrows(dialog, choice, item_count(),
   257 						     scroll, box_y, box_x + check_x + 5, list_height);
   258 
   259 					wnoutrefresh(dialog);
   260 					wrefresh(list);
   261 
   262 					continue;	/* wait for another key press */
   263 				} else
   264 					i = choice + 1;
   265 			}
   266 			if (i != choice) {
   267 				/* De-highlight current item */
   268 				item_set(scroll + choice);
   269 				print_item(list, choice, FALSE);
   270 				/* Highlight new item */
   271 				choice = i;
   272 				item_set(scroll + choice);
   273 				print_item(list, choice, TRUE);
   274 				wnoutrefresh(dialog);
   275 				wrefresh(list);
   276 			}
   277 			continue;	/* wait for another key press */
   278 		}
   279 		switch (key) {
   280 		case 'H':
   281 		case 'h':
   282 		case '?':
   283 			button = 1;
   284 			/* fall-through */
   285 		case 'S':
   286 		case 's':
   287 		case ' ':
   288 		case '\n':
   289 			item_foreach()
   290 				item_set_selected(0);
   291 			item_set(scroll + choice);
   292 			item_set_selected(1);
   293 			delwin(list);
   294 			delwin(dialog);
   295 			return button;
   296 		case TAB:
   297 		case KEY_LEFT:
   298 		case KEY_RIGHT:
   299 			button = ((key == KEY_LEFT ? --button : ++button) < 0)
   300 			    ? 1 : (button > 1 ? 0 : button);
   301 
   302 			print_buttons(dialog, height, width, button);
   303 			wrefresh(dialog);
   304 			break;
   305 		case 'X':
   306 		case 'x':
   307 			key = KEY_ESC;
   308 			break;
   309 		case KEY_ESC:
   310 			key = on_key_esc(dialog);
   311 			break;
   312 		case KEY_RESIZE:
   313 			delwin(list);
   314 			delwin(dialog);
   315 			on_key_resize();
   316 			goto do_resize;
   317 		}
   318 
   319 		/* Now, update everything... */
   320 		doupdate();
   321 	}
   322 	delwin(list);
   323 	delwin(dialog);
   324 	return key;		/* ESC pressed */
   325 }