diff --git a/ui/Cargo.lock b/ui/Cargo.lock index fb3b967..537d499 100644 --- a/ui/Cargo.lock +++ b/ui/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "anyhow" -version = "1.0.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" - [[package]] name = "autocfg" version = "1.5.0" @@ -22,23 +16,21 @@ checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "cairo-rs" -version = "0.18.5" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +checksum = "f6466a563dea2e99f59f6ffbb749fd0bdf75764f5e6e93976b5e7bd73c4c9efb" dependencies = [ "bitflags", "cairo-sys-rs", "glib", "libc", - "once_cell", - "thiserror", ] [[package]] name = "cairo-sys-rs" -version = "0.18.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +checksum = "cab7e9f13c802625aad1ad2b4ae3989f4ce9339ff388f335a6f109f9338705e2" dependencies = [ "glib-sys", "libc", @@ -47,50 +39,14 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.15.8" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +checksum = "0d0390889d58f934f01cd49736275b4c2da15bcfc328c78ff2349907e6cabf22" dependencies = [ "smallvec", "target-lexicon", ] -[[package]] -name = "cfg-if" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" - -[[package]] -name = "directories" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -147,7 +103,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -172,22 +128,21 @@ dependencies = [ [[package]] name = "gdk-pixbuf" -version = "0.18.5" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +checksum = "688dc7eaf551dbac1f5b11d000d089c3db29feb25562455f47c1a2080cc60bda" dependencies = [ "gdk-pixbuf-sys", "gio", "glib", "libc", - "once_cell", ] [[package]] name = "gdk-pixbuf-sys" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +checksum = "5af1823d3d1cb72616873ba0a593bd440eb92da700fdfb047505a21ee3ec3e10" dependencies = [ "gio-sys", "glib-sys", @@ -198,9 +153,9 @@ dependencies = [ [[package]] name = "gdk4" -version = "0.7.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edb019ad581f8ecf8ea8e4baa6df7c483a95b5a59be3140be6a9c3b0c632af6" +checksum = "0a67b064d2f35e649232455c7724f56f977555d2608c43300eabc530eaa4e359" dependencies = [ "cairo-rs", "gdk-pixbuf", @@ -213,9 +168,9 @@ dependencies = [ [[package]] name = "gdk4-sys" -version = "0.7.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbab43f332a3cf1df9974da690b5bb0e26720ed09a228178ce52175372dcfef0" +checksum = "2edbda0d879eb85317bdb49a3da591ed70a804a10776e358ef416be38c6db2c5" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -228,22 +183,11 @@ dependencies = [ "system-deps", ] -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - [[package]] name = "gio" -version = "0.18.4" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +checksum = "273d64c833fbbf7cd86c4cdced893c5d3f2f5d6aeb30fd0c30d172456ce8be2e" dependencies = [ "futures-channel", "futures-core", @@ -252,30 +196,28 @@ dependencies = [ "gio-sys", "glib", "libc", - "once_cell", "pin-project-lite", "smallvec", - "thiserror", ] [[package]] name = "gio-sys" -version = "0.18.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +checksum = "2c8130f5810a839d74afc3a929c34a700bf194972bb034f2ecfe639682dd13cc" dependencies = [ "glib-sys", "gobject-sys", "libc", "system-deps", - "winapi", + "windows-sys", ] [[package]] name = "glib" -version = "0.18.5" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +checksum = "690e8bcf8a819b5911d6ae79879226191d01253a4f602748072603defd5b9553" dependencies = [ "bitflags", "futures-channel", @@ -289,30 +231,36 @@ dependencies = [ "gobject-sys", "libc", "memchr", - "once_cell", "smallvec", - "thiserror", +] + +[[package]] +name = "glib-build-tools" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86aebe63bb050d4918cb1d629880cb35fcba7ccda6f6fc0ec1beffdaa1b9d5c3" +dependencies = [ + "gio", ] [[package]] name = "glib-macros" -version = "0.18.5" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" +checksum = "e772291ebea14c28eb11bb75741f62f4a4894f25e60ce80100797b6b010ef0f9" dependencies = [ - "heck 0.4.1", - "proc-macro-crate 2.0.2", - "proc-macro-error", + "heck", + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] name = "glib-sys" -version = "0.18.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +checksum = "4b2be4c74454fb4a6bd3328320737d0fa3d6939e2d570f5d846da00cb222f6a0" dependencies = [ "libc", "system-deps", @@ -320,9 +268,9 @@ dependencies = [ [[package]] name = "gobject-sys" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +checksum = "ab318a786f9abd49d388013b9161fa0ef8218ea6118ee7111c95e62186f7d31f" dependencies = [ "glib-sys", "libc", @@ -331,9 +279,9 @@ dependencies = [ [[package]] name = "graphene-rs" -version = "0.18.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2228cda1505613a7a956cca69076892cfbda84fc2b7a62b94a41a272c0c401" +checksum = "0487f78e8a772ec89020458fbabadd1332bc1e3236ca1c63ef1d61afd4e5f2cc" dependencies = [ "glib", "graphene-sys", @@ -342,9 +290,9 @@ dependencies = [ [[package]] name = "graphene-sys" -version = "0.18.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc4144cee8fc8788f2a9b73dc5f1d4e1189d1f95305c4cb7bd9c1af1cfa31f59" +checksum = "270cefb6b270fcb2ef9708c3a35c0e25c2e831dac28d75c4f87e5ad3540c9543" dependencies = [ "glib-sys", "libc", @@ -354,9 +302,9 @@ dependencies = [ [[package]] name = "gsk4" -version = "0.7.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d958e351d2f210309b32d081c832d7de0aca0b077aa10d88336c6379bd01f7e" +checksum = "d5dbe33ceed6fc20def67c03d36e532f5a4a569ae437ae015a7146094f31e10c" dependencies = [ "cairo-rs", "gdk4", @@ -369,9 +317,9 @@ dependencies = [ [[package]] name = "gsk4-sys" -version = "0.7.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12bd9e3effea989f020e8f1ff3fa3b8c63ba93d43b899c11a118868853a56d55" +checksum = "8d76011d55dd19fde16ffdedee08877ae6ec942818cfa7bc08a91259bc0b9fc9" dependencies = [ "cairo-sys-rs", "gdk4-sys", @@ -385,9 +333,9 @@ dependencies = [ [[package]] name = "gtk4" -version = "0.7.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeb51aa3e9728575a053e1f43543cd9992ac2477e1b186ad824fd4adfb70842" +checksum = "938d68ad43080ad5ee710c30d467c1bc022ee5947856f593855691d726305b3e" dependencies = [ "cairo-rs", "field-offset", @@ -406,23 +354,21 @@ dependencies = [ [[package]] name = "gtk4-macros" -version = "0.7.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d57ec49cf9b657f69a05bca8027cff0a8dfd0c49e812be026fc7311f2163832f" +checksum = "0912d2068695633002b92c5966edc108b2e4f54b58c509d1eeddd4cbceb7315c" dependencies = [ - "anyhow", - "proc-macro-crate 1.3.1", - "proc-macro-error", + "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "gtk4-sys" -version = "0.7.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54d8c4aa23638ce9faa2caf7e2a27d4a1295af2155c8e8d28c4d4eeca7a65eb8" +checksum = "a923bdcf00e46723801162de24432cbce38a6810e0178a2d0b6dd4ecc26a1c74" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -443,12 +389,6 @@ version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -467,11 +407,10 @@ dependencies = [ [[package]] name = "libadwaita" -version = "0.5.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fe7e70c06507ed10a16cda707f358fbe60fe0dc237498f78c686ade92fd979c" +checksum = "4df6715d1257bd8c093295b77a276ed129d73543b10304fec5829ced5d5b7c41" dependencies = [ - "gdk-pixbuf", "gdk4", "gio", "glib", @@ -483,9 +422,9 @@ dependencies = [ [[package]] name = "libadwaita-sys" -version = "0.5.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e10aaa38de1d53374f90deeb4535209adc40cc5dba37f9704724169bceec69a" +checksum = "fdf8950090cc180250cdb1ff859a39748feeda7a53a9f28ead3a17a14cc37ae2" dependencies = [ "gdk4-sys", "gio-sys", @@ -503,28 +442,6 @@ version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" -[[package]] -name = "libredox" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0" -dependencies = [ - "bitflags", - "libc", -] - -[[package]] -name = "lsfg-vk-ui" -version = "0.1.3" -dependencies = [ - "directories", - "dirs", - "gtk4", - "libadwaita", - "serde", - "toml", -] - [[package]] name = "memchr" version = "2.7.5" @@ -540,36 +457,23 @@ dependencies = [ "autocfg", ] -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - [[package]] name = "pango" -version = "0.18.3" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +checksum = "2d4803f086c4f49163c31ac14db162112a22401c116435080e4be8678c507d61" dependencies = [ "gio", "glib", "libc", - "once_cell", "pango-sys", ] [[package]] name = "pango-sys" -version = "0.18.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +checksum = "66872b3cfd328ad6d1a4f89ebd5357119bd4c592a4ddbb8f6bc2386f8ce7b898" dependencies = [ "glib-sys", "gobject-sys", @@ -597,46 +501,11 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - -[[package]] -name = "proc-macro-crate" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" -dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", + "toml_edit", ] [[package]] @@ -657,17 +526,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - [[package]] name = "rustc_version" version = "0.4.1" @@ -700,7 +558,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -724,17 +582,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.104" @@ -748,12 +595,12 @@ dependencies = [ [[package]] name = "system-deps" -version = "6.2.2" +version = "7.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +checksum = "e4be53aa0cba896d2dc615bd42bbc130acdcffa239e0a2d965ea5b3b2a86ffdb" dependencies = [ "cfg-expr", - "heck 0.5.0", + "heck", "pkg-config", "toml", "version-compare", @@ -761,67 +608,36 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] +checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" [[package]] name = "toml" -version = "0.8.2" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", @@ -830,6 +646,15 @@ dependencies = [ "winnow", ] +[[package]] +name = "ui" +version = "0.1.0" +dependencies = [ + "glib-build-tools", + "gtk4", + "libadwaita", +] + [[package]] name = "unicode-ident" version = "1.0.18" @@ -842,58 +667,25 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", + "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", @@ -902,51 +694,57 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.5.40" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" dependencies = [ "memchr", ] diff --git a/ui/Cargo.toml b/ui/Cargo.toml index 3524dea..9684e1e 100644 --- a/ui/Cargo.toml +++ b/ui/Cargo.toml @@ -1,14 +1,11 @@ [package] -name = "lsfg-vk-ui" -version = "0.1.3" -edition = "2021" -authors = ["Cali666"] -description = "Lossless Scaling Frame Generation Configuration Tool" +name = "ui" +version = "0.1.0" +edition = "2024" [dependencies] -libadwaita = "0.5" -gtk = { version = "0.7", package = "gtk4" } -directories = "5.0" -serde = { version = "1.0", features = ["derive"] } -toml = "0.8" -dirs = "5.0" +gtk = { version = "0.10.0", package = "gtk4" } +adw = { version = "0.8.0", package = "libadwaita" } + +[build-dependencies] +glib-build-tools = "0.21.0" diff --git a/ui/resources/com.cali666.lsfg-vk-ui.desktop b/ui/resources/com.cali666.lsfg-vk-ui.desktop deleted file mode 100644 index 640a161..0000000 --- a/ui/resources/com.cali666.lsfg-vk-ui.desktop +++ /dev/null @@ -1,13 +0,0 @@ -[Desktop Entry] -Version=1.0 -Type=Application -Name=LSFG-VK UI -Comment=Lossless Scaling Frame Generation Configuration Tool -Exec=lsfg-vk-ui %U -Icon=com.cali666.lsfg-vk-ui -Terminal=false -Categories=Game;Settings; -Keywords=lossless;scaling;frame;generation;gaming;graphics;configuration; -StartupNotify=true -StartupWMClass=com.cali666.lsfg-vk-ui -MimeType=application/x-lsfg-profile; diff --git a/ui/resources/icons/lsfg-vk.png b/ui/resources/icons/lsfg-vk.png deleted file mode 100644 index 1c67ee2..0000000 Binary files a/ui/resources/icons/lsfg-vk.png and /dev/null differ diff --git a/ui/resources/ui.ui b/ui/resources/ui.ui deleted file mode 100644 index d72e763..0000000 --- a/ui/resources/ui.ui +++ /dev/null @@ -1,347 +0,0 @@ - - - - - Lossless Scaling Frame Generation - 800 - 600 - true - - - - - - - Lossless Scaling Frame Generation - - - - - - Settings - settings-icon-button - - - - - - - - horizontal - - - - never - automatic - - - vertical - 0 - sidebar-content - - - LSFG Profiles - 0.0 - 12 - 12 - 6 - title-1 - - - - - browse - navigation-sidebar - - - - - - Create New Profile - 12 - 12 - 12 - suggested-action - - - - - - - - - - vertical - true - true - - - center - - - - - true - true - - - - settings_page - Settings - - - never - - - vertical - 48 - 48 - 32 - 32 - 32 - - - - - Frame Generation - true - 8 - 8 - - - true - - - horizontal - 16 - center - 12 - 12 - 8 - 8 - - - Multiplier - start - true - 0 - - - - - - - - off - 2 - 3 - 4 - - - - 0 - - - - - - - - - true - - - horizontal - 16 - center - 12 - 12 - 8 - 8 - - - Flow Scale - start - true - 0 - - - - - 0.7 - number - - - - - - - - - true - - - horizontal - 16 - center - 12 - 12 - 8 - 8 - - - Performance Mode - start - true - 0 - - - - - true - compact - - - - - - - - - - - - - Misc - true - 8 - 8 - - - true - - - horizontal - 16 - center - 12 - 12 - 8 - 8 - - - HDR Mode - start - true - 0 - - - - - true - compact - - - - - - - - - true - - - horizontal - 16 - center - 12 - 12 - 8 - 8 - - - Experimental Present Mode - start - true - 0 - - - - - - - - vsync - mailbox - immediate - - - - 0 - - - - - - - - - - - - - - - - - - about_page - About - - - vertical - center - center - 24 - - - LSFG-VK UI - title-1 - - - - - Lossless Scaling Frame Generation Configuration Tool - title-4 - true - 50 - - - - - Made by Cali666 • 2025 - dim-label - 24 - - - - - For more information refer to the lsfg-vk wiki - https://github.com/PancakeTAS/lsfg-vk/wiki - 12 - - - - - - - - - - - - - - - - diff --git a/ui/src/app_state.rs b/ui/src/app_state.rs deleted file mode 100644 index 552da38..0000000 --- a/ui/src/app_state.rs +++ /dev/null @@ -1,293 +0,0 @@ -use gtk::prelude::*; -use gtk::{glib, MessageDialog}; -use libadwaita::ApplicationWindow; -use std::cell::RefCell; -use std::rc::Rc; - -use crate::config::{Config, save_config}; -use crate::utils::round_to_2_decimals; - -#[allow(dead_code)] -pub struct AppState { - pub config: Config, - pub selected_profile_index: Option, - // Store references to the UI widgets for easy access and updates - pub main_window: ApplicationWindow, - pub sidebar_list_box: gtk::ListBox, - pub multiplier_dropdown: gtk::DropDown, - pub flow_scale_entry: gtk::Entry, - pub performance_mode_switch: gtk::Switch, - pub hdr_mode_switch: gtk::Switch, - pub experimental_present_mode_dropdown: gtk::DropDown, - pub save_button: gtk::Button, - pub main_settings_box: gtk::Box, - pub main_stack: gtk::Stack, - // Store SignalHandlerIds to block/unblock signals - pub multiplier_dropdown_handler_id: Option, - pub flow_scale_entry_handler_id: Option, - pub performance_mode_switch_handler_id: Option, - pub hdr_mode_switch_handler_id: Option, - pub experimental_present_mode_dropdown_handler_id: Option, -} - -impl AppState { - // Saves the current configuration to the TOML file - pub fn save_current_config(&self) { - if let Err(e) = save_config(&self.config) { - eprintln!("Failed to save config: {}", e); - // In a real app, you'd show a user-friendly error dialog here - } - } - - // Updates the main window UI with data from the currently selected profile - pub fn update_main_window_from_profile(&self) { - if let Some(index) = self.selected_profile_index { - if let Some(profile) = self.config.game.get(index) { - // Temporarily block signals to prevent re-entrancy - let _guard_mult = self.multiplier_dropdown_handler_id.as_ref().map(|id| self.multiplier_dropdown.block_signal(id)); - let _guard_flow = self.flow_scale_entry_handler_id.as_ref().map(|id| self.flow_scale_entry.block_signal(id)); - let _guard_perf = self.performance_mode_switch_handler_id.as_ref().map(|id| self.performance_mode_switch.block_signal(id)); - let _guard_hdr = self.hdr_mode_switch_handler_id.as_ref().map(|id| self.hdr_mode_switch.block_signal(id)); - let _guard_exp = self.experimental_present_mode_dropdown_handler_id.as_ref().map(|id| self.experimental_present_mode_dropdown.block_signal(id)); - - // Update Multiplier Dropdown - let multiplier_str = match profile.multiplier { - 1 => "off".to_string(), - _ => profile.multiplier.to_string(), - }; - if let Some(pos) = self.multiplier_dropdown.model().and_then(|model| { - let list_model = model.downcast_ref::()?; - (0..list_model.n_items()).find(|&i| list_model.string(i).map_or(false, |s| s.as_str() == multiplier_str)) - }) { - self.multiplier_dropdown.set_selected(pos); - } - - // Update Flow Scale Entry (round to avoid floating point display issues) - let rounded_flow_scale = round_to_2_decimals(profile.flow_scale); - self.flow_scale_entry.set_text(&format!("{:.2}", rounded_flow_scale)); - - // Update Performance Mode Switch - self.performance_mode_switch.set_active(profile.performance_mode); - - // Update HDR Mode Switch - self.hdr_mode_switch.set_active(profile.hdr_mode); - - // Update Experimental Present Mode Dropdown - if let Some(pos) = self.experimental_present_mode_dropdown.model().and_then(|model| { - let list_model = model.downcast_ref::()?; - (0..list_model.n_items()).find(|&i| list_model.string(i).map_or(false, |s| s.as_str() == profile.experimental_present_mode)) - }) { - self.experimental_present_mode_dropdown.set_selected(pos); - } - // Signal handlers are unblocked automatically when _guard_X go out of scope - - // Switch to the settings page - self.main_stack.set_visible_child_name("settings_page"); - - } - } else { - // Clear or disable main window elements if no profile is selected - self.multiplier_dropdown.set_selected(0); // Default to 'off' or first item - self.flow_scale_entry.set_text(""); - self.performance_mode_switch.set_active(false); - self.hdr_mode_switch.set_active(false); - self.experimental_present_mode_dropdown.set_selected(0); // Default to first item - - // Switch to the about page - self.main_stack.set_visible_child_name("about_page"); - } - } - - // Populates sidebar with optional app_state for button handlers - pub fn populate_sidebar_with_handlers(&self, app_state: Option>>) { - // Clear existing rows - while let Some(child) = self.sidebar_list_box.first_child() { - self.sidebar_list_box.remove(&child); - } - - let mut row_to_select: Option = None; - - for (i, profile) in self.config.game.iter().enumerate() { - let row = gtk::ListBoxRow::new(); - - // Create a horizontal box to hold the profile name and buttons - let row_box = gtk::Box::builder() - .orientation(gtk::Orientation::Horizontal) - .spacing(8) - .margin_start(12) - .margin_end(12) - .margin_top(8) - .margin_bottom(8) - .build(); - - // Profile name label - let label = gtk::Label::builder() - .label(&profile.exe) - .halign(gtk::Align::Start) - .hexpand(true) - .build(); - - // Edit button - let edit_button = gtk::Button::builder() - .label("🖊") - .css_classes(["flat", "circular"]) - .tooltip_text("Edit profile name") - .build(); - - // Remove button - let remove_button = gtk::Button::builder() - .label("𐄂") - .css_classes(["flat", "circular", "destructive-action"]) - .tooltip_text("Remove profile") - .build(); - - // Add all elements to the row box - row_box.append(&label); - row_box.append(&edit_button); - row_box.append(&remove_button); - - // Connect button handlers if app_state is available - if let Some(app_state_ref) = &app_state { - // Edit button handler - let app_state_clone = app_state_ref.clone(); - let profile_index = i; - edit_button.connect_clicked(move |_| { - let state = app_state_clone.borrow(); - let main_window = &state.main_window; - - // Create edit dialog - let dialog = MessageDialog::new( - Some(main_window), - gtk::DialogFlags::MODAL, - gtk::MessageType::Question, - gtk::ButtonsType::None, - "Edit profile name:", - ); - dialog.set_title(Some("Edit Profile")); - - let entry = gtk::Entry::builder() - .placeholder_text("Profile Name") - .text(&state.config.game[profile_index].exe) - .margin_top(12) - .margin_bottom(12) - .margin_start(12) - .margin_end(12) - .build(); - - dialog.content_area().append(&entry); - dialog.add_button("Cancel", gtk::ResponseType::Cancel); - dialog.add_button("Save", gtk::ResponseType::Other(1)); - dialog.set_default_response(gtk::ResponseType::Other(1)); - - // Allow pressing Enter in the entry to trigger the "Save" button - let dialog_clone = dialog.clone(); - entry.connect_activate(move |_| { - dialog_clone.response(gtk::ResponseType::Other(1)); - }); - - let app_state_clone_dialog = app_state_clone.clone(); - let entry_clone = entry.clone(); - dialog.connect_response(move |d, response| { - if response == gtk::ResponseType::Other(1) { - let new_name = entry_clone.text().to_string(); - if !new_name.is_empty() { - let mut state = app_state_clone_dialog.borrow_mut(); - - // Check if profile with this name already exists (excluding current) - if state.config.game.iter().enumerate().any(|(idx, p)| idx != profile_index && p.exe == new_name) { - let error_dialog = MessageDialog::new( - Some(d), - gtk::DialogFlags::MODAL, - gtk::MessageType::Error, - gtk::ButtonsType::Ok, - "A profile with this name already exists", - ); - error_dialog.set_title(Some("Error")); - error_dialog.connect_response(move |d, _| { d.close(); }); - error_dialog.present(); - return; - } - - // Update profile name - state.config.game[profile_index].exe = new_name; - state.save_current_config(); - state.populate_sidebar_with_handlers(Some(app_state_clone_dialog.clone())); - } - } - d.close(); - }); - dialog.present(); - }); - - // Remove button handler - let app_state_clone = app_state_ref.clone(); - let profile_index = i; - remove_button.connect_clicked(move |_| { - let state = app_state_clone.borrow(); - let main_window = &state.main_window; - let profile_name = &state.config.game[profile_index].exe; - - // Create confirmation dialog - let dialog = MessageDialog::new( - Some(main_window), - gtk::DialogFlags::MODAL, - gtk::MessageType::Warning, - gtk::ButtonsType::None, - &format!("Are you sure you want to remove the profile '{}'?", profile_name), - ); - dialog.set_title(Some("Remove Profile")); - dialog.add_button("Cancel", gtk::ResponseType::Cancel); - dialog.add_button("Remove", gtk::ResponseType::Other(1)); - dialog.set_default_response(gtk::ResponseType::Cancel); - - let app_state_clone_dialog = app_state_clone.clone(); - dialog.connect_response(move |d, response| { - if response == gtk::ResponseType::Other(1) { - let mut state = app_state_clone_dialog.borrow_mut(); - - // Remove the profile - state.config.game.remove(profile_index); - - // Update selected index if needed - if let Some(selected) = state.selected_profile_index { - if selected == profile_index { - // If we removed the selected profile, select the first available or none - state.selected_profile_index = if state.config.game.is_empty() { None } else { Some(0) }; - } else if selected > profile_index { - // Adjust index if we removed a profile before the selected one - state.selected_profile_index = Some(selected - 1); - } - } - - state.save_current_config(); - state.populate_sidebar_with_handlers(Some(app_state_clone_dialog.clone())); - drop(state); - - // Update main window - app_state_clone_dialog.borrow().update_main_window_from_profile(); - } - d.close(); - }); - dialog.present(); - }); - } - - row.set_child(Some(&row_box)); - self.sidebar_list_box.append(&row); - - // Mark the row to be selected later - if self.selected_profile_index == Some(i) { - row_to_select = Some(row.clone()); // Clone the row to store it - } - } - - // Perform selection in a separate idle callback - if let Some(row) = row_to_select { - let list_box_clone = self.sidebar_list_box.clone(); - glib::idle_add_local(move || { - list_box_clone.select_row(Some(&row)); - glib::ControlFlow::Break - }); - } - } -} diff --git a/ui/src/config.rs b/ui/src/config.rs deleted file mode 100644 index 7fdde70..0000000 --- a/ui/src/config.rs +++ /dev/null @@ -1,141 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::{fs, io}; -use std::path::PathBuf; -use toml; -use dirs; - -use crate::utils::round_to_2_decimals; // Import from utils module - -// --- Configuration Data Structures --- - -#[derive(Debug, Default, Serialize, Deserialize, Clone)] -pub struct Config { - pub version: u32, // Made public to be accessible from main.rs - #[serde(flatten)] // Flatten this struct into the parent, controlling order - pub ordered_global: OrderedGlobalConfig, - #[serde(default)] - pub game: Vec, -} - -// Helper struct to control the serialization order of global config -#[derive(Debug, Default, Serialize, Deserialize, Clone)] -pub struct OrderedGlobalConfig { - #[serde(default, skip_serializing_if = "Option::is_none")] // Only serialize if Some - pub global: Option, -} - -#[derive(Debug, Default, Serialize, Deserialize, Clone)] -pub struct GlobalConfig { - #[serde(default, skip_serializing_if = "Option::is_none")] // Only serialize if Some - pub dll: Option, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -#[serde(default)] -pub struct GameProfile { - pub exe: String, - pub multiplier: u32, - #[serde(serialize_with = "serialize_flow_scale", deserialize_with = "deserialize_flow_scale")] - pub flow_scale: f32, - pub performance_mode: bool, - pub hdr_mode: bool, - pub experimental_present_mode: String, -} - -// Default values for a new game profile -impl Default for GameProfile { - fn default() -> Self { - GameProfile { - exe: String::new(), - multiplier: 1, // Default to "off" (1) - flow_scale: round_to_2_decimals(0.7), - performance_mode: true, - hdr_mode: false, - experimental_present_mode: "vsync".to_string(), - } - } -} - -// Custom serde functions to ensure flow_scale is always rounded -fn serialize_flow_scale(value: &f32, serializer: S) -> Result -where - S: serde::Serializer, -{ - // Force to 2 decimal places and serialize as a precise decimal - let rounded = round_to_2_decimals(*value); - let formatted = format!("{:.2}", rounded); - let precise_value: f64 = formatted.parse().unwrap_or(*value as f64); - serializer.serialize_f64(precise_value) -} - -fn deserialize_flow_scale<'de, D>(deserializer: D) -> Result -where - D: serde::Deserializer<'de>, -{ - use serde::Deserialize; - let value = f64::deserialize(deserializer)?; - Ok(round_to_2_decimals(value as f32)) -} - -// --- Configuration File Handling Functions --- - -pub fn get_config_path() -> Result { - let config_dir = dirs::config_dir() - .ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "Could not find config directory"))? - .join("lsfg-vk"); - - fs::create_dir_all(&config_dir)?; // Ensure directory exists - println!("Config directory: {:?}", config_dir); - Ok(config_dir.join("conf.toml")) -} - - -pub fn load_config() -> Result { - let config_path = get_config_path()?; - println!("Attempting to load config from: {:?}", config_path); - if config_path.exists() { - let contents = fs::read_to_string(&config_path)?; - println!("Successfully read config contents ({} bytes).", contents.len()); - // Load configuration with default values when the format is invalid - let mut config: Config = toml::from_str(&contents).unwrap_or_else(|_| Config::default()); - - // Old way to load config - // let mut config: Config = toml::from_str(&contents).map_err(|e| { - // io::Error::new( - // io::ErrorKind::InvalidData, - // format!("Failed to parse TOML: {}", e), - // ) - // })?; - - - // Clean up any floating point precision issues in existing configs - let mut needs_save = false; - for profile in &mut config.game { - let original = profile.flow_scale; - profile.flow_scale = round_to_2_decimals(profile.flow_scale); - if (original - profile.flow_scale).abs() > f32::EPSILON { - needs_save = true; - } - } - - // Save the cleaned config if we made changes - if needs_save { - let _ = save_config(&config); - } - - Ok(config) - } else { - println!("Config file not found at {:?}, creating default.", config_path); - Ok(Config { version: 1, ordered_global: OrderedGlobalConfig { global: None }, game: Vec::new() }) - } -} - -pub fn save_config(config: &Config) -> Result<(), io::Error> { - let config_path = get_config_path()?; - println!("Attempting to save config to: {:?}", config_path); - let toml_string = toml::to_string_pretty(config) - .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("Failed to serialize TOML: {}", e)))?; - fs::write(&config_path, toml_string)?; - println!("Successfully saved config."); - Ok(()) -} diff --git a/ui/src/settings_window.rs b/ui/src/settings_window.rs deleted file mode 100644 index 73417e7..0000000 --- a/ui/src/settings_window.rs +++ /dev/null @@ -1,155 +0,0 @@ -use gtk::prelude::*; -use gtk::{glib, Label, Switch, Entry, Box, Orientation}; -use libadwaita::prelude::*; -use libadwaita::{ApplicationWindow, PreferencesGroup, PreferencesPage, PreferencesWindow, ActionRow}; -use std::rc::Rc; -use std::cell::RefCell; - -use crate::app_state::AppState; - -pub fn create_settings_window(parent: &ApplicationWindow, app_state: Rc>) -> PreferencesWindow { - let settings_window = PreferencesWindow::builder() - .title("Settings") - .transient_for(parent) - .modal(true) - .search_enabled(false) - .default_width(450) // Set default width - .default_height(300) // Set default height - .build(); - - let page = PreferencesPage::builder() - .title("General") - .icon_name("preferences-system-symbolic") - .build(); - - let group = PreferencesGroup::builder() - .title("Global Settings") - .build(); - - // --- Custom DLL Toggle and Path (Programmatically created) --- - let custom_dll_switch = Switch::builder() - .halign(gtk::Align::End) - .valign(gtk::Align::Center) - .build(); - - let custom_dll_path_entry = Entry::builder() - .placeholder_text("/path/to/Lossless.dll") - .hexpand(true) - .build(); - - let custom_dll_row = ActionRow::builder() - .title("Custom Path to Lossless.dll") - .build(); - custom_dll_row.add_suffix(&custom_dll_switch); - custom_dll_row.set_activatable_widget(Some(&custom_dll_switch)); - - let custom_dll_box = Box::builder() - .orientation(Orientation::Vertical) - .spacing(6) - .margin_top(6) - .margin_bottom(6) - .build(); - custom_dll_box.append(&custom_dll_row); - custom_dll_box.append(&custom_dll_path_entry); - - group.add(&custom_dll_box); // Add the box directly to the group - - // Initial state setup for Custom DLL - let current_dll_path = app_state.borrow().config.ordered_global.global.as_ref() - .and_then(|g| g.dll.clone()); - - if let Some(path) = current_dll_path { - custom_dll_switch.set_active(true); - custom_dll_path_entry.set_text(&path); - custom_dll_path_entry.set_visible(true); - } else { - custom_dll_switch.set_active(false); - custom_dll_path_entry.set_visible(false); - } - - // Connect switch to show/hide entry and update config - let app_state_clone_switch = app_state.clone(); - let custom_dll_path_entry_clone = custom_dll_path_entry.clone(); - custom_dll_switch.connect_state_set(move |_sw, active| { - custom_dll_path_entry_clone.set_visible(active); - let mut state = app_state_clone_switch.borrow_mut(); - if active { - // If activating, ensure global config exists and set DLL path - let current_path = custom_dll_path_entry_clone.text().to_string(); - state.config.ordered_global.global.get_or_insert_with(Default::default).dll = Some(current_path); - } else { - // If deactivating, set DLL path to None - if let Some(global_config) = state.config.ordered_global.global.as_mut() { - global_config.dll = None; - } - } - glib::Propagation::Proceed - }); - - // Connect entry to update config - let app_state_clone_entry = app_state.clone(); - let custom_dll_switch_clone = custom_dll_switch.clone(); - custom_dll_path_entry.connect_changed(move |entry| { - let mut state = app_state_clone_entry.borrow_mut(); - if custom_dll_switch_clone.is_active() { - let path = entry.text().to_string(); - if !path.is_empty() { - state.config.ordered_global.global.get_or_insert_with(Default::default).dll = Some(path); - } else { - // If path is cleared, set dll to None - if let Some(global_config) = state.config.ordered_global.global.as_mut() { - global_config.dll = None; - } - } - } - }); - - // Save button for settings - let save_settings_button = gtk::Button::builder() - .label("Save Global Settings") - .halign(gtk::Align::End) - .margin_end(12) - .margin_bottom(12) - .margin_top(12) - .build(); - - // Create a box to hold the feedback label - let feedback_container_box = Box::builder() - .orientation(Orientation::Vertical) - .halign(gtk::Align::End) - .margin_end(12) - .margin_bottom(12) - .build(); - - group.add(&save_settings_button); // Add button first - group.add(&feedback_container_box); // Then add the container for feedback - - let app_state_clone_save = app_state.clone(); - let feedback_container_box_clone = feedback_container_box.clone(); // Clone for the closure - save_settings_button.connect_clicked(move |_| { - let state = app_state_clone_save.borrow_mut(); // Removed 'mut' - state.save_current_config(); - - let feedback_label = Label::new(Some("Saved!")); - feedback_label.set_halign(gtk::Align::End); - feedback_label.set_margin_end(12); - feedback_label.set_margin_bottom(12); - - // Append to the dedicated feedback container box - feedback_container_box_clone.append(&feedback_label); - - glib::timeout_add_local(std::time::Duration::new(2, 0), { - let feedback_label_clone = feedback_label.clone(); // Clone for the timeout - let feedback_container_box_clone_for_remove = feedback_container_box_clone.clone(); // Clone for the timeout - move || { - feedback_container_box_clone_for_remove.remove(&feedback_label_clone); - glib::ControlFlow::Break - } - }); - }); - - page.add(&group); - settings_window.add(&page); - - settings_window -} diff --git a/ui/src/utils.rs b/ui/src/utils.rs deleted file mode 100644 index 7fe2612..0000000 --- a/ui/src/utils.rs +++ /dev/null @@ -1,59 +0,0 @@ -use std::process::Command; -use std::io::{BufReader, BufRead}; - -pub fn round_to_2_decimals(value: f32) -> f32 { - // Use string formatting to get exactly 2 decimal places and then parse back - // This avoids floating point precision issues - format!("{:.2}", value).parse().unwrap_or(value) -} - -/// Executes a bash command to find running processes that use Vulkan -/// and are owned by the current user. -/// Returns a vector of process names. -pub fn get_vulkan_processes() -> Vec { - let mut processes = Vec::new(); - let command_str = r#" - for pid in /proc/[0-9]*; do - owner=$(stat -c %U "$pid" 2>/dev/null) - if [[ "$owner" == "$USER" ]]; then - if grep -qi 'vulkan' "$pid/maps" 2>/dev/null; then - procname=$(cat "$pid/comm" 2>/dev/null) - if [[ -n "$procname" ]]; then - printf "%s\n" "$procname" # Only print the process name - fi - fi - fi - done - "#; - - // Execute the bash command - let output = Command::new("bash") - .arg("-c") - .arg(command_str) - .output(); - - match output { - Ok(output) => { - if output.status.success() { - // Read stdout line by line - let reader = BufReader::new(output.stdout.as_slice()); - for line in reader.lines() { - if let Ok(proc_name) = line { - let trimmed_name = proc_name.trim().to_string(); - if !trimmed_name.is_empty() { - processes.push(trimmed_name); - } - } - } - } else { - // Print stderr if the command failed - eprintln!("Command failed with error: {}", String::from_utf8_lossy(&output.stderr)); - } - }, - Err(e) => { - // Print error if the command could not be executed - eprintln!("Failed to execute command: {}", e); - } - } - processes -}