/// // Created by bruno on 5.2.2025. /// #include "texteditor.h" #include "font.h" // Initialize the text editor void init_editor(TextEditor *editor, BitmapFont *font, int x, int y, SDL_Renderer *renderer) { for (int i = 0; i < MAX_LINES_ASM; i++) { editor->lines[i].text[0] = '\0'; // Empty string editor->lines[i].active = 0; } editor->lines[0].active = 1; editor->line_count = 1; editor->cursor_line = 0; editor->cursor_line_offset = 0; editor->cursor_pos = 0; editor->readOnly = 0; editor->rect.x = 2; editor->rect.y = 2; editor->rect.w = MAX_LINE_WIDTH * (font->size + 1); editor->rect.h = MAX_LINES_DISPLAY * (font->size + 4); editor->outRect = editor->rect; editor->outRect.x = x; editor->outRect.y = y; editor->font = font; editor->texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, editor->rect.w, editor->rect.h); } // Insert a new line at a specific position void insert_line(TextEditor *editor, int position, const char *text, SDL_Renderer *renderer) { if (editor->line_count >= MAX_LINES_ASM || position < 0 || position > editor->line_count) { printf("Invalid position or max lines reached!\n"); return; } // Shift lines down if necessary for (int i = editor->line_count; i > position; i--) { strcpy(editor->lines[i].text, editor->lines[i - 1].text); editor->lines[i].active = editor->lines[i - 1].active; } strncpy(editor->lines[position].text, text, MAX_LINE_WIDTH); editor->lines[position].text[MAX_LINE_WIDTH] = '\0'; // Ensure null termination editor->lines[position].active = 1; editor->line_count++; generate_string_display(editor, renderer); } void insert_line_rel(TextEditor *editor, SDL_Renderer *renderer) { editor->cursor_pos = 0; insert_line(editor, editor->cursor_line + 1, "", renderer); editor->cursor_line++; } // Insert a character at the current cursor position void insert_character(TextEditor *editor, char ch, SDL_Renderer *renderer) { if (editor->cursor_line < 0 || editor->cursor_line >= editor->line_count) { printf("Invalid cursor position!\n"); return; } Line *line = &editor->lines[editor->cursor_line]; int len = strlen(line->text); if (len >= MAX_LINE_WIDTH || editor->cursor_pos > len) { printf("Position out of bounds or line is full!\n"); return; } // Shift characters to the right for (int i = len; i >= editor->cursor_pos; i--) { line->text[i + 1] = line->text[i]; } line->text[editor->cursor_pos] = ch; editor->cursor_pos++; generate_string_display(editor, renderer); } void remove_character(TextEditor *editor, SDL_Renderer *renderer) { if (editor->cursor_line < 0 || editor->cursor_line >= editor->line_count) { printf("Invalid cursor position!\n"); return; } if (editor->cursor_pos == 0 && editor->line_count > 1) { // Remove the current line and shift lines up for (int i = editor->cursor_line; i < editor->line_count - 1; i++) { strcpy(editor->lines[i].text, editor->lines[i + 1].text); editor->lines[i].active = editor->lines[i + 1].active; } editor->lines[editor->line_count - 1].text[0] = '\0'; editor->lines[editor->line_count - 1].active = 0; editor->line_count--; if (editor->cursor_line >= editor->line_count) { editor->cursor_line = editor->line_count - 1; } editor->cursor_pos = strlen(editor->lines[editor->cursor_line].text); } else { Line *line = &editor->lines[editor->cursor_line]; int len = strlen(line->text); if (editor->cursor_pos <= 0 || editor->cursor_pos > len) { printf("Position out of bounds!\n"); return; } // Shift characters to the left to remove the character for (int i = editor->cursor_pos - 1; i < len; i++) { line->text[i] = line->text[i + 1]; } editor->cursor_pos--; } generate_string_display(editor, renderer); } // Move cursor void move_cursor_relative(TextEditor *editor, int line_offset, int pos_offset) { int new_line = editor->cursor_line + line_offset; int new_pos = editor->cursor_pos + pos_offset; if (new_line < 0) new_line = 0; if (new_line >= editor->line_count) new_line = editor->line_count - 1; move_cursor(editor, new_line, new_pos); } // Move cursor void move_cursor(TextEditor *editor, int new_line, int new_pos) { if (new_line < 0) new_line = 0; if (new_line >= editor->line_count) new_line = editor->line_count - 1; int line_length = strlen(editor->lines[new_line].text); if (new_pos < 0) new_pos = 0; if (new_pos > line_length) new_pos = line_length; editor->cursor_line = new_line; editor->cursor_pos = new_pos; } // Generate a string from a given offset with a max line count void generate_string_display(TextEditor *editor, SDL_Renderer *renderer) { if (editor->cursor_line_offset < 0 || editor->cursor_line_offset >= editor->line_count) { printf("Invalid start line!\n"); return; } int end_line = editor->cursor_line_offset + MAX_LINES_DISPLAY; if (end_line > editor->line_count) end_line = editor->line_count; memset(editor->displayString, 0, sizeof(editor->displayString)); SDL_SetRenderTarget(renderer, editor->texture); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_Rect charRect; charRect.x = 0; charRect.y = 0; charRect.w = editor->font->size; charRect.h = editor->font->size; SDL_Rect outRect = charRect; outRect.x = 3; outRect.y = 2; SDL_Rect cursorRect; cursorRect.x = 0; cursorRect.y = 0; cursorRect.w = 1; cursorRect.h = editor->font->size; for (int line = editor->cursor_line_offset; line < end_line; line++) { if (editor->lines[line].active) { strcat(editor->displayString, editor->lines[line].text); char *linePTR = editor->lines[line].text; int charIndex = 0; while (*linePTR) { SDL_RenderCopy(renderer, editor->font->texture[*linePTR], &charRect, &outRect); outRect.x += charRect.w + 1; if (line == editor->cursor_line && charIndex == editor->cursor_pos - 1) { cursorRect.x = outRect.x; cursorRect.y = outRect.y; } charIndex++; linePTR++; } strcat(editor->displayString, "\n"); outRect.x = 3; outRect.y += charRect.h + 1; } } SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDL_RenderFillRect(renderer, &cursorRect); SDL_SetRenderTarget(renderer, NULL); } void editor_render(TextEditor *editor, SDL_Renderer *renderer) { SDL_RenderCopy(renderer, editor->texture, &editor->rect, &editor->outRect); } // Generate a string for assembling void generate_string(TextEditor *editor) { memset(editor->outputString, 0, sizeof(editor->outputString)); for (int i = 0; i < MAX_LINES_ASM; i++) { if (editor->lines[i].active) { strcat(editor->outputString, editor->lines[i].text); strcat(editor->outputString, "\n"); } } }