OSDN Git Service

fix #43519
[jnethack/source.git] / win / curses / cursinvt.c
1 /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/
2 /* NetHack 3.6 cursinvt.c */
3 /* Copyright (c) Fredrik Ljungdahl, 2017. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 #include "curses.h"
7 #include "hack.h"
8 #include "wincurs.h"
9 #include "cursinvt.h"
10
11 /* Permanent inventory for curses interface */
12
13 /* Runs when the game indicates that the inventory has been updated */
14 void
15 curses_update_inv(void)
16 {
17     WINDOW *win = curses_get_nhwin(INV_WIN);
18     boolean border;
19     int x = 0, y = 0;
20
21     /* Check if the inventory window is enabled in first place */
22     if (!win) {
23         /* It's not. Re-initialize the main windows if the
24            option was enabled. */
25         if (iflags.perm_invent) {
26             /* [core_]status_initialize, curses_create_main_windows,
27                curses_last_messages, [core_]doredraw; doredraw will
28                call (*update_inventory) [curses_update_inventory] which
29                will call us but 'win' should be defined that time */
30             curs_reset_windows(TRUE, FALSE);
31             /* TODO: guard against window creation failure [if that's
32                possible] which would lead to uncontrolled recursion */
33         }
34         return;
35     }
36
37     border = curses_window_has_border(INV_WIN);
38
39     /* Figure out drawing area */
40     if (border) {
41         x++;
42         y++;
43     }
44
45     /* Clear the window as it is at the moment. */
46     werase(win);
47
48     display_inventory(NULL, FALSE);
49
50     if (border)
51         box(win, 0, 0);
52
53     wnoutrefresh(win);
54 }
55
56 /* Adds an inventory item.  'y' is 1 rather than 0 for the first item. */
57 void
58 curses_add_inv(int y,
59                int glyph UNUSED,
60                CHAR_P accelerator, attr_t attr, const char *str)
61 {
62     WINDOW *win = curses_get_nhwin(INV_WIN);
63     int color = NO_COLOR;
64     int x = 0, width, height, available_width, stroffset = 0,
65         border = curses_window_has_border(INV_WIN) ? 1 : 0;
66
67     /* Figure out where to draw the line */
68     x += border; /* x starts at 0 and is incremented for border */
69     y -= 1 - border; /* y starts at 1 and is decremented for non-border */
70
71     curses_get_window_size(INV_WIN, &height, &width);
72     /*
73      * TODO:
74      *  If border is On and 'y' is too big, turn border Off in order to
75      *  get two more lines of perm_invent.
76      *
77      *  And/or implement a way to switch focus from map to inventory
78      *  so that the latter can be scrolled.  Must not require use of a
79      *  mouse.
80      *
81      *  Also, when entries are omitted due to lack of space, mark the
82      *  last line to indicate "there's more that you can't see" (like
83      *  horizontal status window does for excess status conditions).
84      *  Normal menu does this via 'page M of N'.
85      */
86     if (y - border >= height) /* 'height' is already -2 for Top+Btm borders */
87         return;
88     available_width = width; /* 'width' also already -2 for Lft+Rgt borders */
89
90     wmove(win, y, x);
91     if (accelerator) {
92 #if 0
93         attr_t bold = A_BOLD;
94
95         wattron(win, bold);
96         waddch(win, accelerator);
97         wattroff(win, bold);
98         wprintw(win, ") ");
99 #else
100         /* despite being shown as a menu, nothing is selectable from the
101            persistent inventory window so don't highlight inventory letters */
102         wprintw(win, "%c) ", accelerator);
103 #endif
104         available_width -= 3; /* letter+parenthesis+space */
105
106         /* narrow the entries to fit more of the interesting text; do so
107            unconditionally rather than trying to figure whether it's needed;
108            when 'sortpack' is enabled we could also strip out "<class> of"
109            from "<prefix><class> of <item><suffix> but if that's to be done,
110            core ought to do it;
111            'stroffset': defer skipping the article prefix until after menu
112            color pattern matching has taken place so that the persistent
113            inventory window always gets same coloring as regular inventory */
114         if (!strncmpi(str, "a ", 2))
115             stroffset = 2;
116         else if (!strncmpi(str, "an ", 3))
117             stroffset = 3;
118         else if (!strncmpi(str, "the ", 4))
119             stroffset = 4;
120     }
121 #if 0 /* FIXME: MENU GLYPHS */
122     if (accelerator && glyph != NO_GLYPH && iflags.use_menu_glyphs) {
123         unsigned dummy = 0; /* Not used */
124         int color = 0;
125         int symbol = 0;
126         attr_t glyphclr;
127
128         mapglyph(glyph, &symbol, &color, &dummy, u.ux, u.uy, 0);
129         glyphclr = curses_color_attr(color, 0);
130         wattron(win, glyphclr);
131         wprintw(win, "%c ", symbol);
132         wattroff(win, glyphclr);
133         available_width -= 2;
134     }
135 #endif
136     if (accelerator /* Don't colorize categories */
137         && iflags.use_menu_color) {
138         attr = 0;
139         get_menu_coloring(str, &color, (int *) &attr);
140         attr = curses_convert_attr(attr);
141     }
142     if (color == NO_COLOR)
143         color = NONE;
144     curses_menu_color_attr(win, color, attr, ON);
145     wprintw(win, "%.*s", available_width, str + stroffset);
146     curses_menu_color_attr(win, color, attr, OFF);
147     wclrtoeol(win);
148 }