diff options
Diffstat (limited to '')
| -rw-r--r-- | native/src/widget/svg.rs | 101 | 
1 files changed, 89 insertions, 12 deletions
| diff --git a/native/src/widget/svg.rs b/native/src/widget/svg.rs index 097c1d86..42f2ebdf 100644 --- a/native/src/widget/svg.rs +++ b/native/src/widget/svg.rs @@ -1,28 +1,27 @@  //! Display an icon. -use crate::{ -    image, layout, Element, Hasher, Layout, Length, Point, Size, Widget, -}; +use crate::{layout, Element, Hasher, Layout, Length, Point, Size, Widget};  use std::{      hash::Hash, -    path::PathBuf, +    path::{Path, PathBuf},  };  /// A simple icon_loader widget.  #[derive(Debug, Clone)]  pub struct Svg { -    handle: image::Handle, +    handle: Handle,      width: Length,      height: Length,  }  impl Svg { -    /// Create a new [`Svg`] from the file at `path`. +    /// Creates a new [`Svg`] from the given [`Handle`].      ///      /// [`Svg`]: struct.Svg.html -    pub fn new(path: impl Into<PathBuf>) -> Self { +    /// [`Handle`]: struct.Handle.html +    pub fn new(handle: impl Into<Handle>) -> Self {          Svg { -            handle: image::Handle::from_path(path), +            handle: handle.into(),              width: Length::Fill,              height: Length::Fill,          } @@ -47,7 +46,7 @@ impl Svg {  impl<Message, Renderer> Widget<Message, Renderer> for Svg  where -    Renderer: image::Renderer, +    Renderer: self::Renderer,  {      fn width(&self) -> Length {          self.width @@ -57,7 +56,11 @@ where          self.height      } -    fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node { +    fn layout( +        &self, +        renderer: &Renderer, +        limits: &layout::Limits, +    ) -> layout::Node {          let (width, height) = renderer.dimensions(&self.handle);          let aspect_ratio = width as f32 / height as f32; @@ -65,7 +68,7 @@ where          let mut size = limits              .width(self.width)              .height(self.height) -            .max(); +            .resolve(Size::new(width as f32, height as f32));          let viewport_aspect_ratio = size.width / size.height; @@ -93,9 +96,83 @@ where      }  } +/// An [`Svg`] handle. +/// +/// [`Svg`]: struct.Svg.html +#[derive(Debug, Clone)] +pub struct Handle { +    id: u64, +    path: PathBuf, +} + +impl Handle { +    /// Creates an SVG [`Handle`] pointing to the vector image of the given +    /// path. +    /// +    /// [`Handle`]: struct.Handle.html +    pub fn from_path<T: Into<PathBuf>>(path: T) -> Handle { +        use std::hash::Hasher as _; + +        let path = path.into(); + +        let mut hasher = Hasher::default(); +        path.hash(&mut hasher); + +        Handle { +            id: hasher.finish(), +            path, +        } +    } + +    /// Returns the unique identifier of the [`Handle`]. +    /// +    /// [`Handle`]: struct.Handle.html +    pub fn id(&self) -> u64 { +        self.id +    } + +    /// Returns a reference to the path of the [`Handle`]. +    /// +    /// [`Handle`]: enum.Handle.html +    pub fn path(&self) -> &Path { +        &self.path +    } +} + +impl From<String> for Handle { +    fn from(path: String) -> Handle { +        Handle::from_path(path) +    } +} + +impl From<&str> for Handle { +    fn from(path: &str) -> Handle { +        Handle::from_path(path) +    } +} + +/// The renderer of an [`Svg`]. +/// +/// Your [renderer] will need to implement this trait before being able to use +/// an [`Svg`] in your user interface. +/// +/// [`Svg`]: struct.Svg.html +/// [renderer]: ../../renderer/index.html +pub trait Renderer: crate::Renderer { +    /// Returns the default dimensions of an [`Svg`] located on the given path. +    /// +    /// [`Svg`]: struct.Svg.html +    fn dimensions(&self, handle: &Handle) -> (u32, u32); + +    /// Draws an [`Svg`]. +    /// +    /// [`Svg`]: struct.Svg.html +    fn draw(&mut self, handle: Handle, layout: Layout<'_>) -> Self::Output; +} +  impl<'a, Message, Renderer> From<Svg> for Element<'a, Message, Renderer>  where -    Renderer: image::Renderer, +    Renderer: self::Renderer,  {      fn from(icon: Svg) -> Element<'a, Message, Renderer> {          Element::new(icon) | 
