use crate::Button;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum Theme {
Dark,
Light,
}
impl Theme {
pub fn default_visuals(self) -> crate::Visuals {
match self {
Self::Dark => crate::Visuals::dark(),
Self::Light => crate::Visuals::light(),
}
}
pub fn default_style(self) -> crate::Style {
crate::Style {
visuals: self.default_visuals(),
..Default::default()
}
}
pub fn from_dark_mode(dark_mode: bool) -> Self {
if dark_mode { Self::Dark } else { Self::Light }
}
}
impl Theme {
#[must_use]
pub(crate) fn small_toggle_button(self, ui: &mut crate::Ui) -> Option<Self> {
#![expect(clippy::collapsible_else_if)]
if self == Self::Dark {
if ui
.add(Button::new("☀️").frame(false))
.on_hover_text("Switch to light mode")
.clicked()
{
return Some(Self::Light);
}
} else {
if ui
.add(Button::new("🌙").frame(false))
.on_hover_text("Switch to dark mode")
.clicked()
{
return Some(Self::Dark);
}
}
None
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ThemePreference {
Dark,
Light,
#[default]
System,
}
impl From<Theme> for ThemePreference {
fn from(value: Theme) -> Self {
match value {
Theme::Dark => Self::Dark,
Theme::Light => Self::Light,
}
}
}
impl ThemePreference {
pub fn icon(self) -> &'static str {
match self {
Self::Dark => "🌙",
Self::Light => "☀️",
Self::System => "💻",
}
}
pub fn name(self) -> &'static str {
match self {
Self::Dark => "dark",
Self::Light => "light",
Self::System => "system",
}
}
pub fn buttons(&mut self, ui: &mut crate::Ui) {
ui.horizontal(|ui| {
ui.spacing_mut().item_spacing.x = 2.0;
ui.selectable_value(self, Self::System, Self::System.icon())
.on_hover_ui(system_hover_ui);
ui.selectable_value(self, Self::Dark, Self::Dark.icon())
.on_hover_text("Use the dark mode theme");
ui.selectable_value(self, Self::Light, Self::Light.icon())
.on_hover_text("Use the light mode theme");
});
}
#[deprecated = "Renamed to `buttons`"]
pub fn radio_buttons(&mut self, ui: &mut crate::Ui) {
self.buttons(ui);
}
}
fn system_hover_ui(ui: &mut crate::Ui) {
ui.label("Follow the system theme preference.");
ui.add_space(4.0);
if let Some(system_theme) = ui.input(|i| i.raw.system_theme) {
ui.label(format!(
"The current system theme is: {}",
match system_theme {
Theme::Dark => "dark",
Theme::Light => "light",
}
));
} else {
ui.label("The system theme is unknown.");
}
}