color displays
This commit is contained in:
parent
0faa9d2a0a
commit
c5525158cc
3 changed files with 252 additions and 39 deletions
224
colorpicker.wren
224
colorpicker.wren
|
|
@ -10,61 +10,70 @@ import "luxe: string" for Str
|
|||
class ColorPickerData {
|
||||
|
||||
//parameters - we could make some of this dynamic if we wanted to
|
||||
triangle_size {35}
|
||||
outer_ring_size {200}
|
||||
inner_ring_size {140}
|
||||
triangle_size:Num {35}
|
||||
outer_ring_size:Num {200}
|
||||
inner_ring_size:Num {140}
|
||||
|
||||
r{_r}
|
||||
g{_g}
|
||||
b{_b}
|
||||
r:Num{_r}
|
||||
g:Num{_g}
|
||||
b:Num{_b}
|
||||
|
||||
h{_h}
|
||||
s{_s}
|
||||
v{_v}
|
||||
h:Num{_h}
|
||||
s:Num{_s}
|
||||
v:Num{_v}
|
||||
|
||||
a{_a}
|
||||
a:Num{_a}
|
||||
|
||||
rgba{[_r, _g, _b, _a]}
|
||||
hsva{[_h, _s, _v, _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 ^^
|
||||
|
||||
srgb_hex{_srgb_hex}
|
||||
srgb_hex=(value){_srgb_hex = value}
|
||||
srgb_hex:Bool{_srgb_hex}
|
||||
srgb_hex=(value:Bool){_srgb_hex = value}
|
||||
|
||||
hdr_multiplier:Num{_hdr_mul}
|
||||
hdr_multiplier=(value:Num){_hdr_mul = value}
|
||||
|
||||
allow_hdr:Bool{_allow_hdr}
|
||||
allow_hdr=(v:Bool){_allow_hdr = v}
|
||||
|
||||
toString{"Data - HSV:[%(h), %(s), %(v)] - RGB:[%(r), %(g), %(b)] - A:[%(a)]"}
|
||||
|
||||
construct new(){
|
||||
_hdr_mul = 1
|
||||
set_rgba(Color.hex(0xFFAABB))
|
||||
}
|
||||
|
||||
set_rgba(col){set_rgba(col, true)}
|
||||
set_rgba(col, update_spaces){
|
||||
if(!ColorPicker.approx(_r, col.r)) _r = col.r
|
||||
if(!ColorPicker.approx(_g, col.g)) _g = col.g
|
||||
if(!ColorPicker.approx(_b, col.b)) _b = col.b
|
||||
if(!ColorPicker.approx(_a, col.a)) _a = col.a
|
||||
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
|
||||
if(!CPHelper.approx(_a, col.a)) _a = col.a
|
||||
|
||||
if(!update_spaces) return
|
||||
|
||||
var hsv = Color.rgb2hsv(col)
|
||||
//be careful not to destroy hue when doing rgb to hsv
|
||||
if(!ColorPicker.approx(_h, hsv.x) && !ColorPicker.approx(_s, 0)) _h = hsv.x
|
||||
if(!ColorPicker.approx(_s, hsv.y)) _s = hsv.y
|
||||
if(!ColorPicker.approx(_v, hsv.z)) _v = hsv.z
|
||||
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(_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){
|
||||
if(!ColorPicker.approx(_h, col.x)) _h = col.x
|
||||
if(!ColorPicker.approx(_s, col.y)) _s = col.y
|
||||
if(!ColorPicker.approx(_v, col.z)) _v = col.z
|
||||
if(!ColorPicker.approx(_a, col.a)) _a = col.a
|
||||
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
|
||||
if(!CPHelper.approx(_a, col.a)) _a = col.a
|
||||
|
||||
if(!update_spaces) return
|
||||
|
||||
var rgb = Color.hsv2rgb(col)
|
||||
if(!ColorPicker.approx(_r, rgb.r)) _r = rgb.r
|
||||
if(!ColorPicker.approx(_g, rgb.g)) _g = rgb.g
|
||||
if(!ColorPicker.approx(_b, rgb.b)) _b = rgb.b
|
||||
if(!CPHelper.approx(_r, rgb.r)) _r = rgb.r
|
||||
if(!CPHelper.approx(_g, rgb.g)) _g = rgb.g
|
||||
if(!CPHelper.approx(_b, rgb.b)) _b = rgb.b
|
||||
}
|
||||
|
||||
set_rgba_component(index: Num, value: Num){
|
||||
|
|
@ -119,7 +128,8 @@ class ColorPickerData {
|
|||
|
||||
class ColorPicker{
|
||||
static create(ui: Entity) : Control{
|
||||
var data = ColorPickerData.new()
|
||||
var data: ColorPickerData = ColorPickerData.new()
|
||||
data.allow_hdr = true
|
||||
|
||||
//setup root
|
||||
var panel = UIWindow.create(ui)
|
||||
|
|
@ -137,10 +147,18 @@ class ColorPicker{
|
|||
Control.set_id(panel, "color_view.%(ID.unique())")
|
||||
Control.set_state_data(color_view, data)
|
||||
|
||||
var wheel = create_hsv_wheel(ui, color_view)
|
||||
var wheel_and_color = Control.create(ui)
|
||||
Control.set_contain(wheel_and_color, UIContain.row | UIContain.hfit | UIContain.vfit | UIContain.start)
|
||||
Control.set_behave(wheel_and_color, UIBehave.left)
|
||||
Control.child_add(color_view, wheel_and_color)
|
||||
|
||||
var wheel = CPHelper.create_hsv_wheel(ui, color_view)
|
||||
Control.set_behave(wheel, UIBehave.left | UIBehave.top)
|
||||
Control.set_margin(wheel, 8, 8, 0, 0)
|
||||
Control.child_add(color_view, wheel)
|
||||
Control.child_add(wheel_and_color, wheel)
|
||||
|
||||
var color_display = CPHelper.color_display(ui, color_view)
|
||||
Control.child_add(wheel_and_color, color_display)
|
||||
|
||||
var component_choice = Control.create(ui)
|
||||
Control.set_contain(component_choice, UIContain.row | UIContain.start)
|
||||
|
|
@ -159,10 +177,10 @@ class ColorPicker{
|
|||
UIButton.set_text(hsva_button, "hsv")
|
||||
Control.child_add(component_choice, hsva_button)
|
||||
|
||||
var rgba_components = rgba_values(ui, color_view)
|
||||
var rgba_components = CPHelper.rgba_values(ui, color_view)
|
||||
Control.child_add(color_view, rgba_components)
|
||||
|
||||
var hsva_components = hsva_values(ui, color_view)
|
||||
var hsva_components = CPHelper.hsva_values(ui, color_view)
|
||||
Control.set_visible(hsva_components, false)
|
||||
Control.child_add(color_view, hsva_components)
|
||||
|
||||
|
|
@ -180,7 +198,7 @@ class ColorPicker{
|
|||
}
|
||||
}
|
||||
|
||||
var hex_field = hex_input(ui, color_view)
|
||||
var hex_field = CPHelper.hex_input(ui, color_view)
|
||||
Control.child_add(color_view, hex_field)
|
||||
|
||||
var bottom_offset = Control.create(ui)
|
||||
|
|
@ -190,6 +208,138 @@ class ColorPicker{
|
|||
|
||||
return panel
|
||||
}
|
||||
}
|
||||
|
||||
#hidden
|
||||
class CPHelper{
|
||||
static color_display(ui: UI, data_control: Control){
|
||||
var data: ColorPickerData = Control.get_state_data(data_control)
|
||||
|
||||
var root = Control.create(ui)
|
||||
Control.set_behave(root, UIBehave.left | UIBehave.top)
|
||||
Control.set_contain(root, UIContain.column | UIContain.start | UIContain.hfit | UIContain.vfit)
|
||||
Control.set_margin(root, 16, 0, 0, 0)
|
||||
|
||||
var color_opaque = UIPanel.create(ui)
|
||||
UIPanel.set_color(color_opaque, data.rgba_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)
|
||||
Control.set_behave(color_opaque, UIBehave.left | UIBehave.top)
|
||||
Control.child_add(root, color_opaque)
|
||||
|
||||
var color_w_trans_bg = Control.create(ui)
|
||||
Control.set_size(color_w_trans_bg, 64, 32)
|
||||
Control.set_margin(color_w_trans_bg, 8, 0, 8, 0)
|
||||
Control.set_behave(color_w_trans_bg, UIBehave.left | UIBehave.top)
|
||||
Control.child_add(root, color_w_trans_bg)
|
||||
|
||||
var color_alpha = UIPanel.create(ui)
|
||||
UIPanel.set_color(color_alpha, data.rgba_ldr)
|
||||
UIPanel.set_border(color_alpha, 0, Color.clear)
|
||||
Control.set_clip(color_alpha, false)
|
||||
Control.set_margin(color_alpha, 0, 0, 0, 0)
|
||||
Control.set_behave(color_alpha, UIBehave.fill)
|
||||
Control.child_add(color_w_trans_bg, color_alpha)
|
||||
|
||||
var alpha_bg = UIImage.create(ui)
|
||||
Control.set_margin(alpha_bg, 0, 0, 0, 0)
|
||||
Control.set_behave(alpha_bg, UIBehave.fill)
|
||||
var alpha_mat = Material.create("materials/transparency_grid")
|
||||
UIImage.set_material(alpha_bg, alpha_mat)
|
||||
Control.child_add(color_w_trans_bg, alpha_bg)
|
||||
|
||||
Control.set_events(data_control){|event|
|
||||
if(event.type == UIEvent.change){
|
||||
var color = data.rgba_ldr
|
||||
UIImage.set_color(alpha_bg, color)
|
||||
color.a = 1
|
||||
UIPanel.set_color(color_alpha, color)
|
||||
UIPanel.set_color(color_opaque, color)
|
||||
}
|
||||
}
|
||||
|
||||
var hdr_header = UILabel.create(ui)
|
||||
UILabel.set_text(hdr_header, "HDR:")
|
||||
UILabel.set_text_size(hdr_header, 14)
|
||||
Control.set_margin(hdr_header, 8, 8, 0, 0)
|
||||
Control.set_behave(hdr_header, UIBehave.left | UIBehave.top)
|
||||
Control.set_size(hdr_header, 64, 32)
|
||||
Control.child_add(root, hdr_header)
|
||||
|
||||
var hdr_mult_label = UILabel.create(ui)
|
||||
UILabel.set_text(hdr_mult_label, "multiplier:")
|
||||
UILabel.set_text_size(hdr_mult_label, 12)
|
||||
UILabel.set_color(hdr_mult_label, [0.8, 0.8, 0.8, 1])
|
||||
Control.set_margin(hdr_mult_label, 8, -10, 0, 0)
|
||||
Control.set_size(hdr_mult_label, 64, 32)
|
||||
Control.set_behave(hdr_mult_label, UIBehave.left | UIBehave.top)
|
||||
Control.child_add(root, hdr_mult_label)
|
||||
|
||||
var hdr_number = UINumber.create(ui)
|
||||
UINumber.set_value(hdr_number, 1)
|
||||
UINumber.set_validation(hdr_number) { |input: Num|
|
||||
return input.max(0)
|
||||
}
|
||||
Control.set_size(hdr_number, 64, 32)
|
||||
Control.set_margin(hdr_number, 8, -4, 0, 0)
|
||||
Control.set_behave(hdr_number, UIBehave.left | UIBehave.top)
|
||||
Control.child_add(root, hdr_number)
|
||||
Control.set_events(hdr_number){|event|
|
||||
if(event.type == UIEvent.change){
|
||||
data.hdr_multiplier = event.change
|
||||
UI.events_emit(data_control, UIEvent.change, data)
|
||||
}
|
||||
}
|
||||
Control.set_events(data_control){|event|
|
||||
if(event.type == UIEvent.change){
|
||||
UINumber.set_value(hdr_number, data.hdr_multiplier)
|
||||
}
|
||||
}
|
||||
|
||||
var color_hdr = UIPanel.create(ui)
|
||||
UIPanel.set_color(color_hdr, data.rgba_ldr)
|
||||
UIPanel.set_border(color_hdr, 0, Color.clear)
|
||||
Control.set_size(color_hdr, 64, 32)
|
||||
Control.set_margin(color_hdr, 8, 4, 8, 0)
|
||||
Control.set_behave(color_hdr, UIBehave.left | UIBehave.top)
|
||||
Control.child_add(root, color_hdr)
|
||||
Control.set_events(data_control){|event|
|
||||
if(event.type == UIEvent.change){
|
||||
var color = data.rgba
|
||||
color.a = 1
|
||||
UIPanel.set_color(color_hdr, color)
|
||||
}
|
||||
}
|
||||
|
||||
var maximize_ldr_button = UIButton.create(ui)
|
||||
UIButton.set_text(maximize_ldr_button, "maximize LDR")
|
||||
UIButton.set_text_size(maximize_ldr_button, 12)
|
||||
Control.set_size(maximize_ldr_button, 80, 24)
|
||||
Control.set_behave(maximize_ldr_button, UIBehave.left | UIBehave.top)
|
||||
Control.set_margin(maximize_ldr_button, 0, 4, 8, 0)
|
||||
Control.child_add(root, maximize_ldr_button)
|
||||
Control.set_events(maximize_ldr_button) {|event|
|
||||
if(event.type == UIEvent.press){
|
||||
if(data.v < 1 && data.v > 0.001){
|
||||
var multiplier = data.hdr_multiplier.min(1/data.v).max(1)
|
||||
data.hdr_multiplier = data.hdr_multiplier / multiplier
|
||||
data.set_hsva_component(2, data.v * multiplier)
|
||||
UI.events_emit(data_control, UIEvent.change, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!data.allow_hdr){
|
||||
Control.set_visible(hdr_header, false)
|
||||
Control.set_visible(hdr_mult_label, false)
|
||||
Control.set_visible(hdr_number, false)
|
||||
Control.set_visible(maximize_ldr_button, false)
|
||||
Control.set_visible(color_hdr, false)
|
||||
}
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
static hex_input(ui: UI, data_control: Control){
|
||||
var data: ColorPickerData = Control.get_state_data(data_control)
|
||||
|
|
@ -207,7 +357,7 @@ class ColorPicker{
|
|||
Control.child_add(root, label)
|
||||
|
||||
var text = UIText.create(ui)
|
||||
UIText.set_text(text, color_to_hex_string(data.rgba, true))
|
||||
UIText.set_text(text, color_to_hex_string(data.rgba_ldr, true))
|
||||
Control.set_size(text, 128, 32)
|
||||
Control.set_behave(text, UIBehave.left)
|
||||
Control.child_add(root, text)
|
||||
|
|
@ -215,7 +365,7 @@ class ColorPicker{
|
|||
Control.set_events(data_control) {|event|
|
||||
if(event.type == UIEvent.change){
|
||||
var data: ColorPickerData = event.change
|
||||
var color = data.rgba
|
||||
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)
|
||||
|
|
@ -531,7 +681,7 @@ class ColorPicker{
|
|||
var style: PathStyle = PathStyle.new()
|
||||
|
||||
var picker_state: ColorPickerData = Control.get_state_data(data_root)
|
||||
var color = picker_state.rgba
|
||||
var color = picker_state.rgba_ldr
|
||||
color.a = 1
|
||||
var hue = picker_state.h
|
||||
var saturation = picker_state.s.pow(1/base_sat_gamma)
|
||||
|
|
|
|||
|
|
@ -22,15 +22,22 @@ input ColorTriangle {
|
|||
float saturation_gamma
|
||||
}
|
||||
|
||||
input TransparencyGrid {
|
||||
float2 grid_size,
|
||||
float4 one_color,
|
||||
float4 other_color
|
||||
}
|
||||
|
||||
stage vertex vert(
|
||||
input { View view },
|
||||
vertex in { #0 float4 pos, #1 float4 color, #2 float2 uv },
|
||||
fragment out { float4 color, float2 uv})
|
||||
fragment out { float4 color, float2 uv, float4 cs_pos})
|
||||
{
|
||||
out.color = in.color;
|
||||
out.uv = in.uv;
|
||||
|
||||
stage.pos = input.view.mvp * float4(in.pos.xyz, 1.0);
|
||||
out.cs_pos = stage.pos;
|
||||
}
|
||||
|
||||
stage fragment frag_color_ring(
|
||||
|
|
@ -102,6 +109,25 @@ stage fragment frag_color_triangle(
|
|||
stage.color[0] = color;
|
||||
}
|
||||
|
||||
stage fragment frag_transparency_grid(
|
||||
input { TransparencyGrid trans_grid, View view },
|
||||
fragment in { float4 color, float2 uv, float4 cs_pos })
|
||||
{
|
||||
float2 uv = in.cs_pos.xy / in.cs_pos.w;
|
||||
uv.x = uv.x * (input.view.resolution.x / input.view.resolution.y);
|
||||
float2 grid = floor(uv * input.trans_grid.grid_size);
|
||||
float3 grid_color = float3(0);
|
||||
float grid_sum = grid.x + grid.y;
|
||||
float grid_mod = mod(grid_sum, 2.0);
|
||||
if(grid_mod == 0.0){
|
||||
grid_color = input.trans_grid.one_color.rgb;
|
||||
} else {
|
||||
grid_color = input.trans_grid.other_color.rgb;
|
||||
}
|
||||
|
||||
stage.color[0] = float4(grid_color, 1.0 - in.color.a);
|
||||
}
|
||||
|
||||
float3 hsv2rgb(float3 hsv){
|
||||
float3 rgb = hue2rgb(hsv.x); //apply hue
|
||||
rgb = mix(float3(1.0), rgb, hsv.y); //apply saturation
|
||||
|
|
@ -117,4 +143,4 @@ float3 hue2rgb(float hue) {
|
|||
float3 rgb = float3(r,g,b); //combine components
|
||||
rgb = clamp(rgb, 0.0, 1.0); //clamp between 0 and 1
|
||||
return rgb;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
37
materials/transparency_grid.material_basis.lx
Normal file
37
materials/transparency_grid.material_basis.lx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
material_basis = {
|
||||
vertex_format = "luxe.textured"
|
||||
shaders = {
|
||||
vertex = { library="materials/shaders" function="vert" }
|
||||
fragment = { library="materials/shaders" function="frag_transparency_grid" }
|
||||
}
|
||||
depth_test = true
|
||||
depth_write = true
|
||||
depth_compare = "less_equal"
|
||||
stencil_test = false
|
||||
write_mask = { red=true green=true blue=true alpha=true }
|
||||
blending = true
|
||||
alpha_blend = "add"
|
||||
rgb_blend = "add"
|
||||
src_alpha = "source_alpha"
|
||||
src_rgb = "source_alpha"
|
||||
dest_alpha = "one_minus_source_alpha"
|
||||
dest_rgb = "one_minus_source_alpha"
|
||||
blend_color = [0 0 0 0]
|
||||
cull = "none"
|
||||
winding = "counter_clockwise"
|
||||
layers = ["default"]
|
||||
inputs = {
|
||||
trans_grid.grid_size = {
|
||||
type = "float2",
|
||||
value = [20, 20]
|
||||
},
|
||||
trans_grid.one_color = {
|
||||
type = "float4",
|
||||
value = [0.8, 0.8, 0.8, 1],
|
||||
},
|
||||
trans_grid.other_color = {
|
||||
type = "float4",
|
||||
value = [1, 1, 1, 1],
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue