use gpui::{App, FontWeight, Global, Hsla};
use theme::Theme;
use crate::Marks;
impl Marks {
pub(crate) fn of(cx: &App) -> Self {
cx.try_global::<Installed>()
.map_or_else(Self::default, |installed| installed.0.clone())
}
}
struct Installed(Marks);
impl Global for Installed {}
pub(crate) fn set_marks(cx: &mut App, marks: Marks) {
cx.set_global(Installed(marks));
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct MarkPaint {
pub color: Option<Hsla>,
pub background: Option<Hsla>,
pub weight: Option<FontWeight>,
pub italic: bool,
pub underline: bool,
pub strikethrough: bool,
}
pub type Painter = fn(name: &str, theme: &Theme) -> Option<MarkPaint>;
struct InstalledPaint(Painter);
impl Global for InstalledPaint {}
pub(crate) fn set_mark_paint(cx: &mut App, paint: Painter) {
cx.set_global(InstalledPaint(paint));
}
pub(crate) fn paint_of(cx: &App, name: &str, theme: &Theme) -> Option<MarkPaint> {
(cx.try_global::<InstalledPaint>()?.0)(name, theme)
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum HighlightColor {
#[default]
Yellow,
Green,
Blue,
Pink,
Purple,
}
impl HighlightColor {
pub const ALL: [Self; 5] = [
Self::Yellow,
Self::Green,
Self::Blue,
Self::Pink,
Self::Purple,
];
pub fn name(self) -> &'static str {
match self {
Self::Yellow => "yellow",
Self::Green => "green",
Self::Blue => "blue",
Self::Pink => "pink",
Self::Purple => "purple",
}
}
pub fn from_name(name: &str) -> Option<Self> {
Self::ALL.into_iter().find(|color| color.name() == name)
}
pub fn system(self) -> ui::color::SystemColor {
match self {
Self::Yellow => ui::color::SystemColor::Yellow,
Self::Green => ui::color::SystemColor::Green,
Self::Blue => ui::color::SystemColor::Blue,
Self::Pink => ui::color::SystemColor::Pink,
Self::Purple => ui::color::SystemColor::Purple,
}
}
}
pub type HighlightPaint = fn(color: HighlightColor, theme: &Theme) -> Hsla;
struct InstalledHighlight(HighlightPaint);
impl Global for InstalledHighlight {}
pub(crate) fn set_highlight_paint(cx: &mut App, paint: HighlightPaint) {
cx.set_global(InstalledHighlight(paint));
}
pub(crate) fn highlight_paint_of(cx: &App) -> HighlightPaint {
cx.try_global::<InstalledHighlight>()
.map_or(default_highlight, |installed| installed.0)
}
pub fn highlight_solid(color: HighlightColor, theme: &Theme) -> Hsla {
color.system().resolve(theme)
}
pub fn highlight_wash(color: Hsla, theme: &Theme) -> Hsla {
let alpha = match theme.appearance {
theme::Appearance::Dark => 0.32,
theme::Appearance::Light => 0.45,
};
color.opacity(alpha)
}
pub fn default_highlight(color: HighlightColor, theme: &Theme) -> Hsla {
highlight_wash(highlight_solid(color, theme), theme)
}