mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-29 07:58:01 -04:00
grid: grid_reflow() now translates cursor coordinates
This commit is contained in:
parent
89559d5466
commit
5546b40369
3 changed files with 54 additions and 42 deletions
58
grid.c
58
grid.c
|
|
@ -53,7 +53,7 @@ grid_row_free(struct row *row)
|
||||||
free(row);
|
free(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
int old_screen_rows, int new_screen_rows)
|
int old_screen_rows, int new_screen_rows)
|
||||||
{
|
{
|
||||||
|
|
@ -79,13 +79,26 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
|
|
||||||
tll(struct sixel) new_sixels = tll_init();
|
tll(struct sixel) new_sixels = tll_init();
|
||||||
|
|
||||||
|
/* Turn cursor coordinates into grid absolute coordinates */
|
||||||
|
struct coord cursor = grid->cursor.point;
|
||||||
|
struct coord new_cursor = {};
|
||||||
|
cursor.row += grid->offset;
|
||||||
|
cursor.row &= old_rows - 1;
|
||||||
|
|
||||||
|
struct coord saved_cursor = grid->saved_cursor.point;
|
||||||
|
struct coord new_saved_cursor = {};
|
||||||
|
saved_cursor.row += grid->offset;
|
||||||
|
saved_cursor.row &= old_rows - 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Walk the old grid
|
* Walk the old grid
|
||||||
*/
|
*/
|
||||||
for (int r = 0; r < old_rows; r++) {
|
for (int r = 0; r < old_rows; r++) {
|
||||||
|
|
||||||
|
const size_t old_row_idx = (offset + r) & (old_rows - 1);
|
||||||
|
|
||||||
/* Unallocated (empty) rows we can simply skip */
|
/* Unallocated (empty) rows we can simply skip */
|
||||||
const struct row *old_row = old_grid[(offset + r) & (old_rows - 1)];
|
const struct row *old_row = old_grid[old_row_idx];
|
||||||
if (old_row == NULL)
|
if (old_row == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -102,7 +115,7 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
* the "real" sixel list.
|
* the "real" sixel list.
|
||||||
*/
|
*/
|
||||||
tll_foreach(grid->sixel_images, it) {
|
tll_foreach(grid->sixel_images, it) {
|
||||||
if (it->item.pos.row == ((offset + r) & (old_rows - 1))) {
|
if (it->item.pos.row == old_row_idx) {
|
||||||
struct sixel six = it->item;
|
struct sixel six = it->item;
|
||||||
six.pos.row = new_row_idx;
|
six.pos.row = new_row_idx;
|
||||||
|
|
||||||
|
|
@ -122,7 +135,13 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
|
|
||||||
/* Walk current line of the old grid */
|
/* Walk current line of the old grid */
|
||||||
for (int c = 0; c < old_cols; c++) {
|
for (int c = 0; c < old_cols; c++) {
|
||||||
if (old_row->cells[c].wc == 0) {
|
bool has_cursor = cursor.row == old_row_idx && cursor.col == c;
|
||||||
|
bool has_saved_cursor
|
||||||
|
= saved_cursor.row == old_row_idx && saved_cursor.col == c;
|
||||||
|
|
||||||
|
if (old_row->cells[c].wc == 0 && !has_cursor && !has_saved_cursor) {
|
||||||
|
assert(!has_cursor);
|
||||||
|
assert(!has_saved_cursor);
|
||||||
empty_count++;
|
empty_count++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -168,6 +187,12 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
|
|
||||||
new_row->cells[new_col_idx] = *old_cell;
|
new_row->cells[new_col_idx] = *old_cell;
|
||||||
new_row->cells[new_col_idx].attrs.clean = 1;
|
new_row->cells[new_col_idx].attrs.clean = 1;
|
||||||
|
|
||||||
|
if (has_cursor)
|
||||||
|
new_cursor = (struct coord){new_col_idx, new_row_idx};
|
||||||
|
if (has_saved_cursor)
|
||||||
|
new_saved_cursor = (struct coord){new_col_idx, new_row_idx};
|
||||||
|
|
||||||
new_col_idx++;
|
new_col_idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,11 +236,32 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
grid_row_free(old_grid[r]);
|
grid_row_free(old_grid[r]);
|
||||||
free(grid->rows);
|
free(grid->rows);
|
||||||
|
|
||||||
grid->cur_row = new_grid[new_row_idx];
|
grid->cur_row = new_grid[new_cursor.row];
|
||||||
grid->rows = new_grid;
|
grid->rows = new_grid;
|
||||||
grid->num_rows = new_rows;
|
grid->num_rows = new_rows;
|
||||||
grid->num_cols = new_cols;
|
grid->num_cols = new_cols;
|
||||||
|
|
||||||
|
/* Convert absolute coordinates to screen relative */
|
||||||
|
new_cursor.row -= grid->offset;
|
||||||
|
while (new_cursor.row < 0)
|
||||||
|
new_cursor.row += grid->num_rows;
|
||||||
|
|
||||||
|
assert(new_cursor.row >= 0);
|
||||||
|
assert(new_cursor.row < grid->num_rows);
|
||||||
|
|
||||||
|
new_saved_cursor.row -= grid->offset;
|
||||||
|
while (new_saved_cursor.row < 0)
|
||||||
|
new_saved_cursor.row += grid->num_rows;
|
||||||
|
|
||||||
|
assert(new_saved_cursor.row >= 0);
|
||||||
|
assert(new_saved_cursor.row < grid->num_rows);
|
||||||
|
|
||||||
|
grid->cursor.point = new_cursor;
|
||||||
|
grid->saved_cursor.point = new_saved_cursor;
|
||||||
|
|
||||||
|
grid->cursor.lcf = false;
|
||||||
|
grid->saved_cursor.lcf = false;
|
||||||
|
|
||||||
/* Destroy any non-moved sixels */
|
/* Destroy any non-moved sixels */
|
||||||
tll_foreach(grid->sixel_images, it)
|
tll_foreach(grid->sixel_images, it)
|
||||||
sixel_destroy(&it->item);
|
sixel_destroy(&it->item);
|
||||||
|
|
@ -225,6 +271,4 @@ grid_reflow(struct grid *grid, int new_rows, int new_cols,
|
||||||
tll_foreach(new_sixels, it)
|
tll_foreach(new_sixels, it)
|
||||||
tll_push_back(grid->sixel_images, it->item);
|
tll_push_back(grid->sixel_images, it->item);
|
||||||
tll_free(new_sixels);
|
tll_free(new_sixels);
|
||||||
|
|
||||||
return new_row_idx;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
grid.h
2
grid.h
|
|
@ -6,7 +6,7 @@
|
||||||
void grid_swap_row(struct grid *grid, int row_a, int row_b, bool initialize);
|
void grid_swap_row(struct grid *grid, int row_a, int row_b, bool initialize);
|
||||||
struct row *grid_row_alloc(int cols, bool initialize);
|
struct row *grid_row_alloc(int cols, bool initialize);
|
||||||
void grid_row_free(struct row *row);
|
void grid_row_free(struct row *row);
|
||||||
int grid_reflow(
|
void grid_reflow(
|
||||||
struct grid *grid, int new_rows, int new_cols,
|
struct grid *grid, int new_rows, int new_cols,
|
||||||
int old_screen_rows, int new_screen_rows);
|
int old_screen_rows, int new_screen_rows);
|
||||||
|
|
||||||
|
|
|
||||||
36
render.c
36
render.c
|
|
@ -1754,10 +1754,8 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reflow grids */
|
/* Reflow grids */
|
||||||
int last_normal_row = grid_reflow(
|
grid_reflow(&term->normal, new_normal_grid_rows, new_cols, old_rows, new_rows);
|
||||||
&term->normal, new_normal_grid_rows, new_cols, old_rows, new_rows);
|
grid_reflow(&term->alt, new_alt_grid_rows, new_cols, old_rows, new_rows);
|
||||||
int last_alt_row = grid_reflow(
|
|
||||||
&term->alt, new_alt_grid_rows, new_cols, old_rows, new_rows);
|
|
||||||
|
|
||||||
/* Reset tab stops */
|
/* Reset tab stops */
|
||||||
tll_free(term->tab_stops);
|
tll_free(term->tab_stops);
|
||||||
|
|
@ -1789,36 +1787,6 @@ maybe_resize(struct terminal *term, int width, int height, bool force)
|
||||||
if (term->scroll_region.end >= old_rows)
|
if (term->scroll_region.end >= old_rows)
|
||||||
term->scroll_region.end = term->rows;
|
term->scroll_region.end = term->rows;
|
||||||
|
|
||||||
/* Position cursor at the last copied row */
|
|
||||||
/* TODO: can we do better? */
|
|
||||||
int cursor_row = term->grid == &term->normal
|
|
||||||
? last_normal_row - term->normal.offset
|
|
||||||
: last_alt_row - term->alt.offset;
|
|
||||||
|
|
||||||
while (cursor_row < 0)
|
|
||||||
cursor_row += term->grid->num_rows;
|
|
||||||
|
|
||||||
assert(cursor_row >= 0);
|
|
||||||
assert(cursor_row < term->rows);
|
|
||||||
|
|
||||||
term_cursor_to(
|
|
||||||
term,
|
|
||||||
cursor_row,
|
|
||||||
min(term->grid->cursor.point.col, term->cols - 1));
|
|
||||||
|
|
||||||
/* If in alt screen, update the saved 'normal' cursor too */
|
|
||||||
if (term->grid == &term->alt) {
|
|
||||||
int cursor_row = last_normal_row - term->normal.offset;
|
|
||||||
|
|
||||||
while (cursor_row < 0)
|
|
||||||
cursor_row += term->grid->num_rows;
|
|
||||||
|
|
||||||
term->normal.cursor.lcf = false;
|
|
||||||
term->normal.cursor.point.row = cursor_row;
|
|
||||||
term->normal.cursor.point.col = min(
|
|
||||||
term->normal.cursor.point.col, term->cols - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
term->render.last_cursor.cell = NULL;
|
term->render.last_cursor.cell = NULL;
|
||||||
|
|
||||||
damage_view:
|
damage_view:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue