Under curses interface, provide a way to get a little more space for perm_invent without turning off windowborders entirely. Possible 'windowborders' values: 0 = no borders, max screen space available for useful info 1 = full borders, two lines and two columns wasted for each window 2 = contingent borders, show if screen is big enough, else hide New: 3 = as 1 except no borders for perm_invent window 4 = as 2 except never borders for perm_invent window 3 and 4 let the map, message, and status windows have borders while providing two extra lines and two extra columns on each line for persistent inventory. It's not much but better than nothing when borders are enabled.
122 lines
4.3 KiB
C
122 lines
4.3 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, char 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:
|
|
* 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) {
|
|
/* despite being shown as a menu, nothing is selectable from the
|
|
persistent inventory window so avoid the usual highlighting of
|
|
inventory letters */
|
|
wprintw(win, "%c) ", accelerator);
|
|
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,
|
|
* the 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;
|
|
}
|
|
/* only perform menu coloring on item entries, not subtitles */
|
|
if (accelerator && 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);
|
|
}
|