feat: add configurables for accent_palette_dark and accent_palette_light

Closes #749
This commit is contained in:
Michael Aaron Murphy 2025-02-27 17:17:03 +01:00
parent fc3bc8f2f2
commit 324b8c1622
No known key found for this signature in database
GPG key ID: B2732D4240C9212C
2 changed files with 159 additions and 103 deletions

View file

@ -1,14 +1,19 @@
// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
use cosmic::cosmic_config::{self, ConfigGet, ConfigSet};
use cosmic::{
cosmic_config::{self, ConfigGet, ConfigSet},
cosmic_theme::palette::Srgba,
};
const NAME: &str = "com.system76.CosmicSettings";
const ACTIVE_PAGE: &str = "active-page";
const ACCENT_PALETTE_DARK: &str = "accent_palette_dark";
const ACCENT_PALETTE_LIGHT: &str = "accent_palette_light";
#[must_use]
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Config {
pub cosmic_config: Option<cosmic_config::Config>,
pub active_page: Box<str>,
@ -35,6 +40,20 @@ impl Config {
config
}
pub fn accent_palette_dark(&self) -> Result<Vec<Srgba>, cosmic_config::Error> {
self.cosmic_config
.as_ref()
.unwrap()
.get::<Vec<Srgba>>(ACCENT_PALETTE_DARK)
}
pub fn accent_palette_light(&self) -> Result<Vec<Srgba>, cosmic_config::Error> {
self.cosmic_config
.as_ref()
.unwrap()
.get::<Vec<Srgba>>(ACCENT_PALETTE_LIGHT)
}
pub fn set_active_page(&mut self, page: Box<str>) {
if let Some(context) = self.cosmic_config.as_ref() {
if let Err(why) = context.set::<Box<str>>(ACTIVE_PAGE, page.clone()) {

View file

@ -60,10 +60,12 @@ enum ContextView {
MonospaceFont,
SystemFont,
}
#[allow(clippy::struct_excessive_bools)]
pub struct Page {
entity: page::Entity,
on_enter_handle: Option<cosmic::iced::task::Handle>,
accent_palette: AccentPalette,
can_reset: bool,
no_custom_window_hint: bool,
context_view: Option<ContextView>,
@ -96,12 +98,21 @@ pub struct Page {
auto_switch_descs: [Cow<'static, str>; 4],
tk_config: Option<Config>,
settings_config: crate::config::Config,
day_time: bool,
}
#[derive(Default)]
pub struct AccentPalette {
dark: Option<Vec<Srgba>>,
light: Option<Vec<Srgba>>,
theme: Vec<Srgba>,
}
impl Default for Page {
fn default() -> Self {
let settings_config = crate::config::Config::new();
let theme_mode_config = ThemeMode::config().ok();
let theme_mode = theme_mode_config
.as_ref()
@ -116,26 +127,52 @@ impl Default for Page {
})
.unwrap_or_default();
(theme_mode_config, theme_mode).into()
let accent_palette = AccentPalette {
dark: settings_config.accent_palette_dark().ok(),
light: settings_config.accent_palette_light().ok(),
theme: Vec::new(),
};
let mut page: Page = (
settings_config,
theme_mode_config,
theme_mode,
accent_palette,
)
.into();
page.update_accent_palette();
page
}
}
impl
From<(
crate::config::Config,
Option<Config>,
ThemeMode,
Option<Config>,
ThemeBuilder,
Option<Config>,
AccentPalette,
)> for Page
{
fn from(
(theme_mode_config, theme_mode, theme_builder_config, theme_builder, tk_config): (
(
settings_config,
theme_mode_config,
theme_mode,
theme_builder_config,
theme_builder,
tk_config,
accent_palette,
): (
crate::config::Config,
Option<Config>,
ThemeMode,
Option<Config>,
ThemeBuilder,
Option<Config>,
AccentPalette,
),
) -> Self {
let theme = if theme_mode.is_dark {
@ -212,12 +249,14 @@ impl
icon_theme_active: None,
icon_themes: Vec::new(),
icon_handles: Vec::new(),
accent_palette,
theme,
theme_mode_config,
theme_builder_config,
theme_mode,
theme_builder,
tk_config,
settings_config,
day_time: true,
auto_switch_descs: [
fl!("auto-switch", "sunrise").into(),
@ -229,8 +268,22 @@ impl
}
}
impl From<(Option<Config>, ThemeMode)> for Page {
fn from((theme_mode_config, theme_mode): (Option<Config>, ThemeMode)) -> Self {
impl
From<(
crate::config::Config,
Option<Config>,
ThemeMode,
AccentPalette,
)> for Page
{
fn from(
(settings_config, theme_mode_config, theme_mode, accent_palette): (
crate::config::Config,
Option<Config>,
ThemeMode,
AccentPalette,
),
) -> Self {
let theme_builder_config = if theme_mode.is_dark {
ThemeBuilder::dark_config()
} else {
@ -259,11 +312,13 @@ impl From<(Option<Config>, ThemeMode)> for Page {
let tk_config = CosmicTk::config().ok();
Self::from((
settings_config,
theme_mode_config,
theme_mode,
theme_builder_config,
theme_builder,
tk_config,
accent_palette,
))
}
}
@ -1110,6 +1165,7 @@ impl Page {
// If the theme builder changed, write a new theme to disk on a background thread.
if needs_build {
self.update_accent_palette();
let theme_builder = self.theme_builder.clone();
let is_dark = self.theme_mode.is_dark;
let current_theme = self.theme.clone();
@ -1186,6 +1242,21 @@ impl Page {
cosmic::Task::batch(tasks)
}
fn update_accent_palette(&mut self) {
let palette = self.theme_builder.palette.as_ref();
self.accent_palette.theme = vec![
palette.accent_blue,
palette.accent_indigo,
palette.accent_purple,
palette.accent_pink,
palette.accent_red,
palette.accent_orange,
palette.accent_yellow,
palette.accent_green,
palette.accent_warm_grey,
];
}
fn reload_theme_mode(&mut self) {
let entity = self.entity;
let font_config = std::mem::take(&mut self.font_config);
@ -1194,7 +1265,15 @@ impl Page {
let icon_theme_active = self.icon_theme_active.take();
let day_time = self.day_time;
*self = Self::from((self.theme_mode_config.clone(), self.theme_mode));
*self = Self::from((
self.settings_config.clone(),
self.theme_mode_config.take(),
self.theme_mode,
std::mem::take(&mut self.accent_palette),
));
self.update_accent_palette();
self.entity = entity;
self.day_time = day_time;
self.icon_themes = icon_themes;
@ -1624,6 +1703,58 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
.theme_builder
.accent
.map_or(palette.accent_blue, Srgba::from);
let accent_palette_values = match (
page.theme_mode.is_dark,
page.accent_palette.dark.as_ref(),
page.accent_palette.light.as_ref(),
) {
(true, Some(dark_palette), _) => &dark_palette,
(false, _, Some(light_palette)) => &light_palette,
_ => &page.accent_palette.theme,
};
let mut accent_palette_row =
cosmic::widget::row::with_capacity(accent_palette_values.len());
for &color in accent_palette_values {
accent_palette_row = accent_palette_row.push(color_button(
Some(Message::PaletteAccent(color.into())),
color.into(),
cur_accent == color,
48,
48,
));
}
let accent_color_palette = cosmic::iced::widget::column![
text::body(&descriptions[accent_color]),
scrollable(
accent_palette_row
.push(if let Some(c) = page.custom_accent.get_applied_color() {
container(color_button(
Some(Message::CustomAccent(ColorPickerUpdate::ToggleColorPicker)),
c,
cosmic::iced::Color::from(cur_accent) == c,
48,
48,
))
} else {
container(
page.custom_accent
.picker_button(Message::CustomAccent, None)
.width(Length::Fixed(48.0))
.height(Length::Fixed(48.0)),
)
})
.padding([0, 0, 16, 0])
.spacing(16)
)
.direction(Direction::Horizontal(Scrollbar::new()))
]
.padding([16, 0, 0, 0])
.spacing(space_xxs);
let mut section = settings::section()
.title(&section.title)
.add(
@ -1682,101 +1813,7 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
)
.toggler(page.theme_mode.auto_switch, Message::Autoswitch),
)
.add(
cosmic::iced::widget::column![
text::body(&descriptions[accent_color]),
scrollable(
cosmic::iced::widget::row![
color_button(
Some(Message::PaletteAccent(palette.accent_blue.into())),
palette.accent_blue.into(),
cur_accent == palette.accent_blue,
48,
48
),
color_button(
Some(Message::PaletteAccent(palette.accent_indigo.into())),
palette.accent_indigo.into(),
cur_accent == palette.accent_indigo,
48,
48
),
color_button(
Some(Message::PaletteAccent(palette.accent_purple.into())),
palette.accent_purple.into(),
cur_accent == palette.accent_purple,
48,
48
),
color_button(
Some(Message::PaletteAccent(palette.accent_pink.into())),
palette.accent_pink.into(),
cur_accent == palette.accent_pink,
48,
48
),
color_button(
Some(Message::PaletteAccent(palette.accent_red.into())),
palette.accent_red.into(),
cur_accent == palette.accent_red,
48,
48
),
color_button(
Some(Message::PaletteAccent(palette.accent_orange.into())),
palette.accent_orange.into(),
cur_accent == palette.accent_orange,
48,
48
),
color_button(
Some(Message::PaletteAccent(palette.accent_yellow.into())),
palette.accent_yellow.into(),
cur_accent == palette.accent_yellow,
48,
48
),
color_button(
Some(Message::PaletteAccent(palette.accent_green.into())),
palette.accent_green.into(),
cur_accent == palette.accent_green,
48,
48
),
color_button(
Some(Message::PaletteAccent(palette.accent_warm_grey.into())),
palette.accent_warm_grey.into(),
cur_accent == palette.accent_warm_grey,
48,
48
),
if let Some(c) = page.custom_accent.get_applied_color() {
container(color_button(
Some(Message::CustomAccent(
ColorPickerUpdate::ToggleColorPicker,
)),
c,
cosmic::iced::Color::from(cur_accent) == c,
48,
48,
))
} else {
container(
page.custom_accent
.picker_button(Message::CustomAccent, None)
.width(Length::Fixed(48.0))
.height(Length::Fixed(48.0)),
)
},
]
.padding([0, 0, 16, 0])
.spacing(16)
)
.direction(Direction::Horizontal(Scrollbar::new()))
]
.padding([16, 0, 0, 0])
.spacing(space_xxs),
)
.add(accent_color_palette)
.add(
settings::item::builder(&descriptions[app_bg]).control(
page.application_background