X11 extended command selection

The expansion of the extended commands list to include every command
has made picking extended commands out of X11's menu become tedious.
This uses the existing 'extmenu' option (previously tty-only) to
control whether all the commands are present or just the traditional
subset not bound to non-meta keystrokes ('adjust', 'chat', 'loot', &c).
This commit is contained in:
PatR
2019-04-01 08:58:49 -07:00
parent cd12422af5
commit 0cad960428
5 changed files with 70 additions and 36 deletions

View File

@@ -1,6 +1,6 @@
Boolean options not under specific compile flags (with default values in []): Boolean options not under specific compile flags (with default values in []):
(You can learn which options exist in your version by checking your current (You can learn which options exist in your version by checking your current
option setting, which is reached via the 'O' cmd.) option setting, which is reached via the 'O' command.)
acoustics can your character hear anything [TRUE] acoustics can your character hear anything [TRUE]
autodescribe describe the terrain under cursor [FALSE] autodescribe describe the terrain under cursor [FALSE]
@@ -17,7 +17,8 @@ cmdassist give help for errors on direction & other commands [TRUE]
confirm ask before hitting tame or peaceful monsters [TRUE] confirm ask before hitting tame or peaceful monsters [TRUE]
dark_room show floor not in sight in different color [TRUE] dark_room show floor not in sight in different color [TRUE]
eight_bit_tty send 8-bit characters straight to terminal [FALSE] eight_bit_tty send 8-bit characters straight to terminal [FALSE]
extmenu use a menu for selecting extended commands (#) [FALSE] extmenu tty: use a menu for selecting extended commands (#)[FALSE]
X11: menu has all commands (T) or traditional subset (F)
fixinv try to retain the same letter for the same object [TRUE] fixinv try to retain the same letter for the same object [TRUE]
force_invmenu commands asking for inventory item show a menu [FALSE] force_invmenu commands asking for inventory item show a menu [FALSE]
goldX when filtering objects by bless/curse state, [FALSE] goldX when filtering objects by bless/curse state, [FALSE]

View File

@@ -1,4 +1,4 @@
.\" $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.302 $ $NHDT-Date: 1553858473 2019/03/29 11:21:13 $ .\" $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.303 $ $NHDT-Date: 1554134322 2019/04/01 15:58:42 $
.\" .\"
.\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" This is an excerpt from the 'roff' man page from the 'groff' package.
.\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines. .\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines.
@@ -2972,8 +2972,12 @@ Changes the extended commands interface to pop-up a menu of available
commands. commands.
It is keystroke compatible with the traditional interface except that it It is keystroke compatible with the traditional interface except that it
does not require that you hit \fIEnter\fP. does not require that you hit \fIEnter\fP.
It is implemented only by the tty port It is implemented for the tty interface (default off).
(default off), when the game has been compiled to support tty graphics. .lp ""
For the X11 interface, which always uses a menu for choosing an extended
command, it controls whether the menu shows all available commands (on)
or just the subset of commands which have traditionally been considered
extended ones (off).
.lp female .lp female
An obsolete synonym for \(lqgender:female\(rq. An obsolete synonym for \(lqgender:female\(rq.
Cannot be set with the \(oqO\(cq command. Cannot be set with the \(oqO\(cq command.

View File

@@ -3266,8 +3266,13 @@ Cannot be set with the `{\tt O}' command.
\item[\ib{extmenu}] \item[\ib{extmenu}]
Changes the extended commands interface to pop-up a menu of available commands. Changes the extended commands interface to pop-up a menu of available commands.
It is keystroke compatible with the traditional interface except that it does It is keystroke compatible with the traditional interface except that it does
not require that you hit Enter. It is implemented only by the tty port not require that you hit Enter.
(default off), when the game has been compiled to support tty graphics. It is implemented for the tty interface (default off).
.lp ""
For the X11 interface, which always uses a menu for choosing an extended
command, it controls whether the menu shows all available commands (on)
or just the subset of commands which have traditionally been considered
extended ones (off).
%.lp %.lp
\item[\ib{female}] \item[\ib{female}]
An obsolete synonym for ``{\tt gender:female}''. Cannot be set with the An obsolete synonym for ``{\tt gender:female}''. Cannot be set with the

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.294 $ $NHDT-Date: 1554071680 2019/03/31 22:34:40 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.295 $ $NHDT-Date: 1554134321 2019/04/01 15:58:41 $
This fixes36.2 file is here to capture information about updates in the 3.6.x This fixes36.2 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.1 in April 2018. Please note, however, lineage following the release of 3.6.1 in April 2018. Please note, however,
@@ -499,6 +499,8 @@ tty: when clipping was used to show a subset of the map on a small display,
X11: its use of genl_status_update exposed a negative index use that could X11: its use of genl_status_update exposed a negative index use that could
lead to a segfault lead to a segfault
X11: rollback disabling of keystroke input for PICK_NONE menus (for scrolling) X11: rollback disabling of keystroke input for PICK_NONE menus (for scrolling)
X11: make use of the 'extmenu' option: On to choose among all commands, Off
to choose among the traditional extended command subset
curses: catch up with tty to not put dolook/whatis autodescribe feedback into curses: catch up with tty to not put dolook/whatis autodescribe feedback into
^P message recall (multi-digit count feedback was already handled) ^P message recall (multi-digit count feedback was already handled)
curses: if the interface code ran out of memory, it would crash rather than curses: if the interface code ran out of memory, it would crash rather than

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 winmisc.c $NHDT-Date: 1543830350 2018/12/03 09:45:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.42 $ */ /* NetHack 3.6 winmisc.c $NHDT-Date: 1554134316 2019/04/01 15:58:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.43 $ */
/* Copyright (c) Dean Luick, 1992 */ /* Copyright (c) Dean Luick, 1992 */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -41,6 +41,8 @@
static Widget extended_command_popup = 0; static Widget extended_command_popup = 0;
static Widget extended_command_form; static Widget extended_command_form;
static Widget *extended_commands = 0; static Widget *extended_commands = 0;
static const char **command_list;
static short *command_indx;
static int extended_cmd_selected; /* index of the selected command; */ static int extended_cmd_selected; /* index of the selected command; */
static int ps_selected; /* index of selected role */ static int ps_selected; /* index of selected role */
#define PS_RANDOM (-50) #define PS_RANDOM (-50)
@@ -50,6 +52,7 @@ static const char ps_randchars[] = "*@\n\rrR";
static const char ps_quitchars[] = "\033qQ"; static const char ps_quitchars[] = "\033qQ";
#define EC_NCHARS 32 #define EC_NCHARS 32
static boolean ec_full_list = FALSE;
static boolean ec_active = FALSE; static boolean ec_active = FALSE;
static int ec_nchars = 0; static int ec_nchars = 0;
static char ec_chars[EC_NCHARS]; static char ec_chars[EC_NCHARS];
@@ -111,13 +114,14 @@ XtPointer
i2xtp(i) i2xtp(i)
int i; int i;
{ {
return (XtPointer)(long)i; return (XtPointer) (ptrdiff_t) i;
} }
int int
xtp2i(x) xtp2i(x)
XtPointer x; XtPointer x;
{ {
return (long)x; return (int) (ptrdiff_t) x;
} }
/* Player Selection ------------------------------------------------------- */ /* Player Selection ------------------------------------------------------- */
@@ -1581,9 +1585,16 @@ X11_player_selection()
} }
} }
/* called by core to have the player pick an extended command */
int int
X11_get_ext_cmd() X11_get_ext_cmd()
{ {
if (iflags.extmenu != ec_full_list) {
/* player has toggled the 'extmenu' option, toss the old widgets */
if (extended_commands)
release_extended_cmds(); /* will set extended_commands to Null */
ec_full_list = iflags.extmenu;
}
if (!extended_commands) if (!extended_commands)
init_extended_commands_popup(); init_extended_commands_popup();
@@ -1597,15 +1608,19 @@ X11_get_ext_cmd()
/* The callbacks will enable the event loop exit. */ /* The callbacks will enable the event loop exit. */
(void) x_event(EXIT_ON_EXIT); (void) x_event(EXIT_ON_EXIT);
return extended_cmd_selected; if (extended_cmd_selected < 0)
return -1;
return command_indx[extended_cmd_selected];
} }
void void
release_extended_cmds() release_extended_cmds()
{ {
if (extended_commands) { if (extended_commands) {
XtDestroyWidget(extended_command_popup); XtDestroyWidget(extended_command_popup), extended_command_popup = 0;
free((genericptr_t) extended_commands), extended_commands = 0; free((genericptr_t) extended_commands), extended_commands = 0;
free((genericptr_t) command_list), command_list = (const char **) 0;
free((genericptr_t) command_indx), command_indx = (short *) 0;
} }
} }
@@ -1816,6 +1831,22 @@ int ec_indx; /* might be greater than extended_cmd_selected */
} }
} }
/* decide whether extcmdlist[idx] should be part of extended commands menu */
static boolean
ignore_extcmd(idx)
int idx;
{
/* #shell or #suspect might not be available;
'extmenu' option controls whether we show full list
or just the traditional extended commands */
if ((extcmdlist[idx].flags & CMD_NOT_AVAILABLE) != 0
|| ((extcmdlist[idx].flags & AUTOCOMPLETE) == 0 && !ec_full_list)
|| strlen(extcmdlist[idx].ef_txt) < 2) /* ignore "#" and "?" */
return TRUE;
return FALSE;
}
/* ARGSUSED */ /* ARGSUSED */
void void
ec_key(w, event, params, num_params) ec_key(w, event, params, num_params)
@@ -1886,19 +1917,14 @@ Cardinal *num_params;
if (extended_cmd_selected >= 0) if (extended_cmd_selected >= 0)
swap_fg_bg(extended_commands[extended_cmd_selected]); swap_fg_bg(extended_commands[extended_cmd_selected]);
extended_cmd_selected = -1; /* dismiss */ extended_cmd_selected = -1; /* dismiss */
ec_chars[0] = ec_chars[ec_nchars-1]; ec_chars[0] = ec_chars[ec_nchars - 1];
ec_nchars = 1; ec_nchars = 1;
} }
for (i = 0; extcmdlist[i].ef_txt; i++) { for (i = 0; command_list[i]; ++i) {
if (extcmdlist[i].flags & CMD_NOT_AVAILABLE) if (!strncmp(ec_chars, command_list[i], ec_nchars)) {
continue;
if (extcmdlist[i].ef_txt[0] == '?')
continue;
if (!strncmp(ec_chars, extcmdlist[i].ef_txt, ec_nchars)) {
if (extended_cmd_selected != i) { if (extended_cmd_selected != i) {
/* I should use set() and unset() actions, but how do */ /* I should use set() and unset() actions, but how do
/* I send the an action to the widget? */ I send the an action to the widget? */
if (extended_cmd_selected >= 0) if (extended_cmd_selected >= 0)
swap_fg_bg(extended_commands[extended_cmd_selected]); swap_fg_bg(extended_commands[extended_cmd_selected]);
extended_cmd_selected = i; extended_cmd_selected = i;
@@ -1908,11 +1934,10 @@ Cardinal *num_params;
ambiguous choices, plus one to show thare aren't any ambiguous choices, plus one to show thare aren't any
more such, will scroll into view */ more such, will scroll into view */
do { do {
if (!extcmdlist[i + 1].ef_txt if (!command_list[i + 1])
|| *extcmdlist[i + 1].ef_txt == '?')
break; /* end of list */ break; /* end of list */
++i; ++i;
} while (!strncmp(ec_chars, extcmdlist[i].ef_txt, ec_nchars)); } while (!strncmp(ec_chars, command_list[i], ec_nchars));
ec_scroll_to_view(i); ec_scroll_to_view(i);
return; return;
@@ -1929,25 +1954,24 @@ static void
init_extended_commands_popup() init_extended_commands_popup()
{ {
int i, j, num_commands, ignore_cmds = 0; int i, j, num_commands, ignore_cmds = 0;
const char **command_list;
/* count commands */ /* count commands */
for (num_commands = 0; extcmdlist[num_commands].ef_txt; num_commands++) for (num_commands = 0; extcmdlist[num_commands].ef_txt; num_commands++)
if (extcmdlist[num_commands].flags & CMD_NOT_AVAILABLE) if (ignore_extcmd(num_commands))
++ignore_cmds; ++ignore_cmds;
/* If the last entry is "help", don't use it. */
if (strcmp(extcmdlist[num_commands - 1].ef_txt, "?") == 0)
--num_commands;
j = num_commands - ignore_cmds; j = num_commands - ignore_cmds;
command_list = (const char **) alloc((unsigned) j * sizeof (char *)); command_list = (const char **) alloc((unsigned) (j * sizeof (char *) + 1));
command_indx = (short *) alloc((unsigned) (j * sizeof (short) + 1));
for (i = j = 0; i < num_commands; i++) { for (i = j = 0; i < num_commands; i++) {
if (extcmdlist[i].flags & CMD_NOT_AVAILABLE) if (ignore_extcmd(i))
continue; continue;
command_indx[j] = (short) i;
command_list[j++] = extcmdlist[i].ef_txt; command_list[j++] = extcmdlist[i].ef_txt;
} }
command_list[j] = (char *) 0;
command_indx[j] = -1;
num_commands = j; num_commands = j;
extended_command_popup = extended_command_popup =
@@ -1955,8 +1979,6 @@ init_extended_commands_popup()
extended_command_translations, "dismiss", extend_dismiss, extended_command_translations, "dismiss", extend_dismiss,
"help", extend_help, num_commands, command_list, "help", extend_help, num_commands, command_list,
&extended_commands, extend_select, &extended_command_form); &extended_commands, extend_select, &extended_command_form);
free((char *) command_list);
} }
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */