use gpui::{Global, Hsla, SharedString};
use crate::{Appearance, paint};
mod glass;
mod install;
mod layout;
mod palettes;
mod syntax;
mod typography;
pub use install::set_palette;
pub use layout::{ControlSize, Sizing};
pub use syntax::{HighlightKind, SyntaxPalette};
pub use typography::{Metrics, TextStyle, Typeset, base_text_size, set_base_text_size};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Glass {
Regular,
Clear,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Material {
UltraThin,
Thin,
Regular,
Thick,
UltraThick,
}
impl Material {
pub fn opacity(self) -> f32 {
match self {
Material::UltraThin => 0.440,
Material::Thin => 0.543,
Material::Regular => 0.638,
Material::Thick => 0.737,
Material::UltraThick => 0.825,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SurfaceStyle {
Material(Material),
Glass(Glass),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct MaterialSpec {
pub tone: Hsla,
pub saturation: f32,
pub blur: f32,
pub edge: f32,
pub edge_width: f32,
pub edge_aa: f32,
}
impl MaterialSpec {
pub fn at(&self, thickness: Material) -> SurfaceSpec {
let opacity = thickness.opacity();
SurfaceSpec {
gain: 1.0 - opacity,
saturation: self.saturation,
tint: self.tone.opacity(opacity),
blur: self.blur,
rim: 0.0,
reach: 0.0,
edge: self.edge,
edge_width: self.edge_width,
edge_aa: self.edge_aa,
shadow: true,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct SurfaceSpec {
pub gain: f32,
pub saturation: f32,
pub tint: Hsla,
pub blur: f32,
pub rim: f32,
pub reach: f32,
pub edge: f32,
pub edge_width: f32,
pub edge_aa: f32,
pub shadow: bool,
}
impl SurfaceStyle {
pub fn spec(self, theme: &Theme) -> SurfaceSpec {
match self {
SurfaceStyle::Material(thickness) => theme.material.at(thickness),
SurfaceStyle::Glass(Glass::Regular) => theme.glass_regular,
SurfaceStyle::Glass(Glass::Clear) => theme.glass_clear,
}
}
}
#[derive(Debug, Clone)]
pub struct Theme {
pub appearance: Appearance,
pub bg: Hsla,
pub surface: Hsla,
pub surface_raised: Hsla,
pub surface_card: Hsla,
pub surface_dialog: Hsla,
pub surface_overlay: Hsla,
pub element_hover: Hsla,
pub element_active: Hsla,
pub border: Hsla,
pub border_strong: Hsla,
pub text: Hsla,
pub text_muted: Hsla,
pub text_faint: Hsla,
pub text_dim: Hsla,
pub solid: Hsla,
pub on_solid: Hsla,
pub accent: Hsla,
pub accent_strong: Hsla,
pub on_accent: Hsla,
pub danger: Hsla,
pub danger_muted: Hsla,
pub warning: Hsla,
pub warning_muted: Hsla,
pub success: Hsla,
pub busy: Hsla,
pub success_muted: Hsla,
pub surface_raised_hover: Hsla,
pub band: Hsla,
pub input_bg: Hsla,
pub selection: Hsla,
pub cursor: Hsla,
pub caret: Hsla,
pub ring: Hsla,
pub danger_strong: Hsla,
pub code_text: Hsla,
pub code_wash: Hsla,
pub syntax: SyntaxPalette,
pub diff_add: Hsla,
pub diff_del: Hsla,
pub diff_hunk_bg: Hsla,
pub vibrancy_alpha: f32,
pub vibrancy: bool,
pub glass: bool,
pub material: MaterialSpec,
pub glass_regular: SurfaceSpec,
pub glass_clear: SurfaceSpec,
pub popover_surface: SurfaceStyle,
pub glass_magnify: f32,
pub glass_dispersion: f32,
pub font_sans: SharedString,
pub font_mono: SharedString,
}
impl Theme {
pub fn card_selected_bg(&self) -> Hsla {
paint::card_selected_bg_for(self.appearance)
}
pub fn ink(&self, alpha: f32) -> Hsla {
paint::ink_for(self.appearance, alpha)
}
pub fn hairline(&self, alpha: f32) -> Hsla {
paint::hairline_for(self.appearance, alpha)
}
pub fn wash(&self, alpha: f32) -> Hsla {
paint::wash_for(self.appearance, alpha)
}
}
impl Default for Theme {
fn default() -> Self {
Self::dark()
}
}
impl Global for Theme {}