1use egui::{Color32, Frame, style::Style};
2
3const PANIC_MSG: &str = "Custom theme not supported, use Theme::from_custom() instead";
4
5pub mod editor;
6pub mod hsla;
7pub mod themes;
8pub mod utils;
9pub mod window;
10
11pub use editor::ThemeEditor;
12use themes::*;
13
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15#[derive(Debug, Clone, PartialEq)]
16pub enum ThemeKind {
17 Dark,
18
19 Light,
21
22 Custom,
24}
25
26impl ThemeKind {
27 pub fn to_str(&self) -> &str {
28 match self {
29 ThemeKind::Dark => "Dark",
30 ThemeKind::Light => "Light",
31 ThemeKind::Custom => "Custom",
32 }
33 }
34
35 pub fn to_vec() -> Vec<Self> {
36 vec![Self::Dark, Self::Light]
37 }
38}
39
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41#[derive(Debug, Clone)]
42pub struct Theme {
43 pub dark_mode: bool,
45
46 pub image_tint_recommended: bool,
51 pub kind: ThemeKind,
52 pub style: Style,
53 pub colors: ThemeColors,
54 pub text_sizes: TextSizes,
55 pub window_frame: Frame,
57 pub frame1: Frame,
59 pub frame2: Frame,
61
62 pub frame1_visuals: FrameVisuals,
63 pub frame2_visuals: FrameVisuals,
64}
65
66impl Theme {
67 pub fn new(kind: ThemeKind) -> Self {
71 let theme = match kind {
72 ThemeKind::Dark => dark::theme(),
73 ThemeKind::Light => light::theme(),
74 ThemeKind::Custom => panic!("{}", PANIC_MSG),
75 };
76
77 theme
78 }
79
80 pub fn set_window_frame_colors(&mut self) {
81 match self.kind {
82 ThemeKind::Dark => self.window_frame = dark::window_frame(&self.colors),
83 ThemeKind::Light => self.window_frame = light::window_frame(&self.colors),
84 ThemeKind::Custom => panic!("{}", PANIC_MSG),
85 }
86 }
87
88 pub fn set_frame1_colors(&mut self) {
89 match self.kind {
90 ThemeKind::Dark => self.frame1 = dark::frame1(&self.colors),
91 ThemeKind::Light => self.frame1 = light::frame1(&self.colors),
92 ThemeKind::Custom => panic!("{}", PANIC_MSG),
93 }
94 }
95
96 pub fn set_frame2_colors(&mut self) {
97 match self.kind {
98 ThemeKind::Dark => self.frame2 = dark::frame2(&self.colors),
99 ThemeKind::Light => self.frame2 = light::frame2(&self.colors),
100 ThemeKind::Custom => panic!("{}", PANIC_MSG),
101 }
102 }
103}
104
105
106#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
108#[derive(Debug, Clone)]
109pub struct ThemeColors {
110 pub bg: Color32,
114
115 pub bg2: Color32,
123
124 pub bg3: Color32,
132
133 pub bg4: Color32,
141
142 pub text: Color32,
144
145 pub text_muted: Color32,
149
150 pub highlight: Color32,
152
153 pub border: Color32,
155
156 pub primary: Color32,
158
159 pub secondary: Color32,
161
162 pub error: Color32,
166
167 pub warning: Color32,
169
170 pub success: Color32,
174
175 pub info: Color32,
179}
180
181#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
182#[derive(Clone, Default, Debug)]
183pub struct TextSizes {
184 pub very_small: f32,
185 pub small: f32,
186 pub normal: f32,
187 pub large: f32,
188 pub very_large: f32,
189 pub heading: f32,
190}
191
192impl TextSizes {
193 pub fn new(
194 very_small: f32,
195 small: f32,
196 normal: f32,
197 large: f32,
198 very_large: f32,
199 heading: f32,
200 ) -> Self {
201 Self {
202 very_small,
203 small,
204 normal,
205 large,
206 very_large,
207 heading,
208 }
209 }
210}
211
212#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
213#[derive(Clone, Copy, Debug)]
214pub struct FrameVisuals {
215 pub bg_on_hover: Color32,
216 pub bg_on_click: Color32,
217 pub border_on_hover: (f32, Color32),
218 pub border_on_click: (f32, Color32),
219}