From 3645d34d6a1ba1247238e830e9eefd52d9e5b986 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 21 Mar 2024 22:27:17 +0100 Subject: Implement composable, type-safe renderer fallback --- widget/src/qr_code.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'widget/src/qr_code.rs') diff --git a/widget/src/qr_code.rs b/widget/src/qr_code.rs index 90c0c970..bc46aaaa 100644 --- a/widget/src/qr_code.rs +++ b/widget/src/qr_code.rs @@ -8,7 +8,6 @@ use crate::core::{ Color, Element, Layout, Length, Point, Rectangle, Size, Theme, Vector, Widget, }; -use crate::graphics::geometry::Renderer as _; use crate::Renderer; use std::cell::RefCell; @@ -92,6 +91,8 @@ impl<'a, Message, Theme> Widget _cursor: mouse::Cursor, _viewport: &Rectangle, ) { + use canvas::Frame; + let state = tree.state.downcast_ref::(); let bounds = layout.bounds(); @@ -142,7 +143,7 @@ impl<'a, Message, Theme> Widget renderer.with_translation( bounds.position() - Point::ORIGIN, |renderer| { - renderer.draw(vec![geometry]); + renderer.draw_geometry(vec![geometry]); }, ); } @@ -161,11 +162,11 @@ where /// The data of a [`QRCode`]. /// /// It stores the contents that will be displayed. -#[derive(Debug)] +#[allow(missing_debug_implementations)] pub struct Data { contents: Vec, width: usize, - cache: canvas::Cache, + cache: canvas::Cache, } impl Data { -- cgit From 53a183fe0d6aed460fbb8155ac9541757277aab3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 22 Mar 2024 01:35:14 +0100 Subject: Restore `canvas::Frame` API --- widget/src/qr_code.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'widget/src/qr_code.rs') diff --git a/widget/src/qr_code.rs b/widget/src/qr_code.rs index bc46aaaa..84898dc0 100644 --- a/widget/src/qr_code.rs +++ b/widget/src/qr_code.rs @@ -91,8 +91,6 @@ impl<'a, Message, Theme> Widget _cursor: mouse::Cursor, _viewport: &Rectangle, ) { - use canvas::Frame; - let state = tree.state.downcast_ref::(); let bounds = layout.bounds(); -- cgit From 1f13a91361258a1607c71f4840a26a6437f88612 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 22 Mar 2024 05:27:31 +0100 Subject: Make `iced_tiny_skia` optional with a `tiny-skia` feature --- widget/src/qr_code.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'widget/src/qr_code.rs') diff --git a/widget/src/qr_code.rs b/widget/src/qr_code.rs index 84898dc0..601e5808 100644 --- a/widget/src/qr_code.rs +++ b/widget/src/qr_code.rs @@ -141,7 +141,9 @@ impl<'a, Message, Theme> Widget renderer.with_translation( bounds.position() - Point::ORIGIN, |renderer| { - renderer.draw_geometry(vec![geometry]); + use crate::graphics::geometry::Renderer as _; + + renderer.draw_geometry(geometry); }, ); } -- cgit From f0ae9a0c38c2532220a7460916604914db94c078 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 24 Mar 2024 05:03:09 +0100 Subject: Use `Catalog` approach for all widgets --- widget/src/qr_code.rs | 94 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 36 deletions(-) (limited to 'widget/src/qr_code.rs') diff --git a/widget/src/qr_code.rs b/widget/src/qr_code.rs index 90c0c970..3cc2c294 100644 --- a/widget/src/qr_code.rs +++ b/widget/src/qr_code.rs @@ -20,22 +20,25 @@ const QUIET_ZONE: usize = 2; /// A type of matrix barcode consisting of squares arranged in a grid which /// can be read by an imaging device, such as a camera. #[allow(missing_debug_implementations)] -pub struct QRCode<'a, Theme = crate::Theme> { +pub struct QRCode<'a, Theme = crate::Theme> +where + Theme: Catalog, +{ data: &'a Data, cell_size: u16, - style: Style<'a, Theme>, + class: Theme::Class<'a>, } -impl<'a, Theme> QRCode<'a, Theme> { +impl<'a, Theme> QRCode<'a, Theme> +where + Theme: Catalog, +{ /// Creates a new [`QRCode`] with the provided [`Data`]. - pub fn new(data: &'a Data) -> Self - where - Theme: DefaultStyle + 'a, - { + pub fn new(data: &'a Data) -> Self { Self { data, cell_size: DEFAULT_CELL_SIZE, - style: Box::new(Theme::default_style), + class: Theme::default(), } } @@ -46,14 +49,27 @@ impl<'a, Theme> QRCode<'a, Theme> { } /// Sets the style of the [`QRCode`]. - pub fn style(mut self, style: impl Fn(&Theme) -> Appearance + 'a) -> Self { - self.style = Box::new(style); + #[must_use] + pub fn style(mut self, style: impl Fn(&Theme) -> Style + 'a) -> Self + where + Theme::Class<'a>: From>, + { + self.class = (Box::new(style) as StyleFn<'a, Theme>).into(); + self + } + + /// Sets the style class of the [`QRCode`]. + #[cfg(feature = "advanced")] + #[must_use] + pub fn class(mut self, class: impl Into>) -> Self { + self.class = class.into(); self } } -impl<'a, Message, Theme> Widget - for QRCode<'a, Theme> +impl<'a, Message, Theme> Widget for QRCode<'a, Theme> +where + Theme: Catalog, { fn tag(&self) -> tree::Tag { tree::Tag::of::() @@ -97,13 +113,13 @@ impl<'a, Message, Theme> Widget let bounds = layout.bounds(); let side_length = self.data.width + 2 * QUIET_ZONE; - let appearance = (self.style)(theme); - let mut last_appearance = state.last_appearance.borrow_mut(); + let style = theme.style(&self.class); + let mut last_style = state.last_style.borrow_mut(); - if Some(appearance) != *last_appearance { + if Some(style) != *last_style { self.data.cache.clear(); - *last_appearance = Some(appearance); + *last_style = Some(style); } // Reuse cache if possible @@ -115,7 +131,7 @@ impl<'a, Message, Theme> Widget frame.fill_rectangle( Point::ORIGIN, Size::new(side_length as f32, side_length as f32), - appearance.background, + style.background, ); // Avoid drawing on the quiet zone @@ -134,7 +150,7 @@ impl<'a, Message, Theme> Widget frame.fill_rectangle( Point::new(column as f32, row as f32), Size::UNIT, - appearance.cell, + style.cell, ); }); }); @@ -151,7 +167,7 @@ impl<'a, Message, Theme> Widget impl<'a, Message, Theme> From> for Element<'a, Message, Theme, Renderer> where - Theme: 'a, + Theme: Catalog + 'a, { fn from(qr_code: QRCode<'a, Theme>) -> Self { Self::new(qr_code) @@ -323,44 +339,50 @@ impl From for Error { #[derive(Default)] struct State { - last_appearance: RefCell>, + last_style: RefCell>, } /// The appearance of a QR code. #[derive(Debug, Clone, Copy, PartialEq)] -pub struct Appearance { +pub struct Style { /// The color of the QR code data cells pub cell: Color, /// The color of the QR code background pub background: Color, } -/// The style of a [`QRCode`]. -pub type Style<'a, Theme> = Box Appearance + 'a>; +/// The theme catalog of a [`QRCode`]. +pub trait Catalog { + /// The item class of the [`Catalog`]. + type Class<'a>; -/// The default style of a [`QRCode`]. -pub trait DefaultStyle { - /// Returns the default style of a [`QRCode`]. - fn default_style(&self) -> Appearance; + /// The default class produced by the [`Catalog`]. + fn default<'a>() -> Self::Class<'a>; + + /// The [`Style`] of a class with the given status. + fn style(&self, class: &Self::Class<'_>) -> Style; } -impl DefaultStyle for Theme { - fn default_style(&self) -> Appearance { - default(self) +/// A styling function for a [`QRCode`]. +pub type StyleFn<'a, Theme> = Box Style + 'a>; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(default) } -} -impl DefaultStyle for Appearance { - fn default_style(&self) -> Appearance { - *self + fn style(&self, class: &Self::Class<'_>) -> Style { + class(self) } } /// The default style of a [`QRCode`]. -pub fn default(theme: &Theme) -> Appearance { +pub fn default(theme: &Theme) -> Style { let palette = theme.palette(); - Appearance { + Style { cell: palette.text, background: palette.background, } -- cgit From 1df1cf82f4c9485533f2566c8490cfe188b4ae6a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 26 Mar 2024 04:22:06 +0100 Subject: Derive `Debug` for `qr_code::Data` in `iced_widget` --- widget/src/qr_code.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'widget/src/qr_code.rs') diff --git a/widget/src/qr_code.rs b/widget/src/qr_code.rs index 300028b9..e064aada 100644 --- a/widget/src/qr_code.rs +++ b/widget/src/qr_code.rs @@ -178,7 +178,7 @@ where /// The data of a [`QRCode`]. /// /// It stores the contents that will be displayed. -#[allow(missing_debug_implementations)] +#[derive(Debug)] pub struct Data { contents: Vec, width: usize, -- cgit