mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
selection: add a selection API
This commit is contained in:
parent
1c861e5d69
commit
bcf763d417
6 changed files with 117 additions and 30 deletions
45
input.c
45
input.c
|
|
@ -20,6 +20,7 @@
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "keymap.h"
|
#include "keymap.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
#include "selection.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
||||||
|
|
@ -178,10 +179,10 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
||||||
|
|
||||||
if (term->grid->view != term->grid->offset) {
|
if (term->grid->view != term->grid->offset) {
|
||||||
term->grid->view = term->grid->offset;
|
term->grid->view = term->grid->offset;
|
||||||
/* TODO: damage view */
|
|
||||||
term_damage_all(term);
|
term_damage_all(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selection_cancel(term);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -207,10 +208,10 @@ keyboard_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial,
|
||||||
|
|
||||||
if (term->grid->view != term->grid->offset) {
|
if (term->grid->view != term->grid->offset) {
|
||||||
term->grid->view = term->grid->offset;
|
term->grid->view = term->grid->offset;
|
||||||
/* TODO: damage view */
|
|
||||||
term_damage_all(term);
|
term_damage_all(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selection_cancel(term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,19 +307,20 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
|
||||||
int col = x / term->cell_width;
|
int col = x / term->cell_width;
|
||||||
int row = y / term->cell_height;
|
int row = y / term->cell_height;
|
||||||
|
|
||||||
|
bool update_selection = term->mouse.button == BTN_LEFT;
|
||||||
|
bool update_selection_early = term->selection.end.row == -1;
|
||||||
|
|
||||||
|
if (update_selection && update_selection_early)
|
||||||
|
selection_update(term, col, row);
|
||||||
|
|
||||||
if (col == term->mouse.col && row == term->mouse.row)
|
if (col == term->mouse.col && row == term->mouse.row)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
term->mouse.col = col;
|
term->mouse.col = col;
|
||||||
term->mouse.row = row;
|
term->mouse.row = row;
|
||||||
|
|
||||||
if (term->mouse.button == BTN_LEFT) {
|
if (update_selection && !update_selection_early)
|
||||||
/* Update selection */
|
selection_update(term, col, row);
|
||||||
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_mouse_motion(
|
||||||
term, term->mouse.button, term->mouse.row, term->mouse.col,
|
term, term->mouse.button, term->mouse.row, term->mouse.col,
|
||||||
|
|
@ -335,18 +337,10 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case WL_POINTER_BUTTON_STATE_PRESSED:
|
case WL_POINTER_BUTTON_STATE_PRESSED:
|
||||||
if (button == BTN_LEFT) {
|
if (button == BTN_LEFT)
|
||||||
/* Start selection */
|
selection_start(term, term->mouse.col, term->mouse.row);
|
||||||
term->selection.start = (struct coord){
|
else
|
||||||
term->mouse.col, term->grid->view + term->mouse.row};
|
selection_cancel(term);
|
||||||
term->selection.end = (struct coord){-1, -1};
|
|
||||||
} else {
|
|
||||||
term->selection.start = (struct coord){-1, -1};
|
|
||||||
term->selection.end = (struct coord){-1, -1};
|
|
||||||
term_damage_view(term);
|
|
||||||
if (term->frame_callback == NULL)
|
|
||||||
grid_render(term);
|
|
||||||
}
|
|
||||||
|
|
||||||
term->mouse.button = button; /* For motion events */
|
term->mouse.button = button; /* For motion events */
|
||||||
term_mouse_down(term, button, term->mouse.row, term->mouse.col,
|
term_mouse_down(term, button, term->mouse.row, term->mouse.col,
|
||||||
|
|
@ -354,13 +348,8 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WL_POINTER_BUTTON_STATE_RELEASED:
|
case WL_POINTER_BUTTON_STATE_RELEASED:
|
||||||
if (button == BTN_LEFT && term->selection.end.col == -1) {
|
if (button == BTN_LEFT && term->selection.end.col == -1)
|
||||||
/* No selection made - cancel */
|
selection_cancel(term);
|
||||||
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.button = 0; /* For motion events */
|
||||||
term_mouse_up(term, button, term->mouse.row, term->mouse.col,
|
term_mouse_up(term, button, term->mouse.row, term->mouse.col,
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ executable(
|
||||||
'main.c',
|
'main.c',
|
||||||
'osc.c', 'osc.h',
|
'osc.c', 'osc.h',
|
||||||
'render.c', 'render.h',
|
'render.c', 'render.h',
|
||||||
|
'selection.c', 'selection.h',
|
||||||
'shm.c', 'shm.h',
|
'shm.c', 'shm.h',
|
||||||
'slave.c', 'slave.h',
|
'slave.c', 'slave.h',
|
||||||
'terminal.c', 'terminal.h',
|
'terminal.c', 'terminal.h',
|
||||||
|
|
|
||||||
70
selection.c
Normal file
70
selection.c
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
#include "selection.h"
|
||||||
|
|
||||||
|
#define LOG_MODULE "selection"
|
||||||
|
#define LOG_ENABLE_DBG 1
|
||||||
|
#include "log.h"
|
||||||
|
#include "render.h"
|
||||||
|
|
||||||
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||||
|
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||||
|
|
||||||
|
void
|
||||||
|
selection_start(struct terminal *term, int col, int row)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
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,
|
||||||
|
min(term->selection.start.row, term->selection.end.row) - term->grid->view,
|
||||||
|
max(term->selection.start.row, term->selection.end.row) - term->grid->view);
|
||||||
|
|
||||||
|
if (term->frame_callback == NULL)
|
||||||
|
grid_render(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
selection_finalizie(struct terminal *term)
|
||||||
|
{
|
||||||
|
assert(term->selection.start.row != -1);
|
||||||
|
assert(term->selection.end.row != -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
selection_cancel(struct terminal *term)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
8
selection.h
Normal file
8
selection.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "terminal.h"
|
||||||
|
|
||||||
|
void selection_start(struct terminal *term, int col, int row);
|
||||||
|
void selection_update(struct terminal *term, int col, int row);
|
||||||
|
void selection_finalizie(struct terminal *term);
|
||||||
|
void selection_cancel(struct terminal *term);
|
||||||
19
terminal.c
19
terminal.c
|
|
@ -14,11 +14,26 @@
|
||||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||||
|
|
||||||
|
void
|
||||||
|
term_damage_rows(struct terminal *term, int start, int end)
|
||||||
|
{
|
||||||
|
assert(start <= end);
|
||||||
|
for (int r = start; r <= end; r++)
|
||||||
|
grid_row(term->grid, r)->dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
term_damage_rows_in_view(struct terminal *term, int start, int end)
|
||||||
|
{
|
||||||
|
assert(start <= end);
|
||||||
|
for (int r = start; r <= end; r++)
|
||||||
|
grid_row_in_view(term->grid, r)->dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
term_damage_all(struct terminal *term)
|
term_damage_all(struct terminal *term)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < term->rows; i++)
|
term_damage_rows(term, 0, term->rows);
|
||||||
grid_row(term->grid, i)->dirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -244,8 +244,12 @@ struct terminal {
|
||||||
struct wl_callback *frame_callback;
|
struct wl_callback *frame_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void term_damage_rows(struct terminal *term, int start, int end);
|
||||||
|
void term_damage_rows_in_view(struct terminal *term, int start, int end);
|
||||||
|
|
||||||
void term_damage_all(struct terminal *term);
|
void term_damage_all(struct terminal *term);
|
||||||
void term_damage_view(struct terminal *term);
|
void term_damage_view(struct terminal *term);
|
||||||
|
|
||||||
void term_damage_scroll(
|
void term_damage_scroll(
|
||||||
struct terminal *term, enum damage_type damage_type,
|
struct terminal *term, enum damage_type damage_type,
|
||||||
struct scroll_region region, int lines);
|
struct scroll_region region, int lines);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue