kconfig/lxdialog/checklist.c
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Aug 23 21:11:26 2011 +0200 (2011-08-23)
changeset 2891 f176fee535a0
parent 943 1cca90ce0481
permissions -rw-r--r--
cc/gcc: add 'cflags' paramater to the core backend

As the core backend is used to generate the bare-metal compiler,
we need to pass it the host CFLAGS.

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