srgb hell

This commit is contained in:
Ronja 2021-11-27 14:48:49 +01:00
parent c5525158cc
commit 73da61d329

View file

@ -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)
}