#include "UI.h" #include "../resources/resources.h" #include #include #include void HighlightCharacter(Vector2 lineStartPos, char *line, int index, Font *font, int height, int spacing) { float x_position = 0; for (int i = 0; i < index; i++) { x_position += MeasureChar(font, height, line[i]); x_position += spacing; } DrawLine(lineStartPos.x + x_position, lineStartPos.y, lineStartPos.x + x_position, lineStartPos.y + height, COLORSCHEME_ORANGE); } TextNode *CreateNode(TextNode *prev, TextNode *next) { TextNode *node = malloc(sizeof(TextNode)); if (node == NULL) return NULL; node->NextNode = next; node->PrevNode = prev; node->text = malloc(DEFAULT_TEXT_NODE_SIZE); if (node->text != NULL) node->cap = DEFAULT_TEXT_NODE_SIZE; return node; } /// Recursively frees the nodes void FreeNodeRec(TextNode *node) { if (node == NULL) return; FreeNodeRec(node->NextNode); free(node->text); free(node); } TextArea *CreateTextArea() { TextArea *outp = malloc(sizeof(TextArea)); if (outp == NULL) return NULL; TextNode *start_node = CreateNode(NULL, NULL); if (start_node == NULL) { free(outp); return NULL; } outp->StartNode = start_node; outp->CurrentNode = start_node; outp->NodeLenth = 1; return outp; } void FreeTextArea(TextArea *ta) { FreeNodeRec(ta->StartNode); free(ta); } /// draws a text area on the screen. Main draw entry point void DrawTextArea(TextArea *ta, Rectangle rec, Font *font, int height, int spacing) { Vector2 pos = { .x = rec.x, .y = rec.y }; TextNode *node = ta->StartNode; while (node != NULL) { DrawTextEx(*font, node->text, pos, height, spacing, COLORSCHEME_BROWN); if (node == ta->CurrentNode) HighlightCharacter(pos, node->text, ta->CursorPosition.x, font, height, spacing); node = node->NextNode; pos.x += height; } } void MoveCursorRight(TextArea *ta) { if (ta == NULL || ta->CurrentNode == NULL) return; ta->CursorPosition.x += 1; } void MoveCursorLeft(TextArea *ta) { if (ta == NULL || ta->CurrentNode == NULL) return; ta->CursorPosition.x -= 1; if (ta->CursorPosition.x < 0) ta->CursorPosition.x = 0; } void InsertChar(TextArea *ta, char new_char) { if (ta == NULL || ta->CurrentNode == NULL) return; (ta->CurrentNode->text)[(int)ta->CursorPosition.x] = new_char; ta->CursorPosition.x += 1; size_t line_len = strlen(ta->CurrentNode->text); if (ta->CursorPosition.x > line_len) ta->CursorPosition.x = line_len; } void DeleteChar(TextArea *ta) { if (ta == NULL || ta->CurrentNode == NULL) return; if (ta->CursorPosition.x == 0) return; size_t line_len = strlen(ta->CurrentNode->text); if (ta->CursorPosition.x == line_len) { ta->CurrentNode->text[line_len - 1] = 0x0; } else { char *after_str = (ta->CurrentNode->text + (int)ta->CursorPosition.x); strcpy(ta->CurrentNode->text + (int)ta->CursorPosition.x - 1, after_str); } ta->CursorPosition.x -= 1; } bool IsKeyPressedFix(int key) { return IsKeyPressedRepeat(key) || IsKeyPressed(key); } void HandleKeyboard(TextArea *ta) { int charKey = GetCharPressed(); while (charKey > 0) { if (charKey >= 32 && charKey <= 125) { InsertChar(ta, (char)charKey); } charKey = GetCharPressed(); } if (IsKeyPressedFix(KEY_BACKSPACE)) DeleteChar(ta); if (IsKeyPressedFix(KEY_LEFT)) MoveCursorLeft(ta); if (IsKeyPressedFix(KEY_RIGHT)) MoveCursorRight(ta); }