shithub: orca

Download patch

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) {