From a28799b65e4440fae72797006eaf30e4f45f38e5 Mon Sep 17 00:00:00 2001 From: Max Unsted Date: Mon, 2 May 2022 16:05:40 +0100 Subject: [PATCH] add pure version of color_palette example --- Cargo.toml | 1 + examples/pure/color_palette/Cargo.toml | 10 + examples/pure/color_palette/README.md | 15 + examples/pure/color_palette/screenshot.png | Bin 0 -> 44798 bytes examples/pure/color_palette/src/main.rs | 465 +++++++++++++++++++++ 5 files changed, 491 insertions(+) create mode 100644 examples/pure/color_palette/Cargo.toml create mode 100644 examples/pure/color_palette/README.md create mode 100644 examples/pure/color_palette/screenshot.png create mode 100644 examples/pure/color_palette/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 56b4d06a..2f6727eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,6 +91,7 @@ members = [ "examples/url_handler", "examples/websocket", "examples/pure/arc", + "examples/pure/color_palette", "examples/pure/component", "examples/pure/counter", "examples/pure/game_of_life", diff --git a/examples/pure/color_palette/Cargo.toml b/examples/pure/color_palette/Cargo.toml new file mode 100644 index 00000000..d08309d5 --- /dev/null +++ b/examples/pure/color_palette/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "pure_color_palette" +version = "0.1.0" +authors = ["Clark Moody "] +edition = "2021" +publish = false + +[dependencies] +iced = { path = "../../..", features = ["pure", "canvas", "palette"] } +palette = "0.6.0" diff --git a/examples/pure/color_palette/README.md b/examples/pure/color_palette/README.md new file mode 100644 index 00000000..f90020b1 --- /dev/null +++ b/examples/pure/color_palette/README.md @@ -0,0 +1,15 @@ +## Color palette + +A color palette generator, based on a user-defined root color. + +
+ + + +
+ +You can run it with `cargo run`: + +``` +cargo run --package pure_color_palette +``` diff --git a/examples/pure/color_palette/screenshot.png b/examples/pure/color_palette/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..e8da35c4d52705b9e6cfc34b9e98101b231b4233 GIT binary patch literal 44798 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 iced::Result { + ColorPalette::run(Settings { + antialiasing: true, + ..Settings::default() + }) +} + +#[derive(Default)] +pub struct ColorPalette { + theme: Theme, + rgb: ColorPicker, + hsl: ColorPicker, + hsv: ColorPicker, + hwb: ColorPicker, + lab: ColorPicker, + lch: ColorPicker, +} + +#[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_color(hsl), + Message::HsvColorChanged(hsv) => palette::Srgb::from_color(hsv), + Message::HwbColorChanged(hwb) => palette::Srgb::from_color(hwb), + Message::LabColorChanged(lab) => palette::Srgb::from_color(lab), + Message::LchColorChanged(lch) => palette::Srgb::from_color(lch), + }; + + self.theme = Theme::new(srgb); + } + + fn view(&self) -> Element { + let base = self.theme.base; + + let srgb = palette::Srgb::from(base); + let hsl = palette::Hsl::from_color(srgb); + let hsv = palette::Hsv::from_color(srgb); + let hwb = palette::Hwb::from_color(srgb); + let lab = palette::Lab::from_color(srgb); + let lch = palette::Lch::from_color(srgb); + + column() + .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(self.theme.view()) + .into() + } +} + +#[derive(Debug)] +pub struct Theme { + lower: Vec, + base: Color, + higher: Vec, + canvas_cache: canvas::Cache, +} + +impl Theme { + pub fn new(base: impl Into) -> Theme { + use palette::{Hue, Shade}; + + let base = base.into(); + + // Convert to HSL color for manipulation + let hsl = Hsl::from_color(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(color).into()) + .collect(), + base, + higher: higher + .iter() + .map(|&color| Srgb::from_color(color).into()) + .collect(), + canvas_cache: canvas::Cache::default(), + } + } + + 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()) + } + + pub fn view(&self) -> Element { + Canvas::new(self) + .width(Length::Fill) + .height(Length::Fill) + .into() + } + + fn draw(&self, frame: &mut Frame) { + let pad = 20.0; + + let box_size = Size { + width: frame.width() / self.len() as f32, + 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: alignment::Horizontal::Center, + vertical_alignment: alignment::Vertical::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, + }; + frame.fill_rectangle(anchor, box_size, 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.with_save(|frame| { + frame.translate(Vector::new(triangle_x, box_size.height)); + frame.scale(10.0); + + frame.fill(&triangle, 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 = alignment::Vertical::Bottom; + + let hsl = Hsl::from_color(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_color(graded).into(); + + let anchor = Point { + x: (i as f32) * box_size.width, + y: box_size.height + 2.0 * pad, + }; + + frame.fill_rectangle(anchor, box_size, 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 canvas::Program for Theme { + type State = (); + + fn draw( + &self, + _state: &Self::State, + _theme: &iced::Theme, + bounds: Rectangle, + _cursor: Cursor, + ) -> Vec { + let theme = self.canvas_cache.draw(bounds.size(), |frame| { + self.draw(frame); + }); + + vec![theme] + } +} + +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 { + 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 to_string(&self) -> String; +} + +impl ColorPicker { + fn view(&self, color: C) -> Element { + let [c1, c2, c3] = color.components(); + let [cr1, cr2, cr3] = C::COMPONENT_RANGES; + + fn slider<'a, C: Clone>( + range: RangeInclusive, + component: f32, + update: impl Fn(f32) -> C + 'a, + ) -> Slider<'a, f64, C, iced::Renderer> { + Slider::new(range, f64::from(component), move |v| update(v as f32)) + .step(0.01) + } + + row() + .spacing(10) + .align_items(Alignment::Center) + .push(text(C::LABEL).width(Length::Units(50))) + .push(slider(cr1, c1, move |v| C::new(v, c2, c3))) + .push(slider(cr2, c2, move |v| C::new(c1, v, c3))) + .push(slider(cr3, c3, move |v| C::new(c1, c2, v))) + .push(text(color.to_string()).width(Length::Units(185)).size(14)) + .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 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 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 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 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 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 to_string(&self) -> String { + format!( + "Lch({:.1}, {:.1}, {:.1})", + self.l, + self.chroma, + self.hue.to_positive_degrees() + ) + } +}