ref: 263aa0e2a5adb40d9807a9ac654f552f66d93988
parent: 66c1e7990b7ac332b7bac0fc475e3591b64fd4f7
author: cancel <cancel@cancel.fm>
date: Mon Dec 10 22:12:08 EST 2018
Add drag-selection
--- a/tui_main.c
+++ b/tui_main.c
@@ -628,7 +628,9 @@
char const* filename;
Oosc_dev* oosc_dev;
Midi_mode const* midi_mode;
- int grid_scroll_y;
+ Usz drag_start_y;
+ Usz drag_start_x;
+ int grid_scroll_y; // not sure if i like this being int
int grid_scroll_x;
bool needs_remarking;
bool is_draw_dirty;
@@ -635,6 +637,7 @@
bool is_playing;
bool draw_event_list;
bool is_mouse_down;
+ bool is_mouse_dragging;
} App_state;
void app_init(App_state* a) {
@@ -660,11 +663,14 @@
a->midi_mode = NULL;
a->grid_scroll_y = 0;
a->grid_scroll_x = 0;
+ a->drag_start_y = 0;
+ a->drag_start_x = 0;
a->needs_remarking = true;
a->is_draw_dirty = false;
a->is_playing = false;
a->draw_event_list = false;
a->is_mouse_down = false;
+ a->is_mouse_dragging = false;
}
void app_deinit(App_state* a) {
@@ -994,8 +1000,7 @@
a->is_draw_dirty = true;
}
-Usz confine_scrolled_mouse_hit(Usz field_len, Usz visual_coord,
- int scroll_offset) {
+Usz view_to_scrolled_grid(Usz field_len, Usz visual_coord, int scroll_offset) {
if (field_len == 0)
return 0;
if (scroll_offset < 0) {
@@ -1012,15 +1017,7 @@
return visual_coord;
}
-void app_jump_cursor_to(App_state* a, Usz y, Usz x) {
- a->tui_cursor.y =
- confine_scrolled_mouse_hit(a->field.height, y, a->grid_scroll_y);
- a->tui_cursor.x =
- confine_scrolled_mouse_hit(a->field.width, x, a->grid_scroll_x);
- a->is_draw_dirty = true;
-}
-
-void app_mouse_event(App_state* a, Usz y, Usz x, mmask_t mouse_bstate) {
+void app_mouse_event(App_state* a, Usz vis_y, Usz vis_x, mmask_t mouse_bstate) {
if (mouse_bstate & BUTTON1_RELEASED) {
// hard-disables tracking, but also disables further mouse stuff.
// mousemask() with our original parameters seems to work to get into the
@@ -1029,17 +1026,46 @@
// printf("\033[?1003l\n");
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
a->is_mouse_down = false;
- } else if (mouse_bstate & BUTTON1_PRESSED) {
- app_jump_cursor_to(a, y, x);
- a->is_mouse_down = true;
- // some sequence to hopefully make terminal start reporting all further
- // mouse movement events. 'REPORT_MOUSE_POSITION' alone in the mousemask
- // doesn't seem to work, at least not for xterm. we need to set it only
- // only when needed, otherwise some terminals will send movement updates
- // when we don't want them.
- printf("\033[?1003h\n");
- } else if (a->is_mouse_down) {
- app_jump_cursor_to(a, y, x);
+ a->is_mouse_dragging = false;
+ a->drag_start_y = 0;
+ a->drag_start_x = 0;
+ } else if ((mouse_bstate & BUTTON1_PRESSED) || a->is_mouse_down) {
+ Usz y = view_to_scrolled_grid(a->field.height, vis_y, a->grid_scroll_y);
+ Usz x = view_to_scrolled_grid(a->field.width, vis_x, a->grid_scroll_x);
+ if (!a->is_mouse_down) {
+ // some sequence to hopefully make terminal start reporting all further
+ // mouse movement events. 'REPORT_MOUSE_POSITION' alone in the mousemask
+ // doesn't seem to work, at least not for xterm. we need to set it only
+ // only when needed, otherwise some terminals will send movement updates
+ // when we don't want them.
+ printf("\033[?1003h\n");
+ a->is_mouse_down = true;
+ a->tui_cursor.y = y;
+ a->tui_cursor.x = x;
+ a->tui_cursor.h = 1;
+ a->tui_cursor.w = 1;
+ a->is_draw_dirty = true;
+ } else {
+ if (!a->is_mouse_dragging &&
+ (y != a->tui_cursor.y || x != a->tui_cursor.x)) {
+ a->is_mouse_dragging = true;
+ a->drag_start_y = a->tui_cursor.y;
+ a->drag_start_x = a->tui_cursor.x;
+ }
+ if (a->is_mouse_dragging) {
+ Usz tcy = a->drag_start_y;
+ Usz tcx = a->drag_start_x;
+ Usz loy = y < tcy ? y : tcy;
+ Usz lox = x < tcx ? x : tcx;
+ Usz hiy = y > tcy ? y : tcy;
+ Usz hix = x > tcx ? x : tcx;
+ a->tui_cursor.y = loy;
+ a->tui_cursor.x = lox;
+ a->tui_cursor.h = hiy - loy + 1;
+ a->tui_cursor.w = hix - lox + 1;
+ a->is_draw_dirty = true;
+ }
+ }
}
}