1use eframe::egui;
12
13include!(concat!(env!("OUT_DIR"), "/ssbz_tokens.rs"));
14
15#[must_use]
17pub fn palette(ctx: &egui::Context) -> &'static Sheet {
18 match ctx.theme() {
19 egui::Theme::Dark => &DARK,
20 _ => &LIGHT,
21 }
22}
23
24#[must_use]
27pub fn hover_fill(p: &Sheet) -> egui::Color32 {
28 let mix = |a: u8, b: u8| u8::try_from((u32::from(a) + u32::from(b)) / 2).unwrap_or(255);
29 egui::Color32::from_rgb(
30 mix(p.card.r(), p.line.r()),
31 mix(p.card.g(), p.line.g()),
32 mix(p.card.b(), p.line.b()),
33 )
34}
35
36fn corner_radius() -> egui::CornerRadius {
37 egui::CornerRadius::same(4)
38}
39
40fn apply(p: &Sheet, style: &mut egui::Style) {
41 let hover = hover_fill(p);
42 let v = &mut style.visuals;
43
44 v.panel_fill = p.bg;
45 v.window_fill = p.card;
46 v.extreme_bg_color = p.code;
47 v.faint_bg_color = p.zebra;
48 v.hyperlink_color = p.chip_ink;
49 v.error_fg_color = p.err;
50 v.warn_fg_color = p.err;
51 v.window_stroke = egui::Stroke::new(1.0, p.line);
52 v.selection.bg_fill = p.accent;
53 v.selection.stroke = egui::Stroke::new(1.0, p.accent_ink);
54
55 v.widgets.noninteractive.bg_fill = p.bg;
56 v.widgets.noninteractive.weak_bg_fill = p.bg;
57 v.widgets.noninteractive.fg_stroke = egui::Stroke::new(1.0, p.muted);
58 v.widgets.noninteractive.bg_stroke = egui::Stroke::new(1.0, p.line);
59
60 v.widgets.inactive.bg_fill = p.card;
61 v.widgets.inactive.weak_bg_fill = p.card;
62 v.widgets.inactive.fg_stroke = egui::Stroke::new(1.0, p.text);
63 v.widgets.inactive.bg_stroke = egui::Stroke::new(1.0, p.line);
64
65 v.widgets.hovered.bg_fill = hover;
66 v.widgets.hovered.weak_bg_fill = hover;
67 v.widgets.hovered.fg_stroke = egui::Stroke::new(1.0, p.text);
68 v.widgets.hovered.bg_stroke = egui::Stroke::new(1.0, p.line);
69
70 v.widgets.active.bg_fill = p.accent;
71 v.widgets.active.weak_bg_fill = p.accent;
72 v.widgets.active.fg_stroke = egui::Stroke::new(1.0, p.accent_ink);
73 v.widgets.active.bg_stroke = egui::Stroke::new(1.0, p.accent);
74
75 for widget in [
76 &mut v.widgets.noninteractive,
77 &mut v.widgets.inactive,
78 &mut v.widgets.hovered,
79 &mut v.widgets.active,
80 ] {
81 widget.corner_radius = corner_radius();
82 }
83 v.window_corner_radius = corner_radius();
84 v.menu_corner_radius = corner_radius();
85
86 let text_styles = &mut style.text_styles;
89 text_styles.insert(egui::TextStyle::Body, egui::FontId::proportional(14.0));
90 text_styles.insert(egui::TextStyle::Button, egui::FontId::proportional(14.0));
91 text_styles.insert(egui::TextStyle::Heading, egui::FontId::proportional(15.0));
92 text_styles.insert(egui::TextStyle::Small, egui::FontId::proportional(11.0));
93 text_styles.insert(egui::TextStyle::Monospace, egui::FontId::monospace(13.0));
94}
95
96pub fn install(ctx: &egui::Context) {
100 for theme in [egui::Theme::Dark, egui::Theme::Light] {
101 let sheet = match theme {
102 egui::Theme::Dark => &DARK,
103 _ => &LIGHT,
104 };
105 let mut style = (*ctx.style_of(theme)).clone();
106 apply(sheet, &mut style);
107 ctx.set_style_of(theme, style);
108 }
109}