Beispiel #1
0
void
dlg_format_group(struct dialog_data *dlg_data,
		 struct widget_data *widget_data,
		 int n, int x, int *y, int w, int *rw, int format_only)
{
	struct terminal *term = dlg_data->win->term;
	int space_between_widgets = 1;
	int line_width = 0;
	int xpos;
	struct color_pair *color = get_bfu_color(term, "dialog.text");

	assert(n > 0);
	if_assert_failed return;

	while (n--) {
		int widget_width;
		int width;
		unsigned char *text = widget_data->widget->text;
		int label_length;
		int label_padding;

#ifdef CONFIG_UTF8
		if (term->utf8_cp) {
			if (text && *text)
				label_length = utf8_ptr2cells(text, NULL);
			else
				label_length = 0;
		} else
#endif /* CONFIG_UTF8 */
			label_length = (text && *text) ? strlen(text) : 0;

		label_padding = (label_length > 0);

		if (widget_data->widget->type == WIDGET_CHECKBOX) {
			width = CHECKBOX_LEN;
		} else if (widget_is_textfield(widget_data)) {
#ifdef CONFIG_UTF8
			if (term->utf8_cp) {
				width = utf8_ptr2cells(widget_data->widget->data,
						       NULL);
			} else
#endif /* CONFIG_UTF8 */
				width = widget_data->widget->datalen;
		} else {
			/* TODO: handle all widget types. */
			widget_data++;
			continue;
		}

		int_bounds(&label_length, 0, w - width - label_padding);

		widget_width = width + label_padding + label_length;
		if (line_width + widget_width > w) {
			line_width = 0;
			(*y) += 2;	/* Next line */
		}

		xpos = x + line_width;

		if (!format_only) {
			if (widget_data->widget->type == WIDGET_CHECKBOX) {
				/* Draw text at right of checkbox. */
				if (label_length) {
#ifdef CONFIG_UTF8
					if (term->utf8_cp) {
						int lb = utf8_cells2bytes(
								text,
								label_length,
								NULL);
						draw_dlg_text(dlg_data, xpos + width
								+ label_padding,
							  *y, text, lb, 0,
							  color);
					} else
#endif /* CONFIG_UTF8 */
					{
						draw_dlg_text(dlg_data, xpos + width
								+ label_padding,
							  *y, text,
							  label_length, 0,
							  color);
					}
				}

				set_box(&widget_data->box, xpos, *y, width, 1);

			} else if (widget_is_textfield(widget_data)) {
				/* Draw label at left of widget. */
				if (label_length) {
#ifdef CONFIG_UTF8
					if (term->utf8_cp) {
						int lb = utf8_cells2bytes(
								text,
								label_length,
								NULL);
						draw_dlg_text(dlg_data, xpos, *y,
							  text, lb, 0, color);
					} else
#endif /* CONFIG_UTF8 */
					{
						draw_dlg_text(dlg_data, xpos, *y,
							  text, label_length,
							  0, color);
					}
				}

				set_box(&widget_data->box,
					xpos + label_padding + label_length, *y,
					width, 1);
			}
		}

		line_width += widget_width;
		if (rw) int_bounds(rw, line_width, w);
		line_width += space_between_widgets;

		widget_data++;
	}
	(*y)++;
}
Beispiel #2
0
/* Takes care about rendering of each listbox item. */
static int
display_listbox_item(struct listbox_item *item, void *data_, int *offset)
{
	struct listbox_context *data = (struct listbox_context *)data_;
	int len; /* Length of the current text field. */
	struct color_pair *tree_color, *text_color;
	int depth = item->depth + 1;
	int d;
	int x, y;

	tree_color = get_bfu_color(data->term, (const unsigned char *)"menu.normal");
	if (item == data->box->sel) {
		text_color = get_bfu_color(data->term, (const unsigned char *)"menu.selected");

	} else if (item->marked) {
		text_color = get_bfu_color(data->term, (const unsigned char *)"menu.marked");

	} else {
		text_color = tree_color;
	}

	y = data->widget_data->box.y + data->offset;
	for (d = 0; d < depth - 1; d++) {
		struct listbox_item *root = item;
		struct listbox_item *child = item;
		int i, x;

		for (i = depth - d; i; i--) {
			child = root;
			if (root) root = data->box->ops->get_root(root);
		}

		/* XXX */
		x = data->widget_data->box.x + d * 5;
		draw_text(data->term, x, y, (const unsigned char *)"     ", 5, 0, tree_color);

		if (root ? root->child.prev == child
			 : data->box->items->prev == child)
			continue; /* We were the last branch. */

		draw_border_char(data->term, x + 1, y, BORDER_SVLINE, tree_color);
	}

	if (depth) {
		unsigned char str[5] =
			{ 32, BORDER_SRTEE, BORDER_SHLINE, BORDER_SHLINE, 32 };
		int i;

		switch (item->type) {
		case BI_LEAF:
		case BI_SEPARATOR:
		{
			const struct listbox_item *prev;

			prev = traverse_listbox_items_list(item, data->box,
			                                   -1, 1, NULL, NULL);

			if (item == prev) {
				/* There is no visible item before @item, so it
				 * must be the first item in the listbox. */
				str[1] = BORDER_SULCORNER;
			} else {
				const struct listbox_item *next;

				next = traverse_listbox_items_list(item,
				                  data->box, 1, 1, NULL, NULL);

				if (item == next
				    || item->depth != next->depth) {
					/* There is no visible item after @item
					 * at the same depth, so it must be the
					 * last in its folder. */
					str[1] = BORDER_SDLCORNER;
				}
			}
			break;
		}
		case BI_FOLDER:
			str[0] = '[';
			str[1] = (item->expanded) ? '-' : '+';
			str[2] = ']';
			break;
		default:
			INTERNAL("Unknown item type");
			break;
		}

		if (item->marked) str[4] = '*';

		x = data->widget_data->box.x + (depth - 1) * 5;
		for (i = 0; i < 5; i++) {
			draw_border_char(data->term, x + i, y, str[i], tree_color);
		}
	}

	x = data->widget_data->box.x + depth * 5;

	if (item->type == BI_SEPARATOR) {
		int i;
		int width = data->widget_data->box.width - depth * 5;

		for (i = 0; i < width; i++) {
			draw_border_char(data->term, x + i, y, BORDER_SHLINE, text_color);
		}

	} else if (data->box->ops && data->box->ops->draw) {
		int width = data->widget_data->box.width - depth * 5;

		data->box->ops->draw(item, data, x, y, width);

	} else {
		unsigned char *text;
		const struct listbox_ops *ops = data->box->ops;
		int len_bytes;

		assert(ops && ops->get_info);

		text = ops->get_text(item, data->term);
		if (!text) return 0;

		len = strlen((const char *)text);
		int_upper_bound(&len, int_max(0, data->widget_data->box.width - depth * 5));
#ifdef CONFIG_UTF8
		if (data->term->utf8_cp)
			len_bytes = utf8_cells2bytes(text, len, NULL);
		else
#endif /* CONFIG_UTF8 */
			len_bytes = len;

		draw_text(data->term, x, y, text, len_bytes, 0, text_color);

		mem_free(text);
	}

	if (item == data->box->sel) {
		/* For blind users: */
		x = data->widget_data->box.x + 5 + item->depth * 5;
		set_cursor(data->term, x, y, 1);
		set_window_ptr(data->dlg_data->win, x, y);
	}

	data->offset++;

	return 0;
}
Beispiel #3
0
static widget_handler_status_T
display_button(struct dialog_data *dlg_data, struct widget_data *widget_data)
{
	struct terminal *term = dlg_data->win->term;
	struct color_pair *color, *shortcut_color;
	struct el_box *pos = &widget_data->box;
	int len, x;
	int sel = is_selected_widget(dlg_data, widget_data);

	if (sel) {
		shortcut_color = get_bfu_color(term, "dialog.button-shortcut-selected");
		color =  get_bfu_color(term, "dialog.button-selected");
	} else {
		shortcut_color = get_bfu_color(term, "dialog.button-shortcut");
		color =  get_bfu_color(term, "dialog.button");
	}
	if (!color || !shortcut_color) return EVENT_PROCESSED;

#ifdef CONFIG_UTF8
	if (term->utf8_cp) {
		int button_left_len = utf8_ptr2cells(BUTTON_LEFT, NULL);
		int button_right_len = utf8_ptr2cells(BUTTON_RIGHT, NULL);

		x = pos->x + button_left_len;
		len = widget_data->box.width -
			(button_left_len + button_right_len);

	} else
#endif /* CONFIG_UTF8 */
	{
		x = pos->x + BUTTON_LEFT_LEN;
		len = widget_data->box.width - BUTTON_LR_LEN;
	}


	draw_dlg_text(dlg_data, pos->x, pos->y, BUTTON_LEFT, BUTTON_LEFT_LEN, 0, color);
	if (len > 0) {
		unsigned char *text = widget_data->widget->text;
		int hk_pos = widget_data->widget->info.button.hotkey_pos;
		int attr;

		attr = get_opt_bool("ui.dialogs.underline_button_shortcuts",
		                    NULL)
		     ? SCREEN_ATTR_UNDERLINE : 0;

#ifdef CONFIG_UTF8
		if (term->utf8_cp) {
			if (hk_pos >= 0) {
				int hk_bytes = utf8charlen(&text[hk_pos+1]);
				int cells_to_hk = utf8_ptr2cells(text,
						&text[hk_pos]);
				int right = widget_data->widget->info.button.truetextlen
					- hk_pos
					- hk_bytes;

				int hk_cells = utf8_char2cells(&text[hk_pos
								      + 1],
								NULL);

				if (hk_pos)
					draw_dlg_text(dlg_data, x, pos->y,
						  text, hk_pos, 0, color);

				draw_dlg_text(dlg_data, x + cells_to_hk, pos->y,
					  &text[hk_pos + 1], hk_bytes,
					  attr, shortcut_color);

				if (right > 1)
					draw_dlg_text(dlg_data, x+cells_to_hk+hk_cells,
						  pos->y,
						  &text[hk_pos + hk_bytes + 1],
						  right - 1, 0, color);

			} else {
				int hk_width = utf8_char2cells(text, NULL);
				int hk_len = utf8charlen(text);
				int len_to_display =
					utf8_cells2bytes(&text[hk_len],
							 len - hk_width,
							 NULL);

				draw_dlg_text(dlg_data, x, pos->y,
					  text, hk_len,
					  attr, shortcut_color);

				draw_dlg_text(dlg_data, x + hk_width, pos->y,
					  &text[hk_len], len_to_display,
					  0, color);
			}
		} else
#endif /* CONFIG_UTF8 */
		if (hk_pos >= 0) {
			int right = widget_data->widget->info.button.truetextlen - hk_pos - 1;

			if (hk_pos) {
				draw_dlg_text(dlg_data, x, pos->y, text, hk_pos, 0, color);
			}
			draw_dlg_text(dlg_data, x + hk_pos, pos->y,
				  &text[hk_pos + 1], 1, attr, shortcut_color);
			if (right > 1) {
				draw_dlg_text(dlg_data, x + hk_pos + 1, pos->y,
					  &text[hk_pos + 2], right - 1, 0, color);
			}

		} else {
			draw_dlg_text(dlg_data, x, pos->y, text, 1, attr, shortcut_color);
			draw_dlg_text(dlg_data, x + 1, pos->y, &text[1], len - 1, 0, color);
		}
	}
#ifdef CONFIG_UTF8
	if (term->utf8_cp) {
		int text_cells = utf8_ptr2cells(widget_data->widget->text, NULL);
		int hk = (widget_data->widget->info.button.hotkey_pos >= 0);

		draw_dlg_text(dlg_data, x + text_cells - hk, pos->y,
			  BUTTON_RIGHT, BUTTON_RIGHT_LEN, 0, color);
	} else
#endif /* CONFIG_UTF8 */
		draw_dlg_text(dlg_data, x + len, pos->y, BUTTON_RIGHT,
			  BUTTON_RIGHT_LEN, 0, color);
	if (sel) {
		set_dlg_cursor(term, dlg_data, x, pos->y, 1);
		set_dlg_window_ptr(dlg_data, dlg_data->win, pos->x, pos->y);
	}
	return EVENT_PROCESSED;
}
Beispiel #4
0
static void
draw_textarea_utf8(struct terminal *term, struct form_state *fs,
	      struct document_view *doc_view, struct link *link)
{
	struct line_info *line, *linex;
	struct form_control *fc;
	struct box *box;
	int vx, vy;
	int sl, ye;
	int x, xbase, y;

	assert(term && doc_view && doc_view->document && doc_view->vs && link);
	if_assert_failed return;
	fc = get_link_form_control(link);
	assertm(fc != NULL, "link %d has no form control", (int) (link - doc_view->document->links));
	if_assert_failed return;

	box = &doc_view->box;
	vx = doc_view->vs->x;
	vy = doc_view->vs->y;

	if (!link->npoints) return;
	area_cursor(fc, fs, 1);
	linex = format_textutf8(fs->value, fc->cols, fc->wrap, 0);
	if (!linex) return;
	line = linex;
	sl = fs->vypos;
	while (line->start != -1 && sl) sl--, line++;

	xbase = link->points[0].x + box->x - vx;
	y = link->points[0].y + box->y - vy;
	ye = y + fc->rows;

	for (; line->start != -1 && y < ye; line++, y++) {
		int i;
		unsigned char *text, *end;

		text = fs->value + line->start;
		end = fs->value + line->end;

		text += utf8_cells2bytes(text, fs->vpos, end);

		if (!row_is_in_box(box, y)) continue;

		for (i = 0, x = xbase; i < fc->cols; i++, x++) {
			unicode_val_T data;

			if (i >= -fs->vpos && text < end) {
				/* utf8_to_unicode will increment text. */
				data = utf8_to_unicode(&text, end);
			} else
				data = '_';

			if (col_is_in_box(box, x)) {
				int cell = unicode_to_cell(data);

				if (cell == 2) {
					draw_char_data(term, x++, y, data);
					i++;
					data = UCS_NO_CHAR;
				}

				draw_char_data(term, x, y, data);
			}
		}
	}

	for (; y < ye; y++) {
		int i;

		if (!row_is_in_box(box, y)) continue;

		for (i = 0, x = xbase; i < fc->cols; i++, x++) {
			if (col_is_in_box(box, x))
				draw_char_data(term, x, y, '_');
		}
	}

	mem_free(linex);
}