egui/memory/
theme.rs

1use crate::Button;
2
3/// Dark or Light theme.
4#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
5#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
6pub enum Theme {
7    /// Dark mode: light text on a dark background.
8    Dark,
9
10    /// Light mode: dark text on a light background.
11    Light,
12}
13
14impl Theme {
15    /// Default visuals for this theme.
16    pub fn default_visuals(self) -> crate::Visuals {
17        match self {
18            Self::Dark => crate::Visuals::dark(),
19            Self::Light => crate::Visuals::light(),
20        }
21    }
22
23    /// Default style for this theme.
24    pub fn default_style(self) -> crate::Style {
25        crate::Style {
26            visuals: self.default_visuals(),
27            ..Default::default()
28        }
29    }
30
31    /// Chooses between [`Self::Dark`] or [`Self::Light`] based on a boolean value.
32    pub fn from_dark_mode(dark_mode: bool) -> Self {
33        if dark_mode {
34            Self::Dark
35        } else {
36            Self::Light
37        }
38    }
39}
40
41impl Theme {
42    /// Show small toggle-button for light and dark mode.
43    /// This is not the best design as it doesn't allow switching back to "follow system".
44    #[must_use]
45    pub(crate) fn small_toggle_button(self, ui: &mut crate::Ui) -> Option<Self> {
46        #![allow(clippy::collapsible_else_if)]
47        if self == Self::Dark {
48            if ui
49                .add(Button::new("☀").frame(false))
50                .on_hover_text("Switch to light mode")
51                .clicked()
52            {
53                return Some(Self::Light);
54            }
55        } else {
56            if ui
57                .add(Button::new("🌙").frame(false))
58                .on_hover_text("Switch to dark mode")
59                .clicked()
60            {
61                return Some(Self::Dark);
62            }
63        }
64        None
65    }
66}
67
68/// The user's theme preference.
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
70#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
71pub enum ThemePreference {
72    /// Dark mode: light text on a dark background.
73    Dark,
74
75    /// Light mode: dark text on a light background.
76    Light,
77
78    /// Follow the system's theme preference.
79    System,
80}
81
82impl From<Theme> for ThemePreference {
83    fn from(value: Theme) -> Self {
84        match value {
85            Theme::Dark => Self::Dark,
86            Theme::Light => Self::Light,
87        }
88    }
89}
90
91impl ThemePreference {
92    /// Show radio-buttons to switch between light mode, dark mode and following the system theme.
93    pub fn radio_buttons(&mut self, ui: &mut crate::Ui) {
94        ui.horizontal(|ui| {
95            ui.selectable_value(self, Self::Light, "☀ Light");
96            ui.selectable_value(self, Self::Dark, "🌙 Dark");
97            ui.selectable_value(self, Self::System, "💻 System");
98        });
99    }
100}