From e4b96cc66d8c4269661745ce187cb58c852542d3 Mon Sep 17 00:00:00 2001 From: physick Date: Mon, 31 Aug 2026 17:16:44 +0500 Subject: transitions --- src/scenes/puzzlePreviewScene.c | 193 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 src/scenes/puzzlePreviewScene.c (limited to 'src/scenes/puzzlePreviewScene.c') diff --git a/src/scenes/puzzlePreviewScene.c b/src/scenes/puzzlePreviewScene.c new file mode 100644 index 0000000..6ce3ba7 --- /dev/null +++ b/src/scenes/puzzlePreviewScene.c @@ -0,0 +1,193 @@ +#include +#include +#include +#include "scenes.h" +#include "../ui_elements/UI.h" +#include "../resources/resources.h" +#include "../resources/TextruesAtlas.h" + +static const uint8_t MAX_TINT = 96; +static const float BODY_BUTTON_RATIO = 0.9f; +static const float BUTTON_PADDING_RATIO = 0.015f; + +typedef struct { + Puzzle *puzzle; + Button *backButton; + Button *proceedButton; + float scroll_up; + float hiding_state; + int scroll; + PopUpState state; +} puzzlePreviewData; + +void confirmSelemetion(Scene *self) { + if (self == NULL) return; + puzzlePreviewData *data = ((Scene *)self)->data; + if (data == NULL) return; + TraceLog(LOG_INFO, "Loading a puzzle %s", data->puzzle->Name); + data->state = POPUP_HIDING; +} + + +void closePreviewWindow(Scene *self) { + TraceLog(LOG_INFO, "Closing a preview window"); + if (self == NULL) return; + puzzlePreviewData *data = ((Scene *)self)->data; + if (data == NULL) return; + data->state = POPUP_HIDING_ALT; +} + +bool updatePuzzlePreview(void *self) { + puzzlePreviewData *data = ((Scene *)self)->data; + switch (data->state) { + case POPUP_REVEALING: + data->scroll_up += SCROLL_SPEED * GetFrameTime(); + if (data->scroll_up >= 1) { + data->state = POPUP_ACTIVE; + data->scroll_up = 1; + } + return true; + + case POPUP_HIDING_ALT: + data->scroll_up -= SCROLL_SPEED * GetFrameTime(); + if (data->scroll_up <= 0) { + if (data->puzzle != NULL) FreePuzzle(data->puzzle); + DeleteSceneFromStack(); + } + return true; + + case POPUP_HIDING: + data->hiding_state += BLACKOUT_SPEED * GetFrameTime(); + if (data->hiding_state >= 2) { + DeleteSceneFromStack(); + AddScene(CreatePuzzleScene(data->puzzle)); + } + return true; + + default: break; + } + if (data->backButton != NULL) UpdateButton(data->backButton); + if (data->proceedButton != NULL) UpdateButton(data->proceedButton); + return true; +} + +static Rectangle getBodyRect(puzzlePreviewData *data) { + float screen_h = GetScreenHeight(); + float screen_w = GetScreenWidth(); + return (Rectangle) { + .x = PADDING, + .y = PADDING + (screen_h * (1 - data->scroll_up)), + .width = screen_w - PADDING * 2, + .height = screen_h - PADDING * 2, + }; +} + +bool drawPuzzlePreview(void *self) { + puzzlePreviewData *data = ((Scene *)self)->data; + DrawRectangle(0, 0, + GetScreenWidth(), GetScreenHeight(), + (Color) {0, 0, 0, MAX_TINT * data->scroll_up }); + + Rectangle body = getBodyRect(data); + Rectangle TextArea = { + .x = body.x, + .y = body.y, + .width = body.width, + .height = body.height * BODY_BUTTON_RATIO, + }; + + DrawRecBordered(TextArea, COLORSCHEME_WHITE, COLORSCHEME_ORANGE, BORDER); + if (data->puzzle != NULL) { + DrawTextInRec(TextArea, data->puzzle->Description, + GetMainFont(), TEXT_FONT_SIZE, COLORSCHEME_BROWN, + 3, &data->scroll); + } + + float btn_space_height = body.height * (1 - BODY_BUTTON_RATIO); + float btn_padding = body.height * BUTTON_PADDING_RATIO; + float btn_height = btn_space_height - 2 * btn_padding; + float btn_width = btn_height * 2; + + if (data->backButton != NULL) { + DrawButton(data->backButton, &(Rectangle) { + .x = PADDING, + .y = TextArea.y + TextArea.height + btn_padding, + .height = btn_height, + .width = btn_height * 2, + }); + } + + if (data->proceedButton != NULL) { + DrawButton(data->proceedButton, &(Rectangle) { + .x = body.x + body.width - btn_width, + .y = TextArea.y + TextArea.height + btn_padding, + .height = btn_height, + .width = btn_height * 2, + }); + } + + if (data->state == POPUP_HIDING) { + DrawRectangle(0, 0, + GetScreenWidth(), GetScreenHeight(), + (Color) {0, 0, 0, 255 * (data->hiding_state >= 1 ? 1 : data->hiding_state) }); + } + + return true; +} + +/// DOES NOT FREE THE PUZZLE! This should be handled separatly +void deinitPuzzlePreview(void *self) { + TraceLog(LOG_INFO, "Deleting a puzzle preview"); + if (self == NULL) return; + puzzlePreviewData *data = ((Scene *)self)->data; + if (data != NULL) { + if (data->backButton != NULL) free(data->backButton); + if (data->proceedButton != NULL) free(data->proceedButton); + } + free(self); + TraceLog(LOG_INFO, "Deleting a puzzle preview - success"); +} + +Scene *CreatePuzzlePreview(Puzzle *puzzle) { + if (puzzle == NULL) return NULL; + TraceLog(LOG_INFO, "Creating a puzzle preview for a puzzle %s", + puzzle->Name); + Scene *outp = malloc(sizeof(Scene)); + outp->Update = updatePuzzlePreview; + outp->Draw = drawPuzzlePreview; + outp->Deint = deinitPuzzlePreview; + outp->IsTransparent = true; + + puzzlePreviewData *data = malloc(sizeof(puzzlePreviewData)); + if (data == NULL) { + free(outp); + return NULL; + } + + data->puzzle = puzzle; + data->state = POPUP_REVEALING; + data->scroll_up = 0; + data->scroll = 0; + + Button *backButton = malloc(sizeof(Button)); + if (backButton != NULL) { + backButton->parent = outp; + backButton->OnClick = closePreviewWindow; + backButton->atlas = GetButtonsAtlas(); + backButton->textrueLocation = BACK_BUTTON_WIDE_LOCATION; + } + data->backButton = backButton; + + Button *proceedButton = malloc(sizeof(Button)); + if (proceedButton != NULL) { + proceedButton->parent = outp; + proceedButton->OnClick = confirmSelemetion; + proceedButton->atlas = GetButtonsAtlas(); + proceedButton->textrueLocation = PROCEED_BUTTON_WIDE_LOCATION; + } + data->proceedButton = proceedButton; + + outp->data = data; + + return outp; +} -- cgit v1.3