file picker + show_open_file_picker

This commit is contained in:
Martin Kavík 2024-06-03 19:11:22 +02:00
parent 6cdccb72b2
commit ce36cd914f
13 changed files with 702 additions and 110 deletions

5
.cargo/config.toml Normal file
View file

@ -0,0 +1,5 @@
[build]
# https://docs.rs/web-sys/latest/web_sys/struct.Window.html#method.show_open_file_picker
# https://github.com/rustwasm/wasm-bindgen/issues/2339#issuecomment-1000651386
[target.wasm32-unknown-unknown]
rustflags = ["--cfg=web_sys_unstable_apis"]

579
Cargo.lock generated
View file

@ -315,18 +315,144 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f47b57fc4521e3cae26a4d45b5227f8fadee4c345be0fefd8d5d1711afb8aeb9"
[[package]]
name = "ashpd"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093"
dependencies = [
"enumflags2",
"futures-channel",
"futures-util",
"rand 0.8.5",
"serde",
"serde_repr",
"tokio",
"url",
"zbus",
]
[[package]]
name = "askama_escape"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
[[package]]
name = "async-broadcast"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e"
dependencies = [
"event-listener",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-channel"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
dependencies = [
"concurrent-queue",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-io"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964"
dependencies = [
"async-lock",
"cfg-if",
"concurrent-queue",
"futures-io",
"futures-lite",
"parking",
"polling",
"rustix",
"slab",
"tracing",
"windows-sys 0.52.0",
]
[[package]]
name = "async-lock"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
dependencies = [
"event-listener",
"event-listener-strategy",
"pin-project-lite",
]
[[package]]
name = "async-once-cell"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9338790e78aa95a416786ec8389546c4b6a1dfc3dc36071ed9518a9413a542eb"
[[package]]
name = "async-process"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7eda79bbd84e29c2b308d1dc099d7de8dcc7035e48f4bf5dc4a531a44ff5e2a"
dependencies = [
"async-channel",
"async-io",
"async-lock",
"async-signal",
"async-task",
"blocking",
"cfg-if",
"event-listener",
"futures-lite",
"rustix",
"tracing",
"windows-sys 0.52.0",
]
[[package]]
name = "async-recursion"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.61",
]
[[package]]
name = "async-signal"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "329972aa325176e89114919f2a80fdae4f4c040f66a370b1a1159c6c0f94e7aa"
dependencies = [
"async-io",
"async-lock",
"atomic-waker",
"cfg-if",
"futures-core",
"futures-io",
"rustix",
"signal-hook-registry",
"slab",
"windows-sys 0.52.0",
]
[[package]]
name = "async-task"
version = "4.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
[[package]]
name = "async-trait"
version = "0.1.80"
@ -361,6 +487,12 @@ dependencies = [
"system-deps",
]
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "autocfg"
version = "1.3.0"
@ -431,6 +563,19 @@ dependencies = [
"generic-array",
]
[[package]]
name = "blocking"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea"
dependencies = [
"async-channel",
"async-task",
"futures-io",
"futures-lite",
"piper",
]
[[package]]
name = "bool_ext"
version = "0.5.3"
@ -695,6 +840,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "console_error_panic_hook"
version = "0.1.7"
@ -917,6 +1071,17 @@ dependencies = [
"serde",
]
[[package]]
name = "derivative"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "derive_more"
version = "0.99.17"
@ -940,6 +1105,15 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "dirs"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-next"
version = "2.0.0"
@ -950,6 +1124,18 @@ dependencies = [
"dirs-sys-next",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys 0.48.0",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
@ -1015,7 +1201,7 @@ dependencies = [
"futures-channel",
"futures-signals",
"futures-util",
"gloo-events",
"gloo-events 0.1.2",
"js-sys",
"once_cell",
"pin-project",
@ -1113,6 +1299,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "endi"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
[[package]]
name = "enum-ordinalize"
version = "4.3.0"
@ -1133,6 +1325,27 @@ dependencies = [
"syn 2.0.61",
]
[[package]]
name = "enumflags2"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d"
dependencies = [
"enumflags2_derive",
"serde",
]
[[package]]
name = "enumflags2_derive"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.61",
]
[[package]]
name = "env_logger"
version = "0.10.2"
@ -1170,6 +1383,27 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "event-listener"
version = "5.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1"
dependencies = [
"event-listener",
"pin-project-lite",
]
[[package]]
name = "fastrand"
version = "2.1.0"
@ -1185,6 +1419,7 @@ dependencies = [
"shared",
"tauri",
"tauri-build",
"tauri-plugin-dialog",
"tauri-plugin-window-state",
"wellen",
]
@ -1264,8 +1499,10 @@ dependencies = [
name = "frontend"
version = "0.1.0"
dependencies = [
"gloo-file",
"shared",
"wasm-bindgen-test",
"web-sys",
"wellen",
"zoon",
]
@ -1346,6 +1583,19 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-lite"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"parking",
"pin-project-lite",
]
[[package]]
name = "futures-macro"
version = "0.3.30"
@ -1689,6 +1939,29 @@ dependencies = [
"web-sys",
]
[[package]]
name = "gloo-events"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27c26fb45f7c385ba980f5fa87ac677e363949e065a083722697ef1b2cc91e41"
dependencies = [
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "gloo-file"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97563d71863fb2824b2e974e754a81d19c4a7ec47b09ced8a0e6656b6d54bd1f"
dependencies = [
"futures-channel",
"gloo-events 0.2.0",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "gobject-sys"
version = "0.18.0"
@ -2507,9 +2780,9 @@ dependencies = [
[[package]]
name = "muda"
version = "0.13.1"
version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f428b4e9db3d17e2f809dfb1ff9ddfbbf16c71790d1656d10aee320877e1392f"
checksum = "86b959f97c97044e4c96e32e1db292a7d594449546a3c6b77ae613dc3a5b5145"
dependencies = [
"cocoa",
"crossbeam-channel",
@ -2584,6 +2857,18 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
dependencies = [
"bitflags 2.5.0",
"cfg-if",
"libc",
"memoffset",
]
[[package]]
name = "nodrop"
version = "0.1.14"
@ -2677,6 +2962,17 @@ dependencies = [
"objc_exception",
]
[[package]]
name = "objc-foundation"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
dependencies = [
"block",
"objc",
"objc_id",
]
[[package]]
name = "objc_exception"
version = "0.1.2"
@ -2710,6 +3006,22 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "ordered-stream"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
dependencies = [
"futures-core",
"pin-project-lite",
]
[[package]]
name = "overload"
version = "0.1.1"
@ -2750,6 +3062,12 @@ dependencies = [
"system-deps",
]
[[package]]
name = "parking"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
[[package]]
name = "parking_lot"
version = "0.4.8"
@ -2973,6 +3291,17 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "piper"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391"
dependencies = [
"atomic-waker",
"fastrand",
"futures-io",
]
[[package]]
name = "pkg-config"
version = "0.3.30"
@ -3006,6 +3335,21 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "polling"
version = "3.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6a007746f34ed64099e88783b0ae369eaa3da6392868ba262e2af9b8fbaea1"
dependencies = [
"cfg-if",
"concurrent-queue",
"hermit-abi",
"pin-project-lite",
"rustix",
"tracing",
"windows-sys 0.52.0",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
@ -3361,6 +3705,30 @@ dependencies = [
"winreg",
]
[[package]]
name = "rfd"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251"
dependencies = [
"ashpd",
"block",
"dispatch",
"glib-sys",
"gobject-sys",
"gtk-sys",
"js-sys",
"log",
"objc",
"objc-foundation",
"objc_id",
"raw-window-handle 0.6.1",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-sys 0.48.0",
]
[[package]]
name = "ring"
version = "0.17.8"
@ -4063,9 +4431,9 @@ checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f"
[[package]]
name = "tauri"
version = "2.0.0-beta.19"
version = "2.0.0-beta.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f8e5bc2e4f5eb7496d1a3e5f4d272f69f1333db5f8efed28d79d7f93334fe95"
checksum = "5a258ecc5ac7ddade525f512c4962fd01cd0f5265e917b4572579c32c027bb31"
dependencies = [
"anyhow",
"bytes",
@ -4112,9 +4480,9 @@ dependencies = [
[[package]]
name = "tauri-build"
version = "2.0.0-beta.15"
version = "2.0.0-beta.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8aa28eebafcda490fa7097a6e3a4d07f65967614d35dd88b2aaa19dbb49241cd"
checksum = "82b964bb6d03d97e24e12f896aab463b02a3c2ff76a60f728cc37b5548eb470e"
dependencies = [
"anyhow",
"cargo_toml",
@ -4134,9 +4502,9 @@ dependencies = [
[[package]]
name = "tauri-codegen"
version = "2.0.0-beta.15"
version = "2.0.0-beta.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "727d13a28e9ec895f537d90a09acb0aa3593f703a715fe8a77f87269d3245b52"
checksum = "3529cfa977ed7c097f2a5e8da19ecffbe61982450a6c819e6165b6d0cfd3dd3a"
dependencies = [
"base64 0.22.1",
"brotli",
@ -4161,9 +4529,9 @@ dependencies = [
[[package]]
name = "tauri-macros"
version = "2.0.0-beta.15"
version = "2.0.0-beta.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258667612ad901d256e04ace71ac54d4b3dd8fb1e5baa24403b50991cade4365"
checksum = "36f97dd80334f29314aa5f40b5fad10cb9feffd08e5a5324fd728613841e5d33"
dependencies = [
"heck 0.5.0",
"proc-macro2",
@ -4175,9 +4543,9 @@ dependencies = [
[[package]]
name = "tauri-plugin"
version = "2.0.0-beta.14"
version = "2.0.0-beta.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade77c77db5206b493655d44c395ef67c84fec6bd9d4c19237efdced6b3840f8"
checksum = "7c8385fd0a4f661f5652b0d9e2d7256187d553bb174f88564d10ebcfa6a3af53"
dependencies = [
"anyhow",
"glob",
@ -4191,10 +4559,47 @@ dependencies = [
]
[[package]]
name = "tauri-plugin-window-state"
version = "2.0.0-beta.7"
name = "tauri-plugin-dialog"
version = "2.0.0-beta.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f723f70fef894434dfb265c9b040ea849acc6e49df0d3c66e0b9f9908214b08a"
checksum = "fed4b22c59f7b04ae2a0bed8241aa715b41973c3f042c84aa67a1f4dc0174a8d"
dependencies = [
"dunce",
"log",
"raw-window-handle 0.6.1",
"rfd",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"tauri-plugin-fs",
"thiserror",
]
[[package]]
name = "tauri-plugin-fs"
version = "2.0.0-beta.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3aa91955751f329e0aa431b87c199b7378b6f91ec0765d2ad9d4c64e017c3cda"
dependencies = [
"anyhow",
"glob",
"schemars",
"serde",
"serde_json",
"serde_repr",
"tauri",
"tauri-plugin",
"thiserror",
"url",
"uuid",
]
[[package]]
name = "tauri-plugin-window-state"
version = "2.0.0-beta.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74b5596f41b90668ea37562d512e1dead687d9ae5eadb49f9faa8b875a2740a3"
dependencies = [
"bitflags 2.5.0",
"log",
@ -4207,9 +4612,9 @@ dependencies = [
[[package]]
name = "tauri-runtime"
version = "2.0.0-beta.16"
version = "2.0.0-beta.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "574f3d59cbe6c76b6d849bc35aa3a9e8061ff8f75f557dc33f38c0e43cf55a41"
checksum = "d7dc96172a43536236ab55b7da7b8461bf75810985e668589e2395cb476937cb"
dependencies = [
"dpi",
"gtk",
@ -4226,9 +4631,9 @@ dependencies = [
[[package]]
name = "tauri-runtime-wry"
version = "2.0.0-beta.16"
version = "2.0.0-beta.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6d1f223de1d674aaa561c900ac650b3160f11520e9b191a3574f6c493fc77fa"
checksum = "5d4fd913b1f14a9b618c7f3ae35656d3aa759767fcb95b72006357c12b9d0b09"
dependencies = [
"cocoa",
"gtk",
@ -4250,16 +4655,15 @@ dependencies = [
[[package]]
name = "tauri-utils"
version = "2.0.0-beta.15"
version = "2.0.0-beta.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b4251529d92b5c611ccaa611f8a31cb41b1aa00db8bcc0a49efe5d966bfa911"
checksum = "4f24a9c20d676a3f025331cc1c3841256ba88c9f25fb7fae709d2b3089c50d90"
dependencies = [
"brotli",
"cargo_metadata",
"ctor",
"dunce",
"glob",
"heck 0.5.0",
"html5ever",
"infer",
"json-patch",
@ -4423,6 +4827,7 @@ dependencies = [
"signal-hook-registry",
"socket2",
"tokio-macros",
"tracing",
"windows-sys 0.48.0",
]
@ -4633,14 +5038,14 @@ dependencies = [
[[package]]
name = "tray-icon"
version = "0.13.5"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39240037d755a1832e752d64f99078c3b0b21c09a71c12405070c75ef4e7cd3c"
checksum = "0b27516dfcfa22a9faaf192283a122bfbede38c1e59ef194e3c4db6549b419c0"
dependencies = [
"cocoa",
"core-graphics",
"crossbeam-channel",
"dirs-next",
"dirs",
"libappindicator",
"muda",
"objc",
@ -4673,6 +5078,17 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "uds_windows"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
dependencies = [
"memoffset",
"tempfile",
"winapi",
]
[[package]]
name = "unic-char-property"
version = "0.9.0"
@ -5450,9 +5866,9 @@ dependencies = [
[[package]]
name = "wry"
version = "0.39.3"
version = "0.40.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e180ac2740d6cb4d5cec0abf63eacbea90f1b7e5e3803043b13c1c84c4b7884"
checksum = "1fa597526af53f310a8e6218630c5024fdde8271f229e70d7d2fc70b52b8fb1e"
dependencies = [
"base64 0.22.1",
"block",
@ -5511,6 +5927,75 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "xdg-home"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21e5a325c3cb8398ad6cf859c1135b25dd29e186679cf2da7581d9679f63b38e"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "zbus"
version = "4.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030"
dependencies = [
"async-broadcast",
"async-process",
"async-recursion",
"async-trait",
"derivative",
"enumflags2",
"event-listener",
"futures-core",
"futures-sink",
"futures-util",
"hex",
"nix",
"ordered-stream",
"rand 0.8.5",
"serde",
"serde_repr",
"sha1",
"static_assertions",
"tokio",
"tracing",
"uds_windows",
"windows-sys 0.52.0",
"xdg-home",
"zbus_macros",
"zbus_names",
"zvariant",
]
[[package]]
name = "zbus_macros"
version = "4.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7a3e850ff1e7217a3b7a07eba90d37fe9bb9e89a310f718afcde5885ca9b6d7"
dependencies = [
"proc-macro-crate 1.3.1",
"proc-macro2",
"quote",
"regex",
"syn 1.0.109",
"zvariant_utils",
]
[[package]]
name = "zbus_names"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
dependencies = [
"serde",
"static_assertions",
"zvariant",
]
[[package]]
name = "zerocopy"
version = "0.7.33"
@ -5570,3 +6055,41 @@ dependencies = [
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
name = "zvariant"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e09e8be97d44eeab994d752f341e67b3b0d80512a8b315a0671d47232ef1b65"
dependencies = [
"endi",
"enumflags2",
"serde",
"static_assertions",
"url",
"zvariant_derive",
]
[[package]]
name = "zvariant_derive"
version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72a5857e2856435331636a9fbb415b09243df4521a267c5bedcd5289b4d5799e"
dependencies = [
"proc-macro-crate 1.3.1",
"proc-macro2",
"quote",
"syn 1.0.109",
"zvariant_utils",
]
[[package]]
name = "zvariant_utils"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00bedb16a193cc12451873fee2a1bc6550225acece0e36f333e68326c73c8172"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]

View file

@ -1,6 +1,6 @@
port = 8080
# port = 8443
https = false
# port = 8080
port = 8443
https = true
cache_busting = true
backend_log_level = "warn" # "error" / "warn" / "info" / "debug" / "trace"

View file

@ -14,3 +14,5 @@ wasm-bindgen-test = "0.3.19"
shared.workspace = true
zoon.workspace = true
wellen.workspace = true
web-sys = { version = "*", features = ["FileSystemFileHandle"] }
gloo-file = { version = "0.3.0", features = ["futures"] }

View file

@ -1,5 +1,6 @@
use crate::{platform, HierarchyAndTimeTable, Layout};
use futures_util::join;
use std::cell::Cell;
use std::mem;
use std::ops::Not;
use std::rc::Rc;
@ -9,6 +10,8 @@ use zoon::*;
const SCOPE_VAR_ROW_MAX_WIDTH: u32 = 480;
const MILLER_COLUMN_MAX_HEIGHT: u32 = 500;
type Filename = String;
#[derive(Clone)]
struct VarForUI {
name: Rc<String>,
@ -35,6 +38,7 @@ pub struct ControlsPanel {
hierarchy_and_time_table: Mutable<Option<HierarchyAndTimeTable>>,
selected_var_refs: MutableVec<wellen::VarRef>,
layout: Mutable<Layout>,
loaded_filename: Mutable<Option<Filename>>,
}
impl ControlsPanel {
@ -48,19 +52,28 @@ impl ControlsPanel {
hierarchy_and_time_table,
selected_var_refs,
layout,
loaded_filename: <_>::default(),
}
.root()
}
fn triggers(&self) -> Vec<TaskHandle> {
vec![Task::start_droppable(
self.hierarchy_and_time_table
.signal_ref(Option::is_none)
.for_each_sync(clone!((self => s) move |_| {
s.selected_scope_ref.set(None);
s.selected_var_refs.lock_mut().clear();
})),
)]
vec![Task::start_droppable(clone!((self => s) async move {
let was_some = Cell::new(false);
s.hierarchy_and_time_table
.signal_ref(Option::is_some)
.dedupe()
.for_each_sync(clone!((s) move |is_some| {
if is_some {
return was_some.set(true);
}
if was_some.get() {
s.selected_scope_ref.set(None);
s.selected_var_refs.lock_mut().clear();
s.loaded_filename.set(None);
}
})).await
}))]
}
fn root(&self) -> impl Element {
@ -94,8 +107,7 @@ impl ControlsPanel {
Row::new()
.s(Gap::both(15))
.s(Align::new().left())
.item(self.load_button("simple.vcd"))
.item(self.load_button("wave_27.fst"))
.item(self.load_button())
.item(self.layout_switcher()),
)
.item_signal(
@ -112,9 +124,10 @@ impl ControlsPanel {
))
}
fn load_button(&self, test_file_name: &'static str) -> impl Element {
fn load_button(&self) -> impl Element {
let (hovered, hovered_signal) = Mutable::new_and_signal(false);
let hierarchy_and_time_table = self.hierarchy_and_time_table.clone();
let loaded_filename = self.loaded_filename.clone();
Button::new()
.s(Padding::new().x(20).y(10))
.s(Background::new().color_signal(
@ -122,16 +135,12 @@ impl ControlsPanel {
))
.s(Align::new().left())
.s(RoundedCorners::all(15))
.label(
El::new().s(Font::new().no_wrap()).child_signal(
hierarchy_and_time_table
.signal_ref(Option::is_some)
.map_bool(
|| format!("Unload test file"),
move || format!("Load {test_file_name}"),
),
.label(El::new().s(Font::new().no_wrap()).child_signal(
loaded_filename.signal_cloned().map_option(
|filename| format!("Unload {filename}"),
|| format!("Load file.."),
),
)
))
.on_hovered_change(move |is_hovered| hovered.set_neq(is_hovered))
.on_press(move || {
let mut hierarchy_and_time_table_lock = hierarchy_and_time_table.lock_mut();
@ -141,11 +150,15 @@ impl ControlsPanel {
}
drop(hierarchy_and_time_table_lock);
let hierarchy_and_time_table = hierarchy_and_time_table.clone();
let loaded_filename = loaded_filename.clone();
Task::start(async move {
platform::load_waveform(test_file_name).await;
let (hierarchy, time_table) =
join!(platform::get_hierarchy(), platform::get_time_table());
hierarchy_and_time_table.set(Some((Rc::new(hierarchy), Rc::new(time_table))))
if let Some(filename) = platform::pick_and_load_waveform().await {
loaded_filename.set_neq(Some(filename));
let (hierarchy, time_table) =
join!(platform::get_hierarchy(), platform::get_time_table());
hierarchy_and_time_table
.set(Some((Rc::new(hierarchy), Rc::new(time_table))))
}
})
})
}

View file

@ -13,12 +13,15 @@ mod browser;
#[cfg(FASTWAVE_PLATFORM = "BROWSER")]
use browser as platform;
type Filename = String;
pub async fn show_window() {
platform::show_window().await
}
pub async fn load_waveform(test_file_name: &'static str) {
platform::load_waveform(test_file_name).await
// @TODO allow only support file types
pub async fn pick_and_load_waveform() -> Option<Filename> {
platform::pick_and_load_waveform().await
}
pub async fn get_hierarchy() -> wellen::Hierarchy {

View file

@ -1,7 +1,7 @@
use shared::wellen_helpers;
use std::sync::Mutex;
use wellen::simple::Waveform;
use zoon::*;
use zoon::{println, *};
#[derive(Default)]
struct Store {
@ -12,19 +12,40 @@ static STORE: Lazy<Store> = lazy::default();
pub(super) async fn show_window() {}
pub(super) async fn load_waveform(test_file_name: &'static str) {
static SIMPLE_VCD: &'static [u8; 311] = include_bytes!("../../../test_files/simple.vcd");
// static WAVE_27_FST: &'static [u8; 28860652] = include_bytes!("../../../test_files/wave_27.fst");
let chosen_file = match test_file_name {
"simple.vcd" => SIMPLE_VCD.to_vec(),
// "wave_27.fst" => WAVE_27_FST.to_vec(),
test_file_name => todo!("add {test_file_name} to the `test_files` folder"),
pub(super) async fn pick_and_load_waveform() -> Option<super::Filename> {
let file_handles_promise = window().show_open_file_picker().expect_throw(
"failed to open file picker (browser has to support `showOpenFilePicker` and use HTTPS",
);
let file_handles = JsFuture::from(file_handles_promise).await;
let file_handles = match file_handles {
Ok(file_handles) => file_handles.dyn_into::<js_sys::Array>().unwrap_throw(),
Err(error) => {
println!("file picker error: {error:?}");
return None;
}
};
let waveform = wellen_helpers::read_from_bytes(chosen_file);
let file_handle = file_handles
.at(0)
.dyn_into::<web_sys::FileSystemFileHandle>()
.unwrap_throw();
let file = JsFuture::from(file_handle.get_file())
.await
.unwrap_throw()
.dyn_into::<web_sys::File>()
.unwrap_throw();
let file = gloo_file::File::from(file);
let content = gloo_file::futures::read_as_bytes(&file)
.await
.unwrap_throw();
let waveform = wellen_helpers::read_from_bytes(content);
let Ok(waveform) = waveform else {
panic!("VCD file reading failed")
panic!("Waveform file reading failed")
};
*STORE.waveform.lock().unwrap_throw() = Some(waveform);
Some(file.name())
}
pub(super) async fn get_hierarchy() -> wellen::Hierarchy {

View file

@ -1,28 +1,37 @@
use zoon::*;
pub(super) async fn show_window() {
tauri_glue::show_window().await
tauri_glue::show_window().await.unwrap_throw()
}
pub(super) async fn load_waveform(test_file_name: &'static str) {
tauri_glue::load_waveform(test_file_name).await
pub(super) async fn pick_and_load_waveform() -> Option<super::Filename> {
tauri_glue::pick_and_load_waveform()
.await
.unwrap_throw()
.as_string()
}
pub(super) async fn get_hierarchy() -> wellen::Hierarchy {
serde_wasm_bindgen::from_value(tauri_glue::get_hierarchy().await).unwrap_throw()
serde_wasm_bindgen::from_value(tauri_glue::get_hierarchy().await.unwrap_throw()).unwrap_throw()
}
pub(super) async fn get_time_table() -> wellen::TimeTable {
serde_wasm_bindgen::from_value(tauri_glue::get_time_table().await).unwrap_throw()
serde_wasm_bindgen::from_value(tauri_glue::get_time_table().await.unwrap_throw()).unwrap_throw()
}
pub(super) async fn load_and_get_signal(signal_ref: wellen::SignalRef) -> wellen::Signal {
serde_wasm_bindgen::from_value(tauri_glue::load_and_get_signal(signal_ref.index()).await)
.unwrap_throw()
serde_wasm_bindgen::from_value(
tauri_glue::load_and_get_signal(signal_ref.index())
.await
.unwrap_throw(),
)
.unwrap_throw()
}
pub(super) async fn unload_signal(signal_ref: wellen::SignalRef) {
tauri_glue::unload_signal(signal_ref.index()).await
tauri_glue::unload_signal(signal_ref.index())
.await
.unwrap_throw()
}
mod tauri_glue {
@ -31,16 +40,22 @@ mod tauri_glue {
// Note: Add all corresponding methods to `frontend/typescript/tauri_glue/tauri_glue.ts`
#[wasm_bindgen(module = "/typescript/bundles/tauri_glue.js")]
extern "C" {
pub async fn show_window();
#[wasm_bindgen(catch)]
pub async fn show_window() -> Result<(), JsValue>;
pub async fn load_waveform(test_file_name: &str);
#[wasm_bindgen(catch)]
pub async fn pick_and_load_waveform() -> Result<JsValue, JsValue>;
pub async fn get_hierarchy() -> JsValue;
#[wasm_bindgen(catch)]
pub async fn get_hierarchy() -> Result<JsValue, JsValue>;
pub async fn get_time_table() -> JsValue;
#[wasm_bindgen(catch)]
pub async fn get_time_table() -> Result<JsValue, JsValue>;
pub async fn load_and_get_signal(signal_ref_index: usize) -> JsValue;
#[wasm_bindgen(catch)]
pub async fn load_and_get_signal(signal_ref_index: usize) -> Result<JsValue, JsValue>;
pub async fn unload_signal(signal_ref_index: usize);
#[wasm_bindgen(catch)]
pub async fn unload_signal(signal_ref_index: usize) -> Result<(), JsValue>;
}
}

View file

@ -2514,8 +2514,8 @@ var invoke2 = core_exports.invoke;
async function show_window() {
return await invoke2("show_window");
}
async function load_waveform(test_file_name) {
return await invoke2("load_waveform", { test_file_name });
async function pick_and_load_waveform() {
return await invoke2("pick_and_load_waveform");
}
async function get_hierarchy() {
return await invoke2("get_hierarchy");
@ -2533,7 +2533,7 @@ export {
get_hierarchy,
get_time_table,
load_and_get_signal,
load_waveform,
pick_and_load_waveform,
show_window,
unload_signal
};

View file

@ -4,6 +4,7 @@ import { core } from '@tauri-apps/api'
const invoke = core.invoke;
type Filename = string;
type WellenHierarchy = unknown;
type WellenTimeTable = unknown;
type WellenSignal = unknown;
@ -12,8 +13,8 @@ export async function show_window(): Promise<void> {
return await invoke("show_window");
}
export async function load_waveform(test_file_name: string): Promise<void> {
return await invoke("load_waveform", { test_file_name });
export async function pick_and_load_waveform(): Promise<Filename | undefined> {
return await invoke("pick_and_load_waveform");
}
export async function get_hierarchy(): Promise<WellenHierarchy> {

View file

@ -13,12 +13,13 @@ name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "=2.0.0-beta.15", features = [] }
tauri-build = { version = "=2.0.0-beta.17", features = [] }
[dependencies]
shared.workspace = true
wellen.workspace = true
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "=2.0.0-beta.19", features = ["macos-private-api", "linux-ipc-protocol"] }
tauri-plugin-window-state = "=2.0.0-beta.7"
tauri = { version = "=2.0.0-beta.22", features = ["macos-private-api", "linux-ipc-protocol"] }
tauri-plugin-window-state = "=2.0.0-beta.9"
tauri-plugin-dialog = "=2.0.0-beta.9"

View file

@ -1,50 +1,56 @@
use shared::wellen_helpers;
use std::rc::Rc;
use std::sync::Mutex;
use tauri_plugin_dialog::DialogExt;
use wellen::simple::Waveform;
type Filename = String;
#[derive(Default)]
struct Store {
waveform: Mutex<Option<Waveform>>,
}
#[tauri::command(rename_all = "snake_case")]
fn show_window(window: tauri::Window) {
async fn show_window(window: tauri::Window) {
window.show().unwrap();
}
#[tauri::command(rename_all = "snake_case")]
fn load_waveform(test_file_name: Rc<String>, store: tauri::State<Store>) {
static SIMPLE_VCD: &'static [u8; 311] = include_bytes!("../../test_files/simple.vcd");
static WAVE_27_FST: &'static [u8; 28860652] = include_bytes!("../../test_files/wave_27.fst");
let chosen_file = match test_file_name.as_str() {
"simple.vcd" => SIMPLE_VCD.to_vec(),
"wave_27.fst" => WAVE_27_FST.to_vec(),
test_file_name => todo!("add {test_file_name} to the `test_files` folder"),
async fn pick_and_load_waveform(
store: tauri::State<'_, Store>,
app: tauri::AppHandle,
) -> Result<Option<Filename>, ()> {
let Some(file_response) = app.dialog().file().blocking_pick_file() else {
return Ok(None);
};
let waveform = wellen_helpers::read_from_bytes(chosen_file);
let file_path = file_response.path.as_os_str().to_str().unwrap();
// @TODO `read` should accept `Path` instead of `&str`
let waveform = wellen::simple::read(file_path);
let Ok(waveform) = waveform else {
panic!("VCD file reading failed")
panic!("Waveform file reading failed")
};
*store.waveform.lock().unwrap() = Some(waveform);
Ok(Some(file_response.name.unwrap()))
}
#[tauri::command(rename_all = "snake_case")]
fn get_hierarchy(store: tauri::State<Store>) -> serde_json::Value {
async fn get_hierarchy(store: tauri::State<'_, Store>) -> Result<serde_json::Value, ()> {
let waveform = store.waveform.lock().unwrap();
let hierarchy = waveform.as_ref().unwrap().hierarchy();
serde_json::to_value(hierarchy).unwrap()
Ok(serde_json::to_value(hierarchy).unwrap())
}
#[tauri::command(rename_all = "snake_case")]
fn get_time_table(store: tauri::State<Store>) -> serde_json::Value {
async fn get_time_table(store: tauri::State<'_, Store>) -> Result<serde_json::Value, ()> {
let waveform = store.waveform.lock().unwrap();
let time_table = waveform.as_ref().unwrap().time_table();
serde_json::to_value(time_table).unwrap()
Ok(serde_json::to_value(time_table).unwrap())
}
#[tauri::command(rename_all = "snake_case")]
fn load_and_get_signal(signal_ref_index: usize, store: tauri::State<Store>) -> serde_json::Value {
async fn load_and_get_signal(
signal_ref_index: usize,
store: tauri::State<'_, Store>,
) -> Result<serde_json::Value, ()> {
let signal_ref = wellen::SignalRef::from_index(signal_ref_index).unwrap();
let mut waveform_lock = store.waveform.lock().unwrap();
let waveform = waveform_lock.as_mut().unwrap();
@ -52,15 +58,16 @@ fn load_and_get_signal(signal_ref_index: usize, store: tauri::State<Store>) -> s
// make the command async or return the result through a Tauri channel
waveform.load_signals_multi_threaded(&[signal_ref]);
let signal = waveform.get_signal(signal_ref).unwrap();
serde_json::to_value(signal).unwrap()
Ok(serde_json::to_value(signal).unwrap())
}
#[tauri::command(rename_all = "snake_case")]
fn unload_signal(signal_ref_index: usize, store: tauri::State<Store>) {
async fn unload_signal(signal_ref_index: usize, store: tauri::State<'_, Store>) -> Result<(), ()> {
let signal_ref = wellen::SignalRef::from_index(signal_ref_index).unwrap();
let mut waveform_lock = store.waveform.lock().unwrap();
let waveform = waveform_lock.as_mut().unwrap();
waveform.unload_signals(&[signal_ref]);
Ok(())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
@ -72,10 +79,11 @@ pub fn run() {
tauri::Builder::default()
.manage(Store::default())
.plugin(tauri_plugin_window_state::Builder::default().build())
.plugin(tauri_plugin_dialog::init())
// Npte: Add all handlers to `frontend/src/tauri_bridge.rs`
.invoke_handler(tauri::generate_handler![
show_window,
load_waveform,
pick_and_load_waveform,
get_hierarchy,
get_time_table,
load_and_get_signal,

View file

@ -4,7 +4,7 @@
"identifier": "com.fastwave",
"build": {
"frontendDist": "../frontend_dist",
"devUrl": "http://localhost:8080",
"devUrl": "https://localhost:8443",
"beforeDevCommand": "makers mzoon_for_tauri start",
"beforeBuildCommand": "makers mzoon_for_tauri build -r -f"
},