diff --git a/include/wintty.h b/include/wintty.h index 30e257e97..3cf4cb77c 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -13,14 +13,14 @@ /* menu structure */ typedef struct tty_mi { struct tty_mi *next; - anything identifier; /* user identifier */ - long count; /* user count */ - char *str; /* description string (including accelerator) */ - int attr; /* string attribute */ - boolean selected; /* TRUE if selected by user */ - unsigned int itemflags; /* */ - char selector; /* keyboard accelerator */ - char gselector; /* group accelerator */ + anything identifier; /* user identifier */ + long count; /* user count */ + char *str; /* description string (including accelerator) */ + int attr; /* string attribute */ + boolean selected; /* TRUE if selected by user */ + unsigned itemflags; /* item flags */ + char selector; /* keyboard accelerator */ + char gselector; /* group accelerator */ } tty_menu_item; /* descriptor for tty-based windows */ diff --git a/include/wintype.h b/include/wintype.h index 550afad3a..217b314a5 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -107,8 +107,9 @@ typedef struct mi { #define MENU_INVERT_PAGE '~' #define MENU_SEARCH ':' -#define MENU_ITEMFLAGS_NONE 0x0000000 -#define MENU_ITEMFLAGS_SELECTED 0x0000001 +#define MENU_ITEMFLAGS_NONE 0x0000000U +#define MENU_ITEMFLAGS_SELECTED 0x0000001U +#define MENU_ITEMFLAGS_SKIPINVERT 0x0000002U /* clang-format on */ diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 9926ee70b..81ffacc82 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -376,13 +376,12 @@ void NetHackQtBind::qt_start_menu(winid wid) void NetHackQtBind::qt_add_menu(winid wid, int glyph, const ANY_P * identifier, CHAR_P ch, CHAR_P gch, int attr, - const char *str, unsigned int itemflags) + const char *str, unsigned itemflags) { - boolean presel = ((itemflags & MENU_ITEMFLAGS_SELECTED) != 0); NetHackQtWindow* window=id_to_window[(int)wid]; window->AddMenu(glyph, identifier, ch, gch, attr, QString::fromLatin1(str), - presel); + itemflags); } void NetHackQtBind::qt_end_menu(winid wid, const char *prompt) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 8a0106b4d..b91b056c3 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -160,8 +160,9 @@ NetHackQtMenuWindow::MenuItem::~MenuItem() } void NetHackQtMenuWindow::AddMenu(int glyph, const ANY_P* identifier, - char ch, char gch, int attr, const QString& str, bool presel) + char ch, char gch, int attr, const QString& str, unsigned itemflags) { + bool presel = (itemflags & MENU_ITEMFLAGS_SELECTED) != 0; if (!ch && identifier->a_void!=0) { // Supply a keyboard accelerator. Limited supply. static char accel[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -180,6 +181,7 @@ void NetHackQtMenuWindow::AddMenu(int glyph, const ANY_P* identifier, itemlist[itemcount].attr=attr; itemlist[itemcount].str=str; itemlist[itemcount].selected=presel; + itemlist[itemcount].itemflags=itemflags; itemlist[itemcount].count=-1; itemlist[itemcount].color = -1; // Display the boulder symbol correctly diff --git a/win/Qt/qt_menu.h b/win/Qt/qt_menu.h index 1b278a89f..7aa5c2b8d 100644 --- a/win/Qt/qt_menu.h +++ b/win/Qt/qt_menu.h @@ -55,7 +55,7 @@ public: virtual void StartMenu(); virtual void AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr, - const QString& str, bool presel); + const QString& str, unsigned itemflags); virtual void EndMenu(const QString& prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); @@ -85,6 +85,7 @@ private: char ch; char gch; bool selected; + unsigned itemflags; unsigned color; bool Selectable() const { return identifier.a_void!=0; } @@ -172,7 +173,7 @@ public: // Menu virtual void StartMenu(); virtual void AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr, - const QString& str, bool presel); + const QString& str, unsigned itemflags); virtual void EndMenu(const QString& prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); diff --git a/win/Qt3/qt3_win.cpp b/win/Qt3/qt3_win.cpp index d8443cc83..fdde1daf2 100644 --- a/win/Qt3/qt3_win.cpp +++ b/win/Qt3/qt3_win.cpp @@ -1447,7 +1447,7 @@ void NetHackQtWindow::CursorTo(int x,int y) { puts("unexpected CursorTo"); } void NetHackQtWindow::PutStr(int attr, const char* text) { puts("unexpected PutStr"); } void NetHackQtWindow::StartMenu() { puts("unexpected StartMenu"); } void NetHackQtWindow::AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr, - const char* str, bool presel) { puts("unexpected AddMenu"); } + const char* str, unsigned itemflags) { puts("unexpected AddMenu"); } void NetHackQtWindow::EndMenu(const char* prompt) { puts("unexpected EndMenu"); } int NetHackQtWindow::SelectMenu(int how, MENU_ITEM_P **menu_list) { puts("unexpected SelectMenu"); return 0; } void NetHackQtWindow::ClipAround(int x,int y) { puts("unexpected ClipAround"); } @@ -2788,8 +2788,9 @@ NetHackQtMenuWindow::MenuItem::~MenuItem() #define STR_MARGIN 4 void NetHackQtMenuWindow::AddMenu(int glyph, const ANY_P* identifier, - char ch, char gch, int attr, const char* str, bool presel) + char ch, char gch, int attr, const char* str, unsigned itemflags) { + bool presel = (itemflags & MENU_ITEMFLAGS_SELECTED) != 0; if (!ch && identifier->a_void!=0) { // Supply a keyboard accelerator. Limited supply. static char accel[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -2807,6 +2808,7 @@ void NetHackQtMenuWindow::AddMenu(int glyph, const ANY_P* identifier, item[itemcount].attr=attr; item[itemcount].str=strdup(str); item[itemcount].selected=presel; + item[itemcount].itemflags=itemflags; item[itemcount].count=-1; ++itemcount; diff --git a/win/Qt3/qt3_win.h b/win/Qt3/qt3_win.h index 825fa918b..e9b6dbef0 100644 --- a/win/Qt3/qt3_win.h +++ b/win/Qt3/qt3_win.h @@ -258,7 +258,7 @@ class NetHackQtWindow virtual void PutStr(int attr, const char *text); virtual void StartMenu(); virtual void AddMenu(int glyph, const ANY_P *identifier, char ch, - char gch, int attr, const char *str, bool presel); + char gch, int attr, const char *str, unsigned itemflags); virtual void EndMenu(const char *prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); virtual void ClipAround(int x, int y); @@ -550,7 +550,7 @@ class NetHackQtMenuWindow : public QTableView, public NetHackQtWindow virtual void StartMenu(); virtual void AddMenu(int glyph, const ANY_P *identifier, char ch, - char gch, int attr, const char *str, bool presel); + char gch, int attr, const char *str, unsigned itemflags); virtual void EndMenu(const char *prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); @@ -699,7 +699,7 @@ class NetHackQtMenuOrTextWindow : public NetHackQtWindow // Menu virtual void StartMenu(); virtual void AddMenu(int glyph, const ANY_P *identifier, char ch, - char gch, int attr, const char *str, bool presel); + char gch, int attr, const char *str, unsigned itemflags); virtual void EndMenu(const char *prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); }; @@ -854,7 +854,7 @@ class NetHackQtBind : NetHackQtBindBase static void qt_start_menu(winid wid); static void qt_add_menu(winid wid, int glyph, const ANY_P *identifier, CHAR_P ch, CHAR_P gch, int attr, const char *str, - unsigned int itemflags); + unsigned itemflags); static void qt_end_menu(winid wid, const char *prompt); static int qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list); static void qt_update_inventory(); diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index b86e02ae3..36f60829c 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -542,10 +542,12 @@ struct xwindow *wp; reset_menu_count(wp->menu_information); for (count = 0, curr = wp->menu_information->curr_menu.base; curr; - curr = curr->next, count++) + curr = curr->next, count++) { + if ((curr->itemflags & MENU_ITEMFLAGS_SKIPINVERT) != 0) + continue; if (curr->identifier.a_void != 0) invert_line(wp, curr, count, -1L); - + } } static void @@ -655,6 +657,7 @@ unsigned itemflags; item->next = (x11_menu_item *) 0; item->identifier = *identifier; item->attr = attr; + item->itemflags = itemflags; item->selected = item->preselected = preselected; item->pick_count = -1L; item->window = window; diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index cf88c022b..8210c3523 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -586,6 +586,7 @@ curs_new_menu_item(winid wid, const char *str) new_item->str = new_str; new_item->presel = FALSE; new_item->selected = FALSE; + new_item->itemflags = MENU_ITEMFLAGS_NONE; new_item->page_num = 0; new_item->line_num = 0; new_item->num_lines = 0; @@ -598,10 +599,11 @@ curs_new_menu_item(winid wid, const char *str) void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, CHAR_P accelerator, CHAR_P group_accel, int attr, - const char *str, BOOLEAN_P presel) + const char *str, unsigned itemflags) { nhmenu_item *new_item, *current_items, *menu_item_ptr; nhmenu *current_menu = get_menu(wid); + boolean presel = (itemflags & MENU_ITEMFLAGS_SELECTED) != 0; if (current_menu == NULL) { impossible( @@ -620,7 +622,7 @@ curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, new_item->group_accel = group_accel; new_item->attr = attr; new_item->presel = presel; - + new_item->itemflags = itemflags; current_items = current_menu->entries; menu_item_ptr = current_items; @@ -1549,7 +1551,9 @@ menu_operation(WINDOW * win, nhmenu *menu, menu_op } if (menu_item_ptr->identifier.a_void != NULL) { - menu_select_deselect(win, menu_item_ptr, operation, current_page); + if (operation != INVERT + || (menu_item_ptr->itemflags & MENU_ITEMFLAGS_SKIPINVERT) == 0) + menu_select_deselect(win, menu_item_ptr, operation, current_page); } menu_item_ptr = menu_item_ptr->next_item; diff --git a/win/curses/cursdial.h b/win/curses/cursdial.h index acc6f855b..08b9f2948 100644 --- a/win/curses/cursdial.h +++ b/win/curses/cursdial.h @@ -15,7 +15,7 @@ int curses_ext_cmd(void); void curses_create_nhmenu(winid wid); void curses_add_nhmenu_item(winid wid, int glyph, const ANY_P *identifier, CHAR_P accelerator, CHAR_P group_accel, int attr, - const char *str, BOOLEAN_P presel); + const char *str, unsigned itemflags); void curs_menu_set_bottom_heavy(winid); void curses_finalize_nhmenu(winid wid, const char *prompt); int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P **_selected); diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index bab6d0808..9d1bfe62b 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -522,7 +522,7 @@ add_menu(winid wid, int glyph, const anything identifier, void curses_add_menu(winid wid, int glyph, const ANY_P * identifier, CHAR_P accelerator, CHAR_P group_accel, int attr, - const char *str, unsigned int itemflags) + const char *str, unsigned itemflags) { int curses_attr; boolean presel = ((itemflags & MENU_ITEMFLAGS_SELECTED) != 0); @@ -537,7 +537,7 @@ curses_add_menu(winid wid, int glyph, const ANY_P * identifier, } curses_add_nhmenu_item(wid, glyph, identifier, accelerator, group_accel, - curses_attr, str, presel); + curses_attr, str, itemflags); } /* diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 5dc6fc3fa..901320b0c 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -509,7 +509,8 @@ curses_puts(winid wid, int attr, const char *text) return; } Id = cg.zeroany; - curses_add_nhmenu_item(wid, NO_GLYPH, &Id, 0, 0, attr, text, FALSE); + curses_add_nhmenu_item(wid, NO_GLYPH, &Id, 0, 0, attr, text, + MENU_ITEMFLAGS_NONE); } else { waddstr(win, text); wnoutrefresh(win); diff --git a/win/gem/wingem.c b/win/gem/wingem.c index 76ea26cb9..7eecde401 100644 --- a/win/gem/wingem.c +++ b/win/gem/wingem.c @@ -788,6 +788,7 @@ unsigned int itemflags; /* itemflags such as marked as selected */ G_item->Gmi_selected = preselected ? 1 : 0; G_item->Gmi_accelerator = ch; G_item->Gmi_groupacc = gch; + G_item->Gmi_itemflags = itemflags; G_item->Gmi_attr = attr; G_item->Gmi_str = copy_of(newstr); mar_add_menu(window, G_item); diff --git a/win/gem/wingem1.c b/win/gem/wingem1.c index 08473853f..e25e60ae3 100644 --- a/win/gem/wingem1.c +++ b/win/gem/wingem1.c @@ -1783,7 +1783,9 @@ char acc; for (curr = invent_list; start-- && curr; curr = curr->Gmi_next) ; - for (; page-- && curr; curr = curr->Gmi_next) + for (; page-- && curr; curr = curr->Gmi_next) { + if ((curr->Gmi_itemflags & MENU_ITEMFLAGS_SKIPINVERT) != 0) + continue; if (curr->Gmi_identifier && (acc == 0 || curr->Gmi_groupacc == acc)) { if (curr->Gmi_selected) { curr->Gmi_selected = FALSE; @@ -1791,6 +1793,7 @@ char acc; } else curr->Gmi_selected = TRUE; } + } } /************************* Inv_Handler and Inv_Init diff --git a/win/gnome/gnbind.c b/win/gnome/gnbind.c index fbd9107e8..0b99c2453 100644 --- a/win/gnome/gnbind.c +++ b/win/gnome/gnbind.c @@ -723,6 +723,7 @@ gnome_add_menu(winid wid, int glyph, const ANY_P *identifier, item.attr = attr; item.str = str; item.presel = presel; + item.itemflags = itemflags; if (wid != -1 && gnome_windowlist[wid].win != NULL) { gtk_signal_emit(GTK_OBJECT(gnome_windowlist[wid].win), diff --git a/win/gnome/gnmenu.h b/win/gnome/gnmenu.h index f6ba3231d..b8bd140b1 100644 --- a/win/gnome/gnmenu.h +++ b/win/gnome/gnmenu.h @@ -18,6 +18,7 @@ struct _GHackMenuItem { CHAR_P accelerator; CHAR_P group_accel; int attr; + unsigned itemflags; const char *str; BOOLEAN_P presel; }; diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 8f7ddc9e2..9e41688ed 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1773,7 +1773,10 @@ char acc; /* group accelerator, 0 => all */ tty_menu_item *curr; int n; - for (n = 0, curr = page_start; curr != page_end; n++, curr = curr->next) + for (n = 0, curr = page_start; curr != page_end; n++, curr = curr->next) { + if ((curr->itemflags & MENU_ITEMFLAGS_SKIPINVERT) != 0) + continue; + if (curr->identifier.a_void && (acc == 0 || curr->gselector == acc)) { if (curr->selected) { curr->selected = FALSE; @@ -1782,6 +1785,7 @@ char acc; /* group accelerator, 0 => all */ curr->selected = TRUE; set_item_state(window, n, curr); } + } } /* @@ -1801,6 +1805,9 @@ char acc; /* group accelerator, 0 => all */ /* invert the rest */ for (on_curr_page = FALSE, curr = cw->mlist; curr; curr = curr->next) { + if ((curr->itemflags & MENU_ITEMFLAGS_SKIPINVERT) != 0) + continue; + if (curr == page_start) on_curr_page = TRUE; else if (curr == page_end) diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index 14fa263f9..ab76d41ad 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++) { - SelectMenuItem(hwndList, data, i, + if (!(data->menu.items[i].itemflags & MENU_ITEMFLAGS_SKIPINVERT)) + SelectMenuItem(hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i]) ? 0 : -1); } @@ -1353,7 +1354,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++) { - SelectMenuItem(hwndList, data, i, + if (!(data->menu.items[i].itemflags & MENU_ITEMFLAGS_SKIPINVERT)) + SelectMenuItem(hwndList, data, i, NHMENU_IS_SELECTED(data->menu.items[i]) ? 0 : -1); }