mirror of
https://github.com/0x192/universal-android-debloater.git
synced 2025-12-21 13:20:38 -06:00
feat: add an recap modal window (#565)
A modal window will now appear to give you a recap of the selected packages before applying the changes. A complete overhaul of the way UAD handles package selection was required to implement this feature.
This commit is contained in:
295
Cargo.lock
generated
295
Cargo.lock
generated
@@ -4,9 +4,9 @@ version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ab_glyph"
|
||||
version = "0.2.19"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5568a4aa5ba8adf5175c5c460b030e27d8893412976cc37bef0e4fbc16cfbba"
|
||||
checksum = "fe21446ad43aa56417a767f3e2f3d7c4ca522904de1dd640529a76e9c5c3b33c"
|
||||
dependencies = [
|
||||
"ab_glyph_rasterizer",
|
||||
"owned_ttf_parser",
|
||||
@@ -141,24 +141,24 @@ checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.11.1"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
||||
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.12.3"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f"
|
||||
checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393"
|
||||
dependencies = [
|
||||
"bytemuck_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck_derive"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fe233b960f12f8007e3db2d136e3cb1c291bfd7396e384ee76025fc1a3932b4"
|
||||
checksum = "1aca418a974d83d40a0c1f0c5cba6ff4bc28d8df099109ca459a2118d40b6322"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -186,9 +186,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.78"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -470,9 +470,9 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.86"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579"
|
||||
checksum = "bc831ee6a32dd495436e317595e639a587aa9907bef96fe6e6abc290ab6204e9"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
@@ -482,9 +482,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.86"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70"
|
||||
checksum = "94331d54f1b1a8895cd81049f7eaaaef9d05a7dcb4d1fd08bf3ff0806246789d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
@@ -497,15 +497,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.86"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c"
|
||||
checksum = "48dcd35ba14ca9b40d6e4b4b39961f23d835dbb8eed74565ded361d93e1feb8a"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.86"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5"
|
||||
checksum = "81bbeb29798b407ccd82a3324ade1a7286e0d29851475990b612670f6f5124d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -615,9 +615,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
|
||||
[[package]]
|
||||
name = "encase"
|
||||
@@ -708,7 +708,7 @@ version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2"
|
||||
dependencies = [
|
||||
"toml",
|
||||
"toml 0.5.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -802,9 +802,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
|
||||
checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@@ -817,9 +817,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
|
||||
checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@@ -827,15 +827,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
||||
checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
|
||||
checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@@ -845,15 +845,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
|
||||
checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
|
||||
checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -862,21 +862,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
||||
checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
||||
checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
||||
checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@@ -1169,7 +1169,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced"
|
||||
version = "0.7.0"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"iced_core",
|
||||
"iced_futures",
|
||||
@@ -1185,7 +1185,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced_core"
|
||||
version = "0.7.0"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"instant",
|
||||
@@ -1195,7 +1195,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced_futures"
|
||||
version = "0.5.1"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"log",
|
||||
@@ -1206,7 +1206,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced_glow"
|
||||
version = "0.6.0"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"euclid",
|
||||
@@ -1221,7 +1221,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced_glutin"
|
||||
version = "0.6.0"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"glutin",
|
||||
"iced_graphics",
|
||||
@@ -1233,7 +1233,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced_graphics"
|
||||
version = "0.6.0"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytemuck",
|
||||
@@ -1248,7 +1248,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced_native"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"iced_core",
|
||||
"iced_futures",
|
||||
@@ -1261,7 +1261,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced_style"
|
||||
version = "0.6.0"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"iced_core",
|
||||
"once_cell",
|
||||
@@ -1271,7 +1271,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced_wgpu"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytemuck",
|
||||
@@ -1291,7 +1291,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "iced_winit"
|
||||
version = "0.7.0"
|
||||
source = "git+https://github.com/iced-rs/iced.git#18552f96df5d1fa72c3c87e96a5765f89c340e19"
|
||||
source = "git+https://github.com/iced-rs/iced.git#98a717383acf71d7939d7cc90d350743487f0380"
|
||||
dependencies = [
|
||||
"iced_futures",
|
||||
"iced_graphics",
|
||||
@@ -1356,9 +1356,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.60"
|
||||
version = "0.3.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||
checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -1637,14 +1637,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.2"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom8"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
@@ -1676,18 +1685,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.5.7"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9"
|
||||
checksum = "8d829733185c1ca374f17e52b762f24f535ec625d2cc1f070e34c8a9068f341b"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.5.7"
|
||||
version = "0.5.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce"
|
||||
checksum = "2be1598bf1c313dcdd12092e3f1920f463462525a21b7b4e11b4168353d0123e"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
@@ -1760,9 +1769,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "owned_ttf_parser"
|
||||
version = "0.18.0"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a5f3c7ca08b6879e7965fb25e24d1f5eeb32ea73f9ad99b3854778a38c57e93"
|
||||
checksum = "e25e9fb15717794fae58ab55c26e044103aad13186fbb625893f9a3bbcc24228"
|
||||
dependencies = [
|
||||
"ttf-parser",
|
||||
]
|
||||
@@ -1809,7 +1818,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core 0.9.6",
|
||||
"parking_lot_core 0.9.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1828,15 +1837,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.6"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf"
|
||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-sys 0.42.0",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1925,20 +1934,19 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "1.2.1"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9"
|
||||
checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"toml_edit 0.18.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.49"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
|
||||
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -2034,9 +2042,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.10.1"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
|
||||
checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
@@ -2215,6 +2223,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "servo-fontconfig"
|
||||
version = "0.5.1"
|
||||
@@ -2397,9 +2414,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
@@ -2471,19 +2488,70 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.10"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f"
|
||||
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "772c1426ab886e7362aedf4abc9c0d1348a979517efedfc25862944d10137af0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime 0.6.1",
|
||||
"toml_edit 0.19.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5"
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"nom8",
|
||||
"toml_datetime 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.19.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90a238ee2e6ede22fb95350acc78e21dc40da00bb66c0334bde83de4ed89424e"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"nom8",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime 0.6.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.18.1"
|
||||
@@ -2510,6 +2578,7 @@ dependencies = [
|
||||
"fern",
|
||||
"flate2",
|
||||
"iced",
|
||||
"iced_native",
|
||||
"log",
|
||||
"regex",
|
||||
"retry",
|
||||
@@ -2517,15 +2586,15 @@ dependencies = [
|
||||
"serde_json",
|
||||
"static_init",
|
||||
"tar",
|
||||
"toml",
|
||||
"toml 0.7.1",
|
||||
"ureq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.8"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||
checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
@@ -2544,9 +2613,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.0"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
@@ -2568,9 +2637,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "ureq"
|
||||
version = "2.6.1"
|
||||
version = "2.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "733b5ad78377302af52c0dbcb2623d78fe50e4b3bf215948ff29e9ee031d8566"
|
||||
checksum = "338b31dd1314f68f3aabf3ed57ab922df95ffcd902476ca7ba3c4ce7b908c46d"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"flate2",
|
||||
@@ -2621,9 +2690,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.83"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
@@ -2631,9 +2700,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.83"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
@@ -2646,9 +2715,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.33"
|
||||
version = "0.4.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
|
||||
checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
@@ -2658,9 +2727,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||
checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -2668,9 +2737,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.83"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||
checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2681,9 +2750,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.83"
|
||||
version = "0.2.84"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-timer"
|
||||
@@ -2785,9 +2854,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.60"
|
||||
version = "0.3.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
|
||||
checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@@ -3000,6 +3069,30 @@ dependencies = [
|
||||
"windows_x86_64_msvc 0.42.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc 0.42.1",
|
||||
"windows_i686_gnu 0.42.1",
|
||||
"windows_i686_msvc 0.42.1",
|
||||
"windows_x86_64_gnu 0.42.1",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc 0.42.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
@@ -3115,12 +3208,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "x11-dl"
|
||||
version = "2.20.1"
|
||||
version = "2.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1536d6965a5d4e573c7ef73a2c15ebcd0b2de3347bdf526c34c297c00ac40f0"
|
||||
checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ no-self-update = []
|
||||
|
||||
[dependencies]
|
||||
iced = { git = "https://github.com/iced-rs/iced.git" }
|
||||
iced_native = { git = "https://github.com/iced-rs/iced.git"}
|
||||
serde = { version = "^1.0", features = ["derive"] }
|
||||
serde_json = "^1.0"
|
||||
static_init = "^1.0"
|
||||
|
||||
Binary file not shown.
@@ -1,7 +1,6 @@
|
||||
use crate::core::sync::{hashset_system_packages, list_all_system_packages, User};
|
||||
use crate::core::theme::Theme;
|
||||
use crate::core::uad_lists::{Package, PackageState, Removal, UadList};
|
||||
use crate::gui::views::list::Selection;
|
||||
use crate::gui::widgets::package_row::PackageRow;
|
||||
use chrono::offset::Utc;
|
||||
use chrono::DateTime;
|
||||
@@ -52,33 +51,6 @@ pub fn fetch_packages(
|
||||
user_package
|
||||
}
|
||||
|
||||
pub fn update_selection_count(selection: &mut Selection, p_state: PackageState, add: bool) {
|
||||
match p_state {
|
||||
PackageState::Enabled => {
|
||||
if add {
|
||||
selection.enabled += 1
|
||||
} else if selection.enabled > 0 {
|
||||
selection.enabled -= 1
|
||||
};
|
||||
}
|
||||
PackageState::Disabled => {
|
||||
if add {
|
||||
selection.disabled += 1
|
||||
} else if selection.disabled > 0 {
|
||||
selection.disabled -= 1
|
||||
};
|
||||
}
|
||||
PackageState::Uninstalled => {
|
||||
if add {
|
||||
selection.uninstalled += 1
|
||||
} else if selection.uninstalled > 0 {
|
||||
selection.uninstalled -= 1
|
||||
};
|
||||
}
|
||||
PackageState::All => {}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn string_to_theme(theme: String) -> Theme {
|
||||
match theme.as_str() {
|
||||
"Dark" => Theme::Dark,
|
||||
|
||||
@@ -107,7 +107,12 @@ impl Application for UadGui {
|
||||
None => devices_list.first().map(|x| x.to_owned()),
|
||||
};
|
||||
self.devices_list = devices_list;
|
||||
self.update(Message::SettingsAction(SettingsMessage::LoadDeviceSettings));
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
self.update(Message::SettingsAction(SettingsMessage::LoadDeviceSettings));
|
||||
}
|
||||
|
||||
self.update(Message::AppsAction(AppsMessage::LoadUadList(true)))
|
||||
}
|
||||
Message::AppsPress => {
|
||||
@@ -149,21 +154,46 @@ impl Application for UadGui {
|
||||
)
|
||||
.map(Message::AppsAction),
|
||||
Message::SettingsAction(msg) => {
|
||||
if let SettingsMessage::RestoringDevice(ref output) = msg {
|
||||
self.nb_running_async_adb_commands -= 1;
|
||||
self.view = View::List;
|
||||
self.apps_view.update(
|
||||
&mut self.settings_view,
|
||||
&mut self.selected_device.clone().unwrap_or_default(),
|
||||
&mut self.update_state.uad_list,
|
||||
AppsMessage::RestoringDevice(output.clone()),
|
||||
);
|
||||
match msg {
|
||||
SettingsMessage::RestoringDevice(ref output) => {
|
||||
self.nb_running_async_adb_commands -= 1;
|
||||
self.view = View::List;
|
||||
|
||||
if self.nb_running_async_adb_commands == 0 {
|
||||
return self.update(Message::RefreshButtonPressed);
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
self.apps_view.update(
|
||||
&mut self.settings_view,
|
||||
&mut self.selected_device.clone().unwrap_or_default(),
|
||||
&mut self.update_state.uad_list,
|
||||
AppsMessage::RestoringDevice(output.clone()),
|
||||
);
|
||||
}
|
||||
if self.nb_running_async_adb_commands == 0 {
|
||||
return self.update(Message::RefreshButtonPressed);
|
||||
}
|
||||
}
|
||||
SettingsMessage::MultiUserMode(toggled) => {
|
||||
if toggled {
|
||||
for user in self.apps_view.phone_packages.clone() {
|
||||
for (i, _) in
|
||||
user.iter().enumerate().filter(|&(_, pkg)| pkg.selected)
|
||||
{
|
||||
for u in self
|
||||
.selected_device
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.user_list
|
||||
.iter()
|
||||
.filter(|&u| !u.protected)
|
||||
{
|
||||
self.apps_view.phone_packages[u.index][i].selected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
self.settings_view
|
||||
.update(
|
||||
&self.selected_device.clone().unwrap_or_default(),
|
||||
@@ -221,7 +251,11 @@ impl Application for UadGui {
|
||||
);
|
||||
info!("{:-^65}", "-");
|
||||
self.apps_view.loading_state = ListLoadingState::FindingPhones("".to_string());
|
||||
self.update(Message::SettingsAction(SettingsMessage::LoadDeviceSettings));
|
||||
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
self.update(Message::SettingsAction(SettingsMessage::LoadDeviceSettings));
|
||||
}
|
||||
self.update(Message::AppsAction(AppsMessage::LoadPhonePackages((
|
||||
self.apps_view.uad_lists.clone(),
|
||||
UadListState::Done,
|
||||
|
||||
@@ -28,6 +28,8 @@ pub enum Container {
|
||||
Invisible,
|
||||
Frame,
|
||||
BorderedFrame,
|
||||
Tooltip,
|
||||
Background,
|
||||
}
|
||||
|
||||
impl container::StyleSheet for Theme {
|
||||
@@ -49,6 +51,20 @@ impl container::StyleSheet for Theme {
|
||||
border_width: 1.0,
|
||||
border_color: self.palette().normal.error,
|
||||
},
|
||||
Container::Tooltip => container::Appearance {
|
||||
background: Some(Background::Color(self.palette().base.foreground)),
|
||||
text_color: Some(self.palette().bright.surface),
|
||||
border_radius: 8.0,
|
||||
border_width: 1.0,
|
||||
border_color: self.palette().normal.primary,
|
||||
},
|
||||
|
||||
Container::Background => container::Appearance {
|
||||
background: Some(Background::Color(self.palette().base.background)),
|
||||
text_color: Some(self.palette().bright.surface),
|
||||
border_radius: 5.0,
|
||||
..container::Appearance::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,7 +168,7 @@ impl button::StyleSheet for Theme {
|
||||
match style {
|
||||
Button::RestorePackage => disabled_appearance(p.normal.primary, Some(p.bright.primary)),
|
||||
Button::UninstallPackage => disabled_appearance(p.bright.error, None),
|
||||
Button::Primary => disabled_appearance(p.normal.primary, Some(p.bright.primary)),
|
||||
Button::Primary => disabled_appearance(p.bright.primary, Some(p.bright.primary)),
|
||||
_ => button::Appearance { ..active },
|
||||
}
|
||||
}
|
||||
@@ -176,21 +192,21 @@ impl scrollable::StyleSheet for Theme {
|
||||
|
||||
fn active(&self, style: &Self::Style) -> scrollable::Scrollbar {
|
||||
let from_appearance = |c: Color| scrollable::Scrollbar {
|
||||
background: Some(Background::Color(c)),
|
||||
background: Some(Background::Color(Color::TRANSPARENT)),
|
||||
border_radius: 5.0,
|
||||
border_width: 0.0,
|
||||
border_color: Color::TRANSPARENT,
|
||||
scroller: scrollable::Scroller {
|
||||
color: self.palette().base.foreground,
|
||||
color: c,
|
||||
border_radius: 5.0,
|
||||
border_width: 0.0,
|
||||
border_width: 1.0,
|
||||
border_color: Color::TRANSPARENT,
|
||||
},
|
||||
};
|
||||
|
||||
match style {
|
||||
Scrollable::Description => from_appearance(self.palette().base.foreground),
|
||||
Scrollable::Packages => from_appearance(self.palette().base.background),
|
||||
Scrollable::Description => from_appearance(self.palette().normal.surface),
|
||||
Scrollable::Packages => from_appearance(self.palette().base.foreground),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,6 +402,7 @@ impl pick_list::StyleSheet for Theme {
|
||||
pub enum Text {
|
||||
#[default]
|
||||
Default,
|
||||
Ok,
|
||||
Danger,
|
||||
Commentary,
|
||||
Color(Color),
|
||||
@@ -403,6 +420,9 @@ impl text::StyleSheet for Theme {
|
||||
fn appearance(&self, style: Self::Style) -> text::Appearance {
|
||||
match style {
|
||||
Text::Default => Default::default(),
|
||||
Text::Ok => text::Appearance {
|
||||
color: Some(self.palette().bright.secondary),
|
||||
},
|
||||
Text::Danger => text::Appearance {
|
||||
color: Some(self.palette().bright.error),
|
||||
},
|
||||
|
||||
@@ -4,26 +4,21 @@ use crate::core::theme::Theme;
|
||||
use crate::core::uad_lists::{
|
||||
load_debloat_lists, Opposite, Package, PackageState, Removal, UadList, UadListState,
|
||||
};
|
||||
use crate::core::utils::{fetch_packages, update_selection_count};
|
||||
use crate::core::utils::fetch_packages;
|
||||
use crate::gui::style;
|
||||
use crate::gui::widgets::navigation_menu::ICONS;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
||||
use crate::gui::views::settings::Settings;
|
||||
use crate::gui::widgets::modal::Modal;
|
||||
use crate::gui::widgets::package_row::{Message as RowMessage, PackageRow};
|
||||
use iced::widget::{
|
||||
button, column, container, pick_list, row, scrollable, text, text_input, Space,
|
||||
button, column, container, horizontal_space, pick_list, radio, row, scrollable, text,
|
||||
text_input, tooltip, vertical_rule, Space,
|
||||
};
|
||||
use iced::{alignment, Alignment, Command, Element, Length, Renderer};
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Selection {
|
||||
pub uninstalled: u16,
|
||||
pub enabled: u16,
|
||||
pub disabled: u16,
|
||||
pub selected_packages: Vec<usize>, // phone_packages indexes (= what you've selected)
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct PackageInfo {
|
||||
pub i_user: usize,
|
||||
@@ -53,13 +48,14 @@ pub struct List {
|
||||
pub uad_lists: HashMap<String, Package>,
|
||||
pub phone_packages: Vec<Vec<PackageRow>>, // packages of all users of the phone
|
||||
filtered_packages: Vec<usize>, // phone_packages indexes of the selected user (= what you see on screen)
|
||||
pub selection: Selection,
|
||||
selected_packages: Vec<(usize, usize)>, // Vec of (user_index, pkg_index)
|
||||
selected_package_state: Option<PackageState>,
|
||||
selected_removal: Option<Removal>,
|
||||
selected_list: Option<UadList>,
|
||||
selected_user: Option<User>,
|
||||
pub input_value: String,
|
||||
description: String,
|
||||
selection_modal: bool,
|
||||
current_package_index: usize,
|
||||
}
|
||||
|
||||
@@ -79,6 +75,9 @@ pub enum Message {
|
||||
List(usize, RowMessage),
|
||||
ChangePackageState(Result<CommandType, ()>),
|
||||
Nothing,
|
||||
ModalHide,
|
||||
ModalUserSelected(User),
|
||||
ModalValidate,
|
||||
}
|
||||
|
||||
impl List {
|
||||
@@ -91,6 +90,25 @@ impl List {
|
||||
) -> Command<Message> {
|
||||
let i_user = self.selected_user.unwrap_or_default().index;
|
||||
match message {
|
||||
Message::ModalHide => {
|
||||
self.selection_modal = false;
|
||||
Command::none()
|
||||
}
|
||||
Message::ModalValidate => {
|
||||
let mut commands = vec![];
|
||||
self.selected_packages.sort();
|
||||
self.selected_packages.dedup();
|
||||
for selection in &self.selected_packages {
|
||||
commands.append(&mut build_action_pkg_commands(
|
||||
&self.phone_packages,
|
||||
selected_device,
|
||||
&settings.device,
|
||||
*selection,
|
||||
));
|
||||
}
|
||||
self.selection_modal = false;
|
||||
Command::batch(commands)
|
||||
}
|
||||
Message::RestoringDevice(output) => {
|
||||
if let Ok(res) = output {
|
||||
if let CommandType::PackageManager(p) = res {
|
||||
@@ -138,25 +156,14 @@ impl List {
|
||||
Command::none()
|
||||
}
|
||||
Message::ToggleAllSelected(selected) => {
|
||||
#[allow(unused_must_use)]
|
||||
for i in self.filtered_packages.clone() {
|
||||
self.phone_packages[i_user][i].selected = selected;
|
||||
|
||||
if !selected {
|
||||
if self.selection.selected_packages.contains(&i) {
|
||||
update_selection_count(
|
||||
&mut self.selection,
|
||||
self.phone_packages[i_user][i].state,
|
||||
false,
|
||||
);
|
||||
|
||||
self.selection.selected_packages.retain(|&s_i| s_i != i);
|
||||
}
|
||||
} else if !self.selection.selected_packages.contains(&i) {
|
||||
self.selection.selected_packages.push(i);
|
||||
update_selection_count(
|
||||
&mut self.selection,
|
||||
self.phone_packages[i_user][i].state,
|
||||
true,
|
||||
if self.phone_packages[i_user][i].selected != selected {
|
||||
self.update(
|
||||
settings,
|
||||
selected_device,
|
||||
list_update_state,
|
||||
Message::List(i, RowMessage::ToggleSelection(selected)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -183,9 +190,12 @@ impl List {
|
||||
Command::none()
|
||||
}
|
||||
Message::List(i_package, row_message) => {
|
||||
self.phone_packages[i_user][i_package]
|
||||
.update(row_message.clone())
|
||||
.map(move |row_message| Message::List(i_package, row_message));
|
||||
#[allow(unused_must_use)]
|
||||
{
|
||||
self.phone_packages[i_user][i_package]
|
||||
.update(row_message.clone())
|
||||
.map(move |row_message| Message::List(i_package, row_message));
|
||||
}
|
||||
|
||||
let package = &mut self.phone_packages[i_user][i_package];
|
||||
|
||||
@@ -193,30 +203,35 @@ impl List {
|
||||
RowMessage::ToggleSelection(toggle) => {
|
||||
if package.removal == Removal::Unsafe && !settings.general.expert_mode {
|
||||
package.selected = false;
|
||||
return Command::none();
|
||||
}
|
||||
|
||||
if settings.device.multi_user_mode {
|
||||
for u in selected_device.user_list.iter().filter(|&u| !u.protected) {
|
||||
self.phone_packages[u.index][i_package].selected = toggle;
|
||||
if toggle {
|
||||
self.selected_packages.push((u.index, i_package));
|
||||
}
|
||||
}
|
||||
if !toggle {
|
||||
self.selected_packages.retain(|&x| x.1 != i_package);
|
||||
}
|
||||
} else {
|
||||
package.selected = toggle;
|
||||
|
||||
if package.selected {
|
||||
self.selection.selected_packages.push(i_package);
|
||||
if toggle {
|
||||
self.selected_packages.push((i_user, i_package));
|
||||
} else {
|
||||
self.selection
|
||||
.selected_packages
|
||||
.retain(|&s_i| s_i != i_package);
|
||||
self.selected_packages
|
||||
.retain(|&x| x.1 != i_package || x.0 != i_user);
|
||||
}
|
||||
update_selection_count(
|
||||
&mut self.selection,
|
||||
package.state,
|
||||
package.selected,
|
||||
);
|
||||
}
|
||||
Command::none()
|
||||
}
|
||||
RowMessage::ActionPressed => Command::batch(build_action_pkg_commands(
|
||||
&self.selected_user.unwrap(),
|
||||
&self.phone_packages,
|
||||
selected_device,
|
||||
&settings.device,
|
||||
i_package,
|
||||
(i_user, i_package),
|
||||
)),
|
||||
RowMessage::PackagePressed => {
|
||||
self.description = package.clone().description;
|
||||
@@ -230,26 +245,11 @@ impl List {
|
||||
}
|
||||
}
|
||||
Message::ApplyActionOnSelection => {
|
||||
let mut commands = vec![];
|
||||
for i in &self.selection.selected_packages {
|
||||
commands.append(&mut build_action_pkg_commands(
|
||||
&self.selected_user.unwrap(),
|
||||
&self.phone_packages,
|
||||
selected_device,
|
||||
&settings.device,
|
||||
*i,
|
||||
));
|
||||
}
|
||||
Command::batch(commands)
|
||||
self.selection_modal = true;
|
||||
Command::none()
|
||||
}
|
||||
Message::UserSelected(user) => {
|
||||
for p in &mut self.phone_packages[i_user] {
|
||||
p.selected = false;
|
||||
}
|
||||
self.selected_user = Some(user);
|
||||
for i_package in &self.selection.selected_packages {
|
||||
self.phone_packages[user.index][*i_package].selected = true;
|
||||
}
|
||||
self.filtered_packages = (0..self.phone_packages[user.index].len()).collect();
|
||||
Self::filter_package_lists(self);
|
||||
Command::none()
|
||||
@@ -258,15 +258,22 @@ impl List {
|
||||
if let Ok(CommandType::PackageManager(p)) = res {
|
||||
let package = &mut self.phone_packages[p.i_user][p.index];
|
||||
package.state = package.state.opposite(settings.device.disable_mode);
|
||||
|
||||
update_selection_count(&mut self.selection, package.state, false);
|
||||
self.selection
|
||||
.selected_packages
|
||||
.retain(|&s_i| s_i != p.index);
|
||||
package.selected = false;
|
||||
self.selected_packages
|
||||
.retain(|&x| x.1 != p.index && x.0 != p.i_user);
|
||||
Self::filter_package_lists(self);
|
||||
}
|
||||
Command::none()
|
||||
}
|
||||
Message::ModalUserSelected(user) => {
|
||||
self.selected_user = Some(user);
|
||||
self.update(
|
||||
settings,
|
||||
selected_device,
|
||||
list_update_state,
|
||||
Message::UserSelected(user),
|
||||
)
|
||||
}
|
||||
Message::Nothing => Command::none(),
|
||||
}
|
||||
}
|
||||
@@ -305,8 +312,6 @@ impl List {
|
||||
)
|
||||
.padding(5);
|
||||
|
||||
// let package_amount = text(format!("{} packages found", packages.len()));
|
||||
|
||||
let user_picklist = pick_list(
|
||||
selected_device.user_list.clone(),
|
||||
self.selected_user,
|
||||
@@ -358,8 +363,6 @@ impl List {
|
||||
.height(Length::FillPortion(6))
|
||||
.style(style::Scrollable::Packages);
|
||||
|
||||
// let mut packages_v: Vec<&str> = self.packages.lines().collect();
|
||||
|
||||
let description_scroll =
|
||||
scrollable(text(&self.description)).style(style::Scrollable::Description);
|
||||
|
||||
@@ -368,31 +371,21 @@ impl List {
|
||||
.width(Length::Fill)
|
||||
.style(style::Container::Frame);
|
||||
|
||||
let restore_action = match settings.device.disable_mode {
|
||||
true => "Enable/Restore",
|
||||
false => "Restore",
|
||||
let review_selection = if !self.selected_packages.is_empty() {
|
||||
button(text(format!(
|
||||
"Review selection ({})",
|
||||
self.selected_packages.len()
|
||||
)))
|
||||
.on_press(Message::ApplyActionOnSelection)
|
||||
.padding(5)
|
||||
.style(style::Button::Primary)
|
||||
} else {
|
||||
button(text(format!(
|
||||
"Review selection ({})",
|
||||
self.selected_packages.len()
|
||||
)))
|
||||
.padding(5)
|
||||
};
|
||||
let remove_action = match settings.device.disable_mode {
|
||||
true => "Disable",
|
||||
false => "Uninstall",
|
||||
};
|
||||
|
||||
let apply_restore_selection = button(text(format!(
|
||||
"{} selection ({})",
|
||||
restore_action,
|
||||
self.selection.uninstalled + self.selection.disabled
|
||||
)))
|
||||
.on_press(Message::ApplyActionOnSelection)
|
||||
.padding(5)
|
||||
.style(style::Button::Primary);
|
||||
|
||||
let apply_remove_selection = button(text(format!(
|
||||
"{} selection ({})",
|
||||
remove_action, self.selection.enabled
|
||||
)))
|
||||
.on_press(Message::ApplyActionOnSelection)
|
||||
.padding(5)
|
||||
.style(style::Button::Primary);
|
||||
|
||||
let select_all_btn = button("Select all")
|
||||
.padding(5)
|
||||
@@ -408,8 +401,7 @@ impl List {
|
||||
select_all_btn,
|
||||
unselect_all_btn,
|
||||
Space::new(Length::Fill, Length::Shrink),
|
||||
apply_restore_selection,
|
||||
apply_remove_selection,
|
||||
review_selection,
|
||||
]
|
||||
.width(Length::Fill)
|
||||
.spacing(10)
|
||||
@@ -450,11 +442,232 @@ impl List {
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
};
|
||||
container(content).height(Length::Fill).padding(10).into()
|
||||
if self.selection_modal {
|
||||
Modal::new(
|
||||
content.padding(10),
|
||||
self.apply_selection_modal(
|
||||
selected_device,
|
||||
settings,
|
||||
&self.phone_packages[self.selected_user.unwrap().index],
|
||||
),
|
||||
)
|
||||
.on_blur(Message::ModalHide)
|
||||
.into()
|
||||
} else {
|
||||
container(content).height(Length::Fill).padding(10).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_selection_modal(
|
||||
&self,
|
||||
device: &Phone,
|
||||
settings: &Settings,
|
||||
packages: &[PackageRow],
|
||||
) -> Element<Message, Renderer<Theme>> {
|
||||
let mut h_recap: HashMap<Removal, (u8, u8)> = HashMap::new();
|
||||
for p in packages.iter().filter(|p| p.selected) {
|
||||
if p.state != PackageState::Uninstalled {
|
||||
h_recap.entry(p.removal).or_insert((0, 0)).0 += 1;
|
||||
} else {
|
||||
h_recap.entry(p.removal).or_insert((0, 0)).1 += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let radio_btn_users = device.user_list.iter().filter(|&u| !u.protected).fold(
|
||||
row![].spacing(10),
|
||||
|row, user| {
|
||||
row.push(
|
||||
radio(
|
||||
format!("{}", user.clone()),
|
||||
*user,
|
||||
self.selected_user,
|
||||
Message::ModalUserSelected,
|
||||
)
|
||||
.size(23),
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
let title_ctn =
|
||||
container(row![text("Review your selection").size(25)].align_items(Alignment::Center))
|
||||
.width(Length::Fill)
|
||||
.style(style::Container::Frame)
|
||||
.padding([10, 0, 10, 0])
|
||||
.center_y()
|
||||
.center_x();
|
||||
|
||||
let users_ctn = container(radio_btn_users)
|
||||
.padding(10)
|
||||
.center_x()
|
||||
.style(style::Container::Frame);
|
||||
|
||||
let explaination_ctn = container(
|
||||
row![
|
||||
text("The action for the selected user will be applied to all other users")
|
||||
.style(style::Text::Danger),
|
||||
tooltip(
|
||||
text("\u{EA0C}")
|
||||
.font(ICONS)
|
||||
.width(Length::Units(17))
|
||||
.horizontal_alignment(alignment::Horizontal::Center)
|
||||
.style(style::Text::Commentary)
|
||||
.size(17),
|
||||
"Let's say you choose user 0. If a selected package on user 0\n\
|
||||
is set to be uninstalled and if this same package is disabled on user 10,\n\
|
||||
then the package on both users will be uninstalled.",
|
||||
tooltip::Position::Top,
|
||||
)
|
||||
.gap(20)
|
||||
.padding(10)
|
||||
.size(17)
|
||||
.style(style::Container::Tooltip)
|
||||
]
|
||||
.spacing(10),
|
||||
)
|
||||
.center_x()
|
||||
.padding(10)
|
||||
.style(style::Container::BorderedFrame);
|
||||
|
||||
let modal_btn_row = row![
|
||||
button(text("Cancel")).on_press(Message::ModalHide),
|
||||
horizontal_space(Length::Fill),
|
||||
button(text("Apply")).on_press(Message::ModalValidate),
|
||||
]
|
||||
.padding([0, 15, 10, 10]);
|
||||
|
||||
let recap_view = Removal::ALL
|
||||
.iter()
|
||||
.filter(|&&r| r != Removal::All)
|
||||
.fold(column![].spacing(6).width(Length::Fill), |col, r| {
|
||||
col.push(recap(settings, &mut h_recap, *r))
|
||||
});
|
||||
|
||||
let selected_pkgs_ctn = container(
|
||||
container(
|
||||
scrollable(
|
||||
container(
|
||||
if !self
|
||||
.selected_packages
|
||||
.iter()
|
||||
.any(|s| s.0 == self.selected_user.unwrap().index)
|
||||
{
|
||||
column![text("No packages selected for this user")]
|
||||
.align_items(Alignment::Center)
|
||||
.width(Length::Fill)
|
||||
} else {
|
||||
self.selected_packages
|
||||
.iter()
|
||||
.filter(|s| s.0 == self.selected_user.unwrap().index)
|
||||
.fold(
|
||||
column![].spacing(6).width(Length::Fill),
|
||||
|col, selection| {
|
||||
col.push(
|
||||
row![
|
||||
row![text(
|
||||
self.phone_packages[selection.0][selection.1]
|
||||
.removal
|
||||
)]
|
||||
.width(Length::Units(100)),
|
||||
row![text(
|
||||
self.phone_packages[selection.0][selection.1]
|
||||
.uad_list
|
||||
)]
|
||||
.width(Length::Units(60)),
|
||||
row![text(
|
||||
self.phone_packages[selection.0][selection.1]
|
||||
.name
|
||||
.clone()
|
||||
),],
|
||||
horizontal_space(Length::Fill),
|
||||
row![match self.phone_packages[selection.0]
|
||||
[selection.1]
|
||||
.state
|
||||
{
|
||||
PackageState::Enabled =>
|
||||
if settings.device.disable_mode {
|
||||
text("Disable")
|
||||
.style(style::Text::Danger)
|
||||
} else {
|
||||
text("Uninstall")
|
||||
.style(style::Text::Danger)
|
||||
},
|
||||
PackageState::Disabled =>
|
||||
text("Enable").style(style::Text::Ok),
|
||||
PackageState::Uninstalled =>
|
||||
text("Restore").style(style::Text::Ok),
|
||||
_ => text("Impossible")
|
||||
.style(style::Text::Danger),
|
||||
},]
|
||||
.width(Length::Units(60)),
|
||||
]
|
||||
.width(Length::Fill)
|
||||
.spacing(20),
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
.padding(10)
|
||||
.width(Length::Fill),
|
||||
)
|
||||
.style(style::Scrollable::Description),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.style(style::Container::Frame),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.max_height(150)
|
||||
.padding([0, 10, 0, 10]);
|
||||
|
||||
container(
|
||||
if device
|
||||
.user_list
|
||||
.iter()
|
||||
.filter(|&u| !u.protected)
|
||||
.collect::<Vec<&User>>()
|
||||
.len()
|
||||
> 1
|
||||
&& settings.device.multi_user_mode
|
||||
{
|
||||
column![
|
||||
title_ctn,
|
||||
users_ctn,
|
||||
row![explaination_ctn].padding([0, 10, 0, 10]),
|
||||
container(recap_view).padding(10),
|
||||
selected_pkgs_ctn,
|
||||
modal_btn_row,
|
||||
]
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
} else if !settings.device.multi_user_mode {
|
||||
column![
|
||||
title_ctn,
|
||||
users_ctn,
|
||||
container(recap_view).padding(10),
|
||||
selected_pkgs_ctn,
|
||||
modal_btn_row,
|
||||
]
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
} else {
|
||||
column![
|
||||
title_ctn,
|
||||
container(recap_view).padding(10),
|
||||
selected_pkgs_ctn,
|
||||
modal_btn_row,
|
||||
]
|
||||
.spacing(10)
|
||||
.align_items(Alignment::Center)
|
||||
},
|
||||
)
|
||||
.width(Length::Units(800))
|
||||
.height(Length::Shrink)
|
||||
.max_height(700)
|
||||
.style(style::Container::Background)
|
||||
.into()
|
||||
}
|
||||
fn filter_package_lists(&mut self) {
|
||||
let list_filter: UadList = self.selected_list.unwrap();
|
||||
let package_filter: PackageState = self.selected_package_state.unwrap();
|
||||
@@ -545,30 +758,33 @@ fn waiting_view<'a>(
|
||||
}
|
||||
|
||||
fn build_action_pkg_commands(
|
||||
selected_user: &User,
|
||||
packages: &[Vec<PackageRow>],
|
||||
device: &Phone,
|
||||
settings: &DeviceSettings,
|
||||
p_index: usize,
|
||||
selection: (usize, usize),
|
||||
) -> Vec<Command<Message>> {
|
||||
let pkg = &packages[selected_user.index][p_index];
|
||||
let pkg = &packages[selection.0][selection.1];
|
||||
let wanted_state = pkg.state.opposite(settings.disable_mode);
|
||||
|
||||
let mut commands = vec![];
|
||||
for u in device.user_list.iter().filter(|&&u| {
|
||||
!u.protected
|
||||
&& (u != *selected_user || settings.multi_user_mode)
|
||||
&& packages[u.index][p_index].state != wanted_state
|
||||
!u.protected && (packages[u.index][selection.1].selected || settings.multi_user_mode)
|
||||
}) {
|
||||
let u_pkg = packages[u.index][p_index].clone();
|
||||
let actions = apply_pkg_state_commands(u_pkg.into(), &wanted_state, u, device);
|
||||
let u_pkg = packages[u.index][selection.1].clone();
|
||||
let actions = if settings.multi_user_mode {
|
||||
apply_pkg_state_commands(u_pkg.into(), &wanted_state, u, device)
|
||||
} else {
|
||||
let wanted_state = &u_pkg.state.opposite(settings.disable_mode);
|
||||
apply_pkg_state_commands(u_pkg.into(), wanted_state, u, device)
|
||||
};
|
||||
for (j, action) in actions.into_iter().enumerate() {
|
||||
let p_info = PackageInfo {
|
||||
i_user: u.index,
|
||||
index: p_index,
|
||||
index: selection.1,
|
||||
removal: pkg.removal.to_string(),
|
||||
};
|
||||
// Only the first command can change the package state
|
||||
// In the end there is only one package state change
|
||||
// even if we run multiple adb commands
|
||||
commands.push(Command::perform(
|
||||
perform_adb_commands(action, CommandType::PackageManager(p_info)),
|
||||
if j == 0 {
|
||||
@@ -581,3 +797,47 @@ fn build_action_pkg_commands(
|
||||
}
|
||||
commands
|
||||
}
|
||||
|
||||
fn recap<'a>(
|
||||
settings: &Settings,
|
||||
recap: &mut HashMap<Removal, (u8, u8)>,
|
||||
removal: Removal,
|
||||
) -> Element<'a, Message, Renderer<Theme>> {
|
||||
container(
|
||||
row![
|
||||
text(removal).size(25).width(Length::FillPortion(1)),
|
||||
vertical_rule(5),
|
||||
row![
|
||||
if settings.device.disable_mode {
|
||||
text("Disable").style(style::Text::Danger)
|
||||
} else {
|
||||
text("Uninstall").style(style::Text::Danger)
|
||||
},
|
||||
horizontal_space(Length::Fill),
|
||||
text(recap.entry(removal).or_insert((0, 0)).0.to_string())
|
||||
.style(style::Text::Danger)
|
||||
]
|
||||
.width(Length::FillPortion(1)),
|
||||
vertical_rule(5),
|
||||
row![
|
||||
if settings.device.disable_mode {
|
||||
text("Enable").style(style::Text::Ok)
|
||||
} else {
|
||||
text("Restore").style(style::Text::Ok)
|
||||
},
|
||||
horizontal_space(Length::Fill),
|
||||
text(recap.entry(removal).or_insert((0, 0)).1.to_string()).style(style::Text::Ok)
|
||||
]
|
||||
.width(Length::FillPortion(1))
|
||||
]
|
||||
.spacing(20)
|
||||
.padding([0, 10, 0, 0])
|
||||
.width(Length::Fill)
|
||||
.align_items(Alignment::Center),
|
||||
)
|
||||
.padding(10)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Units(45))
|
||||
.style(style::Container::Frame)
|
||||
.into()
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ impl Settings {
|
||||
];
|
||||
|
||||
let multi_user_mode_checkbox = checkbox(
|
||||
"Affect all the users of the phone (not only the selected user)",
|
||||
"Affect all the users of the device (not only the selected user)",
|
||||
self.device.multi_user_mode,
|
||||
Message::MultiUserMode,
|
||||
)
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod modal;
|
||||
pub mod navigation_menu;
|
||||
pub mod package_row;
|
||||
|
||||
281
src/gui/widgets/modal.rs
Normal file
281
src/gui/widgets/modal.rs
Normal file
@@ -0,0 +1,281 @@
|
||||
use iced_native::alignment::Alignment;
|
||||
use iced_native::widget::{self, Tree};
|
||||
use iced_native::{
|
||||
event, layout, mouse, overlay, renderer, Clipboard, Color, Element, Event, Layout, Length,
|
||||
Point, Rectangle, Shell, Size, Widget,
|
||||
};
|
||||
|
||||
/// A widget that centers a modal element over some base element
|
||||
pub struct Modal<'a, Message, Renderer> {
|
||||
base: Element<'a, Message, Renderer>,
|
||||
modal: Element<'a, Message, Renderer>,
|
||||
on_blur: Option<Message>,
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> Modal<'a, Message, Renderer> {
|
||||
/// Returns a new [`Modal`]
|
||||
pub fn new(
|
||||
base: impl Into<Element<'a, Message, Renderer>>,
|
||||
modal: impl Into<Element<'a, Message, Renderer>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
base: base.into(),
|
||||
modal: modal.into(),
|
||||
on_blur: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the message that will be produces when the background
|
||||
/// of the [`Modal`] is pressed
|
||||
pub fn on_blur(self, on_blur: Message) -> Self {
|
||||
Self {
|
||||
on_blur: Some(on_blur),
|
||||
..self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> Widget<Message, Renderer> for Modal<'a, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer,
|
||||
Message: Clone,
|
||||
{
|
||||
fn children(&self) -> Vec<Tree> {
|
||||
vec![Tree::new(&self.base), Tree::new(&self.modal)]
|
||||
}
|
||||
|
||||
fn diff(&self, tree: &mut Tree) {
|
||||
tree.diff_children(&[&self.base, &self.modal]);
|
||||
}
|
||||
|
||||
fn width(&self) -> Length {
|
||||
self.base.as_widget().width()
|
||||
}
|
||||
|
||||
fn height(&self) -> Length {
|
||||
self.base.as_widget().height()
|
||||
}
|
||||
|
||||
fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node {
|
||||
self.base.as_widget().layout(renderer, limits)
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
&mut self,
|
||||
state: &mut Tree,
|
||||
event: Event,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
renderer: &Renderer,
|
||||
clipboard: &mut dyn Clipboard,
|
||||
shell: &mut Shell<'_, Message>,
|
||||
) -> event::Status {
|
||||
self.base.as_widget_mut().on_event(
|
||||
&mut state.children[0],
|
||||
event,
|
||||
layout,
|
||||
cursor_position,
|
||||
renderer,
|
||||
clipboard,
|
||||
shell,
|
||||
)
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
state: &Tree,
|
||||
renderer: &mut Renderer,
|
||||
theme: &<Renderer as iced_native::Renderer>::Theme,
|
||||
style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
viewport: &Rectangle,
|
||||
) {
|
||||
self.base.as_widget().draw(
|
||||
&state.children[0],
|
||||
renderer,
|
||||
theme,
|
||||
style,
|
||||
layout,
|
||||
cursor_position,
|
||||
viewport,
|
||||
);
|
||||
}
|
||||
|
||||
fn overlay<'b>(
|
||||
&'b mut self,
|
||||
state: &'b mut Tree,
|
||||
layout: Layout<'_>,
|
||||
_renderer: &Renderer,
|
||||
) -> Option<overlay::Element<'b, Message, Renderer>> {
|
||||
Some(overlay::Element::new(
|
||||
layout.position(),
|
||||
Box::new(Overlay {
|
||||
content: &mut self.modal,
|
||||
tree: &mut state.children[1],
|
||||
size: layout.bounds().size(),
|
||||
on_blur: self.on_blur.clone(),
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
fn mouse_interaction(
|
||||
&self,
|
||||
state: &Tree,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
viewport: &Rectangle,
|
||||
renderer: &Renderer,
|
||||
) -> mouse::Interaction {
|
||||
self.base.as_widget().mouse_interaction(
|
||||
&state.children[0],
|
||||
layout,
|
||||
cursor_position,
|
||||
viewport,
|
||||
renderer,
|
||||
)
|
||||
}
|
||||
|
||||
fn operate(
|
||||
&self,
|
||||
state: &mut Tree,
|
||||
layout: Layout<'_>,
|
||||
renderer: &Renderer,
|
||||
operation: &mut dyn widget::Operation<Message>,
|
||||
) {
|
||||
self.base
|
||||
.as_widget()
|
||||
.operate(&mut state.children[0], layout, renderer, operation);
|
||||
}
|
||||
}
|
||||
|
||||
struct Overlay<'a, 'b, Message, Renderer> {
|
||||
content: &'b mut Element<'a, Message, Renderer>,
|
||||
tree: &'b mut Tree,
|
||||
size: Size,
|
||||
on_blur: Option<Message>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, Renderer>
|
||||
for Overlay<'a, 'b, Message, Renderer>
|
||||
where
|
||||
Renderer: iced_native::Renderer,
|
||||
Message: Clone,
|
||||
{
|
||||
fn layout(&self, renderer: &Renderer, _bounds: Size, position: Point) -> layout::Node {
|
||||
let limits = layout::Limits::new(Size::ZERO, self.size)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill);
|
||||
|
||||
let mut child = self.content.as_widget().layout(renderer, &limits);
|
||||
child.align(Alignment::Center, Alignment::Center, limits.max());
|
||||
|
||||
let mut node = layout::Node::with_children(self.size, vec![child]);
|
||||
node.move_to(position);
|
||||
|
||||
node
|
||||
}
|
||||
|
||||
fn on_event(
|
||||
&mut self,
|
||||
event: Event,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
renderer: &Renderer,
|
||||
clipboard: &mut dyn Clipboard,
|
||||
shell: &mut Shell<'_, Message>,
|
||||
) -> event::Status {
|
||||
let content_bounds = layout.children().next().unwrap().bounds();
|
||||
|
||||
if let Some(message) = self.on_blur.as_ref() {
|
||||
if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) = &event {
|
||||
if !content_bounds.contains(cursor_position) {
|
||||
shell.publish(message.clone());
|
||||
return event::Status::Captured;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.content.as_widget_mut().on_event(
|
||||
self.tree,
|
||||
event,
|
||||
layout.children().next().unwrap(),
|
||||
cursor_position,
|
||||
renderer,
|
||||
clipboard,
|
||||
shell,
|
||||
)
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
renderer: &mut Renderer,
|
||||
theme: &Renderer::Theme,
|
||||
style: &renderer::Style,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
) {
|
||||
renderer.fill_quad(
|
||||
renderer::Quad {
|
||||
bounds: layout.bounds(),
|
||||
border_radius: renderer::BorderRadius::from(0.0),
|
||||
border_width: 0.0,
|
||||
border_color: Color::TRANSPARENT,
|
||||
},
|
||||
Color {
|
||||
a: 0.80,
|
||||
..Color::BLACK
|
||||
},
|
||||
);
|
||||
|
||||
self.content.as_widget().draw(
|
||||
self.tree,
|
||||
renderer,
|
||||
theme,
|
||||
style,
|
||||
layout.children().next().unwrap(),
|
||||
cursor_position,
|
||||
&layout.bounds(),
|
||||
);
|
||||
}
|
||||
|
||||
fn operate(
|
||||
&mut self,
|
||||
layout: Layout<'_>,
|
||||
renderer: &Renderer,
|
||||
operation: &mut dyn widget::Operation<Message>,
|
||||
) {
|
||||
self.content.as_widget().operate(
|
||||
self.tree,
|
||||
layout.children().next().unwrap(),
|
||||
renderer,
|
||||
operation,
|
||||
);
|
||||
}
|
||||
|
||||
fn mouse_interaction(
|
||||
&self,
|
||||
layout: Layout<'_>,
|
||||
cursor_position: Point,
|
||||
viewport: &Rectangle,
|
||||
renderer: &Renderer,
|
||||
) -> mouse::Interaction {
|
||||
self.content.as_widget().mouse_interaction(
|
||||
self.tree,
|
||||
layout.children().next().unwrap(),
|
||||
cursor_position,
|
||||
viewport,
|
||||
renderer,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> From<Modal<'a, Message, Renderer>> for Element<'a, Message, Renderer>
|
||||
where
|
||||
Renderer: 'a + iced_native::Renderer,
|
||||
Message: 'a + Clone,
|
||||
{
|
||||
fn from(modal: Modal<'a, Message, Renderer>) -> Self {
|
||||
Element::new(modal)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user