From 73da61d329051aa901d2bb22ad978689b4f1e3f3 Mon Sep 17 00:00:00 2001 From: Ronja Date: Sat, 27 Nov 2021 14:48:49 +0100 Subject: [PATCH] srgb hell --- colorpicker.wren | 189 +++++++++++++++++++++++++++-------------------- 1 file changed, 110 insertions(+), 79 deletions(-) diff --git a/colorpicker.wren b/colorpicker.wren index aba9515..3a2016b 100644 --- a/colorpicker.wren +++ b/colorpicker.wren @@ -14,6 +14,7 @@ class ColorPickerData { outer_ring_size:Num {200} inner_ring_size:Num {140} + //raw color components in linear space r:Num{_r} g:Num{_g} b:Num{_b} @@ -24,12 +25,11 @@ class ColorPickerData { a:Num{_a} - rgba:Color{[_hdr_mul * _r, _hdr_mul * _g, _hdr_mul * _b, _a]} - rgba_ldr:Color{[_r , _g, _b, _a]} - hsva:List{[_h, _s, _v, _a]} //almost a color ^^ + color_ldr:Color{get_rgba(false, false)} + color_hdr:Color{get_rgba(false, true)} - srgb_hex:Bool{_srgb_hex} - srgb_hex=(value:Bool){_srgb_hex = value} + srgb:Bool{_srgb_hex} + srgb=(value:Bool){_srgb_hex = value} hdr_multiplier:Num{_hdr_mul} hdr_multiplier=(value:Num){_hdr_mul = value} @@ -44,8 +44,46 @@ class ColorPickerData { set_rgba(Color.hex(0xFFAABB)) } - set_rgba(col){set_rgba(col, true)} - set_rgba(col, update_spaces){ + get_rgba():Color{get_rgba(srgb, allow_hdr)} + get_rgba(srgb: Bool, hdr: Bool):Color{ + var col = [r, g, b, a] + if(srgb){ + CPHelper.apply_srgb(col) + } + if(hdr){ + col.r = col.r * hdr_multiplier + col.g = col.g * hdr_multiplier + col.b = col.b * hdr_multiplier + } + return col + } + + get_hsva_component():Color{get_hsva_component(srgb)} + get_hsva(srgb: Bool):Color{ + var h = _h + var s = _s + var v = _v + var a = _a + + if(srgb){ + //hsv srgb conversion via rgb is the most easy and solid rn + var rgb = [r, g, b, a] + CPHelper.apply_srgb(rgb) + var hsv_srgb = Color.rgb2hsv(rgb) + + if(!CPHelper.approx(v, 0) && !CPHelper.approx(s, 0)) h = hsv_srgb.x + if(!CPHelper.approx(v, 0)) s = hsv_srgb.y + v = hsv_srgb.z + } + + return [h, s, v, a] + } + + set_rgba(col: Color){set_rgba(col, srgb, true)} + set_rgba(col: Color, srgb: Bool){set_rgba(col, srgb, true)} + set_rgba(col: Color, srgb: Bool, update_spaces: Bool){ + if(srgb) CPHelper.unapply_srgb(col) + if(!CPHelper.approx(_r, col.r)) _r = col.r if(!CPHelper.approx(_g, col.g)) _g = col.g if(!CPHelper.approx(_b, col.b)) _b = col.b @@ -55,14 +93,26 @@ class ColorPickerData { var hsv = Color.rgb2hsv(col) //be careful not to destroy hue when doing rgb to hsv - if(!CPHelper.approx(_h, hsv.x) && !CPHelper.approx(_s, 0) && - !CPHelper.approx(_h, hsv.x-1) && !CPHelper.approx(_h, hsv.x+1)) _h = hsv.x + if(!CPHelper.approx(_h, hsv.x) && !CPHelper.approx(hsv.y, 0) && !CPHelper.approx(hsv.z, 0) && + !CPHelper.approx(_h, hsv.x-1) && !CPHelper.approx(_h, hsv.x+1)) _h = hsv.x if(!CPHelper.approx(_s, hsv.y)) _s = hsv.y if(!CPHelper.approx(_v, hsv.z)) _v = hsv.z } - set_hsva(col){set_hsva(col, true)} - set_hsva(col, update_spaces){ + set_hsva(col){set_hsva(col, srgb, true)} + set_hsva(col: Color, srgb: Bool){set_hsva(col, srgb, true)} + set_hsva(col: Color, srgb: Bool, update_spaces: Bool){ + if(srgb){ + //hsv srgb conversion via rgb is the most easy and solid rn + var rgb = Color.hsv2rgb(col) + CPHelper.unapply_srgb(rgb) + var hsv_srgb = Color.rgb2hsv(rgb) + + if(!CPHelper.approx(col.z, 0) && !CPHelper.approx(col.y, 0) && !CPHelper.approx(col.x, 1)) col.x = hsv_srgb.x + if(!CPHelper.approx(col.z, 0)) col.y = hsv_srgb.y + col.z = hsv_srgb.z + } + if(!CPHelper.approx(_h, col.x)) _h = col.x if(!CPHelper.approx(_s, col.y)) _s = col.y if(!CPHelper.approx(_v, col.z)) _v = col.z @@ -77,51 +127,26 @@ class ColorPickerData { } set_rgba_component(index: Num, value: Num){ - if(index == 0){ - set_rgba([value, _g, _b, _a]) - } else if(index == 1){ - set_rgba([_r, value, _b, _a]) - } else if(index == 2){ - set_rgba([_r, _g, value, _a]) - } else if(index == 3){ - set_rgba([_r, _g, _b, value]) - } + var current = get_rgba() + current[index] = value + set_rgba(current) + } + get_rgba_component(index: Num){get_rgba_component(index, srgb, allow_hdr)} + get_rgba_component(index: Num, srgb: Bool){get_rgba_component(index, srgb, false)} + get_rgba_component(index: Num, srgb: Bool, hdr: Bool){ + return get_rgba(srgb, hdr)[index] } - get_rgba_component(index: Num){ - if(index == 0){ - return _r - } else if(index == 1){ - return _g - } else if(index == 2){ - return _b - } else if(index == 3){ - return _a - } + set_hsva_component(index: Num, value: Num){set_hsva_component(index, value, srgb)} + set_hsva_component(index: Num, value: Num, srgb: Bool){ + var current = get_hsva(srgb) + current[index] = value + set_hsva(current, srgb) } - set_hsva_component(index: Num, value: Num){ - if(index == 0){ - set_hsva([value, _s, _v, _a]) - } else if(index == 1){ - set_hsva([_h, value, _v, _a]) - } else if(index == 2){ - set_hsva([_h, _s, value, _a]) - } else if(index == 3){ - set_hsva([_h, _s, _v, value]) - } - } - - get_hsva_component(index: Num){ - if(index == 0){ - return _h - } else if(index == 1){ - return _s - } else if(index == 2){ - return _v - } else if(index == 3){ - return _a - } + get_hsva_component(index: Num){get_hsva_component(index, srgb)} + get_hsva_component(index: Num, srgb: Bool){ + return get_hsva(srgb)[index] } } @@ -160,6 +185,7 @@ class ColorPicker{ var color_display = CPHelper.color_display(ui, color_view) Control.child_add(wheel_and_color, color_display) + //this should be a dropdown var component_choice = Control.create(ui) Control.set_contain(component_choice, UIContain.row | UIContain.start) Control.set_behave(component_choice, UIBehave.hfill | UIBehave.left | UIBehave.top) @@ -221,7 +247,7 @@ class CPHelper{ Control.set_margin(root, 16, 0, 0, 0) var color_opaque = UIPanel.create(ui) - UIPanel.set_color(color_opaque, data.rgba_ldr) + UIPanel.set_color(color_opaque, data.color_ldr) UIPanel.set_border(color_opaque, 0, Color.clear) Control.set_size(color_opaque, 64, 32) Control.set_margin(color_opaque, 8, 8, 8, 0) @@ -235,7 +261,7 @@ class CPHelper{ Control.child_add(root, color_w_trans_bg) var color_alpha = UIPanel.create(ui) - UIPanel.set_color(color_alpha, data.rgba_ldr) + UIPanel.set_color(color_alpha, data.color_ldr) UIPanel.set_border(color_alpha, 0, Color.clear) Control.set_clip(color_alpha, false) Control.set_margin(color_alpha, 0, 0, 0, 0) @@ -251,7 +277,7 @@ class CPHelper{ Control.set_events(data_control){|event| if(event.type == UIEvent.change){ - var color = data.rgba_ldr + var color = data.color_ldr UIImage.set_color(alpha_bg, color) color.a = 1 UIPanel.set_color(color_alpha, color) @@ -298,7 +324,7 @@ class CPHelper{ } var color_hdr = UIPanel.create(ui) - UIPanel.set_color(color_hdr, data.rgba_ldr) + UIPanel.set_color(color_hdr, data.color_hdr) UIPanel.set_border(color_hdr, 0, Color.clear) Control.set_size(color_hdr, 64, 32) Control.set_margin(color_hdr, 8, 4, 8, 0) @@ -306,7 +332,7 @@ class CPHelper{ Control.child_add(root, color_hdr) Control.set_events(data_control){|event| if(event.type == UIEvent.change){ - var color = data.rgba + var color = data.color_hdr color.a = 1 UIPanel.set_color(color_hdr, color) } @@ -357,7 +383,7 @@ class CPHelper{ Control.child_add(root, label) var text = UIText.create(ui) - UIText.set_text(text, color_to_hex_string(data.rgba_ldr, true)) + UIText.set_text(text, color_to_hex_string(data.get_rgba(data.srgb, false), true)) Control.set_size(text, 128, 32) Control.set_behave(text, UIBehave.left) Control.child_add(root, text) @@ -365,12 +391,7 @@ class CPHelper{ Control.set_events(data_control) {|event| if(event.type == UIEvent.change){ var data: ColorPickerData = event.change - var color = data.rgba_ldr - if(data.srgb_hex){ - color.r = color.r.pow(1 / 2.2) - color.g = color.g.pow(1 / 2.2) - color.b = color.b.pow(1 / 2.2) - } + var color = data.get_rgba(data.srgb, false) UIText.set_text(text, color_to_hex_string(color, true)) } } @@ -380,11 +401,6 @@ class CPHelper{ var input = event.change var color = hex_string_to_color(input) if(color){ - if(data.srgb_hex){ - color.r = color.r.pow(2.2) - color.g = color.g.pow(2.2) - color.b = color.b.pow(2.2) - } data.set_rgba(color) UI.events_emit(data_control, UIEvent.change, data) } @@ -406,14 +422,14 @@ class CPHelper{ Control.set_events(data_control) {|event| if(event.type == UIEvent.change){ var data: ColorPickerData = event.change - UICheck.set_state(srgb_toggle, data.srgb_hex) + UICheck.set_state(srgb_toggle, data.srgb) } } Control.set_events(srgb_toggle){ |event| if(event.type == UIEvent.change){ var input = event.change - data.srgb_hex = input + data.srgb = input UI.events_emit(data_control, UIEvent.change, data) } } @@ -517,19 +533,20 @@ class CPHelper{ Control.set_events(color_view){|event| if(event.type == UIEvent.change){ + var data: ColorPickerData = event.change if(space == "rgb"){ - UISlider.set_value(slider, Math.fixed(event.change.get_rgba_component(index))) - UINumber.set_value(number, Math.fixed(event.change.get_rgba_component(index))) + UISlider.set_value(slider, Math.fixed(data.get_rgba_component(index))) + UINumber.set_value(number, Math.fixed(data.get_rgba_component(index))) } else if(space == "hsv"){ - UISlider.set_value(slider, Math.fixed(event.change.get_hsva_component(index))) - UINumber.set_value(number, Math.fixed(event.change.get_hsva_component(index))) + UISlider.set_value(slider, Math.fixed(data.get_hsva_component(index))) + UINumber.set_value(number, Math.fixed(data.get_hsva_component(index))) } } } Control.set_events(base) {|event| if(event.type == UIEvent.change){ - var color = Control.get_state_data(color_view) + var color: ColorPickerData = Control.get_state_data(color_view) if(space == "rgb"){ if(approx(event.change, color.get_rgba_component(index))) return color.set_rgba_component(index, event.change) @@ -571,7 +588,7 @@ class CPHelper{ //change relevant values var picker_state: ColorPickerData = Control.get_state_data(data_root) var hsv = [hue, picker_state.s, picker_state.v, picker_state.a] - picker_state.set_hsva(hsv) + picker_state.set_hsva(hsv, false) UI.events_emit(data_root, UIEvent.change, picker_state) } else if(state["triangle"] == "captured"){ //if we're editing the triangle (saturation & value) var picker_state: ColorPickerData = Control.get_state_data(data_root) @@ -596,7 +613,7 @@ class CPHelper{ //calculate and apply relevant values var hsv = [picker_state.h, saturation, value, picker_state.a] - picker_state.set_hsva(hsv) + picker_state.set_hsva(hsv, false) UI.events_emit(data_root, UIEvent.change, picker_state) } else { //if we're not editing anything, lets check what we're hovering over! var picker_state: ColorPickerData = Control.get_state_data(data_root) @@ -681,7 +698,7 @@ class CPHelper{ var style: PathStyle = PathStyle.new() var picker_state: ColorPickerData = Control.get_state_data(data_root) - var color = picker_state.rgba_ldr + var color = picker_state.color_ldr color.a = 1 var hue = picker_state.h var saturation = picker_state.s.pow(1/base_sat_gamma) @@ -772,6 +789,20 @@ class CPHelper{ return null } + static apply_srgb(col: Color){ + col.r = col.r.pow(1 / 2.2) + col.g = col.g.pow(1 / 2.2) + col.b = col.b.pow(1 / 2.2) + //no alpha change + } + + static unapply_srgb(col:Color){ + col.r = col.r.pow(2.2) + col.g = col.g.pow(2.2) + col.b = col.b.pow(2.2) + //no alpha change + } + static approx_rgb(one: Color, other: Color, epsilson: Num) : Bool{ return approx(one.x, other.x, epsilson) && approx(one.y, other.y, epsilson) && approx(one.z, other.z, epsilson) }