]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/level/level_editor/color_picker.c
(#1050) Replace system clipboard with internal one
[nothing.git] / src / game / level / level_editor / color_picker.c
index abbc92bccf32faf14d278bd6040ae21bb40bf8cf..6ed915c27cfb5740b177fada915af3699d9fe55d 100644 (file)
@@ -1,33 +1,38 @@
 #include <stdbool.h>
+#include <string.h>
 
 #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_SLIDER_HEIGHT 50.0f
-#define COLOR_SLIDER_WIDTH 300.0f
-
-LayerPtr color_picker_as_layer(ColorPicker *color_picker)
-{
-    LayerPtr layer = {
-        .ptr = color_picker,
-        .type = LAYER_COLOR_PICKER
-    };
-    return layer;
-}
+#include "undo_history.h"
+
+// TODO(#1021): ColorPicker doesn't have any padding between the sliders
+#define COLOR_SLIDER_HEIGHT 60.0f
+#define COLOR_PICKER_WIDTH 300.0f
+#define COLOR_PICKER_HEIGHT (COLOR_SLIDER_HEIGHT * COLOR_SLIDER_N)
+#define COLOR_PICKER_REFERENCE 1920.0f
+#define COLOR_PICKER_HW_RATIO (COLOR_PICKER_HEIGHT/ COLOR_PICKER_WIDTH)
+#define COLOR_PICKER_WR_RATIO (COLOR_PICKER_WIDTH / COLOR_PICKER_REFERENCE)
+
+const char *slider_labels[COLOR_SLIDER_N] = {
+    "Hue",
+    "Saturation",
+    "Lightness"
+};
 
 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}
+        .sliders = {
+            {0, color_hsla.r, 360.0f},
+            {0, color_hsla.g, 1.0f},
+            {0, color_hsla.b, 1.0f}
+        }
     };
     return color_picker;
 }
@@ -50,75 +55,89 @@ int color_picker_read_from_line_stream(ColorPicker *color_picker,
     return 0;
 }
 
-// TODO(#930): 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);
 
-    /* TODO(#931): Color Picker sliders don't have any labels */
+    const Rect viewport = camera_view_port_screen(camera);
+    const Rect boundary = rect(
+        0.0f, 0.0f,
+        viewport.w * COLOR_PICKER_WR_RATIO,
+        viewport.w * COLOR_PICKER_WR_RATIO * COLOR_PICKER_HW_RATIO);
 
-    if (slider_render(
-            &color_picker->hue,
-            camera,
-            rect(0.0f, COLOR_SLIDER_HEIGHT,
-                 COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT)) < 0) {
-        return -1;
-    }
+    const float color_slider_height =
+        boundary.h / (COLOR_SLIDER_N + 1.0f);
 
-    if (slider_render(
-            &color_picker->saturation,
+    if (camera_fill_rect_screen(
             camera,
-            rect(0.0f, COLOR_SLIDER_HEIGHT * 2.0f,
-                 COLOR_SLIDER_WIDTH, COLOR_SLIDER_HEIGHT)) < 0) {
+            rect(boundary.x, boundary.y,
+                 boundary.w, color_slider_height),
+            color_picker_rgba(color_picker)) < 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;
-    }
+    for (ColorPickerSlider index = 0; index < COLOR_SLIDER_N; ++index) {
+        const Rect slider_rect =
+            rect(boundary.x,
+                 boundary.y + color_slider_height * (float) (index + 1),
+                 boundary.w, color_slider_height);
+        const float font_scale = boundary.w / COLOR_PICKER_WIDTH;
+        const Point label_size = vec(2.5f * font_scale, 2.5f * font_scale);
+
+        if (slider_render(
+                &color_picker->sliders[index],
+                camera,
+                slider_rect) < 0) {
+            return -1;
+        }
 
+        if (camera_render_text_screen(
+                camera,
+                slider_labels[index],
+                label_size,
+                COLOR_BLACK,
+                vec(slider_rect.x + boundary.w,
+                    slider_rect.y + color_slider_height * 0.5f - label_size.y * (float) FONT_CHAR_HEIGHT * 0.5f)) < 0) {
+            return -1;
+        }
+    }
 
     return 0;
 }
 
-// TODO: the `selected` event propagation control is cumbersome
-int color_picker_event(ColorPicker *color_picker, const SDL_Event *event, int *selected_out)
+// TODO(#932): the `selected` event propagation control is cumbersome
+int color_picker_event(ColorPicker *color_picker,
+                       const SDL_Event *event,
+                       const Camera *camera,
+                       int *selected_out)
 {
     trace_assert(color_picker);
     trace_assert(event);
+    trace_assert(camera);
 
     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) {
+    const Rect viewport = camera_view_port_screen(camera);
+    const Rect boundary = rect(
+        0.0f, 0.0f,
+        viewport.w * COLOR_PICKER_WR_RATIO,
+        viewport.w * COLOR_PICKER_WR_RATIO * COLOR_PICKER_HW_RATIO);
+
+    const float color_slider_height =
+        boundary.h / (COLOR_SLIDER_N + 1.0f);
+
+    for (ColorPickerSlider index = 0;
+         !selected && index < COLOR_SLIDER_N;
+         ++index) {
+        if (slider_event(
+                &color_picker->sliders[index],
+                event,
+                rect(boundary.x,
+                     boundary.y + color_slider_height * (float) (index + 1),
+                     boundary.w, color_slider_height),
+                &selected) < 0) {
             return -1;
         }
     }
@@ -133,8 +152,8 @@ int color_picker_event(ColorPicker *color_picker, const SDL_Event *event, int *s
 Color color_picker_rgba(const ColorPicker *color_picker)
 {
     return hsla(
-        color_picker->hue.value,
-        color_picker->saturation.value,
-        color_picker->lightness.value,
+        color_picker->sliders[COLOR_SLIDER_HUE].value,
+        color_picker->sliders[COLOR_SLIDER_SAT].value,
+        color_picker->sliders[COLOR_SLIDER_LIT].value,
         1.0f);
 }