summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.zig1
-rw-r--r--src/puzzles/collection.c7
-rw-r--r--src/puzzles/puzzle.h4
-rw-r--r--src/scenes/collectionScene.c68
-rw-r--r--src/scenes/puzzleScene.c35
-rw-r--r--src/scenes/resultView.c4
-rw-r--r--src/scenes/sceneManager.c3
-rw-r--r--src/tests/runner.c14
-rw-r--r--src/tests/test.h3
-rw-r--r--src/tests/ui_elements.c35
-rw-r--r--src/ui_elements/Button.c2
-rw-r--r--src/ui_elements/UI.c8
-rw-r--r--src/ui_elements/UI.h5
13 files changed, 167 insertions, 22 deletions
diff --git a/build.zig b/build.zig
index 4725061..8329f55 100644
--- a/build.zig
+++ b/build.zig
@@ -73,6 +73,7 @@ pub fn build(b: *std.Build) void {
"src/tests/runner.c",
"src/tests/arena_tests.c",
"src/tests/difficulty_calc.c",
+ "src/tests/ui_elements.c",
}
});
diff --git a/src/puzzles/collection.c b/src/puzzles/collection.c
index 5a46239..ea1a3b1 100644
--- a/src/puzzles/collection.c
+++ b/src/puzzles/collection.c
@@ -99,7 +99,7 @@ size_t getElementCount(DIR *dir, CollectionElement *el) {
return outp;
}
-void initCollectionFromDir(CollectionElement *el, void (*callback)(CollectionElement *)) {
+void initCollectionFromDir(CollectionElement *el, void (*callback)(CollectionElement *), void *callbackData) {
if (el == NULL) return;
TraceLog(LOG_INFO, "Initializing a collection element from %s/", el->path);
@@ -145,6 +145,7 @@ void initCollectionFromDir(CollectionElement *el, void (*callback)(CollectionEle
read_el->path = strdup(full_path_buf);
read_el->name = getName(entry->d_name);
read_el->callback = callback;
+ read_el->callbackData = callbackData;
idx += 1;
}
@@ -155,7 +156,7 @@ void initCollectionFromDir(CollectionElement *el, void (*callback)(CollectionEle
closedir(dir);
}
-void InitializeCollection(CollectionElement *el, void (*callback)(CollectionElement *)) {
+void InitializeCollection(CollectionElement *el, void (*callback)(CollectionElement *), void *callbackData) {
if (el == NULL) {
TraceLog(LOG_ERROR, "Failed to initialize collection element: the element is NULL");
return;
@@ -163,7 +164,7 @@ void InitializeCollection(CollectionElement *el, void (*callback)(CollectionElem
switch (el->type) {
case COLLECTION_ELEMENT_PUZZLE: break;
case COLLECTION_ELEMENT_COLLECTION:
- initCollectionFromDir(el, callback);
+ initCollectionFromDir(el, callback, callbackData);
break;
default:
TraceLog(LOG_WARNING, "Invalid CollectionElement type for %s", el->path);
diff --git a/src/puzzles/puzzle.h b/src/puzzles/puzzle.h
index 5af6d6e..b269282 100644
--- a/src/puzzles/puzzle.h
+++ b/src/puzzles/puzzle.h
@@ -116,6 +116,8 @@ typedef struct CollectionElement {
size_t childCount;
/// OnClick callback
void (*callback)(struct CollectionElement *);
+ /// The data that will be passed with the callback
+ void *callbackData;
/// If the element is initialized it has children and an icon loaded into mem
bool IsInitialized;
/// The element has an icon
@@ -127,7 +129,7 @@ typedef struct CollectionElement {
/// Accepts an element which children will be created and a generic callback that
/// will be called when the collection enement is selected.
/// The element passes a selected element as a callback argummment
-void InitializeCollection(CollectionElement *el, void (*callback)(CollectionElement *));
+void InitializeCollection(CollectionElement *el, void (*callback)(CollectionElement *), void *callbackData);
void DrawCollectionElement(CollectionElement *el, CollectionElement *parent, Rectangle rec);
void UpdateCollectionElement(CollectionElement *el);
void DeinitCollectionElement(CollectionElement *el);
diff --git a/src/scenes/collectionScene.c b/src/scenes/collectionScene.c
index f0f91f3..b8c1bc3 100644
--- a/src/scenes/collectionScene.c
+++ b/src/scenes/collectionScene.c
@@ -22,22 +22,51 @@ static const uint8_t ARROWS_ALPHA = 128;
static const float ELEMENT_WIDTH_RATIO = 0.45f;
typedef struct {
+ /// The collection we are displaying
CollectionElement *collection;
+ /// The collection we selected. Used in the transitions
CollectionElement *selected;
Button *backButton;
- size_t count;
float blackout_state;
PopUpState state;
float scroll;
} CollectionSceneData;
+
CollectionSceneData *getData(void *self) {
return ((Scene *)self)->data;
}
+PopUpState getCollectionSceneState(void *self) {
+ if (self == NULL) return POPUP_ACTIVE;
+ CollectionSceneData *data = getData(self);
+ if (data == NULL) return POPUP_ACTIVE;
+ return data->state;
+}
+
+
+void reopenCollectionScene(void *self, PopUpState PreviousSceneState) {
+ if (self == NULL) return;
+ CollectionSceneData *data = getData(self);
+ if (data == NULL) return;
+ if (data->state != POPUP_HIDING) printf("xdx\n");
+ switch (PreviousSceneState) {
+ case POPUP_HIDING:
+ data->state = POPUP_REVEALING;
+ data->blackout_state = 1.0f;
+ break;
+ default:
+ data->state = POPUP_ACTIVE;
+ break;
+ }
+}
+
static void backButton_onClick(Scene *self) {
- // CollectionSceneData *data = getData(self);
- DeleteSceneFromStack();
+ CollectionSceneData *data = getData(self);
+ data->state = POPUP_HIDING;
+ data->selected = NULL;
+ data->blackout_state = 0;
+ // DeleteSceneFromStack();
}
void collectionElement_onSelect(CollectionElement *caller) {
@@ -46,9 +75,18 @@ void collectionElement_onSelect(CollectionElement *caller) {
switch (caller->type) {
case COLLECTION_ELEMENT_PUZZLE:
AddScene(CreatePuzzlePreview(ReadPuzzleFromFile(caller->path)));
- break;
case COLLECTION_ELEMENT_COLLECTION:
- AddScene(CreatePuzzleCollectionScene(caller, false));
+ if (caller->callbackData == NULL) {
+ TraceLog(LOG_WARNING, "The callback data is NULL. Cannot initiate the smooth transition");
+ AddScene(CreatePuzzlePreview(ReadPuzzleFromFile(caller->path)));
+ } else {
+ TraceLog(LOG_WARNING, "The callback data is not NULL");
+ CollectionSceneData *data = ((Scene *)caller->callbackData)->data;
+ data->selected = caller;
+ data->state = POPUP_HIDING;
+ data->blackout_state = 0;
+ }
+ // AddScene(CreatePuzzleCollectionScene(caller, false));
break;
default:
TraceLog(LOG_WARNING, "Invalid CollectionElement type for %s", caller->path);
@@ -77,6 +115,7 @@ char *getCollectionName(char *path) {
bool updateCollectionScene(void *self) {
CollectionSceneData *data = getData(self);
+
if (data->state == POPUP_REVEALING) {
data->blackout_state -= BLACKOUT_SPEED * GetFrameTime();
if (data->blackout_state <= 0) {
@@ -87,6 +126,18 @@ bool updateCollectionScene(void *self) {
return true;
}
+ if (data->state == POPUP_HIDING) {
+ data->blackout_state += BLACKOUT_SPEED * GetFrameTime();
+ if (data->blackout_state >= 1) {
+ TraceLog(LOG_INFO, "Done hiding");
+ if (data->selected == NULL)
+ DeleteSceneFromStack();
+ else
+ AddScene(CreatePuzzleCollectionScene(data->selected, true));
+ }
+ return true;
+ }
+
if (data->collection != NULL) {
for (size_t i = 0; i < data->collection->childCount; ++i) {
UpdateCollectionElement(&data->collection->children[i]);
@@ -101,7 +152,6 @@ bool drawCollectionScene(void *self) {
CollectionSceneData *data = getData(self);
DrawBackground();
DrawCollectionName(data->collection->name);
- DrawPageView(GetScreenHeight() - 60, 5, 2);
if (data->backButton != NULL)
DrawButton(data->backButton, &(Rectangle) {
.x = 10,
@@ -180,8 +230,8 @@ Scene *CreatePuzzleCollectionScene(CollectionElement *el, bool smooothEntry) {
outp->Deint = deinitCollectionScene;
outp->IsTransparent = false;
- outp->Reopen = NULL;
- outp->GetCurrentState = NULL;
+ outp->Reopen = reopenCollectionScene;
+ outp->GetCurrentState = getCollectionSceneState;
CollectionSceneData *data = malloc(sizeof(CollectionSceneData));
if (data == NULL) {
@@ -189,7 +239,7 @@ Scene *CreatePuzzleCollectionScene(CollectionElement *el, bool smooothEntry) {
return NULL;
}
- if (!el->IsInitialized) InitializeCollection(el, collectionElement_onSelect);
+ if (!el->IsInitialized) InitializeCollection(el, collectionElement_onSelect, outp);
data->collection = el;
data->selected = NULL;
data->state = smooothEntry? POPUP_REVEALING : POPUP_ACTIVE;
diff --git a/src/scenes/puzzleScene.c b/src/scenes/puzzleScene.c
index 52652fe..1b11327 100644
--- a/src/scenes/puzzleScene.c
+++ b/src/scenes/puzzleScene.c
@@ -16,6 +16,8 @@ typedef struct {
// Miliseconds elapsed
float time_acc;
float blackout_state;
+ // Set when the solution is submitted. Defines whether the puzzle was solved when the scene is reinvoked
+ enum PUZZLE_TEST_RESULT result;
PopUpState state;
} puzzleSceneData;
@@ -39,19 +41,26 @@ void DrawControls(Scene *self, Rectangle rect) {
.height = rect.height - BORDER * 4,
};
- int acc = panel.width - panel.height + BORDER * 4;
+ int acc = panel.width + BORDER * 4;
if (data->submitButton != NULL) {
+ acc -= (panel.height + PADDING);
Rectangle submit_trg = {
.x = acc,
.y = panel.y,
.width = panel.height,
.height = panel.height,
};
- // Hacky. Should find a way to update in update()
DrawButton(data->submitButton, &submit_trg);
- acc -= (panel.height + PADDING);
}
+
+ // Drawing a remaining time
+ char timer_buf[32];
+ PrintTime(timer_buf, data->distraction_timer);
+ Vector2 timer_size = MeasureTextEx(*GetMainFont(), timer_buf, panel.height, 1);
+ acc -= (timer_size.x) + PADDING;
+ // DrawRectangle(acc, panel.y, timer_size.x, timer_size.y, COLORSCHEME_GREEN);
+ DrawTextEx(*GetMainFont(), timer_buf, (Vector2) { .x = acc, .y = panel.y + 2 }, panel.height, 1, COLORSCHEME_BROWN);
}
Rectangle GetBodyRect() {
@@ -65,6 +74,16 @@ Rectangle GetBodyRect() {
return outp;
}
+void reopenPuzzleScene(void *self, PopUpState PreviousSceneState) {
+ if (self == NULL) return;
+ puzzleSceneData *data = ((Scene *)self)->data;
+ if (data == NULL) return;
+ if (data->result == RESULT_OK) {
+ TraceLog(LOG_INFO, "YIPPEE!!! (puzzle accepted)");
+ DeleteSceneFromStack();
+ }
+}
+
bool drawPuzzleScene(void *self) {
puzzleSceneData *data = ((Scene *)self)->data;
DrawBackground();
@@ -110,11 +129,17 @@ bool drawPuzzleScene(void *self) {
void SubmitPuzzle(Scene *self) {
puzzleSceneData *data = ((Scene *)self)->data;
+ if (data == NULL) {
+ TraceLog(LOG_ERROR, "Failed to submit a puzzle: the data is NULL");
+ return;
+ }
char *script = GetText(data->EditorInfo);
SubmitionResult *res = SubmitSolution(data->PuzzlePtr, script);
- if (res != NULL)
+ if (res != NULL) {
+ data->result = res->result;
AddScene(CreateResultView(res));
+ }
}
void AddTime(Scene *self, size_t additionalTime) {
@@ -178,7 +203,7 @@ Scene *CreatePuzzleScene(Puzzle *puzzle) {
outp->Deint = deinitPuzzleScene;
outp->IsTransparent = false;
- outp->Reopen = NULL;
+ outp->Reopen = reopenPuzzleScene;
outp->GetCurrentState = NULL;
puzzleSceneData *data = malloc(sizeof(puzzleSceneData));
diff --git a/src/scenes/resultView.c b/src/scenes/resultView.c
index add28ea..842c824 100644
--- a/src/scenes/resultView.c
+++ b/src/scenes/resultView.c
@@ -79,9 +79,11 @@ Scene *CreateResultView(SubmitionResult *result) {
outp->Draw = drawResultView;
outp->Update = updateResultView;
outp->Deint = deinitResultView;
- outp->Reopen = NULL;
outp->IsTransparent = true;
+ outp->Reopen = NULL;
+ outp->GetCurrentState = NULL;
+
ResultViewData *data = malloc(sizeof(ResultViewData));
if (data == NULL) {
free(outp);
diff --git a/src/scenes/sceneManager.c b/src/scenes/sceneManager.c
index 8baa18e..c1ed257 100644
--- a/src/scenes/sceneManager.c
+++ b/src/scenes/sceneManager.c
@@ -36,8 +36,9 @@ void DeleteSceneFromStack() {
Scene *currentScene = getCurrentScene();
if (currentScene == NULL) return;
PopUpState currentSceneState = POPUP_ACTIVE;
- if (currentScene->GetCurrentState != NULL)
+ if (currentScene->GetCurrentState != NULL) {
currentSceneState = currentScene->GetCurrentState(currentScene);
+ }
currentScene->Deint(currentScene);
sceneStack[--sceneStackDepth] = NULL;
diff --git a/src/tests/runner.c b/src/tests/runner.c
index bdc4031..58861da 100644
--- a/src/tests/runner.c
+++ b/src/tests/runner.c
@@ -1,10 +1,13 @@
#include "test.h"
#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
const UnitTest TESTS[] = {
(UnitTest) { .Name = "Arena out of mem", .Function = ArenaOutOfMemory },
(UnitTest) { .Name = "Arena allocation", .Function = ArenaAllocation },
- (UnitTest) { .Name = "Test difficulty calculation", .Function = difficultyCalculator},
+ (UnitTest) { .Name = "Test difficulty calculation", .Function = difficultyCalculator },
+ (UnitTest) { .Name = "Timer display", .Function = timerPrintDisplay },
};
void SetGreenColor() {
@@ -36,3 +39,12 @@ int main(void) {
ResetColor();
return 0;
}
+
+char *reportError(const char *format, ...) {
+ char outp[16656];
+ va_list argptr;
+ va_start(argptr, format);
+ vsprintf(outp, format, argptr);
+ va_end(argptr);
+ return strdup(outp);
+}
diff --git a/src/tests/test.h b/src/tests/test.h
index 5994ecb..456c9e2 100644
--- a/src/tests/test.h
+++ b/src/tests/test.h
@@ -8,10 +8,13 @@ typedef struct {
char *(*Function)();
} UnitTest;
+char *reportError(const char *format, ...);
+
// ========== TESTS ==========
char *ArenaAllocation();
char *ArenaOutOfMemory();
char *difficultyCalculator();
+char *timerPrintDisplay();
#endif // TESTS_H
diff --git a/src/tests/ui_elements.c b/src/tests/ui_elements.c
new file mode 100644
index 0000000..a13492d
--- /dev/null
+++ b/src/tests/ui_elements.c
@@ -0,0 +1,35 @@
+#include "../ui_elements/UI.h"
+#include "test.h"
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+char *timerPrintDisplay() {
+ char buf[16];
+
+ size_t time = 0;
+ PrintTime(buf, time);
+ if (strcmp(buf, "00:00")) return reportError("The 00:00 test failed: got: '%s'", buf);
+
+ time = 3;
+ PrintTime(buf, time);
+ if (strcmp(buf, "00:03")) return reportError("The 00:03 test failed: got: '%s'", buf);
+
+ time = 30;
+ PrintTime(buf, time);
+ if (strcmp(buf, "00:30")) return reportError("The 00:30 test failed: got: '%s'", buf);
+
+ time = 60;
+ PrintTime(buf, time);
+ if (strcmp(buf, "01:00")) return reportError("The 01:00 test failed: got: '%s'", buf);
+
+ time = 63;
+ PrintTime(buf, time);
+ if (strcmp(buf, "01:03")) return reportError("The 01:03 test failed: got: '%s'", buf);
+
+ time = 60 * 100;
+ PrintTime(buf, time);
+ if (strcmp(buf, "100:00")) return reportError("The 100:00 test failed: got: '%s'", buf);
+
+ return NULL;
+}
diff --git a/src/ui_elements/Button.c b/src/ui_elements/Button.c
index e7293c8..a12e3a7 100644
--- a/src/ui_elements/Button.c
+++ b/src/ui_elements/Button.c
@@ -2,7 +2,7 @@
#include <raylib.h>
void UpdateButton(Button *btn) {
- if (IsMouseInRec(btn->previousFramePosition) && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
+ if (IsMouseInRec(btn->previousFramePosition) && IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) {
btn->OnClick(btn->parent);
}
}
diff --git a/src/ui_elements/UI.c b/src/ui_elements/UI.c
index ea3463a..f9b7527 100644
--- a/src/ui_elements/UI.c
+++ b/src/ui_elements/UI.c
@@ -139,6 +139,7 @@ void GetPanesSplit(Rectangle *pane1, Rectangle *pane2, Rectangle body, float pro
pane2->width = (body.width - PADDING) * (1 - proportion_h);
}
+// !! Not used anywhere at this moment
void DrawPageView(int y, unsigned int pages, unsigned int current_page) {
if (pages == 0) return;
float width = 2 * PAGE_DOTS_PADDING
@@ -168,3 +169,10 @@ void DrawPageView(int y, unsigned int pages, unsigned int current_page) {
x_pos += PAGE_DOTS_SPACING + PAGE_DOTS_RADIUS * 2;
}
}
+
+void PrintTime(char *trg, size_t seconds) {
+ if (trg == NULL) return;
+ size_t disp_minutes = seconds / 60;
+ size_t disp_seconds = seconds % 60;
+ sprintf(trg, "%02zu:%02zu", disp_minutes, disp_seconds);
+}
diff --git a/src/ui_elements/UI.h b/src/ui_elements/UI.h
index e48804e..356c2f4 100644
--- a/src/ui_elements/UI.h
+++ b/src/ui_elements/UI.h
@@ -50,6 +50,7 @@ static const int PAGE_DOTS_RADIUS = 3;
static const char PAGE_DOTS_TRANSPARENCY = (char)192;
/// Draws the little dots that represent the page you are on
+// !! Not used anywhere at this moment
void DrawPageView(int y, unsigned int pages, unsigned int current_page);
// ========== TEXT EDITOR ==========
@@ -104,4 +105,8 @@ void FreeTextArea(TextArea *ta);
/// and vertical orientation
void GetPanesSplit(Rectangle *pane1, Rectangle *pane2, Rectangle body, float proportion_h, float proportion_v);
+/// Prints the time in the format MM:SS to the trg.
+/// It is expected that size of outp buffer is at least 16 bytes
+void PrintTime(char *trg, size_t seconds);
+
#endif // UI_ELEMENTS_H