diff options
-rw-r--r-- | native/src/widget.rs | 6 | ||||
-rw-r--r-- | native/src/widget/icon.rs | 83 | ||||
-rw-r--r-- | native/src/widget/svg.rs | 103 | ||||
-rw-r--r-- | src/native.rs | 8 |
4 files changed, 110 insertions, 90 deletions
diff --git a/native/src/widget.rs b/native/src/widget.rs index 0cf6a639..ee7232cb 100644 --- a/native/src/widget.rs +++ b/native/src/widget.rs @@ -24,7 +24,7 @@ pub mod button; pub mod checkbox; pub mod column; pub mod container; -pub mod icon; +pub mod svg; pub mod image; pub mod radio; pub mod row; @@ -42,8 +42,6 @@ pub use column::Column; #[doc(no_inline)] pub use container::Container; #[doc(no_inline)] -pub use icon::Icon; -#[doc(no_inline)] pub use image::Image; #[doc(no_inline)] pub use radio::Radio; @@ -54,6 +52,8 @@ pub use scrollable::Scrollable; #[doc(no_inline)] pub use slider::Slider; #[doc(no_inline)] +pub use svg::Svg; +#[doc(no_inline)] pub use text::Text; #[doc(no_inline)] pub use text_input::TextInput; diff --git a/native/src/widget/icon.rs b/native/src/widget/icon.rs deleted file mode 100644 index c324e786..00000000 --- a/native/src/widget/icon.rs +++ /dev/null @@ -1,83 +0,0 @@ -//! Display an icon. -use crate::{ - image, layout, Element, Hasher, Layout, Length, Point, Rectangle, Widget, -}; - -use std::{ - hash::Hash, - path::{Path, PathBuf}, -}; - -/// A simple icon_loader widget. -#[derive(Debug, Clone)] -pub struct Icon { - handle: image::Handle, - size: Length, -} - -impl Icon { - /// Create a new [`Icon`] from the file at `path`. - /// - /// [`Icon`]: struct.Icon.html - pub fn new(path: impl Into<PathBuf>) -> Self { - Icon { - handle: image::Handle::from_path(path), - size: Length::Fill, - } - } - - /// Sets the size of the [`Icon`]. - /// - /// [`Icon`]: struct.Icon.html - pub fn size(mut self, size: Length) -> Self { - self.size = size; - self - } -} - -impl<Message, Renderer> Widget<Message, Renderer> for Icon -where - Renderer: image::Renderer, -{ - fn width(&self) -> Length { - self.size - } - - fn height(&self) -> Length { - self.size - } - - fn layout(&self, _: &Renderer, limits: &layout::Limits) -> layout::Node { - let mut size = limits.width(self.size).height(self.size).max(); - - if size.width > size.height { - size.width = size.height; - } else if size.width < size.height { - size.height = size.width; - } - - 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.size.hash(state); - } -} - -impl<'a, Message, Renderer> From<Icon> for Element<'a, Message, Renderer> -where - Renderer: image::Renderer, -{ - fn from(icon: Icon) -> Element<'a, Message, Renderer> { - Element::new(icon) - } -} 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) + } +} diff --git a/src/native.rs b/src/native.rs index e52b63d3..8c86ec7e 100644 --- a/src/native.rs +++ b/src/native.rs @@ -80,17 +80,17 @@ pub mod widget { pub use iced_winit::image::{Handle, Image}; } - pub mod icon { + pub mod svg { //! Display icons in your user interface. - pub use iced_winit::icon::Icon; + pub use iced_winit::svg::Svg; } pub use iced_winit::{Checkbox, Radio, Text}; #[doc(no_inline)] pub use { - button::Button, icon::Icon, image::Image, scrollable::Scrollable, - slider::Slider, text_input::TextInput, + button::Button, image::Image, scrollable::Scrollable, + slider::Slider, svg::Svg, text_input::TextInput, }; /// A container that distributes its contents vertically. |