import { Slider, HorizontalBox, Button, LineEdit } from "std-widgets.slint"; export component ColourSlider inherits VerticalLayout { spacing: 10px; property hex: "#FF0000"; property base_colour: Colors.red; in-out property final_colour: Colors.red; in-out property colourbox: final_colour; callback hex_to_colour(string) -> color; // required callback set_hex_from_colour(color) -> string; in-out property c1value<=> c1.value; in-out property c2value<=> c2.value; property <[color]> base_colours: [ hsv(0, 1, 1), hsv(10, 1, 1), hsv(20, 1, 1), hsv(30, 1, 1), hsv(40, 1, 1), hsv(50, 1, 1), hsv(60, 1, 1), hsv(70, 1, 1), hsv(80, 1, 1), hsv(90, 1, 1), hsv(100, 1, 1), hsv(110, 1, 1), hsv(120, 1, 1), hsv(130, 1, 1), hsv(140, 1, 1), hsv(150, 1, 1), hsv(160, 1, 1), hsv(170, 1, 1), hsv(180, 1, 1), hsv(190, 1, 1), hsv(200, 1, 1), hsv(210, 1, 1), hsv(220, 1, 1), hsv(230, 1, 1), hsv(240, 1, 1), hsv(250, 1, 1), hsv(260, 1, 1), hsv(270, 1, 1), hsv(280, 1, 1), hsv(290, 1, 1), hsv(300, 1, 1), hsv(310, 1, 1), hsv(320, 1, 1), hsv(330, 1, 1), hsv(340, 1, 1), hsv(350, 1, 1), hsv(360, 1, 1), ]; property <[color]> base_shade: [ blend_lightness(base_colour, 1.0), blend_lightness(base_colour, 0.9), blend_lightness(base_colour, 0.8), blend_lightness(base_colour, 0.7), blend_lightness(base_colour, 0.6), blend_lightness(base_colour, 0.5), blend_lightness(base_colour, 0.4), blend_lightness(base_colour, 0.3), blend_lightness(base_colour, 0.2), blend_lightness(base_colour, 0.1), blend_lightness(base_colour, 0.0) ]; function blend_lightness(c1: color, f: float) -> color { rgb(c1.red * f, c1.green * f, c1.blue * f) } function set_base_colour() { root.base_colour = base_colours[c1.value].interpolate(base_colours[c1.value + 1], c1.value - Math.floor(c1.value)); root.final_colour = blend_lightness(base_colour, ((base_shade.length - c2.value) / base_shade.length)); root.colourbox = root.final_colour; }callback external_colour_change(); external_colour_change => { if (root.final_colour.hue() < 0) { c1.value = (root.base_colours.length - 1) * ((root.final_colour.hue() + 360) / 360); } else { c1.value = (root.base_colours.length - 1) * (root.final_colour.hue() / 360); } c2.value = root.base_shade.length - (root.base_shade.length * root.final_colour.brightness()); root.set_base_colour(); } Rectangle { height: 32px; // 13 colours background: @linear-gradient(90deg, base_colours[0], base_colours[1], base_colours[2], base_colours[3], base_colours[4], base_colours[5], base_colours[6], base_colours[7], base_colours[8], base_colours[9], base_colours[10], base_colours[11], base_colours[12], base_colours[13], base_colours[14], base_colours[15], base_colours[16], base_colours[17], base_colours[18], base_colours[19], base_colours[20], base_colours[21], base_colours[22], base_colours[23], base_colours[24], base_colours[25], base_colours[26], base_colours[27], base_colours[28], base_colours[29], base_colours[30], base_colours[31], base_colours[32], base_colours[33], base_colours[34], base_colours[35]); clip: true; border-radius: 6px; c1 := Slider { width: parent.width; height: parent.height; minimum: 0; maximum: root.base_colours.length - 1; // One less than the array length changed => { set_base_colour(); hex = set_hex_from_colour(final_colour); } } } Rectangle { height: 32px; // 11 colours background: @linear-gradient(90deg, base_shade[0], base_shade[1], base_shade[2], base_shade[3], base_shade[4], base_shade[5], base_shade[6], base_shade[7], base_shade[8], base_shade[9], base_shade[10]); clip: true; border-radius: 6px; c2 := Slider { width: parent.width; height: parent.height; minimum: 0; maximum: 11; changed => { set_base_colour(); hex = set_hex_from_colour(final_colour); } } } HorizontalLayout { LineEdit { // width: 50%; text <=> root.hex; edited => { base_colour = hex_to_colour(self.text); root.colourbox = base_colour; } } Rectangle { width: self.height; background <=> root.colourbox; } } } component ColorButton { callback select<=>i_touch_area.clicked; in property color<=> i_container.background; in property selected; height: self.width; i_container := Rectangle { border_width: 2px; } i_touch_area := TouchArea { } states [ selected when selected: { i_container.border_color: Colors.black; } ] } export component ColorPicker { height: palette.length * 1px / colors_per_row / 1px * color_size; private property selected_color_index; in-out property colors_per_row: 13.0; private property color_size: self.width / colors_per_row; out property selected_color: palette[selected_color_index]; callback selected(color); in property <[color]> palette: [ Colors.rgb(51,0,0), Colors.rgb(51,25,0), Colors.rgb(51,51,0), Colors.rgb(25,51,0), Colors.rgb(0,51,0), Colors.rgb(0,51,25), Colors.rgb(0,51,51), Colors.rgb(0,25,51), Colors.rgb(0,0,51), Colors.rgb(25,0,51), Colors.rgb(51,0,51), Colors.rgb(51,0,25), Colors.rgb(0,0,0), // Colors.rgb(102,0,0), Colors.rgb(102,51,0), Colors.rgb(102,102,0), Colors.rgb(51,102,0), Colors.rgb(0,102,0), Colors.rgb(0,102,51), Colors.rgb(0,102,102), Colors.rgb(0,51,102), Colors.rgb(0,0,102), Colors.rgb(51,0,102), Colors.rgb(102,0,102), Colors.rgb(102,0,51), Colors.rgb(32,32,32), // Colors.rgb(153,0,0), Colors.rgb(153,76,0), Colors.rgb(153,153,0), Colors.rgb(76,153,0), Colors.rgb(0,153,0), Colors.rgb(0,153,76), Colors.rgb(0,153,153), Colors.rgb(0,76,153), Colors.rgb(0,0,153), Colors.rgb(76,0,153), Colors.rgb(153,0,153), Colors.rgb(153,0,76), Colors.rgb(64,64,64), // Colors.rgb(204,0,0), Colors.rgb(204,102,0), Colors.rgb(204,204,0), Colors.rgb(102,204,0), Colors.rgb(0,204,0), Colors.rgb(0,204,102), Colors.rgb(0,204,204), Colors.rgb(0,102,204), Colors.rgb(0,0,204), Colors.rgb(102,0,204), Colors.rgb(204,0,204), Colors.rgb(204,0,102), Colors.rgb(96,96,96), // Colors.rgb(255,0,0), Colors.rgb(255,128,0), Colors.rgb(255,255,0), Colors.rgb(128,255,0), Colors.rgb(0,255,0), Colors.rgb(0,255,128), Colors.rgb(0,255,255), Colors.rgb(0,128,255), Colors.rgb(0,0,255), Colors.rgb(128,0,255), Colors.rgb(255,0,255), Colors.rgb(255,0,128), Colors.rgb(128,128,128), // Colors.rgb(255,51,51), Colors.rgb(255,153,51), Colors.rgb(255,255,51), Colors.rgb(153,255,51), Colors.rgb(51,255,51), Colors.rgb(51,255,153), Colors.rgb(51,255,255), Colors.rgb(51,153,255), Colors.rgb(51,51,255), Colors.rgb(153,51,255), Colors.rgb(255,51,255), Colors.rgb(255,51,153), Colors.rgb(160,160,160), // Colors.rgb(255,102,102), Colors.rgb(255,178,102), Colors.rgb(255,255,102), Colors.rgb(178,255,102), Colors.rgb(102,255,102), Colors.rgb(102,255,178), Colors.rgb(102,255,255), Colors.rgb(102,178,255), Colors.rgb(102,102,255), Colors.rgb(178,102,255), Colors.rgb(255,102,255), Colors.rgb(255,102,178), Colors.rgb(192,192,192), // Colors.rgb(255,153,153), Colors.rgb(255,204,153), Colors.rgb(255,255,153), Colors.rgb(204,255,153), Colors.rgb(153,255,153), Colors.rgb(153,255,204), Colors.rgb(153,255,255), Colors.rgb(153,204,255), Colors.rgb(153,153,255), Colors.rgb(204,153,255), Colors.rgb(255,153,255), Colors.rgb(255,153,204), Colors.rgb(224,224,224), // Colors.rgb(255,204,204), Colors.rgb(255,229,204), Colors.rgb(255,255,204), Colors.rgb(229,255,204), Colors.rgb(204,255,204), Colors.rgb(204,255,229), Colors.rgb(204,255,255), Colors.rgb(204,229,255), Colors.rgb(204,204,255), Colors.rgb(229,204,255), Colors.rgb(255,204,255), Colors.rgb(255,204,229), Colors.rgb(224,224,224), ]; Rectangle { border_width: 1px; border_color: Colors.black; for color[index] in palette: ColorButton { x: color_size * mod(index, colors_per_row); y: color_size * floor(index / colors_per_row); width: color_size; color: color; selected: index == selected_color_index; select => { selected_color_index = index; // debug(Math.mod(selected_color_index, colors_per_row)); // X pos // debug(Math.floor(selected_color_index / colors_per_row)); // Y pos return selected(Math.mod(selected_color_index, colors_per_row) == colors_per_row - 1 ? Colors.rgb(255 / (palette.length / colors_per_row - 1) * Math.floor(selected_color_index / colors_per_row),0,0) : selected_color); } } } }