From 938a0679c004be4ae2b6c1e897de75e4b4e7aa24 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Tue, 1 Oct 2024 07:39:19 +0800 Subject: [PATCH] gpui: Fix img element to auto size when only have width or height (#17994) Release Notes: - N/A --- We may only want to set the height of an image to limit the size and make the width adaptive. In HTML, we will only set width or height, and the other side will adapt and maintain the original image ratio. I changed this because I had a logo image that only to be limited in height, and then I found that setting the height of the `img` alone would not display correctly. I also tried to set `ObjectFit` in this Demo, but it seems that none of them can achieve the same effect as "After". ## Before before 2024-09-18 164029 ## After after 2024-09-18 172003 --- crates/gpui/examples/image/image.rs | 54 +++++++++++++++++++++-------- crates/gpui/src/elements/img.rs | 36 +++++++++++++------ 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/crates/gpui/examples/image/image.rs b/crates/gpui/examples/image/image.rs index 157dbdf70f1afc6cc51b3c96c96a3168b53f8c34..24a94bf746ec473e068968dee5340a981bfd479d 100644 --- a/crates/gpui/examples/image/image.rs +++ b/crates/gpui/examples/image/image.rs @@ -69,25 +69,51 @@ struct ImageShowcase { impl Render for ImageShowcase { fn render(&mut self, _cx: &mut ViewContext) -> impl IntoElement { div() - .flex() - .flex_row() .size_full() + .flex() + .flex_col() .justify_center() .items_center() .gap_8() .bg(rgb(0xFFFFFF)) - .child(ImageContainer::new( - "Image loaded from a local file", - self.local_resource.clone(), - )) - .child(ImageContainer::new( - "Image loaded from a remote resource", - self.remote_resource.clone(), - )) - .child(ImageContainer::new( - "Image loaded from an asset", - self.asset_resource.clone(), - )) + .child( + div() + .flex() + .flex_row() + .justify_center() + .items_center() + .gap_8() + .child(ImageContainer::new( + "Image loaded from a local file", + self.local_resource.clone(), + )) + .child(ImageContainer::new( + "Image loaded from a remote resource", + self.remote_resource.clone(), + )) + .child(ImageContainer::new( + "Image loaded from an asset", + self.asset_resource.clone(), + )), + ) + .child( + div() + .flex() + .flex_row() + .gap_8() + .child( + div() + .flex_col() + .child("Auto Width") + .child(img("https://picsum.photos/800/400").h(px(180.))), + ) + .child( + div() + .flex_col() + .child("Auto Height") + .child(img("https://picsum.photos/480/640").w(px(180.))), + ), + ) } } diff --git a/crates/gpui/src/elements/img.rs b/crates/gpui/src/elements/img.rs index 63236d5309f145bd12ddcc8eab49b766c43618e2..58ee639265ec1a2e186e1eb5d5b3d61f5acfc616 100644 --- a/crates/gpui/src/elements/img.rs +++ b/crates/gpui/src/elements/img.rs @@ -1,7 +1,7 @@ use crate::{ px, AbsoluteLength, AppContext, Asset, Bounds, DefiniteLength, Element, ElementId, GlobalElementId, Hitbox, Image, InteractiveElement, Interactivity, IntoElement, LayoutId, - Length, ObjectFit, Pixels, RenderImage, SharedString, SharedUri, Size, StyleRefinement, Styled, + Length, ObjectFit, Pixels, RenderImage, SharedString, SharedUri, StyleRefinement, Styled, SvgSize, UriOrPath, WindowContext, }; use futures::{AsyncReadExt, Future}; @@ -187,16 +187,30 @@ impl Element for Img { let image_size = data.size(frame_index); - if let (Length::Auto, Length::Auto) = (style.size.width, style.size.height) - { - style.size = Size { - width: Length::Definite(DefiniteLength::Absolute( - AbsoluteLength::Pixels(px(image_size.width.0 as f32)), - )), - height: Length::Definite(DefiniteLength::Absolute( - AbsoluteLength::Pixels(px(image_size.height.0 as f32)), - )), - } + if let Length::Auto = style.size.width { + style.size.width = match style.size.height { + Length::Definite(DefiniteLength::Absolute( + AbsoluteLength::Pixels(height), + )) => Length::Definite( + px(image_size.width.0 as f32 * height.0 + / image_size.height.0 as f32) + .into(), + ), + _ => Length::Definite(px(image_size.width.0 as f32).into()), + }; + } + + if let Length::Auto = style.size.height { + style.size.height = match style.size.width { + Length::Definite(DefiniteLength::Absolute( + AbsoluteLength::Pixels(width), + )) => Length::Definite( + px(image_size.height.0 as f32 * width.0 + / image_size.width.0 as f32) + .into(), + ), + _ => Length::Definite(px(image_size.height.0 as f32).into()), + }; } if global_id.is_some() && data.frame_count() > 1 {