Add ui_font settings and set default rem size accordingly (#3346)

Nate Butler created

[[PR Description]]
- Adds ui_font_family, ui_font_features, ui_font_size to settings and
default settings
- Use the new ui font settings to set the rem size when the workspace is
created.

Release Notes:

- N/A

Change summary

assets/settings/default.json          |  9 +++++++++
crates/editor2/src/editor.rs          | 22 ++++++++++------------
crates/settings2/src/settings_file.rs |  3 +++
crates/theme2/src/settings.rs         | 17 ++++++++++++++---
crates/workspace2/src/workspace2.rs   | 11 ++++++++++-
5 files changed, 46 insertions(+), 16 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -35,6 +35,15 @@
   //           "custom": 2
   //         },
   "buffer_line_height": "comfortable",
+  // The name of a font to use for rendering text in the UI
+  "ui_font_family": "Zed Mono",
+  // The OpenType features to enable for text in the UI
+  "ui_font_features": {
+    // Disable ligatures:
+    "calt": false
+  },
+  // The default font size for text in the UI
+  "ui_font_size": 14,
   // The factor to grow the active pane by. Defaults to 1.0
   // which gives the same size as all other panes.
   "active_pane_magnification": 1.0,

crates/editor2/src/editor.rs 🔗

@@ -9379,18 +9379,16 @@ impl Render for Editor {
     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
         let settings = ThemeSettings::get_global(cx);
         let text_style = match self.mode {
-            EditorMode::SingleLine => {
-                TextStyle {
-                    color: cx.theme().colors().text,
-                    font_family: settings.ui_font.family.clone(), // todo!()
-                    font_features: settings.ui_font.features,
-                    font_size: rems(0.875).into(),
-                    font_weight: FontWeight::NORMAL,
-                    font_style: FontStyle::Normal,
-                    line_height: relative(1.3).into(), // TODO relative(settings.buffer_line_height.value()),
-                    underline: None,
-                }
-            }
+            EditorMode::SingleLine => TextStyle {
+                color: cx.theme().colors().text,
+                font_family: settings.ui_font.family.clone(),
+                font_features: settings.ui_font.features,
+                font_size: rems(0.875).into(),
+                font_weight: FontWeight::NORMAL,
+                font_style: FontStyle::Normal,
+                line_height: relative(1.).into(),
+                underline: None,
+            },
 
             EditorMode::AutoHeight { max_lines } => todo!(),
 

crates/settings2/src/settings_file.rs 🔗

@@ -16,6 +16,9 @@ pub fn test_settings() -> String {
     .unwrap();
     util::merge_non_null_json_value_into(
         serde_json::json!({
+            "ui_font_family": "Courier",
+            "ui_font_features": {},
+            "ui_font_size": 14,
             "buffer_font_family": "Courier",
             "buffer_font_features": {},
             "buffer_font_size": 14,

crates/theme2/src/settings.rs 🔗

@@ -34,6 +34,10 @@ pub struct ThemeSettingsContent {
     #[serde(default)]
     pub ui_font_size: Option<f32>,
     #[serde(default)]
+    pub ui_font_family: Option<String>,
+    #[serde(default)]
+    pub ui_font_features: Option<FontFeatures>,
+    #[serde(default)]
     pub buffer_font_family: Option<String>,
     #[serde(default)]
     pub buffer_font_size: Option<f32>,
@@ -120,10 +124,10 @@ impl settings::Settings for ThemeSettings {
         let themes = cx.default_global::<ThemeRegistry>();
 
         let mut this = Self {
-            ui_font_size: defaults.ui_font_size.unwrap_or(16.).into(),
+            ui_font_size: defaults.ui_font_size.unwrap().into(),
             ui_font: Font {
-                family: "Helvetica".into(),
-                features: Default::default(),
+                family: defaults.ui_font_family.clone().unwrap().into(),
+                features: defaults.ui_font_features.clone().unwrap(),
                 weight: Default::default(),
                 style: Default::default(),
             },
@@ -149,6 +153,13 @@ impl settings::Settings for ThemeSettings {
                 this.buffer_font.features = value;
             }
 
+            if let Some(value) = value.ui_font_family {
+                this.ui_font.family = value.into();
+            }
+            if let Some(value) = value.ui_font_features {
+                this.ui_font.features = value;
+            }
+
             if let Some(value) = &value.theme {
                 if let Some(theme) = themes.get(value).log_err() {
                     this.active_theme = theme;

crates/workspace2/src/workspace2.rs 🔗

@@ -3614,7 +3614,16 @@ impl Render for Workspace {
     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
         let mut context = KeyContext::default();
         context.add("Workspace");
-        let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
+
+        let (ui_font, ui_font_size) = {
+            let theme_settings = ThemeSettings::get_global(cx);
+            (
+                theme_settings.ui_font.family.clone(),
+                theme_settings.ui_font_size.clone(),
+            )
+        };
+
+        cx.set_rem_size(ui_font_size);
 
         self.add_workspace_actions_listeners(div())
             .key_context(context)