feat: support for custom & system themes + move cosmic-theme to libcosmic

This commit is contained in:
Ashley Wulber 2023-05-22 13:05:33 -04:00
parent 259bba4d19
commit bf1c474d08
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
26 changed files with 2639 additions and 44 deletions

View file

@ -12,3 +12,4 @@ libcosmic = { path = "../..", default-features = false, features = ["debug", "wi
once_cell = "1.15"
slotmap = "1.0.6"
env_logger = "0.10"
log = "0.4.17"

View file

@ -1,6 +1,7 @@
/// Copyright 2022 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0
use cosmic::{
cosmic_config::config_subscription,
font::load_fonts,
iced::{self, Application, Command, Length, Subscription},
iced::{
@ -9,15 +10,20 @@ use cosmic::{
window::{self, close, drag, minimize, toggle_maximize},
},
keyboard_nav,
theme::{self, Theme},
theme::{self, CosmicTheme, CosmicThemeCss, Theme},
widget::{
header_bar, icon, list, nav_bar, nav_bar_toggle, scrollable, segmented_button, settings,
warning, IconSource,
},
Element, ElementExt,
};
use log::error;
use std::{
sync::atomic::{AtomicU32, Ordering},
borrow::Cow,
sync::{
atomic::{AtomicU32, Ordering},
Arc,
},
vec,
};
@ -154,6 +160,7 @@ pub struct Window {
warning_message: String,
scale_factor: f64,
scale_factor_string: String,
system_theme: Arc<CosmicTheme>,
}
impl Window {
@ -198,6 +205,7 @@ pub enum Message {
ToggleNavBarCondensed,
ToggleWarning,
FontsLoaded,
SystemTheme(CosmicTheme),
}
impl From<Page> for Message {
@ -375,6 +383,16 @@ impl Application for Window {
Subscription::batch(vec![
window_break.map(|_| Message::CondensedViewToggle),
keyboard_nav::subscription().map(Message::KeyboardNav),
config_subscription::<_, CosmicThemeCss>(0, Cow::from("com.system76.CosmicTheme"), 1)
.map(|(_, update)| match update {
Ok(t) => Message::SystemTheme(t.into_srgba()),
Err((errors, t)) => {
for error in errors {
error!("{:?}", error);
}
Message::SystemTheme(t.into_srgba())
}
}),
])
}
@ -395,7 +413,13 @@ impl Application for Window {
Some(demo::Output::Debug(debug)) => self.debug = debug,
Some(demo::Output::ScalingFactor(factor)) => self.set_scale_factor(factor),
Some(demo::Output::ThemeChanged(theme)) => {
self.theme = theme;
self.theme = match theme {
demo::ThemeVariant::Light => Theme::light(),
demo::ThemeVariant::Dark => Theme::dark(),
demo::ThemeVariant::HighContrastDark => Theme::dark_hc(),
demo::ThemeVariant::HighContrastLight => Theme::light_hc(),
demo::ThemeVariant::Custom => Theme::custom(self.system_theme.clone()),
};
}
Some(demo::Output::ToggleWarning) => self.toggle_warning(),
None => (),
@ -425,6 +449,9 @@ impl Application for Window {
},
Message::ToggleWarning => self.toggle_warning(),
Message::FontsLoaded => {}
Message::SystemTheme(t) => {
self.system_theme = Arc::new(t);
}
}
ret
}
@ -572,6 +599,6 @@ impl Application for Window {
}
fn theme(&self) -> Theme {
self.theme
self.theme.clone()
}
}

View file

@ -1,9 +1,9 @@
use apply::Apply;
use cosmic::{
cosmic_theme,
iced::widget::{checkbox, pick_list, progress_bar, radio, row, slider, text, text_input},
iced::widget::{checkbox, column, pick_list, progress_bar, radio, slider, text, text_input},
iced::{id, Alignment, Length},
theme::{self, Button as ButtonTheme, Theme},
theme::{self, Button as ButtonTheme, Theme, ThemeType},
widget::{
button, container, icon, segmented_button, segmented_selection, settings, spin_button,
toggler, view_switcher,
@ -15,6 +15,33 @@ use once_cell::sync::Lazy;
use super::{Page, Window};
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)]
pub enum ThemeVariant {
Light,
Dark,
HighContrastDark,
HighContrastLight,
Custom,
}
impl From<&ThemeType> for ThemeVariant {
fn from(theme: &ThemeType) -> Self {
match theme {
ThemeType::Light => ThemeVariant::Light,
ThemeType::Dark => ThemeVariant::Dark,
ThemeType::HighContrastDark => ThemeVariant::HighContrastDark,
ThemeType::HighContrastLight => ThemeVariant::HighContrastLight,
ThemeType::Custom(_) => ThemeVariant::Custom,
}
}
}
impl From<ThemeType> for ThemeVariant {
fn from(theme: ThemeType) -> Self {
ThemeVariant::from(&theme)
}
}
pub enum DemoView {
TabA,
TabB,
@ -44,7 +71,7 @@ pub enum Message {
Selection(segmented_button::Entity),
SliderChanged(f32),
SpinButton(spin_button::Message),
ThemeChanged(Theme),
ThemeChanged(ThemeVariant),
ToggleWarning,
TogglerToggled(bool),
ViewSwitcher(segmented_button::Entity),
@ -54,7 +81,7 @@ pub enum Message {
pub enum Output {
Debug(bool),
ScalingFactor(f32),
ThemeChanged(Theme),
ThemeChanged(ThemeVariant),
ToggleWarning,
}
@ -151,20 +178,21 @@ impl State {
pub(super) fn view<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
let choose_theme = [
Theme::light(),
Theme::dark(),
Theme::light_hc(),
Theme::dark_hc(),
ThemeVariant::Light,
ThemeVariant::Dark,
ThemeVariant::HighContrastLight,
ThemeVariant::HighContrastLight,
ThemeVariant::Custom,
]
.iter()
.into_iter()
.fold(
row![].spacing(10).align_items(Alignment::Center),
column![].spacing(10).align_items(Alignment::Center),
|row, theme| {
row.push(radio(
format!("{:?}", theme.theme_type),
*theme,
if window.theme == *theme {
Some(*theme)
format!("{:?}", theme),
theme,
if ThemeVariant::from(&window.theme.theme_type) == theme {
Some(theme)
} else {
None
},