Skip to main content

gpui_liveplot/
style.rs

1//! Style and theming configuration.
2//!
3//! Themes describe plot-level colors (background, grid, axes, overlays).
4
5use gpui::Rgba;
6
7/// Visual theme for plot-level elements such as axes, grid, and overlays.
8///
9/// Themes are applied at the plot level and affect all series and overlays.
10#[derive(Debug, Clone, PartialEq)]
11pub struct Theme {
12    /// Plot background color.
13    pub background: Rgba,
14    /// Axis, tick, and label color.
15    pub axis: Rgba,
16    /// Major grid line color.
17    pub grid_major: Rgba,
18    /// Minor grid line color.
19    pub grid_minor: Rgba,
20    /// Hover tooltip background color.
21    pub hover_bg: Rgba,
22    /// Hover tooltip border color.
23    pub hover_border: Rgba,
24    /// Pin tooltip background color.
25    pub pin_bg: Rgba,
26    /// Pin tooltip border color.
27    pub pin_border: Rgba,
28    /// Selection rectangle fill color.
29    pub selection_fill: Rgba,
30    /// Selection rectangle border color.
31    pub selection_border: Rgba,
32    /// Legend background color.
33    pub legend_bg: Rgba,
34    /// Legend border color.
35    pub legend_border: Rgba,
36}
37
38impl Theme {
39    /// Create the default theme (alias of [`Theme::dark`]).
40    pub fn new() -> Self {
41        Self::default()
42    }
43
44    /// Create a light theme palette.
45    pub fn light() -> Self {
46        Self {
47            background: Rgba {
48                r: 1.0,
49                g: 1.0,
50                b: 1.0,
51                a: 1.0,
52            },
53            axis: Rgba {
54                r: 0.2,
55                g: 0.2,
56                b: 0.2,
57                a: 1.0,
58            },
59            grid_major: Rgba {
60                r: 0.86,
61                g: 0.86,
62                b: 0.86,
63                a: 1.0,
64            },
65            grid_minor: Rgba {
66                r: 0.93,
67                g: 0.93,
68                b: 0.93,
69                a: 1.0,
70            },
71            hover_bg: Rgba {
72                r: 1.0,
73                g: 1.0,
74                b: 1.0,
75                a: 0.9,
76            },
77            hover_border: Rgba {
78                r: 0.2,
79                g: 0.2,
80                b: 0.2,
81                a: 0.8,
82            },
83            pin_bg: Rgba {
84                r: 1.0,
85                g: 1.0,
86                b: 1.0,
87                a: 0.92,
88            },
89            pin_border: Rgba {
90                r: 0.2,
91                g: 0.2,
92                b: 0.2,
93                a: 0.8,
94            },
95            selection_fill: Rgba {
96                r: 0.1,
97                g: 0.4,
98                b: 0.9,
99                a: 0.15,
100            },
101            selection_border: Rgba {
102                r: 0.1,
103                g: 0.4,
104                b: 0.9,
105                a: 0.9,
106            },
107            legend_bg: Rgba {
108                r: 1.0,
109                g: 1.0,
110                b: 1.0,
111                a: 0.85,
112            },
113            legend_border: Rgba {
114                r: 0.2,
115                g: 0.2,
116                b: 0.2,
117                a: 0.6,
118            },
119        }
120    }
121
122    /// Create a dark theme palette.
123    pub fn dark() -> Self {
124        Self {
125            background: Rgba {
126                r: 0.08,
127                g: 0.08,
128                b: 0.09,
129                a: 1.0,
130            },
131            axis: Rgba {
132                r: 0.85,
133                g: 0.85,
134                b: 0.85,
135                a: 1.0,
136            },
137            grid_major: Rgba {
138                r: 0.25,
139                g: 0.25,
140                b: 0.28,
141                a: 1.0,
142            },
143            grid_minor: Rgba {
144                r: 0.18,
145                g: 0.18,
146                b: 0.2,
147                a: 1.0,
148            },
149            hover_bg: Rgba {
150                r: 0.12,
151                g: 0.12,
152                b: 0.13,
153                a: 0.92,
154            },
155            hover_border: Rgba {
156                r: 0.6,
157                g: 0.6,
158                b: 0.6,
159                a: 0.8,
160            },
161            pin_bg: Rgba {
162                r: 0.12,
163                g: 0.12,
164                b: 0.13,
165                a: 0.92,
166            },
167            pin_border: Rgba {
168                r: 0.6,
169                g: 0.6,
170                b: 0.6,
171                a: 0.85,
172            },
173            selection_fill: Rgba {
174                r: 0.2,
175                g: 0.5,
176                b: 0.95,
177                a: 0.18,
178            },
179            selection_border: Rgba {
180                r: 0.3,
181                g: 0.6,
182                b: 1.0,
183                a: 0.9,
184            },
185            legend_bg: Rgba {
186                r: 0.12,
187                g: 0.12,
188                b: 0.13,
189                a: 0.9,
190            },
191            legend_border: Rgba {
192                r: 0.5,
193                g: 0.5,
194                b: 0.5,
195                a: 0.7,
196            },
197        }
198    }
199
200    /// Build a plot theme from the current `gpui-component` theme.
201    ///
202    /// This is only available when the `gpui_component_theme` feature is enabled.
203    #[cfg(feature = "gpui_component_theme")]
204    pub fn from_gpui_component_theme(theme: &gpui_component::Theme) -> Self {
205        Self {
206            background: theme.background.into(),
207            axis: theme.foreground.into(),
208            grid_major: theme.border.opacity(0.9).into(),
209            grid_minor: theme.border.opacity(0.45).into(),
210            hover_bg: theme.popover.opacity(0.92).into(),
211            hover_border: theme.border.opacity(0.9).into(),
212            pin_bg: theme.popover.opacity(0.92).into(),
213            pin_border: theme.border.opacity(0.95).into(),
214            selection_fill: theme.selection.opacity(0.35).into(),
215            selection_border: theme.selection.opacity(0.9).into(),
216            legend_bg: theme.popover.opacity(0.9).into(),
217            legend_border: theme.border.opacity(0.8).into(),
218        }
219    }
220}
221
222impl Default for Theme {
223    fn default() -> Self {
224        Self::dark()
225    }
226}