From 13e73c233b02f043570b18c508f86fa2cf0c5512 Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Tue, 29 Oct 2024 22:21:48 +0100 Subject: [PATCH 1/7] improv: add layouts page --- Cargo.lock | 235 +++++++++--------- Cargo.toml | 5 +- i18n/en/cosmic_ext_tweaks.ftl | 1 + res/icons/bundled/view-coverflow-symbolic.svg | 1 + src/app.rs | 8 + src/core/icons.rs | 1 + src/core/nav.rs | 5 +- src/pages/layouts.rs | 103 ++++++++ src/pages/layouts/config.rs | 93 +++++++ src/pages/layouts/files/cosmic.ron | 164 ++++++++++++ src/pages/layouts/files/mac.ron | 156 ++++++++++++ src/pages/layouts/files/ubuntu.ron | 164 ++++++++++++ src/pages/layouts/files/windows.ron | 156 ++++++++++++ src/pages/mod.rs | 1 + 14 files changed, 978 insertions(+), 115 deletions(-) create mode 100644 res/icons/bundled/view-coverflow-symbolic.svg create mode 100644 src/pages/layouts.rs create mode 100644 src/pages/layouts/config.rs create mode 100644 src/pages/layouts/files/cosmic.ron create mode 100644 src/pages/layouts/files/mac.ron create mode 100644 src/pages/layouts/files/ubuntu.ron create mode 100644 src/pages/layouts/files/windows.ron diff --git a/Cargo.lock b/Cargo.lock index 7844227..1c61367 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -246,9 +246,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.83" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" [[package]] name = "apply" @@ -508,7 +508,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -543,7 +543,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -746,7 +746,7 @@ checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -836,6 +836,46 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + [[package]] name = "clipboard-win" version = "5.3.1" @@ -1064,12 +1104,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cosmic-ext-config-templates" +version = "1.1.0" +source = "git+https://github.com/ryanabx/cosmic-ext-config-templates#a2aac2134a4db8d8bcedc1a0027f1f90bc6a5654" +dependencies = [ + "anyhow", + "clap", + "env_logger 0.11.5", + "log", + "ron", + "serde", + "walkdir", +] + [[package]] name = "cosmic-ext-tweaks" version = "0.1.1" dependencies = [ "anyhow", "ashpd 0.8.1", + "cosmic-ext-config-templates", "cosmic-panel-config", "dirs", "env_logger 0.11.5", @@ -1092,15 +1147,15 @@ dependencies = [ [[package]] name = "cosmic-panel-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#1495bfa2abc4057129c7c3b0e8530b3afd853204" +source = "git+https://github.com/pop-os/cosmic-panel#041a44eb6f825b7e0b3d45ccf745252b136d5da9" dependencies = [ "anyhow", "cosmic-config", "ron", "serde", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit", "tracing", - "wayland-protocols-wlr 0.2.0", + "wayland-protocols-wlr", "xdg-shell-wrapper-config", ] @@ -1272,7 +1327,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1283,7 +1338,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1334,7 +1389,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1382,7 +1437,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1411,7 +1466,7 @@ dependencies = [ "bitflags 2.6.0", "mime 0.1.0", "raw-window-handle", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "smithay-clipboard", ] @@ -1513,7 +1568,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1873,7 +1928,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -2014,7 +2069,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -2260,6 +2315,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -2456,7 +2517,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.63", + "syn 2.0.85", "unic-langid", ] @@ -2470,7 +2531,7 @@ dependencies = [ "i18n-config", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -2656,12 +2717,12 @@ dependencies = [ "resvg", "rustc-hash 2.0.0", "rustix 0.38.34", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "thiserror", "tiny-xlib", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.3", + "wayland-protocols", "wayland-sys", "wgpu", "x11rb", @@ -3550,7 +3611,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -3843,7 +3904,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -3916,12 +3977,12 @@ version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39b0deead1528fd0e5947a8546a9642a9777c25f6e1e26f34c97b204bbb465bd" dependencies = [ - "heck", + "heck 0.4.1", "itertools", "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -3955,7 +4016,7 @@ dependencies = [ "by_address", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -4060,7 +4121,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -4095,7 +4156,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -4250,9 +4311,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -4265,7 +4326,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", "version_check", "yansi", ] @@ -4604,7 +4665,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.63", + "syn 2.0.85", "walkdir", ] @@ -4781,7 +4842,7 @@ dependencies = [ "ab_glyph", "log", "memmap2 0.9.4", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "tiny-skia", ] @@ -4825,22 +4886,22 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "serde" -version = "1.0.202" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -4864,7 +4925,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -4980,33 +5041,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "smithay-client-toolkit" -version = "0.18.0" -source = "git+https://github.com/smithay/client-toolkit?rev=3bed072#3bed072b966022f5f929d12f3aff089b1ace980b" -dependencies = [ - "bitflags 2.6.0", - "bytemuck", - "calloop", - "calloop-wayland-source", - "cursor-icon", - "libc", - "log", - "memmap2 0.9.4", - "pkg-config", - "rustix 0.38.34", - "thiserror", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols 0.31.2", - "wayland-protocols-wlr 0.2.0", - "wayland-scanner", - "xkbcommon", - "xkeysym", -] - [[package]] name = "smithay-client-toolkit" version = "0.19.2" @@ -5028,8 +5062,8 @@ dependencies = [ "wayland-client", "wayland-csd-frame", "wayland-cursor", - "wayland-protocols 0.32.3", - "wayland-protocols-wlr 0.3.3", + "wayland-protocols", + "wayland-protocols-wlr", "wayland-scanner", "xkbcommon", "xkeysym", @@ -5042,7 +5076,7 @@ source = "git+https://github.com/pop-os/smithay-clipboard?tag=pop-dnd-5#5a3007de dependencies = [ "libc", "raw-window-handle", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "wayland-backend", ] @@ -5196,9 +5230,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.63" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -5293,7 +5327,7 @@ checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -5439,7 +5473,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -5598,7 +5632,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -5895,7 +5929,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", "wasm-bindgen-shared", ] @@ -5929,7 +5963,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6003,19 +6037,6 @@ dependencies = [ "xcursor", ] -[[package]] -name = "wayland-protocols" -version = "0.31.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" -dependencies = [ - "bitflags 2.6.0", - "wayland-backend", - "wayland-client", - "wayland-scanner", - "wayland-server", -] - [[package]] name = "wayland-protocols" version = "0.32.3" @@ -6026,6 +6047,7 @@ dependencies = [ "wayland-backend", "wayland-client", "wayland-scanner", + "wayland-server", ] [[package]] @@ -6037,22 +6059,8 @@ dependencies = [ "bitflags 2.6.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.3", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-wlr" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" -dependencies = [ - "bitflags 2.6.0", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.31.2", + "wayland-protocols", "wayland-scanner", - "wayland-server", ] [[package]] @@ -6064,8 +6072,9 @@ dependencies = [ "bitflags 2.6.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.3", + "wayland-protocols", "wayland-scanner", + "wayland-server", ] [[package]] @@ -6081,9 +6090,9 @@ dependencies = [ [[package]] name = "wayland-server" -version = "0.31.1" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e6e4d5c285bc24ba4ed2d5a4bd4febd5fd904451f465973225c8e99772fdb7" +checksum = "2f0a4bab6d420ee4a609b63ef4d5f9b5d309c6b93a029fccab70f2594c0cb3ae" dependencies = [ "bitflags 2.6.0", "downcast-rs", @@ -6338,7 +6347,7 @@ checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -6349,7 +6358,7 @@ checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -6638,7 +6647,7 @@ dependencies = [ "redox_syscall 0.4.1", "rustix 0.38.34", "sctk-adwaita", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "smol_str", "tracing", "unicode-segmentation", @@ -6646,7 +6655,7 @@ dependencies = [ "wasm-bindgen-futures", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.3", + "wayland-protocols", "wayland-protocols-plasma", "web-sys", "web-time", @@ -6731,10 +6740,10 @@ dependencies = [ [[package]] name = "xdg-shell-wrapper-config" version = "0.1.0" -source = "git+https://github.com/pop-os/xdg-shell-wrapper#b5480042615ecfcf30262d5a40625e8f430b474a" +source = "git+https://github.com/pop-os/cosmic-panel#041a44eb6f825b7e0b3d45ccf745252b136d5da9" dependencies = [ "serde", - "wayland-protocols-wlr 0.2.0", + "wayland-protocols-wlr", ] [[package]] @@ -6941,7 +6950,7 @@ checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b196825..63772d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.1" edition = "2021" [dependencies] -anyhow = "1.0.82" ashpd = "0.8.1" dirs = "5.0.1" env_logger = "0.11.5" @@ -17,12 +16,16 @@ reqwest = { version = "0.12", features = ["json"] } ron = "0.8.1" rust-embed = "8.3.0" paste = "1.0" +anyhow = "1.0.91" [dependencies.libcosmic] git = "https://github.com/pop-os/libcosmic.git" default-features = false features = ["multi-window", "tokio", "winit", "wgpu"] +[dependencies.cosmic-ext-config-templates] +git = "https://github.com/ryanabx/cosmic-ext-config-templates" + [dependencies.i18n-embed] version = "0.14" features = ["fluent-system", "desktop-requester"] diff --git a/i18n/en/cosmic_ext_tweaks.ftl b/i18n/en/cosmic_ext_tweaks.ftl index 066762c..c4d5b95 100644 --- a/i18n/en/cosmic_ext_tweaks.ftl +++ b/i18n/en/cosmic_ext_tweaks.ftl @@ -4,6 +4,7 @@ app-description = A tool to customize your COSMIC desktop experience. home = Home dock = Dock panel = Panel +layouts = Layouts color-schemes = Color schemes color-schemes-error = Error loading color schemes import-color-scheme = Import color scheme diff --git a/res/icons/bundled/view-coverflow-symbolic.svg b/res/icons/bundled/view-coverflow-symbolic.svg new file mode 100644 index 0000000..b146e30 --- /dev/null +++ b/res/icons/bundled/view-coverflow-symbolic.svg @@ -0,0 +1 @@ + diff --git a/src/app.rs b/src/app.rs index 5595566..69f8168 100644 --- a/src/app.rs +++ b/src/app.rs @@ -20,6 +20,7 @@ use crate::{ pages::{ self, color_schemes::{config::ColorScheme, preview, ColorSchemeProvider, ColorSchemes}, + layouts::Layouts, }, settings::{AppTheme, TweaksSettings}, }; @@ -33,6 +34,7 @@ pub struct TweakTool { dialog_text_input: widget::Id, key_binds: HashMap, color_schemes: ColorSchemes, + layouts: Layouts, context_page: ContextPage, app_themes: Vec, config_handler: Option, @@ -58,6 +60,7 @@ pub enum DialogPage { pub enum Message { Dock(pages::dock::Message), Panel(pages::panel::Message), + Layouts(pages::layouts::Message), ColorSchemes(Box), OpenSaveDialog, DialogUpdate(DialogPage), @@ -226,6 +229,7 @@ impl Application for TweakTool { dialog_text_input: widget::Id::unique(), key_binds: key_binds(), color_schemes: ColorSchemes::default(), + layouts: Layouts::default(), context_page: ContextPage::About, app_themes: vec![fl!("match-desktop"), fl!("dark"), fl!("light")], config_handler: flags.config_handler, @@ -257,6 +261,7 @@ impl Application for TweakTool { .map(Message::ColorSchemes), NavPage::Dock => pages::dock::Dock::default().view().map(Message::Dock), NavPage::Panel => pages::panel::Panel::default().view().map(Message::Panel), + NavPage::Layouts => self.layouts.view().map(Message::Layouts), }; widget::column::with_children(vec![view]) @@ -370,6 +375,9 @@ impl Application for TweakTool { .update(message) .map(cosmic::app::Message::App), ), + Message::Layouts(message) => { + commands.push(self.layouts.update(message).map(cosmic::app::Message::App)) + } Message::ColorSchemes(message) => match *message { pages::color_schemes::Message::SaveCurrentColorScheme(None) => { commands.push(self.update(Message::OpenSaveDialog)) diff --git a/src/core/icons.rs b/src/core/icons.rs index dff8946..015fea1 100644 --- a/src/core/icons.rs +++ b/src/core/icons.rs @@ -39,6 +39,7 @@ impl IconCache { bundle!("dock-top-symbolic", 18); bundle!("dark-mode-symbolic", 18); bundle!("resize-mode-symbolic", 18); + bundle!("view-coverflow-symbolic", 18); bundle!("arrow-into-box-symbolic", 16); bundle!("document-save-symbolic", 16); bundle!("search-global-symbolic", 16); diff --git a/src/core/nav.rs b/src/core/nav.rs index fab530f..be9538c 100644 --- a/src/core/nav.rs +++ b/src/core/nav.rs @@ -10,6 +10,7 @@ pub enum NavPage { ColorSchemes, Dock, Panel, + Layouts, } impl Default for &NavPage { @@ -24,6 +25,7 @@ impl NavPage { Self::ColorSchemes => fl!("color-schemes"), Self::Dock => fl!("dock"), Self::Panel => fl!("panel"), + Self::Layouts => fl!("layouts"), } } @@ -32,10 +34,11 @@ impl NavPage { Self::ColorSchemes => icons::get_icon("dark-mode-symbolic", 18), Self::Dock => icons::get_icon("dock-bottom-symbolic", 18), Self::Panel => icons::get_icon("dock-top-symbolic", 18), + Self::Layouts => icons::get_icon("view-coverflow-symbolic", 18), } } pub fn all() -> &'static [Self] { - &[Self::ColorSchemes, Self::Dock, Self::Panel] + &[Self::ColorSchemes, Self::Dock, Self::Panel, Self::Layouts] } } diff --git a/src/pages/layouts.rs b/src/pages/layouts.rs new file mode 100644 index 0000000..bc6005a --- /dev/null +++ b/src/pages/layouts.rs @@ -0,0 +1,103 @@ +use std::path::{Path, PathBuf}; + +use config::{CustomLayout, Layout, LayoutsConfig}; +use cosmic::{cosmic_config::Config, widget, Application, Apply, Element, Task}; +use cosmic_ext_config_templates::{generate_template, load_template}; +use dirs::data_local_dir; + +use crate::app::TweakTool; + +pub mod config; + +#[derive(Debug)] +pub struct Layouts { + pub helper: Option, + pub config: LayoutsConfig, +} + +impl Default for Layouts { + fn default() -> Self { + let (helper, config) = (LayoutsConfig::helper(), LayoutsConfig::config()); + Self { helper, config } + } +} + +#[derive(Debug, Clone)] +pub enum Message { + SelectLayout(Layout), + SaveCurrentLayout(String), +} + +impl Layouts { + pub fn view<'a>(&'a self) -> Element<'a, Message> { + let spacing = cosmic::theme::active().cosmic().spacing; + let layouts = self + .config + .layouts + .iter() + .map(|layout| { + widget::button::text(layout.name()) + .on_press(Message::SelectLayout(layout.clone())) + .into() + }) + .collect::>>(); + + widget::column() + .push(widget::text("Layouts")) + .push( + widget::flex_row(layouts) + .row_spacing(spacing.space_xs) + .column_spacing(spacing.space_xs) + .apply(widget::container) + .padding([0, spacing.space_xxs]), + ) + .into() + } + + pub fn update(&mut self, message: Message) -> Task { + match message { + Message::SelectLayout(layout) => { + if let Err(e) = load_template(layout.schema().clone()) { + eprintln!("Failed to load template: {}", e); + } + } + Message::SaveCurrentLayout(name) => { + let path = data_local_dir() + .unwrap() + .join("cosmic") + .join(TweakTool::APP_ID) + .join("layouts") + .join(&name); + let config_dirs = vec![ + PathBuf::from("com.system76.CosmicPanel"), + PathBuf::from("com.system76.CosmicPanel.Dock"), + PathBuf::from("com.system76.CosmicPanel.Panel"), + PathBuf::from("com.system76.CosmicPanelButton"), + ]; + let config_dirs = config_dirs + .iter() + .map(|p| p.as_path()) + .collect::>(); + match generate_template(config_dirs, &path) { + Ok(_) => { + if let Some(helper) = &self.helper { + let layout = CustomLayout::new(name, &path); + let mut layouts = self.config.layouts.clone(); + layouts.push(Layout::Custom(layout)); + match self.config.set_layouts(helper, layouts) { + Ok(written) => { + if !written { + eprintln!("Failed to write layouts to config"); + } + } + Err(e) => eprintln!("Failed to set layouts: {}", e), + } + } + } + Err(e) => eprintln!("Failed to generate template: {}", e), + } + } + } + Task::none() + } +} diff --git a/src/pages/layouts/config.rs b/src/pages/layouts/config.rs new file mode 100644 index 0000000..95a746c --- /dev/null +++ b/src/pages/layouts/config.rs @@ -0,0 +1,93 @@ +use std::path::PathBuf; + +use cosmic::{ + cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, Config, CosmicConfigEntry}, + Application, +}; +use cosmic_ext_config_templates::Schema; +use serde::{Deserialize, Serialize}; + +use crate::app::TweakTool; + +const COSMIC: &str = include_str!("../layouts/files/cosmic.ron"); +const MAC: &str = include_str!("../layouts/files/mac.ron"); +const WINDOWS: &str = include_str!("../layouts/files/windows.ron"); +const UBUNTU: &str = include_str!("../layouts/files/ubuntu.ron"); + +#[derive(Debug, Serialize, Clone, Deserialize, PartialEq, CosmicConfigEntry)] +#[version = 1] +pub struct LayoutsConfig { + pub layouts: Vec, +} + +impl Default for LayoutsConfig { + fn default() -> Self { + Self { + layouts: vec![Layout::Cosmic, Layout::Mac, Layout::Windows, Layout::Ubuntu], + } + } +} + +impl LayoutsConfig { + pub fn helper() -> Option { + Config::new(TweakTool::APP_ID, Self::VERSION).ok() + } + + pub fn config() -> LayoutsConfig { + match Self::helper() { + Some(config_handler) => { + LayoutsConfig::get_entry(&config_handler).unwrap_or_else(|(errs, config)| { + log::info!("errors loading config: {:?}", errs); + config + }) + } + None => LayoutsConfig::default(), + } + } +} + +#[derive(Debug, Serialize, Clone, Deserialize, PartialEq)] +pub enum Layout { + Cosmic, + Mac, + Windows, + Ubuntu, + Custom(CustomLayout), +} + +impl Layout { + pub fn name(&self) -> &str { + match self { + Layout::Cosmic => "cosmic", + Layout::Mac => "mac", + Layout::Windows => "windows", + Layout::Ubuntu => "ubuntu", + Layout::Custom(custom_layout) => &custom_layout.name, + } + } + + pub fn schema(&self) -> Schema { + match self { + Layout::Cosmic => ron::from_str::(COSMIC).unwrap(), + Layout::Mac => ron::from_str::(MAC).unwrap(), + Layout::Windows => ron::from_str::(WINDOWS).unwrap(), + Layout::Ubuntu => ron::from_str::(UBUNTU).unwrap(), + Layout::Custom(custom_layout) => Schema::from_file(&custom_layout.path).unwrap(), + } + } +} + +#[derive(Debug, Serialize, Clone, Default, Deserialize, PartialEq, CosmicConfigEntry)] +pub struct CustomLayout { + name: String, + path: PathBuf, +} + +impl CustomLayout { + pub fn new(name: String, path: &PathBuf) -> Self { + Self { + name, + path: path.clone(), + } + } +} diff --git a/src/pages/layouts/files/cosmic.ron b/src/pages/layouts/files/cosmic.ron new file mode 100644 index 0000000..8edff6c --- /dev/null +++ b/src/pages/layouts/files/cosmic.ron @@ -0,0 +1,164 @@ +( + overrides: [ + ( + path: "com.system76.CosmicPanel/v1/entries", + setting: "[\n \"Panel\",\n \"Dock\",\n]", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/name", + setting: "\"Dock\"", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/anchor", + setting: "Bottom", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/anchor_gap", + setting: "false", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/layer", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", + setting: "OnDemand", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/size", + setting: "L", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/output", + setting: "All", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/background", + setting: "ThemeDefault", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/plugins_wings", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/plugins_center", + setting: "Some([\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicAppletMinimize\",\n])", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/expand_to_edges", + setting: "false", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/padding", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/spacing", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/border_radius", + setting: "160", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/autohide", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/margin", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/opacity", + setting: "1.0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/size_wings", + setting: "Some([\n None,\n Some(()),\n])", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/size_center", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/name", + setting: "\"Panel\"", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/anchor", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", + setting: "false", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/layer", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/keyboard_interactivity", + setting: "OnDemand", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/size", + setting: "XS", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/output", + setting: "All", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/background", + setting: "ThemeDefault", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/plugins_wings", + setting: "Some(([\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n], [\n \"com.system76.CosmicAppletInputSources\",\n \"com.system76.CosmicAppletStatusArea\",\n \"com.system76.CosmicAppletTiling\",\n \"com.system76.CosmicAppletAudio\",\n \"com.system76.CosmicAppletNetwork\",\n \"com.system76.CosmicAppletBattery\",\n \"com.system76.CosmicAppletNotifications\",\n \"com.system76.CosmicAppletBluetooth\",\n \"com.system76.CosmicAppletPower\",\n]))", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/plugins_center", + setting: "Some([\n \"com.system76.CosmicAppletTime\",\n])", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/expand_to_edges", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/padding", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/spacing", + setting: "2", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/border_radius", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/autohide", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/margin", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/opacity", + setting: "1.0", + ), + ( + path: "com.system76.CosmicPanelButton/v1/configs", + setting: "{\n \"Dock\": (\n force_presentation: Some(Icon),\n ),\n \"Panel\": (\n force_presentation: None,\n ),\n}", + ), + ], +) \ No newline at end of file diff --git a/src/pages/layouts/files/mac.ron b/src/pages/layouts/files/mac.ron new file mode 100644 index 0000000..01f7df5 --- /dev/null +++ b/src/pages/layouts/files/mac.ron @@ -0,0 +1,156 @@ +( + overrides: [ + ( + path: "com.system76.CosmicPanel/v1/entries", + setting: "[\n \"Panel\",\n \"Dock\",\n]", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/anchor_gap", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/layer", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/border_radius", + setting: "8", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/padding", + setting: "6", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/margin", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/opacity", + setting: "1.0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/output", + setting: "All", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", + setting: "OnDemand", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/anchor", + setting: "Bottom", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/size", + setting: "S", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/plugins_wings", + setting: "Some(([], []))", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/autohide", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/expand_to_edges", + setting: "false", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/spacing", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/name", + setting: "\"Dock\"", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/background", + setting: "ThemeDefault", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/plugins_center", + setting: "Some([\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppletMinimize\",\n])", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", + setting: "false", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/layer", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/border_radius", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/padding", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/margin", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/opacity", + setting: "0.91", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/output", + setting: "All", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/keyboard_interactivity", + setting: "OnDemand", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/anchor", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/size", + setting: "XS", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/plugins_wings", + setting: "Some(([\n \"com.system76.CosmicAppletPower\",\n], [\n \"com.system76.CosmicAppletStatusArea\",\n \"com.system76.CosmicAppletBattery\",\n \"com.system76.CosmicAppletNetwork\",\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicAppletNotifications\",\n \"com.system76.CosmicAppletTime\",\n]))", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/autohide", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/expand_to_edges", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/spacing", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/name", + setting: "\"Panel\"", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/background", + setting: "ThemeDefault", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/plugins_center", + setting: "Some([])", + ), + ( + path: "com.system76.CosmicPanelButton/v1/configs", + setting: "{\n \"Dock\": (\n force_presentation: Some(Icon),\n ),\n \"Panel\": (\n force_presentation: Some(Icon),\n ),\n}", + ), + ], +) \ No newline at end of file diff --git a/src/pages/layouts/files/ubuntu.ron b/src/pages/layouts/files/ubuntu.ron new file mode 100644 index 0000000..3977140 --- /dev/null +++ b/src/pages/layouts/files/ubuntu.ron @@ -0,0 +1,164 @@ +( + overrides: [ + ( + path: "com.system76.CosmicPanel/v1/entries", + setting: "[\n \"Panel\",\n \"Dock\",\n]", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/name", + setting: "\"Dock\"", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/anchor", + setting: "Left", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/anchor_gap", + setting: "false", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/layer", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", + setting: "OnDemand", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/size", + setting: "M", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/output", + setting: "All", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/background", + setting: "ThemeDefault", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/plugins_wings", + setting: "Some(([\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicAppletMinimize\",\n], []))", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/plugins_center", + setting: "Some([])", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/expand_to_edges", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/padding", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/spacing", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/border_radius", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/autohide", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/margin", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/opacity", + setting: "1.0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/size_wings", + setting: "Some([\n None,\n Some(()),\n])", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/size_center", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/name", + setting: "\"Panel\"", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/anchor", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", + setting: "false", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/layer", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/keyboard_interactivity", + setting: "OnDemand", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/size", + setting: "XS", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/output", + setting: "All", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/background", + setting: "ThemeDefault", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/plugins_wings", + setting: "Some(([\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n], [\n \"com.system76.CosmicAppletInputSources\",\n \"com.system76.CosmicAppletStatusArea\",\n \"com.system76.CosmicAppletTiling\",\n \"com.system76.CosmicAppletAudio\",\n \"com.system76.CosmicAppletNetwork\",\n \"com.system76.CosmicAppletBattery\",\n \"com.system76.CosmicAppletNotifications\",\n \"com.system76.CosmicAppletBluetooth\",\n \"com.system76.CosmicAppletPower\",\n]))", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/plugins_center", + setting: "Some([\n \"com.system76.CosmicAppletTime\",\n])", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/expand_to_edges", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/padding", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/spacing", + setting: "2", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/border_radius", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/autohide", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/margin", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/opacity", + setting: "1.0", + ), + ( + path: "com.system76.CosmicPanelButton/v1/configs", + setting: "{\n \"Dock\": (\n force_presentation: Some(Icon),\n ),\n \"Panel\": (\n force_presentation: None,\n ),\n}", + ), + ], +) \ No newline at end of file diff --git a/src/pages/layouts/files/windows.ron b/src/pages/layouts/files/windows.ron new file mode 100644 index 0000000..7562ca2 --- /dev/null +++ b/src/pages/layouts/files/windows.ron @@ -0,0 +1,156 @@ +( + overrides: [ + ( + path: "com.system76.CosmicPanel/v1/entries", + setting: "[\n \"Panel\",\n]", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/anchor_gap", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/layer", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/border_radius", + setting: "8", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/padding", + setting: "6", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/margin", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/opacity", + setting: "1.0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/output", + setting: "All", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", + setting: "OnDemand", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/anchor", + setting: "Bottom", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/size", + setting: "S", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/plugins_wings", + setting: "Some(([], []))", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/autohide", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/expand_to_edges", + setting: "false", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/spacing", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/name", + setting: "\"Dock\"", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/background", + setting: "ThemeDefault", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/plugins_center", + setting: "Some([\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppletMinimize\",\n])", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", + setting: "false", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/layer", + setting: "Top", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/border_radius", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/padding", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/margin", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/opacity", + setting: "0.91", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/output", + setting: "All", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/keyboard_interactivity", + setting: "OnDemand", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/anchor", + setting: "Bottom", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/size", + setting: "S", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/plugins_wings", + setting: "Some(([\n \"com.system76.CosmicAppletPower\",\n], [\n \"com.system76.CosmicAppletNetwork\",\n \"com.system76.CosmicAppletAudio\",\n \"com.system76.CosmicAppletBattery\",\n \"com.system76.CosmicAppletTime\",\n \"com.system76.CosmicAppletNotifications\",\n]))", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/autohide", + setting: "None", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/expand_to_edges", + setting: "true", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/spacing", + setting: "4", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/name", + setting: "\"Panel\"", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/background", + setting: "ThemeDefault", + ), + ( + path: "com.system76.CosmicPanel.Panel/v1/plugins_center", + setting: "Some([\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicAppList\",\n])", + ), + ( + path: "com.system76.CosmicPanelButton/v1/configs", + setting: "{\n \"Dock\": (\n force_presentation: Some(Icon),\n ),\n \"Panel\": (\n force_presentation: Some(Icon),\n ),\n}", + ), + ], +) \ No newline at end of file diff --git a/src/pages/mod.rs b/src/pages/mod.rs index 873b69b..6b59826 100644 --- a/src/pages/mod.rs +++ b/src/pages/mod.rs @@ -1,3 +1,4 @@ pub mod color_schemes; pub mod dock; +pub mod layouts; pub mod panel; From d83a5a49683edb6cb998dc205fa2156a30fbc528 Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Wed, 30 Oct 2024 13:58:03 +0100 Subject: [PATCH 2/7] improv: add layout preview --- .../layouts/files => res/layouts}/cosmic.ron | 0 .../layouts/files => res/layouts}/mac.ron | 0 .../layouts/files => res/layouts}/ubuntu.ron | 0 .../layouts/files => res/layouts}/windows.ron | 0 src/app.rs | 99 +++++- src/app/key_bind.rs | 6 +- src/main.rs | 1 + src/pages/layouts.rs | 26 +- src/pages/layouts/config.rs | 73 +++- src/pages/layouts/factory.rs | 316 ++++++++++++++++++ src/resources.rs | 4 + 11 files changed, 487 insertions(+), 38 deletions(-) rename {src/pages/layouts/files => res/layouts}/cosmic.ron (100%) rename {src/pages/layouts/files => res/layouts}/mac.ron (100%) rename {src/pages/layouts/files => res/layouts}/ubuntu.ron (100%) rename {src/pages/layouts/files => res/layouts}/windows.ron (100%) create mode 100644 src/pages/layouts/factory.rs create mode 100644 src/resources.rs diff --git a/src/pages/layouts/files/cosmic.ron b/res/layouts/cosmic.ron similarity index 100% rename from src/pages/layouts/files/cosmic.ron rename to res/layouts/cosmic.ron diff --git a/src/pages/layouts/files/mac.ron b/res/layouts/mac.ron similarity index 100% rename from src/pages/layouts/files/mac.ron rename to res/layouts/mac.ron diff --git a/src/pages/layouts/files/ubuntu.ron b/res/layouts/ubuntu.ron similarity index 100% rename from src/pages/layouts/files/ubuntu.ron rename to res/layouts/ubuntu.ron diff --git a/src/pages/layouts/files/windows.ron b/res/layouts/windows.ron similarity index 100% rename from src/pages/layouts/files/windows.ron rename to res/layouts/windows.ron diff --git a/src/app.rs b/src/app.rs index 69f8168..a890fa7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,12 +1,20 @@ -use std::collections::{HashMap, VecDeque}; +use std::{ + any::TypeId, + collections::{HashMap, VecDeque}, +}; use cosmic::{ app::{self, Core}, - cosmic_config, - iced::{Alignment, Length}, + cosmic_config::{self, Update}, + cosmic_theme::{self, ThemeMode}, + iced::{ + event, + keyboard::{Event as KeyEvent, Key, Modifiers}, + Alignment, Event, Length, Subscription, + }, widget::{ self, - menu::{self, KeyBind}, + menu::{self, Action, KeyBind}, segmented_button, }, Application, ApplicationExt, Apply, Element, Task, @@ -22,7 +30,7 @@ use crate::{ color_schemes::{config::ColorScheme, preview, ColorSchemeProvider, ColorSchemes}, layouts::Layouts, }, - settings::{AppTheme, TweaksSettings}, + settings::{AppTheme, TweaksSettings, CONFIG_VERSION}, }; mod key_bind; @@ -32,7 +40,8 @@ pub struct TweakTool { nav_model: segmented_button::SingleSelectModel, dialog_pages: VecDeque, dialog_text_input: widget::Id, - key_binds: HashMap, + key_binds: HashMap, + modifiers: Modifiers, color_schemes: ColorSchemes, layouts: Layouts, context_page: ContextPage, @@ -72,6 +81,9 @@ pub enum Message { AppTheme(usize), FetchAvailableColorSchemes(ColorSchemeProvider, usize), SetAvailableColorSchemes(Vec), + Key(Modifiers, Key), + Modifiers(Modifiers), + SystemThemeModeChange, } #[derive(Debug, Clone, Eq, PartialEq)] @@ -92,17 +104,17 @@ impl ContextPage { } #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Action { +pub enum TweaksAction { About, Settings, } -impl cosmic::widget::menu::Action for Action { +impl Action for TweaksAction { type Message = Message; fn message(&self) -> Self::Message { match self { - Action::About => Message::ToggleContextPage(ContextPage::About), - Action::Settings => Message::ToggleContextPage(ContextPage::Settings), + Self::About => Message::ToggleContextPage(ContextPage::About), + Self::Settings => Message::ToggleContextPage(ContextPage::Settings), } } } @@ -136,8 +148,8 @@ impl Application for TweakTool { menu::items( &self.key_binds, vec![ - menu::Item::Button(fl!("settings"), Action::Settings), - menu::Item::Button(fl!("about"), Action::About), + menu::Item::Button(fl!("settings"), TweaksAction::Settings), + menu::Item::Button(fl!("about"), TweaksAction::About), ], ), )]); @@ -228,6 +240,7 @@ impl Application for TweakTool { dialog_pages: VecDeque::new(), dialog_text_input: widget::Id::unique(), key_binds: key_binds(), + modifiers: Modifiers::empty(), color_schemes: ColorSchemes::default(), layouts: Layouts::default(), context_page: ContextPage::About, @@ -416,9 +429,71 @@ impl Application for TweakTool { Message::DialogCancel => { self.dialog_pages.pop_front(); } + Message::Key(modifiers, key) => { + for (key_bind, action) in &self.key_binds { + if key_bind.matches(modifiers, &key) { + return self.update(action.message()); + } + } + } + Message::Modifiers(modifiers) => { + self.modifiers = modifiers; + } + Message::SystemThemeModeChange => { + commands.push(self.update_config()); + } } Task::batch(commands) } + + fn subscription(&self) -> cosmic::iced::Subscription { + struct ConfigSubscription; + struct ThemeSubscription; + + let subscriptions = vec![ + event::listen_with(|event, _status, _window_id| match event { + Event::Keyboard(KeyEvent::KeyPressed { key, modifiers, .. }) => { + Some(Message::Key(modifiers, key)) + } + Event::Keyboard(KeyEvent::ModifiersChanged(modifiers)) => { + Some(Message::Modifiers(modifiers)) + } + _ => None, + }), + cosmic_config::config_subscription( + TypeId::of::(), + Self::APP_ID.into(), + CONFIG_VERSION, + ) + .map(|update: Update| { + if !update.errors.is_empty() { + log::info!( + "errors loading config {:?}: {:?}", + update.keys, + update.errors + ); + } + Message::SystemThemeModeChange + }), + cosmic_config::config_subscription::<_, cosmic_theme::ThemeMode>( + TypeId::of::(), + cosmic_theme::THEME_MODE_ID.into(), + cosmic_theme::ThemeMode::version(), + ) + .map(|update: Update| { + if !update.errors.is_empty() { + log::info!( + "errors loading theme mode {:?}: {:?}", + update.keys, + update.errors + ); + } + Message::SystemThemeModeChange + }), + ]; + + Subscription::batch(subscriptions) + } } impl TweakTool { diff --git a/src/app/key_bind.rs b/src/app/key_bind.rs index 5ca76d5..b4a5574 100644 --- a/src/app/key_bind.rs +++ b/src/app/key_bind.rs @@ -4,9 +4,9 @@ use cosmic::iced::keyboard::Key; use cosmic::widget::menu::key_bind::KeyBind; use cosmic::widget::menu::key_bind::Modifier; -use crate::app::Action; +use crate::app::TweaksAction; -pub fn key_binds() -> HashMap { +pub fn key_binds() -> HashMap { let mut key_binds = HashMap::new(); macro_rules! bind { @@ -16,7 +16,7 @@ pub fn key_binds() -> HashMap { modifiers: vec![$(Modifier::$modifier),*], key: $key, }, - Action::$action, + TweaksAction::$action, ); }}; } diff --git a/src/main.rs b/src/main.rs index a109283..86aa88f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod app; mod core; mod pages; +mod resources; mod settings; fn main() -> cosmic::iced::Result { diff --git a/src/pages/layouts.rs b/src/pages/layouts.rs index bc6005a..52f1b91 100644 --- a/src/pages/layouts.rs +++ b/src/pages/layouts.rs @@ -1,13 +1,16 @@ use std::path::{Path, PathBuf}; use config::{CustomLayout, Layout, LayoutsConfig}; -use cosmic::{cosmic_config::Config, widget, Application, Apply, Element, Task}; +use cosmic::{ + cosmic_config::Config, iced::alignment::Horizontal, widget, Application, Apply, Element, Task, +}; use cosmic_ext_config_templates::{generate_template, load_template}; use dirs::data_local_dir; use crate::app::TweakTool; pub mod config; +pub mod factory; #[derive(Debug)] pub struct Layouts { @@ -36,22 +39,25 @@ impl Layouts { .layouts .iter() .map(|layout| { - widget::button::text(layout.name()) - .on_press(Message::SelectLayout(layout.clone())) + widget::column() + .push(layout.preview()) + .push(widget::text(layout.name())) + .spacing(spacing.space_xs) + .align_x(Horizontal::Center) .into() }) .collect::>>(); - widget::column() - .push(widget::text("Layouts")) - .push( + widget::scrollable( + widget::settings::section().title("Layouts").add( widget::flex_row(layouts) - .row_spacing(spacing.space_xs) - .column_spacing(spacing.space_xs) + .row_spacing(spacing.space_s) + .column_spacing(spacing.space_s) .apply(widget::container) .padding([0, spacing.space_xxs]), - ) - .into() + ), + ) + .into() } pub fn update(&mut self, message: Message) -> Task { diff --git a/src/pages/layouts/config.rs b/src/pages/layouts/config.rs index 95a746c..26efe2a 100644 --- a/src/pages/layouts/config.rs +++ b/src/pages/layouts/config.rs @@ -1,19 +1,17 @@ use std::path::PathBuf; +use super::{ + factory::{LayoutPreview, PanelProperties, Position}, + Message, +}; +use crate::{app::TweakTool, resources}; use cosmic::{ cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, Config, CosmicConfigEntry}, - Application, + widget, Application, Element, }; use cosmic_ext_config_templates::Schema; use serde::{Deserialize, Serialize}; -use crate::app::TweakTool; - -const COSMIC: &str = include_str!("../layouts/files/cosmic.ron"); -const MAC: &str = include_str!("../layouts/files/mac.ron"); -const WINDOWS: &str = include_str!("../layouts/files/windows.ron"); -const UBUNTU: &str = include_str!("../layouts/files/ubuntu.ron"); - #[derive(Debug, Serialize, Clone, Deserialize, PartialEq, CosmicConfigEntry)] #[version = 1] pub struct LayoutsConfig { @@ -56,7 +54,7 @@ pub enum Layout { } impl Layout { - pub fn name(&self) -> &str { + pub fn file_name(&self) -> &str { match self { Layout::Cosmic => "cosmic", Layout::Mac => "mac", @@ -66,12 +64,61 @@ impl Layout { } } + pub fn name(&self) -> &str { + match self { + Layout::Cosmic => "COSMIC", + Layout::Mac => "macOS", + Layout::Windows => "Windows", + Layout::Ubuntu => "Ubuntu", + Layout::Custom(custom_layout) => &custom_layout.name, + } + } + + pub fn preview(&self) -> Element { + let layout = match self { + Layout::Cosmic => LayoutPreview::new( + Some(PanelProperties::new(Position::Top, true, 10.0)), + Some(PanelProperties::new(Position::Bottom, true, 20.0)), + 6, + true, + ), + Layout::Mac => LayoutPreview::new( + Some(PanelProperties::new(Position::Top, true, 10.0)), + Some(PanelProperties::new(Position::Bottom, false, 20.0)), + 6, + true, + ), + Layout::Windows => LayoutPreview::new( + None, + Some(PanelProperties::new(Position::Bottom, true, 15.0)), + 6, + true, + ), + Layout::Ubuntu => LayoutPreview::new( + Some(PanelProperties::new(Position::Top, true, 10.0)), + Some(PanelProperties::new(Position::Left, true, 20.0)), + 3, + true, + ), + Layout::Custom(_) => LayoutPreview::new( + Some(PanelProperties::new(Position::Top, true, 10.0)), + None, + 0, + true, + ), + }; + + widget::button::custom(layout.render()) + .on_press(Message::SelectLayout(self.clone())) + .into() + } + pub fn schema(&self) -> Schema { match self { - Layout::Cosmic => ron::from_str::(COSMIC).unwrap(), - Layout::Mac => ron::from_str::(MAC).unwrap(), - Layout::Windows => ron::from_str::(WINDOWS).unwrap(), - Layout::Ubuntu => ron::from_str::(UBUNTU).unwrap(), + Layout::Cosmic => ron::from_str::(resources::COSMIC_LAYOUT).unwrap(), + Layout::Mac => ron::from_str::(resources::MAC_LAYOUT).unwrap(), + Layout::Windows => ron::from_str::(resources::WINDOWS_LAYOUT).unwrap(), + Layout::Ubuntu => ron::from_str::(resources::UBUNTU_LAYOUT).unwrap(), Layout::Custom(custom_layout) => Schema::from_file(&custom_layout.path).unwrap(), } } diff --git a/src/pages/layouts/factory.rs b/src/pages/layouts/factory.rs new file mode 100644 index 0000000..31c7c03 --- /dev/null +++ b/src/pages/layouts/factory.rs @@ -0,0 +1,316 @@ +use cosmic::{ + iced::{ + alignment::{Horizontal, Vertical}, + Length, + }, + widget::{self, horizontal_space, vertical_space}, + Element, +}; + +use super::Message; +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct LayoutPreview { + panel: Option, + dock: Option, + dock_icons: u8, + show_window: bool, +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct PanelProperties { + pub position: Position, + pub extend: bool, + pub size: f32, +} + +impl PanelProperties { + pub fn new(position: Position, extend: bool, size: f32) -> Self { + Self { + position, + extend, + size, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Position { + Top, + Bottom, + Left, + Right, +} + +impl LayoutPreview { + pub fn new( + panel: Option, + dock: Option, + dock_icons: u8, + show_window: bool, + ) -> Self { + Self { + panel, + dock, + dock_icons, + show_window, + } + } + + pub fn render<'a>(&self) -> Element<'a, Message> { + let column = widget::column().width(188).height(98); + let row = widget::row().width(188).height(98); + let spacing = cosmic::theme::active().cosmic().spacing; + + let panel = widget::container(widget::text("")).class(cosmic::style::Container::Background); + + let container: Element<_> = match (self.panel, self.dock) { + (None, None) => column.into(), + (None, Some(dock_props)) => { + let extend_dock = if dock_props.extend { + Length::Fill + } else { + Length::Shrink + }; + + let icons = (0..self.dock_icons) + .map(|_| square(dock_props.size - 5.0)) + .collect(); + + let icons: Element<_> = + if matches!(dock_props.position, Position::Top | Position::Bottom) { + widget::row::with_children(icons) + .spacing(spacing.space_xxs) + .align_y(Vertical::Center) + .into() + } else { + widget::column::with_children(icons) + .spacing(spacing.space_xxs) + .align_x(Horizontal::Center) + .into() + }; + + let dock = widget::container(icons) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .padding(5) + .class(cosmic::style::Container::Background); + + match dock_props.position { + Position::Top => column + .push(dock.width(extend_dock)) + .align_x(Horizontal::Center) + .into(), + Position::Bottom => column + .push(vertical_space()) + .push(dock.width(extend_dock)) + .align_x(Horizontal::Center) + .into(), + Position::Left => row.push(dock).align_y(Vertical::Center).into(), + Position::Right => row + .push(horizontal_space()) + .push(dock) + .align_y(Vertical::Center) + .into(), + } + } + (Some(panel_props), None) => { + let extend_panel = if panel_props.extend { + Length::Fill + } else { + Length::Shrink + }; + match panel_props.position { + Position::Top => column + .push(panel.width(extend_panel).height(panel_props.size)) + .align_x(Horizontal::Center) + .into(), + Position::Bottom => column + .push(vertical_space()) + .push(panel.width(extend_panel).height(panel_props.size)) + .align_x(Horizontal::Center) + .into(), + Position::Left => row + .push(panel.width(panel_props.size).height(extend_panel)) + .align_y(Vertical::Center) + .into(), + Position::Right => row + .push(horizontal_space()) + .push(panel.width(panel_props.size).height(extend_panel)) + .align_y(Vertical::Center) + .into(), + } + } + (Some(panel_props), Some(dock_props)) => { + let extend_panel = if panel_props.extend { + Length::Fill + } else { + Length::Shrink + }; + let extend_dock = if dock_props.extend { + Length::Fill + } else { + Length::Shrink + }; + + let icons = (0..self.dock_icons) + .map(|_| square(dock_props.size - 5.0)) + .collect(); + + let icons: Element<_> = + if matches!(dock_props.position, Position::Top | Position::Bottom) { + widget::row::with_children(icons) + .spacing(spacing.space_xxs) + .align_y(Vertical::Center) + .into() + } else { + widget::column::with_children(icons) + .spacing(spacing.space_xxs) + .align_x(Horizontal::Center) + .into() + }; + + let dock = widget::container(icons) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .padding(5) + .class(cosmic::style::Container::Background); + + match (panel_props.position, dock_props.position) { + (Position::Top, Position::Top) => column + .push(panel.width(extend_panel).height(panel_props.size)) + .push(dock.width(extend_dock)) + .align_x(Horizontal::Center) + .into(), + (Position::Top, Position::Bottom) => column + .push(panel.width(extend_panel).height(panel_props.size)) + .push(vertical_space()) + .push(dock.width(extend_dock)) + .align_x(Horizontal::Center) + .into(), + (Position::Top, Position::Left) => column + .push(panel.width(extend_panel).height(panel_props.size)) + .push( + widget::row() + .push(dock.height(extend_dock)) + .width(Length::Fill), + ) + .align_x(Horizontal::Center) + .into(), + (Position::Top, Position::Right) => column + .push(panel.width(extend_panel).height(panel_props.size)) + .push( + widget::row() + .push(horizontal_space()) + .push(dock.height(extend_dock)) + .width(Length::Fill), + ) + .align_x(Horizontal::Center) + .into(), + (Position::Bottom, Position::Top) => column + .push(dock.width(extend_dock)) + .push(vertical_space()) + .push(panel.width(extend_panel).height(panel_props.size)) + .align_x(Horizontal::Center) + .into(), + (Position::Bottom, Position::Bottom) => column + .push(vertical_space()) + .push(panel.width(extend_panel).height(panel_props.size)) + .push(dock.width(extend_dock)) + .align_x(Horizontal::Center) + .into(), + (Position::Bottom, Position::Left) => column + .push( + widget::row() + .push(dock.height(extend_dock)) + .width(Length::Fill), + ) + .push(panel.width(extend_panel).height(panel_props.size)) + .align_x(Horizontal::Center) + .into(), + (Position::Bottom, Position::Right) => column + .push( + widget::row() + .push(horizontal_space()) + .push(dock.height(extend_dock)), + ) + .push(panel.width(extend_panel).height(panel_props.size)) + .align_x(Horizontal::Center) + .into(), + (Position::Left, Position::Top) => row + .push(panel.width(panel_props.size).height(extend_panel)) + .push( + widget::column() + .push(dock.width(extend_dock)) + .align_x(Horizontal::Center), + ) + .align_y(Vertical::Center) + .into(), + (Position::Left, Position::Bottom) => row + .push(panel.width(panel_props.size).height(extend_panel)) + .push( + widget::column() + .push(horizontal_space()) + .push(dock.width(extend_dock)) + .align_x(Horizontal::Center), + ) + .align_y(Vertical::Center) + .into(), + (Position::Left, Position::Left) => row + .push(panel.width(panel_props.size).height(extend_panel)) + .push(dock.height(extend_dock)) + .align_y(Vertical::Center) + .into(), + (Position::Left, Position::Right) => row + .push(panel.width(panel_props.size).height(extend_panel)) + .push(horizontal_space()) + .push(dock.height(extend_dock)) + .align_y(Vertical::Center) + .into(), + (Position::Right, Position::Top) => row + .push( + widget::column() + .push(dock.width(extend_dock)) + .align_x(Horizontal::Center), + ) + .push(horizontal_space()) + .push(panel.width(panel_props.size).height(extend_panel)) + .align_y(Vertical::Center) + .into(), + (Position::Right, Position::Bottom) => row + .push( + widget::column() + .push(vertical_space()) + .push(dock.width(extend_dock)) + .align_x(Horizontal::Center), + ) + .push(horizontal_space()) + .push(panel.width(panel_props.size).height(extend_panel)) + .align_y(Vertical::Center) + .into(), + (Position::Right, Position::Left) => row + .push(dock.height(extend_dock)) + .push(horizontal_space()) + .push(panel.width(panel_props.size).height(extend_panel)) + .align_y(Vertical::Center) + .into(), + (Position::Right, Position::Right) => row + .push(horizontal_space()) + .push(dock.height(extend_dock)) + .push(panel.width(panel_props.size).height(extend_panel)) + .align_y(Vertical::Center) + .into(), + } + } + }; + + container.into() + } +} + +pub fn square<'a>(size: f32) -> Element<'a, Message> { + widget::container(widget::text("")) + .width(Length::Fixed(size)) + .height(Length::Fixed(size)) + .class(cosmic::style::Container::Secondary) + .into() +} diff --git a/src/resources.rs b/src/resources.rs new file mode 100644 index 0000000..98cd1df --- /dev/null +++ b/src/resources.rs @@ -0,0 +1,4 @@ +pub const COSMIC_LAYOUT: &str = include_str!("../res/layouts/cosmic.ron"); +pub const MAC_LAYOUT: &str = include_str!("../res/layouts/mac.ron"); +pub const WINDOWS_LAYOUT: &str = include_str!("../res/layouts/windows.ron"); +pub const UBUNTU_LAYOUT: &str = include_str!("../res/layouts/ubuntu.ron"); From 3684c059fdb059fd2f3784de978eba17beff66d7 Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Wed, 30 Oct 2024 21:33:31 +0100 Subject: [PATCH 3/7] improv: add button to save current layout --- i18n/en/cosmic_ext_tweaks.ftl | 1 + res/layouts/cosmic.ron | 136 +++++++++++++++++----------------- src/app.rs | 80 +++++++++++++------- src/pages/layouts.rs | 62 +++++++++++----- 4 files changed, 166 insertions(+), 113 deletions(-) diff --git a/i18n/en/cosmic_ext_tweaks.ftl b/i18n/en/cosmic_ext_tweaks.ftl index c4d5b95..3fc4766 100644 --- a/i18n/en/cosmic_ext_tweaks.ftl +++ b/i18n/en/cosmic_ext_tweaks.ftl @@ -34,6 +34,7 @@ spacing-description = Spacing is the space between the icons in the dock or pane save = Save cancel = Cancel save-current-color-scheme = Save current color scheme +save-current-layout = Save current layout color-scheme-name = Color scheme name ## About diff --git a/res/layouts/cosmic.ron b/res/layouts/cosmic.ron index 8edff6c..dfc8ba2 100644 --- a/res/layouts/cosmic.ron +++ b/res/layouts/cosmic.ron @@ -4,14 +4,6 @@ path: "com.system76.CosmicPanel/v1/entries", setting: "[\n \"Panel\",\n \"Dock\",\n]", ), - ( - path: "com.system76.CosmicPanel.Dock/v1/name", - setting: "\"Dock\"", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/anchor", - setting: "Bottom", - ), ( path: "com.system76.CosmicPanel.Dock/v1/anchor_gap", setting: "false", @@ -21,144 +13,152 @@ setting: "Top", ), ( - path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", - setting: "OnDemand", + path: "com.system76.CosmicPanel.Dock/v1/border_radius", + setting: "0", ), ( - path: "com.system76.CosmicPanel.Dock/v1/size", - setting: "L", + path: "com.system76.CosmicPanel.Dock/v1/padding", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/margin", + setting: "0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/opacity", + setting: "1.0", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", + setting: "true", ), ( path: "com.system76.CosmicPanel.Dock/v1/output", setting: "All", ), ( - path: "com.system76.CosmicPanel.Dock/v1/background", - setting: "ThemeDefault", + path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", + setting: "OnDemand", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/anchor", + setting: "Bottom", + ), + ( + path: "com.system76.CosmicPanel.Dock/v1/size", + setting: "L", ), ( path: "com.system76.CosmicPanel.Dock/v1/plugins_wings", setting: "None", ), ( - path: "com.system76.CosmicPanel.Dock/v1/plugins_center", - setting: "Some([\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicAppletMinimize\",\n])", + path: "com.system76.CosmicPanel.Dock/v1/autohide", + setting: "None", ), ( path: "com.system76.CosmicPanel.Dock/v1/expand_to_edges", - setting: "false", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/padding", - setting: "0", + setting: "true", ), ( path: "com.system76.CosmicPanel.Dock/v1/spacing", setting: "4", ), ( - path: "com.system76.CosmicPanel.Dock/v1/border_radius", - setting: "160", + path: "com.system76.CosmicPanel.Dock/v1/name", + setting: "\"Dock\"", ), ( - path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", - setting: "true", + path: "com.system76.CosmicPanel.Dock/v1/background", + setting: "ThemeDefault", ), ( - path: "com.system76.CosmicPanel.Dock/v1/autohide", - setting: "None", + path: "com.system76.CosmicPanel.Dock/v1/plugins_center", + setting: "Some([\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicAppletMinimize\",\n])", ), ( - path: "com.system76.CosmicPanel.Dock/v1/margin", - setting: "0", + path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", + setting: "false", ), ( - path: "com.system76.CosmicPanel.Dock/v1/opacity", - setting: "1.0", + path: "com.system76.CosmicPanel.Panel/v1/layer", + setting: "Top", ), ( - path: "com.system76.CosmicPanel.Panel/v1/size_wings", - setting: "Some([\n None,\n Some(()),\n])", + path: "com.system76.CosmicPanel.Panel/v1/border_radius", + setting: "0", ), ( - path: "com.system76.CosmicPanel.Panel/v1/size_center", - setting: "None", + path: "com.system76.CosmicPanel.Panel/v1/padding", + setting: "0", ), ( - path: "com.system76.CosmicPanel.Panel/v1/name", - setting: "\"Panel\"", + path: "com.system76.CosmicPanel.Panel/v1/margin", + setting: "0", ), ( - path: "com.system76.CosmicPanel.Panel/v1/anchor", - setting: "Top", + path: "com.system76.CosmicPanel.Panel/v1/opacity", + setting: "1.0", ), ( - path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", - setting: "false", + path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", + setting: "true", ), ( - path: "com.system76.CosmicPanel.Panel/v1/layer", - setting: "Top", + path: "com.system76.CosmicPanel.Panel/v1/output", + setting: "All", ), ( path: "com.system76.CosmicPanel.Panel/v1/keyboard_interactivity", setting: "OnDemand", ), ( - path: "com.system76.CosmicPanel.Panel/v1/size", - setting: "XS", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/output", - setting: "All", + path: "com.system76.CosmicPanel.Panel/v1/anchor", + setting: "Top", ), ( - path: "com.system76.CosmicPanel.Panel/v1/background", - setting: "ThemeDefault", + path: "com.system76.CosmicPanel.Panel/v1/size", + setting: "XS", ), ( path: "com.system76.CosmicPanel.Panel/v1/plugins_wings", setting: "Some(([\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n], [\n \"com.system76.CosmicAppletInputSources\",\n \"com.system76.CosmicAppletStatusArea\",\n \"com.system76.CosmicAppletTiling\",\n \"com.system76.CosmicAppletAudio\",\n \"com.system76.CosmicAppletNetwork\",\n \"com.system76.CosmicAppletBattery\",\n \"com.system76.CosmicAppletNotifications\",\n \"com.system76.CosmicAppletBluetooth\",\n \"com.system76.CosmicAppletPower\",\n]))", ), ( - path: "com.system76.CosmicPanel.Panel/v1/plugins_center", - setting: "Some([\n \"com.system76.CosmicAppletTime\",\n])", + path: "com.system76.CosmicPanel.Panel/v1/autohide", + setting: "None", ), ( path: "com.system76.CosmicPanel.Panel/v1/expand_to_edges", setting: "true", ), - ( - path: "com.system76.CosmicPanel.Panel/v1/padding", - setting: "0", - ), ( path: "com.system76.CosmicPanel.Panel/v1/spacing", setting: "2", ), ( - path: "com.system76.CosmicPanel.Panel/v1/border_radius", - setting: "0", + path: "com.system76.CosmicPanel.Panel/v1/name", + setting: "\"Panel\"", ), ( - path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", - setting: "true", + path: "com.system76.CosmicPanel.Panel/v1/background", + setting: "ThemeDefault", ), ( - path: "com.system76.CosmicPanel.Panel/v1/autohide", - setting: "None", + path: "com.system76.CosmicPanel.Panel/v1/plugins_center", + setting: "Some([\n \"com.system76.CosmicAppletTime\",\n])", ), ( - path: "com.system76.CosmicPanel.Panel/v1/margin", - setting: "0", + path: "com.system76.CosmicPanel.Panel/v1/size_center", + setting: "None", ), ( - path: "com.system76.CosmicPanel.Panel/v1/opacity", - setting: "1.0", + path: "com.system76.CosmicPanel.Panel/v1/size_wings", + setting: "Some([\n None,\n Some(()),\n])", ), ( path: "com.system76.CosmicPanelButton/v1/configs", setting: "{\n \"Dock\": (\n force_presentation: Some(Icon),\n ),\n \"Panel\": (\n force_presentation: None,\n ),\n}", ), ], -) \ No newline at end of file +) diff --git a/src/app.rs b/src/app.rs index a890fa7..50eab5d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -62,7 +62,8 @@ pub enum Status { #[derive(Clone, Debug, Eq, PartialEq)] pub enum DialogPage { - New(String), + SaveCurrentColorScheme(String), + SaveCurrentLayout(String), } #[derive(Debug, Clone)] @@ -71,7 +72,8 @@ pub enum Message { Panel(pages::panel::Message), Layouts(pages::layouts::Message), ColorSchemes(Box), - OpenSaveDialog, + OpenSaveCurrentColorScheme, + OpenSaveCurrentLayout, DialogUpdate(DialogPage), DialogComplete, DialogCancel, @@ -84,6 +86,7 @@ pub enum Message { Key(Modifiers, Key), Modifiers(Modifiers), SystemThemeModeChange, + SaveNewLayout(String), } #[derive(Debug, Clone, Eq, PartialEq)] @@ -193,27 +196,33 @@ impl Application for TweakTool { let spacing = cosmic::theme::active().cosmic().spacing; - let dialog = match dialog_page { - DialogPage::New(name) => widget::dialog(fl!("save-current-color-scheme")) - .primary_action( - widget::button::suggested(fl!("save")) - .on_press_maybe(Some(Message::DialogComplete)), - ) - .secondary_action( - widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), - ) - .control( - widget::column::with_children(vec![ - widget::text::body(fl!("color-scheme-name")).into(), - widget::text_input("", name.as_str()) - .id(self.dialog_text_input.clone()) - .on_input(move |name| Message::DialogUpdate(DialogPage::New(name))) - .into(), - ]) - .spacing(spacing.space_xxs), - ), + let text_input = match dialog_page { + DialogPage::SaveCurrentColorScheme(name) => widget::text_input("", name.as_str()) + .id(self.dialog_text_input.clone()) + .on_input(move |name| { + Message::DialogUpdate(DialogPage::SaveCurrentColorScheme(name)) + }), + DialogPage::SaveCurrentLayout(name) => widget::text_input("", name.as_str()) + .id(self.dialog_text_input.clone()) + .on_input(move |name| Message::DialogUpdate(DialogPage::SaveCurrentLayout(name))), }; + let dialog = widget::dialog(fl!("save-current-color-scheme")) + .primary_action( + widget::button::suggested(fl!("save")) + .on_press_maybe(Some(Message::DialogComplete)), + ) + .secondary_action( + widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), + ) + .control( + widget::column::with_children(vec![ + widget::text::body(fl!("color-scheme-name")).into(), + text_input.into(), + ]) + .spacing(spacing.space_xxs), + ); + Some(dialog.into()) } @@ -388,12 +397,15 @@ impl Application for TweakTool { .update(message) .map(cosmic::app::Message::App), ), - Message::Layouts(message) => { - commands.push(self.layouts.update(message).map(cosmic::app::Message::App)) - } + Message::Layouts(message) => match message { + pages::layouts::Message::OpenSaveDialog => { + commands.push(self.update(Message::OpenSaveCurrentLayout)) + } + _ => commands.push(self.layouts.update(message).map(cosmic::app::Message::App)), + }, Message::ColorSchemes(message) => match *message { pages::color_schemes::Message::SaveCurrentColorScheme(None) => { - commands.push(self.update(Message::OpenSaveDialog)) + commands.push(self.update(Message::OpenSaveCurrentColorScheme)) } pages::color_schemes::Message::OpenAvailableThemes => commands .push(self.update(Message::ToggleContextPage(ContextPage::AvailableThemes))), @@ -410,8 +422,17 @@ impl Application for TweakTool { pages::color_schemes::Message::SaveCurrentColorScheme(Some(name)), )))) } - Message::OpenSaveDialog => { - self.dialog_pages.push_back(DialogPage::New(String::new())); + Message::SaveNewLayout(name) => commands.push(self.update(Message::Layouts( + pages::layouts::Message::SaveCurrentLayout(name), + ))), + Message::OpenSaveCurrentColorScheme => { + self.dialog_pages + .push_back(DialogPage::SaveCurrentColorScheme(String::new())); + return widget::text_input::focus(self.dialog_text_input.clone()); + } + Message::OpenSaveCurrentLayout => { + self.dialog_pages + .push_back(DialogPage::SaveCurrentLayout(String::new())); return widget::text_input::focus(self.dialog_text_input.clone()); } Message::DialogUpdate(dialog_page) => { @@ -420,9 +441,12 @@ impl Application for TweakTool { Message::DialogComplete => { if let Some(dialog_page) = self.dialog_pages.pop_front() { match dialog_page { - DialogPage::New(name) => { + DialogPage::SaveCurrentColorScheme(name) => { commands.push(self.update(Message::SaveNewColorScheme(name))) } + DialogPage::SaveCurrentLayout(name) => { + commands.push(self.update(Message::SaveNewLayout(name))) + } } } } diff --git a/src/pages/layouts.rs b/src/pages/layouts.rs index 52f1b91..a167fa4 100644 --- a/src/pages/layouts.rs +++ b/src/pages/layouts.rs @@ -7,7 +7,7 @@ use cosmic::{ use cosmic_ext_config_templates::{generate_template, load_template}; use dirs::data_local_dir; -use crate::app::TweakTool; +use crate::{app::TweakTool, core::icons, fl}; pub mod config; pub mod factory; @@ -28,6 +28,7 @@ impl Default for Layouts { #[derive(Debug, Clone)] pub enum Message { SelectLayout(Layout), + OpenSaveDialog, SaveCurrentLayout(String), } @@ -48,32 +49,59 @@ impl Layouts { }) .collect::>>(); - widget::scrollable( - widget::settings::section().title("Layouts").add( - widget::flex_row(layouts) - .row_spacing(spacing.space_s) - .column_spacing(spacing.space_s) - .apply(widget::container) - .padding([0, spacing.space_xxs]), - ), - ) + widget::scrollable(widget::column::with_children(vec![ + widget::row::with_children(vec![ + widget::text::title3(fl!("layouts")).into(), + widget::horizontal_space().into(), + widget::tooltip::tooltip( + icons::get_handle("arrow-into-box-symbolic", 16) + .apply(widget::button::icon) + .padding(spacing.space_xxs) + .on_press(Message::OpenSaveDialog) + .class(cosmic::style::Button::Standard), + widget::text(fl!("save-current-layout")), + widget::tooltip::Position::Bottom, + ) + .into(), + ]) + .spacing(spacing.space_xxs) + .into(), + widget::settings::section() + .title("Default") + .add( + widget::flex_row(layouts) + .row_spacing(spacing.space_s) + .column_spacing(spacing.space_s) + .apply(widget::container) + .padding([0, spacing.space_xxs]), + ) + .into(), + ])) .into() } pub fn update(&mut self, message: Message) -> Task { + let mut commands = vec![]; match message { Message::SelectLayout(layout) => { if let Err(e) = load_template(layout.schema().clone()) { eprintln!("Failed to load template: {}", e); } } + Message::OpenSaveDialog => commands.push(self.update(Message::OpenSaveDialog)), Message::SaveCurrentLayout(name) => { let path = data_local_dir() .unwrap() - .join("cosmic") .join(TweakTool::APP_ID) - .join("layouts") - .join(&name); + .join("layouts"); + + if !path.exists() { + if let Err(e) = std::fs::create_dir_all(&path) { + log::error!("{e}"); + } + } + let mut path = path.join(&name); + path.set_extension("ron"); let config_dirs = vec![ PathBuf::from("com.system76.CosmicPanel"), PathBuf::from("com.system76.CosmicPanel.Dock"), @@ -93,17 +121,17 @@ impl Layouts { match self.config.set_layouts(helper, layouts) { Ok(written) => { if !written { - eprintln!("Failed to write layouts to config"); + log::error!("Failed to write layouts to config"); } } - Err(e) => eprintln!("Failed to set layouts: {}", e), + Err(e) => log::error!("Failed to set layouts: {}", e), } } } - Err(e) => eprintln!("Failed to generate template: {}", e), + Err(e) => log::error!("Failed to generate template: {}", e), } } } - Task::none() + Task::batch(commands) } } From 94c045d0305e279d26eb85fba497bd2c06b0cfa7 Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Thu, 31 Oct 2024 13:15:25 +0100 Subject: [PATCH 4/7] improv: layout button styling --- src/app.rs | 1 + src/app/style.rs | 90 ++++++++++++++++++++++++++++++ src/pages/color_schemes/preview.rs | 84 ++-------------------------- src/pages/layouts/config.rs | 3 +- src/pages/layouts/factory.rs | 36 +++++++++--- 5 files changed, 128 insertions(+), 86 deletions(-) create mode 100644 src/app/style.rs diff --git a/src/app.rs b/src/app.rs index 50eab5d..ece1ee0 100644 --- a/src/app.rs +++ b/src/app.rs @@ -34,6 +34,7 @@ use crate::{ }; mod key_bind; +pub mod style; pub struct TweakTool { core: Core, diff --git a/src/app/style.rs b/src/app/style.rs new file mode 100644 index 0000000..f6a4b04 --- /dev/null +++ b/src/app/style.rs @@ -0,0 +1,90 @@ +use cosmic::{ + cosmic_theme::Theme, + iced::{Background, Border, Color}, + iced_core::Shadow, + widget::{self, button, container}, +}; + +pub fn background<'a>(theme: Theme) -> cosmic::theme::Container<'a> { + let corner_radii = cosmic::theme::active().cosmic().corner_radii; + cosmic::theme::Container::custom(move |_| container::Style { + icon_color: Some(Color::from(theme.background.on)), + text_color: Some(Color::from(theme.background.on)), + background: Some(cosmic::iced::Background::Color( + theme.background.base.into(), + )), + border: Border { + radius: corner_radii.radius_xs.into(), + ..Default::default() + }, + shadow: Shadow::default(), + }) +} + +pub fn card<'a>(theme: Theme) -> cosmic::theme::Container<'a> { + let theme = theme.clone(); + let corner_radii = cosmic::theme::active().cosmic().corner_radii; + + cosmic::theme::Container::custom(move |_| container::Style { + icon_color: Some(Color::from(theme.primary.component.on)), + text_color: Some(Color::from(theme.primary.component.on)), + background: Some(cosmic::iced::Background::Color( + theme.primary.component.base.into(), + )), + border: Border { + radius: corner_radii.radius_s.into(), + ..Default::default() + }, + shadow: Shadow::default(), + }) +} + +pub fn panel_style(theme: &cosmic::Theme) -> widget::container::Style { + let theme = theme.cosmic(); + cosmic::widget::container::Style { + icon_color: Some(Color::from(theme.background.on)), + text_color: Some(Color::from(theme.background.on)), + background: Some(Background::Color(theme.background.base.into())), + border: Border { + radius: theme.corner_radii.radius_0.into(), + ..Default::default() + }, + shadow: Shadow::default(), + } +} + +#[allow(dead_code)] +pub fn standard_button(theme: Theme) -> cosmic::theme::Button { + let active_theme = theme.clone(); + let disabled_theme = theme.clone(); + let hovered_theme = theme.clone(); + let pressed_theme = theme.clone(); + let _corner_radii = cosmic::theme::active().cosmic().corner_radii; + + cosmic::theme::Button::Custom { + active: Box::new(move |_active, _cosmic| button::Style { + background: Some(cosmic::iced_core::Background::Color( + active_theme.on_accent_color().into(), + )), + ..Default::default() + }), + disabled: Box::new(move |_cosmic| button::Style { + background: Some(cosmic::iced_core::Background::Color( + disabled_theme.on_accent_color().into(), + )), + ..Default::default() + }), + hovered: Box::new(move |_hovered, _cosmic| button::Style { + background: Some(cosmic::iced_core::Background::Color( + hovered_theme.on_accent_color().into(), + )), + ..Default::default() + }), + pressed: Box::new(move |_pressed, _cosmic| button::Style { + background: Some(cosmic::iced_core::Background::Color( + pressed_theme.on_accent_color().into(), + )), + ..Default::default() + }), + } +} diff --git a/src/pages/color_schemes/preview.rs b/src/pages/color_schemes/preview.rs index 195c45b..f8cdd40 100644 --- a/src/pages/color_schemes/preview.rs +++ b/src/pages/color_schemes/preview.rs @@ -1,9 +1,7 @@ use crate::fl; use cosmic::{ - cosmic_theme::Theme, - iced::{Alignment, Border, Color, Length}, - iced_core::Shadow, - widget::{self, button, container, tooltip}, + iced::{Alignment, Length}, + widget::{self, tooltip}, Apply, Element, }; @@ -32,7 +30,7 @@ pub fn installed<'a>( .padding(spacing.space_xxs) .width(Length::Fixed(100.0)) .height(Length::Fill) - .class(card(theme.clone())) + .class(crate::app::style::card(theme.clone())) .into(), widget::horizontal_space().into(), widget::tooltip::tooltip( @@ -64,7 +62,7 @@ pub fn installed<'a>( .width(Length::Fixed(200.0)) .height(Length::Fixed(160.0)) .apply(widget::container) - .class(background(theme.clone())), + .class(crate::app::style::background(theme.clone())), ) .selected(selected.name == color_scheme.name) .class(cosmic::style::Button::Image) @@ -94,7 +92,7 @@ pub fn available<'a>(color_scheme: &ColorScheme) -> Element<'a, crate::app::Mess .padding(spacing.space_xxs) .width(Length::Fixed(100.0)) .height(Length::Fill) - .class(card(theme.clone())) + .class(crate::app::style::card(theme.clone())) .into(), widget::horizontal_space().into(), widget::tooltip::tooltip( @@ -129,7 +127,7 @@ pub fn available<'a>(color_scheme: &ColorScheme) -> Element<'a, crate::app::Mess ]) .height(Length::Fixed(160.0)) .apply(widget::container) - .class(background(theme.clone())), + .class(crate::app::style::background(theme.clone())), ) .class(cosmic::style::Button::Image) .on_press(crate::app::Message::ColorSchemes(Box::new( @@ -137,73 +135,3 @@ pub fn available<'a>(color_scheme: &ColorScheme) -> Element<'a, crate::app::Mess ))) .into() } - -pub fn background<'a>(theme: Theme) -> cosmic::theme::Container<'a> { - let corner_radii = cosmic::theme::active().cosmic().corner_radii; - cosmic::theme::Container::custom(move |_| container::Style { - icon_color: Some(Color::from(theme.background.on)), - text_color: Some(Color::from(theme.background.on)), - background: Some(cosmic::iced::Background::Color( - theme.background.base.into(), - )), - border: Border { - radius: corner_radii.radius_xs.into(), - ..Default::default() - }, - shadow: Shadow::default(), - }) -} - -pub fn card<'a>(theme: Theme) -> cosmic::theme::Container<'a> { - let theme = theme.clone(); - let corner_radii = cosmic::theme::active().cosmic().corner_radii; - - cosmic::theme::Container::custom(move |_| container::Style { - icon_color: Some(Color::from(theme.primary.component.on)), - text_color: Some(Color::from(theme.primary.component.on)), - background: Some(cosmic::iced::Background::Color( - theme.primary.component.base.into(), - )), - border: Border { - radius: corner_radii.radius_s.into(), - ..Default::default() - }, - shadow: Shadow::default(), - }) -} - -#[allow(dead_code)] -pub fn standard_button(theme: Theme) -> cosmic::theme::Button { - let active_theme = theme.clone(); - let disabled_theme = theme.clone(); - let hovered_theme = theme.clone(); - let pressed_theme = theme.clone(); - let _corner_radii = cosmic::theme::active().cosmic().corner_radii; - - cosmic::theme::Button::Custom { - active: Box::new(move |_active, _cosmic| button::Style { - background: Some(cosmic::iced_core::Background::Color( - active_theme.on_accent_color().into(), - )), - ..Default::default() - }), - disabled: Box::new(move |_cosmic| button::Style { - background: Some(cosmic::iced_core::Background::Color( - disabled_theme.on_accent_color().into(), - )), - ..Default::default() - }), - hovered: Box::new(move |_hovered, _cosmic| button::Style { - background: Some(cosmic::iced_core::Background::Color( - hovered_theme.on_accent_color().into(), - )), - ..Default::default() - }), - pressed: Box::new(move |_pressed, _cosmic| button::Style { - background: Some(cosmic::iced_core::Background::Color( - pressed_theme.on_accent_color().into(), - )), - ..Default::default() - }), - } -} diff --git a/src/pages/layouts/config.rs b/src/pages/layouts/config.rs index 26efe2a..c8f1672 100644 --- a/src/pages/layouts/config.rs +++ b/src/pages/layouts/config.rs @@ -108,8 +108,9 @@ impl Layout { ), }; - widget::button::custom(layout.render()) + widget::button::custom(layout.view()) .on_press(Message::SelectLayout(self.clone())) + .class(cosmic::style::Button::Image) .into() } diff --git a/src/pages/layouts/factory.rs b/src/pages/layouts/factory.rs index 31c7c03..84998f4 100644 --- a/src/pages/layouts/factory.rs +++ b/src/pages/layouts/factory.rs @@ -4,7 +4,7 @@ use cosmic::{ Length, }, widget::{self, horizontal_space, vertical_space}, - Element, + Apply, Element, }; use super::Message; @@ -56,14 +56,14 @@ impl LayoutPreview { } } - pub fn render<'a>(&self) -> Element<'a, Message> { + pub fn view<'a>(&self) -> Element<'a, Message> { let column = widget::column().width(188).height(98); let row = widget::row().width(188).height(98); let spacing = cosmic::theme::active().cosmic().spacing; - let panel = widget::container(widget::text("")).class(cosmic::style::Container::Background); + let panel = widget::container(widget::text("")); - let container: Element<_> = match (self.panel, self.dock) { + let content: Element<_> = match (self.panel, self.dock) { (None, None) => column.into(), (None, Some(dock_props)) => { let extend_dock = if dock_props.extend { @@ -93,7 +93,11 @@ impl LayoutPreview { .align_x(Horizontal::Center) .align_y(Vertical::Center) .padding(5) - .class(cosmic::style::Container::Background); + .class(if dock_props.extend { + cosmic::style::Container::custom(crate::app::style::panel_style) + } else { + cosmic::style::Container::Background + }); match dock_props.position { Position::Top => column @@ -114,6 +118,11 @@ impl LayoutPreview { } } (Some(panel_props), None) => { + let panel = panel.class(if panel_props.extend { + cosmic::style::Container::custom(crate::app::style::panel_style) + } else { + cosmic::style::Container::Background + }); let extend_panel = if panel_props.extend { Length::Fill } else { @@ -141,6 +150,11 @@ impl LayoutPreview { } } (Some(panel_props), Some(dock_props)) => { + let panel = panel.class(if panel_props.extend { + cosmic::style::Container::custom(crate::app::style::panel_style) + } else { + cosmic::style::Container::Background + }); let extend_panel = if panel_props.extend { Length::Fill } else { @@ -173,7 +187,11 @@ impl LayoutPreview { .align_x(Horizontal::Center) .align_y(Vertical::Center) .padding(5) - .class(cosmic::style::Container::Background); + .class(if dock_props.extend { + cosmic::style::Container::custom(crate::app::style::panel_style) + } else { + cosmic::style::Container::Background + }); match (panel_props.position, dock_props.position) { (Position::Top, Position::Top) => column @@ -303,7 +321,11 @@ impl LayoutPreview { } }; - container.into() + content + .apply(widget::container) + .class(cosmic::style::Container::Secondary) + .padding(spacing.space_xxxs) + .into() } } From ce73f2d9169ca6fe52cc05d3cc513ac2f0e66d54 Mon Sep 17 00:00:00 2001 From: Ryan Brue Date: Thu, 31 Oct 2024 16:05:57 -0500 Subject: [PATCH 5/7] chore: update cosmic-ext-config-templates this commit fixes concurrency issues with cosmic-panel when loading a panel template Signed-off-by: Ryan Brue --- Cargo.lock | 128 +++++++++++++++++---- res/layouts/cosmic.ron | 243 +++++++++++++--------------------------- res/layouts/mac.ron | 227 ++++++++++++------------------------- res/layouts/ubuntu.ron | 243 +++++++++++++--------------------------- res/layouts/windows.ron | 206 +++++++++------------------------- src/pages/layouts.rs | 14 +-- 6 files changed, 389 insertions(+), 672 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c61367..4b37534 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1076,15 +1076,33 @@ dependencies = [ "libc", ] +[[package]] +name = "cosmic-config" +version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic.git?branch=master#4b562867eccb65895953023a19393fa293aafb4b" +dependencies = [ + "atomicwrites", + "cosmic-config-derive 0.1.0 (git+https://github.com/pop-os/libcosmic.git?branch=master)", + "dirs", + "iced_futures 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git?branch=master)", + "known-folders", + "notify", + "once_cell", + "ron", + "serde", + "tracing", + "xdg", +] + [[package]] name = "cosmic-config" version = "0.1.0" source = "git+https://github.com/pop-os/libcosmic.git#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "atomicwrites", - "cosmic-config-derive", + "cosmic-config-derive 0.1.0 (git+https://github.com/pop-os/libcosmic.git)", "dirs", - "iced_futures", + "iced_futures 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", "known-folders", "notify", "once_cell", @@ -1095,6 +1113,15 @@ dependencies = [ "xdg", ] +[[package]] +name = "cosmic-config-derive" +version = "0.1.0" +source = "git+https://github.com/pop-os/libcosmic.git?branch=master#4b562867eccb65895953023a19393fa293aafb4b" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "cosmic-config-derive" version = "0.1.0" @@ -1106,11 +1133,13 @@ dependencies = [ [[package]] name = "cosmic-ext-config-templates" -version = "1.1.0" -source = "git+https://github.com/ryanabx/cosmic-ext-config-templates#a2aac2134a4db8d8bcedc1a0027f1f90bc6a5654" +version = "2.0.0" +source = "git+https://github.com/ryanabx/cosmic-ext-config-templates#5e2ab667aa5a70ce4a63405e0e54369cc257a38a" dependencies = [ "anyhow", "clap", + "cosmic-config 0.1.0 (git+https://github.com/pop-os/libcosmic.git?branch=master)", + "cosmic-panel-config 0.1.0 (git+https://github.com/pop-os/cosmic-panel?branch=master)", "env_logger 0.11.5", "log", "ron", @@ -1125,7 +1154,7 @@ dependencies = [ "anyhow", "ashpd 0.8.1", "cosmic-ext-config-templates", - "cosmic-panel-config", + "cosmic-panel-config 0.1.0 (git+https://github.com/pop-os/cosmic-panel)", "dirs", "env_logger 0.11.5", "i18n-embed", @@ -1144,19 +1173,34 @@ dependencies = [ "vergen", ] +[[package]] +name = "cosmic-panel-config" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-panel?branch=master#041a44eb6f825b7e0b3d45ccf745252b136d5da9" +dependencies = [ + "anyhow", + "cosmic-config 0.1.0 (git+https://github.com/pop-os/libcosmic.git)", + "ron", + "serde", + "smithay-client-toolkit", + "tracing", + "wayland-protocols-wlr", + "xdg-shell-wrapper-config 0.1.0 (git+https://github.com/pop-os/cosmic-panel?branch=master)", +] + [[package]] name = "cosmic-panel-config" version = "0.1.0" source = "git+https://github.com/pop-os/cosmic-panel#041a44eb6f825b7e0b3d45ccf745252b136d5da9" dependencies = [ "anyhow", - "cosmic-config", + "cosmic-config 0.1.0 (git+https://github.com/pop-os/libcosmic.git)", "ron", "serde", "smithay-client-toolkit", "tracing", "wayland-protocols-wlr", - "xdg-shell-wrapper-config", + "xdg-shell-wrapper-config 0.1.0 (git+https://github.com/pop-os/cosmic-panel)", ] [[package]] @@ -1188,7 +1232,7 @@ version = "0.1.0" source = "git+https://github.com/pop-os/libcosmic.git#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "almost", - "cosmic-config", + "cosmic-config 0.1.0 (git+https://github.com/pop-os/libcosmic.git)", "csscolorparser", "dirs", "lazy_static", @@ -2564,8 +2608,8 @@ source = "git+https://github.com/pop-os/libcosmic.git#4b562867eccb65895953023a19 dependencies = [ "dnd", "iced_accessibility", - "iced_core", - "iced_futures", + "iced_core 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", + "iced_futures 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", "iced_renderer", "iced_widget", "iced_winit", @@ -2584,6 +2628,28 @@ dependencies = [ "accesskit_winit", ] +[[package]] +name = "iced_core" +version = "0.14.0-dev" +source = "git+https://github.com/pop-os/libcosmic.git?branch=master#4b562867eccb65895953023a19393fa293aafb4b" +dependencies = [ + "bitflags 2.6.0", + "bytes", + "dnd", + "glam", + "log", + "mime 0.1.0", + "num-traits", + "once_cell", + "palette", + "raw-window-handle", + "rustc-hash 2.0.0", + "smol_str", + "thiserror", + "web-time", + "window_clipboard", +] + [[package]] name = "iced_core" version = "0.14.0-dev" @@ -2607,13 +2673,26 @@ dependencies = [ "window_clipboard", ] +[[package]] +name = "iced_futures" +version = "0.14.0-dev" +source = "git+https://github.com/pop-os/libcosmic.git?branch=master#4b562867eccb65895953023a19393fa293aafb4b" +dependencies = [ + "futures", + "iced_core 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git?branch=master)", + "log", + "rustc-hash 2.0.0", + "wasm-bindgen-futures", + "wasm-timer", +] + [[package]] name = "iced_futures" version = "0.14.0-dev" source = "git+https://github.com/pop-os/libcosmic.git#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "futures", - "iced_core", + "iced_core 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", "log", "rustc-hash 2.0.0", "tokio", @@ -2642,8 +2721,8 @@ dependencies = [ "bytemuck", "cosmic-text", "half", - "iced_core", - "iced_futures", + "iced_core 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", + "iced_futures 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", "image", "kamadak-exif", "log", @@ -2674,8 +2753,8 @@ source = "git+https://github.com/pop-os/libcosmic.git#4b562867eccb65895953023a19 dependencies = [ "bytes", "dnd", - "iced_core", - "iced_futures", + "iced_core 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", + "iced_futures 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", "raw-window-handle", "thiserror", "window_clipboard", @@ -2751,7 +2830,7 @@ version = "0.14.0-dev" source = "git+https://github.com/pop-os/libcosmic.git#4b562867eccb65895953023a19393fa293aafb4b" dependencies = [ "dnd", - "iced_futures", + "iced_futures 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", "iced_graphics", "iced_runtime", "log", @@ -3096,15 +3175,15 @@ dependencies = [ "apply", "ashpd 0.9.1", "chrono", - "cosmic-config", + "cosmic-config 0.1.0 (git+https://github.com/pop-os/libcosmic.git)", "cosmic-theme", "css-color", "derive_setters", "fraction", "freedesktop-icons", "iced", - "iced_core", - "iced_futures", + "iced_core 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", + "iced_futures 0.14.0-dev (git+https://github.com/pop-os/libcosmic.git)", "iced_renderer", "iced_runtime", "iced_tiny_skia", @@ -3133,7 +3212,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -6737,6 +6816,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "xdg-shell-wrapper-config" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-panel?branch=master#041a44eb6f825b7e0b3d45ccf745252b136d5da9" +dependencies = [ + "serde", + "wayland-protocols-wlr", +] + [[package]] name = "xdg-shell-wrapper-config" version = "0.1.0" diff --git a/res/layouts/cosmic.ron b/res/layouts/cosmic.ron index dfc8ba2..c4eb65b 100644 --- a/res/layouts/cosmic.ron +++ b/res/layouts/cosmic.ron @@ -1,164 +1,79 @@ -( - overrides: [ - ( - path: "com.system76.CosmicPanel/v1/entries", - setting: "[\n \"Panel\",\n \"Dock\",\n]", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/anchor_gap", - setting: "false", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/layer", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/border_radius", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/padding", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/margin", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/opacity", - setting: "1.0", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/output", - setting: "All", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", - setting: "OnDemand", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/anchor", - setting: "Bottom", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/size", - setting: "L", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/plugins_wings", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/autohide", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/expand_to_edges", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/spacing", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/name", - setting: "\"Dock\"", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/background", - setting: "ThemeDefault", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/plugins_center", - setting: "Some([\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicAppletMinimize\",\n])", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", - setting: "false", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/layer", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/border_radius", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/padding", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/margin", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/opacity", - setting: "1.0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/output", - setting: "All", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/keyboard_interactivity", - setting: "OnDemand", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/anchor", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/size", - setting: "XS", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/plugins_wings", - setting: "Some(([\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n], [\n \"com.system76.CosmicAppletInputSources\",\n \"com.system76.CosmicAppletStatusArea\",\n \"com.system76.CosmicAppletTiling\",\n \"com.system76.CosmicAppletAudio\",\n \"com.system76.CosmicAppletNetwork\",\n \"com.system76.CosmicAppletBattery\",\n \"com.system76.CosmicAppletNotifications\",\n \"com.system76.CosmicAppletBluetooth\",\n \"com.system76.CosmicAppletPower\",\n]))", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/autohide", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/expand_to_edges", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/spacing", - setting: "2", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/name", - setting: "\"Panel\"", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/background", - setting: "ThemeDefault", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/plugins_center", - setting: "Some([\n \"com.system76.CosmicAppletTime\",\n])", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/size_center", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/size_wings", - setting: "Some([\n None,\n Some(()),\n])", - ), - ( - path: "com.system76.CosmicPanelButton/v1/configs", - setting: "{\n \"Dock\": (\n force_presentation: Some(Icon),\n ),\n \"Panel\": (\n force_presentation: None,\n ),\n}", - ), - ], -) +Panel(( + panel_config: ( + config_list: [ + ( + name: "Panel", + anchor: Top, + anchor_gap: false, + layer: Top, + keyboard_interactivity: OnDemand, + size: XS, + output: All, + background: ThemeDefault, + plugins_wings: Some(([ + "com.system76.CosmicPanelWorkspacesButton", + "com.system76.CosmicPanelAppButton", + ], [ + "com.system76.CosmicAppletInputSources", + "com.system76.CosmicAppletStatusArea", + "com.system76.CosmicAppletTiling", + "com.system76.CosmicAppletAudio", + "com.system76.CosmicAppletNetwork", + "com.system76.CosmicAppletBattery", + "com.system76.CosmicAppletNotifications", + "com.system76.CosmicAppletBluetooth", + "com.system76.CosmicAppletPower", + ])), + plugins_center: Some([ + "com.system76.CosmicAppletTime", + ]), + expand_to_edges: true, + padding: 0, + spacing: 2, + border_radius: 0, + exclusive_zone: true, + autohide: None, + margin: 0, + opacity: 1.0, + ), + ( + name: "Dock", + anchor: Bottom, + anchor_gap: false, + layer: Top, + keyboard_interactivity: OnDemand, + size: L, + output: All, + background: ThemeDefault, + plugins_wings: None, + plugins_center: Some([ + "com.system76.CosmicPanelLauncherButton", + "com.system76.CosmicPanelWorkspacesButton", + "com.system76.CosmicPanelAppButton", + "com.system76.CosmicAppList", + "com.system76.CosmicAppletMinimize", + ]), + expand_to_edges: true, + padding: 0, + spacing: 4, + border_radius: 0, + exclusive_zone: true, + autohide: None, + margin: 0, + opacity: 1.0, + ), + ], + ), + panel_config_version: 1, + panel_button_config: ( + configs: { + "Dock": ( + force_presentation: Some(Icon), + ), + "Panel": ( + force_presentation: None, + ), + }, + ), + panel_button_config_version: 1, +)) \ No newline at end of file diff --git a/res/layouts/mac.ron b/res/layouts/mac.ron index 01f7df5..61c7305 100644 --- a/res/layouts/mac.ron +++ b/res/layouts/mac.ron @@ -1,156 +1,71 @@ -( - overrides: [ - ( - path: "com.system76.CosmicPanel/v1/entries", - setting: "[\n \"Panel\",\n \"Dock\",\n]", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/anchor_gap", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/layer", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/border_radius", - setting: "8", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/padding", - setting: "6", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/margin", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/opacity", - setting: "1.0", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/output", - setting: "All", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", - setting: "OnDemand", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/anchor", - setting: "Bottom", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/size", - setting: "S", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/plugins_wings", - setting: "Some(([], []))", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/autohide", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/expand_to_edges", - setting: "false", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/spacing", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/name", - setting: "\"Dock\"", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/background", - setting: "ThemeDefault", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/plugins_center", - setting: "Some([\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppletMinimize\",\n])", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", - setting: "false", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/layer", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/border_radius", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/padding", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/margin", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/opacity", - setting: "0.91", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/output", - setting: "All", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/keyboard_interactivity", - setting: "OnDemand", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/anchor", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/size", - setting: "XS", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/plugins_wings", - setting: "Some(([\n \"com.system76.CosmicAppletPower\",\n], [\n \"com.system76.CosmicAppletStatusArea\",\n \"com.system76.CosmicAppletBattery\",\n \"com.system76.CosmicAppletNetwork\",\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicAppletNotifications\",\n \"com.system76.CosmicAppletTime\",\n]))", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/autohide", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/expand_to_edges", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/spacing", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/name", - setting: "\"Panel\"", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/background", - setting: "ThemeDefault", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/plugins_center", - setting: "Some([])", - ), - ( - path: "com.system76.CosmicPanelButton/v1/configs", - setting: "{\n \"Dock\": (\n force_presentation: Some(Icon),\n ),\n \"Panel\": (\n force_presentation: Some(Icon),\n ),\n}", - ), - ], -) \ No newline at end of file +Panel(( + panel_config: ( + config_list: [ + ( + name: "Panel", + anchor: Top, + anchor_gap: false, + layer: Top, + keyboard_interactivity: OnDemand, + size: XS, + output: All, + background: ThemeDefault, + plugins_wings: Some(([ + "com.system76.CosmicAppletPower", + ], [ + "com.system76.CosmicAppletStatusArea", + "com.system76.CosmicAppletBattery", + "com.system76.CosmicAppletNetwork", + "com.system76.CosmicPanelLauncherButton", + "com.system76.CosmicAppletNotifications", + "com.system76.CosmicAppletTime", + ])), + plugins_center: Some([]), + expand_to_edges: true, + padding: 4, + spacing: 4, + border_radius: 0, + exclusive_zone: true, + autohide: None, + margin: 0, + opacity: 0.91, + ), + ( + name: "Dock", + anchor: Bottom, + anchor_gap: true, + layer: Top, + keyboard_interactivity: OnDemand, + size: S, + output: All, + background: ThemeDefault, + plugins_wings: Some(([], [])), + plugins_center: Some([ + "com.system76.CosmicAppList", + "com.system76.CosmicPanelAppButton", + "com.system76.CosmicAppletMinimize", + ]), + expand_to_edges: false, + padding: 6, + spacing: 4, + border_radius: 8, + exclusive_zone: true, + autohide: None, + margin: 4, + opacity: 1.0, + ), + ], + ), + panel_config_version: 1, + panel_button_config: ( + configs: { + "Panel": ( + force_presentation: Some(Icon), + ), + "Dock": ( + force_presentation: Some(Icon), + ), + }, + ), + panel_button_config_version: 1, +)) \ No newline at end of file diff --git a/res/layouts/ubuntu.ron b/res/layouts/ubuntu.ron index 3977140..8b25592 100644 --- a/res/layouts/ubuntu.ron +++ b/res/layouts/ubuntu.ron @@ -1,164 +1,79 @@ -( - overrides: [ - ( - path: "com.system76.CosmicPanel/v1/entries", - setting: "[\n \"Panel\",\n \"Dock\",\n]", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/name", - setting: "\"Dock\"", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/anchor", - setting: "Left", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/anchor_gap", - setting: "false", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/layer", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", - setting: "OnDemand", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/size", - setting: "M", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/output", - setting: "All", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/background", - setting: "ThemeDefault", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/plugins_wings", - setting: "Some(([\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicAppletMinimize\",\n], []))", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/plugins_center", - setting: "Some([])", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/expand_to_edges", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/padding", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/spacing", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/border_radius", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/autohide", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/margin", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/opacity", - setting: "1.0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/size_wings", - setting: "Some([\n None,\n Some(()),\n])", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/size_center", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/name", - setting: "\"Panel\"", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/anchor", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", - setting: "false", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/layer", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/keyboard_interactivity", - setting: "OnDemand", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/size", - setting: "XS", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/output", - setting: "All", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/background", - setting: "ThemeDefault", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/plugins_wings", - setting: "Some(([\n \"com.system76.CosmicPanelWorkspacesButton\",\n \"com.system76.CosmicPanelAppButton\",\n], [\n \"com.system76.CosmicAppletInputSources\",\n \"com.system76.CosmicAppletStatusArea\",\n \"com.system76.CosmicAppletTiling\",\n \"com.system76.CosmicAppletAudio\",\n \"com.system76.CosmicAppletNetwork\",\n \"com.system76.CosmicAppletBattery\",\n \"com.system76.CosmicAppletNotifications\",\n \"com.system76.CosmicAppletBluetooth\",\n \"com.system76.CosmicAppletPower\",\n]))", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/plugins_center", - setting: "Some([\n \"com.system76.CosmicAppletTime\",\n])", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/expand_to_edges", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/padding", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/spacing", - setting: "2", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/border_radius", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/autohide", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/margin", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/opacity", - setting: "1.0", - ), - ( - path: "com.system76.CosmicPanelButton/v1/configs", - setting: "{\n \"Dock\": (\n force_presentation: Some(Icon),\n ),\n \"Panel\": (\n force_presentation: None,\n ),\n}", - ), - ], -) \ No newline at end of file +Panel(( + panel_config: ( + config_list: [ + ( + name: "Panel", + anchor: Top, + anchor_gap: false, + layer: Top, + keyboard_interactivity: OnDemand, + size: XS, + output: All, + background: ThemeDefault, + plugins_wings: Some(([ + "com.system76.CosmicPanelWorkspacesButton", + "com.system76.CosmicPanelAppButton", + ], [ + "com.system76.CosmicAppletInputSources", + "com.system76.CosmicAppletStatusArea", + "com.system76.CosmicAppletTiling", + "com.system76.CosmicAppletAudio", + "com.system76.CosmicAppletNetwork", + "com.system76.CosmicAppletBattery", + "com.system76.CosmicAppletNotifications", + "com.system76.CosmicAppletBluetooth", + "com.system76.CosmicAppletPower", + ])), + plugins_center: Some([ + "com.system76.CosmicAppletTime", + ]), + expand_to_edges: true, + padding: 0, + spacing: 2, + border_radius: 0, + exclusive_zone: true, + autohide: None, + margin: 0, + opacity: 1.0, + ), + ( + name: "Dock", + anchor: Left, + anchor_gap: false, + layer: Top, + keyboard_interactivity: OnDemand, + size: M, + output: All, + background: ThemeDefault, + plugins_wings: Some(([ + "com.system76.CosmicPanelLauncherButton", + "com.system76.CosmicPanelWorkspacesButton", + "com.system76.CosmicPanelAppButton", + "com.system76.CosmicAppList", + "com.system76.CosmicAppletMinimize", + ], [])), + plugins_center: Some([]), + expand_to_edges: true, + padding: 0, + spacing: 4, + border_radius: 0, + exclusive_zone: true, + autohide: None, + margin: 0, + opacity: 1.0, + ), + ], + ), + panel_config_version: 1, + panel_button_config: ( + configs: { + "Panel": ( + force_presentation: None, + ), + "Dock": ( + force_presentation: Some(Icon), + ), + }, + ), + panel_button_config_version: 1, +)) \ No newline at end of file diff --git a/res/layouts/windows.ron b/res/layouts/windows.ron index 7562ca2..e50673f 100644 --- a/res/layouts/windows.ron +++ b/res/layouts/windows.ron @@ -1,156 +1,50 @@ -( - overrides: [ - ( - path: "com.system76.CosmicPanel/v1/entries", - setting: "[\n \"Panel\",\n]", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/anchor_gap", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/layer", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/border_radius", - setting: "8", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/padding", - setting: "6", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/margin", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/opacity", - setting: "1.0", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/exclusive_zone", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/output", - setting: "All", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/keyboard_interactivity", - setting: "OnDemand", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/anchor", - setting: "Bottom", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/size", - setting: "S", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/plugins_wings", - setting: "Some(([], []))", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/autohide", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/expand_to_edges", - setting: "false", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/spacing", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/name", - setting: "\"Dock\"", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/background", - setting: "ThemeDefault", - ), - ( - path: "com.system76.CosmicPanel.Dock/v1/plugins_center", - setting: "Some([\n \"com.system76.CosmicAppList\",\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicAppletMinimize\",\n])", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/anchor_gap", - setting: "false", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/layer", - setting: "Top", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/border_radius", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/padding", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/margin", - setting: "0", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/opacity", - setting: "0.91", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/exclusive_zone", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/output", - setting: "All", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/keyboard_interactivity", - setting: "OnDemand", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/anchor", - setting: "Bottom", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/size", - setting: "S", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/plugins_wings", - setting: "Some(([\n \"com.system76.CosmicAppletPower\",\n], [\n \"com.system76.CosmicAppletNetwork\",\n \"com.system76.CosmicAppletAudio\",\n \"com.system76.CosmicAppletBattery\",\n \"com.system76.CosmicAppletTime\",\n \"com.system76.CosmicAppletNotifications\",\n]))", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/autohide", - setting: "None", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/expand_to_edges", - setting: "true", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/spacing", - setting: "4", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/name", - setting: "\"Panel\"", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/background", - setting: "ThemeDefault", - ), - ( - path: "com.system76.CosmicPanel.Panel/v1/plugins_center", - setting: "Some([\n \"com.system76.CosmicPanelAppButton\",\n \"com.system76.CosmicPanelLauncherButton\",\n \"com.system76.CosmicAppList\",\n])", - ), - ( - path: "com.system76.CosmicPanelButton/v1/configs", - setting: "{\n \"Dock\": (\n force_presentation: Some(Icon),\n ),\n \"Panel\": (\n force_presentation: Some(Icon),\n ),\n}", - ), - ], -) \ No newline at end of file +Panel(( + panel_config: ( + config_list: [ + ( + name: "Panel", + anchor: Bottom, + anchor_gap: false, + layer: Top, + keyboard_interactivity: OnDemand, + size: S, + output: All, + background: ThemeDefault, + plugins_wings: Some(([ + "com.system76.CosmicAppletPower", + ], [ + "com.system76.CosmicAppletNetwork", + "com.system76.CosmicAppletAudio", + "com.system76.CosmicAppletBattery", + "com.system76.CosmicAppletTime", + "com.system76.CosmicAppletNotifications", + ])), + plugins_center: Some([ + "com.system76.CosmicPanelAppButton", + "com.system76.CosmicPanelLauncherButton", + "com.system76.CosmicAppList", + ]), + expand_to_edges: true, + padding: 4, + spacing: 4, + border_radius: 0, + exclusive_zone: true, + autohide: None, + margin: 0, + opacity: 0.91, + ), + ], + ), + panel_config_version: 1, + panel_button_config: ( + configs: { + "Dock": ( + force_presentation: Some(Icon), + ), + "Panel": ( + force_presentation: Some(Icon), + ), + }, + ), + panel_button_config_version: 1, +)) \ No newline at end of file diff --git a/src/pages/layouts.rs b/src/pages/layouts.rs index a167fa4..7b7b66a 100644 --- a/src/pages/layouts.rs +++ b/src/pages/layouts.rs @@ -4,7 +4,7 @@ use config::{CustomLayout, Layout, LayoutsConfig}; use cosmic::{ cosmic_config::Config, iced::alignment::Horizontal, widget, Application, Apply, Element, Task, }; -use cosmic_ext_config_templates::{generate_template, load_template}; +use cosmic_ext_config_templates::{load_template, panel::PanelSchema, Schema}; use dirs::data_local_dir; use crate::{app::TweakTool, core::icons, fl}; @@ -102,17 +102,7 @@ impl Layouts { } let mut path = path.join(&name); path.set_extension("ron"); - let config_dirs = vec![ - PathBuf::from("com.system76.CosmicPanel"), - PathBuf::from("com.system76.CosmicPanel.Dock"), - PathBuf::from("com.system76.CosmicPanel.Panel"), - PathBuf::from("com.system76.CosmicPanelButton"), - ]; - let config_dirs = config_dirs - .iter() - .map(|p| p.as_path()) - .collect::>(); - match generate_template(config_dirs, &path) { + match PanelSchema::generate().and_then(|panel_schema| Schema::Panel(panel_schema).save(&path)) { Ok(_) => { if let Some(helper) = &self.helper { let layout = CustomLayout::new(name, &path); From f1b10ecf09114a609931c651d90ef36eec0c98d9 Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Thu, 31 Oct 2024 23:03:21 +0100 Subject: [PATCH 6/7] improv: add delete option for custom layouts --- i18n/en/cosmic_ext_tweaks.ftl | 1 + src/app.rs | 14 ++-- src/pages/layouts.rs | 46 +++++++++++-- src/pages/layouts/config.rs | 70 ++++++++++++++------ src/pages/layouts/{factory.rs => preview.rs} | 1 + 5 files changed, 98 insertions(+), 34 deletions(-) rename src/pages/layouts/{factory.rs => preview.rs} (99%) diff --git a/i18n/en/cosmic_ext_tweaks.ftl b/i18n/en/cosmic_ext_tweaks.ftl index 3fc4766..6425c98 100644 --- a/i18n/en/cosmic_ext_tweaks.ftl +++ b/i18n/en/cosmic_ext_tweaks.ftl @@ -9,6 +9,7 @@ color-schemes = Color schemes color-schemes-error = Error loading color schemes import-color-scheme = Import color scheme delete-color-scheme = Delete color scheme +delete-layout = Delete layout install-color-scheme = Install color scheme find-color-schemes = Find color schemes open-containing-folder = Open containing folder diff --git a/src/app.rs b/src/app.rs index ece1ee0..a3319ab 100644 --- a/src/app.rs +++ b/src/app.rs @@ -117,8 +117,8 @@ impl Action for TweaksAction { type Message = Message; fn message(&self) -> Self::Message { match self { - Self::About => Message::ToggleContextPage(ContextPage::About), - Self::Settings => Message::ToggleContextPage(ContextPage::Settings), + TweaksAction::About => Message::ToggleContextPage(ContextPage::About), + TweaksAction::Settings => Message::ToggleContextPage(ContextPage::Settings), } } } @@ -332,9 +332,9 @@ impl Application for TweakTool { self.status = Status::LoadingMore; } self.limit = limit; - self.offset = self.offset + self.limit; - let limit = self.limit.clone(); - let offset = self.offset.clone(); + self.offset += self.limit; + let limit = self.limit; + let offset = self.offset; commands.push(Task::perform( async move { let url = match provider { @@ -625,8 +625,8 @@ impl TweakTool { widget::settings::view_column( loading .into_iter() - .chain(available.into_iter()) - .chain(show_more_button.into_iter()) + .chain(available) + .chain(show_more_button) .collect(), ) .into() diff --git a/src/pages/layouts.rs b/src/pages/layouts.rs index 7b7b66a..6cda33d 100644 --- a/src/pages/layouts.rs +++ b/src/pages/layouts.rs @@ -1,5 +1,3 @@ -use std::path::{Path, PathBuf}; - use config::{CustomLayout, Layout, LayoutsConfig}; use cosmic::{ cosmic_config::Config, iced::alignment::Horizontal, widget, Application, Apply, Element, Task, @@ -10,30 +8,37 @@ use dirs::data_local_dir; use crate::{app::TweakTool, core::icons, fl}; pub mod config; -pub mod factory; +pub mod preview; #[derive(Debug)] pub struct Layouts { pub helper: Option, pub config: LayoutsConfig, + selected_layout: Option, } impl Default for Layouts { fn default() -> Self { let (helper, config) = (LayoutsConfig::helper(), LayoutsConfig::config()); - Self { helper, config } + Self { + helper, + config, + selected_layout: None, + } } } #[derive(Debug, Clone)] pub enum Message { + ApplyLayout(Layout), SelectLayout(Layout), + DeleteLayout, OpenSaveDialog, SaveCurrentLayout(String), } impl Layouts { - pub fn view<'a>(&'a self) -> Element<'a, Message> { + pub fn view(&self) -> Element { let spacing = cosmic::theme::active().cosmic().spacing; let layouts = self .config @@ -83,11 +88,12 @@ impl Layouts { pub fn update(&mut self, message: Message) -> Task { let mut commands = vec![]; match message { - Message::SelectLayout(layout) => { + Message::ApplyLayout(layout) => { if let Err(e) = load_template(layout.schema().clone()) { eprintln!("Failed to load template: {}", e); } } + Message::SelectLayout(layout) => self.selected_layout = Some(layout), Message::OpenSaveDialog => commands.push(self.update(Message::OpenSaveDialog)), Message::SaveCurrentLayout(name) => { let path = data_local_dir() @@ -102,7 +108,9 @@ impl Layouts { } let mut path = path.join(&name); path.set_extension("ron"); - match PanelSchema::generate().and_then(|panel_schema| Schema::Panel(panel_schema).save(&path)) { + match PanelSchema::generate() + .and_then(|panel_schema| Schema::Panel(panel_schema).save(&path)) + { Ok(_) => { if let Some(helper) = &self.helper { let layout = CustomLayout::new(name, &path); @@ -121,6 +129,30 @@ impl Layouts { Err(e) => log::error!("Failed to generate template: {}", e), } } + Message::DeleteLayout => { + if let Some(layout) = &self.selected_layout { + if let Layout::Custom(existing_layout) = &layout { + if existing_layout.path().exists() { + if let Err(e) = std::fs::remove_file(existing_layout.path()) { + log::error!("Failed to delete layout: {}", e); + return Task::batch(commands); + } + } + let mut layouts = self.config.layouts.clone(); + layouts.retain(|l| l != layout); + if let Some(helper) = &self.helper { + match self.config.set_layouts(helper, layouts) { + Ok(written) => { + if !written { + log::error!("Failed to write layouts to config"); + } + } + Err(e) => log::error!("Failed to set layouts: {}", e), + } + } + } + } + } } Task::batch(commands) } diff --git a/src/pages/layouts/config.rs b/src/pages/layouts/config.rs index c8f1672..dcffe51 100644 --- a/src/pages/layouts/config.rs +++ b/src/pages/layouts/config.rs @@ -1,13 +1,17 @@ -use std::path::PathBuf; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; use super::{ - factory::{LayoutPreview, PanelProperties, Position}, + preview::{LayoutPreview, PanelProperties, Position}, Message, }; -use crate::{app::TweakTool, resources}; +use crate::{app::TweakTool, fl, resources}; use cosmic::{ cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, Config, CosmicConfigEntry}, - widget, Application, Element, + widget::{self, menu::Action}, + Application, Element, }; use cosmic_ext_config_templates::Schema; use serde::{Deserialize, Serialize}; @@ -44,6 +48,20 @@ impl LayoutsConfig { } } +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum LayoutsAction { + DeleteLayout, +} + +impl Action for LayoutsAction { + type Message = Message; + fn message(&self) -> Self::Message { + match self { + LayoutsAction::DeleteLayout => Message::DeleteLayout, + } + } +} + #[derive(Debug, Serialize, Clone, Deserialize, PartialEq)] pub enum Layout { Cosmic, @@ -54,16 +72,6 @@ pub enum Layout { } impl Layout { - pub fn file_name(&self) -> &str { - match self { - Layout::Cosmic => "cosmic", - Layout::Mac => "mac", - Layout::Windows => "windows", - Layout::Ubuntu => "ubuntu", - Layout::Custom(custom_layout) => &custom_layout.name, - } - } - pub fn name(&self) -> &str { match self { Layout::Cosmic => "COSMIC", @@ -108,10 +116,24 @@ impl Layout { ), }; - widget::button::custom(layout.view()) - .on_press(Message::SelectLayout(self.clone())) - .class(cosmic::style::Button::Image) - .into() + widget::mouse_area(widget::context_menu( + widget::button::custom(layout.view()) + .on_press(Message::ApplyLayout(self.clone())) + .class(cosmic::style::Button::Image), + if self.is_custom() { + Some(widget::menu::items( + &HashMap::new(), + vec![widget::menu::Item::Button( + fl!("delete-layout"), + LayoutsAction::DeleteLayout, + )], + )) + } else { + None + }, + )) + .on_right_press(Message::SelectLayout(self.clone())) + .into() } pub fn schema(&self) -> Schema { @@ -123,6 +145,10 @@ impl Layout { Layout::Custom(custom_layout) => Schema::from_file(&custom_layout.path).unwrap(), } } + + pub fn is_custom(&self) -> bool { + matches!(self, Layout::Custom(_)) + } } #[derive(Debug, Serialize, Clone, Default, Deserialize, PartialEq, CosmicConfigEntry)] @@ -132,10 +158,14 @@ pub struct CustomLayout { } impl CustomLayout { - pub fn new(name: String, path: &PathBuf) -> Self { + pub fn new(name: String, path: &Path) -> Self { Self { name, - path: path.clone(), + path: path.to_path_buf(), } } + + pub fn path(&self) -> &PathBuf { + &self.path + } } diff --git a/src/pages/layouts/factory.rs b/src/pages/layouts/preview.rs similarity index 99% rename from src/pages/layouts/factory.rs rename to src/pages/layouts/preview.rs index 84998f4..dc9f1c2 100644 --- a/src/pages/layouts/factory.rs +++ b/src/pages/layouts/preview.rs @@ -34,6 +34,7 @@ impl PanelProperties { } #[derive(Debug, Clone, Copy, PartialEq)] +#[allow(unused)] pub enum Position { Top, Bottom, From 64471d61246bbb0ebb76b710af6993ce1ee704c4 Mon Sep 17 00:00:00 2001 From: Eduardo Flores Date: Thu, 31 Oct 2024 23:12:22 +0100 Subject: [PATCH 7/7] fix: remove default label from layouts --- src/pages/layouts.rs | 54 +++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/pages/layouts.rs b/src/pages/layouts.rs index 6cda33d..869503d 100644 --- a/src/pages/layouts.rs +++ b/src/pages/layouts.rs @@ -54,34 +54,36 @@ impl Layouts { }) .collect::>>(); - widget::scrollable(widget::column::with_children(vec![ - widget::row::with_children(vec![ - widget::text::title3(fl!("layouts")).into(), - widget::horizontal_space().into(), - widget::tooltip::tooltip( - icons::get_handle("arrow-into-box-symbolic", 16) - .apply(widget::button::icon) - .padding(spacing.space_xxs) - .on_press(Message::OpenSaveDialog) - .class(cosmic::style::Button::Standard), - widget::text(fl!("save-current-layout")), - widget::tooltip::Position::Bottom, - ) + widget::scrollable( + widget::column::with_children(vec![ + widget::row::with_children(vec![ + widget::text::title3(fl!("layouts")).into(), + widget::horizontal_space().into(), + widget::tooltip::tooltip( + icons::get_handle("arrow-into-box-symbolic", 16) + .apply(widget::button::icon) + .padding(spacing.space_xxs) + .on_press(Message::OpenSaveDialog) + .class(cosmic::style::Button::Standard), + widget::text(fl!("save-current-layout")), + widget::tooltip::Position::Bottom, + ) + .into(), + ]) + .spacing(spacing.space_xxs) .into(), + widget::settings::section() + .add( + widget::flex_row(layouts) + .row_spacing(spacing.space_s) + .column_spacing(spacing.space_s) + .apply(widget::container) + .padding([0, spacing.space_xxs]), + ) + .into(), ]) - .spacing(spacing.space_xxs) - .into(), - widget::settings::section() - .title("Default") - .add( - widget::flex_row(layouts) - .row_spacing(spacing.space_s) - .column_spacing(spacing.space_s) - .apply(widget::container) - .padding([0, spacing.space_xxs]), - ) - .into(), - ])) + .spacing(spacing.space_s), + ) .into() }