use super::presets::ThemePreset;
use std::sync::atomic::{AtomicU64, Ordering};
static THEME_VERSION: AtomicU64 = AtomicU64::new(0);
#[cfg(target_arch = "wasm32")]
const STORAGE_KEY: &str = "egui_charts_theme";
#[derive(Debug)]
pub struct ThemeManager {
current: ThemePreset,
version: u64,
auto_persist: bool,
}
impl Default for ThemeManager {
fn default() -> Self {
Self::new()
}
}
impl ThemeManager {
pub fn new() -> Self {
let initial = Self::load_persisted().unwrap_or(ThemePreset::Classic);
Self {
current: initial,
version: THEME_VERSION.fetch_add(1, Ordering::SeqCst),
auto_persist: true,
}
}
pub fn with_theme(preset: ThemePreset) -> Self {
Self {
current: preset,
version: THEME_VERSION.fetch_add(1, Ordering::SeqCst),
auto_persist: true,
}
}
#[inline]
pub fn current(&self) -> ThemePreset {
self.current
}
#[inline]
pub fn theme(&self) -> super::Theme {
self.current.to_theme()
}
#[inline]
pub fn version(&self) -> u64 {
self.version
}
#[inline]
pub fn has_changed_since(&self, version: u64) -> bool {
self.version != version
}
pub fn set_theme(&mut self, preset: ThemePreset) {
if self.current != preset {
self.current = preset;
self.version = THEME_VERSION.fetch_add(1, Ordering::SeqCst);
if self.auto_persist {
self.persist();
}
}
}
pub fn next_theme(&mut self) {
let presets = ThemePreset::all();
let curr_idx = presets.iter().position(|p| *p == self.current).unwrap_or(0);
let next_idx = (curr_idx + 1) % presets.len();
self.set_theme(presets[next_idx]);
}
pub fn set_auto_persist(&mut self, enabled: bool) {
self.auto_persist = enabled;
}
pub fn persist(&self) {
Self::save_persisted(self.current);
}
fn load_persisted() -> Option<ThemePreset> {
#[cfg(target_arch = "wasm32")]
{
Self::load_from_local_storage()
}
#[cfg(not(target_arch = "wasm32"))]
{
None
}
}
fn save_persisted(preset: ThemePreset) {
#[cfg(target_arch = "wasm32")]
{
Self::save_to_local_storage(preset);
}
#[cfg(not(target_arch = "wasm32"))]
{
let _ = preset;
}
}
#[cfg(target_arch = "wasm32")]
fn load_from_local_storage() -> Option<ThemePreset> {
let window = web_sys::window()?;
let storage = window.local_storage().ok()??;
let value = storage.get_item(STORAGE_KEY).ok()??;
ThemePreset::from_name(&value)
}
#[cfg(target_arch = "wasm32")]
fn save_to_local_storage(preset: ThemePreset) {
if let Some(window) = web_sys::window() {
if let Ok(Some(storage)) = window.local_storage() {
let _ = storage.set_item(STORAGE_KEY, preset.name());
}
}
}
}