Style avatar image with border and rounded corners

Nathan Sobo and Max Brunsfeld created

Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>

Change summary

gpui/src/elements/image.rs   | 27 ++++++++++++++-------------
zed/assets/themes/_base.toml |  7 ++++---
zed/src/theme.rs             |  5 +++--
zed/src/workspace.rs         |  6 ++++--
4 files changed, 25 insertions(+), 20 deletions(-)

Detailed changes

gpui/src/elements/image.rs 🔗

@@ -1,16 +1,23 @@
+use super::constrain_size_preserving_aspect_ratio;
 use crate::{
     geometry::{rect::RectF, vector::Vector2F},
     json::{json, ToJson},
     scene, Border, DebugContext, Element, Event, EventContext, ImageData, LayoutContext,
     PaintContext, SizeConstraint,
 };
+use serde::Deserialize;
 use std::sync::Arc;
 
-use super::constrain_size_preserving_aspect_ratio;
-
 pub struct Image {
     data: Arc<ImageData>,
+    style: ImageStyle,
+}
+
+#[derive(Copy, Clone, Default, Deserialize)]
+pub struct ImageStyle {
+    #[serde(default)]
     border: Border,
+    #[serde(default)]
     corner_radius: f32,
 }
 
@@ -18,18 +25,12 @@ impl Image {
     pub fn new(data: Arc<ImageData>) -> Self {
         Self {
             data,
-            border: Default::default(),
-            corner_radius: Default::default(),
+            style: Default::default(),
         }
     }
 
-    pub fn with_corner_radius(mut self, corner_radius: f32) -> Self {
-        self.corner_radius = corner_radius;
-        self
-    }
-
-    pub fn with_border(mut self, border: Border) -> Self {
-        self.border = border;
+    pub fn with_style(mut self, style: ImageStyle) -> Self {
+        self.style = style;
         self
     }
 }
@@ -57,8 +58,8 @@ impl Element for Image {
     ) -> Self::PaintState {
         cx.scene.push_image(scene::Image {
             bounds,
-            border: self.border,
-            corner_radius: self.corner_radius,
+            border: self.style.border,
+            corner_radius: self.style.corner_radius,
             data: self.data.clone(),
         });
     }

zed/assets/themes/_base.toml 🔗

@@ -8,8 +8,9 @@ pane_divider = { width = 1, color = "$border.0" }
 [workspace.titlebar]
 border = { width = 1, bottom = true, color = "$border.0" }
 title = "$text.0"
-icon_width = 16
+avatar_width = 20
 icon_signed_out = "$text.2.color"
+avatar = { corner_radius = 10, border = { width = 1, color = "#00000088" } }
 
 [workspace.tab]
 text = "$text.2"
@@ -28,7 +29,7 @@ background = "$surface.1"
 text = "$text.0"
 
 [workspace.sidebar]
-width = 36
+width = 38
 border = { right = true, width = 1, color = "$border.0" }
 
 [workspace.sidebar.resize_handle]
@@ -37,7 +38,7 @@ background = "$border.0"
 
 [workspace.sidebar.icon]
 color = "$text.2.color"
-height = 16
+height = 18
 
 [workspace.sidebar.active_icon]
 extends = "$workspace.sidebar.icon"

zed/src/theme.rs 🔗

@@ -4,7 +4,7 @@ mod theme_registry;
 use anyhow::Result;
 use gpui::{
     color::Color,
-    elements::{ContainerStyle, LabelStyle},
+    elements::{ContainerStyle, ImageStyle, LabelStyle},
     fonts::{HighlightStyle, TextStyle},
     Border,
 };
@@ -47,8 +47,9 @@ pub struct Titlebar {
     #[serde(flatten)]
     pub container: ContainerStyle,
     pub title: TextStyle,
-    pub icon_width: f32,
+    pub avatar_width: f32,
     pub icon_signed_out: Color,
+    pub avatar: ImageStyle,
 }
 
 #[derive(Clone, Deserialize)]

zed/src/workspace.rs 🔗

@@ -963,7 +963,9 @@ impl Workspace {
             .as_ref()
             .and_then(|user| user.avatar.clone())
         {
-            Image::new(avatar).boxed()
+            Image::new(avatar)
+                .with_style(theme.workspace.titlebar.avatar)
+                .boxed()
         } else {
             Svg::new("icons/signed-out-12.svg")
                 .with_color(theme.workspace.titlebar.icon_signed_out)
@@ -973,7 +975,7 @@ impl Workspace {
         ConstrainedBox::new(
             Align::new(
                 ConstrainedBox::new(avatar)
-                    .with_width(theme.workspace.titlebar.icon_width)
+                    .with_width(theme.workspace.titlebar.avatar_width)
                     .boxed(),
             )
             .boxed(),