mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
selection: selections can be made, and are rendered
* Start selection on mouse button down * Update selection on motion * Button release cancels selection if there were no motion after start * Renderer detects cells inside the selection and inverts their colors
This commit is contained in:
parent
decb4503bf
commit
632790d5d8
4 changed files with 57 additions and 1 deletions
21
input.c
21
input.c
|
|
@ -312,6 +312,14 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
|
|||
term->mouse.col = col;
|
||||
term->mouse.row = row;
|
||||
|
||||
if (term->mouse.button != 0) {
|
||||
/* Update selection */
|
||||
term->selection.end = (struct coord){col, term->grid->view + row};
|
||||
term_damage_view(term);
|
||||
if (term->frame_callback == NULL)
|
||||
grid_render(term);
|
||||
}
|
||||
|
||||
term_mouse_motion(
|
||||
term, term->mouse.button, term->mouse.row, term->mouse.col,
|
||||
term->kbd.shift, term->kbd.alt, term->kbd.ctrl);
|
||||
|
|
@ -327,12 +335,25 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
|||
|
||||
switch (state) {
|
||||
case WL_POINTER_BUTTON_STATE_PRESSED:
|
||||
/* Start selection */
|
||||
term->selection.start = (struct coord){
|
||||
term->mouse.col, term->grid->view + term->mouse.row};
|
||||
term->selection.end = (struct coord){-1, -1};
|
||||
|
||||
term->mouse.button = button; /* For motion events */
|
||||
term_mouse_down(term, button, term->mouse.row, term->mouse.col,
|
||||
term->kbd.shift, term->kbd.alt, term->kbd.ctrl);
|
||||
break;
|
||||
|
||||
case WL_POINTER_BUTTON_STATE_RELEASED:
|
||||
if (term->selection.end.col == -1) {
|
||||
/* No selection made - cancel */
|
||||
term->selection.start = (struct coord){-1, -1};
|
||||
term_damage_view(term);
|
||||
if (term->frame_callback == NULL)
|
||||
grid_render(term);
|
||||
}
|
||||
|
||||
term->mouse.button = 0; /* For motion events */
|
||||
term_mouse_up(term, button, term->mouse.row, term->mouse.col,
|
||||
term->kbd.shift, term->kbd.alt, term->kbd.ctrl);
|
||||
|
|
|
|||
4
main.c
4
main.c
|
|
@ -313,6 +313,10 @@ main(int argc, char *const *argv)
|
|||
},
|
||||
.foreground = default_foreground,
|
||||
.background = default_background,
|
||||
.selection = {
|
||||
.start = {-1, -1},
|
||||
.end = {-1, -1},
|
||||
},
|
||||
.normal = {.damage = tll_init(), .scroll_damage = tll_init()},
|
||||
.alt = {.damage = tll_init(), .scroll_damage = tll_init()},
|
||||
.grid = &term.normal,
|
||||
|
|
|
|||
28
render.c
28
render.c
|
|
@ -42,6 +42,32 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
|
|||
double x = col * width;
|
||||
double y = row * height;
|
||||
|
||||
bool is_selected = false;
|
||||
if (term->selection.start.col != -1 && term->selection.end.col != -1) {
|
||||
const struct coord *start = &term->selection.start;
|
||||
const struct coord *end = &term->selection.end;
|
||||
|
||||
if (end->row < start->row || (end->row == start->row && end->col < start->col)) {
|
||||
const struct coord *tmp = start;
|
||||
start = end;
|
||||
end = tmp;
|
||||
}
|
||||
|
||||
assert(start->row <= end->row);
|
||||
|
||||
if (start->row == end->row) {
|
||||
is_selected
|
||||
= term->grid->view + row == start->row && col >= start->col && col <= end->col;
|
||||
} else {
|
||||
if (term->grid->view + row == start->row)
|
||||
is_selected = col >= start->col;
|
||||
else if (term->grid->view + row == end->row)
|
||||
is_selected = col <= end->col;
|
||||
else
|
||||
is_selected = term->grid->view + row >= start->row && term->grid->view + row <= end->row;
|
||||
}
|
||||
}
|
||||
|
||||
const struct rgb *foreground = cell->attrs.have_foreground
|
||||
? &cell->attrs.foreground
|
||||
: !term->reverse ? &term->foreground : &term->background;
|
||||
|
|
@ -50,7 +76,7 @@ render_cell(struct terminal *term, struct buffer *buf, const struct cell *cell,
|
|||
: !term->reverse ? &term->background : &term->foreground;
|
||||
|
||||
/* If *one* is set, we reverse */
|
||||
if (has_cursor ^ cell->attrs.reverse) {
|
||||
if (has_cursor ^ cell->attrs.reverse ^ is_selected) {
|
||||
const struct rgb *swap = foreground;
|
||||
foreground = background;
|
||||
background = swap;
|
||||
|
|
|
|||
|
|
@ -228,6 +228,11 @@ struct terminal {
|
|||
struct coord saved_cursor;
|
||||
struct coord alt_saved_cursor;
|
||||
|
||||
struct {
|
||||
struct coord start;
|
||||
struct coord end;
|
||||
} selection;
|
||||
|
||||
struct grid normal;
|
||||
struct grid alt;
|
||||
struct grid *grid;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue