]> git.lizzy.rs Git - nothing.git/blob - src/game/level/level_editor/layer_picker.c
Merge pull request #1089 from tsoding/vec
[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},
20     {0.0f, 1.0f, 0.0f, 1.0f},
21     {0.0f, 0.0f, 1.0f, 1.0f},
22     {1.0f, 1.0f, 1.0f, 1.0f},
23     {1.0f, 0.2f, 0.6f, 1.0f},
24     {0.6f, 0.6f, 1.0f, 1.0f},
25     {0.2f, 1.0f, 0.6f, 1.0f},
26     {0.2f, 0.6f, 1.0f, 1.0f},
27     {0.2f, 1.0f, 0.6f, 1.0f},
28 };
29
30 static const char *LAYER_CELL_TITLES[LAYER_PICKER_N] = {
31     "Background",              // LAYER_PICKER_BACKGROUND
32     "Player",                  // LAYER_PICKER_PLAYER
33     "Platforms",               // LAYER_PICKER_PLATFORMS,
34     "Goals",                   // LAYER_PICKER_GOALS
35     "Lava",                    // LAYER_PICKER_LAVA
36     "Back Platforms",          // LAYER_PICKER_BACK_PLATFORMS,
37     "Boxes",                   // LAYER_PICKER_BOXES = 0,
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         if (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)) < 0) {
107             return -1;
108         }
109     }
110
111     return 0;
112 }
113
114 int layer_picker_event(LayerPicker *layer_picker,
115                        const SDL_Event *event,
116                        const Camera *camera,
117                        bool *selected)
118 {
119     trace_assert(layer_picker);
120     trace_assert(event);
121     trace_assert(camera);
122
123     const Rect viewport = camera_view_port_screen(camera);
124
125     const Vec2f size = {
126         .x = viewport.w * LAYER_CELL_WR_RATIO,
127         .y = viewport.w * LAYER_CELL_WR_RATIO * LAYER_CELL_HW_RATIO
128     };
129
130     const Vec2f position = {
131         .x = 0.0f,
132         .y = viewport.h * 0.5f - size.y * LAYER_PICKER_N * 0.5f
133     };
134
135     switch (event->type) {
136     case SDL_MOUSEBUTTONDOWN: {
137         for (size_t i = 0; i < LAYER_PICKER_N; ++i) {
138             const Rect cell = rect(
139                 position.x,
140                 size.y * (float) i + position.y,
141                 size.x, size.y);
142             if (rect_contains_point(cell, vec((float) event->button.x, (float) event->button.y))) {
143                 *layer_picker = i;
144                 *selected = true;
145                 return 0;
146             }
147         }
148     } break;
149     }
150
151     return 0;
152 }