Skip to content

Commit

Permalink
Update visuals from system theme
Browse files Browse the repository at this point in the history
  • Loading branch information
bash committed Jul 21, 2024
1 parent cd7ad15 commit a815319
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
46 changes: 45 additions & 1 deletion crates/egui/src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,21 @@ pub struct Options {
#[cfg_attr(feature = "serde", serde(skip))]
pub(crate) style: std::sync::Arc<Style>,

/// Whether to use a dark style, light style or follow
/// the OS' setting.
///
/// Note: Currently only [`ThemePreference::System`] has an effect.
pub theme_preference: ThemePreference,

/// Which theme to use in case [`Self::theme_preference`] is set to [`ThemePreference::System`]
/// and egui fails to detect the system theme.
///
/// Default: [`egui::Theme::Dark`].
pub fallback_theme: Theme,

#[cfg_attr(feature = "serde", serde(skip))]
system_theme: Option<Theme>,

/// Global zoom factor of the UI.
///
/// This is used to calculate the `pixels_per_point`
Expand Down Expand Up @@ -265,6 +280,9 @@ impl Default for Options {

Self {
style: Default::default(),
theme_preference: ThemePreference::System,
fallback_theme: Theme::Dark,
system_theme: None,
zoom_factor: 1.0,
zoom_with_keyboard: true,
tessellation_options: Default::default(),
Expand All @@ -281,11 +299,35 @@ impl Default for Options {
}
}

impl Options {
pub(crate) fn begin_frame(&mut self, new_raw_input: &RawInput) {
if self.theme_preference == ThemePreference::System {
let theme_from_visuals = Theme::from_dark_mode(self.style.visuals.dark_mode);
let current_system_theme = self.system_theme.unwrap_or(theme_from_visuals);
let new_system_theme = new_raw_input.system_theme.unwrap_or(self.fallback_theme);

// Only update the visuals if the system theme has changed.
// This allows users to change the visuals without them
// getting reset on the next frame.
if current_system_theme != new_system_theme || self.system_theme.is_none() {
self.system_theme = Some(new_system_theme);
if theme_from_visuals != new_system_theme {
let visuals = new_system_theme.default_visuals();
std::sync::Arc::make_mut(&mut self.style).visuals = visuals;
}
}
}
}
}

impl Options {
/// Show the options in the ui.
pub fn ui(&mut self, ui: &mut crate::Ui) {
let Self {
style, // covered above
style, // covered above
theme_preference: _,
fallback_theme: _,
system_theme: _,
zoom_factor: _, // TODO(emilk)
zoom_with_keyboard,
tessellation_options,
Expand Down Expand Up @@ -668,6 +710,8 @@ impl Memory {

// self.interactions is handled elsewhere

self.options.begin_frame(new_raw_input);

self.focus
.entry(self.viewport_id)
.or_default()
Expand Down
10 changes: 10 additions & 0 deletions crates/egui/src/memory/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,26 @@ impl Theme {
Self::Light => crate::Visuals::light(),
}
}

pub(crate) fn from_dark_mode(dark_mode: bool) -> Theme {
if dark_mode {
Theme::Dark
} else {
Theme::Light
}
}
}

/// The user's theme preference.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ThemePreference {
/// Dark mode: light text on a dark background.
#[doc(hidden)]
Dark,

/// Light mode: dark text on a light background.
#[doc(hidden)]
Light,

/// Follow the system's theme preference.
Expand Down

0 comments on commit a815319

Please sign in to comment.