diff --git a/widget/src/image/viewer.rs b/widget/src/image/viewer.rs index 811241a970..8c27752e10 100644 --- a/widget/src/image/viewer.rs +++ b/widget/src/image/viewer.rs @@ -6,7 +6,7 @@ use crate::core::renderer; use crate::core::widget::tree::{self, Tree}; use crate::core::{ Clipboard, ContentFit, Element, Event, Image, Layout, Length, Pixels, - Point, Radians, Rectangle, Shell, Size, Vector, Widget, + Point, Rectangle, Rotation, Shell, Size, Vector, Widget, }; /// A frame that displays an image with the ability to zoom in/out and pan. @@ -21,6 +21,7 @@ pub struct Viewer { handle: Handle, filter_method: FilterMethod, content_fit: ContentFit, + rotation: Rotation, } impl Viewer { @@ -36,6 +37,7 @@ impl Viewer { scale_step: 0.10, filter_method: FilterMethod::default(), content_fit: ContentFit::default(), + rotation: Rotation::default(), } } @@ -93,6 +95,12 @@ impl Viewer { self.scale_step = scale_step; self } + + /// Applies the given [`Rotation`] to the [`Viewer`]. + pub fn rotation(mut self, rotation: impl Into) -> Self { + self.rotation = rotation.into(); + self + } } impl Widget @@ -127,11 +135,14 @@ where let image_size = Size::new(image_size.width as f32, image_size.height as f32); + // The rotated size of the image + let rotated_size = self.rotation.apply(image_size); + // The size to be available to the widget prior to `Shrink`ing - let raw_size = limits.resolve(self.width, self.height, image_size); + let raw_size = limits.resolve(self.width, self.height, rotated_size); // The uncropped size of the image when fit to the bounds above - let full_size = self.content_fit.fit(image_size, raw_size); + let full_size = self.content_fit.fit(rotated_size, raw_size); // Shrink the widget to fit the resized image, if requested let final_size = Size { @@ -189,6 +200,7 @@ where state, bounds.size(), self.content_fit, + self.rotation, ); let factor = state.scale / previous_scale - 1.0; @@ -250,6 +262,7 @@ where state, bounds.size(), self.content_fit, + self.rotation, ); let hidden_width = (scaled_size.width - bounds.width / 2.0) .max(0.0) @@ -325,6 +338,7 @@ where state, bounds.size(), self.content_fit, + self.rotation, ); let translation = { @@ -349,7 +363,7 @@ where Image { handle: self.handle.clone(), filter_method: self.filter_method, - rotation: Radians(0.0), + rotation: self.rotation.radians(), opacity: 1.0, snap: true, }, @@ -430,14 +444,15 @@ pub fn scaled_image_size( state: &State, bounds: Size, content_fit: ContentFit, + rotation: Rotation, ) -> Size where Renderer: image::Renderer, { let Size { width, height } = renderer.measure_image(handle); let image_size = Size::new(width as f32, height as f32); - - let adjusted_fit = content_fit.fit(image_size, bounds); + let rotated_size = rotation.apply(image_size); + let adjusted_fit = content_fit.fit(rotated_size, bounds); Size::new( adjusted_fit.width * state.scale,