From fa320a0a5f2cbe3721ce99a51bb8998f4f691338 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 7 Sep 2022 14:37:08 -0700 Subject: [PATCH] doset_simple() Move the guts of doset_simple() into a separate routine. Initially that was just to avoid having to increase indentation when replacing 'goto' with 'do { ... } until ()'. It ends up making the flow of control easier to see. doset() and doset_simple() each had their own static flag indicating whether 'fmtstr_doset' had been assigned a value. Redundant assignment produced the same value so it wasn't an actual problem. doset_simple() probably needs to add menu_tab_sep support for WinGUI. Qt is able to get by without it, but that's because it forces use of fixed-width font when any line in a menu or text window has 4 or more consecutive spaces. I don't think WinGUI does that. --- src/options.c | 185 ++++++++++++++++++++++++++------------------------ 1 file changed, 97 insertions(+), 88 deletions(-) diff --git a/src/options.c b/src/options.c index 004b46d7f..677b9916b 100644 --- a/src/options.c +++ b/src/options.c @@ -296,9 +296,9 @@ static boolean test_regex_pattern(const char *, const char *); static boolean add_menu_coloring_parsed(const char *, int, int); static void free_one_menu_coloring(int); static int count_menucolors(void); -static boolean parse_role_opts(int, boolean, const char *, - char *, char **); +static boolean parse_role_opts(int, boolean, const char *, char *, char **); static unsigned int longest_option_name(int, int); +static int doset_simple_menu(void); static void doset_add_menu(winid, const char *, int, int); static int handle_add_list_remove(const char *, int); static void all_options_menucolors(strbuf_t *); @@ -307,7 +307,8 @@ static void all_options_apes(strbuf_t *); static void remove_autopickup_exception(struct autopickup_exception *); static int count_apes(void); static int count_cond(void); -static void enhance_menu_text(char *, size_t, int, boolean *, struct allopt_t *); +static void enhance_menu_text(char *, size_t, int, boolean *, + struct allopt_t *); static int handler_align_misc(int); static int handler_autounlock(int); @@ -7756,6 +7757,8 @@ fruitadd(char *str, struct fruit *replace_fruit) #define OPTIONS_HEADING "NETHACKOPTIONS" #endif +/* [should be able to get away with not putting these in 'struct g'] */ +static boolean made_doset_fmtstr = FALSE; static char fmtstr_doset[] = "%s%-15s [%s] "; static char fmtstr_doset_tab[] = "%s\t[%s]"; static char n_currently_set[] = "(%d currently set)"; @@ -7960,35 +7963,19 @@ longest_option_name(int startpass, int endpass) return longest_name_len; } -/* #options - the user friendly version */ -int -doset_simple(void) +/* guts of doset_simple(); called repeatedly until no choice is made */ +static int +doset_simple_menu(void) { - static boolean made_fmtstr = FALSE; - char buf[BUFSZ]; - winid tmpwin; - anything any; menu_item *pick_list; - int i, pick_cnt, pick_idx; - enum OptSection section; boolean *bool_p; const char *name; + char buf[BUFSZ], buf2[BUFSZ], abuf[BUFSZ]; + winid tmpwin; + anything any; + enum OptSection section; + int i, k, pick_cnt, reslt; - if (iflags.menu_requested) { - /* doset() checks for 'm' and calls doset_simple(); clear the - menu-requested flag to avoid doing that recursively */ - iflags.menu_requested = FALSE; - return doset(); - } - - if (!made_fmtstr) { - Sprintf(fmtstr_doset, "%%s%%-%us [%%s]", - longest_option_name(set_gameview, set_in_game)); - made_fmtstr = TRUE; - } - - give_opt_msg = FALSE; - rerun: tmpwin = create_nhwindow(NHW_MENU); start_menu(tmpwin, MENU_BEHAVE_STANDARD); @@ -8021,12 +8008,7 @@ doset_simple(void) break; case CompOpt: case OthrOpt: - { - const char *value = "unknown"; - int reslt = optn_err; - char buf2[BUFSZ]; - int k = i; - + k = i; if (allopt[i].optfn == optfn_symset && Is_rogue_level(&u.uz)) { k = opt_roguesymset; @@ -8035,13 +8017,13 @@ doset_simple(void) } buf2[0] = '\0'; + reslt = optn_err; if (allopt[k].optfn) reslt = (*allopt[k].optfn)(allopt[k].idx, get_val, FALSE, buf2, empty_optstr); - if (reslt == optn_ok && buf2[0]) - value = (const char *) buf2; - Sprintf(buf, fmtstr_doset, "", name, value); - } + Sprintf(buf, fmtstr_doset, "", name, + ((reslt == optn_ok && buf2[0]) + ? (const char *) buf2 : "unknown")); break; default: Sprintf(buf, "ERROR"); @@ -8056,68 +8038,96 @@ doset_simple(void) ATR_NONE, 0, buf, MENU_ITEMFLAGS_NONE); } } - end_menu(tmpwin, "Options"); + g.opt_need_redraw = FALSE; g.opt_need_glyph_reset = FALSE; - if ((pick_cnt = select_menu(tmpwin, PICK_ONE, &pick_list)) > 0) { - for (pick_idx = 0; pick_idx < pick_cnt; ++pick_idx) { - int k = pick_list[pick_idx].item.a_int - 1; + pick_cnt = select_menu(tmpwin, PICK_ONE, &pick_list); + /* note: without the complication of a preselected entry, a PICK_ONE + menu returning pick_cnt > 0 implies exactly 1 */ + if (pick_cnt > 0) { + k = pick_list[0].item.a_int - 1; - if (allopt[k].opttyp == BoolOpt) { - /* boolean option */ - Sprintf(buf, "%s%s", *allopt[k].addr ? "!" : "", - allopt[k].name); - (void) parseoptions(buf, FALSE, FALSE); + if (allopt[k].opttyp == BoolOpt) { + /* boolean option */ + Sprintf(buf, "%s%s", *allopt[k].addr ? "!" : "", allopt[k].name); + (void) parseoptions(buf, FALSE, FALSE); + } else { + /* compound option */ + if (allopt[k].has_handler && allopt[k].optfn) { + reslt = (*allopt[k].optfn)(allopt[k].idx, do_handler, FALSE, + empty_optstr, empty_optstr); + /* + * FIXME: got_from_config[] is used to control the + * save-options routine but its name is misleading when + * options that have been set interactively are included. + */ + if (reslt == optn_ok) + got_from_config[k] = TRUE; } else { - /* compound option */ - int reslt UNUSED; + Sprintf(buf, "Set %s to what?", allopt[k].name); + abuf[0] = '\0'; /* suppress EDIT_GETLIN */ + getlin(buf, abuf); + if (abuf[0] == '\033') + return -1; - if (allopt[k].has_handler && allopt[k].optfn) { - reslt = (*allopt[k].optfn)(allopt[k].idx, do_handler, - FALSE, empty_optstr, - empty_optstr); - if (reslt == optn_ok) - got_from_config[k] = TRUE; - } else { - char abuf[BUFSZ]; - - Sprintf(buf, "Set %s to what?", allopt[k].name); - abuf[0] = '\0'; - getlin(buf, abuf); - if (abuf[0] == '\033') - continue; - Sprintf(buf, "%s:", allopt[k].name); - (void) strncat(eos(buf), abuf, - (sizeof buf - 1 - strlen(buf))); - /* pass the buck */ - (void) parseoptions(buf, FALSE, FALSE); - } + Sprintf(buf, "%s:", allopt[k].name); + copynchars(eos(buf), abuf, + (int) (sizeof buf - 1 - strlen(buf))); + /* pass the buck */ + (void) parseoptions(buf, FALSE, FALSE); } - if (wc_supported(allopt[k].name) - || wc2_supported(allopt[k].name)) - preference_update(allopt[k].name); } + if (wc_supported(allopt[k].name) || wc2_supported(allopt[k].name)) + preference_update(allopt[k].name); + free((genericptr_t) pick_list), pick_list = (menu_item *) 0; + + /* some option choices warrant immediate update before caller + calls us again */ + if (g.opt_need_glyph_reset) { + reset_glyphmap(gm_optionchange); + } + if (g.opt_need_redraw) { + check_gold_symbol(); + reglyph_darkroom(); + docrt(); + flush_screen(1); + } + if (g.context.botl || g.context.botlx) { + bot(); + } } + /* tear down this instance of the menu; if pick_cnt is 1, caller + will immediately call us back to put up another instance */ destroy_nhwindow(tmpwin); - if (g.opt_need_glyph_reset) { - reset_glyphmap(gm_optionchange); - } - if (g.opt_need_redraw) { - check_gold_symbol(); - reglyph_darkroom(); - docrt(); - flush_screen(1); - } - if (g.context.botl || g.context.botlx) { - bot(); + return pick_cnt; +} + +/* #options - the user friendly version: get one option from a subset of + the zillion choices, act upon it, and prompt for another */ +int +doset_simple(void) +{ + int pickedone = 0; + + if (iflags.menu_requested) { + /* doset() checks for 'm' and calls doset_simple(); clear the + menu-requested flag to avoid doing that recursively */ + iflags.menu_requested = FALSE; + return doset(); } - if (pick_cnt > 0) - goto rerun; - + if (!made_doset_fmtstr) { + Sprintf(fmtstr_doset, "%%s%%-%us [%%s]", + longest_option_name(set_gameview, set_in_game)); + made_doset_fmtstr = TRUE; + } + give_opt_msg = FALSE; + do { + pickedone = doset_simple_menu(); + } while (pickedone > 0); give_opt_msg = TRUE; return ECMD_OK; } @@ -8126,7 +8136,6 @@ doset_simple(void) int doset(void) /* changing options via menu by Per Liboriussen */ { - static boolean made_fmtstr = FALSE; char buf[BUFSZ]; const char *name; int i = 0, pass, pick_cnt, pick_idx, opt_indx; @@ -8188,10 +8197,10 @@ doset(void) /* changing options via menu by Per Liboriussen */ startpass = set_gameview; endpass = (wizard) ? set_wiznofuz : set_in_game; - if (!made_fmtstr && !iflags.menu_tab_sep) { + if (!made_doset_fmtstr && !iflags.menu_tab_sep) { Sprintf(fmtstr_doset, "%%s%%-%us [%%s]", longest_option_name(startpass, endpass)); - made_fmtstr = TRUE; + made_doset_fmtstr = TRUE; } indexoffset = 1;