From 555371f77e02c962c2312dab7f1f2510b03e352a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Fri, 1 May 2020 22:27:14 +0200 Subject: [PATCH] Move application implementation in `color_palette` --- examples/color_palette/src/main.rs | 412 ++++++++++++++--------------- 1 file changed, 206 insertions(+), 206 deletions(-) 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 - ) -}