diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/puzzles/collection.c | 7 | ||||
| -rw-r--r-- | src/puzzles/puzzle.h | 4 | ||||
| -rw-r--r-- | src/scenes/collectionScene.c | 68 | ||||
| -rw-r--r-- | src/scenes/puzzleScene.c | 35 | ||||
| -rw-r--r-- | src/scenes/resultView.c | 4 | ||||
| -rw-r--r-- | src/scenes/sceneManager.c | 3 | ||||
| -rw-r--r-- | src/tests/runner.c | 14 | ||||
| -rw-r--r-- | src/tests/test.h | 3 | ||||
| -rw-r--r-- | src/tests/ui_elements.c | 35 | ||||
| -rw-r--r-- | src/ui_elements/Button.c | 2 | ||||
| -rw-r--r-- | src/ui_elements/UI.c | 8 | ||||
| -rw-r--r-- | src/ui_elements/UI.h | 5 |
12 files changed, 166 insertions, 22 deletions
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 |
