]> granicus.if.org Git - nethack/commitdiff
curses line-of-input prompting
authorPatR <rankin@nethack.org>
Wed, 6 Jan 2021 23:59:55 +0000 (15:59 -0800)
committerPatR <rankin@nethack.org>
Wed, 6 Jan 2021 23:59:55 +0000 (15:59 -0800)
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.

doc/fixes37.0
win/curses/cursdial.c
win/curses/cursmain.c

index 541b955218a28c18654e659c0650063197ac8e9d..471fe3c960529be7bbccd2e9beffef74e0b5620c 100644 (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
 -----------------------------------
@@ -482,10 +482,10 @@ remove unused vision tables
 curses: 'msg_window' option wasn't functional for curses unless the binary
        also included tty support
 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
-       cancel; "Who are you?" prompt was willing to name a character "^[";
-       have askname() fake the usual ESC handling, but player has to type
-       <escape><return> for that to work
+       window uses a canned curses routine and doesn't support ESC to kill
+       partial input or to cancel; "Who are you?" prompt was willing to name
+       a character "^["; have the popup version of getlin() fake the usual
+       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
        "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
index cee28b7ac5c9da8515ca485872444338548fbc79..d4c388349572e813033321386813dd213f04e691 100644 (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;
     WINDOW *askwin, *bwin;
     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];
 
     /* 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);
         }
         free(tmpstr);
+        /* remember where user's typed response will start, in case we
+           need to re-prompt */
+        getyx(askwin, answery, answerx);
     }
 
     echo();
     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);
     Strcpy(answer, input);
     werase(bwin);
index ed752a45ca8cac591fbc538b464655503f2cbe4c..5607897ba13feebcac698302688e5488a51b5dd3 100644 (file)
@@ -240,9 +240,6 @@ curses_player_selection()
 void
 curses_askname()
 {
-    const char *bail_msg = "Until next time then...";
-    int trylimit = 10;
-
 #ifdef SELECTSAVED
     if (iflags.wc2_selectsaved && !iflags.renameinprogress)
         switch (restore_menu(MAP_WIN)) {
@@ -255,29 +252,16 @@ curses_askname()
         }
 #endif /* SELECTSAVED */
 
-    do {
-        if (--trylimit < 0) {
-             bail_msg = "A name is required; giving up.";
-             goto bail;
-        }
-
-        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;
+    curses_line_input_dialog("Who are you?", g.plname, PL_NSIZ);
+    (void) mungspaces(g.plname);
+    if (g.plname[0] && g.plname[0] != '\033') {
+         iflags.renameallowed = TRUE; /* tty uses this, we don't [yet?] */
+         return;
+    }
 
  bail:
-    curses_bail(bail_msg);
+    /* message is delivered via raw_print() */
+    curses_bail("\nUntil next time then...\n");
     /*NOTREACHED*/
 }