10. 颜色

10.1. 基础知识

没有颜色的生活似乎很单调。Curses 有一个很好的机制来处理颜色。让我们通过一个小程序深入了解一下。

示例 9. 一个简单的颜色示例

#include <ncurses.h>

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string);
int main(int argc, char *argv[])
{	initscr();			/* Start curses mode 		*/
	if(has_colors() == FALSE)
	{	endwin();
		printf("Your terminal does not support color\n");
		exit(1);
	}
	start_color();			/* Start color 			*/
	init_pair(1, COLOR_RED, COLOR_BLACK);

	attron(COLOR_PAIR(1));
	print_in_middle(stdscr, LINES / 2, 0, 0, "Viola !!! In color ...");
	attroff(COLOR_PAIR(1));
    	getch();
	endwin();
}
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string)
{	int length, x, y;
	float temp;

	if(win == NULL)
		win = stdscr;
	getyx(win, y, x);
	if(startx != 0)
		x = startx;
	if(starty != 0)
		y = starty;
	if(width == 0)
		width = 80;

	length = strlen(string);
	temp = (width - length)/ 2;
	x = startx + (int)temp;
	mvwprintw(win, y, x, "%s", string);
	refresh();
}

如您所见,要开始使用颜色,您应该首先调用函数start_color()。之后,您可以使用终端的颜色功能,使用各种函数。要了解终端是否具有颜色功能,您可以使用has_colors()函数,如果终端不支持颜色,则返回 FALSE。

当调用 start_color() 时,Curses 会初始化终端支持的所有颜色。这些颜色可以通过类似以下的定义常量来访问COLOR_BLACK等等。现在要真正开始使用颜色,您必须定义颜色对。颜色总是成对使用。这意味着您必须使用函数init_pair()来为您给定的颜色对编号定义前景色和背景色。之后,该颜色对编号可以像普通属性一样与COLOR_PAIR()函数一起使用。乍一看这似乎很麻烦。但是这种优雅的解决方案使我们能够非常轻松地管理颜色对。为了体会到它的优点,您必须查看 “dialog” 的源代码,这是一个用于从 shell 脚本显示对话框的实用程序。开发人员为他们可能需要的所有颜色定义了前景色和背景色组合,并在开始时进行了初始化。这使得仅通过访问我们已经定义为常量的颜色对来设置属性变得非常容易。

以下颜色在curses.h中定义。您可以将这些用作各种颜色函数的参数。

        COLOR_BLACK   0
        COLOR_RED     1
        COLOR_GREEN   2
        COLOR_YELLOW  3
        COLOR_BLUE    4
        COLOR_MAGENTA 5
        COLOR_CYAN    6
        COLOR_WHITE   7

10.2. 更改颜色定义

函数init_color()可用于更改 curses 最初定义的颜色的 rgb 值。假设您想稍微降低红色颜色的强度。那么您可以使用此函数,如下所示

    init_color(COLOR_RED, 700, 0, 0);
    /* param 1     : color name
     * param 2, 3, 4 : rgb content min = 0, max = 1000 */

如果您的终端无法更改颜色定义,则该函数返回 ERR。函数can_change_color()可用于确定终端是否具有更改颜色内容的功能。rgb 内容的范围从 0 到 1000。最初,红色定义为内容 1000(r)、0(g)、0(b)。

10.3. 颜色内容

函数color_content()pair_content()可用于查找颜色内容以及颜色对的前景色、背景色组合。