diff --git a/crates/theme/src/default_colors.rs b/crates/theme/src/default_colors.rs index a7521bd374..49c216c0e0 100644 --- a/crates/theme/src/default_colors.rs +++ b/crates/theme/src/default_colors.rs @@ -8,12 +8,13 @@ pub(crate) fn neutral() -> ColorScaleSet { sand() } -// Note: We aren't currently making use of the default colors, as all of the -// themes have a value set for each color. -// -// We'll need to revisit these once we're ready to launch user themes, which may -// not specify a value for each color (and thus should fall back to the defaults). +/// The default colors for the theme. +/// +/// Themes that do not specify all colors are refined off of these defaults. impl ThemeColors { + /// Returns the default colors for light themes. + /// + /// Themes that do not specify all colors are refined off of these defaults. pub fn light() -> Self { let system = SystemColors::default(); @@ -114,6 +115,9 @@ impl ThemeColors { } } + /// Returns the default colors for dark themes. + /// + /// Themes that do not specify all colors are refined off of these defaults. pub fn dark() -> Self { let system = SystemColors::default(); @@ -247,6 +251,7 @@ impl TryFrom for ColorScaleSet { } } +/// Color scales used to build the default themes. pub fn default_color_scales() -> ColorScales { ColorScales { gray: gray(), diff --git a/crates/theme/src/default_theme.rs b/crates/theme/src/default_theme.rs index 6722b847ba..5806340916 100644 --- a/crates/theme/src/default_theme.rs +++ b/crates/theme/src/default_theme.rs @@ -45,6 +45,9 @@ pub(crate) fn zed_pro_moonlight() -> Theme { } } +/// Returns the Zed Pro theme family. +/// +/// Note: To be removed until the theme is implemented. pub fn zed_pro_family() -> ThemeFamily { ThemeFamily { id: "zed_pro".to_string(), diff --git a/crates/theme/src/font_family_cache.rs b/crates/theme/src/font_family_cache.rs index c9583b9e8d..755d829902 100644 --- a/crates/theme/src/font_family_cache.rs +++ b/crates/theme/src/font_family_cache.rs @@ -25,14 +25,17 @@ struct GlobalFontFamilyCache(Arc); impl Global for GlobalFontFamilyCache {} impl FontFamilyCache { + /// Initializes the global font family cache. pub fn init_global(cx: &mut AppContext) { cx.default_global::(); } + /// Returns the global font family cache. pub fn global(cx: &AppContext) -> Arc { GlobalFontFamilyCache::global(cx).0.clone() } + /// Returns the list of font families. pub fn list_font_families(&self, cx: &AppContext) -> Vec { if self.state.read().loaded_at.is_some() { return self.state.read().font_families.clone(); diff --git a/crates/theme/src/registry.rs b/crates/theme/src/registry.rs index b70377f440..a77ab141a6 100644 --- a/crates/theme/src/registry.rs +++ b/crates/theme/src/registry.rs @@ -17,9 +17,12 @@ use crate::{ ThemeStyles, }; +/// The metadata for a theme. #[derive(Debug, Clone)] pub struct ThemeMeta { + /// The name of the theme. pub name: SharedString, + /// The appearance of the theme. pub appearance: Appearance, } @@ -38,6 +41,7 @@ struct ThemeRegistryState { themes: HashMap>, } +/// The registry for themes. pub struct ThemeRegistry { state: RwLock, assets: Box, @@ -61,6 +65,7 @@ impl ThemeRegistry { cx.set_global(GlobalThemeRegistry(Arc::new(ThemeRegistry::new(assets)))); } + /// Creates a new [`ThemeRegistry`] with the given [`AssetSource`]. pub fn new(assets: Box) -> Self { let registry = Self { state: RwLock::new(ThemeRegistryState { @@ -99,6 +104,7 @@ impl ThemeRegistry { } } + /// Inserts user themes into the registry. pub fn insert_user_themes(&self, themes: impl IntoIterator) { self.insert_themes(themes.into_iter().map(|user_theme| { let mut theme_colors = match user_theme.appearance { @@ -185,16 +191,19 @@ impl ThemeRegistry { .retain(|name, _| !themes_to_remove.contains(name)) } + /// Removes all themes from the registry. pub fn clear(&mut self) { self.state.write().themes.clear(); } + /// Returns the names of all themes in the registry. pub fn list_names(&self, _staff: bool) -> Vec { let mut names = self.state.read().themes.keys().cloned().collect::>(); names.sort(); names } + /// Returns the metadata of all themes in the registry. pub fn list(&self, _staff: bool) -> Vec { self.state .read() @@ -207,6 +216,7 @@ impl ThemeRegistry { .collect() } + /// Returns the theme with the given name. pub fn get(&self, name: &str) -> Result> { self.state .read() @@ -261,6 +271,7 @@ impl ThemeRegistry { Ok(()) } + /// Asynchronously reads the user theme from the specified path. pub async fn read_user_theme(theme_path: &Path, fs: Arc) -> Result { let reader = fs.open_sync(theme_path).await?; let theme_family: ThemeFamilyContent = serde_json_lenient::from_reader(reader)?; diff --git a/crates/theme/src/scale.rs b/crates/theme/src/scale.rs index 1146090edc..a70dcb9789 100644 --- a/crates/theme/src/scale.rs +++ b/crates/theme/src/scale.rs @@ -1,3 +1,4 @@ +#![allow(missing_docs)] use gpui::{AppContext, Hsla, SharedString}; use crate::{ActiveTheme, Appearance}; diff --git a/crates/theme/src/schema.rs b/crates/theme/src/schema.rs index 9186306123..af334d8aed 100644 --- a/crates/theme/src/schema.rs +++ b/crates/theme/src/schema.rs @@ -1,3 +1,5 @@ +#![allow(missing_docs)] + use anyhow::Result; use gpui::{FontStyle, FontWeight, HighlightStyle, Hsla, WindowBackgroundAppearance}; use indexmap::IndexMap; diff --git a/crates/theme/src/settings.rs b/crates/theme/src/settings.rs index 86383cec8e..0c8ea782cd 100644 --- a/crates/theme/src/settings.rs +++ b/crates/theme/src/settings.rs @@ -35,6 +35,9 @@ const MIN_LINE_HEIGHT: f32 = 1.0; Deserialize, JsonSchema, )] + +/// Specifies the density of the UI. +/// Note: This setting is still experimental. See [this tracking issue](https://github.com/zed-industries/zed/issues/18078) #[serde(rename_all = "snake_case")] pub enum UiDensity { /// A denser UI with tighter spacing and smaller elements. @@ -50,6 +53,8 @@ pub enum UiDensity { } impl UiDensity { + /// The spacing ratio of a given density. + /// TODO: Standardize usage throughout the app or remove pub fn spacing_ratio(self) -> f32 { match self { UiDensity::Compact => 0.75, @@ -80,17 +85,43 @@ impl From for String { } } +/// Customizable settings for the UI and theme system. #[derive(Clone)] pub struct ThemeSettings { + /// The UI font size. Determines the size of text in the UI, + /// as well as the size of a [gpui::Rems] unit. + /// + /// Changing this will impact the size of all UI elements. pub ui_font_size: Pixels, + /// The font used for UI elements. pub ui_font: Font, - pub buffer_font: Font, + /// The font size used for buffers, and the terminal. + /// + /// The terminal font size can be overridden using it's own setting. pub buffer_font_size: Pixels, + /// The font used for buffers, and the terminal. + /// + /// The terminal font family can be overridden using it's own setting. + pub buffer_font: Font, + /// The line height for buffers, and the terminal. + /// + /// Changing this may affect the spacing of some UI elements. + /// + /// The terminal font family can be overridden using it's own setting. pub buffer_line_height: BufferLineHeight, + /// The current theme selection. + /// TODO: Document this further pub theme_selection: Option, + /// The active theme. pub active_theme: Arc, + /// Manual overrides for the active theme. + /// + /// Note: This setting is still experimental. See [this tracking issue](https://github.com/zed-industries/zed/issues/18078) pub theme_overrides: Option, + /// The density of the UI. + /// Note: This setting is still experimental. See [this tracking issue]( pub ui_density: UiDensity, + /// The amount of fading applied to unnecessary code. pub unnecessary_code_fade: f32, } @@ -181,15 +212,21 @@ pub(crate) struct AdjustedUiFontSize(Pixels); impl Global for AdjustedUiFontSize {} +/// Represents the selection of a theme, which can be either static or dynamic. #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] #[serde(untagged)] pub enum ThemeSelection { + /// A static theme selection, represented by a single theme name. Static(#[schemars(schema_with = "theme_name_ref")] String), + /// A dynamic theme selection, which can change based the [ThemeMode]. Dynamic { + /// The mode used to determine which theme to use. #[serde(default)] mode: ThemeMode, + /// The theme to use for light mode. #[schemars(schema_with = "theme_name_ref")] light: String, + /// The theme to use for dark mode. #[schemars(schema_with = "theme_name_ref")] dark: String, }, @@ -199,6 +236,12 @@ fn theme_name_ref(_: &mut SchemaGenerator) -> Schema { Schema::new_ref("#/definitions/ThemeName".into()) } +// TODO: Rename ThemeMode -> ThemeAppearanceMode +/// The mode use to select a theme. +/// +/// `Light` and `Dark` will select their respective themes. +/// +/// `System` will select the theme based on the system's appearance. #[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum ThemeMode { @@ -214,6 +257,7 @@ pub enum ThemeMode { } impl ThemeSelection { + /// Returns the theme name for the selected [ThemeMode]. pub fn theme(&self, system_appearance: Appearance) -> &str { match self { Self::Static(theme) => theme, @@ -228,6 +272,7 @@ impl ThemeSelection { } } + /// Returns the [ThemeMode] for the [ThemeSelection]. pub fn mode(&self) -> Option { match self { ThemeSelection::Static(_) => None, @@ -327,6 +372,7 @@ impl ThemeSettingsContent { } } + /// Sets the mode for the theme. pub fn set_mode(&mut self, mode: ThemeMode) { if let Some(selection) = self.theme.as_mut() { match selection { @@ -355,16 +401,23 @@ impl ThemeSettingsContent { } } +/// The buffer's line height. #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, JsonSchema, Default)] #[serde(rename_all = "snake_case")] pub enum BufferLineHeight { + /// A less dense line height. #[default] Comfortable, + /// The default line height. Standard, + /// A custom line height. + /// + /// A line height of 1.0 is the height of the buffer's font size. Custom(f32), } impl BufferLineHeight { + /// Returns the value of the line height. pub fn value(&self) -> f32 { match self { BufferLineHeight::Comfortable => 1.618, @@ -375,12 +428,15 @@ impl BufferLineHeight { } impl ThemeSettings { + /// Returns the [AdjustedBufferFontSize]. pub fn buffer_font_size(&self, cx: &AppContext) -> Pixels { cx.try_global::() .map_or(self.buffer_font_size, |size| size.0) .max(MIN_FONT_SIZE) } + // TODO: Rename: `line_height` -> `buffer_line_height` + /// Returns the buffer's line height. pub fn line_height(&self) -> f32 { f32::max(self.buffer_line_height.value(), MIN_LINE_HEIGHT) } @@ -433,6 +489,7 @@ impl ThemeSettings { } } +/// Observe changes to the adjusted buffer font size. pub fn observe_buffer_font_size_adjustment( cx: &mut ViewContext, f: impl 'static + Fn(&mut V, &mut ViewContext), @@ -440,6 +497,7 @@ pub fn observe_buffer_font_size_adjustment( cx.observe_global::(f) } +/// Sets the adjusted buffer font size. pub fn adjusted_font_size(size: Pixels, cx: &mut AppContext) -> Pixels { if let Some(AdjustedBufferFontSize(adjusted_size)) = cx.try_global::() { let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size; @@ -451,12 +509,14 @@ pub fn adjusted_font_size(size: Pixels, cx: &mut AppContext) -> Pixels { .max(MIN_FONT_SIZE) } +/// Returns the adjusted buffer font size. pub fn get_buffer_font_size(cx: &AppContext) -> Pixels { let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size; cx.try_global::() .map_or(buffer_font_size, |adjusted_size| adjusted_size.0) } +/// Adjusts the buffer font size. pub fn adjust_buffer_font_size(cx: &mut AppContext, f: fn(&mut Pixels)) { let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size; let mut adjusted_size = cx @@ -469,10 +529,12 @@ pub fn adjust_buffer_font_size(cx: &mut AppContext, f: fn(&mut Pixels)) { cx.refresh(); } +/// Returns whether the buffer font size has been adjusted. pub fn has_adjusted_buffer_font_size(cx: &mut AppContext) -> bool { cx.has_global::() } +/// Resets the buffer font size to the default value. pub fn reset_buffer_font_size(cx: &mut AppContext) { if cx.has_global::() { cx.remove_global::(); @@ -480,6 +542,8 @@ pub fn reset_buffer_font_size(cx: &mut AppContext) { } } +// TODO: Make private, change usages to use `get_ui_font_size` instead. +#[allow(missing_docs)] pub fn setup_ui_font(cx: &mut WindowContext) -> gpui::Font { let (ui_font, ui_font_size) = { let theme_settings = ThemeSettings::get_global(cx); @@ -491,12 +555,14 @@ pub fn setup_ui_font(cx: &mut WindowContext) -> gpui::Font { ui_font } +/// Gets the adjusted UI font size. pub fn get_ui_font_size(cx: &AppContext) -> Pixels { let ui_font_size = ThemeSettings::get_global(cx).ui_font_size; cx.try_global::() .map_or(ui_font_size, |adjusted_size| adjusted_size.0) } +/// Sets the adjusted UI font size. pub fn adjust_ui_font_size(cx: &mut AppContext, f: fn(&mut Pixels)) { let ui_font_size = ThemeSettings::get_global(cx).ui_font_size; let mut adjusted_size = cx @@ -509,10 +575,12 @@ pub fn adjust_ui_font_size(cx: &mut AppContext, f: fn(&mut Pixels)) { cx.refresh(); } +/// Returns whether the UI font size has been adjusted. pub fn has_adjusted_ui_font_size(cx: &mut AppContext) -> bool { cx.has_global::() } +/// Resets the UI font size to the default value. pub fn reset_ui_font_size(cx: &mut AppContext) { if cx.has_global::() { cx.remove_global::(); diff --git a/crates/theme/src/styles/accents.rs b/crates/theme/src/styles/accents.rs index dfcd19911b..e4d7f03cf6 100644 --- a/crates/theme/src/styles/accents.rs +++ b/crates/theme/src/styles/accents.rs @@ -20,6 +20,7 @@ impl Default for AccentColors { } impl AccentColors { + /// Returns the set of dark accent colors. pub fn dark() -> Self { Self(vec![ blue().dark().step_9(), @@ -38,6 +39,7 @@ impl AccentColors { ]) } + /// Returns the set of light accent colors. pub fn light() -> Self { Self(vec![ blue().light().step_9(), @@ -58,6 +60,7 @@ impl AccentColors { } impl AccentColors { + /// Returns the color for the given index. pub fn color_for_index(&self, index: u32) -> Hsla { self.0[index as usize % self.0.len()] } diff --git a/crates/theme/src/styles/colors.rs b/crates/theme/src/styles/colors.rs index 225275f37b..881a68334d 100644 --- a/crates/theme/src/styles/colors.rs +++ b/crates/theme/src/styles/colors.rs @@ -1,3 +1,5 @@ +#![allow(missing_docs)] + use gpui::{Hsla, WindowBackgroundAppearance}; use refineable::Refineable; use std::sync::Arc; diff --git a/crates/theme/src/styles/players.rs b/crates/theme/src/styles/players.rs index e80c7161b1..1307210332 100644 --- a/crates/theme/src/styles/players.rs +++ b/crates/theme/src/styles/players.rs @@ -1,3 +1,5 @@ +#![allow(missing_docs)] + use gpui::Hsla; use serde_derive::Deserialize; diff --git a/crates/theme/src/styles/status.rs b/crates/theme/src/styles/status.rs index 854b876ac2..84afae701d 100644 --- a/crates/theme/src/styles/status.rs +++ b/crates/theme/src/styles/status.rs @@ -1,3 +1,5 @@ +#![allow(missing_docs)] + use gpui::Hsla; use refineable::Refineable; diff --git a/crates/theme/src/styles/stories/color.rs b/crates/theme/src/styles/stories/color.rs index 90e84bcf0f..8e6c86ba76 100644 --- a/crates/theme/src/styles/stories/color.rs +++ b/crates/theme/src/styles/stories/color.rs @@ -4,6 +4,7 @@ use story::Story; use crate::{default_color_scales, ColorScaleStep}; +/// The story showcasing all the default color scales pub struct ColorsStory; impl Render for ColorsStory { diff --git a/crates/theme/src/styles/stories/players.rs b/crates/theme/src/styles/stories/players.rs index 2b356670bf..0d50c6edc9 100644 --- a/crates/theme/src/styles/stories/players.rs +++ b/crates/theme/src/styles/stories/players.rs @@ -3,6 +3,7 @@ use story::Story; use crate::{ActiveTheme, PlayerColors}; +/// The story showcasing the player colors pub struct PlayerStory; impl Render for PlayerStory { diff --git a/crates/theme/src/styles/syntax.rs b/crates/theme/src/styles/syntax.rs index 8016445c16..0a97ff77f2 100644 --- a/crates/theme/src/styles/syntax.rs +++ b/crates/theme/src/styles/syntax.rs @@ -1,3 +1,5 @@ +#![allow(missing_docs)] + use std::sync::Arc; use gpui::{HighlightStyle, Hsla}; diff --git a/crates/theme/src/styles/system.rs b/crates/theme/src/styles/system.rs index aeb0865155..54e892b79c 100644 --- a/crates/theme/src/styles/system.rs +++ b/crates/theme/src/styles/system.rs @@ -1,3 +1,5 @@ +#![allow(missing_docs)] + use gpui::{hsla, Hsla}; #[derive(Clone)] diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index af38c9efc6..a6ca59d734 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -1,3 +1,5 @@ +#![deny(missing_docs)] + //! # Theme //! //! This crate provides the theme system for Zed. @@ -10,6 +12,9 @@ mod default_colors; mod default_theme; mod font_family_cache; mod one_themes; +/// A prelude for working with the theme system. +/// +/// TODO: remove this. This only publishes default colors. pub mod prelude; mod registry; mod scale; @@ -35,16 +40,22 @@ use gpui::{ }; use serde::Deserialize; +/// Defines window border radius for platforms that use client side decorations. +pub const CLIENT_SIDE_DECORATION_ROUNDING: Pixels = px(10.0); +/// Defines window shadow size for platforms that use client side decorations. +pub const CLIENT_SIDE_DECORATION_SHADOW: Pixels = px(10.0); + +/// The appearance of the theme. #[derive(Debug, PartialEq, Clone, Copy, Deserialize)] pub enum Appearance { + /// A light appearance. Light, + /// A dark appearance. Dark, } -pub const CLIENT_SIDE_DECORATION_ROUNDING: Pixels = px(10.0); -pub const CLIENT_SIDE_DECORATION_SHADOW: Pixels = px(10.0); - impl Appearance { + /// Returns whether the appearance is light. pub fn is_light(&self) -> bool { match self { Self::Light => true, @@ -62,6 +73,7 @@ impl From for Appearance { } } +/// Which themes should be loaded. This is used primarlily for testing. pub enum LoadThemes { /// Only load the base theme. /// @@ -72,6 +84,7 @@ pub enum LoadThemes { All(Box), } +/// Initialize the theme system. pub fn init(themes_to_load: LoadThemes, cx: &mut AppContext) { let (assets, load_user_themes) = match themes_to_load { LoadThemes::JustBase => (Box::new(()) as Box, false), @@ -97,7 +110,9 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut AppContext) { .detach(); } +/// Implementing this trait allows accessing the active theme. pub trait ActiveTheme { + /// Returns the active theme. fn theme(&self) -> &Arc; } @@ -107,21 +122,39 @@ impl ActiveTheme for AppContext { } } +/// A theme family is a grouping of themes under a single name. +/// +/// For example, the "One" theme family contains the "One Light" and "One Dark" themes. +/// +/// It can also be used to package themes with many variants. +/// +/// For example, the "Atelier" theme family contains "Cave", "Dune", "Estuary", "Forest", "Heath", etc. pub struct ThemeFamily { + /// The unique identifier for the theme family. pub id: String, + /// The name of the theme family. This will be displayed in the UI, such as when adding or removing a theme family. pub name: SharedString, + /// The author of the theme family. pub author: SharedString, + /// The [Theme]s in the family. pub themes: Vec, + /// The color scales used by the themes in the family. + /// Note: This will be removed in the future. pub scales: ColorScales, } impl ThemeFamily {} +/// A theme is the primary mechanism for defining the appearance of the UI. #[derive(Clone)] pub struct Theme { + /// The unique identifier for the theme. pub id: String, + /// The name of the theme. pub name: SharedString, + /// The appearance of the theme (light or dark). pub appearance: Appearance, + /// The colors and other styles for the theme. pub styles: ThemeStyles, } @@ -181,6 +214,8 @@ impl Theme { } } +/// Compounds a color with an alpha value. +/// TODO: Replace this with a method on Hsla. pub fn color_alpha(color: Hsla, alpha: f32) -> Hsla { let mut color = color; color.a = alpha;