From fbb939ba3f1c1f49c583874af20eb96c8a1df4c4 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 3 May 2019 14:50:08 -0400 Subject: [PATCH 01/12] fix canvas bounds issues --- src/canvas.c | 7 ++++++- src/cursor.c | 12 ++++++++++-- src/frontend.c | 30 ++++++++++++++++++++++++------ src/view.c | 4 ++-- src/view.h | 4 ++-- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/canvas.c b/src/canvas.c index c172df1..82f3bf8 100644 --- a/src/canvas.c +++ b/src/canvas.c @@ -4,6 +4,7 @@ * TODO: assert get/set positions are within canvas sizes? */ #include "canvas.h" +#include #include #include #include @@ -81,7 +82,11 @@ void canvas_schari(Canvas *canvas, int i, char c) { /* Get the character at position (x, y) * */ -char canvas_gcharyx(Canvas *canvas, int y, int x) { return canvas->rows[y][x]; } +char canvas_gcharyx(Canvas *canvas, int y, int x) { + assert(x <= canvas->num_cols); + assert(y <= canvas->num_rows); + return canvas->rows[y][x]; +} /* Get the character at index i * diff --git a/src/cursor.c b/src/cursor.c index 7d946e8..3048099 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -23,7 +23,11 @@ void cursor_move_up(Cursor *cursor, View *view) { } void cursor_move_down(Cursor *cursor, View *view) { - if (cursor->y == view_max_y) { + if (cursor->y + 1 >= view->canvas->num_rows - view->y) { + cursor->y = view->canvas->num_rows - view->y - 1; + return; + } + if (cursor->y + 1 >= view_max_y) { view_move_down(view); return; } @@ -39,7 +43,11 @@ void cursor_move_left(Cursor *cursor, View *view) { } void cursor_move_right(Cursor *cursor, View *view) { - if (cursor->x == view_max_x) { + if (cursor->x >= view->canvas->num_cols - view->x - 1) { + cursor->x = view->canvas->num_cols - view->x - 1; + return; + } + if (cursor->x + 1 >= view_max_x) { view_move_right(view); return; } diff --git a/src/frontend.c b/src/frontend.c index 73a22f9..be89fb7 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -41,7 +41,7 @@ int main(int argc, char *argv[]) { (void)noecho(); /* don't print on getch() */ curs_set(2); - define_key("\r", KEY_ENTER); // Bind the key properly + define_key("\r", KEY_ENTER); // Bind the key properly if (has_colors()) { setup_colors(); @@ -63,9 +63,7 @@ int main(int argc, char *argv[]) { print_status(test_msg, status_win); // Move cursor to starting location and redraw - wmove(canvas_win, cursor_y_to_canvas(cursor), cursor_x_to_canvas(cursor)); - wrefresh(status_win); - wrefresh(canvas_win); // Refresh Canvas last so it gets the cursor + refresh_screen(); //// Main loop State new_state = { @@ -115,12 +113,32 @@ void front_setcharcursor(char ch) { } void redraw_canvas_win() { - for (int x = 0; x < view_max_x; x++) { - for (int y = 0; y < view_max_y; y++) { + int max_x = view_max_x; + int max_y = view_max_y; + + if (max_x >= view->canvas->num_cols - view->x) + (max_x = view->canvas->num_cols - view->x); + if (max_y >= view->canvas->num_rows - view->y) + (max_y = view->canvas->num_rows - view->y); + + // draw canvas onto window + for (int x = 0; x < max_x; x++) { + for (int y = 0; y < max_y; y++) { mvwaddch(canvas_win, y + 1, x + 1, canvas_gcharyx(view->canvas, y + view->y, x + view->x)); } } + + for (int x = max_x; x < view_max_x; x++) { + for (int y = 0; y < view_max_y; y++) { + mvwaddch(canvas_win, y + 1, x + 1, 'X'); + } + } + for (int y = max_y; y < view_max_y; y++) { + for (int x = 0; x < view_max_x; x++) { + mvwaddch(canvas_win, y + 1, x + 1, 'X'); + } + } } void refresh_screen() { diff --git a/src/view.c b/src/view.c index 699379d..4a865c0 100644 --- a/src/view.c +++ b/src/view.c @@ -23,7 +23,7 @@ void view_move_up(View *view) { } void view_move_down(View *view) { - if (view->y - view_max_y == view->canvas->num_rows) { + if (view->y + view_max_y > view->canvas->num_rows) { return; } view->y++; @@ -37,7 +37,7 @@ void view_move_left(View *view) { } void view_move_right(View *view) { - if (view->x + view_max_x == view->canvas->num_cols) { + if (view->x + view_max_x > view->canvas->num_cols) { return; } view->x++; diff --git a/src/view.h b/src/view.h index 76b58cb..1db0ddd 100644 --- a/src/view.h +++ b/src/view.h @@ -6,8 +6,8 @@ #include "canvas.h" #define STATUS_HEIGHT 2 // not including borders -#define view_max_x (COLS - 3) -#define view_max_y (LINES - 4 - STATUS_HEIGHT) +#define view_max_x (COLS - 2) +#define view_max_y (LINES - 3 - STATUS_HEIGHT) typedef struct { int x, y; From bfed6ed63bcaa203f18e2b4b609bbe429116db22 Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Fri, 19 Apr 2019 16:27:52 -0400 Subject: [PATCH 02/12] first pass free line, featuring bad diagonals --- src/fe_modes.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++- src/fe_modes.h | 1 + src/frontend.c | 1 + src/mode_id.h | 1 + 4 files changed, 125 insertions(+), 1 deletion(-) diff --git a/src/fe_modes.c b/src/fe_modes.c index 60e6649..14ae594 100644 --- a/src/fe_modes.c +++ b/src/fe_modes.c @@ -16,6 +16,7 @@ int (*mode_functions[])(State *, WINDOW *, WINDOW *) = { mode_picker, mode_insert, mode_pan, + mode_free_line, }; ////////////////////////////// @@ -114,7 +115,6 @@ int mode_pan(State *state, WINDOW *canvas_win, WINDOW *status_win) { state->current_mode = MODE_PICKER; return 0; } - if ((state->ch_in == KEY_LEFT) || (state->ch_in == KEY_RIGHT) || (state->ch_in == KEY_UP) || (state->ch_in == KEY_DOWN)) { view_pan_ch(state->ch_in, state->view); @@ -123,6 +123,127 @@ int mode_pan(State *state, WINDOW *canvas_win, WINDOW *status_win) { return 0; } +/* mode_free_line + * + * Move with arrows and insert character with keyboard. + */ +int mode_free_line(State *state, WINDOW *canvas_win, WINDOW *status_win) { + // handle mode changing + if (state->ch_in == KEY_TAB) { + // Clean up code + state->last_canvas_mode = MODE_INSERT; + + state->current_mode = MODE_PICKER; + return 0; + } + + // insert mode behavior + + if ((state->ch_in == KEY_LEFT) || (state->ch_in == KEY_RIGHT) || + (state->ch_in == KEY_UP) || (state->ch_in == KEY_DOWN)) { + int current_arrow = state->ch_in; + int last_arrow = state->last_arrow_direction; + + mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), + cursor_x_to_canvas(state->cursor), + free_line_arrows_to_char(last_arrow, current_arrow)); + + cursor_key_to_move(current_arrow, state->cursor, state->view); + state->last_arrow_direction = state->ch_in; + } + + // if ((state->ch_in == KEY_LEFT) || (state->ch_in == KEY_RIGHT) || + // (state->ch_in == KEY_UP) || (state->ch_in == KEY_DOWN)) { + // switch (state->ch_in) { + // case KEY_LEFT: + // cursor_move_left(state->cursor); + // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), + // cursor_x_to_canvas(state->cursor), horizontal); + // break; + // case KEY_RIGHT: + // cursor_move_right(state->cursor); + // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), + // cursor_x_to_canvas(state->cursor), horizontal); + // break; + // case KEY_UP: + // cursor_move_up(state->cursor); + // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), + // cursor_x_to_canvas(state->cursor), vertical); + // break; + // case KEY_DOWN: + // cursor_move_down(state->cursor); + // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), + // cursor_x_to_canvas(state->cursor), vertical); + // break; + // } + + // cursor_key_to_move(state->ch_in, state->cursor); + // state->last_arrow_direction = state->ch_in; + // } else { + // if (' ' <= state->ch_in && + // state->ch_in <= '~') { // check if ch is printable + // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), + // cursor_x_to_canvas(state->cursor), state->ch_in); + // cursor_key_to_move(state->last_arrow_direction, state->cursor); + // } else if (state->ch_in == KEY_BACKSPACE) { + // cursor_key_to_move(cursor_opposite_dir(state->last_arrow_direction), + // state->cursor); + // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), + // cursor_x_to_canvas(state->cursor), ' '); + // } else if (state->ch_in == KEY_DC) { + // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), + // cursor_x_to_canvas(state->cursor), ' '); + // } else { + // // Print non-print characters to bottom left in status_win bar + // mvwaddch(status_win, 1, COLS - 3, state->ch_in); + // } + // } + // Move UI cursor to the right place + wmove(canvas_win, cursor_y_to_canvas(state->cursor), + cursor_x_to_canvas(state->cursor)); + + return 0; +} //////////////////////////// // SPECIFC MODE FUNCTIONS // //////////////////////////// + +/* free_line_arrows_to_char + * + * Takes the current and previous arrow directions, and returns the + * appropriate character, including diagonals. + * + * NOTE: Assumes that the input character is an arrow key + * + * Reference table: + * ^ v > < (current) + * + * ^ | | / \ + * v | | \ / + * > \ / - - + * < / \ - - + * (last) + */ +int free_line_arrows_to_char(int last_arrow, int current_arrow) { + char horizontal = '-'; + char vertical = '|'; + char diag_up = '/'; + char diag_down = '\\'; + + if ((last_arrow == KEY_UP || current_arrow == KEY_DOWN) && + (last_arrow == KEY_DOWN || current_arrow == KEY_UP)) { + // arrows are vertically parallel (top left quarter of truth table) + return vertical; + } else if ((last_arrow == KEY_LEFT || current_arrow == KEY_RIGHT) && + (last_arrow == KEY_RIGHT || current_arrow == KEY_LEFT)) { + // arrows are horizontally parallel (bottom right quarter of truth table) + return horizontal; + } else if ((last_arrow == KEY_UP && current_arrow == KEY_RIGHT) || + (last_arrow == KEY_DOWN && current_arrow == KEY_LEFT) || + (last_arrow == KEY_LEFT && current_arrow == KEY_DOWN) || + (last_arrow == KEY_RIGHT && current_arrow == KEY_UP)) { + return diag_up; + } else { + return diag_down; + } +} diff --git a/src/fe_modes.h b/src/fe_modes.h index 2c4563b..7d0d23f 100644 --- a/src/fe_modes.h +++ b/src/fe_modes.h @@ -7,6 +7,7 @@ int mode_picker(State *state, WINDOW *canvas_win, WINDOW *status_win); int mode_insert(State *state, WINDOW *canvas_win, WINDOW *status_win); int mode_pan(State *state, WINDOW *canvas_win, WINDOW *status_win); +int mode_free_line(State *state, WINDOW *canvas_win, WINDOW *status_win); extern int (*mode_functions[])(State *, WINDOW *, WINDOW *); diff --git a/src/frontend.c b/src/frontend.c index be89fb7..97984f9 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -70,6 +70,7 @@ int main(int argc, char *argv[]) { .ch_in = 0, .cursor = cursor, .current_mode = MODE_INSERT, + .last_arrow_direction = KEY_RIGHT, .last_canvas_mode = MODE_INSERT, .view = view, diff --git a/src/mode_id.h b/src/mode_id.h index 45f7c91..1104a70 100644 --- a/src/mode_id.h +++ b/src/mode_id.h @@ -9,6 +9,7 @@ typedef enum { MODE_PICKER, MODE_INSERT, MODE_PAN, + MODE_FREE_LINE, // ^ add your mode above LAST, // used to get number of elements From df5449c2e5fe59af3d7c26de7f1eac14545af0ee Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Tue, 23 Apr 2019 16:51:59 -0400 Subject: [PATCH 03/12] added last cursor position, doesn't work too well --- src/fe_modes.c | 97 +++++++++++++++++++++++++++----------------------- src/frontend.c | 5 ++- src/state.h | 1 + 3 files changed, 58 insertions(+), 45 deletions(-) diff --git a/src/fe_modes.c b/src/fe_modes.c index 14ae594..6a05015 100644 --- a/src/fe_modes.c +++ b/src/fe_modes.c @@ -39,6 +39,51 @@ Mode_ID return_to_canvas(int input_ch) { // State? return LAST; } +//////////////////////////// +// SPECIFC MODE FUNCTIONS // +//////////////////////////// + +/* free_line_arrows_to_char + * + * Takes the current and previous arrow directions, and returns the + * appropriate character, including diagonals. + * + * NOTE: Assumes that the input character is an arrow key + * + * Reference table: + * ^ v > < (current) + * + * ^ | | / \ + * v | | \ / + * > \ / - - + * < / \ - - + * (last) + */ +int free_line_arrows_to_char(int last_arrow, int current_arrow, + bool *erase_last_position) { + char horizontal = '-'; + char vertical = '|'; + char diag_up = '/'; + char diag_down = '\\'; + + if ((last_arrow == KEY_UP || current_arrow == KEY_DOWN) && + (last_arrow == KEY_DOWN || current_arrow == KEY_UP)) { + // arrows are vertically parallel (top left quarter of truth table) + return vertical; + } else if ((last_arrow == KEY_LEFT || current_arrow == KEY_RIGHT) && + (last_arrow == KEY_RIGHT || current_arrow == KEY_LEFT)) { + // arrows are horizontally parallel (bottom right quarter of truth table) + return horizontal; + } else if ((last_arrow == KEY_UP && current_arrow == KEY_RIGHT) || + (last_arrow == KEY_DOWN && current_arrow == KEY_LEFT) || + (last_arrow == KEY_LEFT && current_arrow == KEY_DOWN) || + (last_arrow == KEY_RIGHT && current_arrow == KEY_UP)) { + return diag_up; + } else { + return diag_down; + } +} + //////////////////// // MODE FUNCTIONS // //////////////////// @@ -144,9 +189,16 @@ int mode_free_line(State *state, WINDOW *canvas_win, WINDOW *status_win) { int current_arrow = state->ch_in; int last_arrow = state->last_arrow_direction; + bool should_erase_last_position = FALSE; mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), cursor_x_to_canvas(state->cursor), - free_line_arrows_to_char(last_arrow, current_arrow)); + free_line_arrows_to_char(last_arrow, current_arrow, + &should_erase_last_position)); + + if (should_erase_last_position) { + mvwaddch(canvas_win, cursor_y_to_canvas(state->last_cursor), + cursor_x_to_canvas(state->last_cursor), ' '); + } cursor_key_to_move(current_arrow, state->cursor, state->view); state->last_arrow_direction = state->ch_in; @@ -204,46 +256,3 @@ int mode_free_line(State *state, WINDOW *canvas_win, WINDOW *status_win) { return 0; } -//////////////////////////// -// SPECIFC MODE FUNCTIONS // -//////////////////////////// - -/* free_line_arrows_to_char - * - * Takes the current and previous arrow directions, and returns the - * appropriate character, including diagonals. - * - * NOTE: Assumes that the input character is an arrow key - * - * Reference table: - * ^ v > < (current) - * - * ^ | | / \ - * v | | \ / - * > \ / - - - * < / \ - - - * (last) - */ -int free_line_arrows_to_char(int last_arrow, int current_arrow) { - char horizontal = '-'; - char vertical = '|'; - char diag_up = '/'; - char diag_down = '\\'; - - if ((last_arrow == KEY_UP || current_arrow == KEY_DOWN) && - (last_arrow == KEY_DOWN || current_arrow == KEY_UP)) { - // arrows are vertically parallel (top left quarter of truth table) - return vertical; - } else if ((last_arrow == KEY_LEFT || current_arrow == KEY_RIGHT) && - (last_arrow == KEY_RIGHT || current_arrow == KEY_LEFT)) { - // arrows are horizontally parallel (bottom right quarter of truth table) - return horizontal; - } else if ((last_arrow == KEY_UP && current_arrow == KEY_RIGHT) || - (last_arrow == KEY_DOWN && current_arrow == KEY_LEFT) || - (last_arrow == KEY_LEFT && current_arrow == KEY_DOWN) || - (last_arrow == KEY_RIGHT && current_arrow == KEY_UP)) { - return diag_up; - } else { - return diag_down; - } -} diff --git a/src/frontend.c b/src/frontend.c index 97984f9..bf468cb 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -51,6 +51,7 @@ int main(int argc, char *argv[]) { status_win = create_status_win(); cursor = cursor_new(); + Cursor *last_cursor = cursor_new(); Canvas *canvas = canvas_new_blank(1000, 1000); view = view_new_startpos(canvas, 300, 300); @@ -74,6 +75,7 @@ int main(int argc, char *argv[]) { .last_arrow_direction = KEY_RIGHT, .last_canvas_mode = MODE_INSERT, .view = view, + .last_cursor = last_cursor, }; State *state = &new_state; @@ -82,8 +84,9 @@ int main(int argc, char *argv[]) { mode_functions[state->current_mode](state, canvas_win, status_win); - update_screen_size(canvas_win, status_win, cursor); + *(state->last_cursor) = *(state->cursor); + update_screen_size(canvas_win, status_win, cursor); refresh_screen(); } diff --git a/src/state.h b/src/state.h index 13858a5..3400713 100644 --- a/src/state.h +++ b/src/state.h @@ -19,6 +19,7 @@ typedef struct { Mode_ID last_canvas_mode; int last_arrow_direction; View *view; + Cursor *last_cursor; } State; #endif From a3801353dc3418f5a3a6e383f4a0eec0a5d527ee Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Tue, 23 Apr 2019 18:11:31 -0400 Subject: [PATCH 04/12] gave up on cleaning diagonal lines due to symmetry --- src/fe_modes.c | 63 +++++--------------------------------------------- src/frontend.c | 4 ++-- 2 files changed, 8 insertions(+), 59 deletions(-) diff --git a/src/fe_modes.c b/src/fe_modes.c index 6a05015..997a200 100644 --- a/src/fe_modes.c +++ b/src/fe_modes.c @@ -59,8 +59,7 @@ Mode_ID return_to_canvas(int input_ch) { // State? * < / \ - - * (last) */ -int free_line_arrows_to_char(int last_arrow, int current_arrow, - bool *erase_last_position) { +int free_line_arrows_to_char(int last_arrow, int current_arrow) { char horizontal = '-'; char vertical = '|'; char diag_up = '/'; @@ -190,67 +189,17 @@ int mode_free_line(State *state, WINDOW *canvas_win, WINDOW *status_win) { int last_arrow = state->last_arrow_direction; bool should_erase_last_position = FALSE; - mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), - cursor_x_to_canvas(state->cursor), - free_line_arrows_to_char(last_arrow, current_arrow, - &should_erase_last_position)); + front_setcharcursor(free_line_arrows_to_char(last_arrow, current_arrow)); - if (should_erase_last_position) { - mvwaddch(canvas_win, cursor_y_to_canvas(state->last_cursor), - cursor_x_to_canvas(state->last_cursor), ' '); - } + // *(state->last_cursor) = *(state->cursor); + state->last_cursor->x = state->cursor->x; + state->last_cursor->y = state->cursor->y; cursor_key_to_move(current_arrow, state->cursor, state->view); + state->last_arrow_direction = state->ch_in; } - // if ((state->ch_in == KEY_LEFT) || (state->ch_in == KEY_RIGHT) || - // (state->ch_in == KEY_UP) || (state->ch_in == KEY_DOWN)) { - // switch (state->ch_in) { - // case KEY_LEFT: - // cursor_move_left(state->cursor); - // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), - // cursor_x_to_canvas(state->cursor), horizontal); - // break; - // case KEY_RIGHT: - // cursor_move_right(state->cursor); - // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), - // cursor_x_to_canvas(state->cursor), horizontal); - // break; - // case KEY_UP: - // cursor_move_up(state->cursor); - // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), - // cursor_x_to_canvas(state->cursor), vertical); - // break; - // case KEY_DOWN: - // cursor_move_down(state->cursor); - // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), - // cursor_x_to_canvas(state->cursor), vertical); - // break; - // } - - // cursor_key_to_move(state->ch_in, state->cursor); - // state->last_arrow_direction = state->ch_in; - // } else { - // if (' ' <= state->ch_in && - // state->ch_in <= '~') { // check if ch is printable - // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), - // cursor_x_to_canvas(state->cursor), state->ch_in); - // cursor_key_to_move(state->last_arrow_direction, state->cursor); - // } else if (state->ch_in == KEY_BACKSPACE) { - // cursor_key_to_move(cursor_opposite_dir(state->last_arrow_direction), - // state->cursor); - // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), - // cursor_x_to_canvas(state->cursor), ' '); - // } else if (state->ch_in == KEY_DC) { - // mvwaddch(canvas_win, cursor_y_to_canvas(state->cursor), - // cursor_x_to_canvas(state->cursor), ' '); - // } else { - // // Print non-print characters to bottom left in status_win bar - // mvwaddch(status_win, 1, COLS - 3, state->ch_in); - // } - // } - // Move UI cursor to the right place wmove(canvas_win, cursor_y_to_canvas(state->cursor), cursor_x_to_canvas(state->cursor)); diff --git a/src/frontend.c b/src/frontend.c index bf468cb..f7268e4 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -70,7 +70,7 @@ int main(int argc, char *argv[]) { State new_state = { .ch_in = 0, .cursor = cursor, - .current_mode = MODE_INSERT, + .current_mode = MODE_FREE_LINE, .last_arrow_direction = KEY_RIGHT, .last_canvas_mode = MODE_INSERT, @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) { mode_functions[state->current_mode](state, canvas_win, status_win); - *(state->last_cursor) = *(state->cursor); + // *(state->last_cursor) = *(state->cursor); update_screen_size(canvas_win, status_win, cursor); refresh_screen(); From 0aa3b10d31fc6e63e36b20a3a9edda067c4a09a2 Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Fri, 3 May 2019 14:35:53 -0400 Subject: [PATCH 05/12] clean up --- src/fe_modes.c | 9 +++++---- src/frontend.c | 3 ++- src/frontend.h | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/fe_modes.c b/src/fe_modes.c index 997a200..b615732 100644 --- a/src/fe_modes.c +++ b/src/fe_modes.c @@ -181,23 +181,24 @@ int mode_free_line(State *state, WINDOW *canvas_win, WINDOW *status_win) { return 0; } - // insert mode behavior - + // free line behavior if ((state->ch_in == KEY_LEFT) || (state->ch_in == KEY_RIGHT) || (state->ch_in == KEY_UP) || (state->ch_in == KEY_DOWN)) { int current_arrow = state->ch_in; int last_arrow = state->last_arrow_direction; - bool should_erase_last_position = FALSE; front_setcharcursor(free_line_arrows_to_char(last_arrow, current_arrow)); - // *(state->last_cursor) = *(state->cursor); state->last_cursor->x = state->cursor->x; state->last_cursor->y = state->cursor->y; cursor_key_to_move(current_arrow, state->cursor, state->view); state->last_arrow_direction = state->ch_in; + } else if (state->ch_in == KEY_BACKSPACE) { + cursor_key_to_move(cursor_opposite_dir(state->last_arrow_direction), + state->cursor, state->view); + front_setcharcursor(' '); } wmove(canvas_win, cursor_y_to_canvas(state->cursor), diff --git a/src/frontend.c b/src/frontend.c index f7268e4..420a581 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -70,7 +70,8 @@ int main(int argc, char *argv[]) { State new_state = { .ch_in = 0, .cursor = cursor, - .current_mode = MODE_FREE_LINE, + .current_mode = MODE_INSERT, + // .current_mode = MODE_FREE_LINE, .last_arrow_direction = KEY_RIGHT, .last_canvas_mode = MODE_INSERT, diff --git a/src/frontend.h b/src/frontend.h index 89b0a21..259f2ce 100644 --- a/src/frontend.h +++ b/src/frontend.h @@ -7,6 +7,7 @@ #define KEY_TAB '\t' #define KEY_SHIFT_TAB KEY_BTAB +// TODO: Understand delete/backspace on mac void finish(int sig); void setup_colors(); From 59242598a34217f1dda55ee632f268deec172103 Mon Sep 17 00:00:00 2001 From: Evan New-Schmidt Date: Fri, 3 May 2019 15:48:22 -0400 Subject: [PATCH 06/12] Comment new redraw_canvas_win steps --- src/frontend.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frontend.c b/src/frontend.c index 420a581..55b1962 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -118,6 +118,7 @@ void front_setcharcursor(char ch) { } void redraw_canvas_win() { + // find max ranges to draw canvas int max_x = view_max_x; int max_y = view_max_y; @@ -134,6 +135,7 @@ void redraw_canvas_win() { } } + // draw fill in rest of window for (int x = max_x; x < view_max_x; x++) { for (int y = 0; y < view_max_y; y++) { mvwaddch(canvas_win, y + 1, x + 1, 'X'); From 09cb615363f5d21472e956e06acbaeb664a67ea0 Mon Sep 17 00:00:00 2001 From: Evan New-Schmidt Date: Fri, 3 May 2019 17:09:44 -0400 Subject: [PATCH 07/12] Draw status window before first keypress --- src/frontend.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/frontend.c b/src/frontend.c index 55b1962..8452640 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -60,10 +60,15 @@ int main(int argc, char *argv[]) { keypad(canvas_win, TRUE); keypad(status_win, TRUE); + // update the screen size first. This clears the status window on any changes + // (including the first time it's run), so refreshing after updating the + // status will clear it otherwise + update_screen_size(); + char test_msg[] = "Test mode"; print_status(test_msg, status_win); - // Move cursor to starting location and redraw + // Move cursor to starting location and redraw canvases refresh_screen(); //// Main loop From 8cb22ee3db865ab1a92309639574e4d8083dc49d Mon Sep 17 00:00:00 2001 From: Evan New-Schmidt Date: Fri, 3 May 2019 17:11:14 -0400 Subject: [PATCH 08/12] Remove old call to update_screen_size The function doesn't accept any parameters, but there weren't any compiler warnings. I just learned that `function()` is different from `function(void)` - the former is a prototype, not a function that accepts zero arguments. > Welcome to the C language, this is part of the legacy standard. https://stackoverflow.com/q/12643202 --- src/frontend.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/frontend.c b/src/frontend.c index 8452640..821620a 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -90,9 +90,6 @@ int main(int argc, char *argv[]) { mode_functions[state->current_mode](state, canvas_win, status_win); - // *(state->last_cursor) = *(state->cursor); - - update_screen_size(canvas_win, status_win, cursor); refresh_screen(); } From 9effe15834cd608d952f842350d8322b24e9c0ec Mon Sep 17 00:00:00 2001 From: Evan New-Schmidt Date: Fri, 3 May 2019 18:30:00 -0400 Subject: [PATCH 09/12] Redirect stderr --- src/frontend.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/frontend.c b/src/frontend.c index 821620a..daf21bb 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -8,10 +8,16 @@ #include "mode_id.h" #include "state.h" +#include +#include + WINDOW *canvas_win, *status_win; Cursor *cursor; View *view; +char *logfile_path = "out.txt"; +FILE *logfile = NULL; + /* Layout * ___________________________________________ * | 0 -- X, COLS | canvas window @@ -30,6 +36,17 @@ View *view; */ int main(int argc, char *argv[]) { + logfile = fopen(logfile_path, "a"); + if (logfile == NULL) { + perror("logfile fopen:"); + exit(1); + } + if (-1 == dup2(fileno(logfile), fileno(stderr))) { + perror("stderr dup2:"); + exit(1); + } + fprintf(stderr, "Starting\n"); + /* initialize your non-curses data structures here */ (void)signal(SIGINT, finish); /* arrange interrupts to terminate */ @@ -246,5 +263,8 @@ void finish(int sig) { /* do your non-curses wrapup here */ + if (logfile != NULL) { + fclose(logfile); + } exit(0); } From b29d56d7dc69a36b9c70b6a0db6cdbb7e2ec9c9f Mon Sep 17 00:00:00 2001 From: Evan New-Schmidt Date: Mon, 15 Apr 2019 14:14:12 -0400 Subject: [PATCH 10/12] Add util header with eprintf --- src/util.h | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/util.h diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..dfda887 --- /dev/null +++ b/src/util.h @@ -0,0 +1,4 @@ +#include + +// printf to stderr +#define eprintf(...) fprintf (stderr, __VA_ARGS__) From 6e810dfa00d421db30ab5ee8194d3552c380e8e5 Mon Sep 17 00:00:00 2001 From: Evan New-Schmidt Date: Fri, 3 May 2019 19:30:15 -0400 Subject: [PATCH 11/12] Add debug log macro --- src/util.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/util.h b/src/util.h index dfda887..32d0ba9 100644 --- a/src/util.h +++ b/src/util.h @@ -1,4 +1,17 @@ +#ifndef util_h +#define util_h + #include // printf to stderr -#define eprintf(...) fprintf (stderr, __VA_ARGS__) +#define eprintf(...) fprintf(stderr, __VA_ARGS__) + +#ifdef DEBUG +// log to stderr if DEBUG is defined +#define logd(...) eprintf(__VA_ARGS__) +#else +// do nothing +#define logd(...) +#endif + +#endif From 1a0fa88faecc232d7e0cfcef50f8490d6b5ade8d Mon Sep 17 00:00:00 2001 From: Evan New-Schmidt Date: Fri, 3 May 2019 19:30:43 -0400 Subject: [PATCH 12/12] Add define to enable logfile --- src/frontend.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/frontend.c b/src/frontend.c index daf21bb..a73321a 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -7,6 +7,7 @@ #include "frontend.h" #include "mode_id.h" #include "state.h" +#include "util.h" #include #include @@ -15,8 +16,14 @@ WINDOW *canvas_win, *status_win; Cursor *cursor; View *view; +#ifdef DEBUG +#define LOG_TO_FILE +#endif + +#ifdef LOG_TO_FILE char *logfile_path = "out.txt"; FILE *logfile = NULL; +#endif /* Layout * ___________________________________________ @@ -36,6 +43,7 @@ FILE *logfile = NULL; */ int main(int argc, char *argv[]) { +#ifdef LOG_TO_FILE logfile = fopen(logfile_path, "a"); if (logfile == NULL) { perror("logfile fopen:"); @@ -45,7 +53,8 @@ int main(int argc, char *argv[]) { perror("stderr dup2:"); exit(1); } - fprintf(stderr, "Starting\n"); +#endif + logd("Starting frontend\n"); /* initialize your non-curses data structures here */ @@ -262,9 +271,10 @@ void finish(int sig) { endwin(); /* do your non-curses wrapup here */ - +#ifdef LOG_TO_FILE if (logfile != NULL) { fclose(logfile); } +#endif exit(0); }