diff --git a/Cargo.lock b/Cargo.lock index 7844227..4b37534 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" @@ -1036,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", @@ -1055,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" @@ -1064,13 +1131,30 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cosmic-ext-config-templates" +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", + "serde", + "walkdir", +] + [[package]] name = "cosmic-ext-tweaks" version = "0.1.1" dependencies = [ "anyhow", "ashpd 0.8.1", - "cosmic-panel-config", + "cosmic-ext-config-templates", + "cosmic-panel-config 0.1.0 (git+https://github.com/pop-os/cosmic-panel)", "dirs", "env_logger 0.11.5", "i18n-embed", @@ -1092,16 +1176,31 @@ 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?branch=master#041a44eb6f825b7e0b3d45ccf745252b136d5da9" dependencies = [ "anyhow", - "cosmic-config", + "cosmic-config 0.1.0 (git+https://github.com/pop-os/libcosmic.git)", "ron", "serde", - "smithay-client-toolkit 0.18.0", + "smithay-client-toolkit", "tracing", - "wayland-protocols-wlr 0.2.0", - "xdg-shell-wrapper-config", + "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 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)", ] [[package]] @@ -1133,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", @@ -1272,7 +1371,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1283,7 +1382,7 @@ checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1334,7 +1433,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1382,7 +1481,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1411,7 +1510,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 +1612,7 @@ checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -1873,7 +1972,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -2014,7 +2113,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -2260,6 +2359,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 +2561,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.63", + "syn 2.0.85", "unic-langid", ] @@ -2470,7 +2575,7 @@ dependencies = [ "i18n-config", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -2503,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", @@ -2523,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" @@ -2546,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", @@ -2581,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", @@ -2613,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", @@ -2656,12 +2796,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", @@ -2690,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", @@ -3035,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", @@ -3072,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]] @@ -3550,7 +3690,7 @@ dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -3843,7 +3983,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -3916,12 +4056,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 +4095,7 @@ dependencies = [ "by_address", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -4060,7 +4200,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -4095,7 +4235,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -4250,9 +4390,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 +4405,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", "version_check", "yansi", ] @@ -4604,7 +4744,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.63", + "syn 2.0.85", "walkdir", ] @@ -4781,7 +4921,7 @@ dependencies = [ "ab_glyph", "log", "memmap2 0.9.4", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "tiny-skia", ] @@ -4825,22 +4965,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 +5004,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -4980,33 +5120,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 +5141,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 +5155,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 +5309,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 +5406,7 @@ checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -5439,7 +5552,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -5598,7 +5711,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -5895,7 +6008,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", "wasm-bindgen-shared", ] @@ -5929,7 +6042,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6003,19 +6116,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 +6126,7 @@ dependencies = [ "wayland-backend", "wayland-client", "wayland-scanner", + "wayland-server", ] [[package]] @@ -6037,24 +6138,10 @@ dependencies = [ "bitflags 2.6.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.3", + "wayland-protocols", "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-scanner", - "wayland-server", -] - [[package]] name = "wayland-protocols-wlr" version = "0.3.3" @@ -6064,8 +6151,9 @@ dependencies = [ "bitflags 2.6.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.3", + "wayland-protocols", "wayland-scanner", + "wayland-server", ] [[package]] @@ -6081,9 +6169,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 +6426,7 @@ checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -6349,7 +6437,7 @@ checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.63", + "syn 2.0.85", ] [[package]] @@ -6638,7 +6726,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 +6734,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 +6819,19 @@ 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?branch=master#041a44eb6f825b7e0b3d45ccf745252b136d5da9" +dependencies = [ + "serde", + "wayland-protocols-wlr", +] + +[[package]] +name = "xdg-shell-wrapper-config" +version = "0.1.0" +source = "git+https://github.com/pop-os/cosmic-panel#041a44eb6f825b7e0b3d45ccf745252b136d5da9" dependencies = [ "serde", - "wayland-protocols-wlr 0.2.0", + "wayland-protocols-wlr", ] [[package]] @@ -6941,7 +7038,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..6425c98 100644 --- a/i18n/en/cosmic_ext_tweaks.ftl +++ b/i18n/en/cosmic_ext_tweaks.ftl @@ -4,10 +4,12 @@ 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 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 @@ -33,6 +35,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/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/res/layouts/cosmic.ron b/res/layouts/cosmic.ron new file mode 100644 index 0000000..c4eb65b --- /dev/null +++ b/res/layouts/cosmic.ron @@ -0,0 +1,79 @@ +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 new file mode 100644 index 0000000..61c7305 --- /dev/null +++ b/res/layouts/mac.ron @@ -0,0 +1,71 @@ +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 new file mode 100644 index 0000000..8b25592 --- /dev/null +++ b/res/layouts/ubuntu.ron @@ -0,0 +1,79 @@ +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 new file mode 100644 index 0000000..e50673f --- /dev/null +++ b/res/layouts/windows.ron @@ -0,0 +1,50 @@ +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/app.rs b/src/app.rs index 5595566..a3319ab 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, @@ -20,19 +28,23 @@ use crate::{ pages::{ self, color_schemes::{config::ColorScheme, preview, ColorSchemeProvider, ColorSchemes}, + layouts::Layouts, }, - settings::{AppTheme, TweaksSettings}, + settings::{AppTheme, TweaksSettings, CONFIG_VERSION}, }; mod key_bind; +pub mod style; pub struct TweakTool { core: Core, 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, app_themes: Vec, config_handler: Option, @@ -51,15 +63,18 @@ pub enum Status { #[derive(Clone, Debug, Eq, PartialEq)] pub enum DialogPage { - New(String), + SaveCurrentColorScheme(String), + SaveCurrentLayout(String), } #[derive(Debug, Clone)] pub enum Message { Dock(pages::dock::Message), Panel(pages::panel::Message), + Layouts(pages::layouts::Message), ColorSchemes(Box), - OpenSaveDialog, + OpenSaveCurrentColorScheme, + OpenSaveCurrentLayout, DialogUpdate(DialogPage), DialogComplete, DialogCancel, @@ -69,6 +84,10 @@ pub enum Message { AppTheme(usize), FetchAvailableColorSchemes(ColorSchemeProvider, usize), SetAvailableColorSchemes(Vec), + Key(Modifiers, Key), + Modifiers(Modifiers), + SystemThemeModeChange, + SaveNewLayout(String), } #[derive(Debug, Clone, Eq, PartialEq)] @@ -89,17 +108,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), + TweaksAction::About => Message::ToggleContextPage(ContextPage::About), + TweaksAction::Settings => Message::ToggleContextPage(ContextPage::Settings), } } } @@ -133,8 +152,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), ], ), )]); @@ -178,27 +197,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()) } @@ -225,7 +250,9 @@ 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, app_themes: vec![fl!("match-desktop"), fl!("dark"), fl!("light")], config_handler: flags.config_handler, @@ -257,6 +284,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]) @@ -304,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 { @@ -370,9 +398,15 @@ impl Application for TweakTool { .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))), @@ -389,8 +423,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) => { @@ -399,18 +442,83 @@ 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))) + } } } } 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 { @@ -517,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/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/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/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/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/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.rs b/src/pages/layouts.rs new file mode 100644 index 0000000..869503d --- /dev/null +++ b/src/pages/layouts.rs @@ -0,0 +1,161 @@ +use config::{CustomLayout, Layout, LayoutsConfig}; +use cosmic::{ + cosmic_config::Config, iced::alignment::Horizontal, widget, Application, Apply, Element, Task, +}; +use cosmic_ext_config_templates::{load_template, panel::PanelSchema, Schema}; +use dirs::data_local_dir; + +use crate::{app::TweakTool, core::icons, fl}; + +pub mod config; +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, + selected_layout: None, + } + } +} + +#[derive(Debug, Clone)] +pub enum Message { + ApplyLayout(Layout), + SelectLayout(Layout), + DeleteLayout, + OpenSaveDialog, + SaveCurrentLayout(String), +} + +impl Layouts { + pub fn view(&self) -> Element { + let spacing = cosmic::theme::active().cosmic().spacing; + let layouts = self + .config + .layouts + .iter() + .map(|layout| { + widget::column() + .push(layout.preview()) + .push(widget::text(layout.name())) + .spacing(spacing.space_xs) + .align_x(Horizontal::Center) + .into() + }) + .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, + ) + .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_s), + ) + .into() + } + + pub fn update(&mut self, message: Message) -> Task { + let mut commands = vec![]; + match message { + 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() + .unwrap() + .join(TweakTool::APP_ID) + .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"); + 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); + let mut layouts = self.config.layouts.clone(); + layouts.push(Layout::Custom(layout)); + 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), + } + } + } + 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 new file mode 100644 index 0000000..dcffe51 --- /dev/null +++ b/src/pages/layouts/config.rs @@ -0,0 +1,171 @@ +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; + +use super::{ + preview::{LayoutPreview, PanelProperties, Position}, + Message, +}; +use crate::{app::TweakTool, fl, resources}; +use cosmic::{ + cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, Config, CosmicConfigEntry}, + widget::{self, menu::Action}, + Application, Element, +}; +use cosmic_ext_config_templates::Schema; +use serde::{Deserialize, Serialize}; + +#[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(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, + Mac, + Windows, + Ubuntu, + Custom(CustomLayout), +} + +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::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 { + match self { + 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(), + } + } + + pub fn is_custom(&self) -> bool { + matches!(self, Layout::Custom(_)) + } +} + +#[derive(Debug, Serialize, Clone, Default, Deserialize, PartialEq, CosmicConfigEntry)] +pub struct CustomLayout { + name: String, + path: PathBuf, +} + +impl CustomLayout { + pub fn new(name: String, path: &Path) -> Self { + Self { + name, + path: path.to_path_buf(), + } + } + + pub fn path(&self) -> &PathBuf { + &self.path + } +} diff --git a/src/pages/layouts/preview.rs b/src/pages/layouts/preview.rs new file mode 100644 index 0000000..dc9f1c2 --- /dev/null +++ b/src/pages/layouts/preview.rs @@ -0,0 +1,339 @@ +use cosmic::{ + iced::{ + alignment::{Horizontal, Vertical}, + Length, + }, + widget::{self, horizontal_space, vertical_space}, + Apply, 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)] +#[allow(unused)] +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 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("")); + + let content: 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(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 + .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 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 { + 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 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 { + 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(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 + .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(), + } + } + }; + + content + .apply(widget::container) + .class(cosmic::style::Container::Secondary) + .padding(spacing.space_xxxs) + .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/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; 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");