disappear (example was apply/loot in-out container menu with two or
more digits typed followed by non-digit); in-out menu was still active
but no longer displayed
+curses: support backspace/delete when entering a count during menu selection
macOS: Xcode project was failing to build if the path to the NetHack source
tree contained a space; the issue was within some shell script code
contained within the project
extern WINDOW *base_term; /* underlying terminal window */
extern boolean counting; /* Count window is active */
extern WINDOW *mapwin, *statuswin, *messagewin; /* Main windows */
+extern WINDOW *activemenu; /* curses window for menu requesting a
+ * count; affects count_window refresh */
#define TEXTCOLOR /* Allow color */
#define NHW_END 19
extern void curses_posthousekeeping(void);
extern void curses_view_file(const char *filename, boolean must_exist);
extern void curses_rtrim(char *str);
-extern int curses_get_count(int first_digit);
+extern long curses_get_count(int first_digit);
extern int curses_convert_attr(int attr);
extern int curses_read_attrs(const char *attrs);
extern char *curses_fmt_attrs(char *);
return cmd;
}
+/* gather typed digits into a number in *count; return the next non-digit */
char
get_count(char *allowchars, char inkey,
long maxcount, long *count,
if (digit(key)) {
cnt = 10L * cnt + (long) (key - '0');
- if (cnt < 0)
- cnt = 0;
- else if (maxcount > 0 && cnt > maxcount)
+ if (cnt < 0L)
+ cnt = 0L;
+ else if (maxcount > 0L && cnt > maxcount)
cnt = maxcount;
} else if (cnt && (key == '\b' || key == STANDBY_erase_char)) {
- cnt = cnt / 10;
+ cnt = cnt / 10L;
backspaced = TRUE;
} else if (key == g.Cmd.spkeys[NHKF_ESC]) {
break;
/* Dialog windows for curses interface */
+WINDOW *activemenu = NULL; /* for count_window refresh handling */
/* Private declarations */
typedef struct nhmi {
winid wid; /* NetHack window id */
- glyph_info glyphinfo; /* holds menu glyph and additional glyph info */
+ glyph_info glyphinfo; /* holds menu glyph and additional info */
anything identifier; /* Value returned if item selected */
- char accelerator; /* Character used to select item from menu */
- char group_accel; /* Group accelerator for menu item, if any */
+ char accelerator; /* Character used to select item from menu */
+ char group_accel; /* Group accelerator for menu item, if any */
int attr; /* Text attributes for item */
const char *str; /* Text of menu item */
- boolean presel; /* Whether menu item should be preselected */
+ boolean presel; /* Whether menu item should be preselected */
boolean selected; /* Whether item is currently selected */
unsigned itemflags;
int page_num; /* Display page number for entry */
if (iflags.wc_popup_dialog /*|| curses_stupid_hack*/) {
askwin = curses_create_window(prompt_width, prompt_height, UP);
+ activemenu = askwin;
+
for (count = 0; count < prompt_height; count++) {
linestr = curses_break_str(askstr, maxwidth, count + 1);
mvwaddstr(askwin, count + 1, 1, linestr);
if (digit(answer)) {
if (accept_count) {
if (answer != '0') {
- yn_number = curses_get_count(answer - '0');
- touchwin(askwin);
- refresh();
- }
+ yn_number = curses_get_count(answer);
+ if (iflags.wc_popup_dialog) {
+ curses_count_window(NULL);
+ touchwin(askwin);
+ wrefresh(askwin);
+ }
+ }
answer = '#';
break;
}
menu_get_selections(WINDOW *win, nhmenu *menu, int how)
{
int curletter, menucmd;
- int count = -1;
+ long count = -1L;
int count_letter = '\0';
int curpage = !menu->bottom_heavy ? 1 : menu->num_pages;
int num_selected = 0;
char selectors[256];
nhmenu_item *menu_item_ptr = menu->entries;
+ activemenu = win;
menu_display_page(menu, win, curpage, selectors);
while (!dismiss) {
/*FALLTHRU*/
default:
if (isdigit(curletter)) {
- count = curses_get_count(curletter - '0');
+ count = curses_get_count(curletter);
/* after count, we know some non-digit is already pending */
curletter = getch();
- count_letter = (count > 0) ? curletter : '\0';
+ count_letter = (count > 0L) ? curletter : '\0';
/* remove the count wind (erases last line of message wind) */
curses_count_window(NULL);
dismiss = curs_nonselect_menu_action(win, (void *) menu, how,
curletter, &curpage,
selectors, &num_selected);
- if (num_selected == -1)
+ if (num_selected == -1) {
+ activemenu = NULL;
return -1;
+ }
}
menu_item_ptr = menu->entries;
}
}
+ activemenu = NULL;
return num_selected;
}
mvwprintw(countwin, 0, 0, "%s", count_text);
wrefresh(countwin);
+ if (activemenu) {
+ touchwin(activemenu);
+ wrefresh(activemenu);
+ }
}
/* Gets a "line" (buffer) of input. */
/* Read numbers until non-digit is encountered, and return number
in int form. */
-int
+long
curses_get_count(int first_digit)
{
- long current_count = first_digit;
int current_char;
+ long current_count = 0L;
- current_char = curses_read_char();
-
- while (isdigit(current_char)) {
- current_count = (current_count * 10) + (current_char - '0');
- if (current_count > LARGEST_INT) {
- current_count = LARGEST_INT;
- }
-
- custompline(SUPPRESS_HISTORY, "Count: %ld", current_count);
- current_char = curses_read_char();
- }
+ /* use core's count routine; we have the first digit; if any more
+ are typed, get_count() will send "Count:123" to the message window;
+ curses's message window will display that in count window instead */
+ current_char = get_count(NULL, (char) first_digit,
+ /* 0L => no limit on value unless it wraps
+ * to negative;
+ * FALSE => suppress from message history */
+ 0L, ¤t_count, FALSE);
ungetch(current_char);
-
if (current_char == '\033') { /* Cancelled with escape */
current_count = -1;
}
-
return current_count;
}
void curses_posthousekeeping(void);
void curses_view_file(const char *filename, boolean must_exist);
void curses_rtrim(char *str);
-int curses_get_count(int first_digit);
+long curses_get_count(int first_digit);
int curses_convert_attr(int attr);
int curses_read_attrs(const char *attrs);
char *curses_fmt_attrs(char *);
werase(win);
wrefresh(win);
delwin(win);
+ if (win == activemenu)
+ activemenu = NULL;
curses_refresh_nethack_windows();
}