From a034e8200c802355bd2c16e2f13acb5dea13c1d2 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 23 Dec 2019 21:44:34 -0500 Subject: [PATCH] centralize the invert decision logic to avoid updates to 7 ports This will make it easier to tinker for best results. --- include/extern.h | 1 + include/flag.h | 2 ++ src/mapglyph.c | 22 ++++++++++++++++++++++ src/options.c | 23 ++++++++++++++++++++++- win/Qt/qt_menu.cpp | 3 ++- win/X11/winmenu.c | 2 +- win/curses/cursdial.c | 3 ++- win/gem/wingem1.c | 3 ++- win/tty/wintty.c | 6 +++--- win/win32/mhmenu.c | 6 ++++-- 10 files changed, 61 insertions(+), 10 deletions(-) diff --git a/include/extern.h b/include/extern.h index 8c5a2cbd2..2d7947e62 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1217,6 +1217,7 @@ E int FDECL(mapglyph, (int, int *, int *, unsigned *, int, int, unsigned)); E char *FDECL(encglyph, (int)); E char *FDECL(decode_mixed, (char *, const char *)); E void FDECL(genl_putmixed, (winid, int, const char *)); +E boolean FDECL(menuitem_invert_test, (int, unsigned, BOOLEAN_P)); /* ### mcastu.c ### */ diff --git a/include/flag.h b/include/flag.h index e1091a562..446f15e5d 100644 --- a/include/flag.h +++ b/include/flag.h @@ -243,6 +243,8 @@ struct instance_flags { */ unsigned msg_history; /* hint: # of top lines to save */ int getpos_coords; /* show coordinates when getting cursor position */ + int menuinvertmode; /* 0 = invert toggles every item; + 1 = invert skips 'all items' item */ int menu_headings; /* ATR for menu headings */ int *opt_booldup; /* for duplication of boolean opts in config file */ int *opt_compdup; /* for duplication of compound opts in conf file */ diff --git a/src/mapglyph.c b/src/mapglyph.c index 74492cc74..59d01010b 100644 --- a/src/mapglyph.c +++ b/src/mapglyph.c @@ -438,4 +438,26 @@ const char *str; putstr(window, attr, decode_mixed(buf, str)); } +/* + * Window port helper function for menu invert routines to move the decision + * logic into one place instead of 7 different window-port routines. + */ +boolean +menuitem_invert_test(mode, itemflags, is_selected) +int mode; +unsigned itemflags; /* The itemflags for the item */ +boolean is_selected; /* The current selection status of the item */ +{ + boolean skipinvert = (itemflags & MENU_ITEMFLAGS_SKIPINVERT) != 0; + + if ((iflags.menuinvertmode == 1 || iflags.menuinvertmode == 2) + && !mode && skipinvert && !is_selected) + return FALSE; + else if (iflags.menuinvertmode == 2 + && !mode && skipinvert && is_selected) + return TRUE; + else + return TRUE; +} + /*mapglyph.c*/ diff --git a/src/options.c b/src/options.c index df5add42d..253ec29fa 100644 --- a/src/options.c +++ b/src/options.c @@ -311,6 +311,7 @@ static struct Comp_Opt { { "horsename", "the name of your (first) horse (e.g., horsename:Silver)", PL_PSIZ, DISP_IN_GAME }, { "map_mode", "map display mode under Windows", 20, DISP_IN_GAME }, /*WC*/ + { "menuinvertmode", "behaviour of menu iverts", 5, SET_IN_GAME }, { "menustyle", "user interface for object selection", MENUTYPELEN, SET_IN_GAME }, { "menu_deselect_all", "deselect all items in a menu", 4, SET_IN_FILE }, @@ -2362,6 +2363,24 @@ boolean tinitial, tfrom_file; return retval; } + /* menuinvertmode=0 or 1 or 2 (2 is experimental) */ + fullname = "menuinvertmode"; + if (match_optname(opts, fullname, 5, TRUE)) { + if (negated) { + bad_negation(fullname, FALSE); + return FALSE; + } else { + int mode = atoi(op); + + if (mode < 0 || mode > 2) { + config_error_add("Illegal %s parameter '%s'", fullname, op); + return FALSE; + } + iflags.menuinvertmode = mode; + } + return retval; + } + fullname = "msghistory"; if (match_optname(opts, fullname, 3, TRUE)) { if (duplicate) @@ -5614,7 +5633,9 @@ char *buf; : (i == MAP_MODE_ASCII_FIT_TO_SCREEN) ? "fit_to_screen" : defopt); - } else if (!strcmp(optname, "menustyle")) + } else if (!strcmp(optname, "menuinvertmode")) + Sprintf(buf, "%d", iflags.menuinvertmode); + else if (!strcmp(optname, "menustyle")) Sprintf(buf, "%s", menutype[(int) flags.menu_style]); else if (!strcmp(optname, "menu_deselect_all")) Sprintf(buf, "%s", to_be_done); diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 8be6abaaf..b959ad5d0 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -534,7 +534,8 @@ void NetHackQtMenuWindow::Invert() return; for (int i=0; iitem(i, 0); diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index 36f60829c..9d0e8a4a7 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -543,7 +543,7 @@ struct xwindow *wp; reset_menu_count(wp->menu_information); for (count = 0, curr = wp->menu_information->curr_menu.base; curr; curr = curr->next, count++) { - if ((curr->itemflags & MENU_ITEMFLAGS_SKIPINVERT) != 0) + if (!menuitem_invert_test(0, curr->itemflags, curr->selected)) continue; if (curr->identifier.a_void != 0) invert_line(wp, curr, count, -1L); diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index a33ef530b..e18ccdc57 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -1553,7 +1553,8 @@ menu_operation(WINDOW * win, nhmenu *menu, menu_op if (menu_item_ptr->identifier.a_void != NULL) { if (operation != INVERT - || (menu_item_ptr->itemflags & MENU_ITEMFLAGS_SKIPINVERT) == 0) + || menuitem_invert_test(0, menu_item_ptr->itemflags, + menu_item_ptr->selected)) menu_select_deselect(win, menu_item_ptr, operation, current_page); } diff --git a/win/gem/wingem1.c b/win/gem/wingem1.c index e25e60ae3..ecf979a1d 100644 --- a/win/gem/wingem1.c +++ b/win/gem/wingem1.c @@ -1784,8 +1784,9 @@ char acc; for (curr = invent_list; start-- && curr; curr = curr->Gmi_next) ; for (; page-- && curr; curr = curr->Gmi_next) { - if ((curr->Gmi_itemflags & MENU_ITEMFLAGS_SKIPINVERT) != 0) + if (!menuitem_invert_test(0, curr->Gmi_itemflags, curr->Gmi_selected) continue; + if (curr->Gmi_identifier && (acc == 0 || curr->Gmi_groupacc == acc)) { if (curr->Gmi_selected) { curr->Gmi_selected = FALSE; diff --git a/win/tty/wintty.c b/win/tty/wintty.c index aaba49f41..0fbe47648 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1774,7 +1774,7 @@ char acc; /* group accelerator, 0 => all */ int n; for (n = 0, curr = page_start; curr != page_end; n++, curr = curr->next) { - if ((curr->itemflags & MENU_ITEMFLAGS_SKIPINVERT) != 0) + if (!menuitem_invert_test(0, curr->itemflags, curr->selected)) continue; if (curr->identifier.a_void && (acc == 0 || curr->gselector == acc)) { @@ -1812,12 +1812,12 @@ char acc; /* group accelerator, 0 => all */ if (!on_curr_page && curr->identifier.a_void && (acc == 0 || curr->gselector == acc)) { - if ((curr->itemflags & MENU_ITEMFLAGS_SKIPINVERT) == 0) { + if (menuitem_invert_test(0, curr->itemflags, curr->selected)) { if (curr->selected) { curr->selected = FALSE; curr->count = -1; } else - curr->selected = TRUE; + curr->selected = TRUE; } } } diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index ab76d41ad..0150e559c 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -1306,7 +1306,8 @@ onListChar(HWND hWnd, HWND hwndList, WORD ch) if (data->how == PICK_ANY) { reset_menu_count(hwndList, data); for (i = 0; i < data->menu.size; i++) { - if (!(data->menu.items[i].itemflags & MENU_ITEMFLAGS_SKIPINVERT)) + if (menuitem_invert_test(0, data->menu.items[i].itemflags, + NHMENU_IS_SELECTED(data->menu.items[i]))) SelectMenuItem(hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i]) ? 0 : -1); @@ -1354,7 +1355,8 @@ onListChar(HWND hWnd, HWND hwndList, WORD ch) from = max(0, topIndex); to = min(data->menu.size, from + pageSize); for (i = from; i < to; i++) { - if (!(data->menu.items[i].itemflags & MENU_ITEMFLAGS_SKIPINVERT)) + if (menuitem_invert_test(0, data->menu.items[i].itemflags, + NHMENU_IS_SELECTED(data->menu.items[i]))) SelectMenuItem(hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i]) ? 0 : -1);