]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/level/level_editor/color_picker.c
(#788) Additional work
[nothing.git] / src / game / level / level_editor / color_picker.c
index c73bffa442ba915a40d2e65dbfc04b9d257d4310..636e44e3548b111166248f8e947fe360cdeb299c 100644 (file)
 
 #include "game/level/boxes.h"
 #include "system/stacktrace.h"
+#include "system/line_stream.h"
+#include "system/log.h"
 #include "game/camera.h"
 #include "proto_rect.h"
 #include "color_picker.h"
 #include "color.h"
 
-#define COLOR_CELL_WIDTH 50.0f
-#define COLOR_CELL_HEIGHT 50.0f
+#define COLOR_SLIDER_HEIGHT 50.0f
+#define COLOR_SLIDER_WIDTH 300.0f
 
-// TODO(#788): Colors of ColorPicker are poor
-static Color colors[] = {
-    {1.0f, 0.0f, 0.0f, 1.0f},
-    {0.0f, 1.0f, 0.0f, 1.0f},
-    {0.0f, 0.0f, 1.0f, 1.0f}
-};
-static const size_t colors_count = sizeof(colors) / sizeof(Color);
+LayerPtr color_picker_as_layer(ColorPicker *color_picker)
+{
+    LayerPtr layer = {
+        .ptr = color_picker,
+        .type = LAYER_COLOR_PICKER
+    };
+    return layer;
+}
+
+ColorPicker create_color_picker_from_rgba(Color color)
+{
+    Color color_hsla = rgba_to_hsla(color);
+    ColorPicker color_picker = {
+        .hue = {0, color_hsla.r, 360.0f},
+        .saturation = {0, color_hsla.g, 1.0f},
+        .lightness = {0, color_hsla.b, 1.0f}
+    };
+    return color_picker;
+}
+
+int color_picker_read_from_line_stream(ColorPicker *color_picker,
+                                       LineStream *line_stream)
+{
+    char color[7];
+    const char *line = line_stream_next(line_stream);
+    if (line == NULL) {
+        return -1;
+    }
+
+    if (sscanf(line, "%6s", color) == EOF) {
+        log_fail("Could not read color\n");
+    }
+
+    *color_picker = create_color_picker_from_rgba(hexstr(color));
+
+    return 0;
+}
 
+// TODO: Color Picker doesn't have any visual indication about the current color
 int color_picker_render(const ColorPicker *color_picker,
                         Camera *camera)
 {
     trace_assert(color_picker);
     trace_assert(camera);
 
-    for (size_t i = 0; i < colors_count; ++i) {
-        if (camera_fill_rect_screen(
-                camera,
-                rect(COLOR_CELL_WIDTH * (float) i, 0,
-                     COLOR_CELL_WIDTH,
-                     COLOR_CELL_HEIGHT),
-                colors[i]) < 0) {
-            return -1;
-        }
+    /* TODO: Color Picker sliders don't have any labels */
+
+    if (slider_render(
+            &color_picker->hue,
+            camera,
+            rect(0.0f, COLOR_SLIDER_HEIGHT,
+                 COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT)) < 0) {
+        return -1;
     }
 
+    if (slider_render(
+            &color_picker->saturation,
+            camera,
+            rect(0.0f, COLOR_SLIDER_HEIGHT * 2.0f,
+                 COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT)) < 0) {
+        return -1;
+    }
+
+    if (slider_render(
+            &color_picker->lightness,
+            camera,
+            rect(0.0f, COLOR_SLIDER_HEIGHT * 3.0f,
+                 COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT)) < 0) {
+        return -1;
+    }
+
+
     return 0;
 }
 
-int color_picker_mouse_button(ColorPicker *color_picker,
-                              const SDL_MouseButtonEvent *event,
-                              bool *selected)
+// TODO: the `selected` event propagation control is cumbersome
+int color_picker_event(ColorPicker *color_picker, const SDL_Event *event, int *selected_out)
 {
     trace_assert(color_picker);
     trace_assert(event);
 
-    if (event->type == SDL_MOUSEBUTTONDOWN) {
-        switch (event->button) {
-        case SDL_BUTTON_LEFT: {
-            for (size_t i = 0; i < colors_count; ++i) {
-                const Vec mouse_position = vec((float) event->x, (float) event->y);
-                const Rect color_cell =
-                    rect(COLOR_CELL_WIDTH * (float) i, 0,
-                         COLOR_CELL_WIDTH,
-                         COLOR_CELL_HEIGHT);
-                if (rect_contains_point(color_cell, mouse_position)) {
-                    color_picker->color = colors[i];
-                    *selected = true;
-                }
-            }
-        } break;
+    int selected = 0;
+
+    if (slider_event(&color_picker->hue,
+                     event,
+                     rect(0.0f, COLOR_SLIDER_HEIGHT,
+                          COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT),
+                     &selected) < 0) {
+        return -1;
+    }
+
+    if (!selected) {
+        if (slider_event(&color_picker->saturation,
+                         event,
+                         rect(0.0f, COLOR_SLIDER_HEIGHT * 2.0f,
+                              COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT),
+                         &selected) < 0) {
+            return -1;
         }
     }
 
+    if (!selected) {
+        if (slider_event(&color_picker->lightness,
+                         event,
+                         rect(0.0f, COLOR_SLIDER_HEIGHT * 3.0f,
+                              COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT),
+                         &selected) < 0) {
+            return -1;
+        }
+    }
+
+    if (selected_out) {
+        *selected_out = selected;
+    }
+
     return 0;
 }
+
+Color color_picker_rgba(const ColorPicker *color_picker)
+{
+    return hsla(
+        color_picker->hue.value,
+        color_picker->saturation.value,
+        color_picker->lightness.value,
+        1.0f);
+}