diff --git a/dash-frontend/assets/gui/view/color_palettes.xml b/dash-frontend/assets/gui/view/color_palettes.xml index 4529dcf5..336d9982 100644 --- a/dash-frontend/assets/gui/view/color_palettes.xml +++ b/dash-frontend/assets/gui/view/color_palettes.xml @@ -1,5 +1,4 @@ - + +
diff --git a/dash-frontend/assets/lang/de.json b/dash-frontend/assets/lang/de.json index 26ace2a5..b63a01db 100644 --- a/dash-frontend/assets/lang/de.json +++ b/dash-frontend/assets/lang/de.json @@ -190,7 +190,9 @@ "COLOR_PALETTE_CURRENT": "Derzeit aktives Thema.", "COLOR_PALETTE_ACTIVATE": "Klicken Sie hier, um dieses Thema zu verwenden.", "APPLY_CHANGES_RESTART": "WayVR neu starten, um die Änderungen zu übernehmen?", - "COLOR_PALETTE_HELP": "Klicken, um Farbpaletten zu durchsuchen.\nUm eigene zu erstellen, besuche die Webseite!" + "COLOR_PALETTE_HELP": "Klicken, um Farbpaletten zu durchsuchen.\nUm eigene zu erstellen, besuche die Webseite!", + "COLOR_PALETTE_CUSTOM_URL": "Füge dein eigenes benutzerdefiniertes Thema hinzu!", + "COLOR_PALETTE_CUSTOM_URL2": "Klicken Sie hier, um das Web-Handbuch zu öffnen." }, "HELLO": "Hallo!", "AUDIO": { diff --git a/dash-frontend/assets/lang/en.json b/dash-frontend/assets/lang/en.json index a618591c..d2b9d802 100644 --- a/dash-frontend/assets/lang/en.json +++ b/dash-frontend/assets/lang/en.json @@ -100,6 +100,8 @@ "COLOR_PALETTE_HELP": "Click to browse color palettes.\nTo create custom ones, see website!", "COLOR_PALETTES": "Color palettes", "COLOR_PALETTE_CURRENT": "Currently active theme.", + "COLOR_PALETTE_CUSTOM_URL": "Add your own custom theme!", + "COLOR_PALETTE_CUSTOM_URL2": "Click to open web manual.", "COLOR_PALETTE_ACTIVATE": "Click to use this theme.", "APPLY_CHANGES_RESTART": "Restart WayVR to apply changes?", "CLEAR_PIPEWIRE_TOKENS": "Clear PipeWire tokens", diff --git a/dash-frontend/assets/lang/es.json b/dash-frontend/assets/lang/es.json index ee908298..76e21408 100644 --- a/dash-frontend/assets/lang/es.json +++ b/dash-frontend/assets/lang/es.json @@ -190,7 +190,9 @@ "COLOR_PALETTE_CURRENT": "Tema actualmente activo.", "COLOR_PALETTE_ACTIVATE": "Haz clic para usar este tema.", "APPLY_CHANGES_RESTART": "¿Reiniciar WayVR para aplicar los cambios?", - "COLOR_PALETTE_HELP": "Haz clic para explorar paletas de colores.\nPara crear paletas personalizadas, ¡visita el sitio web!" + "COLOR_PALETTE_HELP": "Haz clic para explorar paletas de colores.\nPara crear paletas personalizadas, ¡visita el sitio web!", + "COLOR_PALETTE_CUSTOM_URL": "¡Añade tu propio tema personalizado!", + "COLOR_PALETTE_CUSTOM_URL2": "Haz clic para abrir el manual web." }, "HELLO": "¡Hola!", "AUDIO": { diff --git a/dash-frontend/assets/lang/it.json b/dash-frontend/assets/lang/it.json index f7c73867..3011f0f3 100644 --- a/dash-frontend/assets/lang/it.json +++ b/dash-frontend/assets/lang/it.json @@ -211,7 +211,9 @@ "COLOR_PALETTE_CURRENT": "Tema attualmente attivo.", "COLOR_PALETTE_ACTIVATE": "Clicca per usare questo tema.", "APPLY_CHANGES_RESTART": "Riavviare WayVR per applicare le modifiche?", - "COLOR_PALETTE_HELP": "Clicca per sfogliare le palette di colori.\nPer crearne di personalizzate, visita il sito web!" + "COLOR_PALETTE_HELP": "Clicca per sfogliare le palette di colori.\nPer crearne di personalizzate, visita il sito web!", + "COLOR_PALETTE_CUSTOM_URL": "Aggiungi il tuo tema personalizzato!", + "COLOR_PALETTE_CUSTOM_URL2": "Clicca per aprire il manuale web." }, "APPLICATION_LAUNCHER": "Lanciatore applicazioni", "APPLICATION_STARTED": "Applicazione avviata", diff --git a/dash-frontend/assets/lang/ja.json b/dash-frontend/assets/lang/ja.json index 890bccbd..26114a6f 100644 --- a/dash-frontend/assets/lang/ja.json +++ b/dash-frontend/assets/lang/ja.json @@ -190,7 +190,9 @@ "COLOR_PALETTE_CURRENT": "現在有効なテーマ。", "COLOR_PALETTE_ACTIVATE": "クリックしてこのテーマを適用します。", "APPLY_CHANGES_RESTART": "変更を適用するためにWayVRを再起動しますか?", - "COLOR_PALETTE_HELP": "クリックしてカラーパレットを選択してください。\nカスタムパレットの作成については、ウェブサイトを参照してください!" + "COLOR_PALETTE_HELP": "クリックしてカラーパレットを選択してください。\nカスタムパレットの作成については、ウェブサイトを参照してください!", + "COLOR_PALETTE_CUSTOM_URL": "カスタムテーマを追加しましょう!", + "COLOR_PALETTE_CUSTOM_URL2": "クリックしてウェブマニュアルを開く。" }, "HELLO": "こんにちは!", "AUDIO": { diff --git a/dash-frontend/assets/lang/pl.json b/dash-frontend/assets/lang/pl.json index 85768d59..9acf421e 100644 --- a/dash-frontend/assets/lang/pl.json +++ b/dash-frontend/assets/lang/pl.json @@ -185,7 +185,9 @@ "COLOR_PALETTE_CURRENT": "Obecnie aktywny motyw.", "COLOR_PALETTE_ACTIVATE": "Kliknij, aby użyć tego motywu.", "APPLY_CHANGES_RESTART": "Zrestartować WayVR, aby zastosować zmiany?", - "COLOR_PALETTE_HELP": "Kliknij, aby przeglądać palety kolorów.\nAby stworzyć własne, odwiedź stronę internetową!" + "COLOR_PALETTE_HELP": "Kliknij, aby przeglądać palety kolorów.\nAby stworzyć własne, odwiedź stronę internetową!", + "COLOR_PALETTE_CUSTOM_URL": "Dodaj własny motyw!", + "COLOR_PALETTE_CUSTOM_URL2": "Kliknij, aby otworzyć instrukcję internetową." }, "APPLICATION_LAUNCHER": "Uruchamiacz aplikacji", "APPLICATIONS": "Aplikacje", diff --git a/dash-frontend/assets/lang/zh_CN.json b/dash-frontend/assets/lang/zh_CN.json index 8542bb8a..a9762201 100644 --- a/dash-frontend/assets/lang/zh_CN.json +++ b/dash-frontend/assets/lang/zh_CN.json @@ -211,7 +211,9 @@ "COLOR_PALETTE_CURRENT": "当前激活的主题。", "COLOR_PALETTE_ACTIVATE": "点击以使用此主题。", "APPLY_CHANGES_RESTART": "重启 WayVR 以应用更改吗?", - "COLOR_PALETTE_HELP": "点击浏览配色方案。\n如需创建自定义配色,请参阅网站!" + "COLOR_PALETTE_HELP": "点击浏览配色方案。\n如需创建自定义配色,请参阅网站!", + "COLOR_PALETTE_CUSTOM_URL": "添加自定义主题!", + "COLOR_PALETTE_CUSTOM_URL2": "点击打开网页版手册。" }, "APPLICATION_LAUNCHER": "应用启动器", "APPLICATION_STARTED": "应用已启动", diff --git a/dash-frontend/src/frontend.rs b/dash-frontend/src/frontend.rs index c61e2456..48d68608 100644 --- a/dash-frontend/src/frontend.rs +++ b/dash-frontend/src/frontend.rs @@ -24,14 +24,15 @@ use wlx_common::{ audio, dash_interface::{BoxDashInterface, ConfigChangeKind, RecenterMode}, locale::WayVRLangProvider, + palette::load_palette, timestep::{self, Timestep}, }; use crate::{ assets, tab::{ - Tab, TabType, apps::TabApps, donate::TabDonate, games::TabGames, home::TabHome, monado::TabMonado, - settings::TabSettings, welcome::TabWelcome, + apps::TabApps, donate::TabDonate, games::TabGames, home::TabHome, monado::TabMonado, settings::TabSettings, + welcome::TabWelcome, Tab, TabType, }, util::{ popup_manager::{MountPopupOnceParams, PopupManager, PopupManagerParams}, @@ -131,6 +132,8 @@ impl Frontend { let font_binary_regular = assets.load_from_path_gzip("Quicksand-Regular.ttf.gz")?; let font_binary_light = assets.load_from_path_gzip("Quicksand-Light.ttf.gz")?; + let palette = load_palette(params.color_palette); + let globals = WguiGlobals::new( assets, params.lang_provider, @@ -141,7 +144,7 @@ impl Frontend { family_name_monospace: "", }, PathBuf::new(), //FIXME: pass from somewhere else - params.color_palette, + palette, )?; let (layout, state) = wgui::parser::new_layout_from_assets( diff --git a/dash-frontend/src/views/color_palettes.rs b/dash-frontend/src/views/color_palettes.rs index 4399830a..9bfd222e 100644 --- a/dash-frontend/src/views/color_palettes.rs +++ b/dash-frontend/src/views/color_palettes.rs @@ -6,11 +6,15 @@ use wgui::{ globals::WguiGlobals, i18n::Translation, layout::{Layout, WidgetID}, + log::LogErr, palette::PALETTES, parser::{Fetchable, ParseDocumentParams, TemplateParams}, task::Tasks, }; -use wlx_common::dash_interface::ConfigChangeKind; +use wlx_common::{ + dash_interface::ConfigChangeKind, + palette::{list_palette_files, load_custom_palette}, +}; use crate::{ frontend::{FrontendTask, FrontendTasks}, @@ -22,6 +26,7 @@ use crate::{ #[derive(Clone)] enum Task { SelectPalette(String), + CustomPaletteUrl, Restart, Cancel, } @@ -66,6 +71,11 @@ impl ViewTrait for View { self.settings_tasks.push(SettingsTask::RestartSoftware); } + Task::CustomPaletteUrl => { + self.frontend_tasks.push(FrontendTask::OpenURL( + "https://wayvr.org/docs/basics/customization/".into(), + )); + } } } Ok(()) @@ -105,8 +115,67 @@ impl View { let tasks = Tasks::new(); let popup_dialog = PopupHolder::::default(); + for (idx, name) in list_palette_files().into_iter().enumerate() { + let Ok(palette) = load_custom_palette(&name).log_warn("Could not load custom color palette") else { + continue; + }; + + let id = format!("profile_custom_{idx}"); + let is_current = &*params.current_palette == name.as_str(); + + let mut cell_params = TemplateParams::new(); + cell_params.insert("id", &id); + + let display_name = &name[..name.len() - 5]; + + if is_current { + cell_params.insert_str("text", format!("{display_name} ✅")); + cell_params.insert("tooltip", "APP_SETTINGS.COLOR_PALETTE_CURRENT"); + } else { + cell_params.insert("text", display_name); + cell_params.insert("tooltip", "APP_SETTINGS.COLOR_PALETTE_ACTIVATE"); + } + + insert_colors!( + cell_params, + &palette, + "primary" => Primary, + "on_primary" => OnPrimary, + "secondary" => Secondary, + "on_secondary" => OnSecondary, + "tertiary" => Tertiary, + "on_tertiary" => OnTertiary, + "danger" => Danger, + "on_danger" => OnDanger, + "background" => Background, + "on_background" => OnBackground, + "background_variant" => BackgroundVariant, + "outline" => Outline, + "highlight" => Highlight, + ); + + parser_state.instantiate_template( + doc_params, + "ColorPaletteButton", + params.layout, + list_parent, + cell_params, + )?; + + if !is_current { + let btn = parser_state.fetch_component_as::(&id)?; + let tasks_clone = tasks.clone(); + btn.on_click(Rc::new({ + move |_common, _e| { + tasks_clone.push(Task::SelectPalette(name.to_string())); + Ok(()) + } + })); + } + } + for (idx, (name, palette)) in PALETTES.iter().enumerate() { - let id = format!("profile_btn_{idx}"); + let id = format!("profile_builtin_{idx}"); let is_current = &*params.current_palette == *name; let mut cell_params = TemplateParams::new(); @@ -158,6 +227,22 @@ impl View { } } + parser_state.instantiate_template( + doc_params, + "CustomPaletteButton", + params.layout, + list_parent, + TemplateParams::default(), + )?; + let btn = parser_state.fetch_component_as::("custom_btn")?; + let tasks_clone = tasks.clone(); + btn.on_click(Rc::new({ + move |_common, _e| { + tasks_clone.push(Task::CustomPaletteUrl); + Ok(()) + } + })); + Ok(Self { tasks, frontend_tasks: params.frontend_tasks.clone(), diff --git a/uidev/src/testbed/testbed_any.rs b/uidev/src/testbed/testbed_any.rs index d06f674d..ec1e1a2e 100644 --- a/uidev/src/testbed/testbed_any.rs +++ b/uidev/src/testbed/testbed_any.rs @@ -10,6 +10,7 @@ use wgui::{ font_config::WguiFontConfig, globals::WguiGlobals, layout::{Layout, LayoutParams, LayoutUpdateParams}, + palette::WguiColorPalette, parser::{ParseDocumentParams, ParserState}, }; use wlx_common::locale::WayVRLangProvider; @@ -37,7 +38,7 @@ impl TestbedAny { &lang_provider, &WguiFontConfig::default(), PathBuf::new(), // cwd - &palette_name, + WguiColorPalette::get_builtin(&palette_name), )?; let (layout, state) = wgui::parser::new_layout_from_assets( diff --git a/uidev/src/testbed/testbed_generic.rs b/uidev/src/testbed/testbed_generic.rs index aa303479..f78be9ef 100644 --- a/uidev/src/testbed/testbed_generic.rs +++ b/uidev/src/testbed/testbed_generic.rs @@ -8,15 +8,16 @@ use glam::Vec2; use wgui::{ assets::AssetPath, components::{ - Component, button::{ButtonClickCallback, ComponentButton}, checkbox::ComponentCheckbox, + Component, }, drawing::Color, font_config::WguiFontConfig, globals::WguiGlobals, i18n::Translation, layout::{Layout, LayoutParams, LayoutUpdateParams, Widget}, + palette::WguiColorPalette, parser::{Fetchable, ParseDocumentExtra, ParseDocumentParams, ParserState}, taffy::{self, prelude::length}, task::Tasks, @@ -93,7 +94,7 @@ impl TestbedGeneric { &lang_provider, &WguiFontConfig::default(), PathBuf::new(), // cwd - &palette_name, + WguiColorPalette::get_builtin(&palette_name), )?; let extra = ParseDocumentExtra { diff --git a/wayvr/src/state.rs b/wayvr/src/state.rs index a5ea3189..91a6b8fc 100644 --- a/wayvr/src/state.rs +++ b/wayvr/src/state.rs @@ -16,6 +16,7 @@ use wgui::{ use wlx_capture::pipewire::ScreenCastManager; use wlx_common::config::PwTokenMap; use wlx_common::locale::WayVRLangProvider; +use wlx_common::palette::load_palette; use wlx_common::{ audio, config::GeneralConfig, @@ -167,6 +168,8 @@ impl AppState { ) .ok(); + let palette = load_palette(&*session.config.color_palette); + let mut app_state = Self { tasks, gfx, @@ -184,7 +187,7 @@ impl AppState { &lang_provider, &WguiFontConfig::default(), get_config_file_path(&theme_path), - &session.config.color_palette, + palette, )?, wgui_theme: Rc::new(theme), dbus, diff --git a/wgui/src/globals.rs b/wgui/src/globals.rs index 3bb00f22..4f8b4d12 100644 --- a/wgui/src/globals.rs +++ b/wgui/src/globals.rs @@ -37,7 +37,7 @@ impl WguiGlobals { lang_provider: &dyn LangProvider, font_config: &WguiFontConfig, asset_folder: PathBuf, - color_palette: &str, + palette: WguiColorPalette, ) -> anyhow::Result { let i18n_builtin = I18n::new(assets_builtin.as_mut(), lang_provider)?; let assets_internal = Box::new(assets_internal::AssetInternal {}); @@ -49,7 +49,7 @@ impl WguiGlobals { font_system: WguiFontSystem::new(font_config, i18n_builtin.get_locale()), i18n_builtin, custom_glyph_cache: CustomGlyphCache::new(), - palette: WguiColorPalette::from_name(color_palette), + palette, })))) } diff --git a/wgui/src/palette.rs b/wgui/src/palette.rs index 868f642b..ddd8b339 100644 --- a/wgui/src/palette.rs +++ b/wgui/src/palette.rs @@ -13,7 +13,7 @@ pub struct WguiColorPalette { } impl WguiColorPalette { - pub fn from_name(palette_name: &str) -> Self { + pub fn get_builtin(palette_name: &str) -> Self { for (name, palette) in PALETTES { if *name == palette_name { // just clone here, makes it easier for future customization @@ -25,6 +25,10 @@ impl WguiColorPalette { return DEFAULT.clone(); } + pub const fn from_inner(colors: [drawing::Color; WguiColorName::COUNT]) -> Self { + Self { colors } + } + fn apply_modifier(color: WguiColor, modifier: &str) -> Option { match modifier { "transparent" => Some(color.with_alpha(0.0)), @@ -82,8 +86,8 @@ const fn hex(hex: &str) -> drawing::Color { pub static PALETTES: &[(&'static str, &WguiColorPalette)] = &[ ("Default", DEFAULT), - ("Ayu", AYU), - ("Catppuccin", CATTPUCCIN), + ("Ayu Dusk", AYU), + ("Catppuccin", CATPPUCCIN), ("Cyberpunk", CYBERPUNK), ("Dracula", DRACULA), ("Eldritch", ELDRITCH), @@ -93,21 +97,21 @@ pub static PALETTES: &[(&'static str, &WguiColorPalette)] = &[ ("Monochrome", MONOCHROME), ("Nord", NORD), ("Osaka Jade", OSAKA_JADE), - ("Rosepine", ROSEPINE), + ("Rosé Pine", ROSEPINE), ("Solarized Night", SOLARIZED_NIGHT), ("Tokyo Night", TOKYO_NIGHT), - ("Ayu Light", AYU_LIGHT), - ("Catppuccin Light", CATTPUCCIN_LIGHT), + ("Ayu Day", AYU_LIGHT), + ("Catppuccin Latte", CATPPUCCIN_LATTE), ("Cyberpunk Light", CYBERPUNK_LIGHT), - ("Dracula Light", DRACULA_LIGHT), - ("Eldritch Light", ELDRITCH_LIGHT), + ("Alucard", DRACULA_LIGHT), + ("Eldritch Dusk", ELDRITCH_LIGHT), ("Everforest Light", EVERFOREST_LIGHT), ("Gruvbox Light", GRUVBOX_LIGHT), - ("Kanagawa Light", KANAGAWA_LIGHT), + ("Kanagawa Lotus", KANAGAWA_LIGHT), ("Monochrome Light", MONOCHROME_LIGHT), ("Nord Light", NORD_LIGHT), ("Osaka Jade Light", OSAKA_JADE_LIGHT), - ("Rosepine Light", ROSEPINE_LIGHT), + ("Rosé Pine Dawn", ROSEPINE_LIGHT), ("Solarized Day", SOLARIZED_DAY), ("Tokyo Day", TOKYO_DAY), ]; @@ -178,7 +182,7 @@ static AYU_LIGHT: &WguiColorPalette = &WguiColorPalette { ], }; -static CATTPUCCIN: &WguiColorPalette = &WguiColorPalette { +static CATPPUCCIN: &WguiColorPalette = &WguiColorPalette { colors: [ hex("#cba6f7"), // Primary hex("#11111b"), // OnPrimary @@ -200,13 +204,13 @@ static CATTPUCCIN: &WguiColorPalette = &WguiColorPalette { ], }; -static CATTPUCCIN_LIGHT: &WguiColorPalette = &WguiColorPalette { +static CATPPUCCIN_LATTE: &WguiColorPalette = &WguiColorPalette { colors: [ hex("#8839EF"), // Primary hex("#EFF1F5"), // OnPrimary hex("#FE640B"), // Secondary hex("#EFF1F5"), // OnSecondary - hex("#40A02B"), // Tertiary + hex("#179299"), // Tertiary hex("#EFF1F5"), // OnTertiary hex("#D20F39"), // Danger hex("#DCE0E8"), // OnDanger diff --git a/wlx-common/src/config_io.rs b/wlx-common/src/config_io.rs index a3be0964..17aeecc9 100644 --- a/wlx-common/src/config_io.rs +++ b/wlx-common/src/config_io.rs @@ -25,6 +25,10 @@ pub fn get_skymaps_root() -> PathBuf { get_config_root().join("skymaps") } +pub fn get_palettes_root() -> PathBuf { + get_config_root().join("palettes") +} + pub fn get_skymaps_uuids() -> anyhow::Result> { let data = std::fs::read_to_string(get_skymaps_root().join("skymaps.txt"))?; Ok(data.lines().filter(|line| !line.is_empty()).map(String::from).collect()) diff --git a/wlx-common/src/lib.rs b/wlx-common/src/lib.rs index c8140e79..f9ca1a51 100644 --- a/wlx-common/src/lib.rs +++ b/wlx-common/src/lib.rs @@ -15,5 +15,6 @@ pub mod openxr_actions; pub mod openxr_bindings_schema; pub mod openxr_controller_profiles; pub mod overlays; +pub mod palette; pub mod timestep; pub mod windowing; diff --git a/wlx-common/src/palette.rs b/wlx-common/src/palette.rs new file mode 100644 index 00000000..f7dc74bc --- /dev/null +++ b/wlx-common/src/palette.rs @@ -0,0 +1,153 @@ +use std::{fs::File, io::BufReader}; + +use serde::{de::Error as _, Deserialize, Deserializer}; +use wgui::{ + drawing, + log::LogErr, + palette::{WguiColorPalette, PALETTES}, +}; + +use crate::config_io; + +pub fn load_palette(want_palette: &str) -> WguiColorPalette { + if is_custom_palette(want_palette) { + if let Ok(palette) = load_custom_palette(want_palette).log_warn("Could not load custom color palette") { + return palette; + } + } else { + for (name, palette) in PALETTES { + if *name == want_palette { + return (*palette).clone(); + } + } + log::warn!("No color palette found with name: {want_palette}") + } + PALETTES[0].1.clone() +} + +fn is_custom_palette(name: &str) -> bool { + name + .as_bytes() + .get(name.len().saturating_sub(5)..) + .is_some_and(|suffix| suffix.eq_ignore_ascii_case(b".json")) +} + +pub fn list_palette_files() -> Vec { + let path = config_io::get_palettes_root(); + let Ok(entries) = std::fs::read_dir(path) else { + return Vec::new(); + }; + + let mut files: Vec<_> = entries + .filter_map(Result::ok) + .filter_map(|entry| { + let path = entry.path(); + + if !path.is_file() || !path.extension()?.to_str()?.eq_ignore_ascii_case("json") { + return None; + } + + Some(path.file_name()?.to_str()?.to_owned()) + }) + .collect(); + + files.sort_unstable(); + files +} + +pub fn load_custom_palette(name: &str) -> anyhow::Result { + let path = config_io::get_palettes_root().join(name); + let file = File::open(path)?; + let reader = BufReader::new(file); + let scp = serde_json::from_reader::<_, SerializedWguiColorPalette>(reader)?; + Ok(scp.into_palette()) +} + +fn deserialize_color<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let value = String::deserialize(deserializer)?; + + drawing::Color::from_hex(&value).ok_or_else(|| D::Error::custom(format!("invalid hexadecimal color: {value:?}"))) +} + +#[derive(Deserialize)] +#[serde(deny_unknown_fields)] +struct SerializedWguiColorPalette { + #[serde(deserialize_with = "deserialize_color")] + primary: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + on_primary: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + secondary: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + on_secondary: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + tertiary: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + on_tertiary: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + danger: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + on_danger: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + background: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + on_background: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + background_variant: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + on_background_variant: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + background_contrast: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + on_background_contrast: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + outline: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + shadow: drawing::Color, + + #[serde(deserialize_with = "deserialize_color")] + highlight: drawing::Color, +} + +impl SerializedWguiColorPalette { + pub fn into_palette(&self) -> WguiColorPalette { + // order must stay the same as per WguiColorName + WguiColorPalette::from_inner([ + self.primary, + self.on_primary, + self.secondary, + self.on_secondary, + self.tertiary, + self.on_tertiary, + self.danger, + self.on_danger, + self.background, + self.on_background, + self.background_variant, + self.on_background_variant, + self.background_contrast, + self.on_background_contrast, + self.outline, + self.shadow, + self.highlight, + ]) + } +}