hex inputs

This commit is contained in:
Ronja 2021-11-26 16:35:58 +01:00
parent 68ab5fb56f
commit 0faa9d2a0a

View file

@ -1,10 +1,11 @@
import "luxe: world" for Entity, UIClear, UILayoutMode, UIBehave, UIContain, Assets, Material, UI, UIEvent, UILayoutBehave
import "luxe: ui" for Control, UIList, UIWindow, UIButton, UIPanel, UIImage, UISlider, UILabel
import "luxe: world" for Entity, UIClear, UILayoutMode, UIBehave, UIContain, Assets, Material, UI, UIEvent, UILayoutBehave, TextAlign
import "luxe: ui" for Control, UIList, UIWindow, UIButton, UIPanel, UIImage, UISlider, UILabel, UIText, UICheck
import "luxe: ui/field/number" for UINumber
import "luxe: id" for ID
import "luxe: draw" for PathStyle
import "luxe: math" for Math
import "luxe: color" for Color
import "luxe: string" for Str
class ColorPickerData {
@ -26,6 +27,9 @@ class ColorPickerData {
rgba{[_r, _g, _b, _a]}
hsva{[_h, _s, _v, _a]}
srgb_hex{_srgb_hex}
srgb_hex=(value){_srgb_hex = value}
toString{"Data - HSV:[%(h), %(s), %(v)] - RGB:[%(r), %(g), %(b)] - A:[%(a)]"}
construct new(){
@ -119,35 +123,31 @@ class ColorPicker{
//setup root
var panel = UIWindow.create(ui)
Control.set_size(panel, 350, 500)
UIWindow.set_resizable(panel, false)
//Control.set_size(panel, 350, 500)
Control.set_contain(panel, UIContain.vfit | UIContain.hfit)
Control.set_id(panel, "panel.%(ID.unique())")
//Control.set_state_data(panel, base_color) //turns out UIWindows use their own state, whoops
var color_view = Control.create(ui)
Control.set_behave(color_view, UIBehave.fill)
//Control.set_behave(color_view, UIBehave.fill)
Control.set_contain(color_view, UIContain.column | UIContain.start | UIContain.vfit | UIContain.hfit)
Control.set_margin(color_view, 0, 40, 0, 0)
Control.child_add(panel, color_view)
Control.set_id(panel, "color_view.%(ID.unique())")
Control.set_state_data(color_view, data)
var hsv_view = Control.create(ui)
Control.set_behave(hsv_view, UIBehave.fill)
Control.set_margin(hsv_view, 0, 0, 0, 0)
Control.set_contain(hsv_view, UIContain.column | UIContain.start)
Control.child_add(color_view, hsv_view)
Control.set_id(panel, "hsv_view.%(ID.unique())")
var wheel = 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(hsv_view, wheel)
Control.child_add(color_view, wheel)
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)
Control.set_margin(component_choice, 8, 8, 0, 0)
Control.set_size(component_choice, 0, 32)
Control.child_add(hsv_view, component_choice)
Control.child_add(color_view, component_choice)
var rgba_button = UIButton.create(ui)
Control.set_behave(rgba_button, UIBehave.left)
@ -160,11 +160,11 @@ class ColorPicker{
Control.child_add(component_choice, hsva_button)
var rgba_components = rgba_values(ui, color_view)
Control.child_add(hsv_view, rgba_components)
Control.child_add(color_view, rgba_components)
var hsva_components = hsva_values(ui, color_view)
Control.set_visible(hsva_components, false)
Control.child_add(hsv_view, hsva_components)
Control.child_add(color_view, hsva_components)
Control.set_events(rgba_button) {|event|
if(event.type == UIEvent.press){
@ -180,11 +180,97 @@ class ColorPicker{
}
}
//todo: next steps: hex input(s?)
var hex_field = hex_input(ui, color_view)
Control.child_add(color_view, hex_field)
var bottom_offset = Control.create(ui)
Control.set_size(bottom_offset, 0, 8)
Control.set_behave(bottom_offset, UIBehave.left)
Control.child_add(color_view, bottom_offset)
return panel
}
static hex_input(ui: UI, data_control: Control){
var data: ColorPickerData = Control.get_state_data(data_control)
var root = Control.create(ui)
Control.set_size(root, 0, 32)
Control.set_contain(root, UIContain.row | UIContain.wrap)
Control.set_behave(root, UIBehave.left | UIBehave.top | UIBehave.vfill)
Control.set_margin(root, 8, 8, 8, 0)
var label = UILabel.create(ui)
Control.set_size(label, 36, 32)
UILabel.set_text(label, "hex")
Control.set_behave(label, UIBehave.left)
Control.child_add(root, label)
var text = UIText.create(ui)
UIText.set_text(text, color_to_hex_string(data.rgba, true))
Control.set_size(text, 128, 32)
Control.set_behave(text, UIBehave.left)
Control.child_add(root, text)
Control.set_events(data_control) {|event|
if(event.type == UIEvent.change){
var data: ColorPickerData = event.change
var color = data.rgba
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)
}
UIText.set_text(text, color_to_hex_string(color, true))
}
}
Control.set_events(text){ |event|
if(event.type == UIEvent.commit){
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)
}
}
}
var srgb_label = UILabel.create(ui)
Control.set_size(srgb_label, 36, 32)
UILabel.set_text(srgb_label, "srgb")
Control.set_behave(srgb_label, UIBehave.left)
Control.set_margin(srgb_label, 8, 0, 0, 0)
Control.child_add(root, srgb_label)
var srgb_toggle = UICheck.create(ui)
Control.set_size(srgb_toggle, 32, 20)
Control.set_behave(srgb_toggle, UIBehave.left)
Control.child_add(root, srgb_toggle)
Control.set_events(data_control) {|event|
if(event.type == UIEvent.change){
var data: ColorPickerData = event.change
UICheck.set_state(srgb_toggle, data.srgb_hex)
}
}
Control.set_events(srgb_toggle){ |event|
if(event.type == UIEvent.change){
var input = event.change
data.srgb_hex = input
UI.events_emit(data_control, UIEvent.change, data)
}
}
return root
}
static rgba_values(ui: UI, color_view: Control) {
var rgba_components = Control.create(ui)
Control.set_contain(rgba_components, UIContain.column | UIContain.hfit | UIContain.vfit)
@ -234,6 +320,7 @@ class ColorPicker{
var label = UILabel.create(ui)
UILabel.set_text(label, name)
UILabel.set_text_size(label, 20)
UILabel.set_align(label, TextAlign.right)
Control.set_size(label, 20, 32)
Control.set_behave(label, UIBehave.left | UIBehave.vfill)
Control.set_margin(label, 8, 0, 8, 0)
@ -496,6 +583,45 @@ class ColorPicker{
return color_wheel
}
static color_to_hex_string(color: Color, alpha: Boolean): String{
var str: String = Str.hex(Color.hex_color(color, alpha))
str = str[2..-1] //remove 0x
while(str.count < (alpha ? 8 : 6)) str = "0" + str //padding
str = "#"+Str.upper(str)
return str
}
static hex_string_to_color(hex_string: String): Color{
//strip prefix
if(hex_string.startsWith("#")) hex_string = hex_string[1..-1]
if(hex_string.startsWith("0x")) hex_string = hex_string[2..-1]
var length = hex_string.count
var number = Num.fromString("0x"+hex_string)
if(!number) return null
var color = [0, 0, 0, 1]
if(length == 3 || length == 4){ //short half-byte notation
if(length == 4) { //with alpha
color.a = (number & 0xF) / 15
number = number >> 4
}
color.r = ((number >> 8) & 0xF) / 15
color.g = ((number >> 4) & 0xF) / 15
color.b = ((number >> 0) & 0xF) / 15
return color
}
if(length == 6 || length == 8){
if(length == 8) { //with alpha
color.a = (number & 0xFF) / 255
number = number >> 8
}
color.r = ((number >> 16) & 0xFF) / 255
color.g = ((number >> 8) & 0xFF) / 255
color.b = ((number >> 0) & 0xFF) / 255
return color
}
return null
}
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)
}