use gpui::{Global, Hsla, SharedString};
use crate::{Appearance, paint};
mod glass;
mod install;
mod layout;
mod palettes;
mod syntax;
pub use install::set_palette;
pub use syntax::{HighlightKind, SyntaxPalette};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Glass {
Regular,
Clear,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Frost {
UltraThin,
Thin,
Regular,
Thick,
UltraThick,
}
impl Frost {
pub fn opacity(self) -> f32 {
match self {
Frost::UltraThin => 0.440,
Frost::Thin => 0.543,
Frost::Regular => 0.638,
Frost::Thick => 0.737,
Frost::UltraThick => 0.825,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SurfaceStyle {
Frost(Frost),
Glass(Glass),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FrostSpec {
pub tone: Hsla,
pub saturation: f32,
pub blur: f32,
pub edge: f32,
pub edge_width: f32,
pub edge_aa: f32,
}
impl FrostSpec {
pub fn at(&self, thickness: Frost) -> SurfaceSpec {
let opacity = thickness.opacity();
SurfaceSpec {
gain: 1.0 - opacity,
saturation: self.saturation,
tint: self.tone.opacity(opacity),
blur: self.blur,
rim: 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 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::Frost(thickness) => theme.frost.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 frost: FrostSpec,
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,
pub font_sans_fallback: SharedString,
pub font_mono_fallback: SharedString,
}
impl Theme {
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 {}