From 16afe4cdfd64f582e08ebdf888e72e1d8cb91c73 Mon Sep 17 00:00:00 2001 From: jarbus Date: Tue, 27 Jul 2021 15:45:01 -0400 Subject: [PATCH 01/18] better free code --- dtree.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/dtree.c b/dtree.c index 0ea2d58..7484b86 100644 --- a/dtree.c +++ b/dtree.c @@ -521,43 +521,47 @@ void populateHintText(Node* node){ logPrint("Populate start\n"); calculateNeighbors(GRAPH.root, GRAPH.selected); clearHintText(); + logPrint("HintTextCleared\n"); HINT_NODES = initArray(10); if(LEFT_NEIGHBOR) insertArray(HINT_NODES, LEFT_NEIGHBOR); if(RIGHT_NEIGHBOR) insertArray(HINT_NODES, RIGHT_NEIGHBOR); populateHintNodes(GRAPH.root); - logPrint("Cleared\n"); - logPrint("%p: %s\n",node->p->hint_text, node->p->hint_text); + logPrint("Hint Nodes Populated\n"); char** queue = calloc(8192, sizeof(char*)); + logPrint("calloc 1 succeeded\n"); char* prefix = calloc(HINT_BUFFER.size+1, sizeof(char)); + logPrint("calloc 2 succeeded\n"); int front = 0, back=0, done=0; while ( !done ){ + logPrint("in loop\n"); logPrint("Iterating while loop, back: %d, front: %d\n", back, front); for (int i = 0; i < strlen(HINT_CHARS); ++i) { // blacklist hard-coded hints if (HINT_CHARS[i] == 'k' || HINT_CHARS[i] == 'h' || HINT_CHARS[i] == 'l') continue; + logPrint("for looping %p\n", queue); + logPrint("for looping %p\n", queue[back]); queue[back] = calloc(HINT_BUFFER.size+1, sizeof(char)); + logPrint("this copy\n"); strcpy(queue[back], prefix); + logPrint("that copy\n"); queue[back][strlen(prefix)] = HINT_CHARS[i]; + logPrint("queue logic done\n"); if ( back - front == HINT_NODES->num){ done = 1; + logPrint("breaking\n"); break; } back++; } prefix = queue[front++]; } - for (int i = 0; i < front; ++i) { - free(queue[i]); - } - for (int i = 0; i < HINT_NODES->num; i++) { + for (int i = 0; i < HINT_NODES->num; i++) strcpy(HINT_NODES->array[i]->hint_text, queue[front + i]); - free(queue[front + i]); - } - for (int i = front + HINT_NODES->num; i < back; ++i) { + + for (int i = 0; i < back; ++i) free(queue[i]); - } free(queue); // parent is 'k', left neighbor 'h', right neighbor 'l' @@ -596,6 +600,7 @@ void switchMode(enum Mode to){ // When a hint node is selected, this function is run void hintFunction(Node* node){ + printf("hintFunction()\n"); switch(MODE){ case Travel: GRAPH.selected = node; break; case Delete: removeNodeFromGraph(node); break; From 4b9f0fe14365221d7692f9395cefa64cccf6b27d Mon Sep 17 00:00:00 2001 From: jarbus Date: Tue, 27 Jul 2021 23:25:58 -0400 Subject: [PATCH 02/18] delete mode bugfix --- dtree.c | 68 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/dtree.c b/dtree.c index 7484b86..d7f53fe 100644 --- a/dtree.c +++ b/dtree.c @@ -113,6 +113,10 @@ Array* initArray(size_t initial_size) { } void insertArray(Array *a, void* element) { // a->num is the number of used entries, because a->array[a->num++] updates a->num only *after* the array has been accessed. + printf("fddfdf\n"); + printf("fddfdf %p\n", a->array); + printf("a->num %ld\n", a->num); + printf("a->num %ld a->size %ld \n", a->num, a->size); // Therefore a->num can go up to a->size if (a->num == a->size) { a->size *= 2; @@ -136,6 +140,7 @@ void removeFromArray(Array *a, Node* node){ a->num -= 1; } } + void* freeArray(Array *a) { free(a->array); a->array = NULL; @@ -189,7 +194,7 @@ void deleteNode(Node* node){ logPrint("Freeing buffer\n"); free(node->text.buf); logPrint("Freeing hint_text\n"); - free(node->hint_text); + /* free(node->hint_text); */ free(node); logPrint("Deleted node %p\n", node); } @@ -233,6 +238,7 @@ static Buffer HINT_BUFFER = {NULL, 0, HINT_BUFFER_MAX_SIZE}; static Buffer FILENAME_BUFFER = {NULL, 0, FILENAME_BUFFER_MAX_SIZE}; static TTF_Font* FONT; // Global Font object static Array* HINT_NODES; // array of all nodes to be hinted to +static char** HINT_TEXT_QUEUE; static Buffer* CURRENT_BUFFER; // buffer to store current hint progress static Node* CUT = NULL; static bool TOGGLE_MODE = false; @@ -481,9 +487,8 @@ void calculateNeighbors(Node* root, Node* selected) { void clearHintText() { logPrint("clearHintText()\n"); // return if already freed - if (HINT_NODES == NULL || HINT_NODES->array == NULL){ - return; - } + logPrint("Hint nodes %p", HINT_NODES); + logPrint("Hint nodes array %p", HINT_NODES->array); logPrint("Hint nodes %p, num %ld\n", HINT_NODES->array, HINT_NODES->num); // Clear all hint text in each hint node for (int i = 0; i < HINT_NODES->num; ++i) { @@ -495,7 +500,9 @@ void clearHintText() { } // Clear hint node array logPrint("Freeing HINT_NODES\n"); - HINT_NODES = freeArray ( HINT_NODES ); + /* HINT_NODES = freeArray ( HINT_NODES ); */ + HINT_NODES->num = 0; + logPrint("HINT_NODES: %p\n", HINT_NODES); logPrint("End clearHintText()\n"); } @@ -522,32 +529,22 @@ void populateHintText(Node* node){ calculateNeighbors(GRAPH.root, GRAPH.selected); clearHintText(); logPrint("HintTextCleared\n"); - HINT_NODES = initArray(10); - if(LEFT_NEIGHBOR) insertArray(HINT_NODES, LEFT_NEIGHBOR); + if(LEFT_NEIGHBOR) insertArray(HINT_NODES, LEFT_NEIGHBOR); if(RIGHT_NEIGHBOR) insertArray(HINT_NODES, RIGHT_NEIGHBOR); + logPrint("HintTextCleared\n"); populateHintNodes(GRAPH.root); logPrint("Hint Nodes Populated\n"); - char** queue = calloc(8192, sizeof(char*)); - logPrint("calloc 1 succeeded\n"); - char* prefix = calloc(HINT_BUFFER.size+1, sizeof(char)); - logPrint("calloc 2 succeeded\n"); + char* prefix = ""; int front = 0, back=0, done=0; while ( !done ){ - logPrint("in loop\n"); - logPrint("Iterating while loop, back: %d, front: %d\n", back, front); for (int i = 0; i < strlen(HINT_CHARS); ++i) { // blacklist hard-coded hints if (HINT_CHARS[i] == 'k' || HINT_CHARS[i] == 'h' || HINT_CHARS[i] == 'l') continue; - logPrint("for looping %p\n", queue); - logPrint("for looping %p\n", queue[back]); - queue[back] = calloc(HINT_BUFFER.size+1, sizeof(char)); - logPrint("this copy\n"); - strcpy(queue[back], prefix); - logPrint("that copy\n"); - queue[back][strlen(prefix)] = HINT_CHARS[i]; - logPrint("queue logic done\n"); + for (int i = 0; i < HINT_BUFFER.size+1; ++i) HINT_TEXT_QUEUE[back][i] = '\0'; + strcpy(HINT_TEXT_QUEUE[back], prefix); + HINT_TEXT_QUEUE[back][strlen(prefix)] = HINT_CHARS[i]; if ( back - front == HINT_NODES->num){ done = 1; logPrint("breaking\n"); @@ -555,14 +552,10 @@ void populateHintText(Node* node){ } back++; } - prefix = queue[front++]; + prefix = HINT_TEXT_QUEUE[front++]; } for (int i = 0; i < HINT_NODES->num; i++) - strcpy(HINT_NODES->array[i]->hint_text, queue[front + i]); - - for (int i = 0; i < back; ++i) - free(queue[i]); - free(queue); + strcpy(HINT_NODES->array[i]->hint_text, HINT_TEXT_QUEUE[front + i]); // parent is 'k', left neighbor 'h', right neighbor 'l' strcpy(node->p->hint_text,"k"); @@ -584,7 +577,7 @@ void activateHints(){ void switchMode(enum Mode to){ if ( isHintMode(MODE) ){ - HINT_NODES = freeArray (HINT_NODES); + HINT_NODES->num = 0; clearBuffer(&HINT_BUFFER); } switch ( to ){ @@ -833,6 +826,7 @@ void centerOnSelected(Node* node, int selected_x, int selected_y) { // recomputes the coordinates of the nodes (i.e. populates pos field) void calculatePositions(Node* root, Node* selected){ + logPrint("calculatingPositions...\n"); int* y_levels = calloc(1+getDepth(root), sizeof(int)); logPrint("Calculating offsets...\n"); @@ -888,6 +882,7 @@ void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool SDL_RenderCopy(APP.renderer, texture_message, NULL, &message_rect); SDL_FreeSurface(surface_message); SDL_DestroyTexture(texture_message); + logPrint("Rendered\n"); } void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int offset, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ @@ -977,14 +972,18 @@ void drawNode(Node* node) { /* re-computes graph and draws everything onto renderer */ void prepareScene() { + logPrint("start prepareScene()\n"); SDL_SetRenderDrawColor(APP.renderer, BACKGROUND_COLOR[0], BACKGROUND_COLOR[1], BACKGROUND_COLOR[2], BACKGROUND_COLOR[3]); /* Background color */ SDL_RenderClear(APP.renderer); + logPrint("Rendered\n"); // recompute the coordinates of each node in the tree calculatePositions(GRAPH.root, GRAPH.selected); + logPrint("calculatePositions\n"); // Draw Graph drawNode(GRAPH.root); + logPrint("drawNode\n"); // Draw filename Point filename_pos; @@ -1022,6 +1021,8 @@ void presentScene() { void initSDL() { HINT_NODES = initArray(10); + logPrint("%p\n", HINT_NODES->array); + logPrint("%ld\n", HINT_NODES->num); int renderer_flags, window_flags; renderer_flags = SDL_RENDERER_ACCELERATED; window_flags = SDL_WINDOW_RESIZABLE; @@ -1074,6 +1075,11 @@ int main(int argc, char *argv[]) { strcpy(FILENAME_BUFFER.buf, "unnamed.txt"); + HINT_TEXT_QUEUE = calloc(8192, sizeof(char*)); + for (int i = 0; i < 8192; ++i) + HINT_TEXT_QUEUE[i] = calloc(HINT_BUFFER.size + 1, sizeof(char)); + + FILENAME_BUFFER.len = strlen(FILENAME_BUFFER.buf); HINT_BUFFER.buf = calloc(HINT_BUFFER.size + 1, sizeof(char)); @@ -1103,6 +1109,12 @@ int main(int argc, char *argv[]) { SDL_Delay(0); } + + for (int i = 0; i < 8192; ++i) + free ( HINT_TEXT_QUEUE[i] ); + free( HINT_TEXT_QUEUE ); + HINT_NODES = freeArray ( HINT_NODES ); + if (HINT_BUFFER.buf) free(HINT_BUFFER.buf); free(FILENAME_BUFFER.buf); /* delete nodes recursively, starting from root */ From 3fb2c0377483d4fa68171cd3d2b524845383a5a3 Mon Sep 17 00:00:00 2001 From: jarbus Date: Mon, 26 Jul 2021 15:21:44 -0400 Subject: [PATCH 03/18] fix mkj edge case --- dtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtree.c b/dtree.c index d7f53fe..f9f1892 100644 --- a/dtree.c +++ b/dtree.c @@ -600,7 +600,7 @@ void hintFunction(Node* node){ case Cut: CUT = node; switchMode(Paste); break; case MakeChild: makeChild(node); activateHints(); break; case Paste: - if ( !CUT ) break; + if ( !CUT || isInSubtree(CUT, node) ) break; removeFromArray(CUT->p->children, CUT); insertArray(node->children, CUT); CUT->p = node; From 781f0d4c5a00d62e8e444e07e27fdaa9a4b3f35d Mon Sep 17 00:00:00 2001 From: jarbus Date: Sun, 25 Jul 2021 21:28:21 -0400 Subject: [PATCH 04/18] hardcode j fix --- dtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtree.c b/dtree.c index f9f1892..951489f 100644 --- a/dtree.c +++ b/dtree.c @@ -36,7 +36,7 @@ static const int RADIUS = 50; static const int THICKNESS = 5; static const int FONT_SIZE = 40; static const char* FONT_NAME = "./assets/SourceCodePro-Regular.otf"; // Default Font name -static const char* HINT_CHARS = "adfghjkl;\0"; // characters to use for hints +static const char* HINT_CHARS = "adfghkl;\0"; // characters to use for hints // ENUMS AND DATA STRUCTURES From 64a61de176d0681f9e0faaa913c3c833a0794728 Mon Sep 17 00:00:00 2001 From: jarbus Date: Sun, 25 Jul 2021 06:32:57 -0400 Subject: [PATCH 05/18] Added graph zooming with -/= --- dtree.c | 220 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 155 insertions(+), 65 deletions(-) diff --git a/dtree.c b/dtree.c index 951489f..64d74fc 100644 --- a/dtree.c +++ b/dtree.c @@ -25,16 +25,18 @@ static const int UNSELECTED_COLOR[4] = {0, 55, 0, 0}; static const int CUT_COLOR[4] = {0, 0, 220, 0}; static const int EDGE_COLOR[4] = {220, 220, 220, 0}; static const int BACKGROUND_COLOR[4] = {15, 15, 15, 255}; -static const int TEXTBOX_WIDTH_SCALE = 25; // width of char -static const int TEXTBOX_HEIGHT = 50; // height of char +static int TEXTBOX_WIDTH_SCALE = 25; // width of char +static int TEXTBOX_HEIGHT = 50; // height of char +static double UI_SCALE = 1.0; +static double GRAPH_SCALE = 1.0; static const int FILENAME_BUFFER_MAX_SIZE = 64; static const int HINT_BUFFER_MAX_SIZE = 3; static const int MAX_TEXT_LEN = 128; // Max Num of chars in a node -static const int NUM_CHARS_B4_WRAP = 20; +static int NUM_CHARS_B4_WRAP = 20; // radius and thickness of node box static const int RADIUS = 50; static const int THICKNESS = 5; -static const int FONT_SIZE = 40; +static int FONT_SIZE = 40; static const char* FONT_NAME = "./assets/SourceCodePro-Regular.otf"; // Default Font name static const char* HINT_CHARS = "adfghkl;\0"; // characters to use for hints @@ -286,6 +288,8 @@ void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int offset, Uint8 r, Uint8 g, Uint8 b, Uint8 a); void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, Uint8 r, Uint8 g, Uint8 b, Uint8 a); void drawNode(Node* node); +char** getLines(char* message, int wrap); +char* getEndOfLine(char* line_start, int wrap); void prepareScene(); void presentScene(); // INIT @@ -312,27 +316,33 @@ void removeNodeFromGraph(Node* node){ int min(int a, int b){ if (a < b ) return a; else return b; } int max(int a, int b){ if (a > b ) return a; else return b; } -// return graphical width of text (with or without text wrapping) int getWidth (char* message, bool wrap){ - int ret; - if ( wrap ){ - for (int i = 0; i < strlen(message); ++i) { - if ( i > 0 && message[i-1] == '\n' ){ - return NUM_CHARS_B4_WRAP * TEXTBOX_WIDTH_SCALE; - } - } - ret = min( strlen(message), NUM_CHARS_B4_WRAP) * TEXTBOX_WIDTH_SCALE; + int cur_line = 0; + char* tok = message; + + int max_width = 0; + while ( tok ) { + char* line_end = getEndOfLine(tok, wrap); + logPrint("back in loop\n"); + if ( !line_end ){logPrint("breaking\n"); break;} + int line_len = ( line_end - tok ); + printf("line len %d\n", line_len); + max_width = max(line_len, max_width); + // copy all chars up until line_end + tok = line_end; + if ( *line_end == ' ' ) tok = line_end+1; + cur_line++; } - else - ret = strlen(message) * TEXTBOX_WIDTH_SCALE; - return ret; + return max_width * TEXTBOX_WIDTH_SCALE; } + + // return graphical height of text (with or without text wrapping) int getHeight (char* message, bool wrap){ if ( wrap ){ int num_lines=1, chars_since_line_start=0, chars_since_last_space=0; for (int i = 0; i < strlen(message); ++i) { - if ( chars_since_line_start >= NUM_CHARS_B4_WRAP && message[i] != ' ' && message[i] != '\n' ) { + if ( chars_since_line_start >= NUM_CHARS_B4_WRAP && message[i] != ' ' && message[i] != '\n' && !(i == strlen(message) - 1) ) { chars_since_line_start = chars_since_last_space -1; num_lines++; } @@ -353,6 +363,59 @@ int getHeight (char* message, bool wrap){ } +char* getEndOfLine(char* line_start, int wrap){ + if ( !*line_start ) return NULL; + logPrint("getEndOfLine()\n"); + char* last_space = line_start; + char* cur_char = line_start; + int num_chars = 0; + while ( *cur_char ){ + /* return NULL at end of string */ + if ( *cur_char == '\0' ) return cur_char; + if ( *cur_char == '\n' ) return cur_char + 1; + /* if we are past a line length, return the last new space */ + if ( wrap ){ + if ( *cur_char == ' ' ) last_space = cur_char; + if ( num_chars > NUM_CHARS_B4_WRAP && last_space != line_start) return last_space; + } + + cur_char ++; + num_chars++; + } + return cur_char; +} + + +/* string -> strings representing the wrapped string */ +char** getLines(char* message, int wrap){ + + logPrint("getLines()\n"); + int height = getHeight(message, wrap); + int cur_line = 0; + char** lines = calloc(height/TEXTBOX_HEIGHT + 1, sizeof(char*)); + char* tok = message; + char* line_end; + + while ( tok ) { + line_end = getEndOfLine(tok, wrap); + if ( !line_end ) break; + int line_len = ( line_end - tok ); + logPrint("line len: %p - %p=%d\n", line_end, tok, line_len); + lines[cur_line] = calloc(line_len + 1, sizeof(char)); + // copy all chars up until line_end + for (int i = 0; i < line_len; i++) { + if ( i != line_len - 1 || *(tok+i) != '\n') + *(lines[cur_line]+i) = *(tok+i); + } + tok = line_end; + if ( *line_end == ' ' ) tok = line_end+1; + cur_line++; + } + logPrint("returning after making %d lines\n", cur_line); + lines[cur_line] = NULL; + return lines; +} + // READ/WRITE // We replace user-entered \n with | for the file format @@ -660,14 +723,19 @@ void handleTextInput(SDL_Event *event){ } void doKeyDown(SDL_KeyboardEvent *event) { - if ( isEditMode(MODE) ){ - switch(event->keysym.sym) { - case SDLK_BACKSPACE: - if ( CURRENT_BUFFER && CURRENT_BUFFER->len > 0) - CURRENT_BUFFER->buf[--CURRENT_BUFFER->len] = '\0'; - } + switch(event->keysym.sym) { + case SDLK_BACKSPACE: + if ( isEditMode(MODE) && CURRENT_BUFFER && CURRENT_BUFFER->len > 0) + CURRENT_BUFFER->buf[--CURRENT_BUFFER->len] = '\0'; + return; + case SDLK_MINUS: + GRAPH_SCALE *= 0.9; + return; + case SDLK_EQUALS: + GRAPH_SCALE *= 1.1; + return; + return; } - return; } void doKeyUp(SDL_KeyboardEvent *event) { @@ -680,6 +748,12 @@ void doKeyUp(SDL_KeyboardEvent *event) { if (MODE == Travel) CUT = NULL; // clear cut node on a double escape switchMode(Travel); return; + case SDLK_MINUS: + GRAPH_SCALE *= (9./10.); + return; + case SDLK_EQUALS: + GRAPH_SCALE *= (10./9.); + return; } // mode-specific key-bindings @@ -751,7 +825,7 @@ int getDepth(Node* node) { void calculateOffsets(Node* node) { logPrint("Calculating offsets for %p...\n", node); - int text_pixel_length = getWidth(node->text.buf, true); + int text_pixel_length = getWidth(node->text.buf, true) * GRAPH_SCALE; node -> x_offset = 0; node -> rightmost = text_pixel_length/2; node -> leftmost = -text_pixel_length/2; @@ -792,7 +866,7 @@ void calculateOffsets(Node* node) { } void calculateMaxHeights(Node* node, int level, int* max_heights) { - int node_height = getHeight(node->text.buf, true)+RADIUS; + int node_height = getHeight(node->text.buf, true) * GRAPH_SCALE +RADIUS; if (node_height > max_heights[level]) { max_heights[level] = node_height; } @@ -857,32 +931,35 @@ void recursivelyPrintPositions(Node* node, int level){ // RENDERING - void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool wrap){ if (!message) return; - // create surface from string - SDL_Surface* surface_message; - if ( wrap ) - surface_message = TTF_RenderText_Blended_Wrapped(FONT, message, color, NUM_CHARS_B4_WRAP * TEXTBOX_WIDTH_SCALE * scale); - else - surface_message = TTF_RenderText_Solid(FONT, message, color); - - // now you can convert it into a texture - SDL_Texture* texture_message = SDL_CreateTextureFromSurface(APP.renderer, surface_message); - - SDL_Rect message_rect; - message_rect.x = pos.x; - message_rect.y = pos.y; - message_rect.w = getWidth(message, wrap) * scale; - message_rect.h = getHeight(message, wrap) * scale; - - SDL_SetRenderDrawColor(APP.renderer, BACKGROUND_COLOR[0], BACKGROUND_COLOR[1], BACKGROUND_COLOR[2], BACKGROUND_COLOR[3]); - SDL_RenderFillRect(APP.renderer, &message_rect); - logPrint("Rendering %s %d %d\n", message, message_rect.w, message_rect.h); - SDL_RenderCopy(APP.renderer, texture_message, NULL, &message_rect); - SDL_FreeSurface(surface_message); - SDL_DestroyTexture(texture_message); - logPrint("Rendered\n"); + + char** lines = getLines(message, wrap); + int cur_line = 0; + while(lines[cur_line]) { + // create surface from string + SDL_Surface* surface_message; + surface_message = TTF_RenderText_Solid(FONT, lines[cur_line], color); + + // now you can convert it into a texture + SDL_Texture* texture_message = SDL_CreateTextureFromSurface(APP.renderer, surface_message); + + SDL_Rect message_rect; + message_rect.x = pos.x; + message_rect.y = pos.y + (TEXTBOX_HEIGHT * cur_line * GRAPH_SCALE); + message_rect.w = strlen(lines[cur_line]) * TEXTBOX_WIDTH_SCALE * scale; + message_rect.h = TEXTBOX_HEIGHT * scale; + + SDL_SetRenderDrawColor(APP.renderer, BACKGROUND_COLOR[0], BACKGROUND_COLOR[1], BACKGROUND_COLOR[2], BACKGROUND_COLOR[3]); + SDL_RenderFillRect(APP.renderer, &message_rect); + logPrint("Rendering %s %d %d\n", message, message_rect.w, message_rect.h); + SDL_RenderCopy(APP.renderer, texture_message, NULL, &message_rect); + SDL_FreeSurface(surface_message); + SDL_DestroyTexture(texture_message); + free(lines[cur_line]); + cur_line++; + } + free(lines); } void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int offset, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ @@ -918,8 +995,8 @@ void drawNode(Node* node) { int y = node->pos.y; logPrint("Children pointer: %p, num: %lu\n", node->children, node->children->num); /* draw red ring for unselected nodes, green for selected */ - int width = getWidth(node->text.buf, 1); - int height = getHeight(node->text.buf, 1); + int width = getWidth(node->text.buf, 1) * GRAPH_SCALE; + int height = getHeight(node->text.buf, 1) * GRAPH_SCALE; if ( is_visible(node) ){ if (node == CUT) drawBorder(APP.renderer, x, y, width, height, THICKNESS, CUT_COLOR[0], CUT_COLOR[1], CUT_COLOR[2], CUT_COLOR[3]); @@ -932,7 +1009,7 @@ void drawNode(Node* node) { /* draw edges between parent and child nodes */ if (node != GRAPH.root && (is_visible(node->p) || is_visible(node)) ){ SDL_SetRenderDrawColor(APP.renderer, EDGE_COLOR[0], EDGE_COLOR[1], EDGE_COLOR[2], EDGE_COLOR[3]); - SDL_RenderDrawLine(APP.renderer, x, y - (height/2), node->p->pos.x, node->p->pos.y + (getHeight(node->p->text.buf, 1) / 2)); + SDL_RenderDrawLine(APP.renderer, x, y - (height*GRAPH_SCALE/2), node->p->pos.x, node->p->pos.y + (getHeight(node->p->text.buf, 1) * GRAPH_SCALE / 2)); } if ( is_visible(node) ){ @@ -941,7 +1018,20 @@ void drawNode(Node* node) { message_pos.y = y - (height / 2); /* render node text */ - renderMessage(node->text.buf, message_pos, 1.0, EDIT_COLOR, 1); + renderMessage(node->text.buf, message_pos, GRAPH_SCALE, EDIT_COLOR, 1); + char** lines = getLines(node->text.buf, 1); + int cur_line = 0; + char* line = lines[cur_line]; + while ( line ){ + printf("call loop\n"); + printf("%s\n",line); + printf("freeing %p\n", line); + if ( *line ) free (line); + line = lines[++cur_line]; + printf("call loop done\n"); + + } + free ( lines ); /* render hint text */ if ( isHintMode(MODE) && strlen(node->hint_text) > 0 ){ // dont render hint text that doesn't match hint buffer @@ -954,11 +1044,11 @@ void drawNode(Node* node) { } } } - // position char in center of node + // position char in top left of node if ( render_hint ) { - message_pos.x = x - (int)(width / 2) - THICKNESS; - message_pos.y = y - (int)(height / 2) - THICKNESS - RADIUS; - renderMessage(node->hint_text, message_pos, 0.75, HINT_COLOR, 0); + message_pos.x = x - (int)(width/ 2) - THICKNESS; + message_pos.y = y - (int)(height/ 2) - THICKNESS - (RADIUS * GRAPH_SCALE); + renderMessage(node->hint_text, message_pos, 0.75 * GRAPH_SCALE, HINT_COLOR, 0); } } } @@ -988,24 +1078,24 @@ void prepareScene() { // Draw filename Point filename_pos; filename_pos.x = (int) ((0.0) * APP.window_size.x); - filename_pos.y = (int) ((1.0) * APP.window_size.y - TEXTBOX_HEIGHT); - renderMessage(FILENAME_BUFFER.buf, filename_pos, 1.0, EDIT_COLOR, 0); + filename_pos.y = (int) ((1.0) * APP.window_size.y - (TEXTBOX_HEIGHT * UI_SCALE)); + renderMessage(FILENAME_BUFFER.buf, filename_pos, UI_SCALE, EDIT_COLOR, 0); // Draw mode Point mode_text_pos; mode_text_pos.x = (int) ((0.0) * APP.window_size.x); mode_text_pos.y = (int) ((0.0) * APP.window_size.y); - renderMessage(getModeName(MODE), mode_text_pos, 1.0, EDIT_COLOR, 0); + renderMessage(getModeName(MODE), mode_text_pos, UI_SCALE, EDIT_COLOR, 0); //Draw hint buffer Point hint_buf_pos; - hint_buf_pos.x = (int) ((1.0 * APP.window_size.x) - (HINT_BUFFER.len * TEXTBOX_WIDTH_SCALE)); - hint_buf_pos.y = (int) ((1.0) * APP.window_size.y - TEXTBOX_HEIGHT); - renderMessage(HINT_BUFFER.buf, hint_buf_pos, 1.0, HINT_COLOR, 0); + hint_buf_pos.x = (int) ((1.0 * APP.window_size.x) - (HINT_BUFFER.len * TEXTBOX_WIDTH_SCALE * UI_SCALE)); + hint_buf_pos.y = (int) ((1.0) * APP.window_size.y - (TEXTBOX_HEIGHT * UI_SCALE)); + renderMessage(HINT_BUFFER.buf, hint_buf_pos, UI_SCALE, HINT_COLOR, 0); if ( TOGGLE_MODE ){ Point toggle_indicator_pos; - toggle_indicator_pos.x = (int) ((1.0 * APP.window_size.x) - (strlen(TOGGLE_INDICATOR) * TEXTBOX_WIDTH_SCALE)); + toggle_indicator_pos.x = (int) ((1.0 * APP.window_size.x) - (strlen(TOGGLE_INDICATOR) * TEXTBOX_WIDTH_SCALE * UI_SCALE)); toggle_indicator_pos.y = (int) ((0.0) * APP.window_size.y); renderMessage(TOGGLE_INDICATOR, toggle_indicator_pos, 1.0, EDIT_COLOR, 0); } From 111215fdfb3fcd14abdfe1bf4eb9a434ee99ba1f Mon Sep 17 00:00:00 2001 From: jarbus Date: Sun, 25 Jul 2021 15:33:17 -0400 Subject: [PATCH 06/18] Added a cursor for current text buffer --- dtree.c | 154 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 105 insertions(+), 49 deletions(-) diff --git a/dtree.c b/dtree.c index 64d74fc..a684c95 100644 --- a/dtree.c +++ b/dtree.c @@ -115,10 +115,6 @@ Array* initArray(size_t initial_size) { } void insertArray(Array *a, void* element) { // a->num is the number of used entries, because a->array[a->num++] updates a->num only *after* the array has been accessed. - printf("fddfdf\n"); - printf("fddfdf %p\n", a->array); - printf("a->num %ld\n", a->num); - printf("a->num %ld a->size %ld \n", a->num, a->size); // Therefore a->num can go up to a->size if (a->num == a->size) { a->size *= 2; @@ -248,6 +244,7 @@ static char* TOGGLE_INDICATOR = "MODE PERSIST\0"; static Node* LEFT_NEIGHBOR = NULL; // left and right neighbors of the selected node static Node* RIGHT_NEIGHBOR = NULL; static int OFFSCREEN_PADDING = 500; +static int CURSOR_POSITION = 0; // GENERAL UTIL FUNCTIONS void removeNodeFromGraph(Node* node); @@ -255,6 +252,7 @@ int min(int a, int b); int max(int a, int b); int getWidth (char* message, bool wrap); int getHeight (char* message, bool wrap); +void deleteCharInBufferRelativeToCursor(int relative_position); // READ/WRITE void replaceChar(char* arr, char find, char replace); unsigned int countTabs(char* string); @@ -270,6 +268,7 @@ void populateHintText(Node* node); // EVENT HANDLING void activateHints(); void switchMode(enum Mode to); +void switchCurrentBuffer(Buffer* buffer); void hintFunction(Node* node); void handleTextInput(SDL_Event *event); void doKeyDown(SDL_KeyboardEvent *event); @@ -284,9 +283,9 @@ void centerOnSelected(Node* node, int selected_x, int selected_y); void calculatePositions(Node* root, Node* selected); void recursivelyPrintPositions(Node* node, int level); // RENDERING -void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool wrap); +void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool wrap, bool cursor); void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int offset, Uint8 r, Uint8 g, Uint8 b, Uint8 a); -void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, const int* color); void drawNode(Node* node); char** getLines(char* message, int wrap); char* getEndOfLine(char* line_start, int wrap); @@ -326,7 +325,6 @@ int getWidth (char* message, bool wrap){ logPrint("back in loop\n"); if ( !line_end ){logPrint("breaking\n"); break;} int line_len = ( line_end - tok ); - printf("line len %d\n", line_len); max_width = max(line_len, max_width); // copy all chars up until line_end tok = line_end; @@ -594,7 +592,6 @@ void populateHintText(Node* node){ logPrint("HintTextCleared\n"); if(LEFT_NEIGHBOR) insertArray(HINT_NODES, LEFT_NEIGHBOR); if(RIGHT_NEIGHBOR) insertArray(HINT_NODES, RIGHT_NEIGHBOR); - logPrint("HintTextCleared\n"); populateHintNodes(GRAPH.root); logPrint("Hint Nodes Populated\n"); char* prefix = ""; @@ -635,7 +632,12 @@ void populateHintText(Node* node){ void activateHints(){ populateHintText(GRAPH.selected); - CURRENT_BUFFER = &HINT_BUFFER; + switchCurrentBuffer(&HINT_BUFFER); +} + +void switchCurrentBuffer(Buffer* buffer){ + CURRENT_BUFFER = buffer; + CURSOR_POSITION = buffer->len - 1; } void switchMode(enum Mode to){ @@ -644,8 +646,8 @@ void switchMode(enum Mode to){ clearBuffer(&HINT_BUFFER); } switch ( to ){ - case Edit: CURRENT_BUFFER = &GRAPH.selected->text; break; - case FilenameEdit: CURRENT_BUFFER = &FILENAME_BUFFER; to = Edit; break; + case Edit: switchCurrentBuffer(&GRAPH.selected->text); break; + case FilenameEdit: switchCurrentBuffer(&FILENAME_BUFFER); to = Edit; break; case Travel: TOGGLE_MODE = false; break; default: break; } @@ -656,7 +658,7 @@ void switchMode(enum Mode to){ // When a hint node is selected, this function is run void hintFunction(Node* node){ - printf("hintFunction()\n"); + logPrint("hintFunction()\n"); switch(MODE){ case Travel: GRAPH.selected = node; break; case Delete: removeNodeFromGraph(node); break; @@ -677,6 +679,25 @@ void hintFunction(Node* node){ switchMode( Travel ); } +void insertCharIntoCurrentBuffer(char c){ + if ( !CURRENT_BUFFER || CURRENT_BUFFER->len < 0 || CURRENT_BUFFER->len >= CURRENT_BUFFER->size) return; + for (int i = CURRENT_BUFFER->len-1; i > CURSOR_POSITION; i--) { + CURRENT_BUFFER->buf[i+1] = CURRENT_BUFFER->buf[i]; + } + CURRENT_BUFFER->buf[++CURSOR_POSITION] = c; + CURRENT_BUFFER->len += 1; + +} +void deleteCharInBufferRelativeToCursor(int relative_position){ + // relative position allows us to use the same code for both backspace and delete + for (int i = CURSOR_POSITION + relative_position; i < CURRENT_BUFFER->len-1; i++) { + CURRENT_BUFFER->buf[i] = CURRENT_BUFFER->buf[i+1]; + } + CURRENT_BUFFER->buf[CURRENT_BUFFER->len-1] = '\0'; + CURSOR_POSITION -= 1 - relative_position; + CURRENT_BUFFER->len -= 1; +} + void handleTextInput(SDL_Event *event){ if ( CURRENT_BUFFER && CURRENT_BUFFER->len < CURRENT_BUFFER->size ){ logPrint("Adding text to current buffer...\n"); @@ -692,8 +713,8 @@ void handleTextInput(SDL_Event *event){ } } - if ( add_text && CURRENT_BUFFER->len < CURRENT_BUFFER->size) - CURRENT_BUFFER->buf[(CURRENT_BUFFER->len)++] = event->edit.text[0]; + // Add text to buffer + if ( add_text ) insertCharIntoCurrentBuffer(event->edit.text[0]); logPrint("Detected character: %c\n", event->edit.text[0]); logPrint("New CURRENT_BUFFER: len %d: %s\n", CURRENT_BUFFER->len, CURRENT_BUFFER->buf); } @@ -722,19 +743,52 @@ void handleTextInput(SDL_Event *event){ } } +void moveCursorLine(int relative_line){ + char** lines = getLines(GRAPH.selected->text.buf, 1); + + int len_so_far = 0; + for (int i = 0; lines[i]; i++) { + int col = CURSOR_POSITION - len_so_far; + // Move Up + if ( relative_line == -1 && i > 0 && CURSOR_POSITION >= len_so_far && CURSOR_POSITION < len_so_far + strlen(lines[i])){ + if ( col > strlen(lines[i-1]) ) { + CURSOR_POSITION -= col + 1 + 1; + } + else { + CURSOR_POSITION -= col + 1; // move to end of line - 1 + CURSOR_POSITION -= strlen(lines[i-1]) - col; //move to col'th idx of line i-1 + } + } + // Move Down + else if ( relative_line == 1 && lines[i+1] && CURSOR_POSITION > len_so_far && CURSOR_POSITION < len_so_far + strlen(lines[i])){ + if ( col > strlen(lines[i+1]) ) { + CURSOR_POSITION += strlen(lines[i]) - col + strlen(lines[i+1]); + } + else { + CURSOR_POSITION += strlen(lines[i]) + 1 - col; // move to end of line - 1 + CURSOR_POSITION += col; //move to col'th idx of line i-1 + } + break; + } + len_so_far += strlen(lines[i]) + 1; + } + for (int i = 0; lines[i]; i++) + free(lines[i]); + free(lines); + +} + void doKeyDown(SDL_KeyboardEvent *event) { switch(event->keysym.sym) { - case SDLK_BACKSPACE: - if ( isEditMode(MODE) && CURRENT_BUFFER && CURRENT_BUFFER->len > 0) - CURRENT_BUFFER->buf[--CURRENT_BUFFER->len] = '\0'; - return; - case SDLK_MINUS: - GRAPH_SCALE *= 0.9; - return; - case SDLK_EQUALS: - GRAPH_SCALE *= 1.1; - return; - return; + case SDLK_BACKSPACE: if ( isEditMode(MODE) ) deleteCharInBufferRelativeToCursor(0); return; + case SDLK_DELETE: if ( isEditMode(MODE) ) deleteCharInBufferRelativeToCursor(1); return; + case SDLK_MINUS: GRAPH_SCALE *= (9./10.); return; + case SDLK_EQUALS: GRAPH_SCALE *= (10./9.); return; + case SDLK_LEFT: CURSOR_POSITION = max(CURSOR_POSITION-1,-1); return; + case SDLK_RIGHT: CURSOR_POSITION = min(CURSOR_POSITION+1,CURRENT_BUFFER->len-1); return; + case SDLK_UP: moveCursorLine(-1); return; + case SDLK_DOWN: moveCursorLine(1); return; + } } @@ -748,12 +802,6 @@ void doKeyUp(SDL_KeyboardEvent *event) { if (MODE == Travel) CUT = NULL; // clear cut node on a double escape switchMode(Travel); return; - case SDLK_MINUS: - GRAPH_SCALE *= (9./10.); - return; - case SDLK_EQUALS: - GRAPH_SCALE *= (10./9.); - return; } // mode-specific key-bindings @@ -775,8 +823,7 @@ void doKeyUp(SDL_KeyboardEvent *event) { case Edit: switch(event->keysym.sym) { case SDLK_RETURN: - if ( CURRENT_BUFFER && CURRENT_BUFFER->len >= 0) - CURRENT_BUFFER->buf[CURRENT_BUFFER->len++] = '\n'; + insertCharIntoCurrentBuffer('\n'); return; } break; // end of Edit bindings @@ -931,12 +978,14 @@ void recursivelyPrintPositions(Node* node, int level){ // RENDERING -void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool wrap){ +void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool wrap, bool cursor){ if (!message) return; char** lines = getLines(message, wrap); int cur_line = 0; + int len_so_far = 0 ; while(lines[cur_line]) { + // create surface from string SDL_Surface* surface_message; surface_message = TTF_RenderText_Solid(FONT, lines[cur_line], color); @@ -954,10 +1003,21 @@ void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool SDL_RenderFillRect(APP.renderer, &message_rect); logPrint("Rendering %s %d %d\n", message, message_rect.w, message_rect.h); SDL_RenderCopy(APP.renderer, texture_message, NULL, &message_rect); + + if (cursor && len_so_far <= CURSOR_POSITION + 1 && CURSOR_POSITION < len_so_far + strlen(lines[cur_line]) ){ + + int cursor_offset = (CURSOR_POSITION + 1 - len_so_far) * TEXTBOX_WIDTH_SCALE * GRAPH_SCALE; + SDL_SetRenderDrawColor(APP.renderer, 255, 255, 255, 255); + SDL_RenderDrawLine(APP.renderer, message_rect.x + cursor_offset, message_rect.y, message_rect.x + cursor_offset, message_rect.y + (TEXTBOX_HEIGHT * GRAPH_SCALE)); + } + + SDL_FreeSurface(surface_message); SDL_DestroyTexture(texture_message); + len_so_far += strlen(lines[cur_line]) + 1; free(lines[cur_line]); cur_line++; + } free(lines); } @@ -972,9 +1032,9 @@ void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int SDL_RenderDrawRect(surface, &rect); } -void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ +void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, const int* color){ for (int i = 0; i < thickness; ++i) - drawBox(surface, n_cx , n_cy, len, height, i, r, g, b, a); + drawBox(surface, n_cx , n_cy, len, height, i, color[0], color[1], color[2], color[3]); } bool is_visible(Node* node){ @@ -999,11 +1059,11 @@ void drawNode(Node* node) { int height = getHeight(node->text.buf, 1) * GRAPH_SCALE; if ( is_visible(node) ){ if (node == CUT) - drawBorder(APP.renderer, x, y, width, height, THICKNESS, CUT_COLOR[0], CUT_COLOR[1], CUT_COLOR[2], CUT_COLOR[3]); + drawBorder(APP.renderer, x, y, width, height, THICKNESS, CUT_COLOR); else if (node == GRAPH.selected) - drawBorder(APP.renderer, x, y, width, height, THICKNESS, SELECTED_COLOR[0], SELECTED_COLOR[1], SELECTED_COLOR[2], SELECTED_COLOR[3]); + drawBorder(APP.renderer, x, y, width, height, THICKNESS, SELECTED_COLOR); else - drawBorder(APP.renderer, x, y, width, height, THICKNESS, UNSELECTED_COLOR[0], UNSELECTED_COLOR[1], UNSELECTED_COLOR[2], UNSELECTED_COLOR[3]); + drawBorder(APP.renderer, x, y, width, height, THICKNESS, UNSELECTED_COLOR); } /* draw edges between parent and child nodes */ @@ -1018,17 +1078,13 @@ void drawNode(Node* node) { message_pos.y = y - (height / 2); /* render node text */ - renderMessage(node->text.buf, message_pos, GRAPH_SCALE, EDIT_COLOR, 1); + renderMessage(node->text.buf, message_pos, GRAPH_SCALE, EDIT_COLOR, 1, &node->text == CURRENT_BUFFER); char** lines = getLines(node->text.buf, 1); int cur_line = 0; char* line = lines[cur_line]; while ( line ){ - printf("call loop\n"); - printf("%s\n",line); - printf("freeing %p\n", line); if ( *line ) free (line); line = lines[++cur_line]; - printf("call loop done\n"); } free ( lines ); @@ -1048,7 +1104,7 @@ void drawNode(Node* node) { if ( render_hint ) { message_pos.x = x - (int)(width/ 2) - THICKNESS; message_pos.y = y - (int)(height/ 2) - THICKNESS - (RADIUS * GRAPH_SCALE); - renderMessage(node->hint_text, message_pos, 0.75 * GRAPH_SCALE, HINT_COLOR, 0); + renderMessage(node->hint_text, message_pos, 0.75 * GRAPH_SCALE, HINT_COLOR, 0, 0); } } } @@ -1079,25 +1135,25 @@ void prepareScene() { Point filename_pos; filename_pos.x = (int) ((0.0) * APP.window_size.x); filename_pos.y = (int) ((1.0) * APP.window_size.y - (TEXTBOX_HEIGHT * UI_SCALE)); - renderMessage(FILENAME_BUFFER.buf, filename_pos, UI_SCALE, EDIT_COLOR, 0); + renderMessage(FILENAME_BUFFER.buf, filename_pos, UI_SCALE, EDIT_COLOR, 0, &FILENAME_BUFFER == CURRENT_BUFFER); // Draw mode Point mode_text_pos; mode_text_pos.x = (int) ((0.0) * APP.window_size.x); mode_text_pos.y = (int) ((0.0) * APP.window_size.y); - renderMessage(getModeName(MODE), mode_text_pos, UI_SCALE, EDIT_COLOR, 0); + renderMessage(getModeName(MODE), mode_text_pos, UI_SCALE, EDIT_COLOR, 0, 0); //Draw hint buffer Point hint_buf_pos; hint_buf_pos.x = (int) ((1.0 * APP.window_size.x) - (HINT_BUFFER.len * TEXTBOX_WIDTH_SCALE * UI_SCALE)); hint_buf_pos.y = (int) ((1.0) * APP.window_size.y - (TEXTBOX_HEIGHT * UI_SCALE)); - renderMessage(HINT_BUFFER.buf, hint_buf_pos, UI_SCALE, HINT_COLOR, 0); + renderMessage(HINT_BUFFER.buf, hint_buf_pos, UI_SCALE, HINT_COLOR, 0, 0); if ( TOGGLE_MODE ){ Point toggle_indicator_pos; toggle_indicator_pos.x = (int) ((1.0 * APP.window_size.x) - (strlen(TOGGLE_INDICATOR) * TEXTBOX_WIDTH_SCALE * UI_SCALE)); toggle_indicator_pos.y = (int) ((0.0) * APP.window_size.y); - renderMessage(TOGGLE_INDICATOR, toggle_indicator_pos, 1.0, EDIT_COLOR, 0); + renderMessage(TOGGLE_INDICATOR, toggle_indicator_pos, 1.0, EDIT_COLOR, 0, 0); } } From c5786f60d672b2e741ba1873a02ab7cbdd0e50e4 Mon Sep 17 00:00:00 2001 From: jarbus Date: Mon, 2 Aug 2021 16:56:08 -0400 Subject: [PATCH 07/18] fix for j --- dtree.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/dtree.c b/dtree.c index a684c95..0f27d28 100644 --- a/dtree.c +++ b/dtree.c @@ -38,7 +38,7 @@ static const int RADIUS = 50; static const int THICKNESS = 5; static int FONT_SIZE = 40; static const char* FONT_NAME = "./assets/SourceCodePro-Regular.otf"; // Default Font name -static const char* HINT_CHARS = "adfghkl;\0"; // characters to use for hints +static const char* HINT_CHARS = "adfghjkl;\0"; // characters to use for hints // ENUMS AND DATA STRUCTURES @@ -599,7 +599,7 @@ void populateHintText(Node* node){ while ( !done ){ for (int i = 0; i < strlen(HINT_CHARS); ++i) { // blacklist hard-coded hints - if (HINT_CHARS[i] == 'k' || HINT_CHARS[i] == 'h' || HINT_CHARS[i] == 'l') + if (HINT_CHARS[i] == 'k' || HINT_CHARS[i] == 'h' || HINT_CHARS[i] == 'l' || HINT_CHARS[i] == 'j') continue; for (int i = 0; i < HINT_BUFFER.size+1; ++i) HINT_TEXT_QUEUE[back][i] = '\0'; @@ -779,17 +779,20 @@ void moveCursorLine(int relative_line){ } void doKeyDown(SDL_KeyboardEvent *event) { - switch(event->keysym.sym) { - case SDLK_BACKSPACE: if ( isEditMode(MODE) ) deleteCharInBufferRelativeToCursor(0); return; - case SDLK_DELETE: if ( isEditMode(MODE) ) deleteCharInBufferRelativeToCursor(1); return; - case SDLK_MINUS: GRAPH_SCALE *= (9./10.); return; - case SDLK_EQUALS: GRAPH_SCALE *= (10./9.); return; - case SDLK_LEFT: CURSOR_POSITION = max(CURSOR_POSITION-1,-1); return; - case SDLK_RIGHT: CURSOR_POSITION = min(CURSOR_POSITION+1,CURRENT_BUFFER->len-1); return; - case SDLK_UP: moveCursorLine(-1); return; - case SDLK_DOWN: moveCursorLine(1); return; - - } + if ( isEditMode(MODE) ){ + switch(event->keysym.sym) { + case SDLK_BACKSPACE: deleteCharInBufferRelativeToCursor(0); return; + case SDLK_DELETE: deleteCharInBufferRelativeToCursor(1); return; + case SDLK_LEFT: CURSOR_POSITION = max(CURSOR_POSITION-1,-1); return; + case SDLK_RIGHT: CURSOR_POSITION = min(CURSOR_POSITION+1,CURRENT_BUFFER->len-1); return; + case SDLK_UP: moveCursorLine(-1); return; + case SDLK_DOWN: moveCursorLine(1); return; + } + } + switch(event->keysym.sym) { + case SDLK_MINUS: GRAPH_SCALE *= (9./10.); return; + case SDLK_EQUALS: GRAPH_SCALE *= (10./9.); return; + } } void doKeyUp(SDL_KeyboardEvent *event) { From b802d79c687d93d7ef279e2afb1022049f5afa94 Mon Sep 17 00:00:00 2001 From: jarbus Date: Mon, 2 Aug 2021 17:04:46 -0400 Subject: [PATCH 08/18] better color code --- dtree.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/dtree.c b/dtree.c index 0f27d28..a80aaa5 100644 --- a/dtree.c +++ b/dtree.c @@ -18,13 +18,13 @@ #define SCREEN_HEIGHT 720 /* User Customizable Variables*/ -static const SDL_Color EDIT_COLOR = {220, 220, 220}; // RGB -static const SDL_Color HINT_COLOR = {220, 0, 0}; // RGB -static const int SELECTED_COLOR[4] = {0, 220, 0, 0}; -static const int UNSELECTED_COLOR[4] = {0, 55, 0, 0}; -static const int CUT_COLOR[4] = {0, 0, 220, 0}; -static const int EDGE_COLOR[4] = {220, 220, 220, 0}; -static const int BACKGROUND_COLOR[4] = {15, 15, 15, 255}; +static const SDL_Color EDIT_COLOR = {220, 220, 220}; +static const SDL_Color HINT_COLOR = {220, 0, 0}; +static const SDL_Color SELECTED_COLOR = {0, 220, 0}; +static const SDL_Color UNSELECTED_COLOR = {0, 55, 0}; +static const SDL_Color CUT_COLOR = {0, 0, 220}; +static const SDL_Color EDGE_COLOR = {220, 220, 220}; +static const SDL_Color BACKGROUND_COLOR = {15, 15, 15}; static int TEXTBOX_WIDTH_SCALE = 25; // width of char static int TEXTBOX_HEIGHT = 50; // height of char static double UI_SCALE = 1.0; @@ -284,8 +284,8 @@ void calculatePositions(Node* root, Node* selected); void recursivelyPrintPositions(Node* node, int level); // RENDERING void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool wrap, bool cursor); -void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int offset, Uint8 r, Uint8 g, Uint8 b, Uint8 a); -void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, const int* color); +void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int offset, const SDL_Color color); +void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, const SDL_Color color); void drawNode(Node* node); char** getLines(char* message, int wrap); char* getEndOfLine(char* line_start, int wrap); @@ -1002,15 +1002,16 @@ void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool message_rect.w = strlen(lines[cur_line]) * TEXTBOX_WIDTH_SCALE * scale; message_rect.h = TEXTBOX_HEIGHT * scale; - SDL_SetRenderDrawColor(APP.renderer, BACKGROUND_COLOR[0], BACKGROUND_COLOR[1], BACKGROUND_COLOR[2], BACKGROUND_COLOR[3]); + SDL_SetRenderDrawColor(APP.renderer, BACKGROUND_COLOR.r, BACKGROUND_COLOR.g, BACKGROUND_COLOR.b, 255); SDL_RenderFillRect(APP.renderer, &message_rect); logPrint("Rendering %s %d %d\n", message, message_rect.w, message_rect.h); SDL_RenderCopy(APP.renderer, texture_message, NULL, &message_rect); + // draw cursor if (cursor && len_so_far <= CURSOR_POSITION + 1 && CURSOR_POSITION < len_so_far + strlen(lines[cur_line]) ){ int cursor_offset = (CURSOR_POSITION + 1 - len_so_far) * TEXTBOX_WIDTH_SCALE * GRAPH_SCALE; - SDL_SetRenderDrawColor(APP.renderer, 255, 255, 255, 255); + SDL_SetRenderDrawColor(APP.renderer, EDIT_COLOR.r, EDIT_COLOR.g, EDIT_COLOR.b, 255); SDL_RenderDrawLine(APP.renderer, message_rect.x + cursor_offset, message_rect.y, message_rect.x + cursor_offset, message_rect.y + (TEXTBOX_HEIGHT * GRAPH_SCALE)); } @@ -1025,19 +1026,19 @@ void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool free(lines); } -void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int offset, Uint8 r, Uint8 g, Uint8 b, Uint8 a){ +void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int offset, const SDL_Color color){ SDL_Rect rect; rect.x = (int) n_cx - ( len / 2 ) - offset; rect.y = (int) n_cy - ( height / 2 ) - offset; rect.w = len + offset + offset; rect.h = height + offset + offset; - SDL_SetRenderDrawColor(surface, r, g, b, a); + SDL_SetRenderDrawColor(surface, color.r, color.g, color.b, 255); SDL_RenderDrawRect(surface, &rect); } -void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, const int* color){ +void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, const SDL_Color color){ for (int i = 0; i < thickness; ++i) - drawBox(surface, n_cx , n_cy, len, height, i, color[0], color[1], color[2], color[3]); + drawBox(surface, n_cx , n_cy, len, height, i, color); } bool is_visible(Node* node){ @@ -1071,7 +1072,7 @@ void drawNode(Node* node) { /* draw edges between parent and child nodes */ if (node != GRAPH.root && (is_visible(node->p) || is_visible(node)) ){ - SDL_SetRenderDrawColor(APP.renderer, EDGE_COLOR[0], EDGE_COLOR[1], EDGE_COLOR[2], EDGE_COLOR[3]); + SDL_SetRenderDrawColor(APP.renderer, EDGE_COLOR.r, EDGE_COLOR.g, EDGE_COLOR.b, 255); SDL_RenderDrawLine(APP.renderer, x, y - (height*GRAPH_SCALE/2), node->p->pos.x, node->p->pos.y + (getHeight(node->p->text.buf, 1) * GRAPH_SCALE / 2)); } @@ -1122,7 +1123,7 @@ void drawNode(Node* node) { /* re-computes graph and draws everything onto renderer */ void prepareScene() { logPrint("start prepareScene()\n"); - SDL_SetRenderDrawColor(APP.renderer, BACKGROUND_COLOR[0], BACKGROUND_COLOR[1], BACKGROUND_COLOR[2], BACKGROUND_COLOR[3]); /* Background color */ + SDL_SetRenderDrawColor(APP.renderer, BACKGROUND_COLOR.r, BACKGROUND_COLOR.g, BACKGROUND_COLOR.b, 255); /* Background color */ SDL_RenderClear(APP.renderer); logPrint("Rendered\n"); From 6a7e1c92bb9d9dd5189e65724487c38ec55498c3 Mon Sep 17 00:00:00 2001 From: jarbus Date: Mon, 2 Aug 2021 17:08:45 -0400 Subject: [PATCH 09/18] remove redundant code --- dtree.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/dtree.c b/dtree.c index a80aaa5..3292d62 100644 --- a/dtree.c +++ b/dtree.c @@ -192,7 +192,6 @@ void deleteNode(Node* node){ logPrint("Freeing buffer\n"); free(node->text.buf); logPrint("Freeing hint_text\n"); - /* free(node->hint_text); */ free(node); logPrint("Deleted node %p\n", node); } @@ -602,7 +601,6 @@ void populateHintText(Node* node){ if (HINT_CHARS[i] == 'k' || HINT_CHARS[i] == 'h' || HINT_CHARS[i] == 'l' || HINT_CHARS[i] == 'j') continue; - for (int i = 0; i < HINT_BUFFER.size+1; ++i) HINT_TEXT_QUEUE[back][i] = '\0'; strcpy(HINT_TEXT_QUEUE[back], prefix); HINT_TEXT_QUEUE[back][strlen(prefix)] = HINT_CHARS[i]; if ( back - front == HINT_NODES->num){ From 907fb053730ceeea9c29d0b7219c2be91c8669c1 Mon Sep 17 00:00:00 2001 From: jarbus Date: Mon, 2 Aug 2021 17:20:01 -0400 Subject: [PATCH 10/18] fixes and booleans --- dtree.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/dtree.c b/dtree.c index 3292d62..bc375f7 100644 --- a/dtree.c +++ b/dtree.c @@ -339,7 +339,7 @@ int getHeight (char* message, bool wrap){ if ( wrap ){ int num_lines=1, chars_since_line_start=0, chars_since_last_space=0; for (int i = 0; i < strlen(message); ++i) { - if ( chars_since_line_start >= NUM_CHARS_B4_WRAP && message[i] != ' ' && message[i] != '\n' && !(i == strlen(message) - 1) ) { + if ( chars_since_line_start >= NUM_CHARS_B4_WRAP && message[i] != ' ' && message[i] != '\n' && i != strlen(message) - 1 ) { chars_since_line_start = chars_since_last_space -1; num_lines++; } @@ -571,10 +571,10 @@ void populateHintNodes(Node* node){ if ( !node ) return; if ( node == GRAPH.selected->p ) insertArray(HINT_NODES, node); logPrint("Adding hint node: %dx%d\n", node->pos.x, node->pos.y); - if (-(2*getWidth(node->text.buf, 1)) <= node->pos.x && - node->pos.x < APP.window_size.x+(2*getWidth(node->text.buf, 1)) && + if (-(2*getWidth(node->text.buf, true)) <= node->pos.x && + node->pos.x < APP.window_size.x+(2*getWidth(node->text.buf, true)) && RADIUS < node->pos.y && - node->pos.y < APP.window_size.y+(2*getHeight(node->text.buf, 1))) { + node->pos.y < APP.window_size.y+(2*getHeight(node->text.buf, true))) { insertArray(HINT_NODES, node); } for (int i = 0; i < node->children->num; ++i) { @@ -605,7 +605,6 @@ void populateHintText(Node* node){ HINT_TEXT_QUEUE[back][strlen(prefix)] = HINT_CHARS[i]; if ( back - front == HINT_NODES->num){ done = 1; - logPrint("breaking\n"); break; } back++; @@ -1057,8 +1056,8 @@ void drawNode(Node* node) { int y = node->pos.y; logPrint("Children pointer: %p, num: %lu\n", node->children, node->children->num); /* draw red ring for unselected nodes, green for selected */ - int width = getWidth(node->text.buf, 1) * GRAPH_SCALE; - int height = getHeight(node->text.buf, 1) * GRAPH_SCALE; + int width = getWidth(node->text.buf, true) * GRAPH_SCALE; + int height = getHeight(node->text.buf, true) * GRAPH_SCALE; if ( is_visible(node) ){ if (node == CUT) drawBorder(APP.renderer, x, y, width, height, THICKNESS, CUT_COLOR); @@ -1071,7 +1070,7 @@ void drawNode(Node* node) { /* draw edges between parent and child nodes */ if (node != GRAPH.root && (is_visible(node->p) || is_visible(node)) ){ SDL_SetRenderDrawColor(APP.renderer, EDGE_COLOR.r, EDGE_COLOR.g, EDGE_COLOR.b, 255); - SDL_RenderDrawLine(APP.renderer, x, y - (height*GRAPH_SCALE/2), node->p->pos.x, node->p->pos.y + (getHeight(node->p->text.buf, 1) * GRAPH_SCALE / 2)); + SDL_RenderDrawLine(APP.renderer, x, y - (height*GRAPH_SCALE/2), node->p->pos.x, node->p->pos.y + (getHeight(node->p->text.buf, true) * GRAPH_SCALE / 2)); } if ( is_visible(node) ){ From 81639084b5db4eff3d24336baeb5addbaa60a646 Mon Sep 17 00:00:00 2001 From: jarbus Date: Mon, 2 Aug 2021 17:24:23 -0400 Subject: [PATCH 11/18] ZOOM_SPEED variable added --- dtree.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dtree.c b/dtree.c index bc375f7..b12421f 100644 --- a/dtree.c +++ b/dtree.c @@ -29,6 +29,7 @@ static int TEXTBOX_WIDTH_SCALE = 25; // width of char static int TEXTBOX_HEIGHT = 50; // height of char static double UI_SCALE = 1.0; static double GRAPH_SCALE = 1.0; +static const double ZOOM_SPEED = 1.1; // rate at which graph zooms out, > 1 static const int FILENAME_BUFFER_MAX_SIZE = 64; static const int HINT_BUFFER_MAX_SIZE = 3; static const int MAX_TEXT_LEN = 128; // Max Num of chars in a node @@ -787,8 +788,8 @@ void doKeyDown(SDL_KeyboardEvent *event) { } } switch(event->keysym.sym) { - case SDLK_MINUS: GRAPH_SCALE *= (9./10.); return; - case SDLK_EQUALS: GRAPH_SCALE *= (10./9.); return; + case SDLK_MINUS: GRAPH_SCALE *= 1/ZOOM_SPEED; return; + case SDLK_EQUALS: GRAPH_SCALE *= ZOOM_SPEED; return; } } From 947f9202369dc5c77cc09399cdc793a786b78665 Mon Sep 17 00:00:00 2001 From: jarbus Date: Mon, 2 Aug 2021 18:05:59 -0400 Subject: [PATCH 12/18] 1 to true for booleans --- dtree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dtree.c b/dtree.c index b12421f..131c9c2 100644 --- a/dtree.c +++ b/dtree.c @@ -742,7 +742,7 @@ void handleTextInput(SDL_Event *event){ } void moveCursorLine(int relative_line){ - char** lines = getLines(GRAPH.selected->text.buf, 1); + char** lines = getLines(GRAPH.selected->text.buf, true); int len_so_far = 0; for (int i = 0; lines[i]; i++) { @@ -1081,7 +1081,7 @@ void drawNode(Node* node) { /* render node text */ renderMessage(node->text.buf, message_pos, GRAPH_SCALE, EDIT_COLOR, 1, &node->text == CURRENT_BUFFER); - char** lines = getLines(node->text.buf, 1); + char** lines = getLines(node->text.buf, true); int cur_line = 0; char* line = lines[cur_line]; while ( line ){ From 47f97c6985e28612bfd11af1f2f65bae7c488a7b Mon Sep 17 00:00:00 2001 From: jarbus Date: Wed, 4 Aug 2021 14:51:54 -0400 Subject: [PATCH 13/18] Cursor bugfixes, cleanup, top and bottom edgecases --- dtree.c | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/dtree.c b/dtree.c index 131c9c2..48ace0e 100644 --- a/dtree.c +++ b/dtree.c @@ -288,6 +288,7 @@ void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int void drawBorder(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int thickness, const SDL_Color color); void drawNode(Node* node); char** getLines(char* message, int wrap); +void freeLines(char** lines); char* getEndOfLine(char* line_start, int wrap); void prepareScene(); void presentScene(); @@ -414,6 +415,12 @@ char** getLines(char* message, int wrap){ return lines; } +void freeLines(char** lines){ + for (int i = 0; lines[i]; i++) + free(lines[i]); + free(lines); +} + // READ/WRITE // We replace user-entered \n with | for the file format @@ -741,39 +748,37 @@ void handleTextInput(SDL_Event *event){ } } +// can only handle +1 and -1 void moveCursorLine(int relative_line){ char** lines = getLines(GRAPH.selected->text.buf, true); - int len_so_far = 0; + for (int i = 0; lines[i]; i++) { + if ( CURSOR_POSITION < len_so_far - 1 || CURSOR_POSITION > len_so_far + (int) strlen(lines[i]) - 1 ) { + len_so_far += (int) strlen(lines[i]) + 1; + continue; + } + if ( relative_line == 1 && !lines[i+1] ) CURSOR_POSITION = CURRENT_BUFFER->len - 1; + if ( relative_line == -1 && i == 0 ) CURSOR_POSITION = -1; + int col = CURSOR_POSITION - len_so_far; // Move Up - if ( relative_line == -1 && i > 0 && CURSOR_POSITION >= len_so_far && CURSOR_POSITION < len_so_far + strlen(lines[i])){ - if ( col > strlen(lines[i-1]) ) { + if ( relative_line == -1 && i > 0 ){ + if ( col > (int) strlen(lines[i-1]) ) CURSOR_POSITION -= col + 1 + 1; - } - else { - CURSOR_POSITION -= col + 1; // move to end of line - 1 - CURSOR_POSITION -= strlen(lines[i-1]) - col; //move to col'th idx of line i-1 - } + else + CURSOR_POSITION -= strlen(lines[i-1]) + 1; } // Move Down - else if ( relative_line == 1 && lines[i+1] && CURSOR_POSITION > len_so_far && CURSOR_POSITION < len_so_far + strlen(lines[i])){ - if ( col > strlen(lines[i+1]) ) { + else if ( relative_line == 1 && lines[i+1] ){ + if ( col > (int) strlen(lines[i+1]) - 1 ) CURSOR_POSITION += strlen(lines[i]) - col + strlen(lines[i+1]); - } - else { - CURSOR_POSITION += strlen(lines[i]) + 1 - col; // move to end of line - 1 - CURSOR_POSITION += col; //move to col'th idx of line i-1 - } - break; + else + CURSOR_POSITION += strlen(lines[i]) + 1; } - len_so_far += strlen(lines[i]) + 1; + break; } - for (int i = 0; lines[i]; i++) - free(lines[i]); - free(lines); - + freeLines(lines); } void doKeyDown(SDL_KeyboardEvent *event) { @@ -1005,9 +1010,8 @@ void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool logPrint("Rendering %s %d %d\n", message, message_rect.w, message_rect.h); SDL_RenderCopy(APP.renderer, texture_message, NULL, &message_rect); - // draw cursor - if (cursor && len_so_far <= CURSOR_POSITION + 1 && CURSOR_POSITION < len_so_far + strlen(lines[cur_line]) ){ - + // draw cursor (the int cast is required) + if (cursor && len_so_far <= CURSOR_POSITION + 1 && CURSOR_POSITION < len_so_far + (int) strlen(lines[cur_line]) ){ int cursor_offset = (CURSOR_POSITION + 1 - len_so_far) * TEXTBOX_WIDTH_SCALE * GRAPH_SCALE; SDL_SetRenderDrawColor(APP.renderer, EDIT_COLOR.r, EDIT_COLOR.g, EDIT_COLOR.b, 255); SDL_RenderDrawLine(APP.renderer, message_rect.x + cursor_offset, message_rect.y, message_rect.x + cursor_offset, message_rect.y + (TEXTBOX_HEIGHT * GRAPH_SCALE)); @@ -1017,11 +1021,10 @@ void renderMessage(char* message, Point pos, double scale, SDL_Color color, bool SDL_FreeSurface(surface_message); SDL_DestroyTexture(texture_message); len_so_far += strlen(lines[cur_line]) + 1; - free(lines[cur_line]); cur_line++; } - free(lines); + freeLines(lines); } void drawBox(SDL_Renderer *surface, int n_cx, int n_cy, int len, int height, int offset, const SDL_Color color){ From 0dccf325808bfcd18c39d422f81fd15878bdb88e Mon Sep 17 00:00:00 2001 From: jarbus Date: Thu, 5 Aug 2021 04:58:12 -0400 Subject: [PATCH 14/18] Added "unwritten file" indicator --- dtree.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/dtree.c b/dtree.c index 48ace0e..95a92b1 100644 --- a/dtree.c +++ b/dtree.c @@ -245,6 +245,7 @@ static Node* LEFT_NEIGHBOR = NULL; // left and right neighbors of the selected n static Node* RIGHT_NEIGHBOR = NULL; static int OFFSCREEN_PADDING = 500; static int CURSOR_POSITION = 0; +static int unwritten = 0; // GENERAL UTIL FUNCTIONS void removeNodeFromGraph(Node* node); @@ -507,6 +508,7 @@ void writeFile(){ FILE* output = fopen(FILENAME_BUFFER.buf, "w"); writeChildrenStrings(output, GRAPH.root, 0); fclose(output); + unwritten = 0; } @@ -694,6 +696,7 @@ void insertCharIntoCurrentBuffer(char c){ } void deleteCharInBufferRelativeToCursor(int relative_position){ + unwritten = 1; // relative position allows us to use the same code for both backspace and delete for (int i = CURSOR_POSITION + relative_position; i < CURRENT_BUFFER->len-1; i++) { CURRENT_BUFFER->buf[i] = CURRENT_BUFFER->buf[i+1]; @@ -717,6 +720,8 @@ void handleTextInput(SDL_Event *event){ } } } + else + unwritten = 1; // Add text to buffer if ( add_text ) insertCharIntoCurrentBuffer(event->edit.text[0]); @@ -784,8 +789,8 @@ void moveCursorLine(int relative_line){ void doKeyDown(SDL_KeyboardEvent *event) { if ( isEditMode(MODE) ){ switch(event->keysym.sym) { - case SDLK_BACKSPACE: deleteCharInBufferRelativeToCursor(0); return; - case SDLK_DELETE: deleteCharInBufferRelativeToCursor(1); return; + case SDLK_BACKSPACE: deleteCharInBufferRelativeToCursor(0); unwritten = 1; return; + case SDLK_DELETE: deleteCharInBufferRelativeToCursor(1); unwritten = 1; return; case SDLK_LEFT: CURSOR_POSITION = max(CURSOR_POSITION-1,-1); return; case SDLK_RIGHT: CURSOR_POSITION = min(CURSOR_POSITION+1,CURRENT_BUFFER->len-1); return; case SDLK_UP: moveCursorLine(-1); return; @@ -1140,7 +1145,14 @@ void prepareScene() { Point filename_pos; filename_pos.x = (int) ((0.0) * APP.window_size.x); filename_pos.y = (int) ((1.0) * APP.window_size.y - (TEXTBOX_HEIGHT * UI_SCALE)); - renderMessage(FILENAME_BUFFER.buf, filename_pos, UI_SCALE, EDIT_COLOR, 0, &FILENAME_BUFFER == CURRENT_BUFFER); + + char FILENAME_MESSAGE[2048]; + strcpy(FILENAME_MESSAGE, FILENAME_BUFFER.buf); + if ( unwritten ){ + strcpy( FILENAME_MESSAGE + FILENAME_BUFFER.len, "*"); + } + renderMessage(FILENAME_MESSAGE, filename_pos, UI_SCALE, EDIT_COLOR, 0, &FILENAME_BUFFER == CURRENT_BUFFER); + // Draw mode Point mode_text_pos; From d8c987e96818fb1528436f9eea8be95bab3270d1 Mon Sep 17 00:00:00 2001 From: jarbus Date: Fri, 6 Aug 2021 12:55:09 -0400 Subject: [PATCH 15/18] updated roadmap --- ROADMAP.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index d287a05..fb1e8c4 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,13 +1,13 @@ # Roadmap -## v0.2 +## v0.3 * Add a FILE-OPEN key: a node buffer will be a file name, and pressing a key on the node opens it in users' preferred app -* Scaling the graph to zoom in or out -* Add cursor for buffers so users can use arrow keys to edit specific parts of text +* Add clipboard copy, paste functionality for buffers -## v0.3 +## v0.4 * Search + +## v0.5 * Undo -* Add copy, paste functionality for buffers From 7c993be835f885c69597396d32ddedfc6ceaa368 Mon Sep 17 00:00:00 2001 From: jarbus Date: Fri, 6 Aug 2021 12:58:20 -0400 Subject: [PATCH 16/18] Edit mode zoom bugfix --- dtree.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dtree.c b/dtree.c index 95a92b1..17806de 100644 --- a/dtree.c +++ b/dtree.c @@ -324,8 +324,7 @@ int getWidth (char* message, bool wrap){ int max_width = 0; while ( tok ) { char* line_end = getEndOfLine(tok, wrap); - logPrint("back in loop\n"); - if ( !line_end ){logPrint("breaking\n"); break;} + if ( !line_end ){break;} int line_len = ( line_end - tok ); max_width = max(line_len, max_width); // copy all chars up until line_end @@ -797,9 +796,11 @@ void doKeyDown(SDL_KeyboardEvent *event) { case SDLK_DOWN: moveCursorLine(1); return; } } - switch(event->keysym.sym) { - case SDLK_MINUS: GRAPH_SCALE *= 1/ZOOM_SPEED; return; - case SDLK_EQUALS: GRAPH_SCALE *= ZOOM_SPEED; return; + else{ + switch(event->keysym.sym) { + case SDLK_MINUS: GRAPH_SCALE *= 1/ZOOM_SPEED; return; + case SDLK_EQUALS: GRAPH_SCALE *= ZOOM_SPEED; return; + } } } From 53878a36264ceb740b4085b62fac01ecd0b7599c Mon Sep 17 00:00:00 2001 From: jarbus Date: Fri, 6 Aug 2021 12:58:58 -0400 Subject: [PATCH 17/18] Add zoom to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d21fa3c..f7dbf62 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ In Travel Mode: * `r` : edit file name * `w` : save file * `q` : quit the program +* `-` : Zoom out +* `=` : Zoom in In Any Mode: - press `esc` to return to travel mode and switch mode-persist off From b0588e929374c21456e9ec61a6600b465e92283d Mon Sep 17 00:00:00 2001 From: jarbus Date: Fri, 6 Aug 2021 13:04:54 -0400 Subject: [PATCH 18/18] Updated roadmap --- ROADMAP.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ROADMAP.md b/ROADMAP.md index fb1e8c4..e9aadd6 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -4,6 +4,7 @@ * Add a FILE-OPEN key: a node buffer will be a file name, and pressing a key on the node opens it in users' preferred app * Add clipboard copy, paste functionality for buffers +* Better drawing so the nodes at the top of the graph aren't crazy far apart ## v0.4