]> git.lizzy.rs Git - nothing.git/blob - src/game/level/level_editor/layer_picker.c
077a56b3b5e7b1d3ca47b88f549eab102d76076c
[nothing.git] / src / game / level / level_editor / layer_picker.c
1 #include <stdbool.h>
2 #include <string.h>
3
4 #include <SDL.h>
5
6 #include "system/stacktrace.h"
7 #include "layer_picker.h"
8 #include "color.h"
9 #include "game/camera.h"
10 #include "math/rect.h"
11 #include "math/extrema.h"
12 #include "game/sprite_font.h"
13
14 #define LAYER_TITLE_PADDING 15.0f
15 #define LAYER_TITLE_SIZE 3.0f
16 #define LAYER_SELECTED_OFFSET 15.0f
17
18 static const Color LAYER_CELL_BACKGROUND_COLORS[LAYER_PICKER_N] = {
19     {1.0f, 0.0f, 0.0f, 1.0f}, // LAYER_PICKER_BACKGROUND
20     {0.0f, 1.0f, 0.0f, 1.0f}, // LAYER_PICKER_PLAYER
21     {0.6f, 0.6f, 1.0f, 1.0f}, // LAYER_PICKER_BACK_PLATFORMS
22     {0.0f, 0.0f, 1.0f, 1.0f}, // LAYER_PICKER_PLATFORMS
23     {1.0f, 1.0f, 1.0f, 1.0f}, // LAYER_PICKER_GOALS
24     {1.0f, 0.2f, 0.6f, 1.0f}, // LAYER_PICKER_LAVA
25     {0.2f, 1.0f, 0.6f, 1.0f}, // LAYER_PICKER_BOXES
26     {0.2f, 0.6f, 1.0f, 1.0f}, // LAYER_PICKER_LABELS
27     {0.2f, 1.0f, 0.6f, 1.0f}, // LAYER_PICKER_REGIONS
28 };
29
30 static const char *LAYER_CELL_TITLES[LAYER_PICKER_N] = {
31     "Background",              // LAYER_PICKER_BACKGROUND
32     "Player",                  // LAYER_PICKER_PLAYER
33     "Back Platforms",          // LAYER_PICKER_BACK_PLATFORMS
34     "Platforms",               // LAYER_PICKER_PLATFORMS
35     "Goals",                   // LAYER_PICKER_GOALS
36     "Lava",                    // LAYER_PICKER_LAVA
37     "Boxes",                   // LAYER_PICKER_BOXES
38     "Labels",                  // LAYER_PICKER_LABELS
39     "Regions",                 // LAYER_PICKER_REGIONS
40 };
41
42 inline static float layer_picker_max_width(void)
43 {
44     size_t max = 0;
45
46     for (size_t i = 0; i < LAYER_PICKER_N; ++i) {
47         max = max_size_t(max, strlen(LAYER_CELL_TITLES[i]));
48     }
49
50     return (float) max * FONT_CHAR_WIDTH * LAYER_TITLE_SIZE + LAYER_TITLE_PADDING * 2.0f;
51 }
52
53 #define LAYER_CELL_WIDTH layer_picker_max_width()
54 #define LAYER_CELL_HEIGHT (LAYER_TITLE_SIZE * FONT_CHAR_HEIGHT + LAYER_TITLE_PADDING * 2.0f)
55 #define LAYER_CELL_REFERENCE 1980.0f
56 #define LAYER_CELL_WR_RATIO (LAYER_CELL_WIDTH / LAYER_CELL_REFERENCE)
57 #define LAYER_CELL_HW_RATIO (LAYER_CELL_HEIGHT / LAYER_CELL_WIDTH)
58 #define LAYER_TITLE_SW_RATIO (LAYER_TITLE_SIZE / LAYER_CELL_WIDTH)
59 #define LAYER_TITLE_PW_RATIO (LAYER_TITLE_PADDING / LAYER_CELL_WIDTH)
60 #define LAYER_CELL_OW_RATIO (LAYER_SELECTED_OFFSET / LAYER_CELL_WIDTH)
61
62 int layer_picker_render(const LayerPicker *layer_picker,
63                         const Camera *camera)
64 {
65     trace_assert(layer_picker);
66     trace_assert(camera);
67
68     const Rect viewport = camera_view_port_screen(camera);
69
70     for (size_t i = 0; i < LAYER_PICKER_N; ++i) {
71         const Vec2f size = {
72             .x = viewport.w * LAYER_CELL_WR_RATIO,
73             .y = viewport.w * LAYER_CELL_WR_RATIO * LAYER_CELL_HW_RATIO
74         };
75
76         Vec2f position = {
77             .x = 0.0f,
78             .y = viewport.h * 0.5f - size.y * LAYER_PICKER_N * 0.5f
79         };
80
81         Color color = LAYER_CELL_BACKGROUND_COLORS[i];
82
83         if (*layer_picker == i) {
84             position.x += size.x * LAYER_CELL_OW_RATIO;
85         } else {
86             color.a *= 0.70f;
87         }
88
89         if (camera_fill_rect_screen(
90                 camera,
91                 rect(
92                     position.x,
93                     size.y * (float) i + position.y,
94                     size.x, size.y),
95                 color) < 0) {
96             return -1;
97         }
98
99         camera_render_text_screen(
100             camera,
101             LAYER_CELL_TITLES[i],
102             vec(size.x * LAYER_TITLE_SW_RATIO,
103                 size.x * LAYER_TITLE_SW_RATIO),
104             color_invert(color),
105             vec(position.x + size.x * LAYER_TITLE_PW_RATIO,
106                 size.y * (float) i + position.y + size.x * LAYER_TITLE_PW_RATIO));
107     }
108
109     return 0;
110 }
111
112 int layer_picker_event(LayerPicker *layer_picker,
113                        const SDL_Event *event,
114                        const Camera *camera,
115                        bool *selected)
116 {
117     trace_assert(layer_picker);
118     trace_assert(event);
119     trace_assert(camera);
120
121     const Rect viewport = camera_view_port_screen(camera);
122
123     const Vec2f size = {
124         .x = viewport.w * LAYER_CELL_WR_RATIO,
125         .y = viewport.w * LAYER_CELL_WR_RATIO * LAYER_CELL_HW_RATIO
126     };
127
128     const Vec2f position = {
129         .x = 0.0f,
130         .y = viewport.h * 0.5f - size.y * LAYER_PICKER_N * 0.5f
131     };
132
133     switch (event->type) {
134     case SDL_MOUSEBUTTONDOWN: {
135         for (LayerPicker i = 0; i < LAYER_PICKER_N; ++i) {
136             const Rect cell = rect(
137                 position.x,
138                 size.y * (float) i + position.y,
139                 size.x, size.y);
140             if (rect_contains_point(cell, vec((float) event->button.x, (float) event->button.y))) {
141                 *layer_picker = i;
142                 *selected = true;
143                 return 0;
144             }
145         }
146     } break;
147     }
148
149     return 0;
150 }