summaryrefslogtreecommitdiff
path: root/src/scenes/puzzlePreviewScene.c
diff options
context:
space:
mode:
authorphysick <mynameisgennadiy@vk.com>2026-08-31 17:16:44 +0500
committerphysick <mynameisgennadiy@vk.com>2026-08-31 17:16:44 +0500
commite4b96cc66d8c4269661745ce187cb58c852542d3 (patch)
tree4268a1ee350a9d762694e1de8803493ba4237bb1 /src/scenes/puzzlePreviewScene.c
parentb45620544427306854a28a5163fafd45b007acc2 (diff)
transitions
Diffstat (limited to 'src/scenes/puzzlePreviewScene.c')
-rw-r--r--src/scenes/puzzlePreviewScene.c193
1 files changed, 193 insertions, 0 deletions
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 <raylib.h>
+#include <stdint.h>
+#include <stdlib.h>
+#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;
+}