Move font size adjustment code to the theme crate

Max Brunsfeld created

Change summary

crates/diagnostics/src/diagnostics.rs         |  4 -
crates/editor/src/editor.rs                   |  6 -
crates/settings/src/font_size.rs              | 19 --------
crates/settings/src/settings.rs               |  2 
crates/terminal/src/terminal.rs               |  9 +++
crates/terminal_view/src/terminal_element.rs  | 10 +---
crates/theme/src/theme.rs                     |  4 
crates/theme/src/theme_settings.rs            | 48 ++++++++++++++++++++
crates/theme_testbench/src/theme_testbench.rs |  2 
crates/zed/src/zed.rs                         | 21 ++-------
10 files changed, 69 insertions(+), 56 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -682,9 +682,7 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock {
         let settings = settings::get::<ThemeSettings>(cx);
         let theme = &settings.theme.editor;
         let style = theme.diagnostic_header.clone();
-        let font_size = (style.text_scale_factor
-            * settings::font_size_for_setting(settings.buffer_font_size, cx))
-        .round();
+        let font_size = (style.text_scale_factor * settings.buffer_font_size(cx)).round();
         let icon_width = cx.em_width * style.icon_width_factor;
         let icon = if diagnostic.severity == DiagnosticSeverity::ERROR {
             Svg::new("icons/circle_x_mark_12.svg")

crates/editor/src/editor.rs 🔗

@@ -7446,7 +7446,7 @@ fn build_style(
         let font_id = font_cache
             .select_font(font_family_id, &font_properties)
             .unwrap();
-        let font_size = settings::font_size_for_setting(settings.buffer_font_size, cx);
+        let font_size = settings.buffer_font_size(cx);
         EditorStyle {
             text: TextStyle {
                 color: settings.theme.editor.text_color,
@@ -7619,9 +7619,7 @@ pub fn diagnostic_block_renderer(diagnostic: Diagnostic, is_valid: bool) -> Rend
         let settings = settings::get::<ThemeSettings>(cx);
         let theme = &settings.theme.editor;
         let style = diagnostic_style(diagnostic.severity, is_valid, theme);
-        let font_size = (style.text_scale_factor
-            * settings::font_size_for_setting(settings.buffer_font_size, cx))
-        .round();
+        let font_size = (style.text_scale_factor * settings.buffer_font_size(cx)).round();
         Flex::column()
             .with_children(highlighted_lines.iter().map(|(line, highlights)| {
                 Label::new(

crates/settings/src/font_size.rs 🔗

@@ -1,19 +0,0 @@
-use gpui::AppContext;
-
-#[derive(Default)]
-pub struct FontSizeDelta(pub f32);
-
-pub fn adjust_font_size_delta(cx: &mut AppContext, f: fn(&mut f32, cx: &mut AppContext)) {
-    cx.update_default_global::<FontSizeDelta, _, _>(|size, cx| {
-        f(&mut size.0, cx);
-    });
-    cx.refresh_windows();
-}
-
-pub fn font_size_for_setting(size: f32, cx: &AppContext) -> f32 {
-    if cx.has_global::<FontSizeDelta>() {
-        size + cx.global::<FontSizeDelta>().0
-    } else {
-        size
-    }
-}

crates/settings/src/settings.rs 🔗

@@ -1,11 +1,9 @@
-mod font_size;
 mod keymap_file;
 mod settings_file;
 mod settings_store;
 
 use std::{borrow::Cow, str};
 
-pub use font_size::{adjust_font_size_delta, font_size_for_setting};
 use gpui::AssetSource;
 pub use keymap_file::{keymap_file_json_schema, KeymapFileContent};
 pub use settings_file::*;

crates/terminal/src/terminal.rs 🔗

@@ -123,7 +123,7 @@ pub fn init(cx: &mut AppContext) {
 pub struct TerminalSettings {
     pub shell: Shell,
     pub working_directory: WorkingDirectory,
-    pub font_size: Option<f32>,
+    font_size: Option<f32>,
     pub font_family: Option<String>,
     pub line_height: TerminalLineHeight,
     pub font_features: Option<fonts::Features>,
@@ -149,6 +149,13 @@ pub struct TerminalSettingsContent {
     pub copy_on_select: Option<bool>,
 }
 
+impl TerminalSettings {
+    pub fn font_size(&self, cx: &AppContext) -> Option<f32> {
+        self.font_size
+            .map(|size| theme::adjusted_font_size(size, cx))
+    }
+}
+
 impl settings::Setting for TerminalSettings {
     const KEY: Option<&'static str> = Some("terminal");
 

crates/terminal_view/src/terminal_element.rs 🔗

@@ -16,7 +16,6 @@ use gpui::{
 use itertools::Itertools;
 use language::CursorShape;
 use ordered_float::OrderedFloat;
-use settings::font_size_for_setting;
 use terminal::{
     alacritty_terminal::{
         ansi::{Color as AnsiColor, Color::Named, CursorShape as AlacCursorShape, NamedColor},
@@ -531,12 +530,9 @@ impl Element<TerminalView> for TerminalElement {
         let tooltip_style = settings.theme.tooltip.clone();
 
         let font_cache = cx.font_cache();
-        let font_size = font_size_for_setting(
-            terminal_settings
-                .font_size
-                .unwrap_or(settings.buffer_font_size),
-            cx,
-        );
+        let font_size = terminal_settings
+            .font_size(cx)
+            .unwrap_or(settings.buffer_font_size(cx));
         let font_family_name = terminal_settings
             .font_family
             .as_ref()

crates/theme/src/theme.rs 🔗

@@ -13,8 +13,8 @@ use serde_json::Value;
 use std::{collections::HashMap, sync::Arc};
 use ui::{ButtonStyle, CheckboxStyle, IconStyle, ModalStyle, SvgStyle};
 
-pub use theme_registry::ThemeRegistry;
-pub use theme_settings::ThemeSettings;
+pub use theme_registry::*;
+pub use theme_settings::*;
 
 pub fn current(cx: &AppContext) -> Arc<Theme> {
     settings::get::<ThemeSettings>(cx).theme.clone()

crates/theme/src/theme_settings.rs 🔗

@@ -12,15 +12,19 @@ use settings::SettingsJsonSchemaParams;
 use std::sync::Arc;
 use util::ResultExt as _;
 
+const MIN_FONT_SIZE: f32 = 6.0;
+
 #[derive(Clone)]
 pub struct ThemeSettings {
     pub buffer_font_family_name: String,
     pub buffer_font_features: fonts::Features,
     pub buffer_font_family: FamilyId,
-    pub buffer_font_size: f32,
+    buffer_font_size: f32,
     pub theme: Arc<Theme>,
 }
 
+pub struct AdjustedBufferFontSize(pub f32);
+
 #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
 pub struct ThemeSettingsContent {
     #[serde(default)]
@@ -33,6 +37,48 @@ pub struct ThemeSettingsContent {
     pub theme: Option<String>,
 }
 
+impl ThemeSettings {
+    pub fn buffer_font_size(&self, cx: &AppContext) -> f32 {
+        if cx.has_global::<AdjustedBufferFontSize>() {
+            cx.global::<AdjustedBufferFontSize>().0
+        } else {
+            self.buffer_font_size
+        }
+        .max(MIN_FONT_SIZE)
+    }
+}
+
+pub fn adjusted_font_size(size: f32, cx: &AppContext) -> f32 {
+    if cx.has_global::<AdjustedBufferFontSize>() {
+        let buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
+        let delta = cx.global::<AdjustedBufferFontSize>().0 - buffer_font_size;
+        size + delta
+    } else {
+        size
+    }
+    .max(MIN_FONT_SIZE)
+}
+
+pub fn adjust_font_size(cx: &mut AppContext, f: fn(&mut f32)) {
+    if !cx.has_global::<AdjustedBufferFontSize>() {
+        let buffer_font_size = settings::get::<ThemeSettings>(cx).buffer_font_size;
+        cx.set_global(AdjustedBufferFontSize(buffer_font_size));
+    }
+
+    cx.update_global::<AdjustedBufferFontSize, _, _>(|delta, cx| {
+        f(&mut delta.0);
+        delta.0 = delta
+            .0
+            .max(MIN_FONT_SIZE - settings::get::<ThemeSettings>(cx).buffer_font_size);
+    });
+    cx.refresh_windows();
+}
+
+pub fn reset_font_size(cx: &mut AppContext) {
+    cx.remove_global::<AdjustedBufferFontSize>();
+    cx.refresh_windows();
+}
+
 impl settings::Setting for ThemeSettings {
     const KEY: Option<&'static str> = None;
 

crates/theme_testbench/src/theme_testbench.rs 🔗

@@ -222,7 +222,7 @@ impl ThemeTestbench {
         let settings = settings::get::<ThemeSettings>(cx);
         let font_cache = cx.font_cache();
         let family_id = settings.buffer_font_family;
-        let font_size = settings::font_size_for_setting(settings.buffer_font_size, cx);
+        let font_size = settings.buffer_font_size(cx);
         let font_id = font_cache
             .select_font(family_id, &Default::default())
             .unwrap();

crates/zed/src/zed.rs 🔗

@@ -29,12 +29,9 @@ use project_panel::ProjectPanel;
 use search::{BufferSearchBar, ProjectSearchBar};
 use serde::Deserialize;
 use serde_json::to_string_pretty;
-use settings::{
-    adjust_font_size_delta, KeymapFileContent, SettingsStore, DEFAULT_SETTINGS_ASSET_PATH,
-};
+use settings::{KeymapFileContent, SettingsStore, DEFAULT_SETTINGS_ASSET_PATH};
 use std::{borrow::Cow, str, sync::Arc};
 use terminal_view::terminal_button::TerminalButton;
-use theme::ThemeSettings;
 use util::{channel::ReleaseChannel, paths, ResultExt};
 use uuid::Uuid;
 use welcome::BaseKeymap;
@@ -76,8 +73,6 @@ actions!(
     ]
 );
 
-const MIN_FONT_SIZE: f32 = 6.0;
-
 pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
     cx.add_action(about);
     cx.add_global_action(|_: &Hide, cx: &mut gpui::AppContext| {
@@ -121,18 +116,12 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::AppContext) {
     cx.add_global_action(quit);
     cx.add_global_action(move |action: &OpenBrowser, cx| cx.platform().open_url(&action.url));
     cx.add_global_action(move |_: &IncreaseBufferFontSize, cx| {
-        adjust_font_size_delta(cx, |size, _| *size += 1.0)
+        theme::adjust_font_size(cx, |size| *size += 1.0)
     });
     cx.add_global_action(move |_: &DecreaseBufferFontSize, cx| {
-        adjust_font_size_delta(cx, |size, cx| {
-            if cx.global::<ThemeSettings>().buffer_font_size + *size > MIN_FONT_SIZE {
-                *size -= 1.0;
-            }
-        })
-    });
-    cx.add_global_action(move |_: &ResetBufferFontSize, cx| {
-        adjust_font_size_delta(cx, |size, _| *size = 0.0)
+        theme::adjust_font_size(cx, |size| *size -= 1.0)
     });
+    cx.add_global_action(move |_: &ResetBufferFontSize, cx| theme::reset_font_size(cx));
     cx.add_global_action(move |_: &install_cli::Install, cx| {
         cx.spawn(|cx| async move {
             install_cli::install_cli(&cx)
@@ -639,7 +628,7 @@ mod tests {
         collections::HashSet,
         path::{Path, PathBuf},
     };
-    use theme::ThemeRegistry;
+    use theme::{ThemeRegistry, ThemeSettings};
     use util::http::FakeHttpClient;
     use workspace::{
         item::{Item, ItemHandle},