mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
98 lines
2.6 KiB
C
98 lines
2.6 KiB
C
#include "selection.h"
|
|
|
|
#define LOG_MODULE "selection"
|
|
#define LOG_ENABLE_DBG 0
|
|
#include "log.h"
|
|
#include "render.h"
|
|
|
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
|
#define max(x, y) ((x) > (y) ? (x) : (y))
|
|
|
|
static bool
|
|
selection_enabled(const struct terminal *term)
|
|
{
|
|
return term->mouse_tracking == MOUSE_NONE;
|
|
}
|
|
|
|
void
|
|
selection_start(struct terminal *term, int col, int row)
|
|
{
|
|
if (!selection_enabled(term))
|
|
return;
|
|
|
|
selection_cancel(term);
|
|
|
|
LOG_DBG("selection started at %d,%d", row, col);
|
|
term->selection.start = (struct coord){col, row};
|
|
term->selection.end = (struct coord){-1, -1};
|
|
}
|
|
|
|
void
|
|
selection_update(struct terminal *term, int col, int row)
|
|
{
|
|
if (!selection_enabled(term))
|
|
return;
|
|
|
|
LOG_DBG("selection updated: start = %d,%d, end = %d,%d -> %d, %d",
|
|
term->selection.start.row, term->selection.start.col,
|
|
term->selection.end.row, term->selection.end.col,
|
|
row, col);
|
|
|
|
int start_row = term->selection.start.row;
|
|
int old_end_row = term->selection.end.row;
|
|
int new_end_row = term->grid->view + row;
|
|
|
|
assert(start_row != -1);
|
|
assert(new_end_row != -1);
|
|
|
|
if (old_end_row == -1)
|
|
old_end_row = new_end_row;
|
|
|
|
int from = min(start_row, min(old_end_row, new_end_row));
|
|
int to = max(start_row, max(old_end_row, new_end_row));
|
|
|
|
term->selection.end = (struct coord){col, term->grid->view + row};
|
|
|
|
assert(term->selection.start.row != -1 && term->selection.end.row != -1);
|
|
term_damage_rows_in_view(term, from - term->grid->view, to - term->grid->view);
|
|
|
|
if (term->frame_callback == NULL)
|
|
grid_render(term);
|
|
}
|
|
|
|
void
|
|
selection_finalize(struct terminal *term)
|
|
{
|
|
if (!selection_enabled(term))
|
|
return;
|
|
|
|
assert(term->selection.start.row != -1);
|
|
assert(term->selection.end.row != -1);
|
|
}
|
|
|
|
void
|
|
selection_cancel(struct terminal *term)
|
|
{
|
|
if (!selection_enabled(term))
|
|
return;
|
|
|
|
LOG_DBG("selection cancelled: start = %d,%d end = %d,%d",
|
|
term->selection.start.row, term->selection.start.col,
|
|
term->selection.end.row, term->selection.end.col);
|
|
|
|
int start_row = term->selection.start.row;
|
|
int end_row = term->selection.end.row;
|
|
|
|
term->selection.start = (struct coord){-1, -1};
|
|
term->selection.end = (struct coord){-1, -1};
|
|
|
|
if (start_row != -1 && end_row != -1) {
|
|
term_damage_rows_in_view(
|
|
term,
|
|
min(start_row, end_row) - term->grid->view,
|
|
max(start_row, end_row) - term->grid->view);
|
|
|
|
if (term->frame_callback == NULL)
|
|
grid_render(term);
|
|
}
|
|
}
|