TTY: Implement the menu_search command

When in a menu that allows selecting entries, press ':'
to enter any text. Entries that match the text (via pmatch)
will be toggled.
This commit is contained in:
Pasi Kallinen
2015-03-11 21:56:12 +02:00
parent a335f8306f
commit a46b7a3cf3
3 changed files with 67 additions and 22 deletions

View File

@@ -2104,7 +2104,7 @@ Implemented by the Amiga, Gem and tty ports.
Default '<'.
.lp menu_search
Menu character accelerator to search for a menu item.
Implemented by the Amiga, Gem and X11 ports.
Implemented by the Amiga, Gem, X11 and tty ports.
Default ':'.
.lp menu_select_all
Menu character accelerator to select all items in a menu.

View File

@@ -1097,6 +1097,7 @@ win32tty: support for 'selectsaved' option for menu of existing save files
to choose from at game startup
tty: add window port routines for saving/restoring message history
tty: enhanced role, race, &c selection at start of new game
tty: implement : (menu_search) command
smartphone: added "Type Cmd" command that allows to type arbitrary commands
using phone keypad
smartphone: added Q(quiver) command to "Attack" layout

View File

@@ -201,6 +201,7 @@ static const char default_menu_cmds[] = {
MENU_SELECT_PAGE,
MENU_UNSELECT_PAGE,
MENU_INVERT_PAGE,
MENU_SEARCH,
0 /* null terminator */
};
@@ -1228,6 +1229,42 @@ tty_clear_nhwindow(window)
cw->curx = cw->cury = 0;
}
boolean
toggle_menu_curr(window, curr, lineno, in_view, counting, count)
winid window;
tty_menu_item *curr;
int lineno;
boolean in_view, counting;
long count;
{
if (curr->selected) {
if (counting && count > 0) {
curr->count = count;
if (in_view) set_item_state(window, lineno, curr);
return TRUE;
} else { /* change state */
curr->selected = FALSE;
curr->count = -1L;
if (in_view) set_item_state(window, lineno, curr);
return TRUE;
}
} else { /* !selected */
if (counting && count > 0) {
curr->count = count;
curr->selected = TRUE;
if (in_view) set_item_state(window, lineno, curr);
return TRUE;
} else if (!counting) {
curr->selected = TRUE;
if (in_view) set_item_state(window, lineno, curr);
return TRUE;
}
/* do nothing counting&&count==0 */
}
return FALSE;
}
STATIC_OVL void
dmore(cw, s)
register struct WinDesc *cw;
@@ -1600,6 +1637,33 @@ struct WinDesc *cw;
if (cw->how == PICK_ANY)
invert_all(window, page_start, page_end, 0);
break;
case MENU_SEARCH:
if (cw->how == PICK_NONE) {
tty_nhbell();
break;
} else {
char searchbuf[BUFSZ], tmpbuf[BUFSZ];
boolean on_curr_page = FALSE;
int lineno = 0;
tty_getlin("Search for:", tmpbuf);
if (!tmpbuf || tmpbuf[0] == '\033') break;
Sprintf(searchbuf, "*%s*", tmpbuf);
for (curr = cw->mlist; curr; curr = curr->next) {
if (on_curr_page) lineno++;
if (curr == page_start)
on_curr_page = TRUE;
else if (curr == page_end)
on_curr_page = FALSE;
if (curr->identifier.a_void && pmatch(searchbuf, curr->str)) {
toggle_menu_curr(window, curr, lineno, on_curr_page, counting, count);
if (cw->how == PICK_ONE) {
finished = TRUE;
break;
}
}
}
}
break;
default:
if (cw->how == PICK_NONE || !index(resp, morc)) {
/* unacceptable input received */
@@ -1618,27 +1682,7 @@ struct WinDesc *cw;
curr != page_end;
n++, curr = curr->next)
if (morc == curr->selector) {
if (curr->selected) {
if (counting && count > 0) {
curr->count = count;
set_item_state(window, n, curr);
} else { /* change state */
curr->selected = FALSE;
curr->count = -1L;
set_item_state(window, n, curr);
}
} else { /* !selected */
if (counting && count > 0) {
curr->count = count;
curr->selected = TRUE;
set_item_state(window, n, curr);
} else if (!counting) {
curr->selected = TRUE;
set_item_state(window, n, curr);
}
/* do nothing counting&&count==0 */
}
toggle_menu_curr(window, curr, n, TRUE, counting, count);
if (cw->how == PICK_ONE) finished = TRUE;
break; /* from `for' loop */
}