summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.zig1
-rw-r--r--src/main.c1
-rw-r--r--src/scenes/mainMenu.c3
-rw-r--r--src/scenes/puzzleScene.c19
-rw-r--r--src/ui_elements/TextEditor.c118
-rw-r--r--src/ui_elements/UI.h32
6 files changed, 166 insertions, 8 deletions
diff --git a/build.zig b/build.zig
index de498b2..ef10804 100644
--- a/build.zig
+++ b/build.zig
@@ -15,6 +15,7 @@ pub fn build(b: *std.Build) void {
"src/main.c",
"src/resources/resources.c",
"src/ui_elements/UI.c",
+ "src/ui_elements/TextEditor.c",
"src/scenes/sceneManager.c",
"src/scenes/mainMenu.c",
"src/scenes/puzzleScene.c",
diff --git a/src/main.c b/src/main.c
index 7bf8c87..1131db9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,7 +4,6 @@
#include "resources/resources.h"
int main(void) {
-
if (!InitSceneStack()) {
printf("Failed to create a scene stack\n");
return 1;
diff --git a/src/scenes/mainMenu.c b/src/scenes/mainMenu.c
index 31b52c0..7732f6d 100644
--- a/src/scenes/mainMenu.c
+++ b/src/scenes/mainMenu.c
@@ -1,13 +1,14 @@
#include <raylib.h>
#include <stdlib.h>
#include "scenes.h"
+#include "../resources/resources.h"
bool updateMainMenu(void *self) {
return true;
}
bool drawMainMenu(void *self) {
- ClearBackground(SKYBLUE);
+ DrawBackground();
DrawText("Main menu", 0, 0, 100, BLACK);
return true;
}
diff --git a/src/scenes/puzzleScene.c b/src/scenes/puzzleScene.c
index 70a3667..fb45c02 100644
--- a/src/scenes/puzzleScene.c
+++ b/src/scenes/puzzleScene.c
@@ -6,14 +6,10 @@
typedef struct {
Puzzle *PuzzlePtr;
+ TextArea *EditorInfo;
int scroll;
} puzzleSceneData;
-
-bool updatePuzzleScene(void *self) {
- return true;
-}
-
const int HEADER_FONT_SIZE = 50;
const int PADDING = 10;
const int BORDER = 2;
@@ -77,13 +73,23 @@ bool drawPuzzleScene(void *self) {
DrawTextInRec(pane1, data->PuzzlePtr->Description,
GetMainFont(), 20, COLORSCHEME_BROWN, 3, &data->scroll);
+ DrawTextArea(data->EditorInfo, pane2, GetMainFont(), 20, 2);
+
+ return true;
+}
+
+bool updatePuzzleScene(void *self) {
+ puzzleSceneData *data = ((Scene *)self)->data;
+ HandleKeyboard(data->EditorInfo);
return true;
}
void deinitPuzzleScene(void *self) {
+ puzzleSceneData *data = ((Scene *)self)->data;
TraceLog(LOG_INFO, "Deleting a puzzle scene");
- free((puzzleSceneData *)((Scene *)self)->data);
+ FreeTextArea(data->EditorInfo);
+ free(data);
free((Scene *)self);
}
@@ -95,6 +101,7 @@ Scene *CreatePuzzleScene(Puzzle *puzzle) {
puzzleSceneData *data = malloc(sizeof(puzzleSceneData));
data->PuzzlePtr = puzzle;
+ data->EditorInfo = CreateTextArea();
outp->data = data;
return outp;
diff --git a/src/ui_elements/TextEditor.c b/src/ui_elements/TextEditor.c
new file mode 100644
index 0000000..ca2d270
--- /dev/null
+++ b/src/ui_elements/TextEditor.c
@@ -0,0 +1,118 @@
+#include "UI.h"
+#include "../resources/resources.h"
+#include <raylib.h>
+#include <stdlib.h>
+#include <string.h>
+
+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);
+}
diff --git a/src/ui_elements/UI.h b/src/ui_elements/UI.h
index 5868efe..4c94bf7 100644
--- a/src/ui_elements/UI.h
+++ b/src/ui_elements/UI.h
@@ -1,9 +1,41 @@
#include <raylib.h>
+#include <stddef.h>
#ifndef UI_ELEMENTS_H
#define UI_ELEMENTS_H
void DrawRecBordered(Rectangle rec, Color bg, Color border_color, int border_width);
void DrawTextInRec(Rectangle rec, char *text, Font *font, int height, Color color, float padding, int *scroll);
+float MeasureChar(Font *font, int height, char symbol);
+
+// ========== TEXT EDITOR ==========
+
+static const size_t DEFAULT_TEXT_NODE_SIZE = 256;
+
+typedef struct {
+ void *PrevNode;
+ void *NextNode;
+ char *text;
+ size_t cap;
+} TextNode;
+
+typedef struct {
+ TextNode *StartNode;
+ /// For the quick access
+ TextNode *CurrentNode;
+ size_t NodeLenth;
+
+ Vector2 CursorPosition;
+} TextArea;
+
+TextArea *CreateTextArea();
+void FreeTextArea(TextArea *ta);
+void DrawTextArea(TextArea *ta, Rectangle rec, Font *font, int height, int spacing);
+void InsertChar(TextArea *ta, char new_char);
+void DeleteChar(TextArea *ta);
+
+void HandleKeyboard(TextArea *ta);
+void MoveCursorRight(TextArea *ta);
+void MoveCursorLeft(TextArea *ta);
#endif // UI_ELEMENTS_H