Remove explicit 'none' opt from autounlock handler

The autounlock handler included an explicit 'none' option, a choice that
gave it a different UX from similar existing compound option handlers
(e.g. paranoid_confirm or pickup_types), which set 'none' simply by
deselecting all options.  It didn't make the menu any easier to use (at
least in my experience), since in order to go from some combination of
options to 'none', you'd have to deselect everything anyway (which on
its own was enough to set 'none', so there was no reason to explicitly
select it after doing so).

Make the autounlock handler work like other compound option handlers,
such that deselecting all options is the way to set 'none', and there is
no explicit 'none' option included in the list.
This commit is contained in:
Michael Meyer
2022-10-07 12:39:18 -04:00
committed by PatR
parent e5a99e8ad8
commit b02e018225

View File

@@ -193,7 +193,6 @@ static NEARDATA const char *msgwind[][3] = { /* 'msg_window' settings */
#endif #endif
/* autounlock settings */ /* autounlock settings */
static NEARDATA const char *unlocktypes[][2] = { static NEARDATA const char *unlocktypes[][2] = {
{ "none", "" },
{ "untrap", "(might fail)" }, { "untrap", "(might fail)" },
{ "apply-key", "" }, { "apply-key", "" },
{ "kick", "(doors only)" }, { "kick", "(doors only)" },
@@ -782,8 +781,10 @@ optfn_autounlock(
op = trimspaces(op); /* might have trailing space after op = trimspaces(op); /* might have trailing space after
* plus sign removal */ * plus sign removal */
} }
for (i = 0; i < SIZE(unlocktypes); ++i) if (str_start_is("none", op, TRUE))
if (!strncmpi(op, unlocktypes[i][0], Strlen(op)) negated = TRUE;
for (i = 0; i < SIZE(unlocktypes); ++i) {
if (str_start_is(unlocktypes[i][0], op, TRUE)
/* fuzzymatch() doesn't match leading substrings but /* fuzzymatch() doesn't match leading substrings but
this allows "apply_key" and "applykey" to match this allows "apply_key" and "applykey" to match
"apply-key"; "apply key" too if part of foo+bar */ "apply-key"; "apply key" too if part of foo+bar */
@@ -810,6 +811,7 @@ optfn_autounlock(
return optn_silenterr; return optn_silenterr;
} }
} }
}
op = nxt; op = nxt;
} }
if (negated && newflags != 0) { if (negated && newflags != 0) {
@@ -832,13 +834,13 @@ optfn_autounlock(
*opts = '\0'; *opts = '\0';
if (flags.autounlock & AUTOUNLOCK_UNTRAP) if (flags.autounlock & AUTOUNLOCK_UNTRAP)
Sprintf(eos(opts), "%s%s", p, unlocktypes[1][0]), p = plus; Sprintf(eos(opts), "%s%s", p, unlocktypes[0][0]), p = plus;
if (flags.autounlock & AUTOUNLOCK_APPLY_KEY) if (flags.autounlock & AUTOUNLOCK_APPLY_KEY)
Sprintf(eos(opts), "%s%s", p, unlocktypes[2][0]), p = plus; Sprintf(eos(opts), "%s%s", p, unlocktypes[1][0]), p = plus;
if (flags.autounlock & AUTOUNLOCK_KICK) if (flags.autounlock & AUTOUNLOCK_KICK)
Sprintf(eos(opts), "%s%s", p, unlocktypes[3][0]), p = plus; Sprintf(eos(opts), "%s%s", p, unlocktypes[2][0]), p = plus;
if (flags.autounlock & AUTOUNLOCK_FORCE) if (flags.autounlock & AUTOUNLOCK_FORCE)
Sprintf(eos(opts), "%s%s", p, unlocktypes[4][0]); /*no more p*/ Sprintf(eos(opts), "%s%s", p, unlocktypes[3][0]); /*no more p*/
} }
return optn_ok; return optn_ok;
} }
@@ -4856,38 +4858,21 @@ handler_autounlock(int optidx)
for (i = 0; i < SIZE(unlocktypes); ++i) { for (i = 0; i < SIZE(unlocktypes); ++i) {
Sprintf(buf, "%-10.10s%c%.40s", Sprintf(buf, "%-10.10s%c%.40s",
unlocktypes[i][0], sep, unlocktypes[i][1]); unlocktypes[i][0], sep, unlocktypes[i][1]);
presel = !i ? !flags.autounlock : (flags.autounlock & (1 << (i - 1))); presel = (flags.autounlock & (1 << i));
any.a_int = i + 1; any.a_int = i + 1;
add_menu(tmpwin, &nul_glyphinfo, &any, *unlocktypes[i][0], 0, add_menu(tmpwin, &nul_glyphinfo, &any, *unlocktypes[i][0], 0,
ATR_NONE, clr, buf, ATR_NONE, clr, buf,
((presel ? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE) (presel ? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE));
| (!i ? MENU_ITEMFLAGS_SKIPINVERT : 0)));
} }
Sprintf(buf, "Select '%.20s' actions:", optname); Sprintf(buf, "Select '%.20s' actions:", optname);
end_menu(tmpwin, buf); end_menu(tmpwin, buf);
n = select_menu(tmpwin, PICK_ANY, &window_pick); n = select_menu(tmpwin, PICK_ANY, &window_pick);
if (n > 0) { if (n > 0) {
int k; unsigned newflags = 0;
boolean wasnone = !flags.autounlock;
unsigned newflags = 0, noflags = 0;
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i)
k = window_pick[i].item.a_int - 1; newflags |= (1 << (window_pick[i].item.a_int - 1));
if (k) flags.autounlock = newflags;
newflags |= (1 << (k - 1));
else
noflags = 1;
}
/* wasnone: 'none' is preselected;
!wasnone: don't force it to be unselected */
if (newflags && noflags && !wasnone) {
config_error_add(
"Invalid value combination for \"%s\": 'none' with some",
optname);
res = optn_silenterr;
} else {
flags.autounlock = newflags;
}
free((genericptr_t) window_pick); free((genericptr_t) window_pick);
} else if (n == 0) { /* nothing was picked but menu wasn't cancelled */ } else if (n == 0) { /* nothing was picked but menu wasn't cancelled */
/* something that was preselected got unselected, leaving nothing; /* something that was preselected got unselected, leaving nothing;