//! Display images in your user interface. pub mod viewer; pub use viewer::Viewer; use crate::image; use crate::layout; use crate::renderer; use crate::{Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget}; use std::hash::Hash; /// A frame that displays an image while keeping aspect ratio. /// /// # Example /// /// ``` /// # use iced_native::widget::Image; /// # use iced_native::image; /// # /// let image = Image::::new("resources/ferris.png"); /// ``` /// /// #[derive(Debug, Hash)] pub struct Image { handle: Handle, width: Length, height: Length, } impl Image { /// Creates a new [`Image`] with the given path. pub fn new>(handle: T) -> Self { Image { handle: handle.into(), width: Length::Shrink, height: Length::Shrink, } } /// Sets the width of the [`Image`] boundaries. pub fn width(mut self, width: Length) -> Self { self.width = width; self } /// Sets the height of the [`Image`] boundaries. pub fn height(mut self, height: Length) -> Self { self.height = height; self } } /// Computes the layout of an [`Image`]. pub fn layout( renderer: &Renderer, limits: &layout::Limits, handle: &Handle, width: Length, height: Length, ) -> layout::Node where Renderer: image::Renderer, { let (original_width, original_height) = renderer.dimensions(handle); let mut size = limits .width(width) .height(height) .resolve(Size::new(original_width as f32, original_height as f32)); let aspect_ratio = original_width as f32 / original_height as f32; let viewport_aspect_ratio = size.width / size.height; if viewport_aspect_ratio > aspect_ratio { size.width = original_width as f32 * size.height / original_height as f32; } else { size.height = original_height as f32 * size.width / original_width as f32; } layout::Node::new(size) } /// Hashes the layout attributes of an [`Image`]. pub fn hash_layout( state: &mut Hasher, handle: &Handle, width: Length, height: Length, ) { struct Marker; std::any::TypeId::of::().hash(state); handle.hash(state); width.hash(state); height.hash(state); } impl Widget for Image where Renderer: image::Renderer, Handle: Clone + Hash, { fn width(&self) -> Length { self.width } fn height(&self) -> Length { self.height } fn layout( &self, renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { layout(renderer, limits, &self.handle, self.width, self.height) } fn draw( &self, renderer: &mut Renderer, _style: &renderer::Style, layout: Layout<'_>, _cursor_position: Point, _viewport: &Rectangle, ) { renderer.draw(self.handle.clone(), layout.bounds()); } fn hash_layout(&self, state: &mut Hasher) { hash_layout(state, &self.handle, self.width, self.height) } } impl<'a, Message, Renderer, Handle> From> for Element<'a, Message, Renderer> where Renderer: image::Renderer, Handle: Clone + Hash + 'a, { fn from(image: Image) -> Element<'a, Message, Renderer> { Element::new(image) } }