]> git.lizzy.rs Git - nothing.git/blob - src/game/level/level_editor/color_picker.c
Merge pull request #998 from tsoding/824
[nothing.git] / src / game / level / level_editor / color_picker.c
1 #include <stdbool.h>
2
3 #include "game/level/boxes.h"
4 #include "system/stacktrace.h"
5 #include "system/line_stream.h"
6 #include "system/log.h"
7 #include "game/camera.h"
8 #include "color_picker.h"
9 #include "color.h"
10
11 #define COLOR_SLIDER_HEIGHT 50.0f
12 #define COLOR_SLIDER_WIDTH 300.0f
13 #define COLOR_SLIDER_PADDING_BOTTOM 10.0f
14
15 const char *slider_labels[COLOR_SLIDER_N] = {
16     "Hue",
17     "Saturation",
18     "Lightness"
19 };
20
21 LayerPtr color_picker_as_layer(ColorPicker *color_picker)
22 {
23     LayerPtr layer = {
24         .ptr = color_picker,
25         .type = LAYER_COLOR_PICKER
26     };
27     return layer;
28 }
29
30 ColorPicker create_color_picker_from_rgba(Color color)
31 {
32     Color color_hsla = rgba_to_hsla(color);
33     ColorPicker color_picker = {
34         .sliders = {
35             {0, color_hsla.r, 360.0f},
36             {0, color_hsla.g, 1.0f},
37             {0, color_hsla.b, 1.0f}
38         }
39     };
40     return color_picker;
41 }
42
43 int color_picker_read_from_line_stream(ColorPicker *color_picker,
44                                        LineStream *line_stream)
45 {
46     char color[7];
47     const char *line = line_stream_next(line_stream);
48     if (line == NULL) {
49         return -1;
50     }
51
52     if (sscanf(line, "%6s", color) == EOF) {
53         log_fail("Could not read color\n");
54     }
55
56     *color_picker = create_color_picker_from_rgba(hexstr(color));
57
58     return 0;
59 }
60
61 int color_picker_render(const ColorPicker *color_picker,
62                         Camera *camera)
63 {
64     trace_assert(color_picker);
65     trace_assert(camera);
66
67     if (camera_fill_rect_screen(
68             camera,
69             rect(0.0f, 0.0f, COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT),
70             color_picker_rgba(color_picker)) < 0) {
71         return -1;
72     }
73
74     for (ColorPickerSlider index = 0; index < COLOR_SLIDER_N; ++index) {
75         const Rect slider_rect =
76             rect(0.0f, (COLOR_SLIDER_HEIGHT + COLOR_SLIDER_PADDING_BOTTOM) * (float) (index + 1),
77                  COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT);
78         const Point label_size = vec(2.5f, 2.5f);
79
80         if (slider_render(
81                 &color_picker->sliders[index],
82                 camera,
83                 slider_rect) < 0) {
84             return -1;
85         }
86
87         if (camera_render_text_screen(
88                 camera,
89                 slider_labels[index],
90                 label_size,
91                 COLOR_BLACK,
92                 vec(slider_rect.x + COLOR_SLIDER_WIDTH,
93                     slider_rect.y + COLOR_SLIDER_HEIGHT * 0.5f - label_size.y * (float) FONT_CHAR_HEIGHT * 0.5f)) < 0) {
94             return -1;
95         }
96     }
97
98     return 0;
99 }
100
101 // TODO(#932): the `selected` event propagation control is cumbersome
102 int color_picker_event(ColorPicker *color_picker, const SDL_Event *event, int *selected_out)
103 {
104     trace_assert(color_picker);
105     trace_assert(event);
106
107     int selected = 0;
108
109     for (ColorPickerSlider index = 0;
110          !selected && index < COLOR_SLIDER_N;
111          ++index) {
112         if (slider_event(
113                 &color_picker->sliders[index],
114                 event,
115                 rect(0.0f, (COLOR_SLIDER_HEIGHT + COLOR_SLIDER_PADDING_BOTTOM) * (float) (index + 1),
116                      COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT),
117                 &selected) < 0) {
118             return -1;
119         }
120     }
121
122     if (selected_out) {
123         *selected_out = selected;
124     }
125
126     return 0;
127 }
128
129 Color color_picker_rgba(const ColorPicker *color_picker)
130 {
131     return hsla(
132         color_picker->sliders[COLOR_SLIDER_HUE].value,
133         color_picker->sliders[COLOR_SLIDER_SAT].value,
134         color_picker->sliders[COLOR_SLIDER_LIT].value,
135         1.0f);
136 }