mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
grid: track both linear and row,col cursor
This commit is contained in:
parent
963b266cce
commit
50c43be0d9
6 changed files with 95 additions and 27 deletions
14
csi.c
14
csi.c
|
|
@ -96,7 +96,7 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
|
||||
case 'J': {
|
||||
assert(term->vt.params.idx == 0);
|
||||
int start = term->grid.cursor / term->grid.cols * term->grid.cols;
|
||||
int start = grid_cursor_linear(&term->grid, term->grid.cursor.row, 0);
|
||||
int end = term->grid.cols * term->grid.rows;
|
||||
grid_erase(&term->grid, start, end);
|
||||
return true;
|
||||
|
|
@ -104,10 +104,10 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
|
||||
case 'K': {
|
||||
assert(term->vt.params.idx == 0);
|
||||
int start = term->grid.cursor;
|
||||
int end = (start + term->grid.cols - 1) / term->grid.cols * term->grid.cols - 1;
|
||||
assert(start <= end);
|
||||
assert((end + 1) % term->grid.cols == 0);
|
||||
int start = term->grid.linear_cursor;
|
||||
int end = grid_cursor_linear(
|
||||
&term->grid, term->grid.cursor.row, term->grid.cols - 1);
|
||||
LOG_DBG("K: %d -> %d", start, end);
|
||||
|
||||
grid_erase(&term->grid, start, end);
|
||||
return true;
|
||||
|
|
@ -115,13 +115,13 @@ csi_dispatch(struct terminal *term, uint8_t final)
|
|||
|
||||
case 'C': {
|
||||
int count = term->vt.params.idx > 0 ? term->vt.params.v[0].value : 1;
|
||||
grid_cursor_move(&term->grid, count);
|
||||
grid_cursor_right(&term->grid, count);
|
||||
return true;
|
||||
}
|
||||
|
||||
case 'D': {
|
||||
int count = term->vt.params.idx > 0 ? term->vt.params.v[0].value : 1;
|
||||
grid_cursor_move(&term->grid, -count);
|
||||
grid_cursor_left(&term->grid, count);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
75
grid.c
75
grid.c
|
|
@ -1,6 +1,10 @@
|
|||
#include "grid.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
void
|
||||
grid_erase(struct grid *grid, int start, int end)
|
||||
|
|
@ -17,19 +21,74 @@ grid_erase(struct grid *grid, int start, int end)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
grid_cursor_move(struct grid *grid, int cols)
|
||||
int
|
||||
grid_cursor_linear(const struct grid *grid, int row, int col)
|
||||
{
|
||||
int new_cursor = grid->cursor + cols;
|
||||
grid->cells[grid->cursor].dirty = true;
|
||||
grid->cells[new_cursor].dirty = true;
|
||||
grid->cursor = new_cursor;
|
||||
return row * grid->cols + col;
|
||||
}
|
||||
|
||||
void
|
||||
grid_cursor_to(struct grid *grid, int row, int col)
|
||||
{
|
||||
assert(row >= 0);
|
||||
assert(row < grid->rows);
|
||||
assert(col >= 0);
|
||||
assert(col < grid->cols);
|
||||
|
||||
int new_linear = row * grid->cols + col;
|
||||
assert(new_linear >= 0);
|
||||
assert(new_linear < grid->rows * grid->cols);
|
||||
|
||||
grid->cells[grid->linear_cursor].dirty = true;
|
||||
grid->cells[new_linear].dirty = true;
|
||||
grid->dirty = true;
|
||||
grid->print_needs_wrap = false;
|
||||
|
||||
grid->linear_cursor = new_linear;
|
||||
grid->cursor.col = col;
|
||||
grid->cursor.row = row;
|
||||
}
|
||||
|
||||
void
|
||||
grid_cursor_left(struct grid *grid, int count)
|
||||
{
|
||||
int move_amount = min(grid->cursor.col, count);
|
||||
int new_linear = grid->linear_cursor - move_amount;
|
||||
int new_col = grid->cursor.col - move_amount;
|
||||
|
||||
assert(new_linear >= 0);
|
||||
assert(new_linear < grid->rows * grid->cols);
|
||||
assert(new_col >= 0);
|
||||
assert(new_col < grid->cols);
|
||||
|
||||
grid->cells[grid->linear_cursor].dirty = true;
|
||||
grid->cells[new_linear].dirty = true;
|
||||
|
||||
grid->linear_cursor = new_linear;
|
||||
grid->cursor.col = new_col;
|
||||
|
||||
grid->dirty = true;
|
||||
grid->print_needs_wrap = false;
|
||||
}
|
||||
|
||||
void
|
||||
grid_cursor_to(struct grid *grid, int pos)
|
||||
grid_cursor_right(struct grid *grid, int count)
|
||||
{
|
||||
grid_cursor_move(grid, pos - grid->cursor);
|
||||
int move_amount = min(grid->cols - grid->cursor.col - 1, count);
|
||||
int new_linear = grid->linear_cursor + move_amount;
|
||||
int new_col = grid->cursor.col + move_amount;
|
||||
|
||||
assert(new_linear >= 0);
|
||||
assert(new_linear < grid->rows * grid->cols);
|
||||
assert(new_col >= 0);
|
||||
assert(new_col < grid->cols);
|
||||
|
||||
grid->cells[grid->linear_cursor].dirty = true;
|
||||
grid->cells[new_linear].dirty = true;
|
||||
|
||||
grid->linear_cursor = new_linear;
|
||||
grid->cursor.col = new_col;
|
||||
|
||||
grid->dirty = true;
|
||||
grid->print_needs_wrap = false;
|
||||
}
|
||||
|
|
|
|||
10
grid.h
10
grid.h
|
|
@ -4,5 +4,11 @@
|
|||
|
||||
void grid_erase(struct grid *grid, int start, int end);
|
||||
|
||||
void grid_cursor_to(struct grid *grid, int pos);
|
||||
void grid_cursor_move(struct grid *grid, int cols);
|
||||
void grid_cursor_to(struct grid *grid, int row, int col);
|
||||
void grid_cursor_left(struct grid *grid, int count);
|
||||
void grid_cursor_right(struct grid *grid, int count);
|
||||
|
||||
int grid_cursor_linear(const struct grid *grid, int row, int col);
|
||||
|
||||
//void grid_cursor_to(struct grid *grid, int pos);
|
||||
//void grid_cursor_move(struct grid *grid, int cols);
|
||||
|
|
|
|||
2
main.c
2
main.c
|
|
@ -97,7 +97,7 @@ grid_render(struct context *c)
|
|||
|
||||
cell->dirty = false;
|
||||
|
||||
bool has_cursor = c->term.grid.cursor == cell_idx;
|
||||
bool has_cursor = c->term.grid.linear_cursor == cell_idx;
|
||||
|
||||
int y_ofs = row * c->term.grid.cell_height + c->fextents.ascent;
|
||||
int x_ofs = col * c->term.grid.cell_width;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,13 @@ struct grid {
|
|||
int cell_width;
|
||||
int cell_height;
|
||||
|
||||
int cursor;
|
||||
int linear_cursor;
|
||||
struct {
|
||||
int row;
|
||||
int col;
|
||||
} cursor;
|
||||
bool print_needs_wrap;
|
||||
|
||||
struct cell *cells;
|
||||
|
||||
uint32_t foreground;
|
||||
|
|
|
|||
14
vt.c
14
vt.c
|
|
@ -158,13 +158,11 @@ action(struct terminal *term, enum action action, uint8_t c)
|
|||
LOG_DBG("execute: 0x%02x", c);
|
||||
switch (c) {
|
||||
case '\r':
|
||||
grid_cursor_to(
|
||||
&term->grid,
|
||||
term->grid.cursor / term->grid.cols * term->grid.cols);
|
||||
grid_cursor_left(&term->grid, term->grid.cursor.col);
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
grid_cursor_move(&term->grid, -1);
|
||||
grid_cursor_left(&term->grid, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -179,9 +177,9 @@ action(struct terminal *term, enum action action, uint8_t c)
|
|||
|
||||
case ACTION_PRINT: {
|
||||
if (term->grid.print_needs_wrap)
|
||||
grid_cursor_move(&term->grid, 1);
|
||||
grid_cursor_to(&term->grid, term->grid.cursor.row + 1, 0);
|
||||
|
||||
struct cell *cell = &term->grid.cells[term->grid.cursor];
|
||||
struct cell *cell = &term->grid.cells[term->grid.linear_cursor];
|
||||
|
||||
cell->dirty = true;
|
||||
|
||||
|
|
@ -197,8 +195,8 @@ action(struct terminal *term, enum action action, uint8_t c)
|
|||
|
||||
cell->attrs = term->vt.attrs;
|
||||
|
||||
if ((term->grid.cursor + 1) % term->grid.cols)
|
||||
grid_cursor_move(&term->grid, 1);
|
||||
if (term->grid.cursor.col < term->grid.cols - 1)
|
||||
grid_cursor_right(&term->grid, 1);
|
||||
else
|
||||
term->grid.print_needs_wrap = true;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue