diff options
author | 2019-12-12 01:25:18 +0100 | |
---|---|---|
committer | 2019-12-12 01:25:18 +0100 | |
commit | 27717bc70c3947f553a8b75da9789fe967994a31 (patch) | |
tree | 96c43a10601497c9a1c813dd7ee170515dde79b8 /native/src/widget/svg.rs | |
parent | 895eaef99b52c24e6f3d804897ad850c1f1de960 (diff) | |
download | iced-27717bc70c3947f553a8b75da9789fe967994a31.tar.gz iced-27717bc70c3947f553a8b75da9789fe967994a31.tar.bz2 iced-27717bc70c3947f553a8b75da9789fe967994a31.zip |
Renamed `Icon` widget to `Svg` and gave it separate width and height.
The aspect ratio is now preserved like in the `Image` widget.
Diffstat (limited to 'native/src/widget/svg.rs')
-rw-r--r-- | native/src/widget/svg.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/native/src/widget/svg.rs b/native/src/widget/svg.rs new file mode 100644 index 00000000..097c1d86 --- /dev/null +++ b/native/src/widget/svg.rs @@ -0,0 +1,103 @@ +//! Display an icon. +use crate::{ + image, layout, Element, Hasher, Layout, Length, Point, Size, Widget, +}; + +use std::{ + hash::Hash, + path::PathBuf, +}; + +/// A simple icon_loader widget. +#[derive(Debug, Clone)] +pub struct Svg { + handle: image::Handle, + width: Length, + height: Length, +} + +impl Svg { + /// Create a new [`Svg`] from the file at `path`. + /// + /// [`Svg`]: struct.Svg.html + pub fn new(path: impl Into<PathBuf>) -> Self { + Svg { + handle: image::Handle::from_path(path), + width: Length::Fill, + height: Length::Fill, + } + } + + /// Sets the width of the [`Svg`]. + /// + /// [`Svg`]: struct.Svg.html + pub fn width(mut self, width: Length) -> Self { + self.width = width; + self + } + + /// Sets the height of the [`Svg`]. + /// + /// [`Svg`]: struct.Svg.html + pub fn height(mut self, height: Length) -> Self { + self.height = height; + self + } +} + +impl<Message, Renderer> Widget<Message, Renderer> for Svg +where + Renderer: image::Renderer, +{ + fn width(&self) -> Length { + self.width + } + + fn height(&self) -> Length { + self.height + } + + 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; + + let mut size = limits + .width(self.width) + .height(self.height) + .max(); + + let viewport_aspect_ratio = size.width / size.height; + + if viewport_aspect_ratio > aspect_ratio { + size.width = width as f32 * size.height / height as f32; + } else { + size.height = height as f32 * size.width / width as f32; + } + + layout::Node::new(size) + } + + fn draw( + &self, + renderer: &mut Renderer, + layout: Layout<'_>, + _cursor_position: Point, + ) -> Renderer::Output { + renderer.draw(self.handle.clone(), layout) + } + + fn hash_layout(&self, state: &mut Hasher) { + self.width.hash(state); + self.height.hash(state); + } +} + +impl<'a, Message, Renderer> From<Svg> for Element<'a, Message, Renderer> +where + Renderer: image::Renderer, +{ + fn from(icon: Svg) -> Element<'a, Message, Renderer> { + Element::new(icon) + } +} |