summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c3
-rw-r--r--src/puzzles/collection.c21
-rw-r--r--src/resources/TextruesAtlas.h14
-rw-r--r--src/scenes/collectionScene.c88
-rw-r--r--src/scenes/scenes.h3
5 files changed, 114 insertions, 15 deletions
diff --git a/src/main.c b/src/main.c
index 6d563e2..9615d98 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,3 +1,4 @@
+#include <stdbool.h>
#include <stdio.h>
#include <raylib.h>
#include "scenes/scenes.h"
@@ -31,7 +32,7 @@ int main(void) {
return 1;
}
- if (!AddScene(CreatePuzzleCollectionScene(&el))) {
+ if (!AddScene(CreatePuzzleCollectionScene(&el, true))) {
printf("Failed to create a collection scene\n");
return 1;
}
diff --git a/src/puzzles/collection.c b/src/puzzles/collection.c
index ca2743c..a88bae4 100644
--- a/src/puzzles/collection.c
+++ b/src/puzzles/collection.c
@@ -13,6 +13,14 @@
static const char *IMAGE_NAME = "icon.png";
static const float NAME_IN_CARD_RATIO = 0.2f;
+int compare_elements(const void *a, const void *b) {
+ const CollectionElement *elA = (const CollectionElement *)a;
+ const CollectionElement *elB = (const CollectionElement *)b;
+
+ // Sort alphabetically by name
+ return strcmp(elA->path, elB->path);
+}
+
CollectionElementType getTypeFromPath(char *fullPath) {
struct stat st;
if (stat(fullPath, &st) != 0) return COLLECTION_ELEMENT_UNKNOWN;
@@ -65,16 +73,20 @@ char *getName(char *name) {
char buf[1024];
strncpy(buf, name, sizeof(buf));
size_t len = strlen(name);
+ size_t span_start = 0;
+ size_t span_end = 0;
// Cutting a file extention
for (size_t i = 0; i < len; ++i) {
if (buf[i] == '.') {
- buf[i] = 0x0;
- break;
+ if (span_end != 0) span_start = span_end + 1;
+ span_end = i;
}
}
+ if (span_end != 0)
+ buf[span_end] = 0x0;
- return strdup(buf);
+ return strdup(buf + span_start);
}
size_t getElementCount(DIR *dir, CollectionElement *el) {
@@ -136,6 +148,9 @@ void initCollectionFromDir(CollectionElement *el, void (*callback)(CollectionEle
idx += 1;
}
+ if (idx > 1) {
+ qsort(el->children, idx, sizeof(CollectionElement), compare_elements);
+ }
closedir(dir);
}
diff --git a/src/resources/TextruesAtlas.h b/src/resources/TextruesAtlas.h
index 97eb889..a9202c2 100644
--- a/src/resources/TextruesAtlas.h
+++ b/src/resources/TextruesAtlas.h
@@ -50,4 +50,18 @@ static const Rectangle PROCEED_BUTTON_WIDE_LOCATION = {
.height = 32,
};
+static const Rectangle LEFT_ARROW_ICON_LOCATION = {
+ .x = 0,
+ .y = 32,
+ .width = 32,
+ .height = 96,
+};
+
+static const Rectangle RIGHT_ARROW_ICON_LOCATION = {
+ .x = 32,
+ .y = 32,
+ .width = 32,
+ .height = 96,
+};
+
#endif // TEXTURES_ATLAS_H
diff --git a/src/scenes/collectionScene.c b/src/scenes/collectionScene.c
index cda6fd1..1f1173e 100644
--- a/src/scenes/collectionScene.c
+++ b/src/scenes/collectionScene.c
@@ -1,6 +1,8 @@
#include <dirent.h>
#include <raylib.h>
+#include <stdbool.h>
#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -10,19 +12,31 @@
#include "../utils/arena.h"
#include "../resources/TextruesAtlas.h"
+static const float MENU_SCROLL_SENC = 75.0f;
static const size_t ARENA_SIZE = 1024 * 64;
+static const int SCENE_PADDING = 30;
+static const int FOOTER_PADDING = 60;
+static const float ARROWS_HEIGHT = 0.4f;
+static const uint8_t ARROWS_ALPHA = 128;
+/// Height / width
+static const float ELEMENT_WIDTH_RATIO = 0.45f;
typedef struct {
CollectionElement *collection;
+ CollectionElement *selected;
Button *backButton;
size_t count;
+ float blackout_state;
+ PopUpState state;
+ float scroll;
} CollectionSceneData;
CollectionSceneData *getData(void *self) {
return ((Scene *)self)->data;
}
-void backButton_onClick(Scene *self) {
+static void backButton_onClick(Scene *self) {
+ // CollectionSceneData *data = getData(self);
DeleteSceneFromStack();
}
@@ -34,7 +48,7 @@ void collectionElement_onSelect(CollectionElement *caller) {
AddScene(CreatePuzzlePreview(ReadPuzzleFromFile(caller->path)));
break;
case COLLECTION_ELEMENT_COLLECTION:
- AddScene(CreatePuzzleCollectionScene(caller));
+ AddScene(CreatePuzzleCollectionScene(caller, false));
break;
default:
TraceLog(LOG_WARNING, "Invalid CollectionElement type for %s", caller->path);
@@ -43,9 +57,9 @@ void collectionElement_onSelect(CollectionElement *caller) {
}
void DrawCollectionName(char *name) {
- Vector2 width = MeasureTextEx(*GetMainFont(), name, 50, 1);
+ Vector2 width = MeasureTextEx(*GetMainFont(), name, HEADER_FONT_SIZE, 1);
int screen_width = GetScreenWidth();
- Vector2 pos = { .y = 20, .x = (screen_width - width.x) / 2, };
+ Vector2 pos = { .y = SCENE_PADDING , .x = (screen_width - width.x) / 2, };
DrawTextEx(*GetMainFont(), name, pos, HEADER_FONT_SIZE, 1, COLORSCHEME_BROWN);
}
@@ -63,10 +77,21 @@ char *getCollectionName(char *path) {
bool updateCollectionScene(void *self) {
CollectionSceneData *data = getData(self);
- if (data->collection != NULL)
+ if (data->state == POPUP_REVEALING) {
+ data->blackout_state -= BLACKOUT_SPEED * GetFrameTime();
+ if (data->blackout_state <= 0) {
+ data->blackout_state = 0;
+ data->state = POPUP_ACTIVE;
+ TraceLog(LOG_INFO, "Done revealing");
+ }
+ return true;
+ }
+
+ if (data->collection != NULL) {
for (size_t i = 0; i < data->collection->childCount; ++i) {
UpdateCollectionElement(&data->collection->children[i]);
}
+ }
if (data->backButton != NULL) UpdateButton(data->backButton);
return true;
@@ -85,14 +110,53 @@ bool drawCollectionScene(void *self) {
.height = 36, // TODO: make it match the page view scale
});
+ float element_height = GetScreenHeight() - SCENE_PADDING * 2 - HEADER_FONT_SIZE - FOOTER_PADDING;
+ float element_width = element_height * ELEMENT_WIDTH_RATIO;
for (size_t i = 0; i < data->collection->childCount; ++i) {
DrawCollectionElement(&data->collection->children[i], data->collection, (Rectangle) {
- .x = 10 + 210 * i,
- .y = 80,
- .width = 200,
- .height = 450,
+ .x = SCENE_PADDING + (element_width + PADDING) * i - data->scroll,
+ .y = SCENE_PADDING + HEADER_FONT_SIZE,
+ .width = element_width,
+ .height = element_height,
});
}
+
+ data->scroll -= GetMouseWheelMove() * MENU_SCROLL_SENC;
+ if (data->scroll < 0) data->scroll = 0;
+ float max_scroll = (element_width + PADDING) * data->collection->childCount + SCENE_PADDING * 2 - GetScreenWidth();
+ if (max_scroll < 0) max_scroll = 0;
+ if (data->scroll > max_scroll) data->scroll = max_scroll;
+
+ float arrows_height_px = GetScreenHeight() * ARROWS_HEIGHT;
+ Color arrows_color = { .r = 255, .g = 255, .b = 255, .a = ARROWS_ALPHA, };
+
+
+ if (data->scroll != 0)
+ DrawTexturePro(*GetButtonsAtlas(),
+ LEFT_ARROW_ICON_LOCATION,
+ (Rectangle) {
+ .x = 0,
+ .y = (GetScreenHeight() - arrows_height_px) / 2,
+ .width = SCENE_PADDING,
+ .height = arrows_height_px
+ }, (Vector2) {0}, 0, arrows_color);
+
+ if (data->scroll != max_scroll)
+ DrawTexturePro(*GetButtonsAtlas(),
+ RIGHT_ARROW_ICON_LOCATION,
+ (Rectangle) {
+ .x = GetScreenWidth() - SCENE_PADDING,
+ .y = (GetScreenHeight() - arrows_height_px) / 2,
+ .width = SCENE_PADDING,
+ .height = arrows_height_px
+ }, (Vector2) {0}, 0, arrows_color);
+
+ if (data->state != POPUP_ACTIVE) {
+ DrawRectangle(0, 0,
+ GetScreenWidth(), GetScreenHeight(),
+ (Color) {0, 0, 0, 255 * (data->blackout_state >= 1 ? 1 : data->blackout_state) });
+ }
+
return true;
}
@@ -107,7 +171,7 @@ void deinitCollectionScene(void *self) {
free((Scene *)self);
}
-Scene *CreatePuzzleCollectionScene(CollectionElement *el) {
+Scene *CreatePuzzleCollectionScene(CollectionElement *el, bool smooothEntry) {
TraceLog(LOG_INFO, "Creating a collection scene");
Scene *outp = malloc(sizeof(Scene));
if (outp == NULL) return NULL;
@@ -124,6 +188,10 @@ Scene *CreatePuzzleCollectionScene(CollectionElement *el) {
if (!el->IsInitialized) InitializeCollection(el, collectionElement_onSelect);
data->collection = el;
+ data->selected = NULL;
+ data->state = smooothEntry? POPUP_REVEALING : POPUP_ACTIVE;
+ data->blackout_state = 1.0f;
+ data->scroll = 0.0f;
Button *backButton = malloc(sizeof(Button));
if (backButton != NULL) {
diff --git a/src/scenes/scenes.h b/src/scenes/scenes.h
index d705feb..f4ba579 100644
--- a/src/scenes/scenes.h
+++ b/src/scenes/scenes.h
@@ -40,10 +40,11 @@ bool UpdateScene();
Scene *CreateMainMenu();
Scene *CreatePuzzleScene(Puzzle *puzzle);
+/// Expects a callback to add time (second argument = amount of seconds) to the scene.
Scene *CreateDistractionScene(DistractionPuzzle *puzzle, void (*addTime)(Scene *, size_t));
Scene *CreateResultView(SubmitionResult *result);
-Scene *CreatePuzzleCollectionScene(CollectionElement *el);
+Scene *CreatePuzzleCollectionScene(CollectionElement *el, bool smooothEntry);
Scene *CreatePuzzlePreview(Puzzle *puzzle);
#endif // SCENES_H