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