1use gpui::{Hsla, Pixels};
2
3use gpui_kit::base::SemanticThemeTokens;
4
5#[derive(Clone, Debug, PartialEq)]
10pub struct BlockEditorStyle {
11 foreground: Hsla,
12 muted_foreground: Hsla,
13 caret: Hsla,
14 caret_width: Pixels,
15 selection: Hsla,
16 composition_underline: Hsla,
17}
18
19impl Default for BlockEditorStyle {
20 fn default() -> Self {
21 let unset = Hsla::transparent_black();
22 Self {
23 foreground: unset,
24 muted_foreground: unset,
25 caret: unset,
26 caret_width: crate::support::CURSOR_WIDTH,
27 selection: unset,
28 composition_underline: unset,
29 }
30 }
31}
32
33macro_rules! style_field {
34 ($with:ident, $get:ident, $ty:ty) => {
35 pub fn $with(mut self, value: $ty) -> Self {
36 self.$get = value;
37 self
38 }
39 pub fn $get(&self) -> $ty {
40 self.$get
41 }
42 };
43}
44
45impl BlockEditorStyle {
46 style_field!(with_foreground, foreground, Hsla);
47 style_field!(with_muted_foreground, muted_foreground, Hsla);
48 style_field!(with_caret, caret, Hsla);
49 style_field!(with_caret_width, caret_width, Pixels);
50 style_field!(with_selection, selection, Hsla);
51 style_field!(with_composition_underline, composition_underline, Hsla);
52
53 pub(crate) fn selection_is_default(&self) -> bool {
56 self.selection.a == 0.
57 }
58
59 pub fn resolved(&self, tokens: &SemanticThemeTokens) -> Self {
61 let colors = &tokens.colors;
62 let or = |value: Hsla, fallback: Hsla| if value.a == 0. { fallback } else { value };
63 let foreground = or(self.foreground, colors.foreground);
64 Self {
65 foreground,
66 muted_foreground: or(self.muted_foreground, colors.muted_foreground),
67 caret: or(self.caret, foreground),
68 composition_underline: or(self.composition_underline, foreground),
69 ..self.clone()
70 }
71 }
72}