summaryrefslogtreecommitdiffstats
path: root/widget/src/svg.rs
diff options
context:
space:
mode:
authorLibravatar Gigas002 <24297712+Gigas002@users.noreply.github.com>2024-03-27 19:47:48 +0900
committerLibravatar GitHub <noreply@github.com>2024-03-27 19:47:48 +0900
commit19afc66cadfc7ea230d4d749b0d7b0197e29cf93 (patch)
treed012dff84003f2d7d18a1e6bc4bdac62df73b322 /widget/src/svg.rs
parent4334e63ba1dd88b367f3b7f2790b7869d11d12c0 (diff)
parent1df1cf82f4c9485533f2566c8490cfe188b4ae6a (diff)
downloadiced-19afc66cadfc7ea230d4d749b0d7b0197e29cf93.tar.gz
iced-19afc66cadfc7ea230d4d749b0d7b0197e29cf93.tar.bz2
iced-19afc66cadfc7ea230d4d749b0d7b0197e29cf93.zip
Merge branch 'master' into viewer_content_fit
Diffstat (limited to 'widget/src/svg.rs')
-rw-r--r--widget/src/svg.rs97
1 files changed, 60 insertions, 37 deletions
diff --git a/widget/src/svg.rs b/widget/src/svg.rs
index 1ac07ade..eb142189 100644
--- a/widget/src/svg.rs
+++ b/widget/src/svg.rs
@@ -20,36 +20,36 @@ pub use crate::core::svg::Handle;
/// [`Svg`] images can have a considerable rendering cost when resized,
/// specially when they are complex.
#[allow(missing_debug_implementations)]
-pub struct Svg<'a, Theme = crate::Theme> {
+pub struct Svg<'a, Theme = crate::Theme>
+where
+ Theme: Catalog,
+{
handle: Handle,
width: Length,
height: Length,
content_fit: ContentFit,
- style: Style<'a, Theme>,
+ class: Theme::Class<'a>,
}
-impl<'a, Theme> Svg<'a, Theme> {
+impl<'a, Theme> Svg<'a, Theme>
+where
+ Theme: Catalog,
+{
/// Creates a new [`Svg`] from the given [`Handle`].
- pub fn new(handle: impl Into<Handle>) -> Self
- where
- Theme: DefaultStyle + 'a,
- {
+ pub fn new(handle: impl Into<Handle>) -> Self {
Svg {
handle: handle.into(),
width: Length::Fill,
height: Length::Shrink,
content_fit: ContentFit::Contain,
- style: Box::new(Theme::default_style),
+ class: Theme::default(),
}
}
/// Creates a new [`Svg`] that will display the contents of the file at the
/// provided path.
#[must_use]
- pub fn from_path(path: impl Into<PathBuf>) -> Self
- where
- Theme: DefaultStyle + 'a,
- {
+ pub fn from_path(path: impl Into<PathBuf>) -> Self {
Self::new(Handle::from_path(path))
}
@@ -78,13 +78,21 @@ impl<'a, Theme> Svg<'a, Theme> {
}
}
- /// Sets the style variant of this [`Svg`].
+ /// Sets the style of the [`Svg`].
+ #[must_use]
+ pub fn style(mut self, style: impl Fn(&Theme, Status) -> Style + 'a) -> Self
+ where
+ Theme::Class<'a>: From<StyleFn<'a, Theme>>,
+ {
+ self.class = (Box::new(style) as StyleFn<'a, Theme>).into();
+ self
+ }
+
+ /// Sets the style class of the [`Svg`].
+ #[cfg(feature = "advanced")]
#[must_use]
- pub fn style(
- mut self,
- style: impl Fn(&Theme, Status) -> Appearance + 'a,
- ) -> Self {
- self.style = Box::new(style);
+ pub fn class(mut self, class: impl Into<Theme::Class<'a>>) -> Self {
+ self.class = class.into();
self
}
}
@@ -93,6 +101,7 @@ impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
for Svg<'a, Theme>
where
Renderer: svg::Renderer,
+ Theme: Catalog,
{
fn size(&self) -> Size<Length> {
Size {
@@ -108,7 +117,7 @@ where
limits: &layout::Limits,
) -> layout::Node {
// The raw w/h of the underlying image
- let Size { width, height } = renderer.dimensions(&self.handle);
+ let Size { width, height } = renderer.measure_svg(&self.handle);
let image_size = Size::new(width as f32, height as f32);
// The size to be available to the widget prior to `Shrink`ing
@@ -142,7 +151,7 @@ where
cursor: mouse::Cursor,
_viewport: &Rectangle,
) {
- let Size { width, height } = renderer.dimensions(&self.handle);
+ let Size { width, height } = renderer.measure_svg(&self.handle);
let image_size = Size::new(width as f32, height as f32);
let bounds = layout.bounds();
@@ -167,11 +176,11 @@ where
Status::Idle
};
- let appearance = (self.style)(theme, status);
+ let style = theme.style(&self.class, status);
- renderer.draw(
+ renderer.draw_svg(
self.handle.clone(),
- appearance.color,
+ style.color,
drawing_bounds + offset,
);
};
@@ -189,7 +198,7 @@ where
impl<'a, Message, Theme, Renderer> From<Svg<'a, Theme>>
for Element<'a, Message, Theme, Renderer>
where
- Theme: 'a,
+ Theme: Catalog + 'a,
Renderer: svg::Renderer + 'a,
{
fn from(icon: Svg<'a, Theme>) -> Element<'a, Message, Theme, Renderer> {
@@ -208,7 +217,7 @@ pub enum Status {
/// The appearance of an [`Svg`].
#[derive(Debug, Clone, Copy, PartialEq, Default)]
-pub struct Appearance {
+pub struct Style {
/// The [`Color`] filter of an [`Svg`].
///
/// Useful for coloring a symbolic icon.
@@ -217,23 +226,37 @@ pub struct Appearance {
pub color: Option<Color>,
}
-/// The style of an [`Svg`].
-pub type Style<'a, Theme> = Box<dyn Fn(&Theme, Status) -> Appearance + 'a>;
+/// The theme catalog of an [`Svg`].
+pub trait Catalog {
+ /// The item class of the [`Catalog`].
+ type Class<'a>;
+
+ /// The default class produced by the [`Catalog`].
+ fn default<'a>() -> Self::Class<'a>;
-/// The default style of an [`Svg`].
-pub trait DefaultStyle {
- /// Returns the default style of an [`Svg`].
- fn default_style(&self, status: Status) -> Appearance;
+ /// The [`Style`] of a class with the given status.
+ fn style(&self, class: &Self::Class<'_>, status: Status) -> Style;
}
-impl DefaultStyle for Theme {
- fn default_style(&self, _status: Status) -> Appearance {
- Appearance::default()
+impl Catalog for Theme {
+ type Class<'a> = StyleFn<'a, Self>;
+
+ fn default<'a>() -> Self::Class<'a> {
+ Box::new(|_theme, _status| Style::default())
+ }
+
+ fn style(&self, class: &Self::Class<'_>, status: Status) -> Style {
+ class(self, status)
}
}
-impl DefaultStyle for Appearance {
- fn default_style(&self, _status: Status) -> Appearance {
- *self
+/// A styling function for an [`Svg`].
+///
+/// This is just a boxed closure: `Fn(&Theme, Status) -> Style`.
+pub type StyleFn<'a, Theme> = Box<dyn Fn(&Theme, Status) -> Style + 'a>;
+
+impl<'a, Theme> From<Style> for StyleFn<'a, Theme> {
+ fn from(style: Style) -> Self {
+ Box::new(move |_theme, _status| style)
}
}