ref: eae201940e58355f5e441cb47140fa7431bde7f6
parent: af2164233545d8807410ddb1c45fd0850d8d7ed7
author: cancel <cancel@cancel.fm>
date: Fri Jan 3 21:10:28 EST 2020
Add ` and ~ to toggle slide input mode
--- a/tui_main.c
+++ b/tui_main.c
@@ -171,6 +171,7 @@
Ged_input_mode_normal = 0,
Ged_input_mode_append,
Ged_input_mode_selresize,
+ Ged_input_mode_slide,
} Ged_input_mode;
typedef struct {
@@ -512,6 +513,10 @@
wattrset(win, A_bold);
waddstr(win, "select");
break;
+ case Ged_input_mode_slide:
+ wattrset(win, A_reverse);
+ waddstr(win, "slide");
+ break;
}
advance_faketab(win, win_x, Tabstop);
wattrset(win, A_normal);
@@ -1377,6 +1382,76 @@
}
}
+bool ged_try_selection_clipped_to_field(Ged const* a, Usz* out_y, Usz* out_x,
+ Usz* out_h, Usz* out_w) {
+ Usz curs_y = a->ged_cursor.y;
+ Usz curs_x = a->ged_cursor.x;
+ Usz curs_h = a->ged_cursor.h;
+ Usz curs_w = a->ged_cursor.w;
+ Usz field_h = a->field.height;
+ Usz field_w = a->field.width;
+ if (curs_y >= field_h || curs_x >= field_w)
+ return false;
+ if (field_h - curs_y < curs_h)
+ curs_h = field_h - curs_y;
+ if (field_w - curs_x < curs_w)
+ curs_w = field_w - curs_x;
+ *out_y = curs_y;
+ *out_x = curs_x;
+ *out_h = curs_h;
+ *out_w = curs_w;
+ return true;
+}
+
+bool ged_slide_selection(Ged* a, int delta_y, int delta_x) {
+ Usz curs_y_0, curs_x_0, curs_h_0, curs_w_0;
+ Usz curs_y_1, curs_x_1, curs_h_1, curs_w_1;
+ if (!ged_try_selection_clipped_to_field(a, &curs_y_0, &curs_x_0, &curs_h_0,
+ &curs_w_0))
+ return false;
+ ged_move_cursor_relative(a, delta_y, delta_x);
+ if (!ged_try_selection_clipped_to_field(a, &curs_y_1, &curs_x_1, &curs_h_1,
+ &curs_w_1))
+ return false;
+ // Don't create a history entry if nothing is going to happen.
+ if (curs_y_0 == curs_y_1 && curs_x_0 == curs_x_1 && curs_h_0 == curs_h_1 &&
+ curs_w_0 == curs_w_1)
+ return false;
+ undo_history_push(&a->undo_hist, &a->field, a->tick_num);
+ Usz field_h = a->field.height;
+ Usz field_w = a->field.width;
+ gbuffer_copy_subrect(a->field.buffer, a->field.buffer, field_h, field_w,
+ field_h, field_w, curs_y_0, curs_x_0, curs_y_1, curs_x_1,
+ curs_h_0, curs_w_0);
+ // Erase/clear the area that was within the selection rectangle in the
+ // starting position, but wasn't written to during the copy. (In other words,
+ // this is the area that was 'left behind' when we moved the selection
+ // rectangle, plus any area that was along the bottom and right edge of the
+ // field that didn't have anything to copy to it when the selection rectangle
+ // extended outside of the field.)
+ Usz ey, eh, ex, ew;
+ if (curs_y_1 > curs_y_0) {
+ ey = curs_y_0;
+ eh = curs_y_1 - curs_y_0;
+ } else {
+ ey = curs_y_1 + curs_h_0;
+ eh = (curs_y_0 + curs_h_0) - ey;
+ }
+ if (curs_x_1 > curs_x_0) {
+ ex = curs_x_0;
+ ew = curs_x_1 - curs_x_0;
+ } else {
+ ex = curs_x_1 + curs_w_0;
+ ew = (curs_x_0 + curs_w_0) - ex;
+ }
+ gbuffer_fill_subrect(a->field.buffer, field_h, field_w, ey, curs_x_0, eh,
+ curs_w_0, '.');
+ gbuffer_fill_subrect(a->field.buffer, field_h, field_w, curs_y_0, ex,
+ curs_h_0, ew, '.');
+ a->needs_remarking = true;
+ return true;
+}
+
typedef enum {
Ged_dir_up,
Ged_dir_down,
@@ -1419,6 +1494,23 @@
ged_modify_selection_size(a, 0, step_length);
break;
}
+ break;
+ case Ged_input_mode_slide:
+ switch (dir) {
+ case Ged_dir_up:
+ ged_slide_selection(a, -step_length, 0);
+ break;
+ case Ged_dir_down:
+ ged_slide_selection(a, step_length, 0);
+ break;
+ case Ged_dir_left:
+ ged_slide_selection(a, 0, -step_length);
+ break;
+ case Ged_dir_right:
+ ged_slide_selection(a, 0, step_length);
+ break;
+ }
+ break;
}
}
@@ -1552,27 +1644,6 @@
a->is_draw_dirty = true;
}
-bool ged_try_selection_clipped_to_field(Ged const* a, Usz* out_y, Usz* out_x,
- Usz* out_h, Usz* out_w) {
- Usz curs_y = a->ged_cursor.y;
- Usz curs_x = a->ged_cursor.x;
- Usz curs_h = a->ged_cursor.h;
- Usz curs_w = a->ged_cursor.w;
- Usz field_h = a->field.height;
- Usz field_w = a->field.width;
- if (curs_y >= field_h || curs_x >= field_w)
- return false;
- if (field_h - curs_y < curs_h)
- curs_h = field_h - curs_y;
- if (field_w - curs_x < curs_w)
- curs_w = field_w - curs_x;
- *out_y = curs_y;
- *out_x = curs_x;
- *out_h = curs_h;
- *out_w = curs_w;
- return true;
-}
-
bool ged_fill_selection_with_char(Ged* a, Glyph c) {
Usz curs_y, curs_x, curs_h, curs_w;
if (!ged_try_selection_clipped_to_field(a, &curs_y, &curs_x, &curs_h,
@@ -1597,55 +1668,6 @@
return true;
}
-bool ged_slide_selection(Ged* a, int delta_y, int delta_x) {
- Usz curs_y_0, curs_x_0, curs_h_0, curs_w_0;
- Usz curs_y_1, curs_x_1, curs_h_1, curs_w_1;
- if (!ged_try_selection_clipped_to_field(a, &curs_y_0, &curs_x_0, &curs_h_0,
- &curs_w_0))
- return false;
- ged_move_cursor_relative(a, delta_y, delta_x);
- if (!ged_try_selection_clipped_to_field(a, &curs_y_1, &curs_x_1, &curs_h_1,
- &curs_w_1))
- return false;
- // Don't create a history entry if nothing is going to happen.
- if (curs_y_0 == curs_y_1 && curs_x_0 == curs_x_1 && curs_h_0 == curs_h_1 &&
- curs_w_0 == curs_w_1)
- return false;
- undo_history_push(&a->undo_hist, &a->field, a->tick_num);
- Usz field_h = a->field.height;
- Usz field_w = a->field.width;
- gbuffer_copy_subrect(a->field.buffer, a->field.buffer, field_h, field_w,
- field_h, field_w, curs_y_0, curs_x_0, curs_y_1, curs_x_1,
- curs_h_0, curs_w_0);
- // Erase/clear the area that was within the selection rectangle in the
- // starting position, but wasn't written to during the copy. (In other words,
- // this is the area that was 'left behind' when we moved the selection
- // rectangle, plus any area that was along the bottom and right edge of the
- // field that didn't have anything to copy to it when the selection rectangle
- // extended outside of the field.)
- Usz ey, eh, ex, ew;
- if (curs_y_1 > curs_y_0) {
- ey = curs_y_0;
- eh = curs_y_1 - curs_y_0;
- } else {
- ey = curs_y_1 + curs_h_0;
- eh = (curs_y_0 + curs_h_0) - ey;
- }
- if (curs_x_1 > curs_x_0) {
- ex = curs_x_0;
- ew = curs_x_1 - curs_x_0;
- } else {
- ex = curs_x_1 + curs_w_0;
- ew = (curs_x_0 + curs_w_0) - ex;
- }
- gbuffer_fill_subrect(a->field.buffer, field_h, field_w, ey, curs_x_0, eh,
- curs_w_0, '.');
- gbuffer_fill_subrect(a->field.buffer, field_h, field_w, curs_y_0, ex,
- curs_h_0, ew, '.');
- a->needs_remarking = true;
- return true;
-}
-
void ged_input_character(Ged* a, char c) {
switch (a->input_mode) {
case Ged_input_mode_append:
@@ -1653,6 +1675,7 @@
break;
case Ged_input_mode_normal:
case Ged_input_mode_selresize:
+ case Ged_input_mode_slide:
if (a->ged_cursor.h <= 1 && a->ged_cursor.w <= 1) {
ged_write_character(a, c);
} else {
@@ -1669,6 +1692,7 @@
Ged_input_cmd_undo,
Ged_input_cmd_toggle_append_mode,
Ged_input_cmd_toggle_selresize_mode,
+ Ged_input_cmd_toggle_slide_mode,
Ged_input_cmd_step_forward,
Ged_input_cmd_toggle_show_event_list,
Ged_input_cmd_toggle_play_pause,
@@ -1710,6 +1734,14 @@
}
a->is_draw_dirty = true;
break;
+ case Ged_input_cmd_toggle_slide_mode:
+ if (a->input_mode == Ged_input_mode_slide) {
+ a->input_mode = Ged_input_mode_normal;
+ } else {
+ a->input_mode = Ged_input_mode_slide;
+ }
+ a->is_draw_dirty = true;
+ break;
case Ged_input_cmd_step_forward:
undo_history_push(&a->undo_hist, &a->field, a->tick_num);
clear_and_run_vm(a->field.buffer, a->mbuf_r.buffer, a->field.height,
@@ -3033,6 +3065,10 @@
break;
case '\'':
ged_input_cmd(&ged_state, Ged_input_cmd_toggle_selresize_mode);
+ break;
+ case '`':
+ case '~':
+ ged_input_cmd(&ged_state, Ged_input_cmd_toggle_slide_mode);
break;
case ' ':
if (ged_state.input_mode == Ged_input_mode_append) {