Skip to main content

zeus_theme/
utils.rs

1use super::{FrameVisuals, Theme, ThemeKind};
2use egui::{Color32, ComboBox, Frame, Response, Sense, Stroke, Ui};
3
4// Tint/Overlay colors, useful for example if you want to slightly darken an image on the fly
5
6/// Should work for most images that are shown on a very dark background
7pub const TINT_1: Color32 = Color32::from_rgba_premultiplied(216, 216, 216, 255);
8
9/// Show a ComboBox to change the theme
10///
11/// Returns the new theme if we select one, the new theme is also applied to the [egui::Context]
12pub fn change_theme(current_theme: &Theme, ui: &mut Ui) -> Option<Theme> {
13   let mut new_theme_opt = None;
14   ComboBox::from_label("Theme")
15      .selected_text(current_theme.kind.to_str())
16      .show_ui(ui, |ui| {
17         for kind in ThemeKind::to_vec() {
18            if ui.selectable_label(current_theme.kind == kind, kind.to_str()).clicked() {
19               let new_theme = Theme::new(kind);
20               ui.ctx().set_global_style(new_theme.style.clone());
21               new_theme_opt = Some(new_theme);
22            }
23         }
24      });
25   new_theme_opt
26}
27
28/// Apply live theme style to this ui.
29///
30/// Does not rebuild frames — that used to wipe Theme Editor edits every frame.
31/// Palette → still-bound frame colors is [`Theme::remap_derived_frames`].
32pub fn apply_theme_changes(theme: &mut Theme, ui: &mut Ui) {
33   ui.style_mut().visuals = theme.style.visuals.clone();
34}
35
36// Helper functions to override the visuals
37
38/// Removes the border from widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
39///
40/// When the widget is inactive (no hover, clicks etc..)
41pub fn no_border_on_idle(ui: &mut Ui) {
42   ui.visuals_mut().widgets.inactive.bg_stroke = Stroke::NONE;
43}
44
45/// Removes the border from widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
46///
47/// When the widget is active (click)
48pub fn no_border_on_click(ui: &mut Ui) {
49   ui.visuals_mut().widgets.active.bg_stroke = Stroke::NONE;
50}
51
52/// Removes the border from widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
53///
54/// When the widget is hovered
55pub fn no_border_on_hover(ui: &mut Ui) {
56   ui.visuals_mut().widgets.hovered.bg_stroke = Stroke::NONE;
57}
58
59/// Removes the border from widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
60///
61/// At any state
62pub fn no_border(ui: &mut Ui) {
63   ui.visuals_mut().widgets.inactive.bg_stroke = Stroke::NONE;
64   ui.visuals_mut().widgets.active.bg_stroke = Stroke::NONE;
65   ui.visuals_mut().widgets.hovered.bg_stroke = Stroke::NONE;
66}
67
68/// Give a border to widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
69///
70/// When the widget is inactive (no hover, clicks etc..)
71pub fn border_on_idle(ui: &mut Ui, width: f32, color: Color32) {
72   ui.visuals_mut().widgets.inactive.bg_stroke = Stroke::new(width, color);
73}
74
75/// Give a border to widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
76///
77/// When the widget is active (click)
78pub fn border_on_click(ui: &mut Ui, width: f32, color: Color32) {
79   ui.visuals_mut().widgets.active.bg_stroke = Stroke::new(width, color);
80}
81
82/// Give a border to widgets like ComboxBox
83///
84/// When the widget is open
85pub fn border_on_open(ui: &mut Ui, width: f32, color: Color32) {
86   ui.visuals_mut().widgets.open.bg_stroke = Stroke::new(width, color);
87}
88
89/// Give a border to widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
90///
91/// When the widget is hovered
92pub fn border_on_hover(ui: &mut Ui, width: f32, color: Color32) {
93   ui.visuals_mut().widgets.hovered.bg_stroke = Stroke::new(width, color);
94}
95
96/// Give a background color to widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
97///
98/// When the widget is inactive (no hover, clicks etc..)
99pub fn bg_color_on_idle(ui: &mut Ui, color: Color32) {
100   ui.visuals_mut().widgets.inactive.weak_bg_fill = color;
101}
102
103/// Give a background color to widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
104///
105/// When the widget is hovered
106pub fn bg_color_on_hover(ui: &mut Ui, color: Color32) {
107   ui.visuals_mut().widgets.hovered.weak_bg_fill = color;
108}
109
110/// Give a background color to widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
111///
112/// When the widget is active (click)
113pub fn bg_color_on_click(ui: &mut Ui, color: Color32) {
114   ui.visuals_mut().widgets.active.weak_bg_fill = color;
115}
116
117/// Give a background color to widgets like Button, ComboxBox, TextEdit, Slider, RadioButton
118pub fn bg_color_on_open(ui: &mut Ui, color: Color32) {
119   ui.visuals_mut().widgets.open.weak_bg_fill = color;
120}
121
122/// Window Fill Color
123///
124/// It also affects the bg color of an opened ComboBox
125pub fn window_fill(ui: &mut Ui, color: Color32) {
126   ui.visuals_mut().window_fill = color;
127}
128
129/// Window Border
130///
131/// It also affects the border of an opened ComboBox
132pub fn window_border(ui: &mut Ui, width: f32, color: Color32) {
133   ui.visuals_mut().window_stroke = Stroke::new(width, color);
134}
135
136/// Put this ui on top of this frame
137pub fn frame_it(
138   frame: &mut Frame,
139   visuals: Option<FrameVisuals>,
140   ui: &mut Ui,
141   add_contents: impl FnOnce(&mut Ui),
142) -> Response {
143   let mut frame = frame.begin(ui);
144   let res = frame.content_ui.scope(|ui| add_contents(ui));
145
146   if let Some(visuals) = visuals {
147      if res.response.interact(Sense::click()).clicked() {
148         frame.frame = frame.frame.fill(visuals.bg_on_click);
149         frame.frame = frame.frame.stroke(Stroke::new(
150            visuals.border_on_click.0,
151            visuals.border_on_click.1,
152         ));
153      } else if res.response.hovered() {
154         frame.frame = frame.frame.fill(visuals.bg_on_hover);
155         frame.frame = frame.frame.stroke(Stroke::new(
156            visuals.border_on_hover.0,
157            visuals.border_on_hover.1,
158         ));
159      }
160   }
161   frame.end(ui);
162   res.response
163}