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:
@@ -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 ### */
|
||||
|
||||
133
src/options.c
133
src/options.c
@@ -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 },
|
||||
|
||||
133
src/windows.c
133
src/windows.c
@@ -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 },
|
||||
|
||||
Reference in New Issue
Block a user