egui_code_editor/themes/
mod.rs1#![allow(dead_code)]
2pub mod ayu;
3pub mod github;
4pub mod gruvbox;
5pub mod sonokai;
6
7use super::syntax::TokenType;
8#[cfg(feature = "egui")]
9use egui::Color32;
10
11#[cfg(feature = "egui")]
12pub const ERROR_COLOR: Color32 = Color32::from_rgb(255, 0, 255);
13
14pub const DEFAULT_THEMES: [ColorTheme; 8] = [
16 ColorTheme::AYU,
17 ColorTheme::AYU_MIRAGE,
18 ColorTheme::AYU_DARK,
19 ColorTheme::GITHUB_DARK,
20 ColorTheme::GITHUB_LIGHT,
21 ColorTheme::GRUVBOX,
22 ColorTheme::GRUVBOX_LIGHT,
23 ColorTheme::SONOKAI,
24];
25
26#[cfg(feature = "egui")]
27fn color_from_hex(hex: &str) -> Option<Color32> {
28 if hex == "none" {
29 return Some(Color32::from_rgba_premultiplied(255, 0, 255, 0));
30 }
31 let rgb = (1..hex.len())
32 .step_by(2)
33 .filter_map(|i| u8::from_str_radix(&hex[i..i + 2], 16).ok())
34 .collect::<Vec<u8>>();
35 let color = Color32::from_rgb(*rgb.first()?, *rgb.get(1)?, *rgb.get(2)?);
36 Some(color)
37}
38
39#[derive(Hash, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
40pub struct ColorTheme {
42 pub name: &'static str,
43 pub dark: bool,
44 pub bg: &'static str,
45 pub cursor: &'static str,
46 pub selection: &'static str,
47 pub comments: &'static str,
48 pub functions: &'static str,
49 pub keywords: &'static str,
50 pub literals: &'static str,
51 pub numerics: &'static str,
52 pub punctuation: &'static str,
53 pub strs: &'static str,
54 pub types: &'static str,
55 pub special: &'static str,
56}
57impl Default for ColorTheme {
58 fn default() -> Self {
59 ColorTheme::GRUVBOX
60 }
61}
62impl ColorTheme {
63 pub fn name(&self) -> &str {
64 self.name
65 }
66
67 pub fn is_dark(&self) -> bool {
68 self.dark
69 }
70
71 #[cfg(feature = "egui")]
72 pub fn bg(&self) -> Color32 {
73 color_from_hex(self.bg).unwrap_or(ERROR_COLOR)
74 }
75
76 #[cfg(feature = "egui")]
77 pub fn cursor(&self) -> Color32 {
78 color_from_hex(self.cursor).unwrap_or(ERROR_COLOR)
79 }
80
81 #[cfg(feature = "egui")]
82 pub fn selection(&self) -> Color32 {
83 color_from_hex(self.selection).unwrap_or(ERROR_COLOR)
84 }
85
86 #[cfg(feature = "egui")]
87 pub fn modify_style(&self, ui: &mut egui::Ui, fontsize: f32) {
88 let style = ui.style_mut();
89 let bg = self.bg();
90 style.visuals.widgets.noninteractive.bg_fill = bg;
91 style.visuals.window_fill = bg;
92 style.visuals.panel_fill = bg;
93 style.visuals.faint_bg_color = bg;
94 style.visuals.extreme_bg_color = bg;
95 style.visuals.selection.stroke.color = self.cursor();
96 style.visuals.selection.bg_fill = self.selection();
97 style.override_font_id = Some(egui::FontId::monospace(fontsize));
98 style.visuals.text_cursor.stroke.width = fontsize * 0.1;
99 }
100
101 pub const fn type_color_str(&self, ty: TokenType) -> &'static str {
102 match ty {
103 TokenType::Comment(_) => self.comments,
104 TokenType::Function => self.functions,
105 TokenType::Keyword => self.keywords,
106 TokenType::Literal => self.literals,
107 TokenType::Hyperlink => self.special,
108 TokenType::Numeric(_) => self.numerics,
109 TokenType::Punctuation(_) => self.punctuation,
110 TokenType::Special => self.special,
111 TokenType::Str(_) => self.strs,
112 TokenType::Type => self.types,
113 TokenType::Whitespace(_) | TokenType::Unknown => self.comments,
114 }
115 }
116
117 #[cfg(feature = "egui")]
118 pub fn type_color(&self, ty: TokenType) -> Color32 {
119 match ty {
120 TokenType::Comment(_) => color_from_hex(self.comments),
121 TokenType::Function => color_from_hex(self.functions),
122 TokenType::Keyword => color_from_hex(self.keywords),
123 TokenType::Literal => color_from_hex(self.literals),
124 TokenType::Hyperlink => color_from_hex(self.special),
125 TokenType::Numeric(_) => color_from_hex(self.numerics),
126 TokenType::Punctuation(_) => color_from_hex(self.punctuation),
127 TokenType::Special => color_from_hex(self.special),
128 TokenType::Str(_) => color_from_hex(self.strs),
129 TokenType::Type => color_from_hex(self.types),
130 TokenType::Whitespace(_) | TokenType::Unknown => color_from_hex(self.comments),
131 }
132 .unwrap_or(ERROR_COLOR)
133 }
134
135 pub fn monocolor(
136 dark: bool,
137 bg: &'static str,
138 fg: &'static str,
139 cursor: &'static str,
140 selection: &'static str,
141 ) -> Self {
142 ColorTheme {
143 name: "monocolor",
144 dark,
145 bg,
146 cursor,
147 selection,
148 literals: fg,
149 numerics: fg,
150 keywords: fg,
151 functions: fg,
152 punctuation: fg,
153 types: fg,
154 strs: fg,
155 comments: fg,
156 special: fg,
157 }
158 }
159}