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