149 lines
5.1 KiB
C
149 lines
5.1 KiB
C
/* 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" -*-*/
|
|
/* NetHack 3.7 cursinvt.c */
|
|
/* Copyright (c) Fredrik Ljungdahl, 2017. */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#include "curses.h"
|
|
#include "hack.h"
|
|
#include "wincurs.h"
|
|
#include "cursinvt.h"
|
|
|
|
/* Permanent inventory for curses interface */
|
|
|
|
/* Runs when the game indicates that the inventory has been updated */
|
|
void
|
|
curses_update_inv(void)
|
|
{
|
|
WINDOW *win = curses_get_nhwin(INV_WIN);
|
|
boolean border;
|
|
int x = 0, y = 0;
|
|
|
|
/* Check if the inventory window is enabled in first place */
|
|
if (!win) {
|
|
/* It's not. Re-initialize the main windows if the
|
|
option was enabled. */
|
|
if (iflags.perm_invent) {
|
|
/* [core_]status_initialize, curses_create_main_windows,
|
|
curses_last_messages, [core_]doredraw; doredraw will
|
|
call (*update_inventory) [curses_update_inventory] which
|
|
will call us but 'win' should be defined that time */
|
|
curs_reset_windows(TRUE, FALSE);
|
|
/* TODO: guard against window creation failure [if that's
|
|
possible] which would lead to uncontrolled recursion */
|
|
}
|
|
return;
|
|
}
|
|
|
|
border = curses_window_has_border(INV_WIN);
|
|
|
|
/* Figure out drawing area */
|
|
if (border) {
|
|
x++;
|
|
y++;
|
|
}
|
|
|
|
/* Clear the window as it is at the moment. */
|
|
werase(win);
|
|
|
|
display_inventory(NULL, FALSE);
|
|
|
|
if (border)
|
|
box(win, 0, 0);
|
|
|
|
wnoutrefresh(win);
|
|
}
|
|
|
|
/* Adds an inventory item. 'y' is 1 rather than 0 for the first item. */
|
|
void
|
|
curses_add_inv(int y,
|
|
int glyph UNUSED,
|
|
CHAR_P accelerator, attr_t attr, const char *str)
|
|
{
|
|
WINDOW *win = curses_get_nhwin(INV_WIN);
|
|
int color = NO_COLOR;
|
|
int x = 0, width, height, available_width, stroffset = 0,
|
|
border = curses_window_has_border(INV_WIN) ? 1 : 0;
|
|
|
|
/* Figure out where to draw the line */
|
|
x += border; /* x starts at 0 and is incremented for border */
|
|
y -= 1 - border; /* y starts at 1 and is decremented for non-border */
|
|
|
|
curses_get_window_size(INV_WIN, &height, &width);
|
|
/*
|
|
* TODO:
|
|
* If border is On and 'y' is too big, turn border Off in order to
|
|
* get two more lines of perm_invent.
|
|
*
|
|
* And/or implement a way to switch focus from map to inventory
|
|
* so that the latter can be scrolled. Must not require use of a
|
|
* mouse.
|
|
*
|
|
* Also, when entries are omitted due to lack of space, mark the
|
|
* last line to indicate "there's more that you can't see" (like
|
|
* horizontal status window does for excess status conditions).
|
|
* Normal menu does this via 'page M of N'.
|
|
*/
|
|
if (y - border >= height) /* 'height' is already -2 for Top+Btm borders */
|
|
return;
|
|
available_width = width; /* 'width' also already -2 for Lft+Rgt borders */
|
|
|
|
wmove(win, y, x);
|
|
if (accelerator) {
|
|
#if 0
|
|
attr_t bold = A_BOLD;
|
|
|
|
wattron(win, bold);
|
|
waddch(win, accelerator);
|
|
wattroff(win, bold);
|
|
wprintw(win, ") ");
|
|
#else
|
|
/* despite being shown as a menu, nothing is selectable from the
|
|
persistent inventory window so don't highlight inventory letters */
|
|
wprintw(win, "%c) ", accelerator);
|
|
#endif
|
|
available_width -= 3; /* letter+parenthesis+space */
|
|
|
|
/* narrow the entries to fit more of the interesting text; do so
|
|
unconditionally rather than trying to figure whether it's needed;
|
|
when 'sortpack' is enabled we could also strip out "<class> of"
|
|
from "<prefix><class> of <item><suffix> but if that's to be done,
|
|
core ought to do it;
|
|
'stroffset': defer skipping the article prefix until after menu
|
|
color pattern matching has taken place so that the persistent
|
|
inventory window always gets same coloring as regular inventory */
|
|
if (!strncmpi(str, "a ", 2))
|
|
stroffset = 2;
|
|
else if (!strncmpi(str, "an ", 3))
|
|
stroffset = 3;
|
|
else if (!strncmpi(str, "the ", 4))
|
|
stroffset = 4;
|
|
}
|
|
#if 0 /* FIXME: MENU GLYPHS */
|
|
if (accelerator && glyph != NO_GLYPH && iflags.use_menu_glyphs) {
|
|
unsigned dummy = 0; /* Not used */
|
|
int color = 0;
|
|
int symbol = 0;
|
|
attr_t glyphclr;
|
|
|
|
mapglyph(glyph, &symbol, &color, &dummy, u.ux, u.uy, 0);
|
|
glyphclr = curses_color_attr(color, 0);
|
|
wattron(win, glyphclr);
|
|
wprintw(win, "%c ", symbol);
|
|
wattroff(win, glyphclr);
|
|
available_width -= 2;
|
|
}
|
|
#endif
|
|
if (accelerator /* Don't colorize categories */
|
|
&& iflags.use_menu_color) {
|
|
attr = 0;
|
|
get_menu_coloring(str, &color, (int *) &attr);
|
|
attr = curses_convert_attr(attr);
|
|
}
|
|
if (color == NO_COLOR)
|
|
color = NONE;
|
|
curses_menu_color_attr(win, color, attr, ON);
|
|
wprintw(win, "%.*s", available_width, str + stroffset);
|
|
curses_menu_color_attr(win, color, attr, OFF);
|
|
wclrtoeol(win);
|
|
}
|