Ejemplo n.º 1
0
/* Draws possibly centered formatted message with specified title and control
 * message on error_win. */
static void
draw_msg(const char title[], const char msg[], const char ctrl_msg[],
		int centered, int recommended_width)
{
	enum { margin = 1 };

	int sw, sh;
	int w, h;
	int len;
	size_t ctrl_msg_n;
	size_t wctrl_msg;
	size_t i;

	curs_set(FALSE);

	getmaxyx(stdscr, sh, sw);

	ctrl_msg_n = MAX(measure_sub_lines(ctrl_msg, &wctrl_msg), 1U);

	h = sh - 2 - ctrl_msg_n + !cfg.display_statusline;
	/* The outermost condition is for VLA below (to calm static analyzers). */
	w = MAX(2 + 2*margin, MIN(sw - 2,
	        MAX(MAX(recommended_width, sw/3),
	            (int)MAX(wctrl_msg, determine_width(msg)) + 4)));
	wresize(error_win, h, w);

	werase(error_win);

	len = strlen(msg);
	if(len <= w - 2 && strchr(msg, '\n') == NULL)
	{
		h = 5 + ctrl_msg_n;
		wresize(error_win, h, w);
		mvwin(error_win, (sh - h)/2, (sw - w)/2);
		checked_wmove(error_win, 2, (w - len)/2);
		wprint(error_win, msg);
	}
	else
	{
		int i;
		int cy = 2;
		i = 0;
		while(i < len)
		{
			int j;
			char buf[w - 2 - 2*margin + 1];
			int cx;

			copy_str(buf, sizeof(buf), msg + i);

			for(j = 0; buf[j] != '\0'; j++)
				if(buf[j] == '\n')
					break;

			if(buf[j] != '\0')
				i++;
			buf[j] = '\0';
			i += j;

			if(buf[0] == '\0')
				continue;

			h = cy + 4;
			wresize(error_win, h, w);
			mvwin(error_win, (sh - h)/2, (sw - w)/2);

			cx = centered ? (w - utf8_strsw(buf))/2 : (1 + margin);
			checked_wmove(error_win, cy++, cx);
			wprint(error_win, buf);
		}
	}

	box(error_win, 0, 0);
	if(title[0] != '\0')
	{
		mvwprintw(error_win, 0, (w - strlen(title) - 2)/2, " %s ", title);
	}

	/* Print control message line by line. */
	for(i = ctrl_msg_n; i > 0U; --i)
	{
		const size_t len = strcspn(ctrl_msg, "\n");
		mvwaddnstr(error_win, h - i - 1, MAX(0, (w - (int)len)/2), ctrl_msg, len);
		ctrl_msg = skip_char(ctrl_msg + len + 1U, '/');
	}
}
Ejemplo n.º 2
0
/* Draws possibly centered formatted message with specified title and control
 * message on error_win. */
static void
draw_msg(const char title[], const char msg[], const char ctrl_msg[],
		int centered, int recommended_width)
{
	enum { margin = 1 };

	int sw, sh;
	int w, h;
	int max_h;
	int len;
	size_t ctrl_msg_n;
	size_t wctrl_msg;
	size_t i;
	int first_line_x = 1;
	const int first_line_y = 2;

	curs_set(0);

	getmaxyx(stdscr, sh, sw);

	ctrl_msg_n = MAX(measure_sub_lines(ctrl_msg, &wctrl_msg), 1U);

	max_h = sh - 2 - ctrl_msg_n + !cfg.display_statusline;
	h = max_h;
	/* The outermost condition is for VLA below (to calm static analyzers). */
	w = MAX(2 + 2*margin, MIN(sw - 2,
	        MAX(MAX(recommended_width, sw/3),
	            (int)MAX(wctrl_msg, determine_width(msg)) + 4)));
	wresize(error_win, h, w);

	werase(error_win);

	len = strlen(msg);
	if(len <= w - 2 && strchr(msg, '\n') == NULL)
	{
		first_line_x = (w - len)/2;
		h = 5 + ctrl_msg_n;
		wresize(error_win, h, w);
		mvwin(error_win, (sh - h)/2, (sw - w)/2);
		checked_wmove(error_win, first_line_y, first_line_x);
		wprint(error_win, msg);
	}
	else
	{
		int i = 0;
		int cy = first_line_y;
		while(i < len)
		{
			int j;
			char buf[w - 2 - 2*margin + 1];
			int cx;

			copy_str(buf, sizeof(buf), msg + i);

			for(j = 0; buf[j] != '\0'; j++)
				if(buf[j] == '\n')
					break;

			if(buf[j] != '\0')
				i++;
			buf[j] = '\0';
			i += j;

			if(buf[0] == '\0')
				continue;

			if(cy >= max_h - (int)ctrl_msg_n - 3)
			{
				/* Skip trailing part of the message if it's too long, just print how
				 * many lines we're omitting. */
				size_t max_len;
				const int more_lines = 1U + measure_sub_lines(msg + i, &max_len);
				snprintf(buf, sizeof(buf), "<<%d more line%s not shown>>", more_lines,
						(more_lines == 1) ? "" : "s");
				/* Make sure this is the last iteration of the loop. */
				i = len;
			}

			h = 1 + cy + 1 + ctrl_msg_n + 1;
			wresize(error_win, h, w);
			mvwin(error_win, (sh - h)/2, (sw - w)/2);

			cx = centered ? (w - utf8_strsw(buf))/2 : (1 + margin);
			if(cy == first_line_y)
			{
				first_line_x = cx;
			}
			checked_wmove(error_win, cy++, cx);
			wprint(error_win, buf);
		}
	}

	box(error_win, 0, 0);
	if(title[0] != '\0')
	{
		mvwprintw(error_win, 0, (w - strlen(title) - 2)/2, " %s ", title);
	}

	/* Print control message line by line. */
	for(i = ctrl_msg_n; i > 0U; --i)
	{
		const size_t len = strcspn(ctrl_msg, "\n");
		mvwaddnstr(error_win, h - i - 1, MAX(0, (w - (int)len)/2), ctrl_msg, len);
		ctrl_msg = skip_char(ctrl_msg + len + 1U, '/');
	}

	checked_wmove(error_win, first_line_y, first_line_x);
}