📄 lyforms.c
字号:
temp[0] = *c; temp[1] = '\0'; _statusline(SELECT_OPTION_NUMBER); /* * Get the number, possibly with a suffix, from the user. */ if (LYgetstr(temp, VISIBLE, sizeof(temp), NORECALL) < 0 || *temp == 0) { _statusline(CANCELLED); sleep(InfoSecs); *c = '\0'; return(0); } /* * If we had a 'g' or 'p' suffix, load it into c. * Otherwise, zero c. Then return the number. */ if (strchr(temp, 'g') != NULL || strchr(temp, 'G') != NULL) { *c = 'g'; } else if (strchr(temp, 'p') != NULL || strchr(temp, 'P') != NULL) { *c = 'p'; } else { *c = '\0'; } return(atoi(temp));}/* Use this rather than the 'wprintw()' function to write a blank-padded * string to the given window, since someone's asserted that printw doesn't * handle 8-bit characters unlike addstr (though more info would be useful). * * We're blank-filling so that with SVr4 curses, it'll show the background * color to a uniform width in the popup-menu. */#ifndef USE_SLANGPRIVATE void paddstr ARGS3( WINDOW *, the_window, int, width, char *, the_string){ width -= strlen(the_string); waddstr(the_window, the_string); while (width-- > 0) waddstr(the_window, " ");}#endifPRIVATE int popup_options ARGS7( int, cur_selection, OptionType *, list, int, ly, int, lx, int, width, int, i_length, int, disabled){ /* * Revamped to handle within-tag VALUE's, if present, * and to position the popup window appropriately, * taking the user_mode setting into account. -- FM */ int c = 0, cmd = 0, i = 0, j = 0; int orig_selection = cur_selection;#ifndef USE_SLANG WINDOW * form_window;#endif /* !USE_SLANG */ int num_options = 0, top, bottom, length = -1; OptionType * opt_ptr = list; int window_offset = 0; int lines_to_show; int npages;#ifdef VMS extern BOOLEAN HadVMSInterrupt; /* Flag from cleanup_sig() AST */#endif /* VMS */ static char prev_target[512]; /* Search string buffer */ static char prev_target_buffer[512]; /* Next search buffer */ static BOOL first = TRUE; char *cp; int ch = 0, recall; int QueryTotal; int QueryNum; BOOLEAN FirstRecall = TRUE; OptionType * tmp_ptr; BOOLEAN ReDraw = FALSE; int number; char buffer[512]; /* * Initialize the search string buffer. - FM */ if (first) { *prev_target_buffer = '\0'; first = FALSE; } *prev_target = '\0'; QueryTotal = (search_queries ? HTList_count(search_queries) : 0); recall = ((QueryTotal >= 1) ? RECALL : NORECALL); QueryNum = QueryTotal; /* * Set lines_to_show based on the user_mode global. */ if (user_mode == NOVICE_MODE) lines_to_show = LYlines-4; else lines_to_show = LYlines-2; /* * Counting the number of options to be displayed. * num_options ranges 0...n */ for (; opt_ptr->next; num_options++, opt_ptr = opt_ptr->next) ; /* null body */ /* * Let's assume for the sake of sanity that ly is the number * corresponding to the line the selection box is on. * Let's also assume that cur_selection is the number of the * item that should be initially selected, as 0 beign the * first item. * So what we have, is the top equal to the current screen line * subtracting the cur_selection + 1 (the one must be for the * top line we will draw in a box). If the top goes under 0, * consider it 0. */ top = ly - (cur_selection + 1); if (top < 0) top = 0; /* * Check and see if we need to put the i_length parameter up to * the number of real options. */ if (!i_length) { i_length = num_options; } else { /* * Otherwise, it is really one number too high. */ i_length--; } /* * The bottom is the value of the top plus the number of options * to view plus 3 (one for the top line, one for the bottom line, * and one to offset the 0 counted in the num_options). */ bottom = top + i_length + 3; /* * Hmm... If the bottom goes beyond the number of lines available, */ if (bottom > lines_to_show) { /* * Position the window at the top if we have more * options than will fit in the window. */ if (i_length+3 > lines_to_show) { top = 0; bottom = top + i_length+3; if (bottom > lines_to_show) bottom = lines_to_show + 1; } else { /* * Try to position the window so that the selected option will * appear where the selection box currently is positioned. * It could end up too high, at this point, but we'll move it * down latter, if that has happened. */ top = (lines_to_show + 1) - (i_length + 3); bottom = (lines_to_show + 1); } } /* * This is really fun, when the length is 4, it means 0-4, or 5. */ length = (bottom - top) - 2; /* * Move the window down if it's too high. */ if (bottom < ly + 2) { bottom = ly + 2; if (bottom > lines_to_show + 1) bottom = lines_to_show + 1; top = bottom - length - 2; } /* * Set up the overall window, including the boxing characters ('*'), * if it all fits. Otherwise, set up the widest window possible. - FM */#ifdef USE_SLANG SLsmg_fill_region(top, lx - 1, bottom - top, width + 4, ' ');#else if (!(form_window = newwin(bottom - top, width + 4, top, lx - 1)) && !(form_window = newwin(bottom - top, 0, top, 0))) { HTAlert(POPUP_FAILED); return(orig_selection); } scrollok(form_window, TRUE);#ifdef PDCURSES keypad(form_window, TRUE);#endif /* PDCURSES */#ifdef NCURSES LYsubwindow(form_window);#endif#if defined(HAVE_GETBKGD) /* not defined in ncurses 1.8.7 */ wbkgd(form_window, getbkgd(stdscr)); wbkgdset(form_window, getbkgd(stdscr));#endif#endif /* USE_SLANG */ /* * Set up the window_offset for options. * cur_selection ranges from 0...n * length ranges from 0...m */ if (cur_selection >= length) { window_offset = cur_selection - length + 1; } /* * Compute the number of popup window pages. - FM */ npages = ((num_options + 1) > length) ? (((num_options + 1) + (length - 1))/(length)) : 1;/* * OH! I LOVE GOTOs! hack hack hack * 07-11-94 GAB * MORE hack hack hack * 09-05-94 FM */redraw: opt_ptr = list; /* * Display the boxed options. */ for (i = 0; i <= num_options; i++, opt_ptr = opt_ptr->next) { if (i >= window_offset && i - window_offset < length) {#ifdef USE_SLANG SLsmg_gotorc(top + ((i + 1) - window_offset), (lx - 1 + 2)); SLsmg_write_nstring(opt_ptr->name, width);#else wmove(form_window, ((i + 1) - window_offset), 2); paddstr(form_window, width, opt_ptr->name);#endif /* USE_SLANG */ } }#ifdef USE_SLANG SLsmg_draw_box(top, (lx - 1), (bottom - top), (width + 4));#else#ifdef VMS VMSbox(form_window, (bottom - top), (width + 4));#else LYbox(form_window, TRUE);#endif /* VMS */ wrefresh(form_window);#endif /* USE_SLANG */ opt_ptr = NULL; /* * Loop on user input. */ while (cmd != LYK_ACTIVATE) { /* * Unreverse cur selection. */ if (opt_ptr != NULL) {#ifdef USE_SLANG SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); SLsmg_write_nstring(opt_ptr->name, width);#else wmove(form_window, ((i + 1) - window_offset), 2); paddstr(form_window, width, opt_ptr->name);#endif /* USE_SLANG */ } opt_ptr = list; for (i = 0; i < cur_selection; i++, opt_ptr = opt_ptr->next) ; /* null body */#ifdef USE_SLANG SLsmg_set_color(2); SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 2)); SLsmg_write_nstring(opt_ptr->name, width); SLsmg_set_color(0); /* * If LYShowCursor is ON, move the cursor to the left * of the current option, so that blind users, who are * most likely to have LYShowCursor ON, will have it's * string spoken or passed to the braille interface as * each option is made current. Otherwise, move it to * the bottom, right column of the screen, to "hide" * the cursor as for the main document, and let sighted * users rely on the current option's highlighting or * color without the distraction of a blinking cursor * in the window. - FM */ if (LYShowCursor) SLsmg_gotorc((top + ((i + 1) - window_offset)), (lx - 1 + 1)); else SLsmg_gotorc((LYlines - 1), (LYcols - 1)); SLsmg_refresh();#else wstart_reverse(form_window); wmove(form_window, ((i + 1) - window_offset), 2); paddstr(form_window, width, opt_ptr->name); wstop_reverse(form_window); /* * If LYShowCursor is ON, move the cursor to the left * of the current option, so that blind users, who are * most likely to have LYShowCursor ON, will have it's * string spoken or passed to the braille interface as * each option is made current. Otherwise, leave it to * the right of the current option, since we can't move * it out of the window, and let sighted users rely on * the highlighting of the current option without the * distraction of a blinking cursor preceding it. - FM */ if (LYShowCursor) wmove(form_window, ((i + 1) - window_offset), 1); wrefresh(form_window);#endif /* USE_SLANG */ c = LYgetch(); if (c == 3 || c == 7) /* Control-C or Control-G */ cmd = LYK_QUIT; else cmd = keymap[c+1];#ifdef VMS if (HadVMSInterrupt) { HadVMSInterrupt = FALSE; cmd = LYK_QUIT; }#endif /* VMS */ switch(cmd) { case LYK_F_LINK_NUM: c = '\0'; case LYK_1: case LYK_2: case LYK_3: case LYK_4: case LYK_5: case LYK_6: case LYK_7: case LYK_8: case LYK_9: /* * Get a number from the user, possibly with * a 'g' or 'p' suffix (which will be loaded * into c). - FM & LE */ number = get_popup_option_number((int *)&c); /* * Check for a 'p' suffix. - FM */ if (c == 'p') { /* * Treat 1 or less as the first page. - FM */ if (number <= 1) { if (window_offset == 0) { _statusline(ALREADY_AT_OPTION_BEGIN); sleep(MessageSecs); if (disabled) { _statusline(FORM_LINK_OPTION_LIST_UNM_MSG); } else { _statusline(FORM_LINK_OPTION_LIST_MESSAGE); } break; } window_offset = 0; cur_selection = 0; if (disabled) { _statusline(FORM_LINK_OPTION_LIST_UNM_MSG); } else { _statusline(FORM_LINK_OPTION_LIST_MESSAGE); } goto redraw; } /* * Treat a number equal to or greater than the * number of pages as the last page. - FM */ if (number >= npages) { if (window_offset >= ((num_options - length) + 1)) { _statusline(ALREADY_AT_OPTION_END); sleep(MessageSecs); if (disabled) { _statusline(FORM_LINK_OPTION_LIST_UNM_MSG); } else { _statusline(FORM_LINK_OPTION_LIST_MESSAGE); } break; } window_offset = ((npages - 1) * length); if (window_offset > (num_options - length)) { window_offset = (num_options - length + 1); } if (cur_selection < window_offset) cur_selection = window_offset; if (disabled) { _statusline(FORM_LINK_OPTION_LIST_UNM_MSG); } else { _statusline(FORM_LINK_OPTION_LIST_MESSAGE); } goto redraw; } /* * We want an intermediate page. - FM */ if (((number - 1) * length) == window_offset) { sprintf(buffer, ALREADY_AT_OPTION_PAGE, number); _statusline(buffer); sleep(MessageSecs); if (disabled) { _statusline(FORM_LINK_OPTION_LIST_UNM_MSG); } else { _statusline(FORM_LINK_OPTION_LIST_MESSAGE); } break; } cur_selection = window_offset = ((number - 1) * length); if (disabled) { _statusline(FORM_LINK_OPTION_LIST_UNM_MSG); } else { _statusline(FORM_LINK_OPTION_LIST_MESSAGE); } goto redraw; } /* * Check for a positive number, which signifies * that an option should be sought. - FM */ if (number > 0) { /* * Decrement the number so as to correspond * with our cur_selection values. - FM */ number--; /* * If the number is in range and had no legal * suffix, select the indicated option. - FM */ if (number <= num_options && c == '\0') { cur_selection = number; cmd = LYK_ACTIVATE; break; } /* * Verify that we had a 'g' suffix, * and act on the number. - FM */ if (c == 'g') { if (cur_selection == number) { /* * The option already is current. - FM */ sprintf(buffer, OPTION_ALREADY_CURRENT, (number + 1)); _statusline(buffer); sleep(MessageSecs); if (disabled) { _statusline(FORM_LINK_OPTION_LIST_UNM_MSG); } else { _statusline(FORM_LINK_OPTION_LIST_MESSAGE); } break; } if (number <= num_options) { /* * The number is in range and had a 'g' * suffix, so make it the current option, * scrolling if needed. - FM */ j = (number - cur_selection); cur_selection = number; if ((j > 0) && (cur_selection - window_offset) >= length) { window_offset += j; if (window_offset > (num_options - length + 1)) window_offset = (num_options - length + 1); } else if ((cur_selection - window_offset) < 0) { window_offset -= abs(j); if (window_offset < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -