Allow size to be specified in `ImageStyle`

Antonio Scandurra and Nathan Sobo created

Co-Authored-By: Nathan Sobo <nathan@zed.dev>

Change summary

gpui/src/elements/image.rs   | 19 ++++++++++++++++---
gpui/src/presenter.rs        |  7 +++++++
zed/assets/themes/_base.toml |  4 ++--
zed/src/people_panel.rs      | 20 ++++++--------------
4 files changed, 31 insertions(+), 19 deletions(-)

Detailed changes

gpui/src/elements/image.rs 🔗

@@ -1,6 +1,9 @@
 use super::constrain_size_preserving_aspect_ratio;
 use crate::{
-    geometry::{rect::RectF, vector::Vector2F},
+    geometry::{
+        rect::RectF,
+        vector::{vec2f, Vector2F},
+    },
     json::{json, ToJson},
     scene, Border, DebugContext, Element, Event, EventContext, ImageData, LayoutContext,
     PaintContext, SizeConstraint,
@@ -19,6 +22,10 @@ pub struct ImageStyle {
     border: Border,
     #[serde(default)]
     corner_radius: f32,
+    #[serde(default)]
+    height: Option<f32>,
+    #[serde(default)]
+    width: Option<f32>,
 }
 
 impl Image {
@@ -44,8 +51,14 @@ impl Element for Image {
         constraint: SizeConstraint,
         _: &mut LayoutContext,
     ) -> (Vector2F, Self::LayoutState) {
-        let size =
-            constrain_size_preserving_aspect_ratio(constraint.max, self.data.size().to_f32());
+        let desired_size = vec2f(
+            self.style.width.unwrap_or(constraint.max.x()),
+            self.style.height.unwrap_or(constraint.max.y()),
+        );
+        let size = constrain_size_preserving_aspect_ratio(
+            constraint.constrain(desired_size),
+            self.data.size().to_f32(),
+        );
         (size, ())
     }
 

gpui/src/presenter.rs 🔗

@@ -432,6 +432,13 @@ impl SizeConstraint {
             Axis::Vertical => self.min.y(),
         }
     }
+
+    pub fn constrain(&self, size: Vector2F) -> Vector2F {
+        vec2f(
+            size.x().min(self.max.x()).max(self.min.x()),
+            size.y().min(self.max.y()).max(self.min.y()),
+        )
+    }
 }
 
 impl ToJson for SizeConstraint {

zed/assets/themes/_base.toml 🔗

@@ -126,8 +126,8 @@ color = "$text.1.color"
 [people_panel]
 extends = "$panel"
 host_username = { extends = "$text.0", padding.left = 5 }
-worktree_host_avatar = { corner_radius = 10 }
-worktree_guest_avatar = { corner_radius = 8 }
+worktree_host_avatar = { corner_radius = 10, width = 20 }
+worktree_guest_avatar = { corner_radius = 8, width = 16 }
 
 [people_panel.worktree_name]
 extends = "$text.0"

zed/src/people_panel.rs 🔗

@@ -69,13 +69,9 @@ impl PeoplePanel {
             .with_child(
                 Flex::row()
                     .with_children(collaborator.user.avatar.clone().map(|avatar| {
-                        ConstrainedBox::new(
-                            Image::new(avatar)
-                                .with_style(theme.worktree_host_avatar)
-                                .boxed(),
-                        )
-                        .with_width(20.)
-                        .boxed()
+                        Image::new(avatar)
+                            .with_style(theme.worktree_host_avatar)
+                            .boxed()
                     }))
                     .with_child(
                         Container::new(
@@ -152,13 +148,9 @@ impl PeoplePanel {
                             )
                             .with_children(worktree.participants.iter().filter_map(|participant| {
                                 participant.avatar.clone().map(|avatar| {
-                                    ConstrainedBox::new(
-                                        Image::new(avatar)
-                                            .with_style(theme.worktree_guest_avatar)
-                                            .boxed(),
-                                    )
-                                    .with_width(16.)
-                                    .boxed()
+                                    Image::new(avatar)
+                                        .with_style(theme.worktree_guest_avatar)
+                                        .boxed()
                                 })
                             }))
                             .boxed()