From b910bbf0021002b9dee2a65e630194df73eae490 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Wed, 1 Nov 2023 18:11:12 +0100 Subject: [PATCH] Add `ui_font_size` setting (#3199) This PR adds a new `ui_font_size` setting that can be used to control the scale of the entire UI. We use the value in this setting to set the base rem size of the window. Release Notes: - N/A --- Cargo.lock | 1 + crates/gpui2/src/window.rs | 6 ++++ crates/storybook2/src/storybook2.rs | 7 +++- crates/theme2/src/settings.rs | 12 +++++-- crates/ui2/Cargo.toml | 1 + crates/ui2/src/components/icon_button.rs | 6 ++-- crates/ui2/src/components/workspace.rs | 42 ++++++++++++------------ crates/ui2/src/elements/button.rs | 10 +++--- crates/ui2/src/elements/icon.rs | 6 ++-- crates/ui2/src/elements/label.rs | 4 +-- crates/ui2/src/prelude.rs | 11 +------ crates/ui2/src/settings.rs | 2 -- 12 files changed, 58 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea10948b5aa13a661b3215cc4d637d6ecbccea36..755f4440d98c0630b4650a8e98194e2f12a6a540 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9666,6 +9666,7 @@ dependencies = [ "itertools 0.11.0", "rand 0.8.5", "serde", + "settings2", "smallvec", "strum", "theme2", diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 3997a3197f9cc1685b3f455665a8d54852bb8b8c..7223826ab0d10b2b6801aca75950ac9f9289b1d1 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -541,6 +541,12 @@ impl<'a, 'w> WindowContext<'a, 'w> { self.window.rem_size } + /// Sets the size of an em for the base font of the application. Adjusting this value allows the + /// UI to scale, just like zooming a web page. + pub fn set_rem_size(&mut self, rem_size: impl Into) { + self.window.rem_size = rem_size.into(); + } + /// The line height associated with the current text style. pub fn line_height(&self) -> Pixels { let rem_size = self.rem_size(); diff --git a/crates/storybook2/src/storybook2.rs b/crates/storybook2/src/storybook2.rs index 411fe18071b52e991fa741e218ec0694e51f6e70..3b5722732bfbe90246730d6872151b67129fee82 100644 --- a/crates/storybook2/src/storybook2.rs +++ b/crates/storybook2/src/storybook2.rs @@ -81,7 +81,12 @@ fn main() { }), ..Default::default() }, - move |cx| cx.build_view(|cx| StoryWrapper::new(selector.story(cx))), + move |cx| { + let theme_settings = ThemeSettings::get_global(cx); + cx.set_rem_size(theme_settings.ui_font_size); + + cx.build_view(|cx| StoryWrapper::new(selector.story(cx))) + }, ); cx.activate(true); diff --git a/crates/theme2/src/settings.rs b/crates/theme2/src/settings.rs index bad00ee196c29f5ac40c988cc20c8695e5ae0693..c8d2b52273209eaeff95790abd6dc3f6491e1ce1 100644 --- a/crates/theme2/src/settings.rs +++ b/crates/theme2/src/settings.rs @@ -17,6 +17,7 @@ const MIN_LINE_HEIGHT: f32 = 1.0; #[derive(Clone)] pub struct ThemeSettings { + pub ui_font_size: Pixels, pub buffer_font: Font, pub buffer_font_size: Pixels, pub buffer_line_height: BufferLineHeight, @@ -28,6 +29,8 @@ pub struct AdjustedBufferFontSize(Option); #[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] pub struct ThemeSettingsContent { + #[serde(default)] + pub ui_font_size: Option, #[serde(default)] pub buffer_font_family: Option, #[serde(default)] @@ -115,6 +118,7 @@ impl settings2::Settings for ThemeSettings { let themes = cx.default_global::>(); let mut this = Self { + ui_font_size: defaults.ui_font_size.unwrap_or(16.).into(), buffer_font: Font { family: defaults.buffer_font_family.clone().unwrap().into(), features: defaults.buffer_font_features.clone().unwrap(), @@ -123,9 +127,10 @@ impl settings2::Settings for ThemeSettings { }, buffer_font_size: defaults.buffer_font_size.unwrap().into(), buffer_line_height: defaults.buffer_line_height.unwrap(), - active_theme: themes.get("Zed Pro Moonlight").unwrap(), - // todo!(Read the theme name from the settings) - // active_theme: themes.get(defaults.theme.as_ref().unwrap()).unwrap(), + active_theme: themes + .get(defaults.theme.as_ref().unwrap()) + .or(themes.get("Zed Pro Moonlight")) + .unwrap(), }; for value in user_values.into_iter().copied().cloned() { @@ -142,6 +147,7 @@ impl settings2::Settings for ThemeSettings { } } + merge(&mut this.ui_font_size, value.ui_font_size.map(Into::into)); merge( &mut this.buffer_font_size, value.buffer_font_size.map(Into::into), diff --git a/crates/ui2/Cargo.toml b/crates/ui2/Cargo.toml index 58013e34cda8e5ffc429e7d4f976c873c5313486..f11fd652b61d4b5be02ef0f06eb0095a3c3fda44 100644 --- a/crates/ui2/Cargo.toml +++ b/crates/ui2/Cargo.toml @@ -10,6 +10,7 @@ chrono = "0.4" gpui2 = { path = "../gpui2" } itertools = { version = "0.11.0", optional = true } serde.workspace = true +settings2 = { path = "../settings2" } smallvec.workspace = true strum = { version = "0.25.0", features = ["derive"] } theme2 = { path = "../theme2" } diff --git a/crates/ui2/src/components/icon_button.rs b/crates/ui2/src/components/icon_button.rs index 06e242b1efc82d1f78c61731dd8daa3d77ef9da7..101c845a76ed490e051bb02416c1f4bd05b4c1a5 100644 --- a/crates/ui2/src/components/icon_button.rs +++ b/crates/ui2/src/components/icon_button.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use gpui2::MouseButton; +use gpui2::{rems, MouseButton}; use crate::{h_stack, prelude::*}; use crate::{ClickHandler, Icon, IconColor, IconElement}; @@ -88,8 +88,8 @@ impl IconButton { .id(self.id.clone()) .justify_center() .rounded_md() - .py(ui_size(cx, 0.25)) - .px(ui_size(cx, 6. / 14.)) + .py(rems(0.21875)) + .px(rems(0.375)) .bg(bg_color) .hover(|style| style.bg(bg_hover_color)) .active(|style| style.bg(bg_active_color)) diff --git a/crates/ui2/src/components/workspace.rs b/crates/ui2/src/components/workspace.rs index 0e31c6b9ada20e635402639d621444a7d0f8b723..97570a33e3b83d8856db49eed178d53677eb7b48 100644 --- a/crates/ui2/src/components/workspace.rs +++ b/crates/ui2/src/components/workspace.rs @@ -1,14 +1,16 @@ use std::sync::Arc; use chrono::DateTime; -use gpui2::{px, relative, rems, Div, Render, Size, View, VisualContext}; +use gpui2::{px, relative, Div, Render, Size, View, VisualContext}; +use settings2::Settings; +use theme2::ThemeSettings; -use crate::{prelude::*, NotificationsPanel}; +use crate::prelude::*; use crate::{ - static_livestream, user_settings_mut, v_stack, AssistantPanel, Button, ChatMessage, ChatPanel, - CollabPanel, EditorPane, FakeSettings, Label, LanguageSelector, Pane, PaneGroup, Panel, - PanelAllowedSides, PanelSide, ProjectPanel, SettingValue, SplitDirection, StatusBar, Terminal, - TitleBar, Toast, ToastOrigin, + static_livestream, v_stack, AssistantPanel, Button, ChatMessage, ChatPanel, CollabPanel, + EditorPane, Label, LanguageSelector, NotificationsPanel, Pane, PaneGroup, Panel, + PanelAllowedSides, PanelSide, ProjectPanel, SplitDirection, StatusBar, Terminal, TitleBar, + Toast, ToastOrigin, }; #[derive(Clone)] @@ -150,6 +152,18 @@ impl Workspace { pub fn debug_toggle_user_settings(&mut self, cx: &mut ViewContext) { self.debug.enable_user_settings = !self.debug.enable_user_settings; + let mut theme_settings = ThemeSettings::get_global(cx).clone(); + + if self.debug.enable_user_settings { + theme_settings.ui_font_size = 18.0.into(); + } else { + theme_settings.ui_font_size = 16.0.into(); + } + + ThemeSettings::override_global(theme_settings.clone(), cx); + + cx.set_rem_size(theme_settings.ui_font_size); + cx.notify(); } @@ -179,20 +193,6 @@ impl Render for Workspace { type Element = Div; fn render(&mut self, cx: &mut ViewContext) -> Div { - // HACK: This should happen inside of `debug_toggle_user_settings`, but - // we don't have `cx.global::()` in event handlers at the moment. - // Need to talk with Nathan/Antonio about this. - { - let settings = user_settings_mut(cx); - - if self.debug.enable_user_settings { - settings.list_indent_depth = SettingValue::UserDefined(rems(0.5).into()); - settings.ui_scale = SettingValue::UserDefined(1.25); - } else { - *settings = FakeSettings::default(); - } - } - let root_group = PaneGroup::new_panes( vec![Pane::new( "pane-0", @@ -321,7 +321,7 @@ impl Render for Workspace { v_stack() .z_index(9) .absolute() - .bottom_10() + .top_20() .left_1_4() .w_40() .gap_2() diff --git a/crates/ui2/src/elements/button.rs b/crates/ui2/src/elements/button.rs index e63269197cbd068532f75dd0bb576030bc1f91b8..073bcdbb4589ed9fc87e4b63dd6acd0bfd3176f4 100644 --- a/crates/ui2/src/elements/button.rs +++ b/crates/ui2/src/elements/button.rs @@ -1,9 +1,9 @@ use std::sync::Arc; -use gpui2::{div, DefiniteLength, Hsla, MouseButton, WindowContext}; +use gpui2::{div, rems, DefiniteLength, Hsla, MouseButton, WindowContext}; -use crate::{h_stack, Icon, IconColor, IconElement, Label, LabelColor}; -use crate::{prelude::*, LineHeightStyle}; +use crate::prelude::*; +use crate::{h_stack, Icon, IconColor, IconElement, Label, LabelColor, LineHeightStyle}; #[derive(Default, PartialEq, Clone, Copy)] pub enum IconPosition { @@ -151,7 +151,7 @@ impl Button { .relative() .id(SharedString::from(format!("{}", self.label))) .p_1() - .text_size(ui_size(cx, 1.)) + .text_size(rems(1.)) .rounded_md() .bg(self.variant.bg_color(cx)) .hover(|style| style.bg(self.variant.bg_color_hover(cx))) @@ -198,7 +198,7 @@ impl ButtonGroup { } fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { - let mut el = h_stack().text_size(ui_size(cx, 1.)); + let mut el = h_stack().text_size(rems(1.)); for button in self.buttons { el = el.child(button.render(_view, cx)); diff --git a/crates/ui2/src/elements/icon.rs b/crates/ui2/src/elements/icon.rs index 6c1b3a4f08547c6ad5eaedcd29202803b558f88e..8cc62f4a8de1285cf1a2145a24cf9e152d474814 100644 --- a/crates/ui2/src/elements/icon.rs +++ b/crates/ui2/src/elements/icon.rs @@ -1,4 +1,4 @@ -use gpui2::{svg, Hsla}; +use gpui2::{rems, svg, Hsla}; use strum::EnumIter; use crate::prelude::*; @@ -175,8 +175,8 @@ impl IconElement { fn render(self, _view: &mut V, cx: &mut ViewContext) -> impl Component { let fill = self.color.color(cx); let svg_size = match self.size { - IconSize::Small => ui_size(cx, 12. / 14.), - IconSize::Medium => ui_size(cx, 15. / 14.), + IconSize::Small => rems(0.75), + IconSize::Medium => rems(0.9375), }; svg() diff --git a/crates/ui2/src/elements/label.rs b/crates/ui2/src/elements/label.rs index ee8ac9a6368d155986578d2e507132e771e6b33e..dcc28a33196d458183fd4d9252ca5316f0d92b83 100644 --- a/crates/ui2/src/elements/label.rs +++ b/crates/ui2/src/elements/label.rs @@ -1,4 +1,4 @@ -use gpui2::{relative, Hsla, WindowContext}; +use gpui2::{relative, rems, Hsla, WindowContext}; use smallvec::SmallVec; use crate::prelude::*; @@ -86,7 +86,7 @@ impl Label { .bg(LabelColor::Hidden.hsla(cx)), ) }) - .text_size(ui_size(cx, 1.)) + .text_size(rems(1.)) .when(self.line_height_style == LineHeightStyle::UILabel, |this| { this.line_height(relative(1.)) }) diff --git a/crates/ui2/src/prelude.rs b/crates/ui2/src/prelude.rs index b424ce61235713d53ca6b37c25bdd663ae514f77..c3f530d70c8314e79bbdc6aafee2725693fc7b67 100644 --- a/crates/ui2/src/prelude.rs +++ b/crates/ui2/src/prelude.rs @@ -4,21 +4,12 @@ pub use gpui2::{ }; pub use crate::elevation::*; -use crate::settings::user_settings; pub use crate::ButtonVariant; pub use theme2::ActiveTheme; -use gpui2::{rems, Hsla, Rems}; +use gpui2::Hsla; use strum::EnumIter; -pub fn ui_size(cx: &mut WindowContext, size: f32) -> Rems { - const UI_SCALE_RATIO: f32 = 0.875; - - let settings = user_settings(cx); - - rems(*settings.ui_scale * UI_SCALE_RATIO * size) -} - #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, EnumIter)] pub enum FileSystemStatus { #[default] diff --git a/crates/ui2/src/settings.rs b/crates/ui2/src/settings.rs index 48a2e8e7b439513b64e89ca6cd12ae0f5f408d88..6a9426f623ef167d8ec3a24054d2586f1536b7f1 100644 --- a/crates/ui2/src/settings.rs +++ b/crates/ui2/src/settings.rs @@ -58,7 +58,6 @@ pub struct FakeSettings { pub list_disclosure_style: SettingValue, pub list_indent_depth: SettingValue, pub titlebar: TitlebarSettings, - pub ui_scale: SettingValue, } impl Default for FakeSettings { @@ -68,7 +67,6 @@ impl Default for FakeSettings { list_disclosure_style: SettingValue::Default(DisclosureControlStyle::ChevronOnHover), list_indent_depth: SettingValue::Default(rems(0.3).into()), default_panel_size: SettingValue::Default(rems(16.).into()), - ui_scale: SettingValue::Default(1.), } } }