]> git.lizzy.rs Git - nothing.git/blob - src/game/level/level_editor/color_picker.c
Delete LineStream from the existance
[nothing.git] / src / game / level / level_editor / color_picker.c
1 #include <stdbool.h>
2 #include <string.h>
3
4 #include "game/level/boxes.h"
5 #include "system/stacktrace.h"
6 #include "system/log.h"
7 #include "game/camera.h"
8 #include "color_picker.h"
9 #include "color.h"
10 #include "undo_history.h"
11
12 #define COLOR_SLIDER_HEIGHT 60.0f
13 #define COLOR_PICKER_WIDTH 300.0f
14 #define COLOR_PICKER_HEIGHT (COLOR_SLIDER_HEIGHT * COLOR_SLIDER_N)
15 #define COLOR_PICKER_REFERENCE 1920.0f
16 #define COLOR_PICKER_HW_RATIO (COLOR_PICKER_HEIGHT/ COLOR_PICKER_WIDTH)
17 #define COLOR_PICKER_WR_RATIO (COLOR_PICKER_WIDTH / COLOR_PICKER_REFERENCE)
18
19 const char *slider_labels[COLOR_SLIDER_N] = {
20     "Hue",
21     "Saturation",
22     "Lightness"
23 };
24
25 ColorPicker create_color_picker_from_rgba(Color color)
26 {
27     Color color_hsla = rgba_to_hsla(color);
28     ColorPicker color_picker = {
29         .sliders = {
30             {0, color_hsla.r, 360.0f},
31             {0, color_hsla.g, 1.0f},
32             {0, color_hsla.b, 1.0f}
33         }
34     };
35     return color_picker;
36 }
37
38 int color_picker_render(const ColorPicker *color_picker,
39                         const Camera *camera)
40 {
41     trace_assert(color_picker);
42     trace_assert(camera);
43
44     const Rect viewport = camera_view_port_screen(camera);
45     const Rect boundary = rect(
46         0.0f, 0.0f,
47         viewport.w * COLOR_PICKER_WR_RATIO,
48         viewport.w * COLOR_PICKER_WR_RATIO * COLOR_PICKER_HW_RATIO);
49
50     const float color_slider_height =
51         boundary.h / (COLOR_SLIDER_N + 1.0f);
52
53     if (camera_fill_rect_screen(
54             camera,
55             rect(boundary.x, boundary.y,
56                  boundary.w, color_slider_height),
57             color_picker_rgba(color_picker)) < 0) {
58         return -1;
59     }
60
61     for (ColorPickerSlider index = 0; index < COLOR_SLIDER_N; ++index) {
62         const Rect slider_rect =
63             rect(boundary.x,
64                  boundary.y + color_slider_height * (float) (index + 1),
65                  boundary.w, color_slider_height);
66         const float font_scale = boundary.w / COLOR_PICKER_WIDTH;
67         const Vec2f label_size = vec(2.5f * font_scale, 2.5f * font_scale);
68
69         if (slider_render(
70                 &color_picker->sliders[index],
71                 camera,
72                 slider_rect) < 0) {
73             return -1;
74         }
75
76         camera_render_text_screen(
77             camera,
78             slider_labels[index],
79             label_size,
80             COLOR_BLACK,
81             vec(slider_rect.x + boundary.w,
82                 slider_rect.y + color_slider_height * 0.5f - label_size.y * (float) FONT_CHAR_HEIGHT * 0.5f));
83     }
84
85     return 0;
86 }
87
88 // TODO(#932): the `selected` event propagation control is cumbersome
89 int color_picker_event(ColorPicker *color_picker,
90                        const SDL_Event *event,
91                        const Camera *camera,
92                        int *selected_out)
93 {
94     trace_assert(color_picker);
95     trace_assert(event);
96     trace_assert(camera);
97
98     int selected = 0;
99
100     const Rect viewport = camera_view_port_screen(camera);
101     const Rect boundary = rect(
102         0.0f, 0.0f,
103         viewport.w * COLOR_PICKER_WR_RATIO,
104         viewport.w * COLOR_PICKER_WR_RATIO * COLOR_PICKER_HW_RATIO);
105
106     const float color_slider_height =
107         boundary.h / (COLOR_SLIDER_N + 1.0f);
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(boundary.x,
116                      boundary.y + color_slider_height * (float) (index + 1),
117                      boundary.w, color_slider_height),
118                 &selected) < 0) {
119             return -1;
120         }
121     }
122
123     if (selected_out) {
124         *selected_out = selected;
125     }
126
127     return 0;
128 }
129
130 Color color_picker_rgba(const ColorPicker *color_picker)
131 {
132     return hsla(
133         color_picker->sliders[COLOR_SLIDER_HUE].value,
134         color_picker->sliders[COLOR_SLIDER_SAT].value,
135         color_picker->sliders[COLOR_SLIDER_LIT].value,
136         1.0f);
137 }