Curses: implement the windowcolors option
Allow changing the curses windows foreground and background colors, for example: OPTIONS=windowcolor:menu #8000F0/20F080 message grey/blue
This commit is contained in:
@@ -6,6 +6,9 @@
|
||||
#include "curses.h"
|
||||
#include "hack.h"
|
||||
#include "wincurs.h"
|
||||
#include "cursinit.h"
|
||||
#include "curswins.h"
|
||||
#include "cursmisc.h"
|
||||
#include "cursdial.h"
|
||||
#include "func_tab.h"
|
||||
#include <ctype.h>
|
||||
@@ -151,8 +154,9 @@ curses_line_input_dialog(
|
||||
free(tmpstr);
|
||||
}
|
||||
|
||||
bwin = curses_create_window(prompt_width, height,
|
||||
bwin = curses_create_window(TEXT_WIN, prompt_width, height,
|
||||
iflags.window_inited ? UP : CENTER);
|
||||
curses_set_wid_colors(TEXT_WIN, bwin);
|
||||
wrefresh(bwin);
|
||||
getbegyx(bwin, winy, winx);
|
||||
askwin = newwin(height, prompt_width, winy + 1, winx + 1);
|
||||
@@ -277,7 +281,7 @@ curses_character_input_dialog(
|
||||
}
|
||||
|
||||
if (iflags.wc_popup_dialog /*|| curses_stupid_hack*/) {
|
||||
askwin = curses_create_window(prompt_width, prompt_height, UP);
|
||||
askwin = curses_create_window(TEXT_WIN, prompt_width, prompt_height, UP);
|
||||
activemenu = askwin;
|
||||
|
||||
for (count = 0; count < prompt_height; count++) {
|
||||
@@ -286,6 +290,7 @@ curses_character_input_dialog(
|
||||
free(linestr);
|
||||
}
|
||||
|
||||
curses_set_wid_colors(TEXT_WIN, askwin);
|
||||
wrefresh(askwin);
|
||||
} else {
|
||||
/* TODO: add SUPPRESS_HISTORY flag, then after getting a response,
|
||||
@@ -392,7 +397,8 @@ curses_ext_cmd(void)
|
||||
if (iflags.wc_popup_dialog) { /* Prompt in popup window */
|
||||
int x0, y0, w, h; /* bounding coords of popup */
|
||||
|
||||
extwin2 = curses_create_window(25, 1, UP);
|
||||
extwin2 = curses_create_window(TEXT_WIN, 25, 1, UP);
|
||||
curses_set_wid_colors(TEXT_WIN, extwin2);
|
||||
wrefresh(extwin2);
|
||||
/* create window inside window to prevent overwriting of border */
|
||||
getbegyx(extwin2, y0, x0);
|
||||
@@ -784,13 +790,14 @@ curses_display_nhmenu(
|
||||
|
||||
/* Display pre and post-game menus centered */
|
||||
if ((gm.moves <= 1 && !gi.invent) || gp.program_state.gameover) {
|
||||
win = curses_create_window(current_menu->width,
|
||||
win = curses_create_window(wid, current_menu->width,
|
||||
current_menu->height, CENTER);
|
||||
} else { /* Display during-game menus on the right out of the way */
|
||||
win = curses_create_window(current_menu->width,
|
||||
win = curses_create_window(wid, current_menu->width,
|
||||
current_menu->height, RIGHT);
|
||||
}
|
||||
|
||||
curses_set_wid_colors(wid, win);
|
||||
num_chosen = menu_get_selections(win, current_menu, how);
|
||||
curses_destroy_win(win);
|
||||
|
||||
@@ -1337,9 +1344,11 @@ menu_display_page(
|
||||
curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF);
|
||||
}
|
||||
}
|
||||
curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON);
|
||||
if (curses_win_clr_inited(MENU_WIN) < 1)
|
||||
curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON);
|
||||
box(win, 0, 0);
|
||||
curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF);
|
||||
if (curses_win_clr_inited(MENU_WIN) < 1)
|
||||
curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF);
|
||||
wrefresh(win);
|
||||
}
|
||||
|
||||
|
||||
@@ -297,6 +297,36 @@ curses_create_main_windows(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int pairs_used = 0;
|
||||
static int colors_used = 0;
|
||||
|
||||
/* create a new color */
|
||||
int
|
||||
curses_init_rgb(int r, int g, int b)
|
||||
{
|
||||
if (!can_change_color())
|
||||
return 0;
|
||||
|
||||
if (colors_used < COLORS - 1) {
|
||||
colors_used++;
|
||||
init_color(colors_used, r*4, g*4, b*4);
|
||||
return colors_used;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create a new foreground/background combination */
|
||||
int
|
||||
curses_init_pair(int fg, int bg)
|
||||
{
|
||||
if (pairs_used < COLOR_PAIRS - 1) {
|
||||
pairs_used++;
|
||||
init_pair(pairs_used, fg, bg);
|
||||
return pairs_used;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize curses colors to colors used by NetHack */
|
||||
void
|
||||
curses_init_nhcolors(void)
|
||||
@@ -335,6 +365,8 @@ curses_init_nhcolors(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
colors_used = maxc;
|
||||
pairs_used = (maxc * 8) + 16 + 1;
|
||||
}
|
||||
|
||||
#if 0 /* curses_choose_character + curses_character_dialog no longer used */
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
/* Global declarations */
|
||||
|
||||
void curses_create_main_windows(void);
|
||||
int curses_init_rgb(int r, int g, int b);
|
||||
int curses_init_pair(int fg, int bg);
|
||||
void curses_init_nhcolors(void);
|
||||
void curses_choose_character(void);
|
||||
int curses_character_dialog(const char **choices, const char *prompt);
|
||||
|
||||
@@ -54,7 +54,7 @@ static char *dummy_get_color_string(void);
|
||||
struct window_procs curses_procs = {
|
||||
WPID(curses),
|
||||
(WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR | WC_INVERSE
|
||||
| WC_HILITE_PET
|
||||
| WC_HILITE_PET | WC_WINDOWCOLORS
|
||||
#ifdef NCURSES_MOUSE_VERSION /* (this macro name works for PDCURSES too) */
|
||||
| WC_MOUSE_SUPPORT
|
||||
#endif
|
||||
@@ -426,6 +426,10 @@ curses_create_nhwindow(int type)
|
||||
{
|
||||
winid wid = curses_get_wid(type);
|
||||
|
||||
if (curses_is_menu(wid))
|
||||
curses_parse_wid_colors(MENU_WIN, iflags.wc_foregrnd_menu, iflags.wc_backgrnd_menu);
|
||||
else if (curses_is_text(wid))
|
||||
curses_parse_wid_colors(TEXT_WIN, iflags.wc_foregrnd_text, iflags.wc_backgrnd_text);
|
||||
if (curses_is_menu(wid) || curses_is_text(wid)) {
|
||||
curses_start_menu(wid, MENU_BEHAVE_STANDARD);
|
||||
curses_add_wid(wid);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "hack.h"
|
||||
#include "wincurs.h"
|
||||
#include "cursmesg.h"
|
||||
#include "curswins.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/* defined in sys/<foo>/<foo>tty.c or cursmain.c as last resort;
|
||||
@@ -106,6 +107,7 @@ curses_message_win_puts(const char *message, boolean recursed)
|
||||
return; /* user has typed ESC to avoid seeing remaining messages. */
|
||||
}
|
||||
|
||||
curses_set_wid_colors(MESSAGE_WIN, NULL);
|
||||
curses_get_window_size(MESSAGE_WIN, &height, &width);
|
||||
border_space = (border ? 1 : 0);
|
||||
if (mx < border_space)
|
||||
@@ -322,6 +324,7 @@ curses_block(
|
||||
}
|
||||
moreattr = !iflags.wc2_guicolor ? (int) A_REVERSE : NONE;
|
||||
curses_toggle_color_attr(win, MORECOLOR, moreattr, ON);
|
||||
curses_set_wid_colors(MESSAGE_WIN, NULL);
|
||||
if (blink) {
|
||||
wattron(win, A_BLINK);
|
||||
mvwprintw(win, my, mx, ">"), mx += 1;
|
||||
@@ -331,6 +334,7 @@ curses_block(
|
||||
mvwprintw(win, my, mx, ">>"), mx += 2;
|
||||
}
|
||||
curses_toggle_color_attr(win, MORECOLOR, moreattr, OFF);
|
||||
curses_set_wid_colors(MESSAGE_WIN, NULL);
|
||||
wrefresh(win);
|
||||
|
||||
/* cancel mesg suppression; all messages will have had chance to be read */
|
||||
@@ -379,6 +383,7 @@ curses_clear_unhighlight_message_window(void)
|
||||
WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
|
||||
|
||||
turn_lines = 0;
|
||||
curses_set_wid_colors(MESSAGE_WIN, NULL);
|
||||
curses_get_window_size(MESSAGE_WIN, &mh, &mw);
|
||||
|
||||
if (mh == 1) {
|
||||
@@ -413,6 +418,7 @@ curses_last_messages(void)
|
||||
int border = curses_window_has_border(MESSAGE_WIN) ? 1 : 0;
|
||||
WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
|
||||
|
||||
curses_set_wid_colors(MESSAGE_WIN, NULL);
|
||||
curses_get_window_size(MESSAGE_WIN, &height, &width);
|
||||
werase(win);
|
||||
mx = my = border;
|
||||
@@ -605,6 +611,7 @@ curses_count_window(const char *count_text)
|
||||
but not for dolook's autodescribe when it refers to a named monster */
|
||||
if (!countwin)
|
||||
countwin = newwin(1, messagew, winy, winx);
|
||||
curses_set_wid_colors(MESSAGE_WIN, NULL);
|
||||
werase(countwin);
|
||||
|
||||
mvwprintw(countwin, 0, 0, "%s", count_text);
|
||||
@@ -880,6 +887,7 @@ directional_scroll(winid wid, int nlines)
|
||||
boolean border = curses_window_has_border(wid);
|
||||
WINDOW *win = curses_get_nhwin(wid);
|
||||
|
||||
curses_set_wid_colors(wid, NULL);
|
||||
curses_get_window_size(wid, &wh, &ww);
|
||||
if (wh == 1) {
|
||||
curses_clear_nhwin(wid);
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
#include "curses.h"
|
||||
#include "hack.h"
|
||||
#include "wincurs.h"
|
||||
#include "cursinit.h"
|
||||
#include "cursmisc.h"
|
||||
#include "curswins.h"
|
||||
#include "cursstat.h"
|
||||
|
||||
/* Window handling for curses interface */
|
||||
|
||||
@@ -23,6 +26,9 @@ typedef struct nhw {
|
||||
int x; /* start of window on terminal (left) */
|
||||
int y; /* start of window on terminal (top) */
|
||||
int orientation; /* Placement of window relative to map */
|
||||
boolean clr_inited; /* fg/bg/colorpair inited? */
|
||||
int fg, bg; /* foreground, background color index */
|
||||
int colorpair; /* color pair of fg, bg */
|
||||
boolean border; /* Whether window has a visible border */
|
||||
} nethack_window;
|
||||
|
||||
@@ -52,7 +58,7 @@ static void clear_map(void);
|
||||
/* Create a window with the specified size and orientation */
|
||||
|
||||
WINDOW *
|
||||
curses_create_window(int width, int height, orient orientation)
|
||||
curses_create_window(int wid, int width, int height, orient orientation)
|
||||
{
|
||||
int mapx = 0, mapy = 0, maph = 0, mapw = 0;
|
||||
int startx = 0;
|
||||
@@ -142,12 +148,48 @@ curses_create_window(int width, int height, orient orientation)
|
||||
}
|
||||
|
||||
win = newwin(height, width, starty, startx);
|
||||
curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON);
|
||||
|
||||
if (curses_is_text(wid))
|
||||
wid = TEXT_WIN;
|
||||
else if (curses_is_menu(wid))
|
||||
wid = MENU_WIN;
|
||||
|
||||
if (nhwins[wid].clr_inited < 1)
|
||||
curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON);
|
||||
box(win, 0, 0);
|
||||
curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF);
|
||||
if (nhwins[wid].clr_inited < 1)
|
||||
curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF);
|
||||
return win;
|
||||
}
|
||||
|
||||
int
|
||||
curses_win_clr_inited(int wid)
|
||||
{
|
||||
if (curses_is_text(wid)) {
|
||||
wid = TEXT_WIN;
|
||||
} else if (curses_is_menu(wid)) {
|
||||
wid = MENU_WIN;
|
||||
}
|
||||
return nhwins[wid].clr_inited;
|
||||
}
|
||||
|
||||
void
|
||||
curses_set_wid_colors(int wid, WINDOW *win)
|
||||
{
|
||||
if (wid == TEXT_WIN || curses_is_text(wid)) {
|
||||
wid = TEXT_WIN;
|
||||
if (!nhwins[wid].clr_inited)
|
||||
curses_parse_wid_colors(wid, iflags.wc_foregrnd_text, iflags.wc_backgrnd_text);
|
||||
} else if (wid == MENU_WIN || curses_is_menu(wid)) {
|
||||
wid = MENU_WIN;
|
||||
if (!nhwins[wid].clr_inited)
|
||||
curses_parse_wid_colors(wid, iflags.wc_foregrnd_menu, iflags.wc_backgrnd_menu);
|
||||
}
|
||||
/* FIXME: colors and nhwins[] entry for perm invent window */
|
||||
if (nhwins[wid].clr_inited > 0) {
|
||||
wbkgd(win ? win : nhwins[wid].curwin, COLOR_PAIR(nhwins[wid].colorpair));
|
||||
}
|
||||
}
|
||||
|
||||
/* Erase and delete curses window, and refresh standard windows */
|
||||
|
||||
@@ -183,6 +225,7 @@ curses_refresh_nethack_windows(void)
|
||||
refresh();
|
||||
} else {
|
||||
if (status_window != NULL) {
|
||||
curses_set_wid_colors(STATUS_WIN, NULL);
|
||||
touchwin(status_window);
|
||||
wnoutrefresh(status_window);
|
||||
}
|
||||
@@ -191,6 +234,7 @@ curses_refresh_nethack_windows(void)
|
||||
wnoutrefresh(map_window);
|
||||
}
|
||||
if (message_window != NULL) {
|
||||
curses_set_wid_colors(MESSAGE_WIN, NULL);
|
||||
touchwin(message_window);
|
||||
wnoutrefresh(message_window);
|
||||
}
|
||||
@@ -217,6 +261,67 @@ curses_get_nhwin(winid wid)
|
||||
return nhwins[wid].curwin;
|
||||
}
|
||||
|
||||
boolean
|
||||
parse_hexstr(char *colorbuf, int *red, int *green, int *blue)
|
||||
{
|
||||
int len = colorbuf ? strlen(colorbuf) : 0;
|
||||
|
||||
if (len == 7 && colorbuf[0] == '#') {
|
||||
char tmpbuf[16];
|
||||
|
||||
Sprintf(tmpbuf, "0x%c%c", colorbuf[1], colorbuf[2]);
|
||||
*red = strtol(tmpbuf, NULL, 0);
|
||||
Sprintf(tmpbuf, "0x%c%c", colorbuf[3], colorbuf[4]);
|
||||
*green = strtol(tmpbuf, NULL, 0);
|
||||
Sprintf(tmpbuf, "0x%c%c", colorbuf[5], colorbuf[6]);
|
||||
*blue = strtol(tmpbuf, NULL, 0);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
curses_parse_wid_colors(int wid, char *fg, char *bg)
|
||||
{
|
||||
|
||||
if (curses_is_text(wid)) {
|
||||
wid = TEXT_WIN;
|
||||
} else if (curses_is_menu(wid)) {
|
||||
wid = MENU_WIN;
|
||||
}
|
||||
|
||||
if (nhwins[wid].clr_inited)
|
||||
return;
|
||||
|
||||
int nh_fg = fg ? match_str2clr(fg, TRUE) : CLR_MAX;
|
||||
int nh_bg = bg ? match_str2clr(bg, TRUE) : CLR_MAX;
|
||||
int r, g, b;
|
||||
|
||||
if (nh_fg == CLR_MAX) {
|
||||
if (fg && parse_hexstr(fg, &r, &g, &b)) {
|
||||
nh_fg = curses_init_rgb(r, g, b);
|
||||
} else {
|
||||
nh_fg = -1;
|
||||
}
|
||||
}
|
||||
if (nh_bg == CLR_MAX) {
|
||||
if (bg && parse_hexstr(bg, &r, &g, &b)) {
|
||||
nh_bg = curses_init_rgb(r, g, b);
|
||||
} else {
|
||||
nh_bg = -1;
|
||||
}
|
||||
}
|
||||
|
||||
nhwins[wid].fg = nh_fg;
|
||||
nhwins[wid].bg = nh_bg;
|
||||
if (nh_fg == -1 || nh_bg == -1) {
|
||||
nhwins[wid].clr_inited = -1;
|
||||
} else {
|
||||
nhwins[wid].colorpair = curses_init_pair(nh_fg, nh_bg);
|
||||
nhwins[wid].clr_inited = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Add curses window pointer and window info to list for given NetHack winid */
|
||||
|
||||
@@ -241,6 +346,9 @@ curses_add_nhwin(winid wid, int height, int width, int y, int x,
|
||||
nhwins[wid].x = x;
|
||||
nhwins[wid].y = y;
|
||||
nhwins[wid].orientation = orientation;
|
||||
nhwins[wid].fg = nhwins[wid].bg = 0;
|
||||
nhwins[wid].colorpair = -1;
|
||||
nhwins[wid].clr_inited = 0;
|
||||
|
||||
if (border) {
|
||||
real_width += 2; /* leave room for bounding box */
|
||||
@@ -248,13 +356,18 @@ curses_add_nhwin(winid wid, int height, int width, int y, int x,
|
||||
}
|
||||
|
||||
win = newwin(real_height, real_width, y, x);
|
||||
nhwins[wid].curwin = win;
|
||||
|
||||
switch (wid) {
|
||||
case MESSAGE_WIN:
|
||||
messagewin = win;
|
||||
curses_parse_wid_colors(wid, iflags.wc_foregrnd_message, iflags.wc_backgrnd_message);
|
||||
curses_set_wid_colors(wid, NULL);
|
||||
break;
|
||||
case STATUS_WIN:
|
||||
statuswin = win;
|
||||
curses_parse_wid_colors(wid, iflags.wc_foregrnd_status, iflags.wc_backgrnd_status);
|
||||
curses_set_wid_colors(wid, NULL);
|
||||
break;
|
||||
case MAP_WIN:
|
||||
mapwin = win;
|
||||
@@ -266,7 +379,6 @@ curses_add_nhwin(winid wid, int height, int width, int y, int x,
|
||||
box(win, 0, 0);
|
||||
}
|
||||
|
||||
nhwins[wid].curwin = win;
|
||||
}
|
||||
|
||||
|
||||
@@ -301,6 +413,7 @@ curses_add_wid(winid wid)
|
||||
void
|
||||
curses_refresh_nhwin(winid wid)
|
||||
{
|
||||
curses_set_wid_colors(wid, NULL);
|
||||
wnoutrefresh(curses_get_nhwin(wid));
|
||||
doupdate();
|
||||
}
|
||||
@@ -523,6 +636,7 @@ curses_puts(winid wid, int attr, const char *text)
|
||||
}
|
||||
#endif
|
||||
|
||||
curses_set_wid_colors(wid, NULL);
|
||||
if (curses_is_menu(wid) || curses_is_text(wid)) {
|
||||
if (!curses_menu_exists(wid)) {
|
||||
impossible(
|
||||
@@ -553,6 +667,7 @@ curses_clear_nhwin(winid wid)
|
||||
clear_map();
|
||||
}
|
||||
|
||||
curses_set_wid_colors(wid, NULL);
|
||||
werase(win);
|
||||
|
||||
if (border) {
|
||||
@@ -568,6 +683,7 @@ curses_alert_win_border(winid wid, boolean onoff)
|
||||
|
||||
if (!win || !curses_window_has_border(wid))
|
||||
return;
|
||||
curses_set_wid_colors(wid, NULL);
|
||||
if (onoff)
|
||||
curses_toggle_color_attr(win, ALERT_BORDER_COLOR, NONE, ON);
|
||||
box(win, 0, 0);
|
||||
|
||||
@@ -9,11 +9,15 @@
|
||||
|
||||
/* Global declarations */
|
||||
|
||||
WINDOW *curses_create_window(int width, int height, orient orientation);
|
||||
WINDOW *curses_create_window(int wid, int width, int height, orient orientation);
|
||||
|
||||
int curses_win_clr_inited(int wid);
|
||||
void curses_set_wid_colors(int wid, WINDOW *win);
|
||||
void curses_destroy_win(WINDOW * win);
|
||||
void curses_refresh_nethack_windows(void);
|
||||
WINDOW *curses_get_nhwin(winid wid);
|
||||
void curses_parse_wid_colors(int wid, char *fg, char *bg);
|
||||
boolean parse_hexstr(char *colorbuf, int *red, int *green, int *blue);
|
||||
void curses_add_nhwin(winid wid, int height, int width, int y, int x,
|
||||
orient orientation, boolean border);
|
||||
void curses_add_wid(winid wid);
|
||||
|
||||
Reference in New Issue
Block a user