From 962738815ecb4eeef56af61a9b16e6f079849355 Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Fri, 5 Apr 2019 17:39:15 -0400 Subject: [PATCH 1/7] insert mode mvp --- src/.gitignore | 3 + src/frontend.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++ src/frontend.h | 8 ++ 3 files changed, 207 insertions(+) create mode 100644 src/frontend.c create mode 100644 src/frontend.h diff --git a/src/.gitignore b/src/.gitignore index c332f91..4a127a2 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -5,3 +5,6 @@ *.o *.a *.lib + +## VS Code +../.vscode/ diff --git a/src/frontend.c b/src/frontend.c new file mode 100644 index 0000000..c77b011 --- /dev/null +++ b/src/frontend.c @@ -0,0 +1,196 @@ +#include +#include +#include "frontend.h" + +int STATUS_HEIGHT = 1; + +/* The Cursor struct helps with controls. + * It also maps the drawing area to the canvas nicely. + */ + +typedef struct CURSOR { + int x; + int y; +} Cursor; + +Cursor *cursor_init() { + Cursor *cursor = malloc(sizeof(Cursor)); + cursor->x = 0; + cursor->y = 0; + return cursor; +} + +void move_up(Cursor* cursor) { + if (cursor->y == 0) { + return; + } + cursor->y--; +} + +void move_down(Cursor* cursor) { + if (cursor->y == (LINES - 2)) { // Take box lines into account + return; + } + cursor->y++; +} + +void move_left(Cursor* cursor) { + if (cursor->x == 0) { + return; + } + cursor->x--; +} + +void move_right(Cursor* cursor) { + if (cursor->x == (COLS - 2)) { // Take box lines into account + return; + } + cursor->x++; +} + +int x_to_canvas(Cursor* cursor) { + return cursor->x + 1; // TODO: Don't hardcode border +} + +int y_to_canvas(Cursor* cursor) { + return cursor->y + 1; // TODO: Don't hardcode border +} + +void free_cursor(Cursor* cursor) { + free(cursor); +} + +/* Layout + * ___________________________________________ + * | 0 -- X, COLS | canvas window + * | | | + * | Y, LINES | + * | | + * | | + * | | + * | | + * | | + * | | + * ___________________________________________ + * | | command window + * ___________________________________________ + * */ + +int main(int argc, char *argv[]) { + /* initialize your non-curses data structures here */ + + (void) signal(SIGINT, finish); /* arrange interrupts to terminate */ + + (void) initscr(); /* initialize the curses library */ + keypad(stdscr, TRUE); /* enable keyboard mapping */ + (void) nonl(); /* tell curses not to do NL->CR/NL on output */ + (void) cbreak(); /* take input chars one at a time, no wait for \n */ + (void) noecho(); /* don't print on getch() */ + curs_set(2); + + if (has_colors()) { + setup_colors(); + } + + // Create Canvas + WINDOW *canvas = create_newwin(LINES - (STATUS_HEIGHT), COLS,// Account for lines + 0, 0, TRUE); + + // Create Status bar + WINDOW *status = create_newwin(STATUS_HEIGHT + 2, COLS, + LINES - (STATUS_HEIGHT), 0, + FALSE); + keypad(canvas, TRUE); /* enable keyboard mapping */ + + int num = 0; + Cursor *cursor = cursor_init(); + + char test_msg[] = "Test mode"; + print_status(test_msg, status); + + wrefresh(status); + + int ch; + while ((ch = wgetch(canvas))) + { + switch(ch) { + case KEY_LEFT: + // mvwaddch(canvas, 1, 1, 'L'); + move_left(cursor); + break; + case KEY_RIGHT: + // mvwaddch(canvas, 1, 1, 'R'); + move_right(cursor); + break; + case KEY_UP: + // mvwaddch(canvas, 1, 1, 'U'); + move_up(cursor); + break; + case KEY_DOWN: + // mvwaddch(canvas, 1, 1, 'D'); + move_down(cursor); + break; + default: + // waddch(canvas, ch); + if (' ' <= ch && ch <= '~') { // check if ch is printable + mvwaddch(canvas, y_to_canvas(cursor), x_to_canvas(cursor), ch); + } else { + mvwaddch(status, 0, COLS-1, 'X'); + } + } + wmove(canvas, y_to_canvas(cursor), x_to_canvas(cursor)); + wrefresh(canvas); + + /* process the command keystroke */ + } + + free_cursor(cursor); + finish(0); /* we are done */ +} + +static void setup_colors() { + start_color(); + + /* + * Simple color assignment, often all we need. Color pair 0 cannot + * be redefined. This example uses the same value for the color + * pair as for the foreground color, though of course that is not + * necessary: + */ + init_pair(1, COLOR_RED, COLOR_BLACK); + init_pair(2, COLOR_GREEN, COLOR_BLACK); + init_pair(3, COLOR_BLUE, COLOR_BLACK); + init_pair(4, COLOR_CYAN, COLOR_BLACK); + init_pair(5, COLOR_MAGENTA, COLOR_BLACK); + init_pair(6, COLOR_YELLOW, COLOR_BLACK); + init_pair(7, COLOR_BLACK, COLOR_WHITE); +} + +WINDOW *create_newwin(int height, int width, int starty, int startx, int should_draw_box) { + WINDOW *local_win; + + local_win = newwin(height, width, starty, startx); + + if (should_draw_box) { + box(local_win, 0 , 0); /* 0, 0 gives default characters + * for the vertical and horizontal + * lines */ + wrefresh(local_win); /* Show that box */ + + } + + return local_win; +} + +int print_status(char* str, WINDOW* window) { + wattrset(window, COLOR_PAIR(7)); + return mvwprintw(window, 0, 1, str); +} + +static void finish(int sig) { + endwin(); + + /* do your non-curses wrapup here */ + + exit(0); +} diff --git a/src/frontend.h b/src/frontend.h new file mode 100644 index 0000000..4c9e956 --- /dev/null +++ b/src/frontend.h @@ -0,0 +1,8 @@ +#include + +static void finish(int sig); +static void setup_colors(); + +int print_status(char* str, WINDOW* window); + +WINDOW *create_newwin(int height, int width, int starty, int startx, int should_draw_box); From 930540745adc690ef00185a6d57811ca1724fbc3 Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Fri, 5 Apr 2019 18:05:07 -0400 Subject: [PATCH 2/7] Cleaned up --- src/Makefile | 5 ++++- src/frontend.c | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Makefile b/src/Makefile index 2e16ca4..03a6ad2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS+=-Wall # global includes -# LDFLAGS+= +LDFLAGS+=-lncurses # add debug annotations, turn off optimizations, and #define DEBUG # use in bash with `DEBUG=1 make ` @@ -27,5 +27,8 @@ test: $(patsubst %.c, .run-%.c, $(wildcard *_test.c)) %_test: %_test.c minunit.h $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ +frontend.out: frontend.c frontend.h + $(CC) frontend.c $(CFLAGS) $(LDFLAGS) -o frontend.out + clean: -rm *.o *_test diff --git a/src/frontend.c b/src/frontend.c index c77b011..afa4b33 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -4,10 +4,10 @@ int STATUS_HEIGHT = 1; +// TODO: Factor out to different file? /* The Cursor struct helps with controls. * It also maps the drawing area to the canvas nicely. */ - typedef struct CURSOR { int x; int y; @@ -92,6 +92,7 @@ int main(int argc, char *argv[]) { setup_colors(); } + //// Init environment // Create Canvas WINDOW *canvas = create_newwin(LINES - (STATUS_HEIGHT), COLS,// Account for lines 0, 0, TRUE); @@ -102,7 +103,6 @@ int main(int argc, char *argv[]) { FALSE); keypad(canvas, TRUE); /* enable keyboard mapping */ - int num = 0; Cursor *cursor = cursor_init(); char test_msg[] = "Test mode"; @@ -110,42 +110,41 @@ int main(int argc, char *argv[]) { wrefresh(status); + //// Main loop int ch; while ((ch = wgetch(canvas))) { switch(ch) { case KEY_LEFT: - // mvwaddch(canvas, 1, 1, 'L'); move_left(cursor); break; case KEY_RIGHT: - // mvwaddch(canvas, 1, 1, 'R'); move_right(cursor); break; case KEY_UP: - // mvwaddch(canvas, 1, 1, 'U'); move_up(cursor); break; case KEY_DOWN: - // mvwaddch(canvas, 1, 1, 'D'); move_down(cursor); break; default: - // waddch(canvas, ch); if (' ' <= ch && ch <= '~') { // check if ch is printable mvwaddch(canvas, y_to_canvas(cursor), x_to_canvas(cursor), ch); } else { - mvwaddch(status, 0, COLS-1, 'X'); + // Print non-print characters to bottom left in status bar + mvwaddch(status, 0, COLS-3, ch); } } + // Move UI cursor to the right place wmove(canvas, y_to_canvas(cursor), x_to_canvas(cursor)); - wrefresh(canvas); - /* process the command keystroke */ + wrefresh(status); + wrefresh(canvas); // Refresh Canvas last so it gets the cursor } + // Cleanup free_cursor(cursor); - finish(0); /* we are done */ + finish(0); } static void setup_colors() { From 734a9a5dd9e8b78a351e34a232b9eefc978edacb Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Tue, 9 Apr 2019 16:20:35 -0400 Subject: [PATCH 3/7] addressed suggestions --- src/.gitignore => .gitignore | 2 +- src/Makefile | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) rename src/.gitignore => .gitignore (84%) diff --git a/src/.gitignore b/.gitignore similarity index 84% rename from src/.gitignore rename to .gitignore index 4a127a2..ec4b627 100644 --- a/src/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ *.lib ## VS Code -../.vscode/ +.vscode/ diff --git a/src/Makefile b/src/Makefile index 03a6ad2..4d2e0c5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS+=-Wall # global includes -LDFLAGS+=-lncurses +# LDFLAGS+=-lncurses # add debug annotations, turn off optimizations, and #define DEBUG # use in bash with `DEBUG=1 make ` @@ -29,6 +29,7 @@ test: $(patsubst %.c, .run-%.c, $(wildcard *_test.c)) frontend.out: frontend.c frontend.h $(CC) frontend.c $(CFLAGS) $(LDFLAGS) -o frontend.out +frontend: LDLIBS +=-lncurses clean: -rm *.o *_test From 236469bc88ec91aef84a17864daa1015acce2457 Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Tue, 9 Apr 2019 17:49:48 -0400 Subject: [PATCH 4/7] Improved window borders --- src/frontend.c | 55 +++++++++++++++++++++++++++++++++----------------- src/frontend.h | 2 ++ 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/frontend.c b/src/frontend.c index afa4b33..91ac539 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -49,11 +49,11 @@ void move_right(Cursor* cursor) { } int x_to_canvas(Cursor* cursor) { - return cursor->x + 1; // TODO: Don't hardcode border + return cursor->x + 1; } int y_to_canvas(Cursor* cursor) { - return cursor->y + 1; // TODO: Don't hardcode border + return cursor->y + 1; } void free_cursor(Cursor* cursor) { @@ -91,17 +91,13 @@ int main(int argc, char *argv[]) { if (has_colors()) { setup_colors(); } - - //// Init environment - // Create Canvas - WINDOW *canvas = create_newwin(LINES - (STATUS_HEIGHT), COLS,// Account for lines - 0, 0, TRUE); - // Create Status bar - WINDOW *status = create_newwin(STATUS_HEIGHT + 2, COLS, - LINES - (STATUS_HEIGHT), 0, - FALSE); - keypad(canvas, TRUE); /* enable keyboard mapping */ + WINDOW *canvas = create_canvas_win(); + WINDOW *status = create_status_win(); + + // Enable keyboard mapping + keypad(canvas, TRUE); + keypad(status, TRUE); Cursor *cursor = cursor_init(); @@ -150,12 +146,8 @@ int main(int argc, char *argv[]) { static void setup_colors() { start_color(); - /* - * Simple color assignment, often all we need. Color pair 0 cannot - * be redefined. This example uses the same value for the color - * pair as for the foreground color, though of course that is not - * necessary: - */ + // TODO: Use #define to get colors for standard uses + // Assign color codes init_pair(1, COLOR_RED, COLOR_BLACK); init_pair(2, COLOR_GREEN, COLOR_BLACK); init_pair(3, COLOR_BLUE, COLOR_BLACK); @@ -181,9 +173,34 @@ WINDOW *create_newwin(int height, int width, int starty, int startx, int should_ return local_win; } +WINDOW *create_canvas_win() { + WINDOW *local_win; + + local_win = newwin(LINES - (STATUS_HEIGHT + 1), COLS, 0, 0); + + wborder(local_win, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE, // Sides: ls, rs, ts, bs, + ACS_ULCORNER, ACS_URCORNER, ACS_LTEE, ACS_RTEE); // Corners: tl, tr, bl, br + + wrefresh(local_win); + return local_win; +} + +WINDOW *create_status_win() { + WINDOW *local_win; + + local_win = newwin(STATUS_HEIGHT + 2, COLS, + LINES - (STATUS_HEIGHT+2), 0); + + wborder(local_win, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE, // Sides: ls, rs, ts, bs, + ACS_LTEE, ACS_RTEE, ACS_LLCORNER, ACS_LRCORNER); // Corners: tl, tr, bl, br + + wrefresh(local_win); + return local_win; +} + int print_status(char* str, WINDOW* window) { wattrset(window, COLOR_PAIR(7)); - return mvwprintw(window, 0, 1, str); + return mvwprintw(window, 1, 1, str); } static void finish(int sig) { diff --git a/src/frontend.h b/src/frontend.h index 4c9e956..be19176 100644 --- a/src/frontend.h +++ b/src/frontend.h @@ -2,6 +2,8 @@ static void finish(int sig); static void setup_colors(); +WINDOW *create_canvas_win(); +WINDOW *create_status_win(); int print_status(char* str, WINDOW* window); From e5014a7bde5f66df50e334d517b1fbe8c724fbbd Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Tue, 9 Apr 2019 18:03:46 -0400 Subject: [PATCH 5/7] make now compiles into .out files --- src/Makefile | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Makefile b/src/Makefile index 4d2e0c5..d1d95be 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,6 +13,13 @@ endif # link ncurses library # foo: LDFLAGS+=-lncurses +# Generate .out files for easier .gitignore. Based on the default make rule +# https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html#Catalogue-of-Rules +%.out: %.c + $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@ + +LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) + # **GNU Make only** run all test files (any file ending in _test.c) # turns each `foo_test.c` into `.run-foo_test.c` with "Text Functions" test: $(patsubst %.c, .run-%.c, $(wildcard *_test.c)) @@ -27,9 +34,9 @@ test: $(patsubst %.c, .run-%.c, $(wildcard *_test.c)) %_test: %_test.c minunit.h $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -frontend.out: frontend.c frontend.h - $(CC) frontend.c $(CFLAGS) $(LDFLAGS) -o frontend.out -frontend: LDLIBS +=-lncurses +# frontend.out: frontend.c frontend.h +# $(CC) frontend.c $(CFLAGS) $(LDLIBS) -o frontend.out +frontend.out: LDLIBS +=-lncurses clean: - -rm *.o *_test + -rm *.o *_test *.out From 33de676b858ca1bf9342c2b5faea26df0e34c8fb Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Tue, 9 Apr 2019 22:50:28 -0400 Subject: [PATCH 6/7] cursor moves after character input --- src/Makefile | 1 + src/frontend.c | 109 +++++++++++++++++++++++++++++-------------------- src/frontend.h | 1 + 3 files changed, 67 insertions(+), 44 deletions(-) diff --git a/src/Makefile b/src/Makefile index d1d95be..94e0565 100644 --- a/src/Makefile +++ b/src/Makefile @@ -36,6 +36,7 @@ test: $(patsubst %.c, .run-%.c, $(wildcard *_test.c)) # frontend.out: frontend.c frontend.h # $(CC) frontend.c $(CFLAGS) $(LDLIBS) -o frontend.out +# frontend.out: cursor.o frontend.out: LDLIBS +=-lncurses clean: diff --git a/src/frontend.c b/src/frontend.c index 91ac539..3fb09ea 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -2,7 +2,7 @@ #include #include "frontend.h" -int STATUS_HEIGHT = 1; +int STATUS_HEIGHT = 1; // not including borders // TODO: Factor out to different file? /* The Cursor struct helps with controls. @@ -13,50 +13,50 @@ typedef struct CURSOR { int y; } Cursor; -Cursor *cursor_init() { +Cursor *cursor_new() { Cursor *cursor = malloc(sizeof(Cursor)); cursor->x = 0; cursor->y = 0; return cursor; } -void move_up(Cursor* cursor) { +void cursor_move_up(Cursor* cursor) { if (cursor->y == 0) { return; } cursor->y--; } -void move_down(Cursor* cursor) { +void cursor_move_down(Cursor* cursor) { if (cursor->y == (LINES - 2)) { // Take box lines into account return; } cursor->y++; } -void move_left(Cursor* cursor) { +void cursor_move_left(Cursor* cursor) { if (cursor->x == 0) { return; } cursor->x--; } -void move_right(Cursor* cursor) { +void cursor_move_right(Cursor* cursor) { if (cursor->x == (COLS - 2)) { // Take box lines into account return; } cursor->x++; } -int x_to_canvas(Cursor* cursor) { +int cursor_x_to_canvas(Cursor* cursor) { return cursor->x + 1; } -int y_to_canvas(Cursor* cursor) { +int cursor_y_to_canvas(Cursor* cursor) { return cursor->y + 1; } -void free_cursor(Cursor* cursor) { +void cursor_free(Cursor* cursor) { free(cursor); } @@ -71,11 +71,28 @@ void free_cursor(Cursor* cursor) { * | | * | | * | | - * ___________________________________________ + * |________________________________________| * | | command window - * ___________________________________________ + * |________________________________________| * */ +void cursor_key_to_move(int arrow, Cursor *cursor) { + switch(arrow) { + case KEY_LEFT: + cursor_move_left(cursor); + break; + case KEY_RIGHT: + cursor_move_right(cursor); + break; + case KEY_UP: + cursor_move_up(cursor); + break; + case KEY_DOWN: + cursor_move_down(cursor); + break; + } +} + int main(int argc, char *argv[]) { /* initialize your non-curses data structures here */ @@ -92,54 +109,48 @@ int main(int argc, char *argv[]) { setup_colors(); } - WINDOW *canvas = create_canvas_win(); - WINDOW *status = create_status_win(); + WINDOW *canvas_win = create_canvas_win(); + WINDOW *status_win = create_status_win(); // Enable keyboard mapping - keypad(canvas, TRUE); - keypad(status, TRUE); + keypad(canvas_win, TRUE); + keypad(status_win, TRUE); - Cursor *cursor = cursor_init(); + Cursor *cursor = cursor_new(); char test_msg[] = "Test mode"; - print_status(test_msg, status); + print_status(test_msg, status_win); - wrefresh(status); + wrefresh(status_win); //// Main loop + int last_arrow_direction = KEY_RIGHT; int ch; - while ((ch = wgetch(canvas))) + while ((ch = wgetch(canvas_win))) { - switch(ch) { - case KEY_LEFT: - move_left(cursor); - break; - case KEY_RIGHT: - move_right(cursor); - break; - case KEY_UP: - move_up(cursor); - break; - case KEY_DOWN: - move_down(cursor); - break; - default: + if ((ch == KEY_LEFT) || (ch == KEY_RIGHT) || (ch == KEY_UP) || (ch == KEY_DOWN)) { + cursor_key_to_move(ch, cursor); + last_arrow_direction = ch; + } else { if (' ' <= ch && ch <= '~') { // check if ch is printable - mvwaddch(canvas, y_to_canvas(cursor), x_to_canvas(cursor), ch); + mvwaddch(canvas_win, cursor_y_to_canvas(cursor), cursor_x_to_canvas(cursor), ch); + cursor_key_to_move(last_arrow_direction, cursor); } else { - // Print non-print characters to bottom left in status bar - mvwaddch(status, 0, COLS-3, ch); + // Print non-print characters to bottom left in status_win bar + mvwaddch(status_win, 0, COLS-3, ch); } - } + } // Move UI cursor to the right place - wmove(canvas, y_to_canvas(cursor), x_to_canvas(cursor)); + wmove(canvas_win, cursor_y_to_canvas(cursor), cursor_x_to_canvas(cursor)); - wrefresh(status); - wrefresh(canvas); // Refresh Canvas last so it gets the cursor + wrefresh(status_win); + wrefresh(canvas_win); // Refresh Canvas last so it gets the cursor } // Cleanup - free_cursor(cursor); + cursor_free(cursor); + destroy_win(status_win); + destroy_win(canvas_win); finish(0); } @@ -175,8 +186,9 @@ WINDOW *create_newwin(int height, int width, int starty, int startx, int should_ WINDOW *create_canvas_win() { WINDOW *local_win; - - local_win = newwin(LINES - (STATUS_HEIGHT + 1), COLS, 0, 0); + + // + 1 due to bottom border + local_win = newwin(LINES - (STATUS_HEIGHT + 1), COLS, 0, 0); // height, width, starty, startx wborder(local_win, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE, // Sides: ls, rs, ts, bs, ACS_ULCORNER, ACS_URCORNER, ACS_LTEE, ACS_RTEE); // Corners: tl, tr, bl, br @@ -187,7 +199,7 @@ WINDOW *create_canvas_win() { WINDOW *create_status_win() { WINDOW *local_win; - + // + 2 due to horizontal borders local_win = newwin(STATUS_HEIGHT + 2, COLS, LINES - (STATUS_HEIGHT+2), 0); @@ -198,6 +210,15 @@ WINDOW *create_status_win() { return local_win; } +void destroy_win(WINDOW *local_win) +{ + // Clear borders explicitly + wborder(local_win, ' ', ' ', ' ',' ',' ',' ',' ',' '); + + wrefresh(local_win); + delwin(local_win); +} + int print_status(char* str, WINDOW* window) { wattrset(window, COLOR_PAIR(7)); return mvwprintw(window, 1, 1, str); diff --git a/src/frontend.h b/src/frontend.h index be19176..cb14e77 100644 --- a/src/frontend.h +++ b/src/frontend.h @@ -4,6 +4,7 @@ static void finish(int sig); static void setup_colors(); WINDOW *create_canvas_win(); WINDOW *create_status_win(); +void destroy_win(); int print_status(char* str, WINDOW* window); From 6774a9dc3b1bf80146288df84dca7ffbde20347a Mon Sep 17 00:00:00 2001 From: Matthew Beaudouin-Lafon Date: Tue, 9 Apr 2019 23:00:10 -0400 Subject: [PATCH 7/7] factored out cursor struct and co --- src/Makefile | 2 +- src/cursor.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cursor.h | 20 ++++++++++++++ src/frontend.c | 74 +------------------------------------------------- 4 files changed, 93 insertions(+), 74 deletions(-) create mode 100644 src/cursor.c create mode 100644 src/cursor.h diff --git a/src/Makefile b/src/Makefile index 94e0565..c4d7413 100644 --- a/src/Makefile +++ b/src/Makefile @@ -36,7 +36,7 @@ test: $(patsubst %.c, .run-%.c, $(wildcard *_test.c)) # frontend.out: frontend.c frontend.h # $(CC) frontend.c $(CFLAGS) $(LDLIBS) -o frontend.out -# frontend.out: cursor.o +frontend.out: cursor.o frontend.out: LDLIBS +=-lncurses clean: diff --git a/src/cursor.c b/src/cursor.c new file mode 100644 index 0000000..940fde7 --- /dev/null +++ b/src/cursor.c @@ -0,0 +1,71 @@ +#include +#include +#include "cursor.h" + +/* The Cursor struct helps with controls. + * It also maps the drawing area to the canvas nicely. + */ + +Cursor *cursor_new() { + Cursor *cursor = malloc(sizeof(Cursor)); + cursor->x = 0; + cursor->y = 0; + return cursor; +} + +void cursor_move_up(Cursor* cursor) { + if (cursor->y == 0) { + return; + } + cursor->y--; +} + +void cursor_move_down(Cursor* cursor) { + if (cursor->y == (LINES - 2)) { // Take box lines into account + return; + } + cursor->y++; +} + +void cursor_move_left(Cursor* cursor) { + if (cursor->x == 0) { + return; + } + cursor->x--; +} + +void cursor_move_right(Cursor* cursor) { + if (cursor->x == (COLS - 2)) { // Take box lines into account + return; + } + cursor->x++; +} + +int cursor_x_to_canvas(Cursor* cursor) { + return cursor->x + 1; +} + +int cursor_y_to_canvas(Cursor* cursor) { + return cursor->y + 1; +} + +void cursor_key_to_move(int arrow, Cursor *cursor) { + switch(arrow) { + case KEY_LEFT: + cursor_move_left(cursor); + break; + case KEY_RIGHT: + cursor_move_right(cursor); + break; + case KEY_UP: + cursor_move_up(cursor); + break; + case KEY_DOWN: + cursor_move_down(cursor); + break; + } +} + +void cursor_free(Cursor* cursor) { + free(cursor); +} diff --git a/src/cursor.h b/src/cursor.h new file mode 100644 index 0000000..ced3a60 --- /dev/null +++ b/src/cursor.h @@ -0,0 +1,20 @@ +/* The Cursor struct helps with controls. + * It also maps the drawing area to the canvas nicely. + */ + +typedef struct CURSOR { + int x; + int y; +} Cursor; + +Cursor *cursor_new(); +void cursor_free(Cursor* cursor); + +void cursor_move_up(Cursor* cursor); +void cursor_move_down(Cursor* cursor); +void cursor_move_left(Cursor* cursor); +void cursor_move_right(Cursor* cursor); + +int cursor_x_to_canvas(Cursor* cursor); +int cursor_y_to_canvas(Cursor* cursor); +void cursor_key_to_move(int arrow, Cursor *cursor); diff --git a/src/frontend.c b/src/frontend.c index 3fb09ea..95142f3 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -1,65 +1,10 @@ #include #include #include "frontend.h" +#include "cursor.h" int STATUS_HEIGHT = 1; // not including borders -// TODO: Factor out to different file? -/* The Cursor struct helps with controls. - * It also maps the drawing area to the canvas nicely. - */ -typedef struct CURSOR { - int x; - int y; -} Cursor; - -Cursor *cursor_new() { - Cursor *cursor = malloc(sizeof(Cursor)); - cursor->x = 0; - cursor->y = 0; - return cursor; -} - -void cursor_move_up(Cursor* cursor) { - if (cursor->y == 0) { - return; - } - cursor->y--; -} - -void cursor_move_down(Cursor* cursor) { - if (cursor->y == (LINES - 2)) { // Take box lines into account - return; - } - cursor->y++; -} - -void cursor_move_left(Cursor* cursor) { - if (cursor->x == 0) { - return; - } - cursor->x--; -} - -void cursor_move_right(Cursor* cursor) { - if (cursor->x == (COLS - 2)) { // Take box lines into account - return; - } - cursor->x++; -} - -int cursor_x_to_canvas(Cursor* cursor) { - return cursor->x + 1; -} - -int cursor_y_to_canvas(Cursor* cursor) { - return cursor->y + 1; -} - -void cursor_free(Cursor* cursor) { - free(cursor); -} - /* Layout * ___________________________________________ * | 0 -- X, COLS | canvas window @@ -76,23 +21,6 @@ void cursor_free(Cursor* cursor) { * |________________________________________| * */ -void cursor_key_to_move(int arrow, Cursor *cursor) { - switch(arrow) { - case KEY_LEFT: - cursor_move_left(cursor); - break; - case KEY_RIGHT: - cursor_move_right(cursor); - break; - case KEY_UP: - cursor_move_up(cursor); - break; - case KEY_DOWN: - cursor_move_down(cursor); - break; - } -} - int main(int argc, char *argv[]) { /* initialize your non-curses data structures here */