diff options
author | 2020-12-18 10:44:24 +0100 | |
---|---|---|
committer | 2020-12-18 10:44:24 +0100 | |
commit | 21b10dc103638ead2a567b3426c937f39e9addbd (patch) | |
tree | 237a79644c81afb199e28e772c6e723ad22983f4 /native | |
parent | 0cdf8d56ee515fb56b08ee149683a2216a535950 (diff) | |
download | iced-21b10dc103638ead2a567b3426c937f39e9addbd.tar.gz iced-21b10dc103638ead2a567b3426c937f39e9addbd.tar.bz2 iced-21b10dc103638ead2a567b3426c937f39e9addbd.zip |
Fix `layout` of `image::Viewer`
Diffstat (limited to 'native')
-rw-r--r-- | native/src/widget/image/viewer.rs | 90 |
1 files changed, 38 insertions, 52 deletions
diff --git a/native/src/widget/image/viewer.rs b/native/src/widget/image/viewer.rs index 3ffdf2c0..8b8e9824 100644 --- a/native/src/widget/image/viewer.rs +++ b/native/src/widget/image/viewer.rs @@ -122,11 +122,7 @@ impl<'a> Viewer<'a> { /// will be respected. /// /// [`Viewer`]: struct.Viewer.html - fn image_bounds<Renderer>( - &self, - renderer: &Renderer, - bounds: Rectangle, - ) -> Rectangle + fn image_size<Renderer>(&self, renderer: &Renderer, bounds: Size) -> Size where Renderer: self::Renderer + image::Renderer, { @@ -149,12 +145,7 @@ impl<'a> Viewer<'a> { } }; - Rectangle { - x: bounds.x, - y: bounds.y, - width, - height, - } + Size::new(width, height) } } @@ -189,19 +180,25 @@ where fn layout( &self, - _renderer: &Renderer, + renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { - let padding = f32::from(self.padding); + let (width, height) = renderer.dimensions(&self.handle); - let limits = limits - .max_width(self.max_width) - .max_height(self.max_height) + let aspect_ratio = width as f32 / height as f32; + + let mut size = limits .width(self.width) .height(self.height) - .pad(padding); + .resolve(Size::new(width as f32, height as f32)); + + let viewport_aspect_ratio = size.width / size.height; - let size = limits.resolve(Size::INFINITY); + 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) } @@ -242,8 +239,8 @@ where .min(self.max_scale), ); - let image_bounds = - self.image_bounds(renderer, bounds); + let image_size = + self.image_size(renderer, bounds.size()); let factor = self.state.scale.unwrap() / previous_scale @@ -259,13 +256,13 @@ where + self.state.current_offset * factor; self.state.current_offset = Vector::new( - if image_bounds.width > bounds.width { + if image_size.width > bounds.width { self.state.current_offset.x + adjustment.x } else { 0.0 }, - if image_bounds.height > bounds.height { + if image_size.height > bounds.height { self.state.current_offset.y + adjustment.y } else { @@ -290,14 +287,11 @@ where } Event::Mouse(mouse::Event::CursorMoved { position }) => { if self.state.is_cursor_clicked() { - let image_bounds = self.image_bounds(renderer, bounds); - - self.state.pan( - position.x, - position.y, - bounds, - image_bounds, - ); + let image_size = + self.image_size(renderer, bounds.size()); + + self.state + .pan(position.x, position.y, bounds, image_size); } } _ => {} @@ -322,15 +316,15 @@ where ) -> Renderer::Output { let bounds = layout.bounds(); - let image_bounds = self.image_bounds(renderer, bounds); + let image_size = self.image_size(renderer, bounds.size()); let translation = { let image_top_left = Vector::new( - bounds.width / 2.0 - image_bounds.width / 2.0, - bounds.height / 2.0 - image_bounds.height / 2.0, + bounds.width / 2.0 - image_size.width / 2.0, + bounds.height / 2.0 - image_size.height / 2.0, ); - image_top_left - self.state.offset(bounds, image_bounds) + image_top_left - self.state.offset(bounds, image_size) }; let is_mouse_over = bounds.contains(cursor_position); @@ -339,7 +333,7 @@ where renderer, &self.state, bounds, - image_bounds, + image_size, translation, self.handle.clone(), is_mouse_over, @@ -384,31 +378,24 @@ impl State { /// /// [`Viewer`]: struct.Viewer.html /// [`State`]: struct.State.html - fn pan( - &mut self, - x: f32, - y: f32, - bounds: Rectangle, - image_bounds: Rectangle, - ) { - let hidden_width = ((image_bounds.width - bounds.width) as f32 / 2.0) + fn pan(&mut self, x: f32, y: f32, bounds: Rectangle, image_size: Size) { + let hidden_width = ((image_size.width - bounds.width) as f32 / 2.0) .max(0.0) .round(); - let hidden_height = ((image_bounds.height - bounds.height) as f32 - / 2.0) + let hidden_height = ((image_size.height - bounds.height) as f32 / 2.0) .max(0.0) .round(); let delta_x = x - self.starting_cursor_pos.unwrap().x; let delta_y = y - self.starting_cursor_pos.unwrap().y; - if bounds.width < image_bounds.width { + if bounds.width < image_size.width { self.current_offset.x = (self.starting_offset.x - delta_x) .min(hidden_width) .max(-1.0 * hidden_width); } - if bounds.height < image_bounds.height { + if bounds.height < image_size.height { self.current_offset.y = (self.starting_offset.y - delta_y) .min(hidden_height) .max(-1.0 * hidden_height); @@ -420,12 +407,11 @@ impl State { /// /// [`Viewer`]: struct.Viewer.html /// [`State`]: struct.State.html - fn offset(&self, bounds: Rectangle, image_bounds: Rectangle) -> Vector { - let hidden_width = ((image_bounds.width - bounds.width) as f32 / 2.0) + fn offset(&self, bounds: Rectangle, image_size: Size) -> Vector { + let hidden_width = ((image_size.width - bounds.width) as f32 / 2.0) .max(0.0) .round(); - let hidden_height = ((image_bounds.height - bounds.height) as f32 - / 2.0) + let hidden_height = ((image_size.height - bounds.height) as f32 / 2.0) .max(0.0) .round(); @@ -476,7 +462,7 @@ pub trait Renderer: crate::Renderer + Sized { &mut self, state: &State, bounds: Rectangle, - image_bounds: Rectangle, + image_size: Size, translation: Vector, handle: image::Handle, is_mouse_over: bool, |