relocate choose_classes_menu() to windows.c

choose_classes_menu was declared extern. The only caller presently
was calling it was optfn_pickup_types() in options.c.

It could have had the extern declaration from include/extern.h and
declare it as static within options.c, if that was the only use
anticipated. Also, if the one existing caller were all there would
ever be, the argument passed to it that was the subject of pr #1146
could have just been removed along with the switch.

Checking the comments above the function, however, it was clearly
designed as a general-purpose function that could be called from
anywhere for the functionality desired, even though there's presently
just the one caller, passing just the one variation of the category
argument.

Relocate the general-purpose function over to src/windows.c, where
several interface-related / menu-related general-purpose functions
already reside.

options.c has gotten *huge* and this is a fitting opportunity to
reduce its size a little.
This commit is contained in:
nhmall
2023-11-23 14:28:12 -05:00
parent fc5688cee8
commit fa4a47d8ff
3 changed files with 134 additions and 135 deletions

View File

@@ -2067,7 +2067,6 @@ extern void option_help(void);
extern void all_options_strbuf(strbuf_t *);
extern void next_opt(winid, const char *);
extern int fruitadd(char *, struct fruit *);
extern int choose_classes_menu(const char *, int, boolean, char *, char *);
extern boolean parsebindings(char *);
extern void oc_to_str(char *, char *);
extern void add_menu_cmd_alias(char, char);
@@ -3437,12 +3436,12 @@ extern void genl_display_file(const char *, boolean);
extern boolean menuitem_invert_test(int, unsigned, boolean);
extern const char *mixed_to_glyphinfo(const char *str, glyph_info *gip);
extern void adjust_menu_promptstyle(winid, color_attr *);
extern int choose_classes_menu(const char *, int, boolean, char *, char *);
extern void add_menu(winid, const glyph_info *, const ANY_P *,
char, char, int, int, const char *, unsigned int);
extern void add_menu_heading(winid, const char *);
extern void add_menu_str(winid, const char *);
extern int select_menu(winid, int, menu_item **);
extern void getlin(const char *, char *);
/* ### windows.c ### */

View File

@@ -9681,139 +9681,6 @@ next_opt(winid datawin, const char *str)
return;
}
/*
* This is a somewhat generic menu for taking a list of NetHack style
* class choices and presenting them via a description
* rather than the traditional NetHack characters.
* (Benefits users whose first exposure to NetHack is via tiles).
*
* prompt
* The title at the top of the menu.
*
* category: 0 = monster class
* 1 = object class
*
* way
* FALSE = PICK_ONE, TRUE = PICK_ANY
*
* class_list
* a null terminated string containing the list of choices.
*
* class_selection
* a null terminated string containing the selected characters.
*
* Returns number selected.
*/
int
choose_classes_menu(const char *prompt,
int category,
boolean way,
char *class_list,
char *class_select)
{
menu_item *pick_list = (menu_item *) 0;
winid win;
anything any;
char buf[BUFSZ];
const char *text = 0;
boolean selected;
int ret, i, n, next_accelerator, accelerator;
int clr = NO_COLOR;
if (!class_list || !class_select)
return 0;
accelerator = 0;
next_accelerator = 'a';
any = cg.zeroany;
win = create_nhwindow(NHW_MENU);
start_menu(win, MENU_BEHAVE_STANDARD);
while (*class_list) {
selected = FALSE;
switch (category) {
case 0:
text = def_monsyms[def_char_to_monclass(*class_list)].explain;
accelerator = *class_list;
Sprintf(buf, "%s", text);
break;
case 1:
text = def_oc_syms[def_char_to_objclass(*class_list)].explain;
accelerator = next_accelerator;
Sprintf(buf, "%c %s", *class_list, text);
break;
default:
panic("choose_classes_menu: invalid category %d", category);
/*NOTREACHED*/
}
if (way && *class_select) { /* Selections there already */
if (strchr(class_select, *class_list)) {
selected = TRUE;
}
}
any.a_int = *class_list;
add_menu(win, &nul_glyphinfo, &any, accelerator,
category ? *class_list : 0, ATR_NONE, clr, buf,
selected ? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE);
if (category > 0) {
if (next_accelerator == 'Z')
break;
else if (next_accelerator == 'z')
next_accelerator = 'A';
else
++next_accelerator;
}
++class_list;
}
if (category == 1 && next_accelerator <= 'z') {
/* for objects, add "A - ' ' all classes", after a separator */
add_menu_str(win, "");
any = cg.zeroany;
any.a_int = (int) ' ';
Sprintf(buf, "%c %s", (char) any.a_int, "all classes of objects");
/* we won't preselect this even if the incoming list is empty;
having it selected means that it would have to be explicitly
de-selected in order to select anything else */
add_menu(win, &nul_glyphinfo, &any, 'A', 0,
ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE);
if (!strcmp(prompt, "Autopickup what?")) {
Sprintf(buf, "%4s%c %s", " ", ' ',
"Note: when no choices are selected, \"all\" is implied.");
add_menu_str(win, buf);
if (flags.pickup) {
/* for 'O', "toggle" should be intuitive; for 'm O', it would
probably be better to say "Set 'autopickup' to false..." */
Sprintf(buf, "%4s%c %s", " ", ' ',
"Toggle off 'autopickup' to not pick up anything.");
add_menu_str(win, buf);
}
}
}
end_menu(win, prompt);
n = select_menu(win, way ? PICK_ANY : PICK_ONE, &pick_list);
destroy_nhwindow(win);
if (n > 0) {
if (category == 1) {
/* for object classes, first check for 'all'; it means 'use
a blank list' rather than 'collect every possible choice' */
for (i = 0; i < n; ++i)
if (pick_list[i].item.a_int == ' ') {
pick_list[0].item.a_int = ' ';
n = 1; /* return 1; also an implicit 'break;' */
}
}
for (i = 0; i < n; ++i)
*class_select++ = (char) pick_list[i].item.a_int;
free((genericptr_t) pick_list);
ret = n;
} else if (n == -1) {
class_select = eos(class_select);
ret = -1;
} else {
ret = 0;
}
*class_select = '\0';
return ret;
}
static struct wc_Opt wc_options[] = {
{ "ascii_map", WC_ASCII_MAP },
{ "color", WC_COLOR },

View File

@@ -1591,6 +1591,139 @@ mixed_to_glyphinfo(const char *str, glyph_info *gip)
return str;
}
/*
* This is a somewhat generic menu for taking a list of NetHack style
* class choices and presenting them via a description
* rather than the traditional NetHack characters.
* (Benefits users whose first exposure to NetHack is via tiles).
*
* prompt
* The title at the top of the menu.
*
* category: 0 = monster class
* 1 = object class
*
* way
* FALSE = PICK_ONE, TRUE = PICK_ANY
*
* class_list
* a null terminated string containing the list of choices.
*
* class_selection
* a null terminated string containing the selected characters.
*
* Returns number selected.
*/
int
choose_classes_menu(const char *prompt,
int category,
boolean way,
char *class_list,
char *class_select)
{
menu_item *pick_list = (menu_item *) 0;
winid win;
anything any;
char buf[BUFSZ];
const char *text = 0;
boolean selected;
int ret, i, n, next_accelerator, accelerator;
int clr = NO_COLOR;
if (!class_list || !class_select)
return 0;
accelerator = 0;
next_accelerator = 'a';
any = cg.zeroany;
win = create_nhwindow(NHW_MENU);
start_menu(win, MENU_BEHAVE_STANDARD);
while (*class_list) {
selected = FALSE;
switch (category) {
case 0:
text = def_monsyms[def_char_to_monclass(*class_list)].explain;
accelerator = *class_list;
Sprintf(buf, "%s", text);
break;
case 1:
text = def_oc_syms[def_char_to_objclass(*class_list)].explain;
accelerator = next_accelerator;
Sprintf(buf, "%c %s", *class_list, text);
break;
default:
panic("choose_classes_menu: invalid category %d", category);
/*NOTREACHED*/
}
if (way && *class_select) { /* Selections there already */
if (strchr(class_select, *class_list)) {
selected = TRUE;
}
}
any.a_int = *class_list;
add_menu(win, &nul_glyphinfo, &any, accelerator,
category ? *class_list : 0, ATR_NONE, clr, buf,
selected ? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE);
if (category > 0) {
if (next_accelerator == 'Z')
break;
else if (next_accelerator == 'z')
next_accelerator = 'A';
else
++next_accelerator;
}
++class_list;
}
if (category == 1 && next_accelerator <= 'z') {
/* for objects, add "A - ' ' all classes", after a separator */
add_menu_str(win, "");
any = cg.zeroany;
any.a_int = (int) ' ';
Sprintf(buf, "%c %s", (char) any.a_int, "all classes of objects");
/* we won't preselect this even if the incoming list is empty;
having it selected means that it would have to be explicitly
de-selected in order to select anything else */
add_menu(win, &nul_glyphinfo, &any, 'A', 0,
ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE);
if (!strcmp(prompt, "Autopickup what?")) {
Sprintf(buf, "%4s%c %s", " ", ' ',
"Note: when no choices are selected, \"all\" is implied.");
add_menu_str(win, buf);
if (flags.pickup) {
/* for 'O', "toggle" should be intuitive; for 'm O', it would
probably be better to say "Set 'autopickup' to false..." */
Sprintf(buf, "%4s%c %s", " ", ' ',
"Toggle off 'autopickup' to not pick up anything.");
add_menu_str(win, buf);
}
}
}
end_menu(win, prompt);
n = select_menu(win, way ? PICK_ANY : PICK_ONE, &pick_list);
destroy_nhwindow(win);
if (n > 0) {
if (category == 1) {
/* for object classes, first check for 'all'; it means 'use
a blank list' rather than 'collect every possible choice' */
for (i = 0; i < n; ++i)
if (pick_list[i].item.a_int == ' ') {
pick_list[0].item.a_int = ' ';
n = 1; /* return 1; also an implicit 'break;' */
}
}
for (i = 0; i < n; ++i)
*class_select++ = (char) pick_list[i].item.a_int;
free((genericptr_t) pick_list);
ret = n;
} else if (n == -1) {
class_select = eos(class_select);
ret = -1;
} else {
ret = 0;
}
*class_select = '\0';
return ret;
}
/* enum and structs are defined in wintype.h */
win_request_info zerowri = { { 0L, 0, 0, 0, 0, 0, 0, 0 },