]> granicus.if.org Git - nethack/commitdiff
pick-a-color in color
authorPatR <rankin@nethack.org>
Thu, 10 Sep 2020 23:01:18 +0000 (16:01 -0700)
committerPatR <rankin@nethack.org>
Thu, 10 Sep 2020 23:01:18 +0000 (16:01 -0700)
Similar to how the pick-an-attribute menu for menu colors and
status highlights shows the attribute names using the attribute
so that you can see how it looks (or whether it is supported),
have the pick-a-color menu show the color names in the
corresponding color.  Does so by temporarily removing any
user-specified menu colors and setting up another list of such
for matching color names.

Forces the 'menucolors' option On while the pick-a-color menu is
in use, then restores the previous setting along with the user's
menu colorings.  Might need some way to avoid setting that for a
configuration where colors don't work.

doc/fixes37.0
include/decl.h
src/decl.c
src/options.c

index d0dc6f8565a5279bc5943be6513d643574582c0f..f03cb46765ff17b5cfd3adeb07049c87099a113e 100644 (file)
@@ -1,4 +1,4 @@
-NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ $NHDT-Date: 1599686385 2020/09/09 21:19:45 $
+NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.301 $ $NHDT-Date: 1599778430 2020/09/10 22:53:50 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -521,6 +521,8 @@ add section marker [] support to run-time config file; CHOOSE section1,section2
        file to be part of the last section; that still works the same, but []
        can be used to terminate the last section and revert to common options
        for the remainder of the file
+render the color names in the corresponding color when using the pick-a-color
+       menu for adding status highlights or menu colors via 'O'
 
 
 Platform- and/or Interface-Specific New Features
index b4f7f0dc167ddb2d0f98de9594ae2a8f3859dd01..453b450ae603d5ebfae70a38c7a0e3f8cd6c4b90 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7  decl.h  $NHDT-Date: 1596498532 2020/08/03 23:48:52 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.240 $ */
+/* NetHack 3.7  decl.h  $NHDT-Date: 1599778430 2020/09/10 22:53:50 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.241 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2007. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -639,12 +639,7 @@ struct _create_particular_data {
     boolean sleeping, saddled, invisible, hidden;
 };
 
-/* instance_globals holds engine state that does not need to be
- * persisted upon game exit.  The initialization state is well defined
- * an set in decl.c during early early engine initialization.
- *
- * unlike instance_flags, values in the structure can be of any type. */
-
+/* some array sizes for 'g' */
 #define BSIZE 20
 #define WIZKIT_MAX 128
 #define CVT_BUF_SIZE 64
@@ -652,6 +647,16 @@ struct _create_particular_data {
 #define LUA_VER_BUFSIZ 20
 #define LUA_COPYRIGHT_BUFSIZ 120
 
+/*
+ * 'g' -- instance_globals holds engine state that does not need to be
+ * persisted upon game exit.  The initialization state is well defined
+ * and set in decl.c during early early engine initialization.
+ *
+ * Unlike instance_flags, values in the structure can be of any type.
+ *
+ * Pulled from other files to be grouped in one place.  Some comments
+ * which came with them don't make much sense out of their original context.
+ */
 struct instance_globals {
 
     /* apply.c */
@@ -684,12 +689,12 @@ struct instance_globals {
 
     /* cmd.c */
     struct cmd Cmd; /* flag.h */
-    /* Provide a means to redo the last command.  The flag `in_doagain' is set
-     * to true while redoing the command.  This flag is tested in commands that
-     * require additional input (like `throw' which requires a thing and a
-     * direction), and the input prompt is not shown.  Also, while in_doagain is
-     * TRUE, no keystrokes can be saved into the saveq.
-     */
+    /* Provide a means to redo the last command.  The flag `in_doagain'
+       (decl.c below) is set to true while redoing the command.  This flag
+       is tested in commands that require additional input (like `throw'
+       which requires a thing and a direction), and the input prompt is
+       not shown.  Also, while in_doagain is TRUE, no keystrokes can be
+       saved into the saveq. */
     char pushq[BSIZE];
     char saveq[BSIZE];
     int phead;
@@ -999,34 +1004,35 @@ struct instance_globals {
     /* objname.c */
     /* distantname used by distant_name() to pass extra information to
        xname_flags(); it would be much cleaner if this were a parameter,
-       but that would require all of the xname() and doname() calls to be
-       modified */
+       but that would require all xname() and doname() calls to be modified */
     int distantname;
 
     /* options.c */
     struct symsetentry *symset_list; /* files.c will populate this with
-                                        list of available sets */
-    /*
-        * Allow the user to map incoming characters to various menu commands.
-        * The accelerator list must be a valid C string.
-        */
+                                      * list of available sets */
+    /* Allow the user to map incoming characters to various menu commands. */
     char mapped_menu_cmds[MAX_MENU_MAPPED_CMDS + 1]; /* exported */
     char mapped_menu_op[MAX_MENU_MAPPED_CMDS + 1];
     short n_menu_mapped;
+    /* options processing */
     boolean opt_initial;
     boolean opt_from_file;
     boolean opt_need_redraw; /* for doset() */
+    /* use menucolors to show colors in the pick-a-color menu */
+    boolean save_menucolors; /* copy of iflags.use_menu_colors */
+    struct menucoloring *save_colorings; /* copy of g.menu_colorings */
+    struct menucoloring *color_colorings; /* alternate set of menu colors */
 
     /* pickup.c */
     int oldcap; /* last encumberance */
     /* current_container is set in use_container(), to be used by the
        callback routines in_container() and out_container() from askchain()
-       and use_container(). Also used by menu_loot() and container_gone(). */
+       and use_container().  Also used by menu_loot() and container_gone(). */
     struct obj *current_container;
     boolean abort_looting;
     /* Value set by query_objlist() for n_or_more(). */
     long val_for_n_or_more;
-    /* list of valid menu classes for query_objlist() and allow_category callback
+    /* list of menu classes for query_objlist() and allow_category callback
        (with room for all object classes, 'u'npaid, BUCX, and terminator) */
     char valid_menu_classes[MAXOCLASSES + 1 + 4 + 1];
     boolean class_filter;
index 5d528df334a3717a6afef71639b6b22bfebf17cb..7bcf2501a1ef5976e68273bf3d4540d0a746f5bd 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 decl.c  $NHDT-Date: 1596498154 2020/08/03 23:42:34 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.216 $ */
+/* NetHack 3.7 decl.c  $NHDT-Date: 1599778430 2020/09/10 22:53:50 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.217 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2009. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -526,17 +526,20 @@ const struct instance_globals g_init = {
     0, /* distantname */
 
     /* options.c */
-    NULL, /* symset_list */
+    (struct symsetentry *) 0, /* symset_list */
     UNDEFINED_VALUES, /* mapped_menu_cmds */
     UNDEFINED_VALUES, /* mapped_menu_op */
     0, /* n_menu_mapped */
-    UNDEFINED_VALUE, /* opt_initial */
-    UNDEFINED_VALUE, /* opt_from_file */
-    UNDEFINED_VALUE, /* opt_need_redraw */
+    FALSE, /* opt_initial */
+    FALSE, /* opt_from_file */
+    FALSE, /* opt_need_redraw */
+    FALSE, /* save_menucolors */
+    (struct menucoloring *) 0, /* save_colorings */
+    (struct menucoloring *) 0, /* color_colorings */
 
     /* pickup.c */
     0,  /* oldcap */
-    UNDEFINED_PTR, /* current_container */
+    (struct obj *) 0, /* current_container */
     UNDEFINED_VALUE, /* abort_looting */
     UNDEFINED_VALUE, /* val_for_n_or_more */
     UNDEFINED_VALUES, /* valid_menu_classes */
@@ -551,7 +554,7 @@ const struct instance_globals g_init = {
     0, /* saved_pline_index */
     UNDEFINED_VALUES,
 #endif
-    NULL, /* you_buf */
+    (char *) 0, /* you_buf */
     0, /* you_buf_siz */
 
     /* polyself.c */
index 07a38f97cec5839564f97dda00d0a863daa597ef..cea11d4b83b41d766152b32368040a8fc1648082 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 options.c       $NHDT-Date: 1599686385 2020/09/09 21:19:45 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.471 $ */
+/* NetHack 3.7 options.c       $NHDT-Date: 1599778431 2020/09/10 22:53:51 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.472 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Michael Allison, 2008. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -235,13 +235,14 @@ static int FDECL(check_misc_menu_command, (char *, char *));
 int FDECL(spcfn_misc_menu_cmd, (int, int, BOOLEAN_P, char *, char *));
 
 static const char *FDECL(attr2attrname, (int));
+static void FDECL(basic_menu_colors, (BOOLEAN_P));
 static const char * FDECL(msgtype2name, (int));
 static int NDECL(query_msgtype);
 static boolean FDECL(msgtype_add, (int, char *));
 static void FDECL(free_one_msgtype, (int));
 static int NDECL(msgtype_count);
 static boolean FDECL(test_regex_pattern, (const char *, const char *));
-static boolean FDECL(add_menu_coloring_parsed, (char *, int, int));
+static boolean FDECL(add_menu_coloring_parsed, (const char *, int, int));
 static void FDECL(free_one_menu_coloring, (int));
 static int NDECL(count_menucolors);
 static boolean FDECL(parse_role_opts, (int, BOOLEAN_P, const char *,
@@ -6402,9 +6403,9 @@ char* bindings;
  *
  */
 
-static const struct {
+static const struct color_names {
     const char *name;
-    const int color;
+    int color;
 } colornames[] = {
     { "black", CLR_BLACK },
     { "red", CLR_RED },
@@ -6435,9 +6436,9 @@ static const struct {
     { "bright cyan", CLR_BRIGHT_CYAN }
 };
 
-static const struct {
+static const struct attr_names {
     const char *name;
-    const int attr;
+    int attr;
 } attrnames[] = {
     { "none", ATR_NONE },
     { "bold", ATR_BOLD },
@@ -6520,6 +6521,61 @@ boolean complain;
     return a;
 }
 
+extern const char regex_id[]; /* from sys/share/<various>regex.{c,cpp} */
+
+/* True: temporarily replace menu color entries with a fake set of menu
+   colors, { "light blue"=light_blue, "blue"=blue, "red"=red, &c }, that
+   illustrates most colors for use when the pick-a-color menu is rendered;
+   suppresses black and white because one of those will likely be invisible
+   due to matching the background; False: restore user-specified colorings */
+static void
+basic_menu_colors(load_colors)
+boolean load_colors;
+{
+    if (load_colors) {
+        /* replace normal menu colors with a set specifically for colors */
+        g.save_menucolors = iflags.use_menu_color;
+        g.save_colorings = g.menu_colorings;
+
+        iflags.use_menu_color = TRUE;
+        if (g.color_colorings) {
+            /* use the alternate colorings which were set up previously */
+            g.menu_colorings = g.color_colorings;
+        } else {
+            /* create the alternate colorings once */
+            char cnm[QBUFSZ];
+            int i, c;
+            boolean pmatchregex = !strcmpi(regex_id, "pmatchregex");
+
+            /* menu_colorings pointer has been saved; clear it in order
+               to add the alternate entries as if from scratch */
+            g.menu_colorings = (struct menucoloring *) 0;
+
+            /* this orders the patterns last-in/first-out; that means
+               that the "light <foo>" variations come before the basic
+               "<foo>" ones, which is exactly what we want */
+            for (i = 0; i < SIZE(colornames); ++i) {
+                if (!colornames[i].name) /* first alias entry has no name */
+                    break;
+                c = colornames[i].color;
+                if (c == CLR_BLACK || c == CLR_WHITE || c == NO_COLOR)
+                    continue; /* skip these */
+                Sprintf(cnm, pmatchregex ? "*%s" : "%s", colornames[i].name);
+                add_menu_coloring_parsed(dupstr(cnm), c, ATR_NONE);
+            }
+
+            /* right now, menu_colorings contains the alternate color list;
+               remember that list for future pick-a-color instances and
+               also keep it as is for this instance */
+            g.color_colorings = g.menu_colorings;
+        }
+    } else {
+        /* restore normal user-specific menu colors */
+        iflags.use_menu_color = g.save_menucolors;
+        g.menu_colorings = g.save_colorings;
+    }
+}
+
 int
 query_color(prompt)
 const char *prompt;
@@ -6529,6 +6585,9 @@ const char *prompt;
     int i, pick_cnt;
     menu_item *picks = (menu_item *) 0;
 
+    /* replace user patterns with color name ones and force 'menucolors' On */
+    basic_menu_colors(TRUE);
+
     tmpwin = create_nhwindow(NHW_MENU);
     start_menu(tmpwin, MENU_BEHAVE_STANDARD);
     any = cg.zeroany;
@@ -6543,6 +6602,11 @@ const char *prompt;
     end_menu(tmpwin, (prompt && *prompt) ? prompt : "Pick a color");
     pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
     destroy_nhwindow(tmpwin);
+
+    /* remove temporary color name patterns and restore user-specified ones;
+       reset 'menucolors' option to its previous value */
+    basic_menu_colors(FALSE);
+
     if (pick_cnt > 0) {
         i = colornames[picks[0].item.a_int - 1].color;
         /* pick_cnt==2: explicitly picked something other than the
@@ -6876,7 +6940,7 @@ const char *errmsg;
 
 static boolean
 add_menu_coloring_parsed(str, c, a)
-char *str;
+const char *str;
 int c, a;
 {
     static const char re_error[] = "Menucolor regex error";
@@ -6970,20 +7034,27 @@ int *color, *attr;
     return FALSE;
 }
 
+/* release all menu color patterns */
 void
 free_menu_coloring()
 {
-    struct menucoloring *tmp, *tmp2;
+    /* either menu_colorings or color_colorings or both might need to
+       be freed or already be Null; do-loop will iterate at most twice */
+    do {
+        struct menucoloring *tmp, *tmp2;
 
-    for (tmp = g.menu_colorings; tmp; tmp = tmp2) {
-        tmp2 = tmp->next;
-        regex_free(tmp->match);
-        free((genericptr_t) tmp->origstr);
-        free((genericptr_t) tmp);
-    }
-    g.menu_colorings = (struct menucoloring *) 0;
+        for (tmp = g.menu_colorings; tmp; tmp = tmp2) {
+            tmp2 = tmp->next;
+            regex_free(tmp->match);
+            free((genericptr_t) tmp->origstr);
+            free((genericptr_t) tmp);
+        }
+        g.menu_colorings = g.color_colorings;
+        g.color_colorings = (struct menucoloring *) 0;
+    } while (g.menu_colorings);
 }
 
+/* release a specific menu color pattern; not used for color_colorings */
 static void
 free_one_menu_coloring(idx)
 int idx; /* 0 .. */