Example #1
0
static widget_handler_status_T
display_checkbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
{
	struct terminal *term = dlg_data->win->term;
	struct color_pair *color;
	unsigned char *text;
	struct el_box *pos = &widget_data->box;
	int selected = is_selected_widget(dlg_data, widget_data);

	if (selected) {
		color = get_bfu_color(term, "dialog.checkbox-selected");
	} else {
		color = get_bfu_color(term, "dialog.checkbox");
	}
	if (!color) return EVENT_PROCESSED;

	if (widget_data->info.checkbox.checked)
		text = widget_data->widget->info.checkbox.gid ? "(X)" : "[X]";
	else
		text = widget_data->widget->info.checkbox.gid ? "( )" : "[ ]";

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

	if (selected) {
		set_dlg_cursor(term, dlg_data, pos->x + 1, pos->y, 1);
		set_dlg_window_ptr(dlg_data, dlg_data->win, pos->x, pos->y);
	}

	return EVENT_PROCESSED;
}
Example #2
0
static void
draw_file_download(struct listbox_item *item, struct listbox_context *context,
		   int x, int y, int width)
{
	struct file_download *file_download = item->udata;
	struct download *download = &file_download->download;
	unsigned char *stylename;
	struct color_pair *color;
	unsigned char *text;
	int length;
	int trimmedlen;
	int meter = DOWNLOAD_METER_WIDTH;

	/* We have nothing to work with */
	if (width < 4) return;

	stylename = (item == context->box->sel) ? "menu.selected"
		  : ((item->marked)	        ? "menu.marked"
					        : "menu.normal");

	color = get_bfu_color(context->term, stylename);

	text = get_file_download_text(item, context->term);
	if (!text) return;

	length = strlen(text);
	/* Show atleast the required percentage of the URI */
	if (length * DOWNLOAD_URI_PERCENTAGE / 100 < width - meter - 4) {
		trimmedlen = int_min(length, width - meter - 4);
	} else {
		trimmedlen = int_min(length, width - 3);
	}

	draw_text(context->term, x, y, text, trimmedlen, 0, color);
	if (trimmedlen < length) {
		draw_text(context->term, x + trimmedlen, y, "...", 3, 0, color);
		trimmedlen += 3;
	}

	mem_free(text);

	if (!download->progress
	    || download->progress->size < 0
	    || !is_in_state(download->state, S_TRANS)
	    || !has_progress(download->progress)) {
		/* TODO: Show trimmed error message. */
		return;
	}

	if (!dialog_has_refresh(context->dlg_data))
		refresh_dialog(context->dlg_data, refresh_file_download, NULL);

	if (trimmedlen + meter >= width) return;

	x += width - meter;

	draw_progress_bar(download->progress, context->term, x, y, meter, NULL, NULL);
}
Example #3
0
void
draw_progress_bar(struct progress *progress, struct terminal *term,
		  int x, int y, int width,
		  unsigned char *text, struct color_pair *meter_color)
{
	/* Note : values > 100% are theorically possible and were seen. */
	int percent = 0;
	struct box barprogress;

	if (progress->size > 0)
		percent = (int) ((longlong) 100 * progress->pos / progress->size);

	/* Draw the progress meter part "[###    ]" */
	if (!text && width > 2) {
		width -= 2;
		draw_text(term, x++, y, "[", 1, 0, NULL);
		draw_text(term, x + width, y, "]", 1, 0, NULL);
	}

	if (!meter_color) meter_color = get_bfu_color(term, "dialog.meter");
	set_box(&barprogress,
		x, y, int_min(width * percent / 100, width), 1);
	draw_box(term, &barprogress, ' ', 0, meter_color);

	/* On error, will print '?' only, should not occur. */
	if (text) {
		width = int_min(width, strlen(text));

	} else if (width > 1) {
		static unsigned char s[] = "????"; /* Reduce or enlarge at will. */
		unsigned int slen = 0;
		int max = int_min(sizeof(s), width) - 1;

		if (ulongcat(s, &slen, percent, max, 0)) {
			s[0] = '?';
			slen = 1;
		}

		s[slen++] = '%';

		/* Draw the percentage centered in the progress meter */
		x += (1 + width - slen) / 2;

		assert(slen <= width);
		width = slen;
		text = s;
	}

	draw_text(term, x, y, text, width, 0, NULL);
}
Example #4
0
void
dlg_format_checkbox(struct dialog_data *dlg_data,
		    struct widget_data *widget_data,
		    int x, int *y, int w, int *rw,
		    enum format_align align, int format_only)
{
	struct terminal *term = dlg_data->win->term;
	unsigned char *text = widget_data->widget->text;

	set_box(&widget_data->box, x, *y, CHECKBOX_LEN, CHECKBOX_HEIGHT);

	if (w <= CHECKBOX_LS) return;

	if (text && *text) {
		if (rw) *rw -= CHECKBOX_LS;
		dlg_format_text_do(dlg_data, text, x + CHECKBOX_LS, y,
				   w - CHECKBOX_LS, rw,
				   get_bfu_color(term, "dialog.checkbox-label"),
				   align, format_only);
		if (rw) *rw += CHECKBOX_LS;
	}
}
Example #5
0
/* Displays a dialog box */
static widget_handler_status_T
display_listbox(struct dialog_data *dlg_data, struct widget_data *widget_data)
{
	struct terminal *term = dlg_data->win->term;
	struct listbox_data *box = get_listbox_widget_data(widget_data);
	struct listbox_context data;

	listbox_sel_move(widget_data, 0);

	draw_box(term, &widget_data->box, ' ', 0,
		 get_bfu_color(term, (const unsigned char *)"menu.normal"));

	memset(&data, 0, sizeof(data));
	data.term = term;
	data.widget_data = widget_data;
	data.box = box;
	data.dlg_data = dlg_data;

	traverse_listbox_items_list(box->top, box, widget_data->box.height,
				    1, display_listbox_item, &data);

	return EVENT_PROCESSED;
}
Example #6
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)++;
}
Example #7
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;
}
Example #8
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;
}
Example #9
0
static void
download_dialog_layouter(struct dialog_data *dlg_data)
{
	struct file_download *file_download = dlg_data->dlg->udata;
	struct terminal *term = dlg_data->win->term;
	int w = dialog_max_width(term);
	int rw = w;
	int x, y = 0;
	int url_len;
	unsigned char *url;
	struct download *download = &file_download->download;
	struct color_pair *dialog_text_color = get_bfu_color(term, "dialog.text");
	unsigned char *msg = get_download_msg(download, term, 1, 1, "\n");
	int show_meter = (download_is_progressing(download)
			  && download->progress->size >= 0);
#if CONFIG_BITTORRENT
	int bittorrent = (file_download->uri->protocol == PROTOCOL_BITTORRENT
			  && (show_meter || is_in_state(download->state, S_RESUME)));
#endif

	redraw_windows(REDRAW_BEHIND_WINDOW, dlg_data->win);
	file_download->dlg_data = dlg_data;

	if (!msg) return;

	url = get_uri_string(file_download->uri, URI_PUBLIC);
	if (!url) {
		mem_free(msg);
		return;
	}
#ifdef CONFIG_UTF8
	if (term->utf8_cp)
		decode_uri(url);
	else
#endif /* CONFIG_UTF8 */
		decode_uri_for_display(url);
	url_len = strlen(url);

	if (show_meter) {
		int_lower_bound(&w, DOWN_DLG_MIN);
	}

	dlg_format_text_do(dlg_data, url, 0, &y, w, &rw,
			dialog_text_color, ALIGN_LEFT, 1);

	y++;
	if (show_meter) y += 2;

#if CONFIG_BITTORRENT
	if (bittorrent) y += 2;
#endif
	dlg_format_text_do(dlg_data, msg, 0, &y, w, &rw,
			dialog_text_color, ALIGN_LEFT, 1);

	y++;
	dlg_format_buttons(dlg_data, dlg_data->widgets_data,
			   dlg_data->number_of_widgets, 0, &y, w,
			   &rw, ALIGN_CENTER, 1);

	draw_dialog(dlg_data, w, y);

	w = rw;
	if (url_len > w) {
		/* Truncate too long urls */
		url_len = w;
		url[url_len] = '\0';
		if (url_len > 4) {
			url[--url_len] = '.';
			url[--url_len] = '.';
			url[--url_len] = '.';
		}
	}

	y = dlg_data->box.y + DIALOG_TB + 1;
	x = dlg_data->box.x + DIALOG_LB;
	dlg_format_text_do(dlg_data, url, x, &y, w, NULL,
			dialog_text_color, ALIGN_LEFT, 0);

	if (show_meter) {
		y++;
		draw_progress_bar(download->progress, term, x, y, w, NULL, NULL);
		y++;
	}

#if CONFIG_BITTORRENT
	if (bittorrent) {
		y++;
		draw_bittorrent_piece_progress(download, term, x, y, w, NULL, NULL);
		y++;
	}
#endif
	y++;
	dlg_format_text_do(dlg_data, msg, x, &y, w, NULL,
			dialog_text_color, ALIGN_LEFT, 0);

	y++;
	dlg_format_buttons(dlg_data, dlg_data->widgets_data,
			   dlg_data->number_of_widgets, x, &y, w,
			   NULL, ALIGN_CENTER, 0);

	mem_free(url);
	mem_free(msg);
}
Example #10
0
void
dlg_format_group(struct terminal *term,
		 struct widget_data *widget_data,
		 int n, int x, int *y, int w, int *rw)
{
	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 = (text && *text) ? strlen(text) : 0;
		int label_padding = (label_length > 0);

		if (widget_data->widget->type == WIDGET_CHECKBOX) {
			width = 3;
		} else if (widget_is_textfield(widget_data)) {
			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 (term) {
			if (widget_data->widget->type == WIDGET_CHECKBOX) {
				/* Draw text at right of checkbox. */
				if (label_length)
					draw_text(term, 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)
					draw_text(term, 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)++;
}