feat: add configurables for accent_palette_dark and accent_palette_light
Closes #749
This commit is contained in:
parent
fc3bc8f2f2
commit
324b8c1622
2 changed files with 159 additions and 103 deletions
|
|
@ -1,14 +1,19 @@
|
||||||
// Copyright 2023 System76 <info@system76.com>
|
// Copyright 2023 System76 <info@system76.com>
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// 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 NAME: &str = "com.system76.CosmicSettings";
|
||||||
|
|
||||||
const ACTIVE_PAGE: &str = "active-page";
|
const ACTIVE_PAGE: &str = "active-page";
|
||||||
|
const ACCENT_PALETTE_DARK: &str = "accent_palette_dark";
|
||||||
|
const ACCENT_PALETTE_LIGHT: &str = "accent_palette_light";
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub cosmic_config: Option<cosmic_config::Config>,
|
pub cosmic_config: Option<cosmic_config::Config>,
|
||||||
pub active_page: Box<str>,
|
pub active_page: Box<str>,
|
||||||
|
|
@ -35,6 +40,20 @@ impl Config {
|
||||||
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>) {
|
pub fn set_active_page(&mut self, page: Box<str>) {
|
||||||
if let Some(context) = self.cosmic_config.as_ref() {
|
if let Some(context) = self.cosmic_config.as_ref() {
|
||||||
if let Err(why) = context.set::<Box<str>>(ACTIVE_PAGE, page.clone()) {
|
if let Err(why) = context.set::<Box<str>>(ACTIVE_PAGE, page.clone()) {
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,12 @@ enum ContextView {
|
||||||
MonospaceFont,
|
MonospaceFont,
|
||||||
SystemFont,
|
SystemFont,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::struct_excessive_bools)]
|
#[allow(clippy::struct_excessive_bools)]
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
entity: page::Entity,
|
entity: page::Entity,
|
||||||
on_enter_handle: Option<cosmic::iced::task::Handle>,
|
on_enter_handle: Option<cosmic::iced::task::Handle>,
|
||||||
|
accent_palette: AccentPalette,
|
||||||
can_reset: bool,
|
can_reset: bool,
|
||||||
no_custom_window_hint: bool,
|
no_custom_window_hint: bool,
|
||||||
context_view: Option<ContextView>,
|
context_view: Option<ContextView>,
|
||||||
|
|
@ -96,12 +98,21 @@ pub struct Page {
|
||||||
auto_switch_descs: [Cow<'static, str>; 4],
|
auto_switch_descs: [Cow<'static, str>; 4],
|
||||||
|
|
||||||
tk_config: Option<Config>,
|
tk_config: Option<Config>,
|
||||||
|
settings_config: crate::config::Config,
|
||||||
day_time: bool,
|
day_time: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct AccentPalette {
|
||||||
|
dark: Option<Vec<Srgba>>,
|
||||||
|
light: Option<Vec<Srgba>>,
|
||||||
|
theme: Vec<Srgba>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Page {
|
impl Default for Page {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
let settings_config = crate::config::Config::new();
|
||||||
|
|
||||||
let theme_mode_config = ThemeMode::config().ok();
|
let theme_mode_config = ThemeMode::config().ok();
|
||||||
let theme_mode = theme_mode_config
|
let theme_mode = theme_mode_config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -116,26 +127,52 @@ impl Default for Page {
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.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
|
impl
|
||||||
From<(
|
From<(
|
||||||
|
crate::config::Config,
|
||||||
Option<Config>,
|
Option<Config>,
|
||||||
ThemeMode,
|
ThemeMode,
|
||||||
Option<Config>,
|
Option<Config>,
|
||||||
ThemeBuilder,
|
ThemeBuilder,
|
||||||
Option<Config>,
|
Option<Config>,
|
||||||
|
AccentPalette,
|
||||||
)> for Page
|
)> for Page
|
||||||
{
|
{
|
||||||
fn from(
|
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>,
|
Option<Config>,
|
||||||
ThemeMode,
|
ThemeMode,
|
||||||
Option<Config>,
|
Option<Config>,
|
||||||
ThemeBuilder,
|
ThemeBuilder,
|
||||||
Option<Config>,
|
Option<Config>,
|
||||||
|
AccentPalette,
|
||||||
),
|
),
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let theme = if theme_mode.is_dark {
|
let theme = if theme_mode.is_dark {
|
||||||
|
|
@ -212,12 +249,14 @@ impl
|
||||||
icon_theme_active: None,
|
icon_theme_active: None,
|
||||||
icon_themes: Vec::new(),
|
icon_themes: Vec::new(),
|
||||||
icon_handles: Vec::new(),
|
icon_handles: Vec::new(),
|
||||||
|
accent_palette,
|
||||||
theme,
|
theme,
|
||||||
theme_mode_config,
|
theme_mode_config,
|
||||||
theme_builder_config,
|
theme_builder_config,
|
||||||
theme_mode,
|
theme_mode,
|
||||||
theme_builder,
|
theme_builder,
|
||||||
tk_config,
|
tk_config,
|
||||||
|
settings_config,
|
||||||
day_time: true,
|
day_time: true,
|
||||||
auto_switch_descs: [
|
auto_switch_descs: [
|
||||||
fl!("auto-switch", "sunrise").into(),
|
fl!("auto-switch", "sunrise").into(),
|
||||||
|
|
@ -229,8 +268,22 @@ impl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(Option<Config>, ThemeMode)> for Page {
|
impl
|
||||||
fn from((theme_mode_config, theme_mode): (Option<Config>, ThemeMode)) -> Self {
|
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 {
|
let theme_builder_config = if theme_mode.is_dark {
|
||||||
ThemeBuilder::dark_config()
|
ThemeBuilder::dark_config()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -259,11 +312,13 @@ impl From<(Option<Config>, ThemeMode)> for Page {
|
||||||
let tk_config = CosmicTk::config().ok();
|
let tk_config = CosmicTk::config().ok();
|
||||||
|
|
||||||
Self::from((
|
Self::from((
|
||||||
|
settings_config,
|
||||||
theme_mode_config,
|
theme_mode_config,
|
||||||
theme_mode,
|
theme_mode,
|
||||||
theme_builder_config,
|
theme_builder_config,
|
||||||
theme_builder,
|
theme_builder,
|
||||||
tk_config,
|
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 the theme builder changed, write a new theme to disk on a background thread.
|
||||||
if needs_build {
|
if needs_build {
|
||||||
|
self.update_accent_palette();
|
||||||
let theme_builder = self.theme_builder.clone();
|
let theme_builder = self.theme_builder.clone();
|
||||||
let is_dark = self.theme_mode.is_dark;
|
let is_dark = self.theme_mode.is_dark;
|
||||||
let current_theme = self.theme.clone();
|
let current_theme = self.theme.clone();
|
||||||
|
|
@ -1186,6 +1242,21 @@ impl Page {
|
||||||
cosmic::Task::batch(tasks)
|
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) {
|
fn reload_theme_mode(&mut self) {
|
||||||
let entity = self.entity;
|
let entity = self.entity;
|
||||||
let font_config = std::mem::take(&mut self.font_config);
|
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 icon_theme_active = self.icon_theme_active.take();
|
||||||
let day_time = self.day_time;
|
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.entity = entity;
|
||||||
self.day_time = day_time;
|
self.day_time = day_time;
|
||||||
self.icon_themes = icon_themes;
|
self.icon_themes = icon_themes;
|
||||||
|
|
@ -1624,6 +1703,58 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
||||||
.theme_builder
|
.theme_builder
|
||||||
.accent
|
.accent
|
||||||
.map_or(palette.accent_blue, Srgba::from);
|
.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()
|
let mut section = settings::section()
|
||||||
.title(§ion.title)
|
.title(§ion.title)
|
||||||
.add(
|
.add(
|
||||||
|
|
@ -1682,101 +1813,7 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
|
||||||
)
|
)
|
||||||
.toggler(page.theme_mode.auto_switch, Message::Autoswitch),
|
.toggler(page.theme_mode.auto_switch, Message::Autoswitch),
|
||||||
)
|
)
|
||||||
.add(
|
.add(accent_color_palette)
|
||||||
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(
|
.add(
|
||||||
settings::item::builder(&descriptions[app_bg]).control(
|
settings::item::builder(&descriptions[app_bg]).control(
|
||||||
page.application_background
|
page.application_background
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue