1use gpui::{App, FontWeight, Global, Hsla};
5use theme::Theme;
6
7use crate::Marks;
8
9impl Marks {
10 pub(crate) fn of(cx: &App) -> Self {
12 cx.try_global::<Installed>()
13 .map_or_else(Self::default, |installed| installed.0.clone())
14 }
15}
16
17struct Installed(Marks);
18
19impl Global for Installed {}
20
21pub(crate) fn set_marks(cx: &mut App, marks: Marks) {
24 cx.set_global(Installed(marks));
25}
26
27#[derive(Clone, Copy, Debug, Default, PartialEq)]
29pub struct MarkPaint {
30 pub color: Option<Hsla>,
31 pub background: Option<Hsla>,
33 pub weight: Option<FontWeight>,
34 pub italic: bool,
35 pub underline: bool,
36 pub strikethrough: bool,
37}
38
39pub type Painter = fn(name: &str, theme: &Theme) -> Option<MarkPaint>;
42
43struct InstalledPaint(Painter);
44
45impl Global for InstalledPaint {}
46
47pub(crate) fn set_mark_paint(cx: &mut App, paint: Painter) {
51 cx.set_global(InstalledPaint(paint));
52}
53
54pub(crate) fn paint_of(cx: &App, name: &str, theme: &Theme) -> Option<MarkPaint> {
55 (cx.try_global::<InstalledPaint>()?.0)(name, theme)
56}
57
58#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
63#[non_exhaustive]
64pub enum HighlightColor {
65 #[default]
66 Yellow,
67 Green,
68 Blue,
69 Pink,
70 Purple,
71}
72
73impl HighlightColor {
74 pub const ALL: [Self; 5] = [
76 Self::Yellow,
77 Self::Green,
78 Self::Blue,
79 Self::Pink,
80 Self::Purple,
81 ];
82
83 pub fn name(self) -> &'static str {
86 match self {
87 Self::Yellow => "yellow",
88 Self::Green => "green",
89 Self::Blue => "blue",
90 Self::Pink => "pink",
91 Self::Purple => "purple",
92 }
93 }
94
95 pub fn from_name(name: &str) -> Option<Self> {
96 Self::ALL.into_iter().find(|color| color.name() == name)
97 }
98
99 pub fn system(self) -> ui::color::SystemColor {
101 match self {
102 Self::Yellow => ui::color::SystemColor::Yellow,
103 Self::Green => ui::color::SystemColor::Green,
104 Self::Blue => ui::color::SystemColor::Blue,
105 Self::Pink => ui::color::SystemColor::Pink,
106 Self::Purple => ui::color::SystemColor::Purple,
107 }
108 }
109}
110
111pub type HighlightPaint = fn(color: HighlightColor, theme: &Theme) -> Hsla;
113
114struct InstalledHighlight(HighlightPaint);
115
116impl Global for InstalledHighlight {}
117
118pub(crate) fn set_highlight_paint(cx: &mut App, paint: HighlightPaint) {
121 cx.set_global(InstalledHighlight(paint));
122}
123
124pub(crate) fn highlight_paint_of(cx: &App) -> HighlightPaint {
125 cx.try_global::<InstalledHighlight>()
126 .map_or(default_highlight, |installed| installed.0)
127}
128
129pub fn highlight_solid(color: HighlightColor, theme: &Theme) -> Hsla {
133 color.system().resolve(theme)
134}
135
136pub fn highlight_wash(color: Hsla, theme: &Theme) -> Hsla {
139 let alpha = match theme.appearance {
140 theme::Appearance::Dark => 0.32,
141 theme::Appearance::Light => 0.45,
142 };
143 color.opacity(alpha)
144}
145
146pub fn default_highlight(color: HighlightColor, theme: &Theme) -> Hsla {
148 highlight_wash(highlight_solid(color, theme), theme)
149}