diff options
Diffstat (limited to 'native/src')
-rw-r--r-- | native/src/layout/flex.rs | 5 | ||||
-rw-r--r-- | native/src/widget/container.rs | 19 | ||||
-rw-r--r-- | native/src/widget/image.rs | 15 | ||||
-rw-r--r-- | native/src/widget/svg.rs | 80 |
4 files changed, 85 insertions, 34 deletions
diff --git a/native/src/layout/flex.rs b/native/src/layout/flex.rs index 2f65f1c1..9da75a21 100644 --- a/native/src/layout/flex.rs +++ b/native/src/layout/flex.rs @@ -171,8 +171,5 @@ where let (width, height) = axis.pack(main - padding, cross); let size = limits.resolve(Size::new(width, height)); - Node::with_children( - Size::new(size.width + padding * 2.0, size.height + padding * 2.0), - nodes, - ) + Node::with_children(size.pad(padding), nodes) } diff --git a/native/src/widget/container.rs b/native/src/widget/container.rs index 11ef23a9..34032c3a 100644 --- a/native/src/widget/container.rs +++ b/native/src/widget/container.rs @@ -13,6 +13,7 @@ use std::u32; /// It is normally used for alignment purposes. #[allow(missing_debug_implementations)] pub struct Container<'a, Message, Renderer: self::Renderer> { + padding: u16, width: Length, height: Length, max_width: u32, @@ -35,6 +36,7 @@ where T: Into<Element<'a, Message, Renderer>>, { Container { + padding: 0, width: Length::Shrink, height: Length::Shrink, max_width: u32::MAX, @@ -46,6 +48,14 @@ where } } + /// Sets the padding of the [`Container`]. + /// + /// [`Container`]: struct.Column.html + pub fn padding(mut self, units: u16) -> Self { + self.padding = units; + self + } + /// Sets the width of the [`Container`]. /// /// [`Container`]: struct.Container.html @@ -137,19 +147,23 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { + let padding = f32::from(self.padding); + let limits = limits .loose() .max_width(self.max_width) .max_height(self.max_height) .width(self.width) - .height(self.height); + .height(self.height) + .pad(padding); let mut content = self.content.layout(renderer, &limits.loose()); let size = limits.resolve(content.size()); + content.move_to(Point::new(padding, padding)); content.align(self.horizontal_alignment, self.vertical_alignment, size); - layout::Node::with_children(size, vec![content]) + layout::Node::with_children(size.pad(padding), vec![content]) } fn on_event( @@ -191,6 +205,7 @@ where fn hash_layout(&self, state: &mut Hasher) { std::any::TypeId::of::<Container<'_, (), Renderer>>().hash(state); + self.padding.hash(state); self.width.hash(state); self.height.hash(state); self.max_width.hash(state); diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs index 9dc13fa9..0f38a90e 100644 --- a/native/src/widget/image.rs +++ b/native/src/widget/image.rs @@ -177,15 +177,12 @@ impl Handle { } } -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) +impl<T> From<T> for Handle +where + T: Into<PathBuf>, +{ + fn from(path: T) -> Handle { + Handle::from_path(path.into()) } } diff --git a/native/src/widget/svg.rs b/native/src/widget/svg.rs index 4a227f3d..114d5e41 100644 --- a/native/src/widget/svg.rs +++ b/native/src/widget/svg.rs @@ -2,8 +2,9 @@ use crate::{layout, Element, Hasher, Layout, Length, Point, Size, Widget}; use std::{ - hash::Hash, - path::{Path, PathBuf}, + hash::{Hash, Hasher as _}, + path::PathBuf, + sync::Arc, }; /// A vector graphics image. @@ -34,6 +35,14 @@ impl Svg { } } + /// Creates a new [`Svg`] that will display the contents of the file at the + /// provided path. + /// + /// [`Svg`]: struct.Svg.html + pub fn from_path(path: impl Into<PathBuf>) -> Self { + Self::new(Handle::from_path(path)) + } + /// Sets the width of the [`Svg`]. /// /// [`Svg`]: struct.Svg.html @@ -101,6 +110,7 @@ where fn hash_layout(&self, state: &mut Hasher) { std::any::TypeId::of::<Svg>().hash(state); + self.handle.hash(state); self.width.hash(state); self.height.hash(state); } @@ -112,7 +122,7 @@ where #[derive(Debug, Clone)] pub struct Handle { id: u64, - path: PathBuf, + data: Arc<Data>, } impl Handle { @@ -120,17 +130,28 @@ impl Handle { /// path. /// /// [`Handle`]: struct.Handle.html - pub fn from_path<T: Into<PathBuf>>(path: T) -> Handle { - use std::hash::Hasher as _; + pub fn from_path(path: impl Into<PathBuf>) -> Handle { + Self::from_data(Data::Path(path.into())) + } - let path = path.into(); + /// Creates an SVG [`Handle`] from raw bytes containing either an SVG string + /// or gzip compressed data. + /// + /// This is useful if you already have your SVG data in-memory, maybe + /// because you downloaded or generated it procedurally. + /// + /// [`Handle`]: struct.Handle.html + pub fn from_memory(bytes: impl Into<Vec<u8>>) -> Handle { + Self::from_data(Data::Bytes(bytes.into())) + } + fn from_data(data: Data) -> Handle { let mut hasher = Hasher::default(); - path.hash(&mut hasher); + data.hash(&mut hasher); Handle { id: hasher.finish(), - path, + data: Arc::new(data), } } @@ -141,20 +162,40 @@ impl Handle { self.id } - /// Returns a reference to the path of the [`Handle`]. + /// Returns a reference to the SVG [`Data`]. /// - /// [`Handle`]: enum.Handle.html - pub fn path(&self) -> &Path { - &self.path + /// [`Data`]: enum.Data.html + pub fn data(&self) -> &Data { + &self.data } } -impl<T> From<T> for Handle -where - T: Into<PathBuf>, -{ - fn from(path: T) -> Handle { - Handle::from_path(path) +impl Hash for Handle { + fn hash<H: std::hash::Hasher>(&self, state: &mut H) { + self.id.hash(state); + } +} + +/// The data of an [`Svg`]. +/// +/// [`Svg`]: struct.Svg.html +#[derive(Clone, Hash)] +pub enum Data { + /// File data + Path(PathBuf), + + /// In-memory data + /// + /// Can contain an SVG string or a gzip compressed data. + Bytes(Vec<u8>), +} + +impl std::fmt::Debug for Data { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Data::Path(path) => write!(f, "Path({:?})", path), + Data::Bytes(_) => write!(f, "Bytes(...)"), + } } } @@ -166,9 +207,10 @@ where /// [`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. + /// Returns the default dimensions of an [`Svg`] for the given [`Handle`]. /// /// [`Svg`]: struct.Svg.html + /// [`Handle`]: struct.Handle.html fn dimensions(&self, handle: &Handle) -> (u32, u32); /// Draws an [`Svg`]. |