From e995c6cd1a08ca0f81f8666be6d4035fe4fab698 Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Tue, 7 Nov 2023 09:38:37 +0000 Subject: [PATCH 01/10] chore: updated dependencies --- Cargo.lock | 371 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 228 insertions(+), 143 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ff1536..e700e1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,11 +161,11 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b0c4a4f319e45986f347ee47fef8bf5e81c9abc3f6f58dc2391439f30df65f0" dependencies = [ - "async-lock", + "async-lock 2.8.0", "async-task", "concurrent-queue", "fastrand 2.0.1", - "futures-lite", + "futures-lite 1.13.0", "slab", ] @@ -175,10 +175,10 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "blocking", - "futures-lite", + "futures-lite 1.13.0", ] [[package]] @@ -189,10 +189,10 @@ checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" dependencies = [ "async-channel", "async-executor", - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "blocking", - "futures-lite", + "futures-lite 1.13.0", "once_cell", ] @@ -202,20 +202,40 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "cfg-if", "concurrent-queue", - "futures-lite", + "futures-lite 1.13.0", "log", "parking", - "polling", - "rustix 0.37.26", + "polling 2.8.0", + "rustix 0.37.27", "slab", "socket2 0.4.10", "waker-fn", ] +[[package]] +name = "async-io" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9d5715c2d329bf1b4da8d60455b99b187f27ba726df2883799af9af60997" +dependencies = [ + "async-lock 3.0.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.0.1", + "parking", + "polling 3.3.0", + "rustix 0.38.21", + "slab", + "tracing", + "waker-fn", + "windows-sys", +] + [[package]] name = "async-lock" version = "2.8.0" @@ -225,20 +245,31 @@ dependencies = [ "event-listener 2.5.3", ] +[[package]] +name = "async-lock" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e900cdcd39bb94a14487d3f7ef92ca222162e6c7c3fe7cb3550ea75fb486ed" +dependencies = [ + "event-listener 3.0.1", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-process" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-signal", "blocking", "cfg-if", - "event-listener 3.0.0", - "futures-lite", - "rustix 0.38.20", + "event-listener 3.0.1", + "futures-lite 1.13.0", + "rustix 0.38.21", "windows-sys", ] @@ -250,22 +281,22 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] name = "async-signal" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2a5415b7abcdc9cd7d63d6badba5288b2ca017e3fbd4173b8f405449f1a2399" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" dependencies = [ - "async-io", - "async-lock", + "async-io 2.2.0", + "async-lock 2.8.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.20", + "rustix 0.38.21", "signal-hook-registry", "slab", "windows-sys", @@ -279,13 +310,13 @@ checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ "async-channel", "async-global-executor", - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite", + "futures-lite 1.13.0", "gloo-timers", "kv-log-macro", "log", @@ -311,7 +342,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -396,11 +427,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" dependencies = [ "async-channel", - "async-lock", + "async-lock 2.8.0", "async-task", "fastrand 2.0.1", "futures-io", - "futures-lite", + "futures-lite 1.13.0", "piper", "tracing", ] @@ -507,9 +538,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" dependencies = [ "clap_builder", "clap_derive", @@ -517,9 +548,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" dependencies = [ "anstream", "anstyle", @@ -529,21 +560,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "color_quant" @@ -590,9 +621,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -696,7 +727,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -713,9 +744,9 @@ checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "either" @@ -805,7 +836,7 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -845,15 +876,25 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" +checksum = "01cec0252c2afff729ee6f00e903d479fba81784c8e2bd77447673471fdfaea1" dependencies = [ "concurrent-queue", "parking", "pin-project-lite", ] +[[package]] +name = "event-listener-strategy" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96b852f1345da36d551b9473fa1e2b1eb5c5195585c6c018118bc92a8d91160" +dependencies = [ + "event-listener 3.0.1", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -871,9 +912,9 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fdeflate" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868" dependencies = [ "simd-adler32", ] @@ -1026,9 +1067,9 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" dependencies = [ "futures-channel", "futures-core", @@ -1041,9 +1082,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", "futures-sink", @@ -1051,15 +1092,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -1068,9 +1109,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-lite" @@ -1087,34 +1128,44 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "futures-lite" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3831c2651acb5177cbd83943f3d9c8912c5ad03c76afcc0e9511ba568ec5ebb" +dependencies = [ + "futures-core", + "pin-project-lite", +] + [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-channel", "futures-core", @@ -1596,9 +1647,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http", @@ -1706,9 +1757,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown", @@ -1770,7 +1821,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.20", + "rustix 0.38.21", "windows-sys", ] @@ -1803,9 +1854,9 @@ checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] @@ -1818,7 +1869,7 @@ checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ "base64 0.21.5", "pem", - "ring", + "ring 0.16.20", "serde", "serde_json", "simple_asn1", @@ -1874,9 +1925,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libloading" @@ -2315,7 +2366,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -2388,6 +2439,20 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "polling" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53b6af1f60f36f8c2ac2aad5459d75a5a9b4be1e8cdd40264f315d78193e531" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix 0.38.21", + "tracing", + "windows-sys", +] + [[package]] name = "pollster" version = "0.3.0" @@ -2554,9 +2619,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] @@ -2632,7 +2697,7 @@ checksum = "9340e2553c0a184a80a0bfa1dcf73c47f3d48933aa6be90724b202f9fbd24735" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -2642,7 +2707,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c9e7b57df6e8472152674607f6cc68aa14a748a3157a857a94f516e11aeacc2" dependencies = [ "ashpd", - "async-io", + "async-io 1.13.0", "block", "dispatch", "futures-util", @@ -2670,11 +2735,25 @@ dependencies = [ "libc", "once_cell", "spin 0.5.2", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + [[package]] name = "ron" version = "0.8.1" @@ -2719,9 +2798,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.26" +version = "0.37.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f3f8f960ed3b5a59055428714943298bf3fa2d4a1d53135084e0544829d995" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ "bitflags 1.3.2", "errno", @@ -2733,9 +2812,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.20" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ "bitflags 2.4.1", "errno", @@ -2746,12 +2825,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" dependencies = [ "log", - "ring", + "ring 0.17.5", "rustls-webpki", "sct", ] @@ -2779,12 +2858,12 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.5", + "untrusted 0.9.0", ] [[package]] @@ -2860,12 +2939,12 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.5", + "untrusted 0.9.0", ] [[package]] @@ -2929,22 +3008,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.189" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -2960,9 +3039,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa 1.0.9", "ryu", @@ -2981,13 +3060,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -3229,9 +3308,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -3249,9 +3328,9 @@ dependencies = [ [[package]] name = "system-deps" -version = "6.1.2" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af52f9402f94aac4948a2518b43359be8d9ce6cd9efc1c4de3b2f7b7e897d6" +checksum = "2a2d580ff6a20c55dfb86be5f9c238f67835d0e81cbdea8bf5680e0897320331" dependencies = [ "cfg-expr", "heck", @@ -3268,14 +3347,14 @@ checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand 2.0.1", "redox_syscall", - "rustix 0.38.20", + "rustix 0.38.21", "windows-sys", ] @@ -3430,7 +3509,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -3582,9 +3661,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -3595,14 +3674,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.4" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ef75d881185fd2df4a040793927c153d863651108a93c7e17a9e591baa95cc6" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.4", + "toml_edit 0.21.0", ] [[package]] @@ -3627,9 +3706,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.20.4" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380f9e8120405471f7c9ad1860a713ef5ece6a670c7eae39225e477340f32fc4" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap", "serde", @@ -3708,7 +3787,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -3821,6 +3900,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.4.1" @@ -3905,9 +3990,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3915,24 +4000,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ "cfg-if", "js-sys", @@ -3942,9 +4027,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3952,28 +4037,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" dependencies = [ "js-sys", "wasm-bindgen", @@ -4093,9 +4178,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.17" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" dependencies = [ "memchr", ] @@ -4119,8 +4204,8 @@ dependencies = [ "async-broadcast", "async-executor", "async-fs", - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-process", "async-recursion", "async-task", From 14e0231179d95d51d889824ebc8861fcde9b1694 Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Wed, 6 Dec 2023 14:09:30 +0000 Subject: [PATCH 02/10] fix: searches reset scroll fixes #142 --- testangel/src/ui/actions/header.rs | 447 ++++++++++++++-------------- testangel/src/ui/flows/header.rs | 461 +++++++++++++++-------------- 2 files changed, 459 insertions(+), 449 deletions(-) diff --git a/testangel/src/ui/actions/header.rs b/testangel/src/ui/actions/header.rs index e04ce4a..bf633a7 100644 --- a/testangel/src/ui/actions/header.rs +++ b/testangel/src/ui/actions/header.rs @@ -1,221 +1,226 @@ -use std::sync::Arc; - -use adw::prelude::*; -use relm4::{ - adw, factory::FactoryVecDeque, gtk, Component, ComponentParts, ComponentSender, RelmWidgetExt, -}; -use testangel::{action_loader::ActionMap, ipc::EngineList}; - -use crate::ui::{ - components::add_step_factory::{AddStepInit, AddStepResult, AddStepTrait}, - lang, -}; - -#[derive(Debug)] -pub struct ActionsHeader { - action_map: Arc, - engine_list: Arc, - add_button: gtk::MenuButton, - action_open: bool, - search_results: FactoryVecDeque>, -} - -#[derive(Debug)] -pub enum ActionsHeaderOutput { - NewAction, - OpenAction, - SaveAction, - SaveAsAction, - CloseAction, - AddStep(String), -} - -#[derive(Debug)] -pub enum ActionsHeaderInput { - ActionsMapChanged(Arc), - /// Add the step with the instruction ID given - AddStep(String), - /// Trigger a search for the steps provided - SearchForSteps(String), - /// Add the top search result to the action. - AddTopSearchResult, - /// Inform the header bar if a action is open or not. - ChangeActionOpen(bool), - /// Ask this to output the provided event - PleaseOutput(ActionsHeaderOutput), -} - -impl AddStepTrait for ActionsHeaderInput { - fn add_step(value: String) -> Self { - Self::AddStep(value) - } -} - -#[relm4::component(pub)] -impl Component for ActionsHeader { - type Init = (Arc, Arc); - type Input = ActionsHeaderInput; - type Output = ActionsHeaderOutput; - type CommandOutput = (); - - view! { - #[root] - #[name = "start"] - gtk::Box { - set_spacing: 5, - - #[local_ref] - add_button -> gtk::MenuButton { - set_icon_name: relm4_icons::icon_name::PLUS, - set_tooltip: &lang::lookup("action-header-add"), - - #[wrap(Some)] - #[name = "menu_popover"] - set_popover = >k::Popover { - gtk::Box { - set_spacing: 2, - set_orientation: gtk::Orientation::Vertical, - - gtk::SearchEntry { - set_max_width_chars: 20, - - connect_activate[sender] => move |_| { - sender.input(ActionsHeaderInput::AddTopSearchResult); - }, - - connect_search_changed[sender] => move |slf| { - let query = slf.text().to_string(); - sender.input(ActionsHeaderInput::SearchForSteps(query)); - }, - }, - - gtk::ScrolledWindow { - set_hscrollbar_policy: gtk::PolicyType::Never, - set_min_content_height: 150, - - #[local_ref] - results_box -> gtk::Box { - set_spacing: 2, - set_orientation: gtk::Orientation::Vertical, - }, - }, - }, - }, - }, - }, - } - - fn init( - init: Self::Init, - root: &Self::Root, - sender: ComponentSender, - ) -> ComponentParts { - let model = ActionsHeader { - engine_list: init.0, - action_map: init.1, - action_open: false, - add_button: gtk::MenuButton::default(), - search_results: FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()), - }; - // Reset search results - sender.input(ActionsHeaderInput::SearchForSteps(String::new())); - - let results_box = model.search_results.widget(); - let add_button = &model.add_button; - let widgets = view_output!(); - - ComponentParts { model, widgets } - } - - fn update_with_view( - &mut self, - widgets: &mut Self::Widgets, - message: Self::Input, - sender: ComponentSender, - _root: &Self::Root, - ) { - match message { - ActionsHeaderInput::PleaseOutput(output) => { - let _ = sender.output(output); - } - ActionsHeaderInput::ChangeActionOpen(now) => { - self.action_open = now; - } - ActionsHeaderInput::ActionsMapChanged(new_map) => { - self.action_map = new_map; - } - ActionsHeaderInput::AddStep(step_id) => { - // close popover - self.add_button.popdown(); - // unwrap rationale: the receiver will never be disconnected - sender - .output(ActionsHeaderOutput::AddStep(step_id)) - .unwrap(); - } - ActionsHeaderInput::AddTopSearchResult => { - if let Some(result) = self.search_results.get(0) { - widgets.menu_popover.popdown(); - let id = result.value(); - // unwrap rationale: the receiver will never be disconnected - sender.output(ActionsHeaderOutput::AddStep(id)).unwrap(); - } - } - ActionsHeaderInput::SearchForSteps(query) => { - let mut results = self.search_results.guard(); - results.clear(); - - // Collect results - if query.is_empty() { - // List all alphabetically - let mut unsorted_results = vec![]; - for engine in self.engine_list.inner() { - for instruction in &engine.instructions { - unsorted_results.push(( - format!("{}: {}", engine.name, instruction.friendly_name()), - engine.name.clone(), - instruction.clone(), - )); - } - } - - // Sort - unsorted_results.sort_by(|(a, _, _), (b, _, _)| a.cmp(b)); - for (_, engine_name, ins) in unsorted_results { - results.push_back(AddStepInit { - label: format!("{engine_name}: {}", ins.friendly_name()), - value: ins.id().clone(), - }); - } - } else { - let mut unsorted_results = vec![]; - use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher}; - let matcher = SkimMatcherV2::default(); - for engine in self.engine_list.inner() { - for instruction in &engine.instructions { - if let Some(score) = matcher.fuzzy_match( - &format!("{}: {}", engine.name, instruction.friendly_name()), - &query, - ) { - unsorted_results.push(( - score, - engine.name.clone(), - instruction.clone(), - )); - } - } - } - - // Sort - unsorted_results.sort_by(|(a, _, _), (b, _, _)| a.cmp(b)); - for (_, engine_name, ins) in unsorted_results { - results.push_back(AddStepInit { - label: format!("{engine_name}: {}", ins.friendly_name()), - value: ins.id().clone(), - }); - } - } - } - } - self.update_view(widgets, sender); - } -} +use std::sync::Arc; + +use adw::prelude::*; +use relm4::{ + adw, factory::FactoryVecDeque, gtk, Component, ComponentParts, ComponentSender, RelmWidgetExt, +}; +use testangel::{action_loader::ActionMap, ipc::EngineList}; + +use crate::ui::{ + components::add_step_factory::{AddStepInit, AddStepResult, AddStepTrait}, + lang, +}; + +#[derive(Debug)] +pub struct ActionsHeader { + action_map: Arc, + engine_list: Arc, + add_button: gtk::MenuButton, + action_open: bool, + search_results: FactoryVecDeque>, +} + +#[derive(Debug)] +pub enum ActionsHeaderOutput { + NewAction, + OpenAction, + SaveAction, + SaveAsAction, + CloseAction, + AddStep(String), +} + +#[derive(Debug)] +pub enum ActionsHeaderInput { + ActionsMapChanged(Arc), + /// Add the step with the instruction ID given + AddStep(String), + /// Trigger a search for the steps provided + SearchForSteps(String), + /// Add the top search result to the action. + AddTopSearchResult, + /// Inform the header bar if a action is open or not. + ChangeActionOpen(bool), + /// Ask this to output the provided event + PleaseOutput(ActionsHeaderOutput), +} + +impl AddStepTrait for ActionsHeaderInput { + fn add_step(value: String) -> Self { + Self::AddStep(value) + } +} + +#[relm4::component(pub)] +impl Component for ActionsHeader { + type Init = (Arc, Arc); + type Input = ActionsHeaderInput; + type Output = ActionsHeaderOutput; + type CommandOutput = (); + + view! { + #[root] + #[name = "start"] + gtk::Box { + set_spacing: 5, + + #[local_ref] + add_button -> gtk::MenuButton { + set_icon_name: relm4_icons::icon_name::PLUS, + set_tooltip: &lang::lookup("action-header-add"), + + #[wrap(Some)] + #[name = "menu_popover"] + set_popover = >k::Popover { + gtk::Box { + set_spacing: 2, + set_orientation: gtk::Orientation::Vertical, + + gtk::SearchEntry { + set_max_width_chars: 20, + + connect_activate[sender] => move |_| { + sender.input(ActionsHeaderInput::AddTopSearchResult); + }, + + connect_search_changed[sender] => move |slf| { + let query = slf.text().to_string(); + sender.input(ActionsHeaderInput::SearchForSteps(query)); + }, + }, + + #[name = "menu_scrolled_area"] + gtk::ScrolledWindow { + set_hscrollbar_policy: gtk::PolicyType::Never, + set_min_content_height: 150, + + #[local_ref] + results_box -> gtk::Box { + set_spacing: 2, + set_orientation: gtk::Orientation::Vertical, + }, + }, + }, + }, + }, + }, + } + + fn init( + init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = ActionsHeader { + engine_list: init.0, + action_map: init.1, + action_open: false, + add_button: gtk::MenuButton::default(), + search_results: FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()), + }; + // Reset search results + sender.input(ActionsHeaderInput::SearchForSteps(String::new())); + + let results_box = model.search_results.widget(); + let add_button = &model.add_button; + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::Input, + sender: ComponentSender, + _root: &Self::Root, + ) { + match message { + ActionsHeaderInput::PleaseOutput(output) => { + let _ = sender.output(output); + } + ActionsHeaderInput::ChangeActionOpen(now) => { + self.action_open = now; + } + ActionsHeaderInput::ActionsMapChanged(new_map) => { + self.action_map = new_map; + } + ActionsHeaderInput::AddStep(step_id) => { + // close popover + self.add_button.popdown(); + // unwrap rationale: the receiver will never be disconnected + sender + .output(ActionsHeaderOutput::AddStep(step_id)) + .unwrap(); + } + ActionsHeaderInput::AddTopSearchResult => { + if let Some(result) = self.search_results.get(0) { + widgets.menu_popover.popdown(); + let id = result.value(); + // unwrap rationale: the receiver will never be disconnected + sender.output(ActionsHeaderOutput::AddStep(id)).unwrap(); + } + } + ActionsHeaderInput::SearchForSteps(query) => { + let mut results = self.search_results.guard(); + results.clear(); + + // Reset scroll + let adj = widgets.menu_scrolled_area.vadjustment(); + adj.set_value(adj.lower()); + + // Collect results + if query.is_empty() { + // List all alphabetically + let mut unsorted_results = vec![]; + for engine in self.engine_list.inner() { + for instruction in &engine.instructions { + unsorted_results.push(( + format!("{}: {}", engine.name, instruction.friendly_name()), + engine.name.clone(), + instruction.clone(), + )); + } + } + + // Sort + unsorted_results.sort_by(|(a, _, _), (b, _, _)| a.cmp(b)); + for (_, engine_name, ins) in unsorted_results { + results.push_back(AddStepInit { + label: format!("{engine_name}: {}", ins.friendly_name()), + value: ins.id().clone(), + }); + } + } else { + let mut unsorted_results = vec![]; + use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher}; + let matcher = SkimMatcherV2::default(); + for engine in self.engine_list.inner() { + for instruction in &engine.instructions { + if let Some(score) = matcher.fuzzy_match( + &format!("{}: {}", engine.name, instruction.friendly_name()), + &query, + ) { + unsorted_results.push(( + score, + engine.name.clone(), + instruction.clone(), + )); + } + } + } + + // Sort + unsorted_results.sort_by(|(a, _, _), (b, _, _)| a.cmp(b)); + for (_, engine_name, ins) in unsorted_results { + results.push_back(AddStepInit { + label: format!("{engine_name}: {}", ins.friendly_name()), + value: ins.id().clone(), + }); + } + } + } + } + self.update_view(widgets, sender); + } +} diff --git a/testangel/src/ui/flows/header.rs b/testangel/src/ui/flows/header.rs index 8a4ecfa..ae413d9 100644 --- a/testangel/src/ui/flows/header.rs +++ b/testangel/src/ui/flows/header.rs @@ -1,228 +1,233 @@ -use std::sync::Arc; - -use adw::prelude::*; -use relm4::{ - adw, factory::FactoryVecDeque, gtk, Component, ComponentParts, ComponentSender, RelmWidgetExt, -}; -use testangel::action_loader::ActionMap; - -use crate::ui::{ - components::add_step_factory::{AddStepInit, AddStepResult, AddStepTrait}, - lang, -}; - -#[derive(Debug)] -pub struct FlowsHeader { - action_map: Arc, - add_button: gtk::MenuButton, - flow_open: bool, - search_results: FactoryVecDeque>, -} - -#[derive(Debug)] -pub enum FlowsHeaderOutput { - NewFlow, - OpenFlow, - SaveFlow, - SaveAsFlow, - CloseFlow, - RunFlow, - AddStep(String), -} - -#[derive(Debug)] -pub enum FlowsHeaderInput { - ActionsMapChanged(Arc), - /// Add the step with the action ID given - AddStep(String), - /// Trigger a search for the steps provided - SearchForSteps(String), - /// Add the top search result to the flow. - AddTopSearchResult, - /// Inform the header bar if a flow is open or not. - ChangeFlowOpen(bool), - /// Ask this to output the provided event - PleaseOutput(FlowsHeaderOutput), -} - -impl AddStepTrait for FlowsHeaderInput { - fn add_step(value: String) -> Self { - Self::AddStep(value) - } -} - -#[relm4::component(pub)] -impl Component for FlowsHeader { - type Init = Arc; - type Input = FlowsHeaderInput; - type Output = FlowsHeaderOutput; - type CommandOutput = (); - - view! { - #[root] - #[name = "start"] - gtk::Box { - set_spacing: 5, - - #[local_ref] - add_button -> gtk::MenuButton { - set_icon_name: relm4_icons::icon_name::PLUS, - set_tooltip: &lang::lookup("flow-header-add"), - - #[wrap(Some)] - #[name = "menu_popover"] - set_popover = >k::Popover { - gtk::Box { - set_spacing: 2, - set_orientation: gtk::Orientation::Vertical, - - gtk::SearchEntry { - set_max_width_chars: 20, - - connect_activate[sender] => move |_| { - sender.input(FlowsHeaderInput::AddTopSearchResult); - }, - - connect_search_changed[sender] => move |slf| { - let query = slf.text().to_string(); - sender.input(FlowsHeaderInput::SearchForSteps(query)); - }, - }, - - gtk::ScrolledWindow { - set_hscrollbar_policy: gtk::PolicyType::Never, - set_min_content_height: 150, - - #[local_ref] - results_box -> gtk::Box { - set_spacing: 2, - set_orientation: gtk::Orientation::Vertical, - }, - }, - }, - }, - }, - gtk::Button { - set_icon_name: relm4_icons::icon_name::PLAY, - set_tooltip: &lang::lookup("flow-header-run"), - #[watch] - set_sensitive: model.flow_open, - connect_clicked[sender] => move |_| { - // unwrap rationale: receivers will never be dropped - sender.output(FlowsHeaderOutput::RunFlow).unwrap(); - }, - }, - }, - } - - fn init( - init: Self::Init, - root: &Self::Root, - sender: ComponentSender, - ) -> ComponentParts { - let model = FlowsHeader { - action_map: init, - flow_open: false, - add_button: gtk::MenuButton::default(), - search_results: FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()), - }; - // Reset search results - sender.input(FlowsHeaderInput::SearchForSteps(String::new())); - - let results_box = model.search_results.widget(); - let add_button = &model.add_button; - let widgets = view_output!(); - - ComponentParts { model, widgets } - } - - fn update_with_view( - &mut self, - widgets: &mut Self::Widgets, - message: Self::Input, - sender: ComponentSender, - _root: &Self::Root, - ) { - match message { - FlowsHeaderInput::PleaseOutput(output) => { - let _ = sender.output(output); - } - FlowsHeaderInput::ChangeFlowOpen(now) => { - self.flow_open = now; - } - FlowsHeaderInput::ActionsMapChanged(new_map) => { - self.action_map = new_map; - } - FlowsHeaderInput::AddStep(step_id) => { - // close popover - self.add_button.popdown(); - // unwrap rationale: the receiver will never be disconnected - sender.output(FlowsHeaderOutput::AddStep(step_id)).unwrap(); - } - FlowsHeaderInput::AddTopSearchResult => { - if let Some(result) = self.search_results.get(0) { - widgets.menu_popover.popdown(); - let id = result.value(); - // unwrap rationale: the receiver will never be disconnected - sender.output(FlowsHeaderOutput::AddStep(id)).unwrap(); - } - } - FlowsHeaderInput::SearchForSteps(query) => { - let mut results = self.search_results.guard(); - results.clear(); - - let show_hidden = std::env::var("TA_SHOW_HIDDEN_ACTIONS") - .unwrap_or("no".to_string()) - .eq_ignore_ascii_case("yes"); - // Collect results - if query.is_empty() { - // List all alphabetically - let mut unsorted_results = vec![]; - for (group, actions) in self.action_map.get_by_group() { - for action in actions { - if action.visible || show_hidden { - unsorted_results - .push((format!("{group}: {}", action.friendly_name), action)); - } - } - } - - // Sort - unsorted_results.sort_by(|(a, _a), (b, _b)| a.cmp(b)); - for (_, a) in unsorted_results { - results.push_back(AddStepInit { - label: format!("{}: {}", a.group, a.friendly_name), - value: a.id, - }); - } - } else { - let mut unsorted_results = vec![]; - use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher}; - let matcher = SkimMatcherV2::default(); - for (group, actions) in self.action_map.get_by_group() { - for action in actions { - if action.visible || show_hidden { - if let Some(score) = matcher.fuzzy_match( - &format!("{group}: {}", action.friendly_name), - &query, - ) { - unsorted_results.push((score, action)); - } - } - } - } - - // Sort - unsorted_results.sort_by(|(a, _a), (b, _b)| a.cmp(b)); - for (_, a) in unsorted_results { - results.push_back(AddStepInit { - label: format!("{}: {}", a.group, a.friendly_name), - value: a.id, - }); - } - } - } - } - self.update_view(widgets, sender); - } -} +use std::sync::Arc; + +use adw::prelude::*; +use relm4::{ + adw, factory::FactoryVecDeque, gtk, Component, ComponentParts, ComponentSender, RelmWidgetExt, +}; +use testangel::action_loader::ActionMap; + +use crate::ui::{ + components::add_step_factory::{AddStepInit, AddStepResult, AddStepTrait}, + lang, +}; + +#[derive(Debug)] +pub struct FlowsHeader { + action_map: Arc, + add_button: gtk::MenuButton, + flow_open: bool, + search_results: FactoryVecDeque>, +} + +#[derive(Debug)] +pub enum FlowsHeaderOutput { + NewFlow, + OpenFlow, + SaveFlow, + SaveAsFlow, + CloseFlow, + RunFlow, + AddStep(String), +} + +#[derive(Debug)] +pub enum FlowsHeaderInput { + ActionsMapChanged(Arc), + /// Add the step with the action ID given + AddStep(String), + /// Trigger a search for the steps provided + SearchForSteps(String), + /// Add the top search result to the flow. + AddTopSearchResult, + /// Inform the header bar if a flow is open or not. + ChangeFlowOpen(bool), + /// Ask this to output the provided event + PleaseOutput(FlowsHeaderOutput), +} + +impl AddStepTrait for FlowsHeaderInput { + fn add_step(value: String) -> Self { + Self::AddStep(value) + } +} + +#[relm4::component(pub)] +impl Component for FlowsHeader { + type Init = Arc; + type Input = FlowsHeaderInput; + type Output = FlowsHeaderOutput; + type CommandOutput = (); + + view! { + #[root] + #[name = "start"] + gtk::Box { + set_spacing: 5, + + #[local_ref] + add_button -> gtk::MenuButton { + set_icon_name: relm4_icons::icon_name::PLUS, + set_tooltip: &lang::lookup("flow-header-add"), + + #[wrap(Some)] + #[name = "menu_popover"] + set_popover = >k::Popover { + gtk::Box { + set_spacing: 2, + set_orientation: gtk::Orientation::Vertical, + + gtk::SearchEntry { + set_max_width_chars: 20, + + connect_activate[sender] => move |_| { + sender.input(FlowsHeaderInput::AddTopSearchResult); + }, + + connect_search_changed[sender] => move |slf| { + let query = slf.text().to_string(); + sender.input(FlowsHeaderInput::SearchForSteps(query)); + }, + }, + + #[name = "menu_scrolled_area"] + gtk::ScrolledWindow { + set_hscrollbar_policy: gtk::PolicyType::Never, + set_min_content_height: 150, + + #[local_ref] + results_box -> gtk::Box { + set_spacing: 2, + set_orientation: gtk::Orientation::Vertical, + }, + }, + }, + }, + }, + gtk::Button { + set_icon_name: relm4_icons::icon_name::PLAY, + set_tooltip: &lang::lookup("flow-header-run"), + #[watch] + set_sensitive: model.flow_open, + connect_clicked[sender] => move |_| { + // unwrap rationale: receivers will never be dropped + sender.output(FlowsHeaderOutput::RunFlow).unwrap(); + }, + }, + }, + } + + fn init( + init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = FlowsHeader { + action_map: init, + flow_open: false, + add_button: gtk::MenuButton::default(), + search_results: FactoryVecDeque::new(gtk::Box::default(), sender.input_sender()), + }; + // Reset search results + sender.input(FlowsHeaderInput::SearchForSteps(String::new())); + + let results_box = model.search_results.widget(); + let add_button = &model.add_button; + let widgets = view_output!(); + + ComponentParts { model, widgets } + } + + fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::Input, + sender: ComponentSender, + _root: &Self::Root, + ) { + match message { + FlowsHeaderInput::PleaseOutput(output) => { + let _ = sender.output(output); + } + FlowsHeaderInput::ChangeFlowOpen(now) => { + self.flow_open = now; + } + FlowsHeaderInput::ActionsMapChanged(new_map) => { + self.action_map = new_map; + } + FlowsHeaderInput::AddStep(step_id) => { + // close popover + self.add_button.popdown(); + // unwrap rationale: the receiver will never be disconnected + sender.output(FlowsHeaderOutput::AddStep(step_id)).unwrap(); + } + FlowsHeaderInput::AddTopSearchResult => { + if let Some(result) = self.search_results.get(0) { + widgets.menu_popover.popdown(); + let id = result.value(); + // unwrap rationale: the receiver will never be disconnected + sender.output(FlowsHeaderOutput::AddStep(id)).unwrap(); + } + } + FlowsHeaderInput::SearchForSteps(query) => { + let mut results = self.search_results.guard(); + results.clear(); + + // Reset scroll + let adj = widgets.menu_scrolled_area.vadjustment(); + adj.set_value(adj.lower()); + + let show_hidden = std::env::var("TA_SHOW_HIDDEN_ACTIONS") + .unwrap_or("no".to_string()) + .eq_ignore_ascii_case("yes"); + // Collect results + if query.is_empty() { + // List all alphabetically + let mut unsorted_results = vec![]; + for (group, actions) in self.action_map.get_by_group() { + for action in actions { + if action.visible || show_hidden { + unsorted_results + .push((format!("{group}: {}", action.friendly_name), action)); + } + } + } + + // Sort + unsorted_results.sort_by(|(a, _a), (b, _b)| a.cmp(b)); + for (_, a) in unsorted_results { + results.push_back(AddStepInit { + label: format!("{}: {}", a.group, a.friendly_name), + value: a.id, + }); + } + } else { + let mut unsorted_results = vec![]; + use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher}; + let matcher = SkimMatcherV2::default(); + for (group, actions) in self.action_map.get_by_group() { + for action in actions { + if action.visible || show_hidden { + if let Some(score) = matcher.fuzzy_match( + &format!("{group}: {}", action.friendly_name), + &query, + ) { + unsorted_results.push((score, action)); + } + } + } + } + + // Sort + unsorted_results.sort_by(|(a, _a), (b, _b)| a.cmp(b)); + for (_, a) in unsorted_results { + results.push_back(AddStepInit { + label: format!("{}: {}", a.group, a.friendly_name), + value: a.id, + }); + } + } + } + } + self.update_view(widgets, sender); + } +} From 3a4d2c511929238dea4c1c9089d0c69fbb2da249 Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Wed, 6 Dec 2023 14:12:14 +0000 Subject: [PATCH 03/10] fix: visible switch too tall fixes #147 --- testangel/src/ui/actions/metadata_component.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testangel/src/ui/actions/metadata_component.rs b/testangel/src/ui/actions/metadata_component.rs index f3b9600..f71955d 100644 --- a/testangel/src/ui/actions/metadata_component.rs +++ b/testangel/src/ui/actions/metadata_component.rs @@ -83,6 +83,9 @@ impl Component for Metadata { #[name = "visible"] add_suffix = >k::Switch { + set_margin_top: 12, + set_margin_bottom: 12, + connect_state_set[sender] => move |_switch, state| { let _ = sender.output(MetadataOutput { new_visible: Some(state), From 4cdeedbc407e87e6ef5e7d28f67b0730c4e9bc39 Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Wed, 6 Dec 2023 14:14:58 +0000 Subject: [PATCH 04/10] fix: attempt to fix #144 --- testangel/data/icons.gresource.xml | 3 +++ testangel/data/icons/document-edit-symbolic.svg | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 testangel/data/icons/document-edit-symbolic.svg diff --git a/testangel/data/icons.gresource.xml b/testangel/data/icons.gresource.xml index cb6d533..4adba4f 100644 --- a/testangel/data/icons.gresource.xml +++ b/testangel/data/icons.gresource.xml @@ -3,4 +3,7 @@ icons/testangel.svg + + document-edit-symbolic.svg + diff --git a/testangel/data/icons/document-edit-symbolic.svg b/testangel/data/icons/document-edit-symbolic.svg new file mode 100644 index 0000000..d5d54f6 --- /dev/null +++ b/testangel/data/icons/document-edit-symbolic.svg @@ -0,0 +1,4 @@ + + + + From d8147f1edd75cc5af3d0e46e7c93e8adbcfffe31 Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Wed, 6 Dec 2023 14:21:14 +0000 Subject: [PATCH 05/10] fix: fixed save as accelerator fixes #152 --- testangel/src/ui/header_bar.rs | 610 ++++++++++++++++----------------- 1 file changed, 305 insertions(+), 305 deletions(-) diff --git a/testangel/src/ui/header_bar.rs b/testangel/src/ui/header_bar.rs index e3e5d31..c8975ad 100644 --- a/testangel/src/ui/header_bar.rs +++ b/testangel/src/ui/header_bar.rs @@ -1,305 +1,305 @@ -use std::{rc::Rc, sync::Arc}; - -use gtk::prelude::*; -use relm4::{ - actions::{AccelsPlus, RelmAction, RelmActionGroup}, - adw, gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, - RelmIterChildrenExt, RelmWidgetExt, -}; -use testangel::{action_loader::ActionMap, ipc::EngineList}; - -use crate::ui::lang; - -use super::{ - actions::header::{ActionsHeader, ActionsHeaderInput}, - flows::header::{FlowsHeader, FlowsHeaderInput}, -}; - -#[derive(Debug)] -pub enum HeaderBarInput { - ChangedView(String), - OpenAboutDialog, - ActionsMapChanged(Arc), - NewFile, - OpenFile, - SaveFile, - SaveAsFile, - CloseFile, -} - -#[derive(Debug)] -pub enum HeaderBarOutput { - AttachFileActionGroup(RelmActionGroup), - AttachGeneralActionGroup(RelmActionGroup), -} - -#[derive(Debug)] -enum MenuTarget { - Nothing, - Flows, - Actions, -} - -#[derive(Debug)] -pub struct HeaderBarModel { - currently_menu_target: MenuTarget, - engine_list: Arc, - action_map: Arc, - action_header_rc: Rc>, - flow_header_rc: Rc>, -} - -impl HeaderBarModel { - fn swap_content(&mut self, swap_target: >k::Box, new_content: >k::Box) { - for child in swap_target.iter_children() { - swap_target.remove(&child); - } - swap_target.append(new_content); - } -} - -#[relm4::component(pub)] -impl Component for HeaderBarModel { - type Init = ( - Rc>, - Rc>, - Rc, - Arc, - Arc, - ); - type Input = HeaderBarInput; - type Output = HeaderBarOutput; - type CommandOutput = (); - - view! { - #[root] - root = adw::HeaderBar { - #[name = "start_box"] - pack_start = >k::Box, - - #[wrap(Some)] - set_title_widget = &adw::ViewSwitcher { - #[local_ref] - #[wrap(Some)] - set_stack = stack -> adw::ViewStack, - }, - - pack_end = >k::MenuButton { - set_icon_name: relm4_icons::icon_name::MENU, - set_tooltip: &lang::lookup("header-more"), - set_direction: gtk::ArrowType::Down, - - #[wrap(Some)] - set_popover = >k::PopoverMenu::from_model(Some(&menu)) { - set_position: gtk::PositionType::Bottom, - }, - }, - } - } - - menu! { - menu: { - &lang::lookup("header-new") => FileNewAction, - &lang::lookup("header-open") => FileOpenAction, - &lang::lookup("header-save") => FileSaveAction, - &lang::lookup("header-save-as") => FileSaveAsAction, - &lang::lookup("header-close") => FileCloseAction, - section! { - &lang::lookup("header-about") => GeneralAboutAction, - } - } - } - - fn init( - init: Self::Init, - root: &Self::Root, - sender: ComponentSender, - ) -> ComponentParts { - let model = HeaderBarModel { - currently_menu_target: MenuTarget::Nothing, - action_header_rc: init.0, - flow_header_rc: init.1, - engine_list: init.3, - action_map: init.4, - }; - - let stack = &*init.2; - let widgets = view_output!(); - - let sender_c = sender.clone(); - let new_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::NewFile); - }); - relm4::main_application().set_accelerators_for_action::(&["N"]); - - let sender_c = sender.clone(); - let open_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::OpenFile); - }); - relm4::main_application().set_accelerators_for_action::(&["O"]); - - let sender_c = sender.clone(); - let save_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::SaveFile); - }); - relm4::main_application().set_accelerators_for_action::(&["S"]); - - let sender_c = sender.clone(); - let save_as_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::SaveAsFile); - }); - relm4::main_application().set_accelerators_for_action::(&["S"]); - - let sender_c = sender.clone(); - let close_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::CloseFile); - }); - relm4::main_application().set_accelerators_for_action::(&["W"]); - - let sender_c = sender.clone(); - let about_action: RelmAction = RelmAction::new_stateless(move |_| { - sender_c.input(HeaderBarInput::OpenAboutDialog); - }); - relm4::main_application().set_accelerators_for_action::(&["F1"]); - - let mut group = RelmActionGroup::::new(); - group.add_action(new_action); - group.add_action(open_action); - group.add_action(save_action); - group.add_action(save_as_action); - group.add_action(close_action); - let _ = sender.output(HeaderBarOutput::AttachFileActionGroup(group)); - - let mut group = RelmActionGroup::::new(); - group.add_action(about_action); - let _ = sender.output(HeaderBarOutput::AttachGeneralActionGroup(group)); - - ComponentParts { model, widgets } - } - - fn update_with_view( - &mut self, - widgets: &mut Self::Widgets, - message: Self::Input, - sender: ComponentSender, - root: &Self::Root, - ) { - match message { - HeaderBarInput::ActionsMapChanged(new_map) => self.action_map = new_map, - HeaderBarInput::OpenAboutDialog => { - crate::ui::about::AppAbout::builder() - .transient_for(root) - .launch((self.engine_list.clone(), self.action_map.clone())) - .widget() - .set_visible(true); - } - HeaderBarInput::ChangedView(new_view) => { - if new_view == "flows" { - let rc_clone = self.flow_header_rc.clone(); - self.swap_content(&widgets.start_box, &rc_clone.widgets().start); - self.currently_menu_target = MenuTarget::Flows; - } else if new_view == "actions" { - let rc_clone = self.action_header_rc.clone(); - self.swap_content(&widgets.start_box, &rc_clone.widgets().start); - self.currently_menu_target = MenuTarget::Actions; - } else { - self.swap_content(&widgets.start_box, >k::Box::builder().build()); - self.currently_menu_target = MenuTarget::Nothing; - } - } - HeaderBarInput::NewFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::NewFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::NewAction, - )); - } - }, - HeaderBarInput::OpenFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::OpenFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::OpenAction, - )); - } - }, - HeaderBarInput::SaveFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::SaveFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::SaveAction, - )); - } - }, - HeaderBarInput::SaveAsFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::SaveAsFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::SaveAsAction, - )); - } - }, - HeaderBarInput::CloseFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::CloseFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::CloseAction, - )); - } - }, - } - self.update_view(widgets, sender); - } -} - -relm4::new_action_group!(pub FileActionGroup, "file"); -relm4::new_stateless_action!(FileNewAction, FileActionGroup, "new"); -relm4::new_stateless_action!(FileOpenAction, FileActionGroup, "open"); -relm4::new_stateless_action!(FileSaveAction, FileActionGroup, "save"); -relm4::new_stateless_action!(FileSaveAsAction, FileActionGroup, "save-as"); -relm4::new_stateless_action!(FileCloseAction, FileActionGroup, "close"); - -impl std::fmt::Debug for FileActionGroup { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "FileActionGroup") - } -} - -relm4::new_action_group!(pub GeneralActionGroup, "general"); -relm4::new_stateless_action!(pub GeneralAboutAction, GeneralActionGroup, "about"); - -impl std::fmt::Debug for GeneralActionGroup { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "GeneralActionGroup") - } -} +use std::{rc::Rc, sync::Arc}; + +use gtk::prelude::*; +use relm4::{ + actions::{AccelsPlus, RelmAction, RelmActionGroup}, + adw, gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, + RelmIterChildrenExt, RelmWidgetExt, +}; +use testangel::{action_loader::ActionMap, ipc::EngineList}; + +use crate::ui::lang; + +use super::{ + actions::header::{ActionsHeader, ActionsHeaderInput}, + flows::header::{FlowsHeader, FlowsHeaderInput}, +}; + +#[derive(Debug)] +pub enum HeaderBarInput { + ChangedView(String), + OpenAboutDialog, + ActionsMapChanged(Arc), + NewFile, + OpenFile, + SaveFile, + SaveAsFile, + CloseFile, +} + +#[derive(Debug)] +pub enum HeaderBarOutput { + AttachFileActionGroup(RelmActionGroup), + AttachGeneralActionGroup(RelmActionGroup), +} + +#[derive(Debug)] +enum MenuTarget { + Nothing, + Flows, + Actions, +} + +#[derive(Debug)] +pub struct HeaderBarModel { + currently_menu_target: MenuTarget, + engine_list: Arc, + action_map: Arc, + action_header_rc: Rc>, + flow_header_rc: Rc>, +} + +impl HeaderBarModel { + fn swap_content(&mut self, swap_target: >k::Box, new_content: >k::Box) { + for child in swap_target.iter_children() { + swap_target.remove(&child); + } + swap_target.append(new_content); + } +} + +#[relm4::component(pub)] +impl Component for HeaderBarModel { + type Init = ( + Rc>, + Rc>, + Rc, + Arc, + Arc, + ); + type Input = HeaderBarInput; + type Output = HeaderBarOutput; + type CommandOutput = (); + + view! { + #[root] + root = adw::HeaderBar { + #[name = "start_box"] + pack_start = >k::Box, + + #[wrap(Some)] + set_title_widget = &adw::ViewSwitcher { + #[local_ref] + #[wrap(Some)] + set_stack = stack -> adw::ViewStack, + }, + + pack_end = >k::MenuButton { + set_icon_name: relm4_icons::icon_name::MENU, + set_tooltip: &lang::lookup("header-more"), + set_direction: gtk::ArrowType::Down, + + #[wrap(Some)] + set_popover = >k::PopoverMenu::from_model(Some(&menu)) { + set_position: gtk::PositionType::Bottom, + }, + }, + } + } + + menu! { + menu: { + &lang::lookup("header-new") => FileNewAction, + &lang::lookup("header-open") => FileOpenAction, + &lang::lookup("header-save") => FileSaveAction, + &lang::lookup("header-save-as") => FileSaveAsAction, + &lang::lookup("header-close") => FileCloseAction, + section! { + &lang::lookup("header-about") => GeneralAboutAction, + } + } + } + + fn init( + init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = HeaderBarModel { + currently_menu_target: MenuTarget::Nothing, + action_header_rc: init.0, + flow_header_rc: init.1, + engine_list: init.3, + action_map: init.4, + }; + + let stack = &*init.2; + let widgets = view_output!(); + + let sender_c = sender.clone(); + let new_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::NewFile); + }); + relm4::main_application().set_accelerators_for_action::(&["N"]); + + let sender_c = sender.clone(); + let open_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::OpenFile); + }); + relm4::main_application().set_accelerators_for_action::(&["O"]); + + let sender_c = sender.clone(); + let save_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::SaveFile); + }); + relm4::main_application().set_accelerators_for_action::(&["S"]); + + let sender_c = sender.clone(); + let save_as_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::SaveAsFile); + }); + relm4::main_application().set_accelerators_for_action::(&["S"]); + + let sender_c = sender.clone(); + let close_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::CloseFile); + }); + relm4::main_application().set_accelerators_for_action::(&["W"]); + + let sender_c = sender.clone(); + let about_action: RelmAction = RelmAction::new_stateless(move |_| { + sender_c.input(HeaderBarInput::OpenAboutDialog); + }); + relm4::main_application().set_accelerators_for_action::(&["F1"]); + + let mut group = RelmActionGroup::::new(); + group.add_action(new_action); + group.add_action(open_action); + group.add_action(save_action); + group.add_action(save_as_action); + group.add_action(close_action); + let _ = sender.output(HeaderBarOutput::AttachFileActionGroup(group)); + + let mut group = RelmActionGroup::::new(); + group.add_action(about_action); + let _ = sender.output(HeaderBarOutput::AttachGeneralActionGroup(group)); + + ComponentParts { model, widgets } + } + + fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::Input, + sender: ComponentSender, + root: &Self::Root, + ) { + match message { + HeaderBarInput::ActionsMapChanged(new_map) => self.action_map = new_map, + HeaderBarInput::OpenAboutDialog => { + crate::ui::about::AppAbout::builder() + .transient_for(root) + .launch((self.engine_list.clone(), self.action_map.clone())) + .widget() + .set_visible(true); + } + HeaderBarInput::ChangedView(new_view) => { + if new_view == "flows" { + let rc_clone = self.flow_header_rc.clone(); + self.swap_content(&widgets.start_box, &rc_clone.widgets().start); + self.currently_menu_target = MenuTarget::Flows; + } else if new_view == "actions" { + let rc_clone = self.action_header_rc.clone(); + self.swap_content(&widgets.start_box, &rc_clone.widgets().start); + self.currently_menu_target = MenuTarget::Actions; + } else { + self.swap_content(&widgets.start_box, >k::Box::builder().build()); + self.currently_menu_target = MenuTarget::Nothing; + } + } + HeaderBarInput::NewFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::NewFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::NewAction, + )); + } + }, + HeaderBarInput::OpenFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::OpenFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::OpenAction, + )); + } + }, + HeaderBarInput::SaveFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::SaveFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::SaveAction, + )); + } + }, + HeaderBarInput::SaveAsFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::SaveAsFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::SaveAsAction, + )); + } + }, + HeaderBarInput::CloseFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::CloseFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::CloseAction, + )); + } + }, + } + self.update_view(widgets, sender); + } +} + +relm4::new_action_group!(pub FileActionGroup, "file"); +relm4::new_stateless_action!(FileNewAction, FileActionGroup, "new"); +relm4::new_stateless_action!(FileOpenAction, FileActionGroup, "open"); +relm4::new_stateless_action!(FileSaveAction, FileActionGroup, "save"); +relm4::new_stateless_action!(FileSaveAsAction, FileActionGroup, "save-as"); +relm4::new_stateless_action!(FileCloseAction, FileActionGroup, "close"); + +impl std::fmt::Debug for FileActionGroup { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "FileActionGroup") + } +} + +relm4::new_action_group!(pub GeneralActionGroup, "general"); +relm4::new_stateless_action!(pub GeneralAboutAction, GeneralActionGroup, "about"); + +impl std::fmt::Debug for GeneralActionGroup { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "GeneralActionGroup") + } +} From 803be396132a144a9b006ba13d9cbf5d076001b4 Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Wed, 6 Dec 2023 14:21:35 +0000 Subject: [PATCH 06/10] fix: edit icon in metadata fixes #148 --- testangel/data/icons.gresource.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testangel/data/icons.gresource.xml b/testangel/data/icons.gresource.xml index 4adba4f..a2d48db 100644 --- a/testangel/data/icons.gresource.xml +++ b/testangel/data/icons.gresource.xml @@ -3,7 +3,7 @@ icons/testangel.svg - - document-edit-symbolic.svg + + icons/document-edit-symbolic.svg From 6af5d719f4c8c0fc9e2cd833122dd6aa5850edcb Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Wed, 6 Dec 2023 14:28:11 +0000 Subject: [PATCH 07/10] fix: popover pops down after source selected fixes #154 --- testangel/src/ui/components/variable_row.rs | 19 +- testangel/src/ui/header_bar.rs | 611 ++++++++++---------- 2 files changed, 319 insertions(+), 311 deletions(-) diff --git a/testangel/src/ui/components/variable_row.rs b/testangel/src/ui/components/variable_row.rs index 858334c..27cff8c 100644 --- a/testangel/src/ui/components/variable_row.rs +++ b/testangel/src/ui/components/variable_row.rs @@ -139,11 +139,9 @@ where self.literal_input.widget(), } } else { - adw::Bin { - gtk::Label { - #[watch] - set_label: &self.get_nice_name_for(&self.source), - }, + gtk::Label { + #[watch] + set_label: &self.get_nice_name_for(&self.source), } }, @@ -154,6 +152,7 @@ where set_direction: gtk::ArrowType::Left, #[wrap(Some)] + #[name = "popover"] set_popover = >k::Popover { gtk::ScrolledWindow { set_hscrollbar_policy: gtk::PolicyType::Never, @@ -219,10 +218,17 @@ where widgets } - fn update(&mut self, message: Self::Input, sender: FactorySender) { + fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::Input, + sender: FactorySender, + ) { match message { VariableRowInput::SourceSelected(new_source) => { self.source = new_source.clone(); + widgets.popover.popdown(); + sender.output(VariableRowOutput::NewSourceFor( self.idx.clone(), new_source, @@ -233,6 +239,7 @@ where sender.output(VariableRowOutput::NewValueFor(self.idx.clone(), new_value)); } } + self.update_view(widgets, sender); } fn forward_to_parent(output: Self::Output) -> Option { diff --git a/testangel/src/ui/header_bar.rs b/testangel/src/ui/header_bar.rs index c8975ad..06c9ee3 100644 --- a/testangel/src/ui/header_bar.rs +++ b/testangel/src/ui/header_bar.rs @@ -1,305 +1,306 @@ -use std::{rc::Rc, sync::Arc}; - -use gtk::prelude::*; -use relm4::{ - actions::{AccelsPlus, RelmAction, RelmActionGroup}, - adw, gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, - RelmIterChildrenExt, RelmWidgetExt, -}; -use testangel::{action_loader::ActionMap, ipc::EngineList}; - -use crate::ui::lang; - -use super::{ - actions::header::{ActionsHeader, ActionsHeaderInput}, - flows::header::{FlowsHeader, FlowsHeaderInput}, -}; - -#[derive(Debug)] -pub enum HeaderBarInput { - ChangedView(String), - OpenAboutDialog, - ActionsMapChanged(Arc), - NewFile, - OpenFile, - SaveFile, - SaveAsFile, - CloseFile, -} - -#[derive(Debug)] -pub enum HeaderBarOutput { - AttachFileActionGroup(RelmActionGroup), - AttachGeneralActionGroup(RelmActionGroup), -} - -#[derive(Debug)] -enum MenuTarget { - Nothing, - Flows, - Actions, -} - -#[derive(Debug)] -pub struct HeaderBarModel { - currently_menu_target: MenuTarget, - engine_list: Arc, - action_map: Arc, - action_header_rc: Rc>, - flow_header_rc: Rc>, -} - -impl HeaderBarModel { - fn swap_content(&mut self, swap_target: >k::Box, new_content: >k::Box) { - for child in swap_target.iter_children() { - swap_target.remove(&child); - } - swap_target.append(new_content); - } -} - -#[relm4::component(pub)] -impl Component for HeaderBarModel { - type Init = ( - Rc>, - Rc>, - Rc, - Arc, - Arc, - ); - type Input = HeaderBarInput; - type Output = HeaderBarOutput; - type CommandOutput = (); - - view! { - #[root] - root = adw::HeaderBar { - #[name = "start_box"] - pack_start = >k::Box, - - #[wrap(Some)] - set_title_widget = &adw::ViewSwitcher { - #[local_ref] - #[wrap(Some)] - set_stack = stack -> adw::ViewStack, - }, - - pack_end = >k::MenuButton { - set_icon_name: relm4_icons::icon_name::MENU, - set_tooltip: &lang::lookup("header-more"), - set_direction: gtk::ArrowType::Down, - - #[wrap(Some)] - set_popover = >k::PopoverMenu::from_model(Some(&menu)) { - set_position: gtk::PositionType::Bottom, - }, - }, - } - } - - menu! { - menu: { - &lang::lookup("header-new") => FileNewAction, - &lang::lookup("header-open") => FileOpenAction, - &lang::lookup("header-save") => FileSaveAction, - &lang::lookup("header-save-as") => FileSaveAsAction, - &lang::lookup("header-close") => FileCloseAction, - section! { - &lang::lookup("header-about") => GeneralAboutAction, - } - } - } - - fn init( - init: Self::Init, - root: &Self::Root, - sender: ComponentSender, - ) -> ComponentParts { - let model = HeaderBarModel { - currently_menu_target: MenuTarget::Nothing, - action_header_rc: init.0, - flow_header_rc: init.1, - engine_list: init.3, - action_map: init.4, - }; - - let stack = &*init.2; - let widgets = view_output!(); - - let sender_c = sender.clone(); - let new_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::NewFile); - }); - relm4::main_application().set_accelerators_for_action::(&["N"]); - - let sender_c = sender.clone(); - let open_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::OpenFile); - }); - relm4::main_application().set_accelerators_for_action::(&["O"]); - - let sender_c = sender.clone(); - let save_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::SaveFile); - }); - relm4::main_application().set_accelerators_for_action::(&["S"]); - - let sender_c = sender.clone(); - let save_as_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::SaveAsFile); - }); - relm4::main_application().set_accelerators_for_action::(&["S"]); - - let sender_c = sender.clone(); - let close_action: RelmAction = RelmAction::new_stateless(move |_| { - // unwrap rationale: receiver will never be disconnected - sender_c.input(HeaderBarInput::CloseFile); - }); - relm4::main_application().set_accelerators_for_action::(&["W"]); - - let sender_c = sender.clone(); - let about_action: RelmAction = RelmAction::new_stateless(move |_| { - sender_c.input(HeaderBarInput::OpenAboutDialog); - }); - relm4::main_application().set_accelerators_for_action::(&["F1"]); - - let mut group = RelmActionGroup::::new(); - group.add_action(new_action); - group.add_action(open_action); - group.add_action(save_action); - group.add_action(save_as_action); - group.add_action(close_action); - let _ = sender.output(HeaderBarOutput::AttachFileActionGroup(group)); - - let mut group = RelmActionGroup::::new(); - group.add_action(about_action); - let _ = sender.output(HeaderBarOutput::AttachGeneralActionGroup(group)); - - ComponentParts { model, widgets } - } - - fn update_with_view( - &mut self, - widgets: &mut Self::Widgets, - message: Self::Input, - sender: ComponentSender, - root: &Self::Root, - ) { - match message { - HeaderBarInput::ActionsMapChanged(new_map) => self.action_map = new_map, - HeaderBarInput::OpenAboutDialog => { - crate::ui::about::AppAbout::builder() - .transient_for(root) - .launch((self.engine_list.clone(), self.action_map.clone())) - .widget() - .set_visible(true); - } - HeaderBarInput::ChangedView(new_view) => { - if new_view == "flows" { - let rc_clone = self.flow_header_rc.clone(); - self.swap_content(&widgets.start_box, &rc_clone.widgets().start); - self.currently_menu_target = MenuTarget::Flows; - } else if new_view == "actions" { - let rc_clone = self.action_header_rc.clone(); - self.swap_content(&widgets.start_box, &rc_clone.widgets().start); - self.currently_menu_target = MenuTarget::Actions; - } else { - self.swap_content(&widgets.start_box, >k::Box::builder().build()); - self.currently_menu_target = MenuTarget::Nothing; - } - } - HeaderBarInput::NewFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::NewFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::NewAction, - )); - } - }, - HeaderBarInput::OpenFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::OpenFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::OpenAction, - )); - } - }, - HeaderBarInput::SaveFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::SaveFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::SaveAction, - )); - } - }, - HeaderBarInput::SaveAsFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::SaveAsFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::SaveAsAction, - )); - } - }, - HeaderBarInput::CloseFile => match self.currently_menu_target { - MenuTarget::Nothing => (), - MenuTarget::Flows => { - self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( - super::flows::header::FlowsHeaderOutput::CloseFlow, - )); - } - MenuTarget::Actions => { - self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( - super::actions::header::ActionsHeaderOutput::CloseAction, - )); - } - }, - } - self.update_view(widgets, sender); - } -} - -relm4::new_action_group!(pub FileActionGroup, "file"); -relm4::new_stateless_action!(FileNewAction, FileActionGroup, "new"); -relm4::new_stateless_action!(FileOpenAction, FileActionGroup, "open"); -relm4::new_stateless_action!(FileSaveAction, FileActionGroup, "save"); -relm4::new_stateless_action!(FileSaveAsAction, FileActionGroup, "save-as"); -relm4::new_stateless_action!(FileCloseAction, FileActionGroup, "close"); - -impl std::fmt::Debug for FileActionGroup { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "FileActionGroup") - } -} - -relm4::new_action_group!(pub GeneralActionGroup, "general"); -relm4::new_stateless_action!(pub GeneralAboutAction, GeneralActionGroup, "about"); - -impl std::fmt::Debug for GeneralActionGroup { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "GeneralActionGroup") - } -} +use std::{rc::Rc, sync::Arc}; + +use gtk::prelude::*; +use relm4::{ + actions::{AccelsPlus, RelmAction, RelmActionGroup}, + adw, gtk, Component, ComponentController, ComponentParts, ComponentSender, Controller, + RelmIterChildrenExt, RelmWidgetExt, +}; +use testangel::{action_loader::ActionMap, ipc::EngineList}; + +use crate::ui::lang; + +use super::{ + actions::header::{ActionsHeader, ActionsHeaderInput}, + flows::header::{FlowsHeader, FlowsHeaderInput}, +}; + +#[derive(Debug)] +pub enum HeaderBarInput { + ChangedView(String), + OpenAboutDialog, + ActionsMapChanged(Arc), + NewFile, + OpenFile, + SaveFile, + SaveAsFile, + CloseFile, +} + +#[derive(Debug)] +pub enum HeaderBarOutput { + AttachFileActionGroup(RelmActionGroup), + AttachGeneralActionGroup(RelmActionGroup), +} + +#[derive(Debug)] +enum MenuTarget { + Nothing, + Flows, + Actions, +} + +#[derive(Debug)] +pub struct HeaderBarModel { + currently_menu_target: MenuTarget, + engine_list: Arc, + action_map: Arc, + action_header_rc: Rc>, + flow_header_rc: Rc>, +} + +impl HeaderBarModel { + fn swap_content(&mut self, swap_target: >k::Box, new_content: >k::Box) { + for child in swap_target.iter_children() { + swap_target.remove(&child); + } + swap_target.append(new_content); + } +} + +#[relm4::component(pub)] +impl Component for HeaderBarModel { + type Init = ( + Rc>, + Rc>, + Rc, + Arc, + Arc, + ); + type Input = HeaderBarInput; + type Output = HeaderBarOutput; + type CommandOutput = (); + + view! { + #[root] + root = adw::HeaderBar { + #[name = "start_box"] + pack_start = >k::Box, + + #[wrap(Some)] + set_title_widget = &adw::ViewSwitcher { + #[local_ref] + #[wrap(Some)] + set_stack = stack -> adw::ViewStack, + }, + + pack_end = >k::MenuButton { + set_icon_name: relm4_icons::icon_name::MENU, + set_tooltip: &lang::lookup("header-more"), + set_direction: gtk::ArrowType::Down, + + #[wrap(Some)] + set_popover = >k::PopoverMenu::from_model(Some(&menu)) { + set_position: gtk::PositionType::Bottom, + }, + }, + } + } + + menu! { + menu: { + &lang::lookup("header-new") => FileNewAction, + &lang::lookup("header-open") => FileOpenAction, + &lang::lookup("header-save") => FileSaveAction, + &lang::lookup("header-save-as") => FileSaveAsAction, + &lang::lookup("header-close") => FileCloseAction, + section! { + &lang::lookup("header-about") => GeneralAboutAction, + } + } + } + + fn init( + init: Self::Init, + root: &Self::Root, + sender: ComponentSender, + ) -> ComponentParts { + let model = HeaderBarModel { + currently_menu_target: MenuTarget::Nothing, + action_header_rc: init.0, + flow_header_rc: init.1, + engine_list: init.3, + action_map: init.4, + }; + + let stack = &*init.2; + let widgets = view_output!(); + + let sender_c = sender.clone(); + let new_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::NewFile); + }); + relm4::main_application().set_accelerators_for_action::(&["N"]); + + let sender_c = sender.clone(); + let open_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::OpenFile); + }); + relm4::main_application().set_accelerators_for_action::(&["O"]); + + let sender_c = sender.clone(); + let save_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::SaveFile); + }); + relm4::main_application().set_accelerators_for_action::(&["S"]); + + let sender_c = sender.clone(); + let save_as_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::SaveAsFile); + }); + relm4::main_application() + .set_accelerators_for_action::(&["S"]); + + let sender_c = sender.clone(); + let close_action: RelmAction = RelmAction::new_stateless(move |_| { + // unwrap rationale: receiver will never be disconnected + sender_c.input(HeaderBarInput::CloseFile); + }); + relm4::main_application().set_accelerators_for_action::(&["W"]); + + let sender_c = sender.clone(); + let about_action: RelmAction = RelmAction::new_stateless(move |_| { + sender_c.input(HeaderBarInput::OpenAboutDialog); + }); + relm4::main_application().set_accelerators_for_action::(&["F1"]); + + let mut group = RelmActionGroup::::new(); + group.add_action(new_action); + group.add_action(open_action); + group.add_action(save_action); + group.add_action(save_as_action); + group.add_action(close_action); + let _ = sender.output(HeaderBarOutput::AttachFileActionGroup(group)); + + let mut group = RelmActionGroup::::new(); + group.add_action(about_action); + let _ = sender.output(HeaderBarOutput::AttachGeneralActionGroup(group)); + + ComponentParts { model, widgets } + } + + fn update_with_view( + &mut self, + widgets: &mut Self::Widgets, + message: Self::Input, + sender: ComponentSender, + root: &Self::Root, + ) { + match message { + HeaderBarInput::ActionsMapChanged(new_map) => self.action_map = new_map, + HeaderBarInput::OpenAboutDialog => { + crate::ui::about::AppAbout::builder() + .transient_for(root) + .launch((self.engine_list.clone(), self.action_map.clone())) + .widget() + .set_visible(true); + } + HeaderBarInput::ChangedView(new_view) => { + if new_view == "flows" { + let rc_clone = self.flow_header_rc.clone(); + self.swap_content(&widgets.start_box, &rc_clone.widgets().start); + self.currently_menu_target = MenuTarget::Flows; + } else if new_view == "actions" { + let rc_clone = self.action_header_rc.clone(); + self.swap_content(&widgets.start_box, &rc_clone.widgets().start); + self.currently_menu_target = MenuTarget::Actions; + } else { + self.swap_content(&widgets.start_box, >k::Box::builder().build()); + self.currently_menu_target = MenuTarget::Nothing; + } + } + HeaderBarInput::NewFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::NewFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::NewAction, + )); + } + }, + HeaderBarInput::OpenFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::OpenFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::OpenAction, + )); + } + }, + HeaderBarInput::SaveFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::SaveFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::SaveAction, + )); + } + }, + HeaderBarInput::SaveAsFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::SaveAsFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::SaveAsAction, + )); + } + }, + HeaderBarInput::CloseFile => match self.currently_menu_target { + MenuTarget::Nothing => (), + MenuTarget::Flows => { + self.flow_header_rc.emit(FlowsHeaderInput::PleaseOutput( + super::flows::header::FlowsHeaderOutput::CloseFlow, + )); + } + MenuTarget::Actions => { + self.action_header_rc.emit(ActionsHeaderInput::PleaseOutput( + super::actions::header::ActionsHeaderOutput::CloseAction, + )); + } + }, + } + self.update_view(widgets, sender); + } +} + +relm4::new_action_group!(pub FileActionGroup, "file"); +relm4::new_stateless_action!(FileNewAction, FileActionGroup, "new"); +relm4::new_stateless_action!(FileOpenAction, FileActionGroup, "open"); +relm4::new_stateless_action!(FileSaveAction, FileActionGroup, "save"); +relm4::new_stateless_action!(FileSaveAsAction, FileActionGroup, "save-as"); +relm4::new_stateless_action!(FileCloseAction, FileActionGroup, "close"); + +impl std::fmt::Debug for FileActionGroup { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "FileActionGroup") + } +} + +relm4::new_action_group!(pub GeneralActionGroup, "general"); +relm4::new_stateless_action!(pub GeneralAboutAction, GeneralActionGroup, "about"); + +impl std::fmt::Debug for GeneralActionGroup { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "GeneralActionGroup") + } +} From bb77168af699d333b58612e5cb4f182592e3b289 Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Wed, 6 Dec 2023 14:31:34 +0000 Subject: [PATCH 08/10] fix: fixed very tall elements fixes #149 --- testangel/src/ui/actions/instruction_component.rs | 10 ++++++++++ testangel/src/ui/flows/action_component.rs | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/testangel/src/ui/actions/instruction_component.rs b/testangel/src/ui/actions/instruction_component.rs index df0592f..d2b2ca3 100644 --- a/testangel/src/ui/actions/instruction_component.rs +++ b/testangel/src/ui/actions/instruction_component.rs @@ -131,6 +131,8 @@ impl FactoryComponent for InstructionComponent { .collect::>() .as_slice())), set_selected: self.run_condition_index, + set_valign: gtk::Align::Start, + set_height_request: 30, connect_selected_notify[sender] => move |dropdown| { let idx = dropdown.selected(); @@ -140,6 +142,8 @@ impl FactoryComponent for InstructionComponent { gtk::MenuButton::builder().css_classes(["flat"]).build() { set_icon_name: relm4_icons::icon_name::TAG, set_tooltip: &lang::lookup("action-step-set-comment"), + set_valign: gtk::Align::Start, + set_height_request: 30, #[wrap(Some)] set_popover = >k::Popover { @@ -156,6 +160,8 @@ impl FactoryComponent for InstructionComponent { gtk::Button::builder().css_classes(["flat"]).build() { set_icon_name: relm4_icons::icon_name::UP, set_tooltip: &lang::lookup("move-up"), + set_valign: gtk::Align::Start, + set_height_request: 30, connect_clicked[sender, index, config] => move |_| { if index.clone().current_index() != 0 { @@ -167,6 +173,8 @@ impl FactoryComponent for InstructionComponent { gtk::Button::builder().css_classes(["flat"]).build() { set_icon_name: relm4_icons::icon_name::DOWN, set_tooltip: &lang::lookup("move-down"), + set_valign: gtk::Align::Start, + set_height_request: 30, connect_clicked[sender, index, config] => move |_| { sender.output(InstructionComponentOutput::Cut(index.clone())); @@ -176,6 +184,8 @@ impl FactoryComponent for InstructionComponent { gtk::Button::builder().css_classes(["flat"]).build() { set_icon_name: relm4_icons::icon_name::X_CIRCULAR, set_tooltip: &lang::lookup("delete-step"), + set_valign: gtk::Align::Start, + set_height_request: 30, connect_clicked[sender, index] => move |_| { sender.output(InstructionComponentOutput::Remove(index.clone())); diff --git a/testangel/src/ui/flows/action_component.rs b/testangel/src/ui/flows/action_component.rs index 831cb67..4910815 100644 --- a/testangel/src/ui/flows/action_component.rs +++ b/testangel/src/ui/flows/action_component.rs @@ -120,6 +120,8 @@ impl FactoryComponent for ActionComponent { gtk::Button::builder().css_classes(["flat"]).build() { set_icon_name: relm4_icons::icon_name::UP, set_tooltip: &lang::lookup("move-up"), + set_valign: gtk::Align::Start, + set_height_request: 30, connect_clicked[sender, index, config] => move |_| { if index.clone().current_index() != 0 { @@ -131,6 +133,8 @@ impl FactoryComponent for ActionComponent { gtk::Button::builder().css_classes(["flat"]).build() { set_icon_name: relm4_icons::icon_name::DOWN, set_tooltip: &lang::lookup("move-down"), + set_valign: gtk::Align::Start, + set_height_request: 30, connect_clicked[sender, index, config] => move |_| { sender.output(ActionComponentOutput::Cut(index.clone())); @@ -140,6 +144,8 @@ impl FactoryComponent for ActionComponent { gtk::Button::builder().css_classes(["flat"]).build() { set_icon_name: relm4_icons::icon_name::X_CIRCULAR, set_tooltip: &lang::lookup("delete-step"), + set_valign: gtk::Align::Start, + set_height_request: 30, connect_clicked[sender, index] => move |_| { sender.output(ActionComponentOutput::Remove(index.clone())); From 8c22868696cff866a119b84ea7cb53ed92b27e42 Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Wed, 6 Dec 2023 14:34:03 +0000 Subject: [PATCH 09/10] fix: reset search results when actions are reloaded fixes #155 --- testangel/src/ui/flows/header.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/testangel/src/ui/flows/header.rs b/testangel/src/ui/flows/header.rs index ae413d9..91d3218 100644 --- a/testangel/src/ui/flows/header.rs +++ b/testangel/src/ui/flows/header.rs @@ -153,6 +153,7 @@ impl Component for FlowsHeader { } FlowsHeaderInput::ActionsMapChanged(new_map) => { self.action_map = new_map; + sender.input(FlowsHeaderInput::SearchForSteps(String::new())); } FlowsHeaderInput::AddStep(step_id) => { // close popover From 3a3f385d700cac32abf4cf3c0948c7508561e012 Mon Sep 17 00:00:00 2001 From: Lily Hopkins Date: Wed, 6 Dec 2023 14:35:26 +0000 Subject: [PATCH 10/10] chore: bumped version --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e700e1d..7059c39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3369,7 +3369,7 @@ dependencies = [ [[package]] name = "testangel" -version = "0.20.0" +version = "0.20.1" dependencies = [ "base64 0.21.5", "chrono", @@ -3401,7 +3401,7 @@ dependencies = [ [[package]] name = "testangel-arithmetic" -version = "0.20.0" +version = "0.20.1" dependencies = [ "lazy_static", "testangel-engine", @@ -3409,7 +3409,7 @@ dependencies = [ [[package]] name = "testangel-compare" -version = "0.20.0" +version = "0.20.1" dependencies = [ "lazy_static", "testangel-engine", @@ -3417,7 +3417,7 @@ dependencies = [ [[package]] name = "testangel-convert" -version = "0.20.0" +version = "0.20.1" dependencies = [ "lazy_static", "testangel-engine", @@ -3425,7 +3425,7 @@ dependencies = [ [[package]] name = "testangel-date" -version = "0.20.0" +version = "0.20.1" dependencies = [ "chrono", "lazy_static", @@ -3434,7 +3434,7 @@ dependencies = [ [[package]] name = "testangel-engine" -version = "0.20.0" +version = "0.20.1" dependencies = [ "testangel-engine-macros", "testangel-ipc", @@ -3442,11 +3442,11 @@ dependencies = [ [[package]] name = "testangel-engine-macros" -version = "0.20.0" +version = "0.20.1" [[package]] name = "testangel-evidence" -version = "0.20.0" +version = "0.20.1" dependencies = [ "lazy_static", "testangel-engine", @@ -3454,7 +3454,7 @@ dependencies = [ [[package]] name = "testangel-ipc" -version = "0.20.0" +version = "0.20.1" dependencies = [ "schemars", "serde", @@ -3463,7 +3463,7 @@ dependencies = [ [[package]] name = "testangel-rand" -version = "0.20.0" +version = "0.20.1" dependencies = [ "lazy_static", "rand", @@ -3474,7 +3474,7 @@ dependencies = [ [[package]] name = "testangel-regex" -version = "0.20.0" +version = "0.20.1" dependencies = [ "lazy_static", "regex", @@ -3484,7 +3484,7 @@ dependencies = [ [[package]] name = "testangel-user-interaction" -version = "0.20.0" +version = "0.20.1" dependencies = [ "lazy_static", "rfd", diff --git a/Cargo.toml b/Cargo.toml index 858c663..a59223a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "0.20.0" +version = "0.20.1" edition = "2021" [workspace]