summaryrefslogtreecommitdiffstats
path: root/native/src
diff options
context:
space:
mode:
authorLibravatar Emi Simpson <emi@alchemi.dev>2022-01-22 20:09:35 -0500
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2022-02-16 18:19:33 +0700
commitca1fcdaf1454fd3febae8e6864c9a7dec04f41b1 (patch)
tree56c062b664a5060bee6ca98a48fd018c16c2fa9c /native/src
parentadce9e04213803bd775538efddf6e7908d1c605e (diff)
downloadiced-ca1fcdaf1454fd3febae8e6864c9a7dec04f41b1.tar.gz
iced-ca1fcdaf1454fd3febae8e6864c9a7dec04f41b1.tar.bz2
iced-ca1fcdaf1454fd3febae8e6864c9a7dec04f41b1.zip
Add support for `ContentFit` for `Image`
Diffstat (limited to 'native/src')
-rw-r--r--native/src/lib.rs4
-rw-r--r--native/src/widget/image.rs66
2 files changed, 52 insertions, 18 deletions
diff --git a/native/src/lib.rs b/native/src/lib.rs
index 6d98f7d1..5c9c24c9 100644
--- a/native/src/lib.rs
+++ b/native/src/lib.rs
@@ -71,8 +71,8 @@ mod debug;
pub use iced_core::alignment;
pub use iced_core::time;
pub use iced_core::{
- Alignment, Background, Color, Font, Length, Padding, Point, Rectangle,
- Size, Vector,
+ Alignment, Background, Color, ContentFit, Font, Length, Padding, Point,
+ Rectangle, Size, Vector,
};
pub use iced_futures::{executor, futures};
diff --git a/native/src/widget/image.rs b/native/src/widget/image.rs
index b8fb662e..5ddc3642 100644
--- a/native/src/widget/image.rs
+++ b/native/src/widget/image.rs
@@ -5,7 +5,9 @@ pub use viewer::Viewer;
use crate::image;
use crate::layout;
use crate::renderer;
-use crate::{Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget};
+use crate::{
+ ContentFit, Element, Hasher, Layout, Length, Point, Rectangle, Size, Widget,
+};
use std::hash::Hash;
@@ -26,6 +28,7 @@ pub struct Image<Handle> {
handle: Handle,
width: Length,
height: Length,
+ fit: ContentFit,
}
impl<Handle> Image<Handle> {
@@ -35,6 +38,7 @@ impl<Handle> Image<Handle> {
handle: handle.into(),
width: Length::Shrink,
height: Length::Shrink,
+ fit: ContentFit::Contain,
}
}
@@ -49,6 +53,13 @@ impl<Handle> Image<Handle> {
self.height = height;
self
}
+
+ /// Sets the image fit
+ ///
+ /// Defaults to [`ContentFit::Contain`]
+ pub fn fit(self, fit: ContentFit) -> Self {
+ Self { fit, ..self }
+ }
}
impl<Message, Renderer, Handle> Widget<Message, Renderer> for Image<Handle>
@@ -69,24 +80,32 @@ where
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
+ // The raw w/h of the underlying image
let (width, height) = renderer.dimensions(&self.handle);
+ let image_size = Size::new(width as f32, height as f32);
- let aspect_ratio = width as f32 / height as f32;
-
- let mut size = limits
+ // The size to be available to the widget prior to `Shrink`ing
+ let raw_size = limits
.width(self.width)
.height(self.height)
- .resolve(Size::new(width as f32, height as f32));
-
- 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)
+ .resolve(image_size);
+
+ // The uncropped size of the image when fit to the bounds above
+ let full_size = self.fit.fit(image_size, raw_size);
+
+ // Shrink the widget to fit the resized image, if requested
+ let final_size = Size {
+ width: match self.width {
+ Length::Shrink => f32::min(raw_size.width, full_size.width),
+ _ => raw_size.width,
+ },
+ height: match self.height {
+ Length::Shrink => f32::min(raw_size.height, full_size.height),
+ _ => raw_size.height,
+ },
+ };
+
+ layout::Node::new(final_size)
}
fn draw(
@@ -97,7 +116,22 @@ where
_cursor_position: Point,
_viewport: &Rectangle,
) {
- renderer.draw(self.handle.clone(), layout.bounds());
+ // The raw w/h of the underlying image
+ let (width, height) = renderer.dimensions(&self.handle);
+ let image_size = Size::new(width as f32, height as f32);
+
+ let adjusted_fit = self.fit.fit(image_size, layout.bounds().size());
+
+ renderer.with_layer(layout.bounds(), |renderer| {
+ renderer.draw(
+ self.handle.clone(),
+ Rectangle {
+ width: adjusted_fit.width,
+ height: adjusted_fit.height,
+ ..layout.bounds()
+ },
+ )
+ })
}
fn hash_layout(&self, state: &mut Hasher) {