Files
nethack/win/curses/cursinvt.c
PatR 71bb01c328 curses persistent inventory window tweak
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.
2021-02-08 16:34:29 -08:00

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);
}