zeus_theme/
lib.rs

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   /// WIP
20   Light,
21
22   /// A custom theme
23   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   /// True if the theme is dark
44   pub dark_mode: bool,
45
46   /// True if a tint is recomended to be applied to images
47   /// to soften the contrast between the image and the background
48   /// 
49   /// This is usually true for themes with very dark background
50   pub image_tint_recommended: bool,
51   pub kind: ThemeKind,
52   pub style: Style,
53   pub colors: ThemeColors,
54   pub text_sizes: TextSizes,
55   /// Used for [window::window_frame]
56   pub window_frame: Frame,
57   /// Base container frame for major UI sections.
58   pub frame1: Frame,
59   /// Frame for nested elements, like individual list items.
60   pub frame2: Frame,
61
62   pub frame1_visuals: FrameVisuals,
63   pub frame2_visuals: FrameVisuals,
64}
65
66impl Theme {
67   /// Panics if the kind is [ThemeKind::Custom]
68   ///
69   /// Use [Theme::from_custom()] instead
70   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/// This is the color palette of the theme
107#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
108#[derive(Debug, Clone)]
109pub struct ThemeColors {
110   /// Main BG color of the theme
111   ///
112   /// This is usually the darkest color of the theme
113   pub bg: Color32,
114
115   /// BG2 color
116   ///
117   /// A secondary bg color that is applied on top of the `bg` color
118   /// 
119   /// Usually this is the color of choice for a popup window or a base frame/container
120   /// 
121   /// Its a should be a lighter shade/color of the `bg` color.
122   pub bg2: Color32,
123
124   /// BG3 color
125   ///
126   /// A third `bg` color that is applied on top of the `bg2` color
127   /// 
128   /// Usually this is the color of choice for a frame/container that is already inside a Ui that uses the `bg2` color
129   /// 
130   /// Its a should be a lighter shade/color of the `bg2` color.
131   pub bg3: Color32,
132
133   /// BG 4 color
134   ///
135   /// A fourth `bg` color that can be applied on top of the `bg3` color
136   /// 
137   /// Usually this is the color of choice for a frame/container that is already inside a Ui that uses the `bg3` color
138   /// 
139   /// Its a should be a lighter shade/color of the `bg3` color.
140   pub bg4: Color32,
141
142   /// Main text color
143   pub text: Color32,
144
145   /// Muted text color
146   /// 
147   /// For example a hint inside a text field
148   pub text_muted: Color32,
149
150   /// Highlight color
151   pub highlight: Color32,
152
153   /// Border color
154   pub border: Color32,
155
156   /// Primary action color
157   pub primary: Color32,
158
159   /// Secondary action color
160   pub secondary: Color32,
161
162   /// Error color
163   /// 
164   /// Can be used to indicate something bad or to highlight a dangerous action
165   pub error: Color32,
166
167   /// Warning color
168   pub warning: Color32,
169
170   /// Success color
171   /// 
172   /// Can be used to indicate something good or to highlight a successful action
173   pub success: Color32,
174
175   /// Info color
176   ///
177   /// Can be used for hyperlinks or to highlight something important
178   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}