diff options
Diffstat (limited to 'native/src/widget/image.rs')
-rw-r--r-- | native/src/widget/image.rs | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs index b2541b87..8420ca76 100644 --- a/native/src/widget/image.rs +++ b/native/src/widget/image.rs @@ -1,10 +1,58 @@ //! Display images in your user interface. -use crate::{layout, Element, Hasher, Layout, Point, Widget}; +use crate::{layout, Element, Hasher, Layout, Length, Point, Size, Widget}; use std::hash::Hash; -pub use iced_core::Image; +/// A frame that displays an image while keeping aspect ratio. +/// +/// # Example +/// +/// ``` +/// # use iced_native::Image; +/// +/// let image = Image::new("resources/ferris.png"); +/// ``` +#[derive(Debug)] +pub struct Image { + /// The image path + pub path: String, + + /// The width of the image + pub width: Length, + + /// The height of the image + pub height: Length, +} + +impl Image { + /// Creates a new [`Image`] with the given path. + /// + /// [`Image`]: struct.Image.html + pub fn new<T: Into<String>>(path: T) -> Self { + Image { + path: path.into(), + width: Length::Shrink, + height: Length::Shrink, + } + } + + /// Sets the width of the [`Image`] boundaries. + /// + /// [`Image`]: struct.Image.html + pub fn width(mut self, width: Length) -> Self { + self.width = width; + self + } + + /// Sets the height of the [`Image`] boundaries. + /// + /// [`Image`]: struct.Image.html + pub fn height(mut self, height: Length) -> Self { + self.height = height; + self + } +} impl<Message, Renderer> Widget<Message, Renderer> for Image where @@ -15,7 +63,26 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - renderer.layout(&self, limits) + let (width, height) = renderer.dimensions(&self.path); + + let aspect_ratio = width as f32 / height as f32; + + // TODO: Deal with additional cases + let (width, height) = match (self.width, self.height) { + (Length::Units(width), _) => ( + self.width, + Length::Units((width as f32 / aspect_ratio).round() as u16), + ), + (_, _) => { + (Length::Units(width as u16), Length::Units(height as u16)) + } + }; + + let mut size = limits.width(width).height(height).resolve(Size::ZERO); + + size.height = size.width / aspect_ratio; + + layout::Node::new(size) } fn draw( @@ -41,13 +108,7 @@ where /// [`Image`]: struct.Image.html /// [renderer]: ../../renderer/index.html pub trait Renderer: crate::Renderer { - /// Creates a [`Node`] for the provided [`Image`]. - /// - /// You should probably keep the original aspect ratio, if possible. - /// - /// [`Node`]: ../../struct.Node.html - /// [`Image`]: struct.Image.html - fn layout(&self, image: &Image, limits: &layout::Limits) -> layout::Node; + fn dimensions(&self, path: &str) -> (u32, u32); /// Draws an [`Image`]. /// |