fix github issue #193 - curses: menu search
Fixes #193 Under curses interface, make characters which are both entry selectors and menu commands function as a selector. Needed to support using ':' to look inside a container when applying/looting it via menu, instead of performing a menu search operation. (There was another case like this but I can't remember what the circumstances are. The fix is general enough to cover it, whatever it is.) For menus which don't have ':' as a choice, make sure search prompt doesn't offer garbage default input when built with EDIT_GETLIN. Bug? If player has 'popup_dialog' option On, EDIT_GETLIN is ignored. Plain curses I/O doesn't seem to offer a way to implement it.
This commit is contained in:
@@ -97,7 +97,8 @@ static char menu_get_accel(boolean first);
|
||||
static void menu_determine_pages(nhmenu *menu);
|
||||
static boolean menu_is_multipage(nhmenu *menu, int width, int height);
|
||||
static void menu_win_size(nhmenu *menu);
|
||||
static void menu_display_page(nhmenu *menu, WINDOW * win, int page_num);
|
||||
static void menu_display_page(nhmenu *menu, WINDOW * win, int page_num,
|
||||
char *);
|
||||
static int menu_get_selections(WINDOW * win, nhmenu *menu, int how);
|
||||
static void menu_select_deselect(WINDOW * win, nhmenu_item *item,
|
||||
menu_op operation);
|
||||
@@ -116,7 +117,7 @@ static nhmenu *nhmenus = NULL; /* NetHack menu array */
|
||||
|
||||
|
||||
/* Get a line of text from the player, such as asking for a character name
|
||||
or a wish */
|
||||
or a wish. Note: EDIT_GETLIN not supported for popup prompting. */
|
||||
|
||||
void
|
||||
curses_line_input_dialog(const char *prompt, char *answer, int buffer)
|
||||
@@ -133,8 +134,8 @@ curses_line_input_dialog(const char *prompt, char *answer, int buffer)
|
||||
re-activate them now that input is being requested */
|
||||
curses_got_input();
|
||||
|
||||
if (buffer >= (int) sizeof input)
|
||||
buffer = (int) sizeof input - 1;
|
||||
if (buffer > (int) sizeof input)
|
||||
buffer = (int) sizeof input;
|
||||
maxwidth = term_cols - 2;
|
||||
|
||||
if (iflags.window_inited) {
|
||||
@@ -1059,7 +1060,7 @@ menu_win_size(nhmenu *menu)
|
||||
/* Displays menu selections in the given window */
|
||||
|
||||
static void
|
||||
menu_display_page(nhmenu *menu, WINDOW * win, int page_num)
|
||||
menu_display_page(nhmenu *menu, WINDOW * win, int page_num, char *selectors)
|
||||
{
|
||||
nhmenu_item *menu_item_ptr;
|
||||
int count, curletter, entry_cols, start_col, num_lines;
|
||||
@@ -1068,6 +1069,10 @@ menu_display_page(nhmenu *menu, WINDOW * win, int page_num)
|
||||
int color = NO_COLOR, attr = A_NORMAL;
|
||||
boolean menu_color = FALSE;
|
||||
|
||||
/* letters assigned to entries on current page */
|
||||
if (selectors)
|
||||
(void) memset((genericptr_t) selectors, 0, 256);
|
||||
|
||||
/* Cycle through entries until we are on the correct page */
|
||||
|
||||
menu_item_ptr = menu->entries;
|
||||
@@ -1117,6 +1122,9 @@ menu_display_page(nhmenu *menu, WINDOW * win, int page_num)
|
||||
}
|
||||
menu_item_ptr->accelerator = curletter;
|
||||
}
|
||||
/* we have a selector letter; tell caller about it */
|
||||
if (selectors)
|
||||
selectors[(unsigned) (curletter & 0xFF)]++;
|
||||
|
||||
if (menu_item_ptr->selected) {
|
||||
curses_toggle_color_attr(win, HIGHLIGHT_COLOR, A_REVERSE, ON);
|
||||
@@ -1222,10 +1230,10 @@ menu_get_selections(WINDOW * win, nhmenu *menu, int how)
|
||||
int curpage = !menu->bottom_heavy ? 1 : menu->num_pages;
|
||||
int num_selected = 0;
|
||||
boolean dismiss = FALSE;
|
||||
char search_key[BUFSZ];
|
||||
char search_key[BUFSZ], selectors[256];
|
||||
nhmenu_item *menu_item_ptr = menu->entries;
|
||||
|
||||
menu_display_page(menu, win, curpage);
|
||||
menu_display_page(menu, win, curpage, selectors);
|
||||
|
||||
while (!dismiss) {
|
||||
curletter = getch();
|
||||
@@ -1253,25 +1261,27 @@ menu_get_selections(WINDOW * win, nhmenu *menu, int how)
|
||||
}
|
||||
break;
|
||||
case PICK_ANY:
|
||||
switch (curletter) {
|
||||
case MENU_SELECT_PAGE:
|
||||
(void) menu_operation(win, menu, SELECT, curpage);
|
||||
break;
|
||||
case MENU_SELECT_ALL:
|
||||
curpage = menu_operation(win, menu, SELECT, 0);
|
||||
break;
|
||||
case MENU_UNSELECT_PAGE:
|
||||
(void) menu_operation(win, menu, DESELECT, curpage);
|
||||
break;
|
||||
case MENU_UNSELECT_ALL:
|
||||
curpage = menu_operation(win, menu, DESELECT, 0);
|
||||
break;
|
||||
case MENU_INVERT_PAGE:
|
||||
(void) menu_operation(win, menu, INVERT, curpage);
|
||||
break;
|
||||
case MENU_INVERT_ALL:
|
||||
curpage = menu_operation(win, menu, INVERT, 0);
|
||||
break;
|
||||
if (curletter <= 0 || curletter >= 256 || !selectors[curletter]) {
|
||||
switch (curletter) {
|
||||
case MENU_SELECT_PAGE:
|
||||
(void) menu_operation(win, menu, SELECT, curpage);
|
||||
break;
|
||||
case MENU_SELECT_ALL:
|
||||
curpage = menu_operation(win, menu, SELECT, 0);
|
||||
break;
|
||||
case MENU_UNSELECT_PAGE:
|
||||
(void) menu_operation(win, menu, DESELECT, curpage);
|
||||
break;
|
||||
case MENU_UNSELECT_ALL:
|
||||
curpage = menu_operation(win, menu, DESELECT, 0);
|
||||
break;
|
||||
case MENU_INVERT_PAGE:
|
||||
(void) menu_operation(win, menu, INVERT, curpage);
|
||||
break;
|
||||
case MENU_INVERT_ALL:
|
||||
curpage = menu_operation(win, menu, INVERT, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*FALLTHRU*/
|
||||
default:
|
||||
@@ -1286,86 +1296,88 @@ menu_get_selections(WINDOW * win, nhmenu *menu, int how)
|
||||
}
|
||||
}
|
||||
|
||||
switch (curletter) {
|
||||
case KEY_ESC:
|
||||
num_selected = -1;
|
||||
dismiss = TRUE;
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
dismiss = TRUE;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
case KEY_NPAGE:
|
||||
case MENU_NEXT_PAGE:
|
||||
case ' ':
|
||||
if (curpage < menu->num_pages) {
|
||||
curpage++;
|
||||
menu_display_page(menu, win, curpage);
|
||||
} else if (curletter == ' ') {
|
||||
if (curletter <= 0 || curletter >= 256 || !selectors[curletter]) {
|
||||
switch (curletter) {
|
||||
case KEY_ESC:
|
||||
num_selected = -1;
|
||||
dismiss = TRUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
case KEY_PPAGE:
|
||||
case MENU_PREVIOUS_PAGE:
|
||||
if (curpage > 1) {
|
||||
curpage--;
|
||||
menu_display_page(menu, win, curpage);
|
||||
}
|
||||
break;
|
||||
case KEY_END:
|
||||
case MENU_LAST_PAGE:
|
||||
if (curpage != menu->num_pages) {
|
||||
curpage = menu->num_pages;
|
||||
menu_display_page(menu, win, curpage);
|
||||
}
|
||||
break;
|
||||
case KEY_HOME:
|
||||
case MENU_FIRST_PAGE:
|
||||
if (curpage != 1) {
|
||||
curpage = 1;
|
||||
menu_display_page(menu, win, curpage);
|
||||
}
|
||||
break;
|
||||
case MENU_SEARCH:
|
||||
curses_line_input_dialog("Search for:", search_key, BUFSZ);
|
||||
|
||||
refresh();
|
||||
touchwin(win);
|
||||
wrefresh(win);
|
||||
|
||||
if (!*search_key) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
dismiss = TRUE;
|
||||
break;
|
||||
}
|
||||
case KEY_RIGHT:
|
||||
case KEY_NPAGE:
|
||||
case MENU_NEXT_PAGE:
|
||||
case ' ':
|
||||
if (curpage < menu->num_pages) {
|
||||
curpage++;
|
||||
menu_display_page(menu, win, curpage, selectors);
|
||||
} else if (curletter == ' ') {
|
||||
dismiss = TRUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KEY_LEFT:
|
||||
case KEY_PPAGE:
|
||||
case MENU_PREVIOUS_PAGE:
|
||||
if (curpage > 1) {
|
||||
curpage--;
|
||||
menu_display_page(menu, win, curpage, selectors);
|
||||
}
|
||||
break;
|
||||
case KEY_END:
|
||||
case MENU_LAST_PAGE:
|
||||
if (curpage != menu->num_pages) {
|
||||
curpage = menu->num_pages;
|
||||
menu_display_page(menu, win, curpage, selectors);
|
||||
}
|
||||
break;
|
||||
case KEY_HOME:
|
||||
case MENU_FIRST_PAGE:
|
||||
if (curpage != 1) {
|
||||
curpage = 1;
|
||||
menu_display_page(menu, win, curpage, selectors);
|
||||
}
|
||||
break;
|
||||
case MENU_SEARCH:
|
||||
search_key[0] = '\0';
|
||||
curses_line_input_dialog("Search for:", search_key, BUFSZ);
|
||||
|
||||
menu_item_ptr = menu->entries;
|
||||
refresh();
|
||||
touchwin(win);
|
||||
wrefresh(win);
|
||||
|
||||
while (menu_item_ptr != NULL) {
|
||||
if (menu_item_ptr->identifier.a_void != NULL
|
||||
&& strstri(menu_item_ptr->str, search_key)) {
|
||||
if (how == PICK_ONE) {
|
||||
menu_clear_selections(menu);
|
||||
menu_select_deselect(win, menu_item_ptr, SELECT);
|
||||
num_selected = 1;
|
||||
dismiss = TRUE;
|
||||
break;
|
||||
} else {
|
||||
menu_select_deselect(win, menu_item_ptr, INVERT);
|
||||
if (!*search_key)
|
||||
break;
|
||||
|
||||
menu_item_ptr = menu->entries;
|
||||
|
||||
while (menu_item_ptr != NULL) {
|
||||
if (menu_item_ptr->identifier.a_void != NULL
|
||||
&& strstri(menu_item_ptr->str, search_key)) {
|
||||
if (how == PICK_ONE) {
|
||||
menu_clear_selections(menu);
|
||||
menu_select_deselect(win, menu_item_ptr, SELECT);
|
||||
num_selected = 1;
|
||||
dismiss = TRUE;
|
||||
break;
|
||||
} else {
|
||||
menu_select_deselect(win, menu_item_ptr, INVERT);
|
||||
}
|
||||
}
|
||||
|
||||
menu_item_ptr = menu_item_ptr->next_item;
|
||||
}
|
||||
|
||||
menu_item_ptr = menu_item_ptr->next_item;
|
||||
}
|
||||
|
||||
menu_item_ptr = menu->entries;
|
||||
break;
|
||||
default:
|
||||
if (how == PICK_NONE) {
|
||||
num_selected = 0;
|
||||
dismiss = TRUE;
|
||||
menu_item_ptr = menu->entries;
|
||||
break;
|
||||
default:
|
||||
if (how == PICK_NONE) {
|
||||
num_selected = 0;
|
||||
dismiss = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1379,7 +1391,7 @@ menu_get_selections(WINDOW * win, nhmenu *menu, int how)
|
||||
&& curletter == menu_item_ptr->group_accel)) {
|
||||
if (curpage != menu_item_ptr->page_num) {
|
||||
curpage = menu_item_ptr->page_num;
|
||||
menu_display_page(menu, win, curpage);
|
||||
menu_display_page(menu, win, curpage, selectors);
|
||||
}
|
||||
|
||||
if (how == PICK_ONE) {
|
||||
@@ -1479,7 +1491,7 @@ menu_operation(WINDOW * win, nhmenu *menu, menu_op
|
||||
current_page = first_page;
|
||||
|
||||
if (page_num == 0) {
|
||||
menu_display_page(menu, win, current_page);
|
||||
menu_display_page(menu, win, current_page, (char *) 0);
|
||||
}
|
||||
|
||||
if (menu_item_ptr == NULL) { /* Page not found */
|
||||
@@ -1494,7 +1506,7 @@ menu_operation(WINDOW * win, nhmenu *menu, menu_op
|
||||
}
|
||||
|
||||
current_page = menu_item_ptr->page_num;
|
||||
menu_display_page(menu, win, current_page);
|
||||
menu_display_page(menu, win, current_page, (char *) 0);
|
||||
}
|
||||
|
||||
if (menu_item_ptr->identifier.a_void != NULL) {
|
||||
|
||||
@@ -202,6 +202,7 @@ curses_player_selection()
|
||||
void
|
||||
curses_askname()
|
||||
{
|
||||
plname[0] = '\0';
|
||||
curses_line_input_dialog("Who are you?", plname, PL_NSIZ);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user