summaryrefslogtreecommitdiffstats
path: root/native/src/widget/svg.rs
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-12-15 06:19:07 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-12-15 06:19:07 +0100
commit09707f29fcf7fbd71570a43db214921043427c3f (patch)
treeb3e045a64e81f58910c976b0478e6f7f91780ad0 /native/src/widget/svg.rs
parent27717bc70c3947f553a8b75da9789fe967994a31 (diff)
downloadiced-09707f29fcf7fbd71570a43db214921043427c3f.tar.gz
iced-09707f29fcf7fbd71570a43db214921043427c3f.tar.bz2
iced-09707f29fcf7fbd71570a43db214921043427c3f.zip
Rerasterize SVGs when resized and refactor a bit
Diffstat (limited to 'native/src/widget/svg.rs')
-rw-r--r--native/src/widget/svg.rs101
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)