~strahinja/poe

c38792a9e0d21d99b08aa3a90e1947071778174f — Страхиња Радић a month ago fa331e9
Calculate edit box, help and search box widths; fix backspace at the end of lines longer than edit box; fix positioning when backspacing at the start of a line

Signed-off-by: Страхиња Радић <contact@strahinja.org>
4 files changed, 97 insertions(+), 52 deletions(-)

M TODO
M draw.c
M draw.h
M poe.c
M TODO => TODO +2 -2
@@ 1,8 1,8 @@
				      TODO
				      ====

	[ ] Don't assume minimal width when drawing (or lower the assumption)
		[ ] Investigate backspace/insert at the end of a line longer
	[x] Don't assume minimal width when drawing (or lower the assumption)
		[x] Investigate backspace/insert at the end of a line longer
                    than edit box width

	[ ] Change the word-operations (C-W, C-R, C-T) to be more intuitive with

M draw.c => draw.c +27 -6
@@ 96,6 96,9 @@ init_drawstate(struct DrawState* state, char* error, char* filename,
	state->info_first_shown_column	 = 0;
	state->info_first_shown_row	 = 0;
	state->info_rows_count		 = 0;
	state->help_width                = calculate_help_width(state);
	state->edit_width                = calculate_edit_width(state);
	state->search_width              = calculate_search_width(state);
	state->paste_buffer		 = NULL;
	state->paste_rows_count		 = 0;
	state->search_column		 = 0;


@@ 276,6 279,24 @@ input_length(const struct DrawState* state, uint32_t* buffer,
	return i;
}

int
calculate_help_width(const struct DrawState* state)
{
	return state->maxx > HELP_WIDTH + 2 ? HELP_WIDTH : state->maxx - 2;
}

int
calculate_edit_width(const struct DrawState* state)
{
	return state->maxx > EDIT_WIDTH + 2 ? EDIT_WIDTH : state->maxx - 2;
}

int
calculate_search_width(const struct DrawState* state)
{
	return state->maxx > SEARCH_WIDTH + 2 ? SEARCH_WIDTH : state->maxx - 2;
}

void
draw_rect(const int startx, const int endx, const int starty, const int endy,
	const uint16_t fg, const uint16_t bg)


@@ 560,7 581,7 @@ draw_help(const struct DrawState* state)
		return NULL;

	int startx, endx, starty, endy;
	int w	 = HELP_WIDTH;
	int w	 = state->help_width;
	int h	 = HELP_HEIGHT;
	int row	 = 0;
	int maxx = state->maxx;


@@ 595,7 616,7 @@ draw_editbox(const struct DrawState* state)
		return NULL;

	int startx, endx, starty, endy;
	int w	 = EDIT_WIDTH;
	int w	 = state->edit_width;
	int h	 = EDIT_HEIGHT;
	int maxx = state->maxx;
	int maxy = state->maxy;


@@ 607,10 628,10 @@ draw_editbox(const struct DrawState* state)
	format_flags(flags_buf + 2, MAXFLAGSBUF, entry);
	strcpy(flags_buf + 2 + MAXFLAGSBUF - 1, " ]");

	startx = w > maxx ? 0 : (maxx - w) / 2;
	startx = w > maxx ? 0        : (maxx - w) / 2;
	endx   = w > maxx ? maxx - 1 : maxx - startx;

	starty = h > maxy - 1 ? 0 : (maxy - h) / 2;
	starty = h > maxy - 1 ? 0        : (maxy - h) / 2;
	endy   = h > maxy - 1 ? maxy - 2 : maxy - starty;

	draw_box(startx, endx, starty, endy, DLG_FG, DLG_BG);


@@ 703,14 724,14 @@ const struct DrawState*
draw_search(const struct DrawState* state)
{
	int startx, endx, starty, endy;
	int w	    = SEARCH_WIDTH;
	int w	    = state->search_width;
	int h	    = SEARCH_HEIGHT;
	int maxx    = state->maxx;
	int maxy    = state->maxy;
	size_t len  = u32_strlen(state->search);
	size_t dlen = 0;

	startx = w > maxx ? 0 : (maxx - w) / 2;
	startx = w > maxx ? 0        : (maxx - w) / 2;
	endx   = w > maxx ? maxx - 1 : maxx - startx;

	starty = maxy - 1 - h;

M draw.h => draw.h +6 -0
@@ 50,6 50,9 @@ struct DrawState {
	int info_first_shown_row;
	int info_rows_count;
	int info_rows_maxlen;
	int help_width;
	int edit_width;
	int search_width;
	struct BufferLine* paste_buffer;
	int paste_rows_count;
	int search_column;


@@ 101,6 104,9 @@ size_t display_length(const struct DrawState* state, uint32_t* buffer,
	const size_t max_index);
size_t input_length(const struct DrawState* state, uint32_t* buffer,
	const size_t max_index);
int calculate_help_width(const struct DrawState* state);
int calculate_edit_width(const struct DrawState* state);
int calculate_search_width(const struct DrawState* state);
void draw_rect(const int startx, const int endx, const int starty,
	const int endy, const uint16_t fg, const uint16_t bg);
void draw_box(const int startx, const int endx, const int starty,

M poe.c => poe.c +62 -44
@@ 500,7 500,7 @@ save_msgstr(struct DrawState* state)
	for (size_t i = 0; i < state->info_rows_count; i++)
		free_bufferline(state->info_buffer + i);
	free(state->info_buffer);
	state->dirty = (state->dirty_before_edit || state->dirty);
	state->dirty	       = (state->dirty_before_edit || state->dirty);
	state->info_rows_count = 0;
	state->info_buffer     = NULL;
	u32_encode_tabs(to_save, to_save_size * sizeof(uint32_t));


@@ 564,7 564,7 @@ show_search(struct DrawState* state)
	if (!state->search)
		state->search = calloc(MAXSEARCH, sizeof(uint32_t));
	state->search[0] = 0;
	tb_set_cursor((state->maxx - SEARCH_WIDTH + 2) / 2,
	tb_set_cursor((state->maxx - state->search_width + 2) / 2,
		state->maxy - 1 - SEARCH_HEIGHT + 1);
}



@@ 623,9 623,9 @@ move_search_right(struct DrawState* state)
	state->search_column++;

	if (state->search_display_column - state->search_first_shown_column
		> SEARCH_WIDTH - 4)
		state->search_first_shown_column
			= state->search_display_column - SEARCH_WIDTH + 4;
		> state->search_width - 4)
		state->search_first_shown_column = state->search_display_column
			- state->search_width + 4;
}

void


@@ 636,8 636,9 @@ move_search_end(struct DrawState* state)
	size_t dlen
		= display_length(state, state->search, state->search_column);
	state->search_display_column = dlen;
	if (dlen > SEARCH_WIDTH - 4)
		state->search_first_shown_column = dlen - SEARCH_WIDTH + 4;
	if (dlen > state->search_width - 4)
		state->search_first_shown_column
			= dlen - state->search_width + 4;
	else
		state->search_first_shown_column = 0;
}


@@ 662,11 663,11 @@ insert_search_char(struct DrawState* state, uint32_t ch)
			state->search, state->search_column);
		if (state->search_display_column
				- state->search_first_shown_column
			> SEARCH_WIDTH - 4)
			> state->search_width - 4)
		{
			state->search_first_shown_column
				= state->search_display_column - SEARCH_WIDTH
				+ 4;
				= state->search_display_column
				- state->search_width + 4;
			state->search_display_column = display_length(state,
				state->search, state->search_column);
		}


@@ 692,10 693,10 @@ erase_search_backwards(struct DrawState* state)
		state->search_column--;
		if (state->search_column < state->search_first_shown_column)
		{
			if (state->search_column > SEARCH_WIDTH - 4)
			if (state->search_column > state->search_width - 4)
				state->search_first_shown_column
					= state->search_column - SEARCH_WIDTH
					+ 4;
					= state->search_column
					- state->search_width + 4;
			else
				state->search_first_shown_column = 0;
		}


@@ 763,9 764,9 @@ move_search_prev_word(struct DrawState* state)

	if (state->search_column < state->search_first_shown_column)
	{
		if (state->search_column > SEARCH_WIDTH - 4)
			state->search_first_shown_column
				= state->search_column - SEARCH_WIDTH + 4;
		if (state->search_column > state->search_width - 4)
			state->search_first_shown_column = state->search_column
				- state->search_width + 4;
		else
			state->search_first_shown_column = 0;
	}


@@ 789,10 790,10 @@ move_search_next_word(struct DrawState* state)
		= display_length(state, state->search, state->search_column);

	if (state->search_display_column - state->search_first_shown_column
		> SEARCH_WIDTH - 4)
		> state->search_width - 4)
	{
		state->search_first_shown_column
			= state->search_display_column - SEARCH_WIDTH + 4;
		state->search_first_shown_column = state->search_display_column
			- state->search_width + 4;
		state->search_display_column = display_length(state,
			state->search, state->search_column);
	}


@@ 824,9 825,9 @@ erase_search_prev_word(struct DrawState* state)

	if (state->search_column < state->search_first_shown_column)
	{
		if (state->search_column > SEARCH_WIDTH - 4)
			state->search_first_shown_column
				= state->search_column - SEARCH_WIDTH + 4;
		if (state->search_column > state->search_width - 4)
			state->search_first_shown_column = state->search_column
				- state->search_width + 4;
		else
			state->search_first_shown_column = 0;
	}


@@ 1262,10 1263,10 @@ move_up(struct DrawState* state)
		state->input_display_column);
	if (state->input_first_shown_column > state->input_display_column)
		state->input_first_shown_column = state->input_display_column;
	if (state->input_first_shown_column + EDIT_WIDTH - 4
	if (state->input_first_shown_column + state->edit_width - 4
		< state->input_display_column)
		state->input_first_shown_column
			= state->input_display_column - EDIT_WIDTH + 4;
			= state->input_display_column - state->edit_width + 4;
	state->input_display_column = display_length(state,
		state->input_buffer[state->input_row].text,
		state->input_column);


@@ 1302,10 1303,10 @@ move_down(struct DrawState* state)
		state->input_display_column);
	if (state->input_first_shown_column > state->input_display_column)
		state->input_first_shown_column = state->input_display_column;
	if (state->input_first_shown_column + EDIT_WIDTH - 4
	if (state->input_first_shown_column + state->edit_width - 4
		< state->input_display_column)
		state->input_first_shown_column
			= state->input_display_column - EDIT_WIDTH + 4;
			= state->input_display_column - state->edit_width + 4;
	state->input_display_column = display_length(state,
		state->input_buffer[state->input_row].text,
		state->input_column);


@@ 1398,7 1399,7 @@ move_right(struct DrawState* state)
{
	if (state->edit_info_focused)
	{
		if (state->info_first_shown_column + EDIT_WIDTH - 3
		if (state->info_first_shown_column + state->edit_width - 3
			< state->info_rows_maxlen + 1)
			state->info_first_shown_column++;
		return;


@@ 1418,9 1419,9 @@ move_right(struct DrawState* state)
	state->input_column++;

	if (state->input_display_column - state->input_first_shown_column
		> EDIT_WIDTH - 4)
		> state->edit_width - 4)
		state->input_first_shown_column
			= state->input_display_column - EDIT_WIDTH + 4;
			= state->input_display_column - state->edit_width + 4;
}

void


@@ 1470,9 1471,9 @@ move_next_word(struct DrawState* state)
		state->input_buffer[state->input_row].text,
		state->input_column);
	if (state->input_display_column - state->input_first_shown_column
		> EDIT_WIDTH - 4)
		> state->edit_width - 4)
		state->input_first_shown_column
			= state->input_display_column - EDIT_WIDTH + 4;
			= state->input_display_column - state->edit_width + 4;
}

void


@@ 1527,8 1528,8 @@ move_end(struct DrawState* state)
			state->input_buffer[state->input_row].text,
			state->input_column);
	state->input_display_column = dlen;
	if (dlen > EDIT_WIDTH - 4)
		state->input_first_shown_column = dlen - EDIT_WIDTH + 4;
	if (dlen > state->edit_width - 4)
		state->input_first_shown_column = dlen - state->edit_width + 4;
	else
		state->input_first_shown_column = 0;
}


@@ 1684,10 1685,11 @@ insert_char(struct DrawState* state, uint32_t ch)
			state->input_buffer[state->input_row].text,
			state->input_column);
		if (state->input_display_column - state->input_first_shown_column
			> EDIT_WIDTH - 4)
			> state->edit_width - 4)
		{
			state->input_first_shown_column
				= state->input_display_column - EDIT_WIDTH + 4;
				= state->input_display_column
				- state->edit_width + 4;
			state->input_display_column = display_length(state,
				state->input_buffer[state->input_row].text,
				state->input_column);


@@ 1714,6 1716,15 @@ erase_backwards(struct DrawState* state)
		buffer_line->text[i - 1] = 0;
		buffer_line->length--;
		state->input_column--;
		if (state->input_first_shown_column > 0)
		{
			const struct BufferLine* current_line
				= &state->input_buffer[state->input_row];
			if (display_length(state, current_line->text,
				    current_line->length)
				>= state->edit_width - 4)
				state->input_first_shown_column--;
		}
		state->input_display_column = display_length(state,
			state->input_buffer[state->input_row].text,
			state->input_column);


@@ 1725,13 1736,9 @@ erase_backwards(struct DrawState* state)
	}
	else if (state->input_row > 0)
	{
		if (!join_lines(state, state->input_row - 1, 0))
		{
			strcpy(state->error, errors[ERR_CANT_ALLOC]);
			state->running = 0;
		}
		else
			move_end(state);
		move_up(state);
		move_end(state);
		erase_forward(state);
	}
}



@@ 2214,9 2221,20 @@ main(int argc, char** argv)

	while (state.running)
	{
		int maxx = tb_width();
		int maxy = tb_height();

		tb_clear();
		state.maxx = tb_width();
		state.maxy = tb_height();

		if (maxx != state.maxx)
		{
			state.maxx	   = maxx;
			state.help_width   = calculate_help_width(&state);
			state.edit_width   = calculate_edit_width(&state);
			state.search_width = calculate_search_width(&state);
		}
		if (maxy != state.maxy)
			state.maxy = maxy;

		if (!draw(&state))
			strcpy(state.error, errors[ERR_CANT_ALLOC]);