239 lines
No EOL
8.1 KiB
Text
239 lines
No EOL
8.1 KiB
Text
import "luxe: world" for Entity, UIClear, UILayoutMode, UIBehave, UIContain, Assets, Material, UI, UIEvent
|
|
import "luxe: ui" for Control, UIList, UIWindow, UIButton, UIPanel, UIImage
|
|
import "luxe: id" for ID
|
|
import "luxe: draw" for PathStyle
|
|
import "luxe: math" for Math
|
|
import "luxe: color" for Color
|
|
|
|
var Color_spaces = [
|
|
{
|
|
"name": "RGB",
|
|
"components": ["r", "g", "b"],
|
|
"componentsFull": ["Red", "Green", "Blue"],
|
|
},
|
|
{
|
|
"name": "HSV",
|
|
"components": ["h", "s", "v"],
|
|
"componentsFull": ["Hue", "Saturation", "Value"],
|
|
},
|
|
{
|
|
"name": "HSL",
|
|
"components": ["h", "s", "l"],
|
|
"componentsFull": ["Hue", "Saturation", "Lightness"],
|
|
},
|
|
{
|
|
"name": "Oklab",
|
|
"components": ["L", "a", "b"],
|
|
"componentsFull": ["Lightness", "red/green", "blue/yellow"],
|
|
}
|
|
]
|
|
|
|
var Modes = [
|
|
//I wanted to do unicode icons but it doesnt render with the current font
|
|
{
|
|
"name": "Triangle",
|
|
"icon": "tri", //▲
|
|
},
|
|
{
|
|
"name": "Square",
|
|
"icon": "box", //■
|
|
},
|
|
{
|
|
"name": "Circle",
|
|
"icon": "round", //●
|
|
}
|
|
]
|
|
|
|
class ColorPicker{
|
|
static create(ui: Entity) : Control{
|
|
//setup root
|
|
var panel = UIWindow.create(ui)
|
|
Control.set_size(panel, 350, 400)
|
|
Control.set_id(panel, "panel.%(ID.unique())")
|
|
Control.set_state_data(panel, [1, 0, 0, 1])
|
|
|
|
var color_view = Control.create(ui)
|
|
Control.set_behave(color_view, UIBehave.fill)
|
|
Control.set_margin(color_view, 0, 40, 0, 0)
|
|
Control.child_add(panel, color_view)
|
|
Control.set_id(panel, "color_view.%(ID.unique())")
|
|
|
|
var color_wheel = Control.create(ui)
|
|
Control.set_size(color_wheel, 200, 200)
|
|
Control.child_add(color_view, color_wheel)
|
|
Control.set_state_data(color_wheel, {"ring":null, "triangle":null, "hue": 0})
|
|
Control.set_process(color_wheel){|control, state, event, x,y,w,h|
|
|
if(event.control != control) return
|
|
if(event.type == UIEvent.move){
|
|
x = Control.get_pos_x_abs(control)
|
|
y = Control.get_pos_y_abs(control)
|
|
var center = [x + w/2, y + h/2]
|
|
if(state["ring"] == "captured"){
|
|
var diff = [event.x - center.x, event.y - center.y]
|
|
var angle = Math.atan2(-diff.x, diff.y) + Num.pi
|
|
var hue = angle / Num.tau
|
|
|
|
var color = Control.get_state_data(panel)
|
|
var hsv = Color.rgb2hsv(color)
|
|
hsv[0] = hue
|
|
state["hue"] = hue
|
|
color = Color.hsv2rgb(hsv)
|
|
Control.set_state_data(panel, color)
|
|
UI.events_emit(control, UIEvent.change, state)
|
|
UI.events_emit(panel, UIEvent.change, color)
|
|
} else {
|
|
var distance = Math.dist2D(center, event)
|
|
if(distance > 70 && distance < 100){
|
|
state["ring"] = "hover"
|
|
} else {
|
|
state["ring"] = null
|
|
}
|
|
}
|
|
} else if(event.type == UIEvent.press && event.button == 1) {
|
|
if(!state["ring"]) return
|
|
state["ring"] = "captured"
|
|
UI.capture(control)
|
|
} else if(event.type == UIEvent.release && event.button == 1) {
|
|
state["ring"] = null
|
|
UI.uncapture(control)
|
|
}
|
|
}
|
|
Control.set_allow_input(color_wheel, true)
|
|
|
|
var color_ring = UIImage.create(ui)
|
|
Control.set_size(color_ring, 200, 200)
|
|
Control.set_contain(color_ring, UIContain.justify)
|
|
var color_ring_mat = Material.create("materials/color_ring")
|
|
UIImage.set_material(color_ring, color_ring_mat)
|
|
Control.child_add(color_wheel, color_ring)
|
|
|
|
var color_triangle = UIImage.create(ui)
|
|
Control.set_margin(color_triangle, 30, 30, 0, 0)
|
|
Control.set_size(color_triangle, 140, 140)
|
|
Control.set_contain(color_triangle, UIContain.justify)
|
|
var color_tri_mat = Material.create("materials/color_triangle")
|
|
UIImage.set_material(color_triangle, color_tri_mat)
|
|
Control.child_add(color_wheel, color_triangle)
|
|
Control.set_events(color_wheel) {|event|
|
|
if(event.type == UIEvent.change){
|
|
var hue = event.change["hue"]
|
|
UIImage.set_angle(color_triangle, hue * -360)
|
|
Material.set_input(color_tri_mat, "triangle.hue", hue)
|
|
}
|
|
}
|
|
|
|
var color_wheel_overlay = Control.create(ui)
|
|
Control.set_behave(color_wheel_overlay, UIBehave.fill)
|
|
Control.set_margin(color_wheel_overlay, 0, 0, 0, 0)
|
|
Control.set_render(color_wheel_overlay){|control, state, x, y, w, h|
|
|
var depth = UI.draw_depth_of(control, 0)
|
|
var center = [x + w/2, y + h/2]
|
|
var style: PathStyle = PathStyle.new()
|
|
var wheel_state = Control.get_state_data(color_wheel)
|
|
var hover = wheel_state["ring"]
|
|
|
|
var hue = wheel_state["hue"]
|
|
var angle = hue * Num.tau
|
|
var direction = [angle.sin, -angle.cos]
|
|
style.thickness = 4
|
|
style.color = hover ? [0.5,0.5,0.5,1] : [0.22,0.22,0.22,1]
|
|
var from = [center.x + direction.x * 70, center.y + direction.y * 70]
|
|
var to = [center.x + direction.x * 100, center.y + direction.y * 100]
|
|
UI.draw_line(control, from.x, from.y, to.x, to.y, depth, style)
|
|
|
|
style.color = [0.22,0.22,0.22,1]
|
|
style.thickness = 2
|
|
UI.draw_ring(control, center.x, center.y, depth, w/2, h/2, 0, 360, 8, style)
|
|
UI.draw_ring(control, center.x, center.y, depth, w/2*0.7, h/2*0.7, 0, 360, 8, style)
|
|
}
|
|
Control.child_add(color_wheel, color_wheel_overlay)
|
|
|
|
return panel
|
|
|
|
/*
|
|
|
|
//setup colorspace buttons
|
|
//todo: this should be a dropdown???
|
|
var colorspace_list = UIList.create(ui) //could use naked control but logically its a list?
|
|
Control.child_add(root, colorspace_list)
|
|
//base button size is 92x32 btw
|
|
var space_button_height = 30
|
|
var space_button_width = 50
|
|
for(i in 0...Color_spaces.count){
|
|
var space = Color_spaces[i]
|
|
var colorspace_button = UIButton.create(ui)
|
|
Control.set_size(colorspace_button, space_button_width, space_button_height)
|
|
UIList.add(colorspace_list, colorspace_button)
|
|
UIButton.set_text(colorspace_button, space["name"])
|
|
Control.set_pos(colorspace_button, i * space_button_width, 0) //manually set position
|
|
//todo: add event to actually do stuff here
|
|
}
|
|
Control.set_size(colorspace_list, Control.get_width(root).min(space_button_width * Color_spaces.count), space_button_height)
|
|
//UIList.refresh(colorspace_list) //uilist can only do vertical ordering so far :(
|
|
|
|
//setup uimode buttons
|
|
//todo: this should be a dropdown???
|
|
var mode_list = UIList.create(ui)
|
|
Control.child_add(root, mode_list)
|
|
Control.set_pos(mode_list, 0, space_button_height)
|
|
//base button size is 92x32 btw
|
|
var mode_button_height = 30
|
|
var mode_button_width = 50
|
|
for(i in 0...Modes.count){
|
|
var mode = Modes[i]
|
|
var mode_button = UIButton.create(ui)
|
|
Control.set_size(mode_button, mode_button_width, mode_button_height)
|
|
UIList.add(mode_list, mode_button)
|
|
UIButton.set_text(mode_button, mode["icon"])
|
|
Control.set_pos(mode_button, i * mode_button_width, 0) //manually set position
|
|
//todo: add event to actually do stuff here
|
|
}
|
|
Control.set_size(mode_list, Control.get_width(root).min(mode_button_width * Modes.count), mode_button_height)
|
|
|
|
//setup main editor
|
|
var main_editor_root = Control.create(ui)
|
|
Control.child_add(root, main_editor_root)
|
|
Control.set_size(main_editor_root, 200, 200)
|
|
Control.set_pos(main_editor_root, 0, mode_button_height + space_button_height)
|
|
//todo: configurable default editor
|
|
build_triangle_editor(ui, main_editor_root)
|
|
|
|
//setup sliders
|
|
var sliders_root = Control.create(ui)
|
|
Control.child_add(root, sliders_root)
|
|
Control.set_size(sliders_root, 300, 140)
|
|
Control.set_pos(sliders_root, 0, mode_button_height + space_button_height + 200)
|
|
|
|
//setup text input/output
|
|
var text_io_root = Control.create(ui)
|
|
Control.child_add(root, text_io_root)
|
|
Control.set_size(text_io_root, 150, 100)
|
|
Control.set_pos(text_io_root, 200, 160)
|
|
|
|
//setup preview field (old => new)
|
|
var preview_root = Control.create(ui)
|
|
Control.child_add(root, preview_root)
|
|
Control.set_size(preview_root, 150, 100)
|
|
Control.set_pos(preview_root, 200, 60)
|
|
|
|
|
|
//other stuff? gamma/linear? scene color pick? range toggle (0-1/0-255)? HDR??
|
|
//todo
|
|
|
|
return root
|
|
|
|
*/
|
|
}
|
|
|
|
static build_triangle_editor(ui: Entity, root: Control){
|
|
Control.clear(root, UIClear.destroy)
|
|
}
|
|
|
|
static build_square_editor(ui: Entity, root: Control){
|
|
Control.clear(root, UIClear.destroy)
|
|
}
|
|
|
|
static build_circle_editor(ui: Entity, root: Control){
|
|
Control.clear(root, UIClear.destroy)
|
|
}
|
|
} |