Exemplo n.º 1
0
/*
 * Display a menu for choosing among a number of options
 */
int
dialog_menu (const char *title, const char *prompt, int height, int width,
		int menu_height, const char *current, int item_no,
		const char * const * items)

{
    int i, j, x, y, box_x, box_y;
    int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
    WINDOW *dialog, *menu;
    FILE *f;

    max_choice = MIN (menu_height, item_no);

    /* center dialog box on screen */
    x = (COLS - width) / 2;
    y = (LINES - height) / 2;

    draw_shadow (stdscr, y, x, height, width);

    dialog = newwin (height, width, y, x);
    keypad (dialog, TRUE);

    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
    wattrset (dialog, border_attr);
    mvwaddch (dialog, height - 3, 0, ACS_LTEE);
    for (i = 0; i < width - 2; i++)
	waddch (dialog, ACS_HLINE);
    wattrset (dialog, dialog_attr);
    wbkgdset (dialog, dialog_attr & A_COLOR);
    waddch (dialog, ACS_RTEE);

    if (title != NULL && strlen(title) >= width-2 ) {
	/* truncate long title -- mec */
	char * title2 = malloc(width-2+1);
	memcpy( title2, title, width-2 );
	title2[width-2] = '\0';
	title = title2;
    }

    if (title != NULL) {
	wattrset (dialog, title_attr);
	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
	waddstr (dialog, (char *)title);
	waddch (dialog, ' ');
    }

    wattrset (dialog, dialog_attr);
    print_autowrap (dialog, prompt, width - 2, 1, 3);

    menu_width = width - 6;
    box_y = height - menu_height - 5;
    box_x = (width - menu_width) / 2 - 1;

    /* create new window for the menu */
    menu = subwin (dialog, menu_height, menu_width,
		y + box_y + 1, x + box_x + 1);
    keypad (menu, TRUE);

    /* draw a box around the menu items */
    draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
	      menubox_border_attr, menubox_attr);

    /*
     * Find length of longest item in order to center menu.
     * Set 'choice' to default item. 
     */
    item_x = 0;
    for (i = 0; i < item_no; i++) {
	item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2));
	if (strcmp(current, items[i*2]) == 0) choice = i;
    }

    item_x = (menu_width - item_x) / 2;

    /* get the scroll info from the temp file */
    if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
	if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
	     (scroll+max_choice > choice) && (scroll >= 0) &&
	     (scroll+max_choice <= item_no) ) {
	    first_item = scroll;
	    choice = choice - scroll;
	    fclose(f);
	} else {
	    scroll=0;
	    remove("lxdialog.scrltmp");
	    fclose(f);
	    f=NULL;
	}
    }
    if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
	if (choice >= item_no-max_choice/2)
	    scroll = first_item = item_no-max_choice;
	else
	    scroll = first_item = choice - max_choice/2;
	choice = choice - scroll;
    }

    /* Print the menu */
    for (i=0; i < max_choice; i++) {
	print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
                    (items[(first_item + i)*2][0] != ':'));
    }

    wnoutrefresh (menu);

    print_arrows(dialog, item_no, scroll,
		 box_y, box_x+item_x+1, menu_height);

    print_buttons (dialog, height, width, 0);

    while (key != ESC) {
	key = wgetch(dialog);

	if (key < 256 && isalpha(key)) key = tolower(key);

	if (strchr("ynm", key))
		i = max_choice;
	else {
        for (i = choice+1; i < max_choice; i++) {
		j = first_alpha(items[(scroll+i)*2+1], "YyNnMm");
		if (key == tolower(items[(scroll+i)*2+1][j]))
                	break;
	}
	if (i == max_choice)
       		for (i = 0; i < max_choice; i++) {
			j = first_alpha(items[(scroll+i)*2+1], "YyNnMm");
			if (key == tolower(items[(scroll+i)*2+1][j]))
                		break;
		}
	}

	if (i < max_choice || 
            key == KEY_UP || key == KEY_DOWN ||
            key == '-' || key == '+' ||
            key == KEY_PPAGE || key == KEY_NPAGE) {

            print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
                       (items[(scroll+choice)*2][0] != ':'));

	    if (key == KEY_UP || key == '-') {
                if (choice < 2 && scroll) {
	            /* Scroll menu down */
                    scrollok (menu, TRUE);
                    wscrl (menu, -1);
                    scrollok (menu, FALSE);

                    scroll--;

                    print_item (menu, items[scroll * 2 + 1], 0, FALSE,
                               (items[scroll*2][0] != ':'));
		} else
		    choice = MAX(choice - 1, 0);

	    } else if (key == KEY_DOWN || key == '+')  {

		print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
                                (items[(scroll+choice)*2][0] != ':'));

                if ((choice > max_choice-3) &&
                    (scroll + max_choice < item_no)
                   ) {
		    /* Scroll menu up */
		    scrollok (menu, TRUE);
                    scroll (menu);
                    scrollok (menu, FALSE);

                    scroll++;

                    print_item (menu, items[(scroll+max_choice-1)*2+1],
                               max_choice-1, FALSE,
                               (items[(scroll+max_choice-1)*2][0] != ':'));
                } else
                    choice = MIN(choice+1, max_choice-1);

	    } else if (key == KEY_PPAGE) {
	        scrollok (menu, TRUE);
                for (i=0; (i < max_choice); i++) {
                    if (scroll > 0) {
                	wscrl (menu, -1);
                	scroll--;
                	print_item (menu, items[scroll * 2 + 1], 0, FALSE,
                	(items[scroll*2][0] != ':'));
                    } else {
                        if (choice > 0)
                            choice--;
                    }
                }
                scrollok (menu, FALSE);

            } else if (key == KEY_NPAGE) {
                for (i=0; (i < max_choice); i++) {
                    if (scroll+max_choice < item_no) {
			scrollok (menu, TRUE);
			scroll(menu);
			scrollok (menu, FALSE);
                	scroll++;
                	print_item (menu, items[(scroll+max_choice-1)*2+1],
			            max_choice-1, FALSE,
			            (items[(scroll+max_choice-1)*2][0] != ':'));
		    } else {
			if (choice+1 < max_choice)
			    choice++;
		    }
                }

            } else
                choice = i;

            print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
                       (items[(scroll+choice)*2][0] != ':'));

            print_arrows(dialog, item_no, scroll,
                         box_y, box_x+item_x+1, menu_height);

            wnoutrefresh (menu);
            wrefresh (dialog);

	    continue;		/* wait for another key press */
        }

	switch (key) {
	case KEY_LEFT:
	case TAB:
	case KEY_RIGHT:
	    button = ((key == KEY_LEFT ? --button : ++button) < 0)
			? 2 : (button > 2 ? 0 : button);

	    print_buttons(dialog, height, width, button);
	    wrefresh (dialog);
	    break;
	case ' ':
	case 's':
	case 'y':
	case 'n':
	case 'm':
	    /* save scroll info */
	    if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
		fprintf(f,"%d\n",scroll);
		fclose(f);
	    }
	    delwin (dialog);
            fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
            switch (key) {
            case 's': return 3;
            case 'y': return 3;
            case 'n': return 4;
            case 'm': return 5;
            case ' ': return 6;
            }
	    return 0;
	case 'h':
	case '?':
	    button = 2;
	case '\n':
	    delwin (dialog);
	    if (button == 2) 
            	fprintf(stderr, "%s \"%s\"\n", 
			items[(scroll + choice) * 2],
			items[(scroll + choice) * 2 + 1] +
			first_alpha(items[(scroll + choice) * 2 + 1],""));
	    else
            	fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);

	    remove("lxdialog.scrltmp");
	    return button;
	case 'e':
	case 'x':
	    key = ESC;
	case ESC:
	    break;
	}
    }

    delwin (dialog);
    remove("lxdialog.scrltmp");
    return -1;			/* ESC pressed */
}
Exemplo n.º 2
0
/*
 * Display a dialog box with a list of options that can be turned on or off
 * in the style of radiolist (only one option turned on at a time).
 */
int dialog_checklist(const char *title, const char *prompt, int height,
		     int width, int list_height)
{
	int i, x, y, box_x, box_y;
	int key = 0, button = 0, choice = 0, scroll = 0, max_choice;
	WINDOW *dialog, *list;

	/* which item to highlight */
	item_foreach() {
		if (item_is_tag('X'))
			choice = item_n();
		if (item_is_selected()) {
			choice = item_n();
			break;
		}
	}

do_resize:
	if (getmaxy(stdscr) < (height + 6))
		return -ERRDISPLAYTOOSMALL;
	if (getmaxx(stdscr) < (width + 6))
		return -ERRDISPLAYTOOSMALL;

	max_choice = MIN(list_height, item_count());

	/* center dialog box on screen */
	x = (COLS - width) / 2;
	y = (LINES - height) / 2;

	draw_shadow(stdscr, y, x, height, width);

	dialog = newwin(height, width, y, x);
	keypad(dialog, TRUE);

	draw_box(dialog, 0, 0, height, width,
		 dlg.dialog.atr, dlg.border.atr);
	wattrset(dialog, dlg.border.atr);
	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
	for (i = 0; i < width - 2; i++)
		waddch(dialog, ACS_HLINE);
	wattrset(dialog, dlg.dialog.atr);
	waddch(dialog, ACS_RTEE);

	print_title(dialog, title, width);

	wattrset(dialog, dlg.dialog.atr);
	print_autowrap(dialog, prompt, width - 2, 1, 3);

	list_width = width - 6;
	box_y = height - list_height - 5;
	box_x = (width - list_width) / 2 - 1;

	/* create new window for the list */
	list = subwin(dialog, list_height, list_width, y + box_y + 1,
	              x + box_x + 1);

	keypad(list, TRUE);

	/* draw a box around the list items */
	draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
	         dlg.menubox_border.atr, dlg.menubox.atr);

	/* Find length of longest item in order to center checklist */
	check_x = 0;
	item_foreach()
		check_x = MAX(check_x, strlen(item_str()) + 4);

	check_x = (list_width - check_x) / 2;
	item_x = check_x + 4;

	if (choice >= list_height) {
		scroll = choice - list_height + 1;
		choice -= scroll;
	}

	/* Print the list */
	for (i = 0; i < max_choice; i++) {
		item_set(scroll + i);
		print_item(list, i, i == choice);
	}

	print_arrows(dialog, choice, item_count(), scroll,
		     box_y, box_x + check_x + 5, list_height);

	print_buttons(dialog, height, width, 0);

	wnoutrefresh(dialog);
	wnoutrefresh(list);
	doupdate();

	while (key != KEY_ESC) {
		key = wgetch(dialog);

		for (i = 0; i < max_choice; i++) {
			item_set(i + scroll);
			if (toupper(key) == toupper(item_str()[0]))
				break;
		}

		if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
		    key == '+' || key == '-') {
			if (key == KEY_UP || key == '-') {
				if (!choice) {
					if (!scroll)
						continue;
					/* Scroll list down */
					if (list_height > 1) {
						/* De-highlight current first item */
						item_set(scroll);
						print_item(list, 0, FALSE);
						scrollok(list, TRUE);
						wscrl(list, -1);
						scrollok(list, FALSE);
					}
					scroll--;
					item_set(scroll);
					print_item(list, 0, TRUE);
					print_arrows(dialog, choice, item_count(),
						     scroll, box_y, box_x + check_x + 5, list_height);

					wnoutrefresh(dialog);
					wrefresh(list);

					continue;	/* wait for another key press */
				} else
					i = choice - 1;
			} else if (key == KEY_DOWN || key == '+') {
				if (choice == max_choice - 1) {
					if (scroll + choice >= item_count() - 1)
						continue;
					/* Scroll list up */
					if (list_height > 1) {
						/* De-highlight current last item before scrolling up */
						item_set(scroll + max_choice - 1);
						print_item(list,
							    max_choice - 1,
							    FALSE);
						scrollok(list, TRUE);
						wscrl(list, 1);
						scrollok(list, FALSE);
					}
					scroll++;
					item_set(scroll + max_choice - 1);
					print_item(list, max_choice - 1, TRUE);

					print_arrows(dialog, choice, item_count(),
						     scroll, box_y, box_x + check_x + 5, list_height);

					wnoutrefresh(dialog);
					wrefresh(list);

					continue;	/* wait for another key press */
				} else
					i = choice + 1;
			}
			if (i != choice) {
				/* De-highlight current item */
				item_set(scroll + choice);
				print_item(list, choice, FALSE);
				/* Highlight new item */
				choice = i;
				item_set(scroll + choice);
				print_item(list, choice, TRUE);
				wnoutrefresh(dialog);
				wrefresh(list);
			}
			continue;	/* wait for another key press */
		}
		switch (key) {
		case 'H':
		case 'h':
		case '?':
			button = 1;
			/* fall-through */
		case 'S':
		case 's':
		case ' ':
		case '\n':
			item_foreach()
				item_set_selected(0);
			item_set(scroll + choice);
			item_set_selected(1);
			delwin(list);
			delwin(dialog);
			return button;
		case TAB:
		case KEY_LEFT:
		case KEY_RIGHT:
			button = ((key == KEY_LEFT ? --button : ++button) < 0)
			    ? 1 : (button > 1 ? 0 : button);

			print_buttons(dialog, height, width, button);
			wrefresh(dialog);
			break;
		case 'X':
		case 'x':
			key = KEY_ESC;
			break;
		case KEY_ESC:
			key = on_key_esc(dialog);
			break;
		case KEY_RESIZE:
			delwin(list);
			delwin(dialog);
			on_key_resize();
			goto do_resize;
		}

		/* Now, update everything... */
		doupdate();
	}
	delwin(list);
	delwin(dialog);
	return key;		/* ESC pressed */
}