curses line-of-input prompting

Redo the fake ESC handling for curses' wgetnstr() so that it
applies to all popup prompts rather than just to "Who are you?",
in case the player sets the 'popup_dialog' option.
This commit is contained in:
PatR
2021-01-06 15:59:55 -08:00
parent 2df4f08c0b
commit 7ba7873a41
3 changed files with 33 additions and 31 deletions
+5 -5
View File
@@ -1,4 +1,4 @@
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.420 $ $NHDT-Date: 1609811543 2021/01/05 01:52:23 $ NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.423 $ $NHDT-Date: 1609977590 2021/01/06 23:59:50 $
General Fixes and Modified Features General Fixes and Modified Features
----------------------------------- -----------------------------------
@@ -482,10 +482,10 @@ remove unused vision tables
curses: 'msg_window' option wasn't functional for curses unless the binary curses: 'msg_window' option wasn't functional for curses unless the binary
also included tty support also included tty support
curses: line input that doesn't take place on the bottom line of the message curses: line input that doesn't take place on the bottom line of the message
window or in a popup doesn't support ESC to kill partial input or to window uses a canned curses routine and doesn't support ESC to kill
cancel; "Who are you?" prompt was willing to name a character "^["; partial input or to cancel; "Who are you?" prompt was willing to name
have askname() fake the usual ESC handling, but player has to type a character "^["; have the popup version of getlin() fake the usual
<escape><return> for that to work ESC handling, but player has to type <escape><return> for that to work
Qt: at Xp levels above 20 with 'showexp' On, the combined status field Qt: at Xp levels above 20 with 'showexp' On, the combined status field
"Level:NN/nnnnnnnn" was too big and truncated by a char at each end "Level:NN/nnnnnnnn" was too big and truncated by a char at each end
Qt: searching a text window for something that wasn't found and then searching Qt: searching a text window for something that wasn't found and then searching
+20 -2
View File
@@ -131,7 +131,8 @@ curses_line_input_dialog(const char *prompt, char *answer, int buffer)
int map_height, map_width, maxwidth, remaining_buf, winx, winy, count; int map_height, map_width, maxwidth, remaining_buf, winx, winy, count;
WINDOW *askwin, *bwin; WINDOW *askwin, *bwin;
char *tmpstr; char *tmpstr;
int prompt_width, prompt_height = 1, height = prompt_height; int prompt_width, prompt_height = 1, height = prompt_height,
answerx = 0, answery = 0, trylim;
char input[BUFSZ]; char input[BUFSZ];
/* if messages were being suppressed for the remainder of the turn, /* if messages were being suppressed for the remainder of the turn,
@@ -185,11 +186,28 @@ curses_line_input_dialog(const char *prompt, char *answer, int buffer)
wmove(askwin, count + 1, 0); wmove(askwin, count + 1, 0);
} }
free(tmpstr); free(tmpstr);
/* remember where user's typed response will start, in case we
need to re-prompt */
getyx(askwin, answery, answerx);
} }
echo(); echo();
curs_set(1); curs_set(1);
wgetnstr(askwin, input, buffer - 1); trylim = 10;
do {
/* move and clear are only needed for 2nd and subsequent passes */
wmove(askwin, answery, answerx);
wclrtoeol(askwin);
wgetnstr(askwin, input, buffer - 1);
/* ESC after some input kills that input and tries again;
ESC at the start cancels, leaving ESC in the result buffer.
[Note: wgetnstr() treats <escape> as an ordinary character
so user has to type <escape><return> for it to behave the
way we want it to.] */
if (input[0] != '\033' && index(input, '\033') != 0)
input[0] = '\0';
} while (--trylim > 0 && !input[0]);
curs_set(0); curs_set(0);
Strcpy(answer, input); Strcpy(answer, input);
werase(bwin); werase(bwin);
+8 -24
View File
@@ -240,9 +240,6 @@ curses_player_selection()
void void
curses_askname() curses_askname()
{ {
const char *bail_msg = "Until next time then...";
int trylimit = 10;
#ifdef SELECTSAVED #ifdef SELECTSAVED
if (iflags.wc2_selectsaved && !iflags.renameinprogress) if (iflags.wc2_selectsaved && !iflags.renameinprogress)
switch (restore_menu(MAP_WIN)) { switch (restore_menu(MAP_WIN)) {
@@ -255,29 +252,16 @@ curses_askname()
} }
#endif /* SELECTSAVED */ #endif /* SELECTSAVED */
do { curses_line_input_dialog("Who are you?", g.plname, PL_NSIZ);
if (--trylimit < 0) { (void) mungspaces(g.plname);
bail_msg = "A name is required; giving up."; if (g.plname[0] && g.plname[0] != '\033') {
goto bail; iflags.renameallowed = TRUE; /* tty uses this, we don't [yet?] */
} return;
}
g.plname[0] = '\0';
/* for askname(), this will use wgetnstr() which treats ESC like
an ordinary character; fake the behavior we want: as kill_char
if it follows any input or as cancel if it is at the start;
player has to type <escape><return> to get back here though */
curses_line_input_dialog("Who are you?", g.plname, PL_NSIZ);
if (g.plname[0] == '\033')
goto bail;
(void) mungspaces(g.plname);
} while (!g.plname[0] || index(g.plname, '\033') != 0);
/* we get here if input is non-empty and doesn't contain ESC */
return;
bail: bail:
curses_bail(bail_msg); /* message is delivered via raw_print() */
curses_bail("\nUntil next time then...\n");
/*NOTREACHED*/ /*NOTREACHED*/
} }