From 0faa9d2a0a8872caf41980a7cc877eadb34e82d4 Mon Sep 17 00:00:00 2001 From: Ronja Date: Fri, 26 Nov 2021 16:35:58 +0100 Subject: [PATCH] hex inputs --- colorpicker.wren | 158 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 142 insertions(+), 16 deletions(-) diff --git a/colorpicker.wren b/colorpicker.wren index 354261d..bb84295 100644 --- a/colorpicker.wren +++ b/colorpicker.wren @@ -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) }