#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; }