From 664a63a4b8c1b0b945ca45b1181ead040a12fa73 Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Thu, 2 Apr 2020 17:52:21 -0500 Subject: Add example program: color palette Sliders for many color spaces update as any other sliders are moved around. Color is space is clamped to sRGB, so Lab and Lch color spaces cannot be fully expressed. TODO: - Real-time manipulation of base color to create a color scheme. - Show slider value under each slider - Show output values in text boxes for each color space --- examples/color_palette/Cargo.toml | 14 +++ examples/color_palette/README.md | 9 ++ examples/color_palette/src/main.rs | 250 +++++++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+) create mode 100644 examples/color_palette/Cargo.toml create mode 100644 examples/color_palette/README.md create mode 100644 examples/color_palette/src/main.rs (limited to 'examples') diff --git a/examples/color_palette/Cargo.toml b/examples/color_palette/Cargo.toml new file mode 100644 index 00000000..0ad6708c --- /dev/null +++ b/examples/color_palette/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "color_palette" +version = "0.1.0" +authors = ["Clark Moody "] +edition = "2018" +publish = false + +[features] +palette = [] + +[dependencies] +iced = { path = "../..", features = ["palette"] } +iced_core = { path = "../../core" } +iced_native = { path = "../../native" } diff --git a/examples/color_palette/README.md b/examples/color_palette/README.md new file mode 100644 index 00000000..b646f3b3 --- /dev/null +++ b/examples/color_palette/README.md @@ -0,0 +1,9 @@ +## Color Palette + +A color palette generator, based on a user-defined root color. + +You can run it with `cargo run`: + +``` +cargo run --package color_palette +``` diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs new file mode 100644 index 00000000..1c9fffbc --- /dev/null +++ b/examples/color_palette/src/main.rs @@ -0,0 +1,250 @@ +use iced::{ + slider, Color, Column, Element, Row, Sandbox, Settings, Slider, Text, +}; +use iced_core::palette::{self, Limited}; + +pub fn main() { + ColorPalette::run(Settings::default()) +} + +#[derive(Default)] +pub struct ColorPalette { + base_color: Color, + rgb_sliders: [slider::State; 3], + hsl_sliders: [slider::State; 3], + hsv_sliders: [slider::State; 3], + hwb_sliders: [slider::State; 3], + lab_sliders: [slider::State; 3], + lch_sliders: [slider::State; 3], +} + +#[derive(Debug, Clone, Copy)] +pub enum Message { + RgbColorChanged(Color), + HslColorChanged(palette::Hsl), + HsvColorChanged(palette::Hsv), + HwbColorChanged(palette::Hwb), + LabColorChanged(palette::Lab), + LchColorChanged(palette::Lch), +} + +impl Sandbox for ColorPalette { + type Message = Message; + + fn new() -> Self { + let mut s = Self::default(); + s.base_color = Color::from_rgb8(27, 135, 199); + s + } + + fn title(&self) -> String { + String::from("Color Palette") + } + + fn update(&mut self, message: Message) { + let mut srgb = match message { + Message::RgbColorChanged(rgb) => palette::Srgb::from(rgb), + Message::HslColorChanged(hsl) => palette::Srgb::from(hsl), + Message::HsvColorChanged(hsv) => palette::Srgb::from(hsv), + Message::HwbColorChanged(hwb) => palette::Srgb::from(hwb), + Message::LabColorChanged(lab) => palette::Srgb::from(lab), + Message::LchColorChanged(lch) => palette::Srgb::from(lch), + }; + srgb.clamp_self(); + self.base_color = Color::from(srgb); + } + + fn view(&mut self) -> Element { + let [rgb1, rgb2, rgb3] = &mut self.rgb_sliders; + let [hsl1, hsl2, hsl3] = &mut self.hsl_sliders; + let [hsv1, hsv2, hsv3] = &mut self.hsv_sliders; + let [hwb1, hwb2, hwb3] = &mut self.hwb_sliders; + let [lab1, lab2, lab3] = &mut self.lab_sliders; + let [lch1, lch2, lch3] = &mut self.lch_sliders; + + let color = self.base_color; + let srgb = palette::Srgb::from(self.base_color); + let hsl = palette::Hsl::from(srgb); + let hsv = palette::Hsv::from(srgb); + let hwb = palette::Hwb::from(srgb); + let lab = palette::Lab::from(srgb); + let lch = palette::Lch::from(srgb); + + Column::new() + .padding(20) + .spacing(20) + .push( + Row::new() + .spacing(10) + .push(Text::new("RGB")) + .push(Slider::new(rgb1, 0.0..=1.0, color.r, move |r| { + Message::RgbColorChanged(Color { r, ..color }) + })) + .push(Slider::new(rgb2, 0.0..=1.0, color.g, move |g| { + Message::RgbColorChanged(Color { g, ..color }) + })) + .push(Slider::new(rgb3, 0.0..=1.0, color.b, move |b| { + Message::RgbColorChanged(Color { b, ..color }) + })), + ) + .push( + Row::new() + .spacing(10) + .push(Text::new("HSL")) + .push(Slider::new( + hsl1, + 0.0..=360.0, + hsl.hue.to_positive_degrees(), + move |hue| { + Message::HslColorChanged(palette::Hsl { + hue: palette::RgbHue::from_degrees(hue), + ..hsl + }) + }, + )) + .push(Slider::new( + hsl2, + 0.0..=1.0, + hsl.saturation, + move |saturation| { + Message::HslColorChanged(palette::Hsl { + saturation, + ..hsl + }) + }, + )) + .push(Slider::new( + hsl3, + 0.0..=1.0, + hsl.lightness, + move |lightness| { + Message::HslColorChanged(palette::Hsl { + lightness, + ..hsl + }) + }, + )), + ) + .push( + Row::new() + .spacing(10) + .push(Text::new("HSV")) + .push(Slider::new( + hsv1, + 0.0..=360.0, + hsv.hue.to_positive_degrees(), + move |hue| { + Message::HsvColorChanged(palette::Hsv { + hue: palette::RgbHue::from_degrees(hue), + ..hsv + }) + }, + )) + .push(Slider::new( + hsv2, + 0.0..=1.0, + hsv.saturation, + move |saturation| { + Message::HsvColorChanged(palette::Hsv { + saturation, + ..hsv + }) + }, + )) + .push(Slider::new( + hsv3, + 0.0..=1.0, + hsv.value, + move |value| { + Message::HsvColorChanged(palette::Hsv { + value, + ..hsv + }) + }, + )), + ) + .push( + Row::new() + .spacing(10) + .push(Text::new("HWB")) + .push(Slider::new( + hwb1, + 0.0..=360.0, + hwb.hue.to_positive_degrees(), + move |hue| { + Message::HwbColorChanged(palette::Hwb { + hue: palette::RgbHue::from_degrees(hue), + ..hwb + }) + }, + )) + .push(Slider::new( + hwb2, + 0.0..=1.0, + hwb.whiteness, + move |whiteness| { + Message::HwbColorChanged(palette::Hwb { + whiteness, + ..hwb + }) + }, + )) + .push(Slider::new( + hwb3, + 0.0..=1.0, + hwb.blackness, + move |blackness| { + Message::HwbColorChanged(palette::Hwb { + blackness, + ..hwb + }) + }, + )), + ) + .push( + Row::new() + .spacing(10) + .push(Text::new("Lab")) + .push(Slider::new(lab1, 0.0..=100.0, lab.l, move |l| { + Message::LabColorChanged(palette::Lab { l, ..lab }) + })) + .push(Slider::new(lab2, -128.0..=127.0, lab.a, move |a| { + Message::LabColorChanged(palette::Lab { a, ..lab }) + })) + .push(Slider::new(lab3, -128.0..=127.0, lab.b, move |b| { + Message::LabColorChanged(palette::Lab { b, ..lab }) + })), + ) + .push( + Row::new() + .spacing(10) + .push(Text::new("Lch")) + .push(Slider::new(lch1, 0.0..=100.0, lch.l, move |l| { + Message::LchColorChanged(palette::Lch { l, ..lch }) + })) + .push(Slider::new( + lch2, + 0.0..=128.0, + lch.chroma, + move |chroma| { + Message::LchColorChanged(palette::Lch { + chroma, + ..lch + }) + }, + )) + .push(Slider::new( + lch3, + 0.0..=360.0, + lch.hue.to_positive_degrees(), + move |hue| { + Message::LchColorChanged(palette::Lch { + hue: palette::LabHue::from_degrees(hue), + ..lch + }) + }, + )), + ) + .into() + } +} -- cgit From 6b18e78e535d50f648bd5ba739eb29b3c76a7965 Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Wed, 8 Apr 2020 17:45:54 -0500 Subject: Use canvas to draw color palette for example --- examples/color_palette/Cargo.toml | 2 +- examples/color_palette/src/main.rs | 106 +++++++++++++++++++++++++++++++++---- 2 files changed, 98 insertions(+), 10 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/Cargo.toml b/examples/color_palette/Cargo.toml index 0ad6708c..ad7a0114 100644 --- a/examples/color_palette/Cargo.toml +++ b/examples/color_palette/Cargo.toml @@ -9,6 +9,6 @@ publish = false palette = [] [dependencies] -iced = { path = "../..", features = ["palette"] } +iced = { path = "../..", features = ["canvas", "palette"] } iced_core = { path = "../../core" } iced_native = { path = "../../native" } diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 1c9fffbc..267cc58c 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -1,5 +1,6 @@ use iced::{ - slider, Color, Column, Element, Row, Sandbox, Settings, Slider, Text, + canvas, slider, Canvas, Color, Column, Element, Length, Point, Row, + Sandbox, Settings, Slider, Text, }; use iced_core::palette::{self, Limited}; @@ -7,15 +8,39 @@ pub fn main() { ColorPalette::run(Settings::default()) } -#[derive(Default)] +#[derive(Debug, Default)] +pub struct State { + color: Color, + theme: Vec, +} + +fn generate_theme(base_color: &Color) -> Vec { + use palette::{Hsl, Hue, Shade, Srgb}; + let mut theme = Vec::::new(); + // Convert to linear color for manipulation + let srgb = Srgb::from(*base_color); + + let hsl = Hsl::from(srgb); + + theme.push(Srgb::from(hsl.shift_hue(-120.0)).clamp().into()); + theme.push(Srgb::from(hsl.shift_hue(-115.0).darken(0.075)).clamp().into()); + theme.push(Srgb::from(hsl.darken(0.075)).clamp().into()); + theme.push(*base_color); + theme.push(Srgb::from(hsl.lighten(0.075)).clamp().into()); + theme.push(Srgb::from(hsl.shift_hue(115.0).darken(0.075)).clamp().into()); + theme.push(Srgb::from(hsl.shift_hue(120.0)).clamp().into()); + theme +} + pub struct ColorPalette { - base_color: Color, + state: State, rgb_sliders: [slider::State; 3], hsl_sliders: [slider::State; 3], hsv_sliders: [slider::State; 3], hwb_sliders: [slider::State; 3], lab_sliders: [slider::State; 3], lch_sliders: [slider::State; 3], + canvas_layer: canvas::layer::Cache, } #[derive(Debug, Clone, Copy)] @@ -32,9 +57,24 @@ impl Sandbox for ColorPalette { type Message = Message; fn new() -> Self { - let mut s = Self::default(); - s.base_color = Color::from_rgb8(27, 135, 199); - s + fn triple_slider() -> [slider::State; 3] { + [ + slider::State::new(), + slider::State::new(), + slider::State::new(), + ] + } + + ColorPalette { + state: State::new(), + rgb_sliders: triple_slider(), + hsl_sliders: triple_slider(), + hsv_sliders: triple_slider(), + hwb_sliders: triple_slider(), + lab_sliders: triple_slider(), + lch_sliders: triple_slider(), + canvas_layer: canvas::layer::Cache::new(), + } } fn title(&self) -> String { @@ -51,7 +91,11 @@ impl Sandbox for ColorPalette { Message::LchColorChanged(lch) => palette::Srgb::from(lch), }; srgb.clamp_self(); - self.base_color = Color::from(srgb); + self.canvas_layer.clear(); + self.state.color = Color::from(srgb); + + // Set theme colors + self.state.theme = generate_theme(&self.state.color); } fn view(&mut self) -> Element { @@ -62,8 +106,8 @@ impl Sandbox for ColorPalette { let [lab1, lab2, lab3] = &mut self.lab_sliders; let [lch1, lch2, lch3] = &mut self.lch_sliders; - let color = self.base_color; - let srgb = palette::Srgb::from(self.base_color); + let color = self.state.color; + let srgb = palette::Srgb::from(self.state.color); let hsl = palette::Hsl::from(srgb); let hsv = palette::Hsv::from(srgb); let hwb = palette::Hwb::from(srgb); @@ -245,6 +289,50 @@ impl Sandbox for ColorPalette { }, )), ) + .push( + Canvas::new() + .width(Length::Fill) + .height(Length::Units(150)) + .push(self.canvas_layer.with(&self.state)), + ) .into() } } + +impl State { + pub fn new() -> State { + let base = Color::from_rgb8(27, 135, 199); + State { + color: base, + theme: generate_theme(&base), + } + } +} + +impl canvas::Drawable for State { + fn draw(&self, frame: &mut canvas::Frame) { + use canvas::{Fill, Path}; + if self.theme.len() == 0 { + println!("Zero len"); + return; + } + + let box_width = frame.width() / self.theme.len() as f32; + for i in 0..self.theme.len() { + let anchor = Point { + x: (i as f32) * box_width, + y: 0.0, + }; + let rect = Path::new(|path| { + path.move_to(anchor); + path.line_to(Point { x: anchor.x + box_width, y: anchor.y }); + path.line_to(Point { + x: anchor.x + box_width, + y: anchor.y + frame.height(), + }); + path.line_to(Point { x: anchor.x, y: anchor.y + frame.height() }); + }); + frame.fill(&rect, Fill::Color(self.theme[i])); + } + } +} -- cgit From b1328f193cceb803e81e59230ff4ca89072ef5a5 Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Thu, 9 Apr 2020 13:11:39 -0500 Subject: More theme colors and gradient of lightness --- examples/color_palette/src/main.rs | 76 +++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 9 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 267cc58c..f7918df4 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -17,18 +17,34 @@ pub struct State { fn generate_theme(base_color: &Color) -> Vec { use palette::{Hsl, Hue, Shade, Srgb}; let mut theme = Vec::::new(); - // Convert to linear color for manipulation - let srgb = Srgb::from(*base_color); - - let hsl = Hsl::from(srgb); + // Convert to HSL color for manipulation + let hsl = Hsl::from(Srgb::from(*base_color)); + theme.push( + Srgb::from(hsl.shift_hue(-135.0).lighten(0.075)) + .clamp() + .into(), + ); theme.push(Srgb::from(hsl.shift_hue(-120.0)).clamp().into()); - theme.push(Srgb::from(hsl.shift_hue(-115.0).darken(0.075)).clamp().into()); + theme.push( + Srgb::from(hsl.shift_hue(-105.0).darken(0.075)) + .clamp() + .into(), + ); theme.push(Srgb::from(hsl.darken(0.075)).clamp().into()); theme.push(*base_color); theme.push(Srgb::from(hsl.lighten(0.075)).clamp().into()); - theme.push(Srgb::from(hsl.shift_hue(115.0).darken(0.075)).clamp().into()); + theme.push( + Srgb::from(hsl.shift_hue(105.0).darken(0.075)) + .clamp() + .into(), + ); theme.push(Srgb::from(hsl.shift_hue(120.0)).clamp().into()); + theme.push( + Srgb::from(hsl.shift_hue(135.0).lighten(0.075)) + .clamp() + .into(), + ); theme } @@ -312,12 +328,17 @@ impl State { impl canvas::Drawable for State { fn draw(&self, frame: &mut canvas::Frame) { use canvas::{Fill, Path}; + use palette::{Hsl, Srgb}; + if self.theme.len() == 0 { println!("Zero len"); return; } + let pad = 5.0; + let box_width = frame.width() / self.theme.len() as f32; + let box_height = frame.height() / 2.0 - pad; for i in 0..self.theme.len() { let anchor = Point { x: (i as f32) * box_width, @@ -325,14 +346,51 @@ impl canvas::Drawable for State { }; let rect = Path::new(|path| { path.move_to(anchor); - path.line_to(Point { x: anchor.x + box_width, y: anchor.y }); path.line_to(Point { x: anchor.x + box_width, - y: anchor.y + frame.height(), + y: anchor.y, + }); + path.line_to(Point { + x: anchor.x + box_width, + y: anchor.y + box_height, + }); + path.line_to(Point { + x: anchor.x, + y: anchor.y + box_height, }); - path.line_to(Point { x: anchor.x, y: anchor.y + frame.height() }); }); frame.fill(&rect, Fill::Color(self.theme[i])); } + + let hsl = Hsl::from(Srgb::from(self.color)); + for i in 0..self.theme.len() { + let pct = (i as f32 + 1.0) / (self.theme.len() as f32 + 1.0); + let graded = Hsl { + lightness: 1.0 - pct, + ..hsl + }; + let color: Color = Srgb::from(graded.clamp()).into(); + + let anchor = Point { + x: (i as f32) * box_width, + y: box_height + 2.0 * pad, + }; + let rect = Path::new(|path| { + path.move_to(anchor); + path.line_to(Point { + x: anchor.x + box_width, + y: anchor.y, + }); + path.line_to(Point { + x: anchor.x + box_width, + y: anchor.y + box_height, + }); + path.line_to(Point { + x: anchor.x, + y: anchor.y + box_height, + }); + }); + frame.fill(&rect, Fill::Color(color)); + } } } -- cgit From 39fd8ad9e973b8f6ec9e4e4d08f4e8aca72b069e Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Thu, 9 Apr 2020 17:49:29 -0500 Subject: TextInput fields with color encodings. Draw shades. --- examples/color_palette/src/main.rs | 287 ++++++++++++++++++++++++++++++++++--- 1 file changed, 266 insertions(+), 21 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index f7918df4..fc733787 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -1,11 +1,14 @@ use iced::{ - canvas, slider, Canvas, Color, Column, Element, Length, Point, Row, - Sandbox, Settings, Slider, Text, + canvas, slider, text_input, Canvas, Color, Column, Element, Length, Point, + Row, Sandbox, Settings, Slider, Text, TextInput, }; use iced_core::palette::{self, Limited}; pub fn main() { - ColorPalette::run(Settings::default()) + ColorPalette::run(Settings { + antialiasing: true, + ..Settings::default() + }) } #[derive(Debug, Default)] @@ -56,6 +59,18 @@ pub struct ColorPalette { hwb_sliders: [slider::State; 3], lab_sliders: [slider::State; 3], lch_sliders: [slider::State; 3], + rgb_text_state: text_input::State, + hsl_text_state: text_input::State, + hsv_text_state: text_input::State, + hwb_text_state: text_input::State, + lab_text_state: text_input::State, + lch_text_state: text_input::State, + rgb_text_value: String, + hsl_text_value: String, + hsv_text_value: String, + hwb_text_value: String, + lab_text_value: String, + lch_text_value: String, canvas_layer: canvas::layer::Cache, } @@ -67,6 +82,7 @@ pub enum Message { HwbColorChanged(palette::Hwb), LabColorChanged(palette::Lab), LchColorChanged(palette::Lch), + TextInput, } impl Sandbox for ColorPalette { @@ -81,14 +97,34 @@ impl Sandbox for ColorPalette { ] } + let state = State::new(); + let rgb_text_value = color_str(&state.color, ColorFormat::Rgb); + let hsl_text_value = color_str(&state.color, ColorFormat::Hsl); + let hsv_text_value = color_str(&state.color, ColorFormat::Hsv); + let hwb_text_value = color_str(&state.color, ColorFormat::Hwb); + let lab_text_value = color_str(&state.color, ColorFormat::Lab); + let lch_text_value = color_str(&state.color, ColorFormat::Lch); + ColorPalette { - state: State::new(), + state, rgb_sliders: triple_slider(), hsl_sliders: triple_slider(), hsv_sliders: triple_slider(), hwb_sliders: triple_slider(), lab_sliders: triple_slider(), lch_sliders: triple_slider(), + rgb_text_state: text_input::State::new(), + hsl_text_state: text_input::State::new(), + hsv_text_state: text_input::State::new(), + hwb_text_state: text_input::State::new(), + lab_text_state: text_input::State::new(), + lch_text_state: text_input::State::new(), + rgb_text_value, + hsl_text_value, + hsv_text_value, + hwb_text_value, + lab_text_value, + lch_text_value, canvas_layer: canvas::layer::Cache::new(), } } @@ -98,6 +134,11 @@ impl Sandbox for ColorPalette { } fn update(&mut self, message: Message) { + match message { + Message::TextInput => return, + _ => {} + } + let mut srgb = match message { Message::RgbColorChanged(rgb) => palette::Srgb::from(rgb), Message::HslColorChanged(hsl) => palette::Srgb::from(hsl), @@ -105,6 +146,7 @@ impl Sandbox for ColorPalette { Message::HwbColorChanged(hwb) => palette::Srgb::from(hwb), Message::LabColorChanged(lab) => palette::Srgb::from(lab), Message::LchColorChanged(lch) => palette::Srgb::from(lch), + _ => return, }; srgb.clamp_self(); self.canvas_layer.clear(); @@ -112,6 +154,14 @@ impl Sandbox for ColorPalette { // Set theme colors self.state.theme = generate_theme(&self.state.color); + + // Set text + self.rgb_text_value = color_str(&self.state.color, ColorFormat::Rgb); + self.hsl_text_value = color_str(&self.state.color, ColorFormat::Hsl); + self.hsv_text_value = color_str(&self.state.color, ColorFormat::Hsv); + self.hwb_text_value = color_str(&self.state.color, ColorFormat::Hwb); + self.lab_text_value = color_str(&self.state.color, ColorFormat::Lab); + self.lch_text_value = color_str(&self.state.color, ColorFormat::Lch); } fn view(&mut self) -> Element { @@ -131,12 +181,12 @@ impl Sandbox for ColorPalette { let lch = palette::Lch::from(srgb); Column::new() - .padding(20) - .spacing(20) + .padding(10) + .spacing(10) .push( Row::new() .spacing(10) - .push(Text::new("RGB")) + .push(Text::new("RGB").width(Length::Units(50))) .push(Slider::new(rgb1, 0.0..=1.0, color.r, move |r| { Message::RgbColorChanged(Color { r, ..color }) })) @@ -145,12 +195,23 @@ impl Sandbox for ColorPalette { })) .push(Slider::new(rgb3, 0.0..=1.0, color.b, move |b| { Message::RgbColorChanged(Color { b, ..color }) - })), + })) + .push( + TextInput::new( + &mut self.rgb_text_state, + "", + &mut self.rgb_text_value, + |_s| Message::TextInput, + ) + .width(Length::Units(150)) + .size(14) + .padding(2), + ), ) .push( Row::new() .spacing(10) - .push(Text::new("HSL")) + .push(Text::new("HSL").width(Length::Units(50))) .push(Slider::new( hsl1, 0.0..=360.0, @@ -183,12 +244,23 @@ impl Sandbox for ColorPalette { ..hsl }) }, - )), + )) + .push( + TextInput::new( + &mut self.hsl_text_state, + "", + &mut self.hsl_text_value, + |_s| Message::TextInput, + ) + .width(Length::Units(150)) + .size(14) + .padding(2), + ), ) .push( Row::new() .spacing(10) - .push(Text::new("HSV")) + .push(Text::new("HSV").width(Length::Units(50))) .push(Slider::new( hsv1, 0.0..=360.0, @@ -221,12 +293,23 @@ impl Sandbox for ColorPalette { ..hsv }) }, - )), + )) + .push( + TextInput::new( + &mut self.hsv_text_state, + "", + &mut self.hsv_text_value, + |_s| Message::TextInput, + ) + .width(Length::Units(150)) + .size(14) + .padding(2), + ), ) .push( Row::new() .spacing(10) - .push(Text::new("HWB")) + .push(Text::new("HWB").width(Length::Units(50))) .push(Slider::new( hwb1, 0.0..=360.0, @@ -259,12 +342,23 @@ impl Sandbox for ColorPalette { ..hwb }) }, - )), + )) + .push( + TextInput::new( + &mut self.hwb_text_state, + "", + &mut self.hwb_text_value, + |_s| Message::TextInput, + ) + .width(Length::Units(150)) + .size(14) + .padding(2), + ), ) .push( Row::new() .spacing(10) - .push(Text::new("Lab")) + .push(Text::new("Lab").width(Length::Units(50))) .push(Slider::new(lab1, 0.0..=100.0, lab.l, move |l| { Message::LabColorChanged(palette::Lab { l, ..lab }) })) @@ -273,12 +367,23 @@ impl Sandbox for ColorPalette { })) .push(Slider::new(lab3, -128.0..=127.0, lab.b, move |b| { Message::LabColorChanged(palette::Lab { b, ..lab }) - })), + })) + .push( + TextInput::new( + &mut self.lab_text_state, + "", + &mut self.lab_text_value, + |_s| Message::TextInput, + ) + .width(Length::Units(150)) + .size(14) + .padding(2), + ), ) .push( Row::new() .spacing(10) - .push(Text::new("Lch")) + .push(Text::new("Lch").width(Length::Units(50))) .push(Slider::new(lch1, 0.0..=100.0, lch.l, move |l| { Message::LchColorChanged(palette::Lch { l, ..lch }) })) @@ -303,12 +408,24 @@ impl Sandbox for ColorPalette { ..lch }) }, - )), + )) + .push( + TextInput::new( + &mut self.lch_text_state, + "", + &mut self.lch_text_value, + |_s| Message::TextInput, + ) + .width(Length::Units(150)) + .size(14) + .padding(2), + ), ) .push( Canvas::new() .width(Length::Fill) - .height(Length::Units(150)) + // .height(Length::Units(250)) + .height(Length::Fill) .push(self.canvas_layer.with(&self.state)), ) .into() @@ -317,7 +434,7 @@ impl Sandbox for ColorPalette { impl State { pub fn new() -> State { - let base = Color::from_rgb8(27, 135, 199); + let base = Color::from_rgb8(75, 128, 190); State { color: base, theme: generate_theme(&base), @@ -328,6 +445,7 @@ impl State { impl canvas::Drawable for State { fn draw(&self, frame: &mut canvas::Frame) { use canvas::{Fill, Path}; + use iced::{HorizontalAlignment, VerticalAlignment}; use palette::{Hsl, Srgb}; if self.theme.len() == 0 { @@ -335,10 +453,16 @@ impl canvas::Drawable for State { return; } - let pad = 5.0; + let pad = 20.0; let box_width = frame.width() / self.theme.len() as f32; let box_height = frame.height() / 2.0 - pad; + + let mut text = canvas::Text::default(); + text.horizontal_alignment = HorizontalAlignment::Left; + text.vertical_alignment = VerticalAlignment::Top; + text.size = 15.0; + for i in 0..self.theme.len() { let anchor = Point { x: (i as f32) * box_width, @@ -360,6 +484,57 @@ impl canvas::Drawable for State { }); }); frame.fill(&rect, Fill::Color(self.theme[i])); + + if self.theme[i] == self.color { + let cx = anchor.x + box_width / 2.0; + let tri_w = 10.0; + + let tri = Path::new(|path| { + path.move_to(Point { + x: cx - tri_w, + y: 0.0, + }); + path.line_to(Point { + x: cx + tri_w, + y: 0.0, + }); + path.line_to(Point { x: cx, y: tri_w }); + path.line_to(Point { + x: cx - tri_w, + y: 0.0, + }); + }); + frame.fill(&tri, Fill::Color(Color::WHITE)); + + let tri = Path::new(|path| { + path.move_to(Point { + x: cx - tri_w, + y: box_height, + }); + path.line_to(Point { + x: cx + tri_w, + y: box_height, + }); + path.line_to(Point { + x: cx, + y: box_height - tri_w, + }); + path.line_to(Point { + x: cx - tri_w, + y: box_height, + }); + }); + frame.fill(&tri, Fill::Color(Color::WHITE)); + } + + frame.fill_text(canvas::Text { + content: color_str(&self.theme[i], ColorFormat::Hex), + position: Point { + x: anchor.x, + y: box_height, + }, + ..text + }); } let hsl = Hsl::from(Srgb::from(self.color)); @@ -391,6 +566,76 @@ impl canvas::Drawable for State { }); }); frame.fill(&rect, Fill::Color(color)); + + frame.fill_text(canvas::Text { + content: color_str(&color, ColorFormat::Hex), + position: Point { + x: anchor.x, + y: box_height + 2.0 * pad - 15.0, + }, + ..text + }); + } + } +} + +enum ColorFormat { + Hex, + Rgb, + Hsl, + Hsv, + Hwb, + Lab, + Lch, +} + +fn color_str(color: &Color, color_format: ColorFormat) -> String { + let srgb = palette::Srgb::from(*color); + let hsl = palette::Hsl::from(srgb); + let hsv = palette::Hsv::from(srgb); + let hwb = palette::Hwb::from(srgb); + let lab = palette::Lab::from(srgb); + let lch = palette::Lch::from(srgb); + + match color_format { + ColorFormat::Hex => format!( + "#{:x}{:x}{:x}", + (255.0 * color.r).round() as u8, + (255.0 * color.g).round() as u8, + (255.0 * color.b).round() as u8 + ), + ColorFormat::Rgb => format!( + "rgb({:.0}, {:.0}, {:.0})", + 255.0 * color.r, + 255.0 * color.g, + 255.0 * color.b + ), + ColorFormat::Hsl => format!( + "hsl({:.1}, {:.1}%, {:.1}%)", + hsl.hue.to_positive_degrees(), + 100.0 * hsl.saturation, + 100.0 * hsl.lightness + ), + ColorFormat::Hsv => format!( + "hsv({:.1}, {:.1}%, {:.1}%)", + hsv.hue.to_positive_degrees(), + 100.0 * hsv.saturation, + 100.0 * hsv.value + ), + ColorFormat::Hwb => format!( + "hwb({:.1}, {:.1}%, {:.1}%)", + hwb.hue.to_positive_degrees(), + 100.0 * hwb.whiteness, + 100.0 * hwb.blackness + ), + ColorFormat::Lab => { + format!("Lab({:.1}, {:.1}, {:.1})", lab.l, lab.a, lab.b) } + ColorFormat::Lch => format!( + "Lch({:.1}, {:.1}, {:.1})", + lch.l, + lch.chroma, + lch.hue.to_positive_degrees() + ), } } -- cgit From 4b90241ea1d2139464587ce8475aeebbf283abc7 Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Fri, 10 Apr 2020 14:59:57 -0500 Subject: Hex label text alignment --- examples/color_palette/src/main.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index fc733787..b80db299 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -459,7 +459,7 @@ impl canvas::Drawable for State { let box_height = frame.height() / 2.0 - pad; let mut text = canvas::Text::default(); - text.horizontal_alignment = HorizontalAlignment::Left; + text.horizontal_alignment = HorizontalAlignment::Center; text.vertical_alignment = VerticalAlignment::Top; text.size = 15.0; @@ -530,13 +530,15 @@ impl canvas::Drawable for State { frame.fill_text(canvas::Text { content: color_str(&self.theme[i], ColorFormat::Hex), position: Point { - x: anchor.x, + x: anchor.x + box_width / 2.0, y: box_height, }, ..text }); } + text.vertical_alignment = VerticalAlignment::Bottom; + let hsl = Hsl::from(Srgb::from(self.color)); for i in 0..self.theme.len() { let pct = (i as f32 + 1.0) / (self.theme.len() as f32 + 1.0); @@ -570,8 +572,8 @@ impl canvas::Drawable for State { frame.fill_text(canvas::Text { content: color_str(&color, ColorFormat::Hex), position: Point { - x: anchor.x, - y: box_height + 2.0 * pad - 15.0, + x: anchor.x + box_width / 2.0, + y: box_height + 2.0 * pad, }, ..text }); -- cgit From 27fadad3246d555f52b991230a0352353d6700b4 Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Fri, 24 Apr 2020 15:20:00 -0500 Subject: Do not re-export Palette from iced_core --- examples/color_palette/Cargo.toml | 4 +--- examples/color_palette/src/main.rs | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/Cargo.toml b/examples/color_palette/Cargo.toml index ad7a0114..61c9f6b2 100644 --- a/examples/color_palette/Cargo.toml +++ b/examples/color_palette/Cargo.toml @@ -5,10 +5,8 @@ authors = ["Clark Moody "] edition = "2018" publish = false -[features] -palette = [] - [dependencies] iced = { path = "../..", features = ["canvas", "palette"] } iced_core = { path = "../../core" } iced_native = { path = "../../native" } +palette = "0.5.0" diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index b80db299..576a0e64 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -2,7 +2,7 @@ use iced::{ canvas, slider, text_input, Canvas, Color, Column, Element, Length, Point, Row, Sandbox, Settings, Slider, Text, TextInput, }; -use iced_core::palette::{self, Limited}; +use palette::{self, Limited}; pub fn main() { ColorPalette::run(Settings { -- cgit From 758a444d7f11809959aa73d7da32f06e98ecc89b Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Fri, 24 Apr 2020 15:31:12 -0500 Subject: Replace text input fields for simple text --- examples/color_palette/src/main.rs | 95 ++++++++------------------------------ 1 file changed, 20 insertions(+), 75 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 576a0e64..464dc828 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -1,6 +1,6 @@ use iced::{ - canvas, slider, text_input, Canvas, Color, Column, Element, Length, Point, - Row, Sandbox, Settings, Slider, Text, TextInput, + canvas, slider, Canvas, Color, Column, Element, Length, Point, Row, + Sandbox, Settings, Slider, Text, }; use palette::{self, Limited}; @@ -59,12 +59,6 @@ pub struct ColorPalette { hwb_sliders: [slider::State; 3], lab_sliders: [slider::State; 3], lch_sliders: [slider::State; 3], - rgb_text_state: text_input::State, - hsl_text_state: text_input::State, - hsv_text_state: text_input::State, - hwb_text_state: text_input::State, - lab_text_state: text_input::State, - lch_text_state: text_input::State, rgb_text_value: String, hsl_text_value: String, hsv_text_value: String, @@ -82,7 +76,6 @@ pub enum Message { HwbColorChanged(palette::Hwb), LabColorChanged(palette::Lab), LchColorChanged(palette::Lch), - TextInput, } impl Sandbox for ColorPalette { @@ -113,12 +106,6 @@ impl Sandbox for ColorPalette { hwb_sliders: triple_slider(), lab_sliders: triple_slider(), lch_sliders: triple_slider(), - rgb_text_state: text_input::State::new(), - hsl_text_state: text_input::State::new(), - hsv_text_state: text_input::State::new(), - hwb_text_state: text_input::State::new(), - lab_text_state: text_input::State::new(), - lch_text_state: text_input::State::new(), rgb_text_value, hsl_text_value, hsv_text_value, @@ -134,11 +121,6 @@ impl Sandbox for ColorPalette { } fn update(&mut self, message: Message) { - match message { - Message::TextInput => return, - _ => {} - } - let mut srgb = match message { Message::RgbColorChanged(rgb) => palette::Srgb::from(rgb), Message::HslColorChanged(hsl) => palette::Srgb::from(hsl), @@ -146,7 +128,6 @@ impl Sandbox for ColorPalette { Message::HwbColorChanged(hwb) => palette::Srgb::from(hwb), Message::LabColorChanged(lab) => palette::Srgb::from(lab), Message::LchColorChanged(lch) => palette::Srgb::from(lch), - _ => return, }; srgb.clamp_self(); self.canvas_layer.clear(); @@ -197,15 +178,9 @@ impl Sandbox for ColorPalette { Message::RgbColorChanged(Color { b, ..color }) })) .push( - TextInput::new( - &mut self.rgb_text_state, - "", - &mut self.rgb_text_value, - |_s| Message::TextInput, - ) - .width(Length::Units(150)) - .size(14) - .padding(2), + Text::new(&self.rgb_text_value) + .width(Length::Units(185)) + .size(16), ), ) .push( @@ -246,15 +221,9 @@ impl Sandbox for ColorPalette { }, )) .push( - TextInput::new( - &mut self.hsl_text_state, - "", - &mut self.hsl_text_value, - |_s| Message::TextInput, - ) - .width(Length::Units(150)) - .size(14) - .padding(2), + Text::new(&self.hsl_text_value) + .width(Length::Units(185)) + .size(16), ), ) .push( @@ -295,15 +264,9 @@ impl Sandbox for ColorPalette { }, )) .push( - TextInput::new( - &mut self.hsv_text_state, - "", - &mut self.hsv_text_value, - |_s| Message::TextInput, - ) - .width(Length::Units(150)) - .size(14) - .padding(2), + Text::new(&self.hsv_text_value) + .width(Length::Units(185)) + .size(16), ), ) .push( @@ -344,15 +307,9 @@ impl Sandbox for ColorPalette { }, )) .push( - TextInput::new( - &mut self.hwb_text_state, - "", - &mut self.hwb_text_value, - |_s| Message::TextInput, - ) - .width(Length::Units(150)) - .size(14) - .padding(2), + Text::new(&self.hwb_text_value) + .width(Length::Units(185)) + .size(16), ), ) .push( @@ -369,15 +326,9 @@ impl Sandbox for ColorPalette { Message::LabColorChanged(palette::Lab { b, ..lab }) })) .push( - TextInput::new( - &mut self.lab_text_state, - "", - &mut self.lab_text_value, - |_s| Message::TextInput, - ) - .width(Length::Units(150)) - .size(14) - .padding(2), + Text::new(&self.lab_text_value) + .width(Length::Units(185)) + .size(16), ), ) .push( @@ -410,15 +361,9 @@ impl Sandbox for ColorPalette { }, )) .push( - TextInput::new( - &mut self.lch_text_state, - "", - &mut self.lch_text_value, - |_s| Message::TextInput, - ) - .width(Length::Units(150)) - .size(14) - .padding(2), + Text::new(&self.lch_text_value) + .width(Length::Units(185)) + .size(16), ), ) .push( -- cgit From 3e71eaee37bc3aea85feb0f643dcbd4ecc11d0c4 Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Fri, 24 Apr 2020 15:40:28 -0500 Subject: Use Path::rectangle and Size for drawing swatches --- examples/color_palette/src/main.rs | 63 +++++++++++++------------------------- 1 file changed, 21 insertions(+), 42 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 464dc828..76a6bf17 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -1,6 +1,6 @@ use iced::{ - canvas, slider, Canvas, Color, Column, Element, Length, Point, Row, - Sandbox, Settings, Slider, Text, + canvas, slider, Canvas, Color, Column, Element, Length, Row, Sandbox, + Settings, Slider, Text, }; use palette::{self, Limited}; @@ -391,6 +391,7 @@ impl canvas::Drawable for State { fn draw(&self, frame: &mut canvas::Frame) { use canvas::{Fill, Path}; use iced::{HorizontalAlignment, VerticalAlignment}; + use iced_native::{Point, Size}; use palette::{Hsl, Srgb}; if self.theme.len() == 0 { @@ -400,8 +401,10 @@ impl canvas::Drawable for State { let pad = 20.0; - let box_width = frame.width() / self.theme.len() as f32; - let box_height = frame.height() / 2.0 - pad; + let box_size = Size { + width: frame.width() / self.theme.len() as f32, + height: frame.height() / 2.0 - pad, + }; let mut text = canvas::Text::default(); text.horizontal_alignment = HorizontalAlignment::Center; @@ -410,28 +413,16 @@ impl canvas::Drawable for State { for i in 0..self.theme.len() { let anchor = Point { - x: (i as f32) * box_width, + x: (i as f32) * box_size.width, y: 0.0, }; let rect = Path::new(|path| { - path.move_to(anchor); - path.line_to(Point { - x: anchor.x + box_width, - y: anchor.y, - }); - path.line_to(Point { - x: anchor.x + box_width, - y: anchor.y + box_height, - }); - path.line_to(Point { - x: anchor.x, - y: anchor.y + box_height, - }); + path.rectangle(anchor, box_size); }); frame.fill(&rect, Fill::Color(self.theme[i])); if self.theme[i] == self.color { - let cx = anchor.x + box_width / 2.0; + let cx = anchor.x + box_size.width / 2.0; let tri_w = 10.0; let tri = Path::new(|path| { @@ -454,19 +445,19 @@ impl canvas::Drawable for State { let tri = Path::new(|path| { path.move_to(Point { x: cx - tri_w, - y: box_height, + y: box_size.height, }); path.line_to(Point { x: cx + tri_w, - y: box_height, + y: box_size.height, }); path.line_to(Point { x: cx, - y: box_height - tri_w, + y: box_size.height - tri_w, }); path.line_to(Point { x: cx - tri_w, - y: box_height, + y: box_size.height, }); }); frame.fill(&tri, Fill::Color(Color::WHITE)); @@ -475,8 +466,8 @@ impl canvas::Drawable for State { frame.fill_text(canvas::Text { content: color_str(&self.theme[i], ColorFormat::Hex), position: Point { - x: anchor.x + box_width / 2.0, - y: box_height, + x: anchor.x + box_size.width / 2.0, + y: box_size.height, }, ..text }); @@ -494,31 +485,19 @@ impl canvas::Drawable for State { let color: Color = Srgb::from(graded.clamp()).into(); let anchor = Point { - x: (i as f32) * box_width, - y: box_height + 2.0 * pad, + x: (i as f32) * box_size.width, + y: box_size.height + 2.0 * pad, }; let rect = Path::new(|path| { - path.move_to(anchor); - path.line_to(Point { - x: anchor.x + box_width, - y: anchor.y, - }); - path.line_to(Point { - x: anchor.x + box_width, - y: anchor.y + box_height, - }); - path.line_to(Point { - x: anchor.x, - y: anchor.y + box_height, - }); + path.rectangle(anchor, box_size); }); frame.fill(&rect, Fill::Color(color)); frame.fill_text(canvas::Text { content: color_str(&color, ColorFormat::Hex), position: Point { - x: anchor.x + box_width / 2.0, - y: box_height + 2.0 * pad, + x: anchor.x + box_size.width / 2.0, + y: box_size.height + 2.0 * pad, }, ..text }); -- cgit From 430f78a693a87e9ba3ac4638cac96aab57dd3042 Mon Sep 17 00:00:00 2001 From: Clark Moody Date: Mon, 27 Apr 2020 16:25:13 -0500 Subject: Abstract into ColorPicker and ColorSpace trait Each color type implements ColorSpace to define its own representation and update methods. View sliders are implemented on the ColorPicker struct. --- examples/color_palette/src/main.rs | 635 +++++++++++++++++++------------------ 1 file changed, 323 insertions(+), 312 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 76a6bf17..993b7fb0 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -3,6 +3,8 @@ use iced::{ Settings, Slider, Text, }; use palette::{self, Limited}; +use std::marker::PhantomData; +use std::ops::RangeInclusive; pub fn main() { ColorPalette::run(Settings { @@ -51,20 +53,288 @@ fn generate_theme(base_color: &Color) -> Vec { theme } +struct ColorPicker { + sliders: [slider::State; 3], + color_space: PhantomData, +} + +trait ColorSpace: Sized { + const LABEL: &'static str; + const COMPONENT_RANGES: [RangeInclusive; 3]; + + fn new(a: f32, b: f32, c: f32) -> Self; + + fn components(&self) -> [f32; 3]; + + fn update_component(c: Self, i: usize, val: f32) -> Self; + + fn to_string(&self) -> String; +} + +impl ColorPicker { + fn view(&mut self, color: C) -> Element { + let [c1, c2, c3] = color.components(); + let [s1, s2, s3] = &mut self.sliders; + let [cr1, cr2, cr3] = C::COMPONENT_RANGES; + Row::new() + .spacing(10) + .push(Text::new(C::LABEL).width(Length::Units(50))) + .push(Slider::new(s1, cr1, c1, move |v| { + C::update_component(color, 0, v) + })) + .push(Slider::new(s2, cr2, c2, move |v| { + C::update_component(color, 1, v) + })) + .push(Slider::new(s3, cr3, c3, move |v| { + C::update_component(color, 2, v) + })) + .push( + Text::new(color.to_string()) + .width(Length::Units(185)) + .size(16), + ) + .into() + } +} + +impl ColorSpace for Color { + const LABEL: &'static str = "RGB"; + const COMPONENT_RANGES: [RangeInclusive; 3] = + [0.0..=1.0, 0.0..=1.0, 0.0..=1.0]; + + fn new(r: f32, g: f32, b: f32) -> Self { + Color::from_rgb(r, g, b) + } + + fn components(&self) -> [f32; 3] { + [self.r, self.g, self.b] + } + + fn update_component(c: Color, i: usize, val: f32) -> Self { + match i { + 0 => Color { r: val, ..c }, + 1 => Color { g: val, ..c }, + 2 => Color { b: val, ..c }, + _ => panic!("Invalid component index: {:?}", i), + } + } + + fn to_string(&self) -> String { + format!( + "rgb({:.0}, {:.0}, {:.0})", + 255.0 * self.r, + 255.0 * self.g, + 255.0 * self.b + ) + } +} + +impl ColorSpace for palette::Hsl { + const LABEL: &'static str = "HSL"; + const COMPONENT_RANGES: [RangeInclusive; 3] = + [0.0..=360.0, 0.0..=1.0, 0.0..=1.0]; + + fn new(hue: f32, saturation: f32, lightness: f32) -> Self { + palette::Hsl::new( + palette::RgbHue::from_degrees(hue), + saturation, + lightness, + ) + } + + fn components(&self) -> [f32; 3] { + [ + self.hue.to_positive_degrees(), + self.saturation, + self.lightness, + ] + } + + fn update_component(c: palette::Hsl, i: usize, val: f32) -> Self { + match i { + 0 => palette::Hsl { + hue: palette::RgbHue::from_degrees(val), + ..c + }, + 1 => palette::Hsl { + saturation: val, + ..c + }, + 2 => palette::Hsl { + lightness: val, + ..c + }, + _ => panic!("Invalid component index: {:?}", i), + } + } + + fn to_string(&self) -> String { + format!( + "hsl({:.1}, {:.1}%, {:.1}%)", + self.hue.to_positive_degrees(), + 100.0 * self.saturation, + 100.0 * self.lightness + ) + } +} + +impl ColorSpace for palette::Hsv { + const LABEL: &'static str = "HSV"; + const COMPONENT_RANGES: [RangeInclusive; 3] = + [0.0..=360.0, 0.0..=1.0, 0.0..=1.0]; + + fn new(hue: f32, saturation: f32, value: f32) -> Self { + palette::Hsv::new(palette::RgbHue::from_degrees(hue), saturation, value) + } + + fn components(&self) -> [f32; 3] { + [self.hue.to_positive_degrees(), self.saturation, self.value] + } + + fn update_component(c: palette::Hsv, i: usize, val: f32) -> Self { + match i { + 0 => palette::Hsv { + hue: palette::RgbHue::from_degrees(val), + ..c + }, + 1 => palette::Hsv { + saturation: val, + ..c + }, + 2 => palette::Hsv { value: val, ..c }, + _ => panic!("Invalid component index: {:?}", i), + } + } + + fn to_string(&self) -> String { + format!( + "hsv({:.1}, {:.1}%, {:.1}%)", + self.hue.to_positive_degrees(), + 100.0 * self.saturation, + 100.0 * self.value + ) + } +} + +impl ColorSpace for palette::Hwb { + const LABEL: &'static str = "HWB"; + const COMPONENT_RANGES: [RangeInclusive; 3] = + [0.0..=360.0, 0.0..=1.0, 0.0..=1.0]; + + fn new(hue: f32, whiteness: f32, blackness: f32) -> Self { + palette::Hwb::new( + palette::RgbHue::from_degrees(hue), + whiteness, + blackness, + ) + } + + fn components(&self) -> [f32; 3] { + [ + self.hue.to_positive_degrees(), + self.whiteness, + self.blackness, + ] + } + + fn update_component(c: palette::Hwb, i: usize, val: f32) -> Self { + match i { + 0 => palette::Hwb { + hue: palette::RgbHue::from_degrees(val), + ..c + }, + 1 => palette::Hwb { + whiteness: val, + ..c + }, + 2 => palette::Hwb { + blackness: val, + ..c + }, + _ => panic!("Invalid component index: {:?}", i), + } + } + + fn to_string(&self) -> String { + format!( + "hwb({:.1}, {:.1}%, {:.1}%)", + self.hue.to_positive_degrees(), + 100.0 * self.whiteness, + 100.0 * self.blackness + ) + } +} + +impl ColorSpace for palette::Lab { + const LABEL: &'static str = "Lab"; + const COMPONENT_RANGES: [RangeInclusive; 3] = + [0.0..=100.0, -128.0..=127.0, -128.0..=127.0]; + + fn new(l: f32, a: f32, b: f32) -> Self { + palette::Lab::new(l, a, b) + } + + fn components(&self) -> [f32; 3] { + [self.l, self.a, self.b] + } + + fn update_component(c: palette::Lab, i: usize, val: f32) -> Self { + match i { + 0 => palette::Lab { l: val, ..c }, + 1 => palette::Lab { a: val, ..c }, + 2 => palette::Lab { b: val, ..c }, + _ => panic!("Invalid component index: {:?}", i), + } + } + + fn to_string(&self) -> String { + format!("Lab({:.1}, {:.1}, {:.1})", self.l, self.a, self.b) + } +} + +impl ColorSpace for palette::Lch { + const LABEL: &'static str = "Lch"; + const COMPONENT_RANGES: [RangeInclusive; 3] = + [0.0..=100.0, 0.0..=128.0, 0.0..=360.0]; + + fn new(l: f32, chroma: f32, hue: f32) -> Self { + palette::Lch::new(l, chroma, palette::LabHue::from_degrees(hue)) + } + + fn components(&self) -> [f32; 3] { + [self.l, self.chroma, self.hue.to_positive_degrees()] + } + + fn update_component(c: palette::Lch, i: usize, val: f32) -> Self { + match i { + 0 => palette::Lch { l: val, ..c }, + 1 => palette::Lch { chroma: val, ..c }, + 2 => palette::Lch { + hue: palette::LabHue::from_degrees(val), + ..c + }, + _ => panic!("Invalid component index: {:?}", i), + } + } + + fn to_string(&self) -> String { + format!( + "Lch({:.1}, {:.1}, {:.1})", + self.l, + self.chroma, + self.hue.to_positive_degrees() + ) + } +} + pub struct ColorPalette { state: State, - rgb_sliders: [slider::State; 3], - hsl_sliders: [slider::State; 3], - hsv_sliders: [slider::State; 3], - hwb_sliders: [slider::State; 3], - lab_sliders: [slider::State; 3], - lch_sliders: [slider::State; 3], - rgb_text_value: String, - hsl_text_value: String, - hsv_text_value: String, - hwb_text_value: String, - lab_text_value: String, - lch_text_value: String, + rgb: ColorPicker, + hsl: ColorPicker, + hsv: ColorPicker, + hwb: ColorPicker, + lab: ColorPicker, + lch: ColorPicker, canvas_layer: canvas::layer::Cache, } @@ -90,28 +360,33 @@ impl Sandbox for ColorPalette { ] } - let state = State::new(); - let rgb_text_value = color_str(&state.color, ColorFormat::Rgb); - let hsl_text_value = color_str(&state.color, ColorFormat::Hsl); - let hsv_text_value = color_str(&state.color, ColorFormat::Hsv); - let hwb_text_value = color_str(&state.color, ColorFormat::Hwb); - let lab_text_value = color_str(&state.color, ColorFormat::Lab); - let lch_text_value = color_str(&state.color, ColorFormat::Lch); - ColorPalette { - state, - rgb_sliders: triple_slider(), - hsl_sliders: triple_slider(), - hsv_sliders: triple_slider(), - hwb_sliders: triple_slider(), - lab_sliders: triple_slider(), - lch_sliders: triple_slider(), - rgb_text_value, - hsl_text_value, - hsv_text_value, - hwb_text_value, - lab_text_value, - lch_text_value, + state: State::new(), + rgb: ColorPicker { + sliders: triple_slider(), + color_space: PhantomData::, + }, + hsl: ColorPicker { + sliders: triple_slider(), + color_space: PhantomData::, + }, + hsv: ColorPicker { + sliders: triple_slider(), + color_space: PhantomData::, + }, + + hwb: ColorPicker { + sliders: triple_slider(), + color_space: PhantomData::, + }, + lab: ColorPicker { + sliders: triple_slider(), + color_space: PhantomData::, + }, + lch: ColorPicker { + sliders: triple_slider(), + color_space: PhantomData::, + }, canvas_layer: canvas::layer::Cache::new(), } } @@ -135,24 +410,9 @@ impl Sandbox for ColorPalette { // Set theme colors self.state.theme = generate_theme(&self.state.color); - - // Set text - self.rgb_text_value = color_str(&self.state.color, ColorFormat::Rgb); - self.hsl_text_value = color_str(&self.state.color, ColorFormat::Hsl); - self.hsv_text_value = color_str(&self.state.color, ColorFormat::Hsv); - self.hwb_text_value = color_str(&self.state.color, ColorFormat::Hwb); - self.lab_text_value = color_str(&self.state.color, ColorFormat::Lab); - self.lch_text_value = color_str(&self.state.color, ColorFormat::Lch); } fn view(&mut self) -> Element { - let [rgb1, rgb2, rgb3] = &mut self.rgb_sliders; - let [hsl1, hsl2, hsl3] = &mut self.hsl_sliders; - let [hsv1, hsv2, hsv3] = &mut self.hsv_sliders; - let [hwb1, hwb2, hwb3] = &mut self.hwb_sliders; - let [lab1, lab2, lab3] = &mut self.lab_sliders; - let [lch1, lch2, lch3] = &mut self.lch_sliders; - let color = self.state.color; let srgb = palette::Srgb::from(self.state.color); let hsl = palette::Hsl::from(srgb); @@ -164,208 +424,12 @@ impl Sandbox for ColorPalette { Column::new() .padding(10) .spacing(10) - .push( - Row::new() - .spacing(10) - .push(Text::new("RGB").width(Length::Units(50))) - .push(Slider::new(rgb1, 0.0..=1.0, color.r, move |r| { - Message::RgbColorChanged(Color { r, ..color }) - })) - .push(Slider::new(rgb2, 0.0..=1.0, color.g, move |g| { - Message::RgbColorChanged(Color { g, ..color }) - })) - .push(Slider::new(rgb3, 0.0..=1.0, color.b, move |b| { - Message::RgbColorChanged(Color { b, ..color }) - })) - .push( - Text::new(&self.rgb_text_value) - .width(Length::Units(185)) - .size(16), - ), - ) - .push( - Row::new() - .spacing(10) - .push(Text::new("HSL").width(Length::Units(50))) - .push(Slider::new( - hsl1, - 0.0..=360.0, - hsl.hue.to_positive_degrees(), - move |hue| { - Message::HslColorChanged(palette::Hsl { - hue: palette::RgbHue::from_degrees(hue), - ..hsl - }) - }, - )) - .push(Slider::new( - hsl2, - 0.0..=1.0, - hsl.saturation, - move |saturation| { - Message::HslColorChanged(palette::Hsl { - saturation, - ..hsl - }) - }, - )) - .push(Slider::new( - hsl3, - 0.0..=1.0, - hsl.lightness, - move |lightness| { - Message::HslColorChanged(palette::Hsl { - lightness, - ..hsl - }) - }, - )) - .push( - Text::new(&self.hsl_text_value) - .width(Length::Units(185)) - .size(16), - ), - ) - .push( - Row::new() - .spacing(10) - .push(Text::new("HSV").width(Length::Units(50))) - .push(Slider::new( - hsv1, - 0.0..=360.0, - hsv.hue.to_positive_degrees(), - move |hue| { - Message::HsvColorChanged(palette::Hsv { - hue: palette::RgbHue::from_degrees(hue), - ..hsv - }) - }, - )) - .push(Slider::new( - hsv2, - 0.0..=1.0, - hsv.saturation, - move |saturation| { - Message::HsvColorChanged(palette::Hsv { - saturation, - ..hsv - }) - }, - )) - .push(Slider::new( - hsv3, - 0.0..=1.0, - hsv.value, - move |value| { - Message::HsvColorChanged(palette::Hsv { - value, - ..hsv - }) - }, - )) - .push( - Text::new(&self.hsv_text_value) - .width(Length::Units(185)) - .size(16), - ), - ) - .push( - Row::new() - .spacing(10) - .push(Text::new("HWB").width(Length::Units(50))) - .push(Slider::new( - hwb1, - 0.0..=360.0, - hwb.hue.to_positive_degrees(), - move |hue| { - Message::HwbColorChanged(palette::Hwb { - hue: palette::RgbHue::from_degrees(hue), - ..hwb - }) - }, - )) - .push(Slider::new( - hwb2, - 0.0..=1.0, - hwb.whiteness, - move |whiteness| { - Message::HwbColorChanged(palette::Hwb { - whiteness, - ..hwb - }) - }, - )) - .push(Slider::new( - hwb3, - 0.0..=1.0, - hwb.blackness, - move |blackness| { - Message::HwbColorChanged(palette::Hwb { - blackness, - ..hwb - }) - }, - )) - .push( - Text::new(&self.hwb_text_value) - .width(Length::Units(185)) - .size(16), - ), - ) - .push( - Row::new() - .spacing(10) - .push(Text::new("Lab").width(Length::Units(50))) - .push(Slider::new(lab1, 0.0..=100.0, lab.l, move |l| { - Message::LabColorChanged(palette::Lab { l, ..lab }) - })) - .push(Slider::new(lab2, -128.0..=127.0, lab.a, move |a| { - Message::LabColorChanged(palette::Lab { a, ..lab }) - })) - .push(Slider::new(lab3, -128.0..=127.0, lab.b, move |b| { - Message::LabColorChanged(palette::Lab { b, ..lab }) - })) - .push( - Text::new(&self.lab_text_value) - .width(Length::Units(185)) - .size(16), - ), - ) - .push( - Row::new() - .spacing(10) - .push(Text::new("Lch").width(Length::Units(50))) - .push(Slider::new(lch1, 0.0..=100.0, lch.l, move |l| { - Message::LchColorChanged(palette::Lch { l, ..lch }) - })) - .push(Slider::new( - lch2, - 0.0..=128.0, - lch.chroma, - move |chroma| { - Message::LchColorChanged(palette::Lch { - chroma, - ..lch - }) - }, - )) - .push(Slider::new( - lch3, - 0.0..=360.0, - lch.hue.to_positive_degrees(), - move |hue| { - Message::LchColorChanged(palette::Lch { - hue: palette::LabHue::from_degrees(hue), - ..lch - }) - }, - )) - .push( - Text::new(&self.lch_text_value) - .width(Length::Units(185)) - .size(16), - ), - ) + .push(self.rgb.view(color).map(Message::RgbColorChanged)) + .push(self.hsl.view(hsl).map(Message::HslColorChanged)) + .push(self.hsv.view(hsv).map(Message::HsvColorChanged)) + .push(self.hwb.view(hwb).map(Message::HwbColorChanged)) + .push(self.lab.view(lab).map(Message::LabColorChanged)) + .push(self.lch.view(lch).map(Message::LchColorChanged)) .push( Canvas::new() .width(Length::Fill) @@ -395,7 +459,6 @@ impl canvas::Drawable for State { use palette::{Hsl, Srgb}; if self.theme.len() == 0 { - println!("Zero len"); return; } @@ -464,7 +527,7 @@ impl canvas::Drawable for State { } frame.fill_text(canvas::Text { - content: color_str(&self.theme[i], ColorFormat::Hex), + content: color_hex_str(&self.theme[i]), position: Point { x: anchor.x + box_size.width / 2.0, y: box_size.height, @@ -494,7 +557,7 @@ impl canvas::Drawable for State { frame.fill(&rect, Fill::Color(color)); frame.fill_text(canvas::Text { - content: color_str(&color, ColorFormat::Hex), + content: color_hex_str(&color), position: Point { x: anchor.x + box_size.width / 2.0, y: box_size.height + 2.0 * pad, @@ -505,63 +568,11 @@ impl canvas::Drawable for State { } } -enum ColorFormat { - Hex, - Rgb, - Hsl, - Hsv, - Hwb, - Lab, - Lch, -} - -fn color_str(color: &Color, color_format: ColorFormat) -> String { - let srgb = palette::Srgb::from(*color); - let hsl = palette::Hsl::from(srgb); - let hsv = palette::Hsv::from(srgb); - let hwb = palette::Hwb::from(srgb); - let lab = palette::Lab::from(srgb); - let lch = palette::Lch::from(srgb); - - match color_format { - ColorFormat::Hex => format!( - "#{:x}{:x}{:x}", - (255.0 * color.r).round() as u8, - (255.0 * color.g).round() as u8, - (255.0 * color.b).round() as u8 - ), - ColorFormat::Rgb => format!( - "rgb({:.0}, {:.0}, {:.0})", - 255.0 * color.r, - 255.0 * color.g, - 255.0 * color.b - ), - ColorFormat::Hsl => format!( - "hsl({:.1}, {:.1}%, {:.1}%)", - hsl.hue.to_positive_degrees(), - 100.0 * hsl.saturation, - 100.0 * hsl.lightness - ), - ColorFormat::Hsv => format!( - "hsv({:.1}, {:.1}%, {:.1}%)", - hsv.hue.to_positive_degrees(), - 100.0 * hsv.saturation, - 100.0 * hsv.value - ), - ColorFormat::Hwb => format!( - "hwb({:.1}, {:.1}%, {:.1}%)", - hwb.hue.to_positive_degrees(), - 100.0 * hwb.whiteness, - 100.0 * hwb.blackness - ), - ColorFormat::Lab => { - format!("Lab({:.1}, {:.1}, {:.1})", lab.l, lab.a, lab.b) - } - ColorFormat::Lch => format!( - "Lch({:.1}, {:.1}, {:.1})", - lch.l, - lch.chroma, - lch.hue.to_positive_degrees() - ), - } +fn color_hex_str(color: &Color) -> String { + format!( + "#{:x}{:x}{:x}", + (255.0 * color.r).round() as u8, + (255.0 * color.g).round() as u8, + (255.0 * color.b).round() as u8 + ) } -- cgit From 11e4039b5644606e40d603397f1039686ecd6fe5 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 1 May 2020 21:43:11 +0200 Subject: Remove `update_component` in `color_palette` We can use `ColorSpace::new` instead --- examples/color_palette/src/main.rs | 96 ++------------------------------------ 1 file changed, 4 insertions(+), 92 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 993b7fb0..46a4d085 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -66,8 +66,6 @@ trait ColorSpace: Sized { fn components(&self) -> [f32; 3]; - fn update_component(c: Self, i: usize, val: f32) -> Self; - fn to_string(&self) -> String; } @@ -76,18 +74,13 @@ impl ColorPicker { let [c1, c2, c3] = color.components(); let [s1, s2, s3] = &mut self.sliders; let [cr1, cr2, cr3] = C::COMPONENT_RANGES; + Row::new() .spacing(10) .push(Text::new(C::LABEL).width(Length::Units(50))) - .push(Slider::new(s1, cr1, c1, move |v| { - C::update_component(color, 0, v) - })) - .push(Slider::new(s2, cr2, c2, move |v| { - C::update_component(color, 1, v) - })) - .push(Slider::new(s3, cr3, c3, move |v| { - C::update_component(color, 2, v) - })) + .push(Slider::new(s1, cr1, c1, move |v| C::new(v, c2, c3))) + .push(Slider::new(s2, cr2, c2, move |v| C::new(c1, v, c3))) + .push(Slider::new(s3, cr3, c3, move |v| C::new(c1, c2, v))) .push( Text::new(color.to_string()) .width(Length::Units(185)) @@ -110,15 +103,6 @@ impl ColorSpace for Color { [self.r, self.g, self.b] } - fn update_component(c: Color, i: usize, val: f32) -> Self { - match i { - 0 => Color { r: val, ..c }, - 1 => Color { g: val, ..c }, - 2 => Color { b: val, ..c }, - _ => panic!("Invalid component index: {:?}", i), - } - } - fn to_string(&self) -> String { format!( "rgb({:.0}, {:.0}, {:.0})", @@ -150,24 +134,6 @@ impl ColorSpace for palette::Hsl { ] } - fn update_component(c: palette::Hsl, i: usize, val: f32) -> Self { - match i { - 0 => palette::Hsl { - hue: palette::RgbHue::from_degrees(val), - ..c - }, - 1 => palette::Hsl { - saturation: val, - ..c - }, - 2 => palette::Hsl { - lightness: val, - ..c - }, - _ => panic!("Invalid component index: {:?}", i), - } - } - fn to_string(&self) -> String { format!( "hsl({:.1}, {:.1}%, {:.1}%)", @@ -191,21 +157,6 @@ impl ColorSpace for palette::Hsv { [self.hue.to_positive_degrees(), self.saturation, self.value] } - fn update_component(c: palette::Hsv, i: usize, val: f32) -> Self { - match i { - 0 => palette::Hsv { - hue: palette::RgbHue::from_degrees(val), - ..c - }, - 1 => palette::Hsv { - saturation: val, - ..c - }, - 2 => palette::Hsv { value: val, ..c }, - _ => panic!("Invalid component index: {:?}", i), - } - } - fn to_string(&self) -> String { format!( "hsv({:.1}, {:.1}%, {:.1}%)", @@ -237,24 +188,6 @@ impl ColorSpace for palette::Hwb { ] } - fn update_component(c: palette::Hwb, i: usize, val: f32) -> Self { - match i { - 0 => palette::Hwb { - hue: palette::RgbHue::from_degrees(val), - ..c - }, - 1 => palette::Hwb { - whiteness: val, - ..c - }, - 2 => palette::Hwb { - blackness: val, - ..c - }, - _ => panic!("Invalid component index: {:?}", i), - } - } - fn to_string(&self) -> String { format!( "hwb({:.1}, {:.1}%, {:.1}%)", @@ -278,15 +211,6 @@ impl ColorSpace for palette::Lab { [self.l, self.a, self.b] } - fn update_component(c: palette::Lab, i: usize, val: f32) -> Self { - match i { - 0 => palette::Lab { l: val, ..c }, - 1 => palette::Lab { a: val, ..c }, - 2 => palette::Lab { b: val, ..c }, - _ => panic!("Invalid component index: {:?}", i), - } - } - fn to_string(&self) -> String { format!("Lab({:.1}, {:.1}, {:.1})", self.l, self.a, self.b) } @@ -305,18 +229,6 @@ impl ColorSpace for palette::Lch { [self.l, self.chroma, self.hue.to_positive_degrees()] } - fn update_component(c: palette::Lch, i: usize, val: f32) -> Self { - match i { - 0 => palette::Lch { l: val, ..c }, - 1 => palette::Lch { chroma: val, ..c }, - 2 => palette::Lch { - hue: palette::LabHue::from_degrees(val), - ..c - }, - _ => panic!("Invalid component index: {:?}", i), - } - } - fn to_string(&self) -> String { format!( "Lch({:.1}, {:.1}, {:.1})", -- cgit From 0a011f90313dfbd77da5fdaa58bd93924ba7625c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 1 May 2020 21:51:08 +0200 Subject: Improve `generate_theme` in `color_palette` --- examples/color_palette/src/main.rs | 42 ++++++++++++++------------------------ 1 file changed, 15 insertions(+), 27 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 46a4d085..12c24a64 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -21,36 +21,24 @@ pub struct State { fn generate_theme(base_color: &Color) -> Vec { use palette::{Hsl, Hue, Shade, Srgb}; - let mut theme = Vec::::new(); + // Convert to HSL color for manipulation let hsl = Hsl::from(Srgb::from(*base_color)); - theme.push( - Srgb::from(hsl.shift_hue(-135.0).lighten(0.075)) - .clamp() - .into(), - ); - theme.push(Srgb::from(hsl.shift_hue(-120.0)).clamp().into()); - theme.push( - Srgb::from(hsl.shift_hue(-105.0).darken(0.075)) - .clamp() - .into(), - ); - theme.push(Srgb::from(hsl.darken(0.075)).clamp().into()); - theme.push(*base_color); - theme.push(Srgb::from(hsl.lighten(0.075)).clamp().into()); - theme.push( - Srgb::from(hsl.shift_hue(105.0).darken(0.075)) - .clamp() - .into(), - ); - theme.push(Srgb::from(hsl.shift_hue(120.0)).clamp().into()); - theme.push( - Srgb::from(hsl.shift_hue(135.0).lighten(0.075)) - .clamp() - .into(), - ); - theme + [ + hsl.shift_hue(-135.0).lighten(0.075), + hsl.shift_hue(-120.0), + hsl.shift_hue(-105.0).darken(0.075), + hsl.darken(0.075), + hsl, + hsl.lighten(0.075), + hsl.shift_hue(105.0).darken(0.075), + hsl.shift_hue(120.0), + hsl.shift_hue(135.0).lighten(0.075), + ] + .iter() + .map(|&color| Srgb::from(color).clamp().into()) + .collect() } struct ColorPicker { -- cgit From 4d724a88e6b8b4f707501c2a45710354f8612b47 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 1 May 2020 22:24:34 +0200 Subject: Introduce `Theme` type in `color_palette` example --- examples/color_palette/src/main.rs | 191 +++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 103 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 12c24a64..97363b75 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -1,6 +1,6 @@ use iced::{ - canvas, slider, Canvas, Color, Column, Element, Length, Row, Sandbox, - Settings, Slider, Text, + canvas, slider, Align, Canvas, Color, Column, Element, Length, Row, + Sandbox, Settings, Slider, Text, }; use palette::{self, Limited}; use std::marker::PhantomData; @@ -13,34 +13,68 @@ pub fn main() { }) } -#[derive(Debug, Default)] -pub struct State { - color: Color, - theme: Vec, +#[derive(Debug)] +pub struct Theme { + lower: Vec, + base: Color, + higher: Vec, } -fn generate_theme(base_color: &Color) -> Vec { - use palette::{Hsl, Hue, Shade, Srgb}; - - // Convert to HSL color for manipulation - let hsl = Hsl::from(Srgb::from(*base_color)); - - [ - hsl.shift_hue(-135.0).lighten(0.075), - hsl.shift_hue(-120.0), - hsl.shift_hue(-105.0).darken(0.075), - hsl.darken(0.075), - hsl, - hsl.lighten(0.075), - hsl.shift_hue(105.0).darken(0.075), - hsl.shift_hue(120.0), - hsl.shift_hue(135.0).lighten(0.075), - ] - .iter() - .map(|&color| Srgb::from(color).clamp().into()) - .collect() +impl Default for Theme { + fn default() -> Self { + Theme::new(Color::from_rgb8(75, 128, 190)) + } +} + +impl Theme { + pub fn new(base: impl Into) -> Theme { + use palette::{Hsl, Hue, Shade, Srgb}; + + let base = base.into(); + + // Convert to HSL color for manipulation + let hsl = Hsl::from(Srgb::from(base)); + + let lower = [ + hsl.shift_hue(-135.0).lighten(0.075), + hsl.shift_hue(-120.0), + hsl.shift_hue(-105.0).darken(0.075), + hsl.darken(0.075), + ]; + + let higher = [ + hsl.lighten(0.075), + hsl.shift_hue(105.0).darken(0.075), + hsl.shift_hue(120.0), + hsl.shift_hue(135.0).lighten(0.075), + ]; + + Theme { + lower: lower + .iter() + .map(|&color| Srgb::from(color).clamp().into()) + .collect(), + base, + higher: higher + .iter() + .map(|&color| Srgb::from(color).clamp().into()) + .collect(), + } + } + + pub fn len(&self) -> usize { + self.lower.len() + self.higher.len() + 1 + } + + pub fn colors(&self) -> impl Iterator { + self.lower + .iter() + .chain(std::iter::once(&self.base)) + .chain(self.higher.iter()) + } } +#[derive(Default)] struct ColorPicker { sliders: [slider::State; 3], color_space: PhantomData, @@ -65,6 +99,7 @@ impl ColorPicker { Row::new() .spacing(10) + .align_items(Align::Center) .push(Text::new(C::LABEL).width(Length::Units(50))) .push(Slider::new(s1, cr1, c1, move |v| C::new(v, c2, c3))) .push(Slider::new(s2, cr2, c2, move |v| C::new(c1, v, c3))) @@ -227,15 +262,16 @@ impl ColorSpace for palette::Lch { } } +#[derive(Default)] pub struct ColorPalette { - state: State, + theme: Theme, rgb: ColorPicker, hsl: ColorPicker, hsv: ColorPicker, hwb: ColorPicker, lab: ColorPicker, lch: ColorPicker, - canvas_layer: canvas::layer::Cache, + canvas_layer: canvas::layer::Cache, } #[derive(Debug, Clone, Copy)] @@ -252,43 +288,7 @@ impl Sandbox for ColorPalette { type Message = Message; fn new() -> Self { - fn triple_slider() -> [slider::State; 3] { - [ - slider::State::new(), - slider::State::new(), - slider::State::new(), - ] - } - - ColorPalette { - state: State::new(), - rgb: ColorPicker { - sliders: triple_slider(), - color_space: PhantomData::, - }, - hsl: ColorPicker { - sliders: triple_slider(), - color_space: PhantomData::, - }, - hsv: ColorPicker { - sliders: triple_slider(), - color_space: PhantomData::, - }, - - hwb: ColorPicker { - sliders: triple_slider(), - color_space: PhantomData::, - }, - lab: ColorPicker { - sliders: triple_slider(), - color_space: PhantomData::, - }, - lch: ColorPicker { - sliders: triple_slider(), - color_space: PhantomData::, - }, - canvas_layer: canvas::layer::Cache::new(), - } + Self::default() } fn title(&self) -> String { @@ -296,7 +296,7 @@ impl Sandbox for ColorPalette { } fn update(&mut self, message: Message) { - let mut srgb = match message { + let srgb = match message { Message::RgbColorChanged(rgb) => palette::Srgb::from(rgb), Message::HslColorChanged(hsl) => palette::Srgb::from(hsl), Message::HsvColorChanged(hsv) => palette::Srgb::from(hsv), @@ -304,17 +304,15 @@ impl Sandbox for ColorPalette { Message::LabColorChanged(lab) => palette::Srgb::from(lab), Message::LchColorChanged(lch) => palette::Srgb::from(lch), }; - srgb.clamp_self(); - self.canvas_layer.clear(); - self.state.color = Color::from(srgb); - // Set theme colors - self.state.theme = generate_theme(&self.state.color); + self.theme = Theme::new(srgb.clamp()); + self.canvas_layer.clear(); } fn view(&mut self) -> Element { - let color = self.state.color; - let srgb = palette::Srgb::from(self.state.color); + let base = self.theme.base; + + let srgb = palette::Srgb::from(base); let hsl = palette::Hsl::from(srgb); let hsv = palette::Hsv::from(srgb); let hwb = palette::Hwb::from(srgb); @@ -324,7 +322,7 @@ impl Sandbox for ColorPalette { Column::new() .padding(10) .spacing(10) - .push(self.rgb.view(color).map(Message::RgbColorChanged)) + .push(self.rgb.view(base).map(Message::RgbColorChanged)) .push(self.hsl.view(hsl).map(Message::HslColorChanged)) .push(self.hsv.view(hsv).map(Message::HsvColorChanged)) .push(self.hwb.view(hwb).map(Message::HwbColorChanged)) @@ -333,48 +331,35 @@ impl Sandbox for ColorPalette { .push( Canvas::new() .width(Length::Fill) - // .height(Length::Units(250)) .height(Length::Fill) - .push(self.canvas_layer.with(&self.state)), + .push(self.canvas_layer.with(&self.theme)), ) .into() } } -impl State { - pub fn new() -> State { - let base = Color::from_rgb8(75, 128, 190); - State { - color: base, - theme: generate_theme(&base), - } - } -} - -impl canvas::Drawable for State { +impl canvas::Drawable for Theme { fn draw(&self, frame: &mut canvas::Frame) { use canvas::{Fill, Path}; use iced::{HorizontalAlignment, VerticalAlignment}; use iced_native::{Point, Size}; use palette::{Hsl, Srgb}; - if self.theme.len() == 0 { - return; - } - let pad = 20.0; let box_size = Size { - width: frame.width() / self.theme.len() as f32, + width: frame.width() / self.len() as f32, height: frame.height() / 2.0 - pad, }; - let mut text = canvas::Text::default(); - text.horizontal_alignment = HorizontalAlignment::Center; - text.vertical_alignment = VerticalAlignment::Top; - text.size = 15.0; + let mut text = canvas::Text { + horizontal_alignment: HorizontalAlignment::Center, + vertical_alignment: VerticalAlignment::Top, + size: 15.0, + ..canvas::Text::default() + }; - for i in 0..self.theme.len() { + for (i, &color) in self.colors().enumerate() { let anchor = Point { x: (i as f32) * box_size.width, y: 0.0, @@ -382,9 +367,9 @@ impl canvas::Drawable for State { let rect = Path::new(|path| { path.rectangle(anchor, box_size); }); - frame.fill(&rect, Fill::Color(self.theme[i])); + frame.fill(&rect, Fill::Color(color)); - if self.theme[i] == self.color { + if self.base == color { let cx = anchor.x + box_size.width / 2.0; let tri_w = 10.0; @@ -427,7 +412,7 @@ impl canvas::Drawable for State { } frame.fill_text(canvas::Text { - content: color_hex_str(&self.theme[i]), + content: color_hex_str(&color), position: Point { x: anchor.x + box_size.width / 2.0, y: box_size.height, @@ -438,9 +423,9 @@ impl canvas::Drawable for State { text.vertical_alignment = VerticalAlignment::Bottom; - let hsl = Hsl::from(Srgb::from(self.color)); - for i in 0..self.theme.len() { - let pct = (i as f32 + 1.0) / (self.theme.len() as f32 + 1.0); + let hsl = Hsl::from(Srgb::from(self.base)); + for i in 0..self.len() { + let pct = (i as f32 + 1.0) / (self.len() as f32 + 1.0); let graded = Hsl { lightness: 1.0 - pct, ..hsl -- cgit From 555371f77e02c962c2312dab7f1f2510b03e352a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 1 May 2020 22:27:14 +0200 Subject: Move application implementation in `color_palette` --- examples/color_palette/src/main.rs | 412 ++++++++++++++++++------------------- 1 file changed, 206 insertions(+), 206 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 97363b75..243fae1d 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -13,6 +13,82 @@ pub fn main() { }) } +#[derive(Default)] +pub struct ColorPalette { + theme: Theme, + rgb: ColorPicker, + hsl: ColorPicker, + hsv: ColorPicker, + hwb: ColorPicker, + lab: ColorPicker, + lch: ColorPicker, + canvas_layer: canvas::layer::Cache, +} + +#[derive(Debug, Clone, Copy)] +pub enum Message { + RgbColorChanged(Color), + HslColorChanged(palette::Hsl), + HsvColorChanged(palette::Hsv), + HwbColorChanged(palette::Hwb), + LabColorChanged(palette::Lab), + LchColorChanged(palette::Lch), +} + +impl Sandbox for ColorPalette { + type Message = Message; + + fn new() -> Self { + Self::default() + } + + fn title(&self) -> String { + String::from("Color palette - Iced") + } + + fn update(&mut self, message: Message) { + let srgb = match message { + Message::RgbColorChanged(rgb) => palette::Srgb::from(rgb), + Message::HslColorChanged(hsl) => palette::Srgb::from(hsl), + Message::HsvColorChanged(hsv) => palette::Srgb::from(hsv), + Message::HwbColorChanged(hwb) => palette::Srgb::from(hwb), + Message::LabColorChanged(lab) => palette::Srgb::from(lab), + Message::LchColorChanged(lch) => palette::Srgb::from(lch), + }; + + self.theme = Theme::new(srgb.clamp()); + self.canvas_layer.clear(); + } + + fn view(&mut self) -> Element { + let base = self.theme.base; + + let srgb = palette::Srgb::from(base); + let hsl = palette::Hsl::from(srgb); + let hsv = palette::Hsv::from(srgb); + let hwb = palette::Hwb::from(srgb); + let lab = palette::Lab::from(srgb); + let lch = palette::Lch::from(srgb); + + Column::new() + .padding(10) + .spacing(10) + .push(self.rgb.view(base).map(Message::RgbColorChanged)) + .push(self.hsl.view(hsl).map(Message::HslColorChanged)) + .push(self.hsv.view(hsv).map(Message::HsvColorChanged)) + .push(self.hwb.view(hwb).map(Message::HwbColorChanged)) + .push(self.lab.view(lab).map(Message::LabColorChanged)) + .push(self.lch.view(lch).map(Message::LchColorChanged)) + .push( + Canvas::new() + .width(Length::Fill) + .height(Length::Fill) + .push(self.canvas_layer.with(&self.theme)), + ) + .into() + } +} + #[derive(Debug)] pub struct Theme { lower: Vec, @@ -20,12 +96,6 @@ pub struct Theme { higher: Vec, } -impl Default for Theme { - fn default() -> Self { - Theme::new(Color::from_rgb8(75, 128, 190)) - } -} - impl Theme { pub fn new(base: impl Into) -> Theme { use palette::{Hsl, Hue, Shade, Srgb}; @@ -74,6 +144,136 @@ impl Theme { } } +impl canvas::Drawable for Theme { + fn draw(&self, frame: &mut canvas::Frame) { + use canvas::{Fill, Path}; + use iced::{HorizontalAlignment, VerticalAlignment}; + use iced_native::{Point, Size}; + use palette::{Hsl, Srgb}; + + let pad = 20.0; + + let box_size = Size { + width: frame.width() / self.len() as f32, + height: frame.height() / 2.0 - pad, + }; + + let mut text = canvas::Text { + horizontal_alignment: HorizontalAlignment::Center, + vertical_alignment: VerticalAlignment::Top, + size: 15.0, + ..canvas::Text::default() + }; + + for (i, &color) in self.colors().enumerate() { + let anchor = Point { + x: (i as f32) * box_size.width, + y: 0.0, + }; + let rect = Path::new(|path| { + path.rectangle(anchor, box_size); + }); + frame.fill(&rect, Fill::Color(color)); + + if self.base == color { + let cx = anchor.x + box_size.width / 2.0; + let tri_w = 10.0; + + let tri = Path::new(|path| { + path.move_to(Point { + x: cx - tri_w, + y: 0.0, + }); + path.line_to(Point { + x: cx + tri_w, + y: 0.0, + }); + path.line_to(Point { x: cx, y: tri_w }); + path.line_to(Point { + x: cx - tri_w, + y: 0.0, + }); + }); + frame.fill(&tri, Fill::Color(Color::WHITE)); + + let tri = Path::new(|path| { + path.move_to(Point { + x: cx - tri_w, + y: box_size.height, + }); + path.line_to(Point { + x: cx + tri_w, + y: box_size.height, + }); + path.line_to(Point { + x: cx, + y: box_size.height - tri_w, + }); + path.line_to(Point { + x: cx - tri_w, + y: box_size.height, + }); + }); + frame.fill(&tri, Fill::Color(Color::WHITE)); + } + + frame.fill_text(canvas::Text { + content: color_hex_string(&color), + position: Point { + x: anchor.x + box_size.width / 2.0, + y: box_size.height, + }, + ..text + }); + } + + text.vertical_alignment = VerticalAlignment::Bottom; + + let hsl = Hsl::from(Srgb::from(self.base)); + for i in 0..self.len() { + let pct = (i as f32 + 1.0) / (self.len() as f32 + 1.0); + let graded = Hsl { + lightness: 1.0 - pct, + ..hsl + }; + let color: Color = Srgb::from(graded.clamp()).into(); + + let anchor = Point { + x: (i as f32) * box_size.width, + y: box_size.height + 2.0 * pad, + }; + let rect = Path::new(|path| { + path.rectangle(anchor, box_size); + }); + frame.fill(&rect, Fill::Color(color)); + + frame.fill_text(canvas::Text { + content: color_hex_string(&color), + position: Point { + x: anchor.x + box_size.width / 2.0, + y: box_size.height + 2.0 * pad, + }, + ..text + }); + } + } +} + +impl Default for Theme { + fn default() -> Self { + Theme::new(Color::from_rgb8(75, 128, 190)) + } +} + +fn color_hex_string(color: &Color) -> String { + format!( + "#{:x}{:x}{:x}", + (255.0 * color.r).round() as u8, + (255.0 * color.g).round() as u8, + (255.0 * color.b).round() as u8 + ) +} + #[derive(Default)] struct ColorPicker { sliders: [slider::State; 3], @@ -261,203 +461,3 @@ impl ColorSpace for palette::Lch { ) } } - -#[derive(Default)] -pub struct ColorPalette { - theme: Theme, - rgb: ColorPicker, - hsl: ColorPicker, - hsv: ColorPicker, - hwb: ColorPicker, - lab: ColorPicker, - lch: ColorPicker, - canvas_layer: canvas::layer::Cache, -} - -#[derive(Debug, Clone, Copy)] -pub enum Message { - RgbColorChanged(Color), - HslColorChanged(palette::Hsl), - HsvColorChanged(palette::Hsv), - HwbColorChanged(palette::Hwb), - LabColorChanged(palette::Lab), - LchColorChanged(palette::Lch), -} - -impl Sandbox for ColorPalette { - type Message = Message; - - fn new() -> Self { - Self::default() - } - - fn title(&self) -> String { - String::from("Color Palette") - } - - fn update(&mut self, message: Message) { - let srgb = match message { - Message::RgbColorChanged(rgb) => palette::Srgb::from(rgb), - Message::HslColorChanged(hsl) => palette::Srgb::from(hsl), - Message::HsvColorChanged(hsv) => palette::Srgb::from(hsv), - Message::HwbColorChanged(hwb) => palette::Srgb::from(hwb), - Message::LabColorChanged(lab) => palette::Srgb::from(lab), - Message::LchColorChanged(lch) => palette::Srgb::from(lch), - }; - - self.theme = Theme::new(srgb.clamp()); - self.canvas_layer.clear(); - } - - fn view(&mut self) -> Element { - let base = self.theme.base; - - let srgb = palette::Srgb::from(base); - let hsl = palette::Hsl::from(srgb); - let hsv = palette::Hsv::from(srgb); - let hwb = palette::Hwb::from(srgb); - let lab = palette::Lab::from(srgb); - let lch = palette::Lch::from(srgb); - - Column::new() - .padding(10) - .spacing(10) - .push(self.rgb.view(base).map(Message::RgbColorChanged)) - .push(self.hsl.view(hsl).map(Message::HslColorChanged)) - .push(self.hsv.view(hsv).map(Message::HsvColorChanged)) - .push(self.hwb.view(hwb).map(Message::HwbColorChanged)) - .push(self.lab.view(lab).map(Message::LabColorChanged)) - .push(self.lch.view(lch).map(Message::LchColorChanged)) - .push( - Canvas::new() - .width(Length::Fill) - .height(Length::Fill) - .push(self.canvas_layer.with(&self.theme)), - ) - .into() - } -} - -impl canvas::Drawable for Theme { - fn draw(&self, frame: &mut canvas::Frame) { - use canvas::{Fill, Path}; - use iced::{HorizontalAlignment, VerticalAlignment}; - use iced_native::{Point, Size}; - use palette::{Hsl, Srgb}; - - let pad = 20.0; - - let box_size = Size { - width: frame.width() / self.len() as f32, - height: frame.height() / 2.0 - pad, - }; - - let mut text = canvas::Text { - horizontal_alignment: HorizontalAlignment::Center, - vertical_alignment: VerticalAlignment::Top, - size: 15.0, - ..canvas::Text::default() - }; - - for (i, &color) in self.colors().enumerate() { - let anchor = Point { - x: (i as f32) * box_size.width, - y: 0.0, - }; - let rect = Path::new(|path| { - path.rectangle(anchor, box_size); - }); - frame.fill(&rect, Fill::Color(color)); - - if self.base == color { - let cx = anchor.x + box_size.width / 2.0; - let tri_w = 10.0; - - let tri = Path::new(|path| { - path.move_to(Point { - x: cx - tri_w, - y: 0.0, - }); - path.line_to(Point { - x: cx + tri_w, - y: 0.0, - }); - path.line_to(Point { x: cx, y: tri_w }); - path.line_to(Point { - x: cx - tri_w, - y: 0.0, - }); - }); - frame.fill(&tri, Fill::Color(Color::WHITE)); - - let tri = Path::new(|path| { - path.move_to(Point { - x: cx - tri_w, - y: box_size.height, - }); - path.line_to(Point { - x: cx + tri_w, - y: box_size.height, - }); - path.line_to(Point { - x: cx, - y: box_size.height - tri_w, - }); - path.line_to(Point { - x: cx - tri_w, - y: box_size.height, - }); - }); - frame.fill(&tri, Fill::Color(Color::WHITE)); - } - - frame.fill_text(canvas::Text { - content: color_hex_str(&color), - position: Point { - x: anchor.x + box_size.width / 2.0, - y: box_size.height, - }, - ..text - }); - } - - text.vertical_alignment = VerticalAlignment::Bottom; - - let hsl = Hsl::from(Srgb::from(self.base)); - for i in 0..self.len() { - let pct = (i as f32 + 1.0) / (self.len() as f32 + 1.0); - let graded = Hsl { - lightness: 1.0 - pct, - ..hsl - }; - let color: Color = Srgb::from(graded.clamp()).into(); - - let anchor = Point { - x: (i as f32) * box_size.width, - y: box_size.height + 2.0 * pad, - }; - let rect = Path::new(|path| { - path.rectangle(anchor, box_size); - }); - frame.fill(&rect, Fill::Color(color)); - - frame.fill_text(canvas::Text { - content: color_hex_str(&color), - position: Point { - x: anchor.x + box_size.width / 2.0, - y: box_size.height + 2.0 * pad, - }, - ..text - }); - } - } -} - -fn color_hex_str(color: &Color) -> String { - format!( - "#{:x}{:x}{:x}", - (255.0 * color.r).round() as u8, - (255.0 * color.g).round() as u8, - (255.0 * color.b).round() as u8 - ) -} -- cgit From 573929d5ec99981ae3a4a0d675f1248932d56e61 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 1 May 2020 22:32:40 +0200 Subject: Use `Path::rectangle` directly in `color_palette` --- examples/color_palette/src/main.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 243fae1d..ff399e76 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -170,9 +170,7 @@ impl canvas::Drawable for Theme { x: (i as f32) * box_size.width, y: 0.0, }; - let rect = Path::new(|path| { - path.rectangle(anchor, box_size); - }); + let rect = Path::rectangle(anchor, box_size); frame.fill(&rect, Fill::Color(color)); if self.base == color { @@ -242,9 +240,8 @@ impl canvas::Drawable for Theme { x: (i as f32) * box_size.width, y: box_size.height + 2.0 * pad, }; - let rect = Path::new(|path| { - path.rectangle(anchor, box_size); - }); + + let rect = Path::rectangle(anchor, box_size); frame.fill(&rect, Fill::Color(color)); frame.fill_text(canvas::Text { -- cgit From 03ca7eea6c05b32c6273284c35883506e4cf6eb1 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 1 May 2020 22:45:47 +0200 Subject: Reuse triangle path with transforms in `color_palette` --- examples/color_palette/src/main.rs | 71 +++++++++++++++----------------------- 1 file changed, 28 insertions(+), 43 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index ff399e76..b3ad98d0 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -1,6 +1,6 @@ use iced::{ canvas, slider, Align, Canvas, Color, Column, Element, Length, Row, - Sandbox, Settings, Slider, Text, + Sandbox, Settings, Slider, Text, Vector, }; use palette::{self, Limited}; use std::marker::PhantomData; @@ -146,7 +146,7 @@ impl Theme { impl canvas::Drawable for Theme { fn draw(&self, frame: &mut canvas::Frame) { - use canvas::{Fill, Path}; + use canvas::Path; use iced::{HorizontalAlignment, VerticalAlignment}; use iced_native::{Point, Size}; use palette::{Hsl, Srgb}; @@ -158,6 +158,13 @@ impl canvas::Drawable for Theme { height: frame.height() / 2.0 - pad, }; + let triangle = Path::new(|path| { + path.move_to(Point { x: 0.0, y: -0.5 }); + path.line_to(Point { x: -0.5, y: 0.0 }); + path.line_to(Point { x: 0.5, y: 0.0 }); + path.close(); + }); + let mut text = canvas::Text { horizontal_alignment: HorizontalAlignment::Center, vertical_alignment: VerticalAlignment::Top, @@ -171,48 +178,26 @@ impl canvas::Drawable for Theme { y: 0.0, }; let rect = Path::rectangle(anchor, box_size); - frame.fill(&rect, Fill::Color(color)); - - if self.base == color { - let cx = anchor.x + box_size.width / 2.0; - let tri_w = 10.0; - - let tri = Path::new(|path| { - path.move_to(Point { - x: cx - tri_w, - y: 0.0, - }); - path.line_to(Point { - x: cx + tri_w, - y: 0.0, - }); - path.line_to(Point { x: cx, y: tri_w }); - path.line_to(Point { - x: cx - tri_w, - y: 0.0, - }); + frame.fill(&rect, color); + + // We show a little indicator for the base color + if color == self.base { + let triangle_x = anchor.x + box_size.width / 2.0; + + frame.with_save(|frame| { + frame.translate(Vector::new(triangle_x, 0.0)); + frame.scale(10.0); + frame.rotate(std::f32::consts::PI); + + frame.fill(&triangle, Color::WHITE); }); - frame.fill(&tri, Fill::Color(Color::WHITE)); - - let tri = Path::new(|path| { - path.move_to(Point { - x: cx - tri_w, - y: box_size.height, - }); - path.line_to(Point { - x: cx + tri_w, - y: box_size.height, - }); - path.line_to(Point { - x: cx, - y: box_size.height - tri_w, - }); - path.line_to(Point { - x: cx - tri_w, - y: box_size.height, - }); + + frame.with_save(|frame| { + frame.translate(Vector::new(triangle_x, box_size.height)); + frame.scale(10.0); + + frame.fill(&triangle, Color::WHITE); }); - frame.fill(&tri, Fill::Color(Color::WHITE)); } frame.fill_text(canvas::Text { @@ -242,7 +227,7 @@ impl canvas::Drawable for Theme { }; let rect = Path::rectangle(anchor, box_size); - frame.fill(&rect, Fill::Color(color)); + frame.fill(&rect, color); frame.fill_text(canvas::Text { content: color_hex_string(&color), -- cgit From 24574b355d8c5c5e624524c6974df822da98befb Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 4 May 2020 22:50:25 +0200 Subject: Mention `color_palette` in examples `README` --- examples/README.md | 1 + 1 file changed, 1 insertion(+) (limited to 'examples') diff --git a/examples/README.md b/examples/README.md index 5aea51eb..f67a0dd2 100644 --- a/examples/README.md +++ b/examples/README.md @@ -71,6 +71,7 @@ A bunch of simpler examples exist: - [`bezier_tool`](bezier_tool), a Paint-like tool for drawing Bézier curves using [`lyon`]. - [`clock`](clock), an application that uses the `Canvas` widget to draw a clock and its hands to display the current time. +- [`color_palette`](color_palette), a color palette generator based on a user-defined root color. - [`counter`](counter), the classic counter example explained in the [`README`](../README.md). - [`custom_widget`](custom_widget), a demonstration of how to build a custom widget that draws a circle. - [`download_progress`](download_progress), a basic application that asynchronously downloads a dummy file of 100 MB and tracks the download progress. -- cgit From 1a8d253611d3796b0a32b2f096bb54565a5292e0 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 4 May 2020 22:51:20 +0200 Subject: Add screenshot of `color_palette` example --- examples/color_palette/screenshot.png | Bin 0 -> 105201 bytes examples/color_palette/src/main.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 examples/color_palette/screenshot.png (limited to 'examples') diff --git a/examples/color_palette/screenshot.png b/examples/color_palette/screenshot.png new file mode 100644 index 00000000..aa4772e0 Binary files /dev/null and b/examples/color_palette/screenshot.png differ diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index b3ad98d0..0092c6ad 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -289,7 +289,7 @@ impl ColorPicker { .push( Text::new(color.to_string()) .width(Length::Units(185)) - .size(16), + .size(14), ) .into() } -- cgit From 3d3e51a742ec940e19271897a8266172bffd6587 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 4 May 2020 22:53:07 +0200 Subject: Add screenshot to `README` of `color_palette` --- examples/color_palette/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'examples') diff --git a/examples/color_palette/README.md b/examples/color_palette/README.md index b646f3b3..e70188f8 100644 --- a/examples/color_palette/README.md +++ b/examples/color_palette/README.md @@ -1,7 +1,13 @@ -## Color Palette +## Color palette A color palette generator, based on a user-defined root color. + + You can run it with `cargo run`: ``` -- cgit From e3555174d7c12599d454cbe890248449dc3ea958 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 4 May 2020 22:55:10 +0200 Subject: Use only `iced` dependency for `color_palette` `Point` and `Size` are now properly re-exported. --- examples/color_palette/Cargo.toml | 2 -- examples/color_palette/src/main.rs | 7 +++---- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'examples') diff --git a/examples/color_palette/Cargo.toml b/examples/color_palette/Cargo.toml index 61c9f6b2..00f33e20 100644 --- a/examples/color_palette/Cargo.toml +++ b/examples/color_palette/Cargo.toml @@ -7,6 +7,4 @@ publish = false [dependencies] iced = { path = "../..", features = ["canvas", "palette"] } -iced_core = { path = "../../core" } -iced_native = { path = "../../native" } palette = "0.5.0" diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 0092c6ad..073a6734 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -1,6 +1,7 @@ use iced::{ - canvas, slider, Align, Canvas, Color, Column, Element, Length, Row, - Sandbox, Settings, Slider, Text, Vector, + canvas, slider, Align, Canvas, Color, Column, Element, HorizontalAlignment, + Length, Point, Row, Sandbox, Settings, Size, Slider, Text, Vector, + VerticalAlignment, }; use palette::{self, Limited}; use std::marker::PhantomData; @@ -147,8 +148,6 @@ impl Theme { impl canvas::Drawable for Theme { fn draw(&self, frame: &mut canvas::Frame) { use canvas::Path; - use iced::{HorizontalAlignment, VerticalAlignment}; - use iced_native::{Point, Size}; use palette::{Hsl, Srgb}; let pad = 20.0; -- cgit