feat: add support for dark / light mode switching and simultaneouscustom light / dark mode themes

This commit is contained in:
Ashley Wulber 2023-10-03 13:26:35 -04:00
parent a91deacff5
commit b1b32b867c
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
9 changed files with 186 additions and 21 deletions

View file

@ -1,11 +1,13 @@
pub use corner::*;
pub use cosmic_palette::*;
pub use derivation::*;
pub use mode::*;
pub use spacing::*;
pub use theme::*;
mod corner;
mod cosmic_palette;
mod derivation;
mod mode;
mod spacing;
mod theme;

View file

@ -0,0 +1,46 @@
use cosmic_config::{Config, ConfigGet, ConfigSet, CosmicConfigEntry};
/// ID for the ThemeMode config
pub const THEME_MODE_ID: &str = "com.system76.CosmicTheme.Mode";
/// The config for cosmic theme dark / light settings
#[derive(
Debug, Clone, Copy, PartialEq, Eq, cosmic_config::cosmic_config_derive::CosmicConfigEntry,
)]
pub struct ThemeMode {
/// The theme dark mode setting.
pub is_dark: bool,
/// The theme auto-switch dark and light mode setting.
pub auto_switch: bool,
}
impl Default for ThemeMode {
fn default() -> Self {
Self {
is_dark: true,
auto_switch: false,
}
}
}
impl ThemeMode {
/// Check if the theme is currently using dark mode
pub fn is_dark(config: &Config) -> Result<bool, cosmic_config::Error> {
config.get::<bool>("is_dark")
}
/// version of the theme
pub fn version() -> u64 {
1
}
/// Set auto-switch from light to dark mode
pub fn set_auto_switch(config: &Config, value: bool) -> Result<(), cosmic_config::Error> {
config.set("auto_switch", value)
}
/// Get the config for the theme mode
pub fn config() -> Result<Config, cosmic_config::Error> {
Config::new(THEME_MODE_ID, Self::version())
}
}

View file

@ -1,12 +1,24 @@
use crate::{
composite::over, steps::*, Component, Container, CornerRadii, CosmicPalette,
CosmicPaletteInner, Spacing, DARK_PALETTE, LIGHT_PALETTE, NAME,
CosmicPaletteInner, Spacing, ThemeMode, DARK_PALETTE, LIGHT_PALETTE, NAME,
};
use cosmic_config::{Config, ConfigGet, ConfigSet, CosmicConfigEntry};
use palette::{IntoColor, Srgb, Srgba};
use serde::{Deserialize, Serialize};
use std::num::NonZeroUsize;
/// ID for the current dark ThemeBuilder config
pub const DARK_THEME_BUILDER_ID: &str = "com.system76.CosmicTheme.Dark.Builder";
/// ID for the current dark Theme config
pub const DARK_THEME_ID: &str = "com.system76.CosmicTheme.Dark";
/// ID for the current light ThemeBuilder config
pub const LIGHT_THEME_BUILDER_ID: &str = "com.system76.CosmicTheme.Light.Builder";
/// ID for the current light Theme config
pub const LIGHT_THEME_ID: &str = "com.system76.CosmicTheme.Light";
#[derive(Clone, Copy, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
/// Theme layer type
pub enum Layer {
@ -66,7 +78,7 @@ pub struct Theme<C> {
pub is_high_contrast: bool,
}
impl CosmicConfigEntry for Theme<Srgba> {
impl cosmic_config::CosmicConfigEntry for Theme<Srgba> {
fn write_entry(&self, config: &Config) -> Result<(), cosmic_config::Error> {
let self_ = self.clone();
// TODO do as transaction
@ -176,6 +188,16 @@ impl<C> Theme<C> {
pub fn id() -> &'static str {
NAME
}
/// Get the config for the current dark theme
pub fn dark_config() -> Result<Config, cosmic_config::Error> {
Config::new(DARK_THEME_ID, Self::version())
}
/// Get the config for the current light theme
pub fn light_config() -> Result<Config, cosmic_config::Error> {
Config::new(LIGHT_THEME_ID, Self::version())
}
}
impl Theme<Srgba> {
@ -410,6 +432,20 @@ impl Theme<Srgba> {
pub fn radius_xl(&self) -> [f32; 4] {
self.corner_radii.radius_xl
}
/// get the active theme
pub fn get_active() -> Result<Self, (Vec<cosmic_config::Error>, Self)> {
let config =
Config::new(Self::id(), Self::version()).map_err(|e| (vec![e], Self::default()))?;
let is_dark = ThemeMode::is_dark(&config).map_err(|e| (vec![e], Self::default()))?;
let config = if is_dark {
Self::dark_config()
} else {
Self::light_config()
}
.map_err(|e| (vec![e], Self::default()))?;
Self::get_entry(&config)
}
}
impl<C> From<CosmicPalette<C>> for Theme<Srgba>
@ -422,7 +458,7 @@ where
}
/// Helper for building customized themes
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, cosmic_config::cosmic_config_derive::CosmicConfigEntry)]
pub struct ThemeBuilder {
palette: CosmicPalette<Srgba>,
spacing: Spacing,
@ -890,4 +926,19 @@ impl ThemeBuilder {
theme.corner_radii = corner_radii;
theme
}
/// Get the builder for the dark config
pub fn dark_config() -> Result<Config, cosmic_config::Error> {
Config::new(DARK_THEME_BUILDER_ID, Self::version())
}
/// Get the builder for the light config
pub fn light_config() -> Result<Config, cosmic_config::Error> {
Config::new(LIGHT_THEME_BUILDER_ID, Self::version())
}
/// version of the theme builder
pub fn version() -> u64 {
1
}
}