Exemple #1
0
void textui_textblock_place(textblock *tb, region orig_area, const char *header)
{
	const char *text = textblock_text(tb);
	const byte *attrs = textblock_attrs(tb);

	/* xxx on resize this should be recalculated */
	region area = region_calculate(orig_area);

	size_t *line_starts = NULL, *line_lengths = NULL;
	size_t n_lines;

	n_lines = textblock_calculate_lines(tb,
			&line_starts, &line_lengths, area.width);

	area.page_rows--;

	if (n_lines > (size_t) area.page_rows)
		n_lines = area.page_rows;

	c_prt(TERM_L_BLUE, header, area.row, area.col);
	area.row++;

	display_area(text, attrs, line_starts, line_lengths, n_lines, area, 0);

	mem_free(line_starts);
	mem_free(line_lengths);
}
Exemple #2
0
void textblock_dump(textblock *tb, char_attr_line **line, int *current_line, 
		   int indent, int wrap)
{
    const char *text = textblock_text(tb);
    const byte *attrs = textblock_attrs(tb);
    
    size_t *line_starts = NULL, *line_lengths = NULL;
    size_t i, j, n_lines;
    
    char_attr_line *lline = *line;

    n_lines = textblock_calculate_lines(tb, &line_starts, &line_lengths, 
					wrap - indent);
    
    for (i = 0; i < n_lines; i++) {
	for (j = 0; j < line_lengths[i]; j++) {
	    dump_put_str(attrs[line_starts[i] + j], 
			 format("%c",text[line_starts[i] + j]),
			 j + indent);
	}
	(*current_line)++;
	dump_ptr = (char_attr *) &lline[*current_line];
    }
    if (!n_lines) (*current_line)--;
}
Exemple #3
0
/**
 * Output a textblock to file.
 */
void textblock_to_file(textblock *tb, ang_file *f, int indent, int wrap_at)
{
	size_t *line_starts = NULL;
	size_t *line_lengths = NULL;

	size_t n_lines, i;

	int width = wrap_at - indent;
	assert(width > 0);

	n_lines = textblock_calculate_lines(tb, &line_starts, &line_lengths, width);

	for (i = 0; i < n_lines; i++) {
		file_putf(f, "%*c%.*s\n",
				indent, ' ',
				line_lengths[i], tb->text + line_starts[i]);
	}
}
Exemple #4
0
void textui_textblock_show(textblock *tb, region orig_area, const char *header)
{
	const char *text = textblock_text(tb);
	const byte *attrs = textblock_attrs(tb);

	/* xxx on resize this should be recalculated */
	region area = region_calculate(orig_area);

	size_t *line_starts = NULL, *line_lengths = NULL;
	size_t n_lines;

	n_lines = textblock_calculate_lines(tb,
			&line_starts, &line_lengths, area.width);

	screen_save();

	/* make room for the header & footer */
	area.page_rows -= 3;

	c_prt(TERM_L_BLUE, header, area.row, area.col);
	area.row++;

	if (n_lines > (size_t) area.page_rows) {
		int start_line = 0;

		c_prt(TERM_WHITE, "", area.row + area.page_rows, area.col);
		c_prt(TERM_L_BLUE, "(Up/down or ESCAPE to exit.)",
				area.row + area.page_rows + 1, area.col);

		/* Pager mode */
		while (1) {
			struct keypress ch;

			display_area(text, attrs, line_starts, line_lengths, n_lines,
					area, start_line);

			ch = inkey();
			if (ch.code == ARROW_UP)
				start_line--;
			else if (ch.code== ESCAPE || ch.code == 'q')
				break;
			else if (ch.code == ARROW_DOWN)
				start_line++;
			else if (ch.code == ' ')
				start_line += area.page_rows;

			if (start_line < 0)
				start_line = 0;
			if (start_line + (size_t) area.page_rows > n_lines)
				start_line = n_lines - area.page_rows;
		}
	} else {
		display_area(text, attrs, line_starts, line_lengths, n_lines, area, 0);

		c_prt(TERM_WHITE, "", area.row + n_lines, area.col);
		c_prt(TERM_L_BLUE, "(Press any key to continue.)",
				area.row + n_lines + 1, area.col);
		inkey();
	}

	mem_free(line_starts);
	mem_free(line_lengths);

	screen_load();

	return;
}
Exemple #5
0
int edit_text(char *buffer, int buflen) {
	int len = strlen(buffer);
	bool done = FALSE;
	int cursor = 0;

	while (!done) {
		int x, y;
		struct keypress ke;

		region area = { 1, HIST_INSTRUCT_ROW + 1, 71, 5 };
		textblock *tb = textblock_new();

		size_t *line_starts = NULL, *line_lengths = NULL;
		size_t n_lines;

		/* Display on screen */
		clear_from(HIST_INSTRUCT_ROW);
		textblock_append(tb, buffer);
		textblock_append(tb, "\n"); /* XXX This shouldn't be necessary */
		textui_textblock_place(tb, area, NULL);

		n_lines = textblock_calculate_lines(tb,
				&line_starts, &line_lengths, area.width);

		/* Set cursor to current editing position */
		get_screen_loc(cursor, &x, &y, n_lines, line_starts, line_lengths);
		Term_gotoxy(1 + x, 19 + y);

		ke = inkey();
		switch (ke.code) {
			case ESCAPE:
				return -1;

			case KC_ENTER:
				done = TRUE;
				break;

			case ARROW_LEFT:
				if (cursor > 0) cursor--;
				break;

			case ARROW_RIGHT:
				if (cursor < len) cursor++;
				break;

			case ARROW_DOWN: {
				int add = line_lengths[y] + 1;
				if (cursor + add < len) cursor += add;
				break;
			}

			case ARROW_UP:
				if (y > 0) {
					int up = line_lengths[y - 1] + 1;
					if (cursor - up >= 0) cursor -= up;
				}
				break;

			case KC_END:
				cursor = MAX(0, len);
				break;

			case KC_HOME:
				cursor = 0;
				break;

			case KC_BACKSPACE:
			case KC_DELETE: {
				/* Refuse to backspace into oblivion */
				if ((ke.code == KC_BACKSPACE && cursor == 0) ||
						(ke.code == KC_DELETE && cursor >= len))
					break;

				/* Move the string from k to nul along to the left by 1 */
				if (ke.code == KC_BACKSPACE)
					memmove(&buffer[cursor - 1], &buffer[cursor], len - cursor);
				else
					memmove(&buffer[cursor], &buffer[cursor + 1], len - cursor - 1);

				/* Decrement */
				if (ke.code == KC_BACKSPACE)
					cursor--;
				len--;

				/* Terminate */
				buffer[len] = '\0';

				break;
			}
			
			default: {
				bool atnull = (buffer[cursor] == 0);

				if (!isprint(ke.code))
					break;

				if (atnull) {
					/* Make sure we have enough room for a new character */
					if ((cursor + 1) >= buflen) break;
				} else {
					/* Make sure we have enough room to add a new character */
					if ((cursor + 1) >= buflen) break;

					/* Move the rest of the buffer along to make room */
					memmove(&buffer[cursor + 1], &buffer[cursor], len - cursor);
				}

				/* Insert the character */
				buffer[cursor++] = (char)ke.code;
				len++;

				/* Terminate */
				buffer[len] = '\0';

				break;
			}
		}

		textblock_free(tb);
	}

	return 0;
}