diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 6ee4128..5cb2bb2 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -23,19 +23,19 @@ jobs: uses: actions-rs/cargo@v1 with: command: clippy - args: --all-targets --all-features -- -D warnings + args: --all-targets --all-features --workspace -- -D warnings - name: RustFmt uses: actions-rs/cargo@v1 with: command: fmt - args: --all -- --check + args: --all --check - name: Test uses: actions-rs/cargo@v1 with: command: test - args: --all-features + args: --all-features --workspace - name: Cargo Doc if: ${{ matrix.os == 'ubuntu-latest' }} diff --git a/Cargo.lock b/Cargo.lock index 4a3bd2e..3b23081 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ab_glyph" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1061f3ff92c2f65800df1f12fc7b4ff44ee14783104187dd04dfee6f11b0fd2" +checksum = "80179d7dd5d7e8c285d67c4a1e652972a92de7475beddfb92028c76463b13225" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -20,9 +20,9 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "accesskit" -version = "0.11.2" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76eb1adf08c5bcaa8490b9851fd53cca27fa9880076f178ea9d29f05196728a8" +checksum = "6cb10ed32c63247e4e39a8f42e8e30fb9442fbf7878c8e4a9849e7e381619bea" dependencies = [ "enumn", "serde", @@ -30,18 +30,18 @@ dependencies = [ [[package]] name = "accesskit_consumer" -version = "0.15.2" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04bb4d9e4772fe0d47df57d0d5dbe5d85dd05e2f37ae1ddb6b105e76be58fb00" +checksum = "8c17cca53c09fbd7288667b22a201274b9becaa27f0b91bf52a526db95de45e6" dependencies = [ "accesskit", ] [[package]] name = "accesskit_macos" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134d0acf6acb667c89d3332999b1a5df4edbc8d6113910f392ebb73f2b03bb56" +checksum = "cd3b6ae1eabbfbced10e840fd3fce8a93ae84f174b3e4ba892ab7bcb42e477a7" dependencies = [ "accesskit", "accesskit_consumer", @@ -51,38 +51,40 @@ dependencies = [ [[package]] name = "accesskit_unix" -version = "0.5.2" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e084cb5168790c0c112626175412dc5ad127083441a8248ae49ddf6725519e83" +checksum = "09f46c18d99ba61ad7123dd13eeb0c104436ab6af1df6a1cd8c11054ed394a08" dependencies = [ "accesskit", "accesskit_consumer", "async-channel", + "async-once-cell", "atspi", - "futures-lite", + "futures-lite 1.13.0", + "once_cell", "serde", "zbus", ] [[package]] name = "accesskit_windows" -version = "0.14.3" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eac0a7f2d7cd7a93b938af401d3d8e8b7094217989a7c25c55a953023436e31" +checksum = "afcae27ec0974fc7c3b0b318783be89fd1b2e66dd702179fe600166a38ff4a0b" dependencies = [ "accesskit", "accesskit_consumer", - "arrayvec", "once_cell", "paste", + "static_assertions", "windows", ] [[package]] name = "accesskit_winit" -version = "0.14.4" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "825d23acee1bd6d25cbaa3ca6ed6e73faf24122a774ec33d52c5c86c6ab423c0" +checksum = "88e39fcec2e10971e188730b7a76bab60647dacc973d4591855ebebcadfaa738" dependencies = [ "accesskit", "accesskit_macos", @@ -91,6 +93,15 @@ dependencies = [ "winit", ] +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -99,14 +110,15 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", "once_cell", "serde", "version_check", + "zerocopy", ] [[package]] @@ -144,9 +156,9 @@ checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] name = "arboard" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac57f2b058a76363e357c056e4f74f1945bf734d37b8b3ef49066c4787dde0fc" +checksum = "aafb29b107435aa276664c1db8954ac27a6e105cdad3c88287a199eb0e313c08" dependencies = [ "clipboard-win", "log", @@ -183,26 +195,28 @@ dependencies = [ [[package]] name = "async-channel" -version = "1.9.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" dependencies = [ "concurrent-queue", - "event-listener 2.5.3", + "event-listener 4.0.2", + "event-listener-strategy", "futures-core", + "pin-project-lite", ] [[package]] name = "async-executor" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0c4a4f319e45986f347ee47fef8bf5e81c9abc3f6f58dc2391439f30df65f0" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" dependencies = [ - "async-lock", + "async-lock 3.2.0", "async-task", "concurrent-queue", "fastrand 2.0.1", - "futures-lite", + "futures-lite 2.1.0", "slab", ] @@ -212,10 +226,10 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "blocking", - "futures-lite", + "futures-lite 1.13.0", ] [[package]] @@ -224,20 +238,39 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "cfg-if", "concurrent-queue", - "futures-lite", + "futures-lite 1.13.0", "log", "parking", - "polling", - "rustix 0.37.26", + "polling 2.8.0", + "rustix 0.37.27", "slab", "socket2", "waker-fn", ] +[[package]] +name = "async-io" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +dependencies = [ + "async-lock 3.2.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.1.0", + "parking", + "polling 3.3.1", + "rustix 0.38.28", + "slab", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "async-lock" version = "2.8.0" @@ -247,20 +280,37 @@ dependencies = [ "event-listener 2.5.3", ] +[[package]] +name = "async-lock" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +dependencies = [ + "event-listener 4.0.2", + "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 = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-signal", "blocking", "cfg-if", - "event-listener 3.0.0", - "futures-lite", - "rustix 0.38.20", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -272,22 +322,22 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] name = "async-signal" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2a5415b7abcdc9cd7d63d6badba5288b2ca017e3fbd4173b8f405449f1a2399" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" dependencies = [ - "async-io", - "async-lock", + "async-io 2.2.2", + "async-lock 2.8.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.20", + "rustix 0.38.28", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -295,19 +345,19 @@ dependencies = [ [[package]] name = "async-task" -version = "4.5.0" +version = "4.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] @@ -318,29 +368,50 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atspi" -version = "0.10.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "674e7a3376837b2e7d12d34d58ac47073c491dc3bf6f71a7adaf687d4d817faa" +checksum = "6059f350ab6f593ea00727b334265c4dfc7fd442ee32d264794bd9bdc68e87ca" +dependencies = [ + "atspi-common", + "atspi-connection", + "atspi-proxies", +] + +[[package]] +name = "atspi-common" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92af95f966d2431f962bc632c2e68eda7777330158bf640c4af4249349b2cdf5" dependencies = [ - "async-recursion", - "async-trait", - "atspi-macros", "enumflags2", - "futures-lite", "serde", - "tracing", + "static_assertions", "zbus", "zbus_names", + "zvariant", ] [[package]] -name = "atspi-macros" -version = "0.2.0" +name = "atspi-connection" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb4870a32c0eaa17e35bca0e6b16020635157121fb7d45593d242c295bc768" +checksum = "a0c65e7d70f86d4c0e3b2d585d9bf3f979f0b19d635a336725a88d279f76b939" dependencies = [ - "quote", - "syn 1.0.109", + "atspi-common", + "atspi-proxies", + "futures-lite 1.13.0", + "zbus", +] + +[[package]] +name = "atspi-proxies" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6495661273703e7a229356dcbe8c8f38223d697aacfaf0e13590a9ac9977bb52" +dependencies = [ + "atspi-common", + "serde", + "zbus", ] [[package]] @@ -349,11 +420,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "bit_field" @@ -409,16 +495,16 @@ dependencies = [ [[package]] name = "blocking" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ "async-channel", - "async-lock", + "async-lock 3.2.0", "async-task", "fastrand 2.0.1", "futures-io", - "futures-lite", + "futures-lite 2.1.0", "piper", "tracing", ] @@ -446,7 +532,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] @@ -577,18 +663,18 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" dependencies = [ "crossbeam-utils", ] [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -596,9 +682,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-graphics" @@ -615,9 +701,9 @@ dependencies = [ [[package]] name = "core-graphics-types" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -626,9 +712,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbc60abd742b35f2492f808e1abbb83d45f72db402e14c55057edc9c7b1e9e4" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] @@ -644,9 +730,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -655,22 +741,20 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" dependencies = [ "cfg-if", ] @@ -729,9 +813,9 @@ dependencies = [ [[package]] name = "document-features" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e493c573fce17f00dcab13b6ac057994f3ce17d1af4dc39bfd482b83c6eb6157" +checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" dependencies = [ "litrs", ] @@ -744,9 +828,9 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "ecolor" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf4e52dbbb615cfd30cf5a5265335c217b5fd8d669593cea74a517d9c605af" +checksum = "4b7637fc2e74d17e52931bac90ff4fc061ac776ada9c7fa272f24cdca5991972" dependencies = [ "bytemuck", "color-hex", @@ -755,9 +839,9 @@ dependencies = [ [[package]] name = "eframe" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d9efede6c8905d3fc51a5ec9a506d4da4011bbcae0253d0304580fe40af3f5" +checksum = "cdd73918a828c35a7efb4d7188ea973df4bffc589178ed95f521c917b03ddcfa" dependencies = [ "bytemuck", "cocoa", @@ -785,9 +869,9 @@ dependencies = [ [[package]] name = "egui" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd69fed5fcf4fbb8225b24e80ea6193b61e17a625db105ef0c4d71dde6eb8b7" +checksum = "c55bcb864b764eb889515a38b8924757657a250738ad15126637ee2df291ee6b" dependencies = [ "accesskit", "ahash", @@ -799,9 +883,9 @@ dependencies = [ [[package]] name = "egui-winit" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c15479a96d9fadccf5dac690bdc6373b97b8e1c0dd28367058f25a5298da0195" +checksum = "3b673606b6606b12b95e3a3194d7882bf5cff302db36a520b8144c7c342e4e84" dependencies = [ "accesskit_winit", "arboard", @@ -842,9 +926,9 @@ dependencies = [ [[package]] name = "egui_extras" -version = "0.23.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ffe3fe5c00295f91c2a61a74ee271c32f74049c94ba0b1cea8f26eb478bc07" +checksum = "97624eaf17a16058265d3a3e712e167798655baf7c8f693de25be75cdd6c57b5" dependencies = [ "egui", "ehttp", @@ -856,15 +940,15 @@ dependencies = [ [[package]] name = "egui_glow" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6726c08798822280038bbad2e32f4fc3cbed800cd51c6e34e99cd2d60cc1bc" +checksum = "262151f9d57c557c02a40a46f27b9e050a6eb0b006b94dced9c6f4519a04d489" dependencies = [ "bytemuck", "egui", "glow", "log", - "memoffset 0.6.5", + "memoffset 0.7.1", "wasm-bindgen", "web-sys", ] @@ -886,6 +970,8 @@ dependencies = [ "egui_extras", "egui_inbox", "egui_virtual_list", + "rand", + "web-time", ] [[package]] @@ -924,6 +1010,7 @@ version = "0.1.0" dependencies = [ "eframe", "egui", + "rand", ] [[package]] @@ -948,9 +1035,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "emath" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ef2b29de53074e575c18b694167ccbe6e5191f7b25fe65175a0d905a32eeec0" +checksum = "a045c6c0b44b35e98513fc1e9d183ab42881ac27caccb9fa345465601f56cce4" dependencies = [ "bytemuck", "serde", @@ -958,9 +1045,9 @@ dependencies = [ [[package]] name = "enum-map" -version = "2.7.0" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53337c2dbf26a3c31eccc73a37b10c1614e8d4ae99b6a50d553e8936423c1f16" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" dependencies = [ "enum-map-derive", "serde", @@ -968,13 +1055,13 @@ dependencies = [ [[package]] name = "enum-map-derive" -version = "0.14.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04d0b288e3bb1d861c4403c1774a6f7a798781dfc519b3647df2a3dd4ae95f25" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] @@ -995,25 +1082,25 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] name = "enumn" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b" +checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] name = "epaint" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58067b840d009143934d91d8dcb8ded054d8301d7c11a517ace0a99bb1e1595e" +checksum = "7d1b9e000d21bab9b535ce78f9f7745be28b3f777f6c7223936561c5c7fefab8" dependencies = [ "ab_glyph", "ahash", @@ -1034,12 +1121,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1060,15 +1147,36 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29e56284f00d94c1bc7fd3c77027b4623c88c1f53d8d2394c6199f2921dea325" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" dependencies = [ "concurrent-queue", "parking", "pin-project-lite", ] +[[package]] +name = "event-listener" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "218a870470cce1469024e9fb66b901aa983929d81304a1cdb299f28118e550d5" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.2", + "pin-project-lite", +] + [[package]] name = "exr" version = "1.71.0" @@ -1092,13 +1200,18 @@ dependencies = [ "color-hex", "eframe", "egui", + "egui_animation", "egui_dnd", "egui_extras", + "egui_inbox", "egui_infinite_scroll", "ehttp", + "gloo-timers", + "hello_egui_utils", "image", "serde", "serde_json", + "tokio", "wasm-bindgen", "wasm-bindgen-futures", ] @@ -1120,9 +1233,9 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fdeflate" -version = "0.3.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" dependencies = [ "simd-adler32", ] @@ -1143,7 +1256,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ - "spin 0.9.8", + "spin", ] [[package]] @@ -1163,24 +1276,33 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -1197,23 +1319,36 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "futures-lite" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" +dependencies = [ + "fastrand 2.0.1", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-core", "futures-io", @@ -1237,9 +1372,9 @@ dependencies = [ [[package]] name = "gethostname" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +checksum = "bb65d4ba3173c56a500b555b532f72c42e8d1fe64962b518897f8959fae2c177" dependencies = [ "libc", "winapi", @@ -1247,9 +1382,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -1266,6 +1401,12 @@ dependencies = [ "weezl", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "gl_generator" version = "0.14.0" @@ -1277,6 +1418,18 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "glow" version = "0.12.3" @@ -1355,9 +1508,9 @@ dependencies = [ [[package]] name = "grid" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df00eed8d1f0db937f6be10e46e8072b0671accb504cf0f959c5c52c679f5b9" +checksum = "d196ffc1627db18a531359249b2bf8416178d84b729f3cebeb278f285fb9b58c" [[package]] name = "half" @@ -1370,9 +1523,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "hello_egui" @@ -1406,18 +1559,18 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1444,9 +1597,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown", @@ -1477,9 +1630,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jni" @@ -1523,9 +1676,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -1550,9 +1703,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libloading" @@ -1574,6 +1727,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "libredox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -1582,15 +1746,15 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "litrs" -version = "0.2.3" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9275e0933cf8bb20f008924c0cb07a0692fe54d8064996520bf998de9eb79aa" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" [[package]] name = "lock_api" @@ -1619,9 +1783,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memmap2" @@ -1659,12 +1823,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1677,9 +1835,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", @@ -1759,16 +1917,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "num-integer" version = "0.1.45" @@ -1838,7 +1986,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] @@ -1896,19 +2044,28 @@ dependencies = [ "objc", ] +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "orbclient" -version = "0.3.46" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8378ac0dfbd4e7895f2d2c1f1345cab3836910baf3a300b000d04250f0c8428f" +checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ - "redox_syscall 0.3.5", + "libredox", ] [[package]] @@ -1923,9 +2080,9 @@ dependencies = [ [[package]] name = "owned_ttf_parser" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "706de7e2214113d63a8238d1910463cfce781129a6f263d13fdb09ff64355ba4" +checksum = "d4586edfe4c648c71797a74c84bacb32b52b212eff5dfe2bb9f2c599844023e7" dependencies = [ "ttf-parser", ] @@ -1967,9 +2124,9 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" @@ -1996,9 +2153,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" [[package]] name = "png" @@ -2029,6 +2186,20 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "polling" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix 0.38.28", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2047,9 +2218,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" dependencies = [ "unicode-ident", ] @@ -2065,9 +2236,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2177,24 +2348,29 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "ring" -version = "0.16.20" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", + "getrandom", "libc", - "once_cell", - "spin 0.5.2", + "spin", "untrusted", - "web-sys", - "winapi", + "windows-sys 0.48.0", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustix" -version = "0.37.26" +version = "0.37.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f3f8f960ed3b5a59055428714943298bf3fa2d4a1d53135084e0544829d995" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ "bitflags 1.3.2", "errno", @@ -2206,22 +2382,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.20" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys 0.4.10", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring", @@ -2231,9 +2407,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring", "untrusted", @@ -2241,9 +2417,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -2268,9 +2444,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring", "untrusted", @@ -2291,29 +2467,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.189" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.194" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -2322,13 +2498,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] @@ -2374,18 +2550,18 @@ dependencies = [ [[package]] name = "slotmap" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ "version_check", ] [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "smithay-client-toolkit" @@ -2418,20 +2594,14 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -2472,9 +2642,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" dependencies = [ "proc-macro2", "quote", @@ -2484,45 +2654,46 @@ dependencies = [ [[package]] name = "taffy" version = "0.3.11" -source = "git+https://github.com/DioxusLabs/taffy?branch=main#23ff477566b0239f04d3b89a2b3a4da2495e9577" +source = "git+https://github.com/DioxusLabs/taffy?branch=main#563d5dcee7b9138b4c3f865155d036a8b7597e65" dependencies = [ "arrayvec", "grid", "num-traits", + "serde", "slotmap", ] [[package]] name = "tempfile" -version = "3.8.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", "fastrand 2.0.1", - "redox_syscall 0.3.5", - "rustix 0.38.20", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "rustix 0.38.28", + "windows-sys 0.52.0", ] [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] @@ -2576,11 +2747,33 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +dependencies = [ + "backtrace", + "pin-project-lite", + "tokio-macros", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.47", +] + [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" [[package]] name = "toml_edit" @@ -2612,7 +2805,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", ] [[package]] @@ -2626,9 +2819,9 @@ dependencies = [ [[package]] name = "ttf-parser" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1" +checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" [[package]] name = "typenum" @@ -2638,19 +2831,20 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uds_windows" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ + "memoffset 0.9.0", "tempfile", "winapi", ] [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -2669,15 +2863,15 @@ dependencies = [ [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.8.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" +checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" dependencies = [ "base64", "flate2", @@ -2691,9 +2885,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -2736,9 +2930,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2746,24 +2940,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if", "js-sys", @@ -2773,9 +2967,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2783,22 +2977,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.47", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wayland-client" @@ -2887,9 +3081,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -2897,9 +3091,9 @@ dependencies = [ [[package]] name = "web-time" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8208e3fdbc243c8fd30805721869242a7f6de3e2e9f3b057652ab36e52ae1e87" +checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" dependencies = [ "js-sys", "wasm-bindgen", @@ -2924,9 +3118,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "weezl" @@ -3025,6 +3219,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -3055,6 +3258,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -3067,6 +3285,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -3079,6 +3303,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -3091,6 +3321,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -3103,6 +3339,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -3115,6 +3357,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -3127,6 +3375,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -3139,6 +3393,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winit" version = "0.28.7" @@ -3176,9 +3436,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.5.17" +version = "0.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" +checksum = "8434aeec7b290e8da5c3f0d628cb0eac6cabcb31d14bb74f779a08109a5914d6" dependencies = [ "memchr", ] @@ -3196,12 +3456,12 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.10.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" +checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a" dependencies = [ "gethostname", - "nix 0.24.3", + "nix 0.26.4", "winapi", "winapi-wsapoll", "x11rb-protocol", @@ -3209,21 +3469,18 @@ dependencies = [ [[package]] name = "x11rb-protocol" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" +checksum = "82d6c3f9a0fb6701fab8f6cea9b0c0bd5d6876f1f89f7fada07e558077c344bc" dependencies = [ - "nix 0.24.3", + "nix 0.26.4", ] [[package]] name = "xcursor" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" -dependencies = [ - "nom", -] +checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" [[package]] name = "xdg-home" @@ -3250,8 +3507,8 @@ dependencies = [ "async-broadcast", "async-executor", "async-fs", - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-process", "async-recursion", "async-task", @@ -3307,6 +3564,26 @@ dependencies = [ "zvariant", ] +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.47", +] + [[package]] name = "zune-inflate" version = "0.2.54" diff --git a/crates/egui_animation/src/lib.rs b/crates/egui_animation/src/lib.rs index 2c36961..df3da2f 100644 --- a/crates/egui_animation/src/lib.rs +++ b/crates/egui_animation/src/lib.rs @@ -2,6 +2,11 @@ mod collapse; use std::fmt::Debug; use std::hash::Hash; +use std::time::Duration; + +pub mod easing { + pub use simple_easing::*; +} pub use collapse::*; use egui::{Context, Id, Pos2, Rect, Sense, Ui, Vec2}; @@ -111,3 +116,11 @@ pub fn animate_ui_translation( rect } + +pub fn animate_continuous(ui: &mut Ui, easing: Easing, duration: Duration, offset: f32) -> f32 { + ui.ctx().request_repaint(); + + let t = ui.input(|i| i.time as f32 + offset); + let x = t % duration.as_secs_f32(); + easing::roundtrip(easing(x / duration.as_secs_f32())) +} diff --git a/crates/egui_dnd/examples/nested.rs b/crates/egui_dnd/examples/nested.rs index 28f3acf..0d5883f 100644 --- a/crates/egui_dnd/examples/nested.rs +++ b/crates/egui_dnd/examples/nested.rs @@ -5,7 +5,6 @@ use egui_dnd::{dnd, DragDropItem, Handle}; pub fn main() { let options = eframe::NativeOptions { - initial_window_size: Some(egui::vec2(320.0, 240.0)), ..Default::default() }; eframe::run_native("DnD", options, Box::new(|_cc| Box::::default())).unwrap(); diff --git a/crates/egui_infinite_scroll/Cargo.toml b/crates/egui_infinite_scroll/Cargo.toml index 01cb65f..7c49678 100644 --- a/crates/egui_infinite_scroll/Cargo.toml +++ b/crates/egui_infinite_scroll/Cargo.toml @@ -15,7 +15,8 @@ egui_virtual_list = { path = "../egui_virtual_list" } egui.workspace = true egui_extras = { workspace = true, optional = true } +web-time = "0.2" [dev-dependencies] eframe = { workspace = true, default-features = true } - +rand = "0.8" \ No newline at end of file diff --git a/crates/egui_infinite_scroll/examples/infinite_scroll.rs b/crates/egui_infinite_scroll/examples/infinite_scroll.rs index f72e36c..5ecc2b3 100644 --- a/crates/egui_infinite_scroll/examples/infinite_scroll.rs +++ b/crates/egui_infinite_scroll/examples/infinite_scroll.rs @@ -10,7 +10,7 @@ pub fn main() -> eframe::Result<()> { }); eframe::run_simple_native( - "DnD Simple Example", + "Infinite Scroll Simple Example", Default::default(), move |ctx, _frame| { CentralPanel::default().show(ctx, |ui| { diff --git a/crates/egui_infinite_scroll/examples/infinite_scroll_both_directions.rs b/crates/egui_infinite_scroll/examples/infinite_scroll_both_directions.rs new file mode 100644 index 0000000..6f53225 --- /dev/null +++ b/crates/egui_infinite_scroll/examples/infinite_scroll_both_directions.rs @@ -0,0 +1,52 @@ +use eframe::egui; +use egui::{CentralPanel, ScrollArea}; +use std::thread::{sleep, spawn}; + +use egui_infinite_scroll::InfiniteScroll; + +pub fn main() -> eframe::Result<()> { + let mut infinite_scroll = InfiniteScroll::new() + .start_loader(|cursor, callback| { + let start = cursor.unwrap_or(0); + let end = start - 100; + spawn(move || { + sleep(std::time::Duration::from_secs_f32(0.6)); + callback(Ok(((end..start).collect(), Some(end)))); + }); + }) + .end_loader(|cursor, callback| { + let start = cursor.unwrap_or(0); + let end = start + 100; + spawn(move || { + sleep(std::time::Duration::from_secs_f32(0.5)); + callback(Ok(((start..end).collect(), Some(end)))); + }); + }); + + eframe::run_simple_native( + "Infinite Scroll Both Directions Example", + Default::default(), + move |ctx, _frame| { + CentralPanel::default().show(ctx, |ui| { + ScrollArea::vertical().show(ui, |ui| { + if ui.button("Reset").clicked() { + infinite_scroll.reset(); + }; + ui.vertical_centered(|ui| { + ui.set_visible(infinite_scroll.top_loading_state().loading()); + ui.spinner(); + }); + + infinite_scroll.ui(ui, 10, |ui, _index, item| { + ui.label(format!("Item {}", item)); + }); + + ui.vertical_centered(|ui| { + ui.set_visible(infinite_scroll.bottom_loading_state().loading()); + ui.spinner(); + }); + }); + }); + }, + ) +} diff --git a/crates/egui_infinite_scroll/examples/infinite_scroll_retry.rs b/crates/egui_infinite_scroll/examples/infinite_scroll_retry.rs new file mode 100644 index 0000000..0e66288 --- /dev/null +++ b/crates/egui_infinite_scroll/examples/infinite_scroll_retry.rs @@ -0,0 +1,51 @@ +use eframe::egui; +use egui::{CentralPanel, ScrollArea}; +use egui_infinite_scroll::{InfiniteScroll, LoadingState}; + +pub fn main() -> eframe::Result<()> { + let mut infinite_scroll = InfiniteScroll::new().end_loader(|cursor, callback| { + let start = cursor.unwrap_or(0); + let end = start + 100; + + let err = rand::random::(); + let err = err > 0.7; + callback(if err { + Err("Error loading your numbers :( please try again".to_string()) + } else { + Ok(((start..end).collect(), Some(end))) + }); + }); + + eframe::run_simple_native( + "Infinite Scroll Simple Example", + Default::default(), + move |ctx, _frame| { + CentralPanel::default().show(ctx, |ui| { + ScrollArea::vertical().show(ui, |ui| { + ui.set_width(ui.available_width()); + if ui.button("Reset").clicked() { + infinite_scroll.reset(); + }; + + infinite_scroll.ui(ui, 10, |ui, _index, item| { + ui.label(format!("Item {}", item)); + }); + + match infinite_scroll.bottom_loading_state() { + LoadingState::Error(err) => { + ui.label("Error:"); + ui.code(err); + if ui.button("Retry").clicked() { + infinite_scroll.retry_bottom(); + }; + } + LoadingState::Loading => { + ui.spinner(); + } + _ => {} + } + }); + }); + }, + ) +} diff --git a/crates/egui_infinite_scroll/src/lib.rs b/crates/egui_infinite_scroll/src/lib.rs index f82691e..436d7e2 100644 --- a/crates/egui_infinite_scroll/src/lib.rs +++ b/crates/egui_infinite_scroll/src/lib.rs @@ -3,9 +3,9 @@ use std::mem; use std::ops::Range; use egui::Ui; - #[cfg(feature = "egui_extras")] use egui_extras::{TableBody, TableRow}; + use egui_inbox::UiInbox; use egui_virtual_list::{VirtualList, VirtualListResponse}; @@ -42,7 +42,7 @@ type FilterType = Box bool + Send + Sync>; pub struct InfiniteScroll { pub items: Vec, - // start_loader: Option>, + start_loader: Option>, end_loader: Option>, start_cursor: Option, @@ -59,9 +59,25 @@ pub struct InfiniteScroll { virtual_list: VirtualList, } -impl Debug for InfiniteScroll { +impl Debug for InfiniteScroll +where + T: Debug + Send + Sync, + Cursor: Clone + Debug + Send + Sync, +{ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.write_str("InfiniteScroll { ... }") + f.debug_struct("InfiniteScroll") + .field("items", &self.items) + .field("start_loader", &self.start_loader.is_some()) + .field("end_loader", &self.end_loader.is_some()) + .field("start_cursor", &self.start_cursor) + .field("end_cursor", &self.end_cursor) + .field("top_loading_state", &self.top_loading_state) + .field("bottom_loading_state", &self.bottom_loading_state) + .field("top_inbox", &self.top_inbox) + .field("bottom_inbox", &self.bottom_inbox) + .field("filter", &self.filter.is_some()) + .field("virtual_list", &self.virtual_list) + .finish() } } @@ -84,7 +100,7 @@ impl let bottom_inbox = UiInbox::new(); Self { items: Vec::new(), - // start_loader: None, + start_loader: None, end_loader: None, start_cursor: None, end_cursor: None, @@ -97,13 +113,13 @@ impl } } - // fn start_loader, Callback) + Send + Sync + 'static>( - // mut self, - // f: F, - // ) -> Self { - // self.start_loader = Some(Box::new(f)); - // self - // } + pub fn start_loader, Callback) + Send + Sync + 'static>( + mut self, + f: F, + ) -> Self { + self.start_loader = Some(Box::new(f)); + self + } /// Sets the loader function for the end of the list. /// The loader function is called initially and when the user scrolls to the end of the list. @@ -136,6 +152,22 @@ impl &self.bottom_loading_state } + /// Retry loading the top items + /// This only works if the top loading state is [LoadingState::Error] + pub fn retry_top(&mut self) { + if let LoadingState::Error(_) = self.top_loading_state { + self.top_loading_state = LoadingState::Idle; + } + } + + /// Retry loading the bottom items + /// This only works if the bottom loading state is [LoadingState::Error] + pub fn retry_bottom(&mut self) { + if let LoadingState::Error(_) = self.bottom_loading_state { + self.bottom_loading_state = LoadingState::Idle; + } + } + /// Resets the infinite scroll, clearing all items and loading states. /// This is a alias for [InfiniteScroll::reload]. pub fn reset(&mut self) { @@ -178,6 +210,8 @@ impl } let empty = items.is_empty(); self.items.extend(items); + + ui.ctx().request_repaint(); if empty || !has_cursor { LoadingState::NoMoreItems } else { @@ -191,6 +225,7 @@ impl self.top_inbox.read(ui).for_each(|state| { self.top_loading_state = match state { LoadingState::Loaded(items, cursor) => { + self.virtual_list.items_inserted_at_start(items.len()); let has_cursor = cursor.is_some(); if has_cursor { self.start_cursor = cursor; @@ -199,6 +234,8 @@ impl let mut old_items = mem::take(&mut self.items); self.items = items; self.items.append(&mut old_items); + + ui.ctx().request_repaint(); if empty || !has_cursor { LoadingState::NoMoreItems } else { @@ -239,34 +276,6 @@ impl layout(ui, start_index, &mut items[start_index..]) }); - ui.add_space(20.0); - - ui.separator(); - - ui.add_space(20.0); - - ui.vertical_centered(|ui| match &self.bottom_loading_state { - LoadingState::Loading => { - ui.spinner(); - } - LoadingState::Idle => { - ui.spinner(); - } - LoadingState::NoMoreItems => { - ui.label("No more items"); - } - LoadingState::Error(e) => { - ui.label(format!("Error: {}", e)); - if ui.button("Try again").clicked() { - self.bottom_loading_state = LoadingState::Idle; - ui.ctx().request_repaint(); - } - } - _ => {} - }); - - ui.add_space(20.0); - self.update_items(&response.item_range, end_prefetch); response @@ -276,7 +285,7 @@ impl let items = Self::filtered_items(&mut self.items, &self.filter); if item_range.end + end_prefetch >= items.len() - && matches!(self.bottom_loading_state, LoadingState::Idle) + && matches!(self.bottom_loading_state, LoadingState::Idle { .. }) { self.bottom_loading_state = LoadingState::Loading; let inbox = self.bottom_inbox.clone(); @@ -295,6 +304,27 @@ impl ); } } + + if item_range.start < end_prefetch + && matches!(self.top_loading_state, LoadingState::Idle { .. }) + { + self.top_loading_state = LoadingState::Loading; + let inbox = self.top_inbox.clone(); + + if let Some(start_loader) = &mut self.start_loader { + start_loader( + self.start_cursor.clone(), + Box::new(move |result| match result { + Ok((items, cursor)) => { + inbox.send(LoadingState::Loaded(items, cursor)); + } + Err(err) => { + inbox.send(LoadingState::Error(err.to_string())); + } + }), + ); + } + } } /// A simple layout with multiple columns. diff --git a/crates/egui_taffy/src/lib.rs b/crates/egui_taffy/src/lib.rs index a741755..23a1a73 100644 --- a/crates/egui_taffy/src/lib.rs +++ b/crates/egui_taffy/src/lib.rs @@ -7,7 +7,7 @@ use taffy::prelude::*; type Node = NodeId; struct TaffyState { - taffy: Taffy<(usize, egui::Layout)>, + taffy: TaffyTree<(usize, egui::Layout)>, children: Vec, @@ -28,7 +28,7 @@ unsafe impl Sync for TaffyState {} impl TaffyState { pub fn new() -> Self { - let mut taffy = Taffy::new(); + let mut taffy = TaffyTree::new(); Self { root_node: taffy.new_with_children(Style::default(), &[]).unwrap(), @@ -271,7 +271,7 @@ impl<'a, 'f> TaffyPass<'a, 'f> { let result_rect = response.response.rect; Size { - width: result_rect.width().ceil(), + width: result_rect.width().ceil() + 0.01, height: result_rect.height(), } }, diff --git a/crates/egui_virtual_list/Cargo.toml b/crates/egui_virtual_list/Cargo.toml index 7c7e547..176ceb0 100644 --- a/crates/egui_virtual_list/Cargo.toml +++ b/crates/egui_virtual_list/Cargo.toml @@ -11,3 +11,4 @@ egui.workspace = true [dev-dependencies] eframe = { workspace = true, default-features = true } +rand = "0.8" \ No newline at end of file diff --git a/crates/egui_virtual_list/examples/simple.rs b/crates/egui_virtual_list/examples/simple.rs deleted file mode 100644 index d512271..0000000 --- a/crates/egui_virtual_list/examples/simple.rs +++ /dev/null @@ -1,24 +0,0 @@ -use eframe::egui; -use egui::{CentralPanel, ScrollArea}; -use egui_virtual_list::VirtualList; - -pub fn main() -> eframe::Result<()> { - let items: Vec<_> = (0..100000).collect(); - let mut virtual_list = VirtualList::new(); - - eframe::run_simple_native( - "Virtual List Simple Example", - Default::default(), - move |ctx, _frame| { - CentralPanel::default().show(ctx, |ui| { - ScrollArea::vertical().show(ui, |ui| { - ui.set_width(ui.available_width()); - virtual_list.ui_custom_layout(ui, items.len(), |ui, start_index| { - ui.label(format!("Start index: {}", start_index)); - 1 - }); - }); - }); - }, - ) -} diff --git a/crates/egui_virtual_list/examples/virtual_list.rs b/crates/egui_virtual_list/examples/virtual_list.rs new file mode 100644 index 0000000..17510fa --- /dev/null +++ b/crates/egui_virtual_list/examples/virtual_list.rs @@ -0,0 +1,38 @@ +use eframe::egui; +use egui::{CentralPanel, Frame, Margin, ScrollArea}; +use egui_virtual_list::VirtualList; +use rand::prelude::StdRng; +use rand::{Rng, SeedableRng}; + +pub fn main() -> eframe::Result<()> { + let items: Vec<_> = (0..100000).collect(); + let mut virtual_list = VirtualList::new(); + + eframe::run_simple_native( + "Virtual List Simple Example", + Default::default(), + move |ctx, _frame| { + CentralPanel::default().show(ctx, |ui| { + ScrollArea::vertical().show(ui, |ui| { + ui.set_width(ui.available_width()); + virtual_list.ui_custom_layout(ui, items.len(), |ui, start_index| { + let item = &items[start_index]; + + let mut rng = StdRng::seed_from_u64(*item as u64); + // Should be random height based on start_index between 0 and 100 + let height = rng.gen_range(0.0..=100.0); + + Frame::canvas(ui.style()) + .inner_margin(Margin::symmetric(16.0, 8.0 + height / 2.0)) + .show(ui, |ui| { + ui.set_width(ui.available_width()); + ui.label(format!("Item {}", item)); + }); + + 1 + }); + }); + }); + }, + ) +} diff --git a/crates/egui_virtual_list/src/lib.rs b/crates/egui_virtual_list/src/lib.rs index 2201654..e99ef95 100644 --- a/crates/egui_virtual_list/src/lib.rs +++ b/crates/egui_virtual_list/src/lib.rs @@ -17,6 +17,7 @@ struct RowData { pos: Pos2, } +#[derive(Debug)] pub struct VirtualList { rows: Vec, @@ -34,6 +35,11 @@ pub struct VirtualList { max_rows_calculated_per_frame: usize, over_scan: f32, + + // If set, the list will scroll by this many items from the top. + // Useful when items at the top are added, and the scroll position should be maintained. + // The value should be the number of items that were added at the top. + items_inserted_at_start: Option, } impl Default for VirtualList { @@ -57,9 +63,21 @@ impl VirtualList { average_items_per_row: None, max_rows_calculated_per_frame: 1000, over_scan: 200.0, + items_inserted_at_start: None, } } + /// Set the number of items that were added at the top. + pub fn items_inserted_at_start(&mut self, scroll_top_items: usize) { + self.items_inserted_at_start = Some(scroll_top_items); + } + + /// Set the overscan, or how much the list should render outside of the visible area. + /// The default is 200.0. + pub fn over_scan(&mut self, over_scan: f32) { + self.over_scan = over_scan; + } + /// Layout gets called with the index of the first item that should be displayed. /// It should return the number of items that were displayed. pub fn ui_custom_layout( @@ -74,17 +92,49 @@ impl VirtualList { self.rows.clear(); } - // Start of the scroll area (!=0 after scrolling) - let min = ui.next_widget_position(); + // Start of the scroll area (basically scroll_offset + whatever is above the scroll area) + let min = ui.next_widget_position().to_vec2(); let mut row_start_index = self.last_known_row_index.unwrap_or(0); - // This calculates the visual rect inside the scroll area - // Should be equivalent to to viewport from ScrollArea::show_viewport() - let visible_rect = ui.clip_rect().translate(-ui.min_rect().min.to_vec2()); + // This calculates the visible rect inside the scroll area + // Should be equivalent to to viewport from ScrollArea::show_viewport(), offset by whatever is above the scroll area + let visible_rect = ui.clip_rect().translate(-min); let visible_rect = visible_rect.expand2(Vec2::new(0.0, self.over_scan)); + let mut index_offset = 0; + + // Calculate the added_height for items that were added at the top and scroll by that amount + // to maintain the scroll position + let scroll_items_top_step_2 = + if let Some(scroll_top_items) = self.items_inserted_at_start.take() { + let mut measure_ui = ui.child_ui(ui.max_rect(), *ui.layout()); + measure_ui.set_visible(false); + + let start_height = measure_ui.next_widget_position(); + for i in 0..scroll_top_items { + layout(&mut measure_ui, i); + } + let end_height = measure_ui.next_widget_position(); + + let added_height = end_height.y - start_height.y + ui.spacing().item_spacing.y; + + // TODO: Ideally we should be able to use scroll_with_delta here but that doesn't work + // until https://github.com/emilk/egui/issues/2783 is fixed. Before, scroll_to_rect + // only works when the mouse is over the scroll area. + // ui.scroll_with_delta(Vec2::new(0.0, -added_height)); + ui.scroll_to_rect(ui.clip_rect().translate(Vec2::new(0.0, added_height)), None); + + index_offset = scroll_top_items; + + ui.ctx().request_repaint(); + + Some(added_height) + } else { + None + }; + // Find the first row that is visible loop { if row_start_index == 0 { @@ -105,12 +155,15 @@ impl VirtualList { .rows .get(row_start_index) .map(|row| row.range.start) - .unwrap_or(0); + .unwrap_or(0) + + index_offset; let mut current_item_index = item_start_index; let mut iterations = 0; + let mut first_visible_item_index = None; + loop { // Bail out if we're recalculating too many items if iterations > self.max_rows_calculated_per_frame { @@ -121,13 +174,17 @@ impl VirtualList { // let item = self.items.get_mut(current_row); if current_item_index < length { - let pos = ui.next_widget_position() - min.to_vec2(); + let pos = ui.next_widget_position() - min; let count = layout(ui, current_item_index); - let size = ui.next_widget_position() - min.to_vec2() - pos; + let size = ui.next_widget_position() - min - pos; let rect = Rect::from_min_size(pos, size); let range = current_item_index..current_item_index + count; + if first_visible_item_index.is_none() && pos.y >= visible_rect.min.y { + first_visible_item_index = Some(current_item_index); + } + if let Some(row) = self.rows.get_mut(current_row) { row.range = range; row.pos = pos; @@ -172,7 +229,7 @@ impl VirtualList { current_row += 1; } - let item_range = item_start_index..current_item_index; + let item_range = first_visible_item_index.unwrap_or(item_start_index)..current_item_index; if item_range.end < length { ui.set_min_height( @@ -196,6 +253,12 @@ impl VirtualList { self.previous_item_range = item_range.clone(); + if let Some(added_height) = scroll_items_top_step_2 { + // We need to add the height at the bottom or else we might not be able to scroll + ui.add_space(added_height); + self.reset(); + } + VirtualListResponse { item_range, newly_visible_items: visible_range, diff --git a/fancy-example/Cargo.toml b/fancy-example/Cargo.toml index 9a295b3..0722b58 100644 --- a/fancy-example/Cargo.toml +++ b/fancy-example/Cargo.toml @@ -7,6 +7,9 @@ publish = false [dependencies] egui_dnd = { path = "../crates/egui_dnd" } egui_infinite_scroll = { path = "../crates/egui_infinite_scroll" } +hello_egui_utils = { path = "../crates/hello_egui_utils" } +egui_inbox = { path = "../crates/egui_inbox" } +egui_animation = { path = "../crates/egui_animation" } egui = { workspace = true, features = ["color-hex"] } eframe = { workspace = true, default-features = true } @@ -22,5 +25,12 @@ wasm-bindgen-futures = "0.4.33" serde = { version = "1", features = ["derive"] } serde_json = "1" +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +tokio = { version = "1", features = ["time", "rt", "macros"] } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen-futures = "0.4.39" +gloo-timers = { version = "0.3.0", features = ["futures"] } + [package.metadata.release] release = false diff --git a/fancy-example/src/chat.rs b/fancy-example/src/chat.rs new file mode 100644 index 0000000..770e02e --- /dev/null +++ b/fancy-example/src/chat.rs @@ -0,0 +1,337 @@ +use std::iter::repeat; +use std::sync::Arc; +use std::time::Duration; +use std::usize; + +use eframe::emath::Vec2; +use egui::{ + Align, Frame, Label, Layout, Rect, RichText, Rounding, ScrollArea, Shape, Stroke, Ui, Widget, +}; + +use egui_animation::animate_continuous; +use egui_inbox::UiInbox; +use egui_infinite_scroll::InfiniteScroll; + +use crate::demo_area; +use crate::futures::{sleep, spawn}; +use crate::shared_state::SharedState; +use crate::sidebar::Example; + +pub const CHAT_HISTORY: &str = include_str!("chat_history.txt"); + +pub const CHAT_MESSAGES: &str = include_str!("chat.txt"); + +#[derive(Debug)] +struct HistoryLoader { + history: Vec, + messages: Vec<(ChatMessage, Duration)>, +} + +impl HistoryLoader { + pub fn new() -> Self { + let history: Vec<_> = CHAT_HISTORY + .lines() + .filter(|line| !line.is_empty()) + .map(|line| { + let (name, content) = line.split_once(": ").unwrap(); + + ChatMessage { + content: content.to_string(), + from: if name == "me" { + None + } else { + Some(name.to_string()) + }, + } + }) + .rev() + .collect(); + + // Repeat the history 5 times to make it longer. + let history = repeat(history) + .take(5) + .flat_map(|history| history.clone()) + .collect(); + + Self { + history, + + messages: CHAT_MESSAGES + .lines() + .filter(|line| !line.is_empty()) + .map(|line| { + let (name, content) = line.split_once(": ").unwrap(); + + let (name, duration) = name.split_once(", ").unwrap(); + + let duration = Duration::from_secs_f32(duration.parse::().unwrap()); + + ( + ChatMessage { + content: content.to_string(), + from: if name == "me" { + None + } else { + Some(name.to_string()) + }, + }, + duration, + ) + }) + .collect(), + } + } + + pub async fn load(&self, page: Option) -> (Vec, Option) { + let page = page.unwrap_or(0); + sleep(Duration::from_secs_f32(0.7)).await; + let page_size = 10; + let start = page * page_size; + let end = usize::min(start + page_size, self.history.len()); + + let has_more = end < self.history.len(); + + let messages = self.history[start..end].iter().cloned().rev().collect(); + + (messages, if has_more { Some(page + 1) } else { None }) + } +} + +#[derive(Debug, Clone)] +pub struct ChatMessage { + pub content: String, + pub from: Option, +} + +#[derive(Debug)] +pub struct ChatExample { + messages: InfiniteScroll, + inbox: UiInbox, + history_loader: Arc, + shown: bool, + msgs_received: usize, +} + +impl ChatExample { + pub fn new() -> Self { + let history_loader = Arc::new(HistoryLoader::new()); + + let inbox = UiInbox::new(); + + let history_loader_clone = history_loader.clone(); + + ChatExample { + messages: InfiniteScroll::new().start_loader(move |cursor, cb| { + println!("Loading messages..."); + let history_loader = history_loader_clone.clone(); + spawn(async move { + let (messages, cursor) = history_loader.load(cursor).await; + cb(Ok((messages, cursor))); + }); + }), + inbox, + history_loader, + shown: false, + msgs_received: 0, + } + } + + pub fn ui(&mut self, ui: &mut Ui) { + if !self.shown { + self.shown = true; + + let inbox_clone = self.inbox.clone(); + self.history_loader + .messages + .iter() + .for_each(|(message, duration)| { + let inbox_clone = inbox_clone.clone(); + let duration = *duration; + let message = message.clone(); + spawn(async move { + sleep(duration).await; + inbox_clone.send(message); + }); + }); + } + + self.inbox.read(ui).for_each(|message| { + self.messages.items.push(message); + self.msgs_received += 1; + }); + + let title = self.name(); + demo_area(ui, title, 500.0, |ui| { + ScrollArea::vertical() + .max_height(400.0) + .auto_shrink([false, false]) + .stick_to_bottom(true) + .show(ui, |ui| { + ui.set_width(ui.available_width()); + + ui.vertical_centered(|ui| { + ui.set_visible(self.messages.top_loading_state().loading()); + ui.spinner(); + }); + + let max_msg_width = ui.available_width() - 40.0; + let inner_margin = 8.0; + let outer_margin = 8.0; + + self.messages.ui(ui, 10, |ui, _index, item| { + let is_message_from_myself = item.from.is_none(); + + // Messages from the user are right-aligned. + let layout = if is_message_from_myself { + Layout::top_down(Align::Max) + } else { + Layout::top_down(Align::Min) + }; + + ui.with_layout(layout, |ui| { + ui.set_max_width(max_msg_width); + + let mut measure = |text| { + let label = Label::new(text); + // We need to calculate the text width here to enable the typical + // chat bubble layout where the own bubbles are right-aligned and + // the text within is left-aligned. + let (_pos, galley, _response) = label + .layout_in_ui(&mut ui.child_ui(ui.max_rect(), *ui.layout())); + let rect = galley.galley.rect; + // Calculate the width of the frame based on the width of + // the text and add 0.1 to account for floating point errors. + f32::min( + rect.width() + inner_margin * 2.0 + outer_margin * 2.0 + 0.1, + max_msg_width, + ) + }; + + let content = RichText::new(&item.content); + let mut msg_width = measure(content.clone()); + let name = if let Some(from) = &item.from { + let name = RichText::new(from).strong(); + let width = measure(name.clone()); + msg_width = f32::max(msg_width, width); + Some(name) + } else { + None + }; + + // Set the width of the ui to the width of the message. + ui.set_min_width(msg_width); + + let msg_color = if is_message_from_myself { + ui.style().visuals.widgets.inactive.bg_fill + } else { + ui.style().visuals.extreme_bg_color + }; + + let rounding = 8.0; + let margin = 8.0; + let response = Frame::none() + .rounding(Rounding { + ne: if is_message_from_myself { + 0.0 + } else { + rounding + }, + nw: if is_message_from_myself { + rounding + } else { + 0.0 + }, + se: rounding, + sw: rounding, + }) + .inner_margin(margin) + .outer_margin(margin) + .fill(msg_color) + .show(ui, |ui| { + ui.with_layout(Layout::top_down(Align::Min), |ui| { + if let Some(from) = name { + Label::new(from).ui(ui); + } + + ui.label(&item.content); + }); + }) + .response; + + let points = if !is_message_from_myself { + let top = response.rect.left_top() + Vec2::splat(margin); + let arrow_rect = + Rect::from_two_pos(top, top + Vec2::new(-rounding, rounding)); + + vec![ + arrow_rect.left_top(), + arrow_rect.right_top(), + arrow_rect.right_bottom(), + ] + } else { + let top = response.rect.right_top() + Vec2::new(-margin, margin); + let arrow_rect = + Rect::from_two_pos(top, top + Vec2::new(rounding, rounding)); + + vec![ + arrow_rect.left_top(), + arrow_rect.right_top(), + arrow_rect.left_bottom(), + ] + }; + + ui.painter() + .add(Shape::convex_polygon(points, msg_color, Stroke::NONE)) + }); + }); + + if self.msgs_received < self.history_loader.messages.len() + && !self.messages.initial_loading() + { + Frame::none() + .rounding(8.0) + .inner_margin(8.0) + .outer_margin(8.0) + .fill(ui.style().visuals.faint_bg_color) + .show(ui, |ui| { + ui.horizontal_top(|ui| { + let mut dot = |offset| { + let t = animate_continuous( + ui, + egui_animation::easing::sine_in_out, + Duration::from_secs_f32(1.0), + offset, + ); + + let res = ui.allocate_response( + Vec2::splat(4.0), + egui::Sense::hover(), + ); + + ui.painter().circle_filled( + res.rect.center() + Vec2::Y * t * 4.0, + res.rect.width() / 2.0, + ui.style().visuals.text_color(), + ) + }; + + dot(0.0); + dot(0.3); + dot(8.6); + }); + }); + } + }); + }); + } +} + +impl Example for ChatExample { + fn name(&self) -> &'static str { + "Chat" + } + + fn ui(&mut self, ui: &mut Ui, _shared_state: &mut SharedState) { + self.ui(ui) + } +} diff --git a/fancy-example/src/chat.txt b/fancy-example/src/chat.txt new file mode 100644 index 0000000..2a2a08e --- /dev/null +++ b/fancy-example/src/chat.txt @@ -0,0 +1,11 @@ +Lucas, 2: Hi! + +Lucas, 4: Thanks for trying the chat example. + +Lucas, 8: The above history was generated with ChatGPT to add some content (so what you read above is basically glibberish). + +Lucas, 10: This is now real Lucas talking. + +Lucas, 13: If you enjoy my crates, please consider leaving a star on the github repo. + +Lucas, 15: This provides no real value but tingles my dopamine receptors. \ No newline at end of file diff --git a/fancy-example/src/chat_history.txt b/fancy-example/src/chat_history.txt new file mode 100644 index 0000000..c693874 --- /dev/null +++ b/fancy-example/src/chat_history.txt @@ -0,0 +1,60 @@ +LucasGPT: Hi there! How are you? + +me: Hey Lucas! +me: I just tried egui_dnd and I'm amazed at how well it works. + +LucasGPT: That's awesome! I've been exploring egui_infinite_scroll. It's a game-changer for handling large datasets in my apps. + +me: Oh, I haven't tried that yet. How's your experience been with it? + +LucasGPT: It's fantastic! Scrolling through extensive lists feels seamless. By the way, have you worked with egui_custom_widgets? + +me: Not yet, but I've heard it allows for some really cool customizations. What kind of widgets have you implemented? + +LucasGPT: I created a custom color picker that integrates perfectly with the egui style. It's slick and user-friendly. + +me: Nice! Customization is key. I've been grappling with some layout challenges. Any tips on handling complex layouts in egui? + +LucasGPT: Absolutely! I found that using egui_grid helps maintain a clean layout, especially when dealing with multiple components. How's your experience with layout? + +me: I'll give egui_grid a shot. Layouts have been a bit tricky, but I recently discovered egui_window, and it made managing multiple windows much more manageable. + +LucasGPT: Great find! Speaking of discoveries, have you checked out egui_animation for creating smooth transitions in your UI? + +me: No, not yet. Animations could add a nice touch to my apps. I'll definitely look into egui_animation. Thanks for the tip! + +LucasGPT: No problem! By the way, have you faced any performance issues with egui in your projects? + +me: Surprisingly, no. The rendering speed is impressive, even with complex UIs. How about you? + +LucasGPT: Agreed! Performance has been solid for me too. Have you integrated egui with any rust backend frameworks? + +me: Yes, I integrated it with Actix for a web app. The combination of egui and Actix was surprisingly smooth. + +LucasGPT: That sounds interesting! I've been considering Rocket for my backend. Any thoughts on that combo? + +me: Rocket should pair well with egui. The key is to ensure smooth communication between the frontend and backend. How's your experience with Rocket? + +LucasGPT: Rocket has been solid, and integrating with egui seems straightforward. Have you explored any other rust GUI frameworks? + +me: I briefly looked into druid, but I found egui's simplicity and performance more appealing for my projects. What about you? + +LucasGPT: Same here. Egui's minimalism is a big plus. By the way, have you encountered any challenges with cross-platform compatibility? + +me: Fortunately, no major issues so far. Egui's cross-platform support has been reliable for my projects. How's it been for you? + +LucasGPT: Smooth sailing on my end too. I love the fact that it works seamlessly on different platforms. Have you tried deploying egui apps to mobile? + +me: Not yet. Mobile deployment is on my to-do list. Have you had any success with egui on mobile platforms? + +LucasGPT: I haven't tried it extensively, but I've seen some success stories. It seems promising for mobile development. Let me know how it goes for you! + +me: Will do! By the way, have you contributed to the egui community or come across any interesting community projects? + +LucasGPT: I haven't contributed yet, but I've seen some impressive community projects, like custom themes and plugins. Planning to contribute? + +me: Definitely considering it. The community seems vibrant and supportive. Let me know if you decide to contribute too! + +LucasGPT: Absolutely! It's been great chatting with you about egui and rust. Let's stay in touch and share our progress. + +me: Agreed! Feel free to reach out if you have any more insights or run into challenges. Happy coding! \ No newline at end of file diff --git a/fancy-example/src/color_sort.rs b/fancy-example/src/color_sort.rs new file mode 100644 index 0000000..6591a0a --- /dev/null +++ b/fancy-example/src/color_sort.rs @@ -0,0 +1,155 @@ +use crate::demo_area; +use crate::shared_state::SharedState; +use crate::sidebar::Example; +use eframe::emath::Vec2; +use eframe::epaint::{Color32, Hsva, Rounding}; +use egui::{Id, Sense, Ui}; +use egui_dnd::{dnd, DragDropItem}; +use std::hash::{Hash, Hasher}; + +#[derive(Clone)] +pub struct Color { + pub color: Color32, + pub name: &'static str, + pub rounded: bool, + pub index: usize, +} + +impl Hash for Color { + fn hash(&self, state: &mut H) { + self.index.hash(state) + } +} + +pub enum ColorSortKind { + // Vertical colors are in shared state so we can use it as a global background color + Vertical, + Wrapped { colors: Vec }, +} + +pub struct ColorSort { + kind: ColorSortKind, +} + +impl ColorSort { + pub fn wrapped() -> Self { + Self { + kind: ColorSortKind::Wrapped { + colors: many_colors(), + }, + } + } + + pub fn vertical() -> Self { + Self { + kind: ColorSortKind::Vertical, + } + } + + fn dnd_ui(items: &mut [Color], ui: &mut Ui, many: bool) { + let item_size = if many { + Vec2::splat(32.0) + } else { + Vec2::new(ui.available_width(), 32.0) + }; + + let response = dnd(ui, "fancy_dnd").show_custom(|ui, iter| { + items.iter_mut().enumerate().for_each(|(index, item)| { + iter.next(ui, Id::new(item.index), index, true, |ui, item_handle| { + item_handle.ui_sized(ui, item_size, |ui, handle, state| { + ui.horizontal(|ui| { + handle.ui_sized(ui, item_size, |ui| { + let size_factor = ui.ctx().animate_value_with_time( + item.id().with("handle_anim"), + if state.dragged { 1.1 } else { 1.0 }, + 0.2, + ); + let size = 32.0; + + let (_id, response) = + ui.allocate_exact_size(Vec2::splat(size), Sense::click()); + + if response.clicked() { + item.rounded = !item.rounded; + } + let rect = response.rect; + + let x = ui.ctx().animate_bool(item.id(), item.rounded); + let rounding = x * 16.0 + 1.0; + + ui.painter().rect_filled( + rect.shrink(x * 4.0 * size_factor) + .shrink(rect.width() * (1.0 - size_factor)), + Rounding::same(rounding), + item.color, + ); + + if !many { + ui.heading(item.name); + } + }); + }); + }) + }) + }); + }); + + response.update_vec(items); + } +} + +impl Example for ColorSort { + fn name(&self) -> &'static str { + match self.kind { + ColorSortKind::Vertical => "Color Sort", + ColorSortKind::Wrapped { .. } => "Color Sort (wrapped)", + } + } + + fn ui(&mut self, ui: &mut Ui, shared_state: &mut SharedState) { + demo_area(ui, self.name(), 286.0, |ui| { + ui.spacing_mut().item_spacing.x = ui.spacing().item_spacing.y; + match &mut self.kind { + ColorSortKind::Vertical => { + Self::dnd_ui(&mut shared_state.background_colors, ui, false); + ui.add_space(5.0); + ui.small("* it's actually yellow"); + } + ColorSortKind::Wrapped { colors } => { + ui.horizontal_wrapped(|ui| { + Self::dnd_ui(colors, ui, true); + }); + ui.small(""); + } + } + + ui.separator(); + + ui.label("This is a demo for egui_dnd, a drag and drop sorting library for egui."); + + ui.hyperlink_to( + "View on GitHub", + "https://github.com/lucasmerlin/hello_egui/tree/main/crates/egui_dnd", + ); + ui.hyperlink_to("View on Crates.io", "https://crates.io/crates/egui_dnd"); + ui.hyperlink_to("View on docs.rs", "https://docs.rs/egui_dnd"); + }); + } +} + +fn many_colors() -> Vec { + let colors = 21; + + (0..colors) + .map(|i| { + let hue = i as f32 / colors as f32; + let color = Color32::from(Hsva::new(hue, 0.8, 0.8, 1.0)); + Color { + name: "Rainbow Color", + color, + rounded: false, + index: i, + } + }) + .collect() +} diff --git a/fancy-example/src/futures.rs b/fancy-example/src/futures.rs new file mode 100644 index 0000000..18252e3 --- /dev/null +++ b/fancy-example/src/futures.rs @@ -0,0 +1,24 @@ +use std::future::Future; +use std::time::Duration; + +//pub use maybe_sync::{BoxFuture, MaybeSend, MaybeSync}; + +#[cfg(not(target_arch = "wasm32"))] +pub fn spawn(f: impl Future + Send + 'static) { + tokio::spawn(f); +} + +#[cfg(target_arch = "wasm32")] +pub fn spawn(f: impl Future + 'static) { + wasm_bindgen_futures::spawn_local(f); +} + +#[cfg(not(target_arch = "wasm32"))] +pub fn sleep(dur: Duration) -> impl Future { + tokio::time::sleep(dur) +} + +#[cfg(target_arch = "wasm32")] +pub fn sleep(dur: Duration) -> impl Future { + gloo_timers::future::TimeoutFuture::new(dur.as_millis() as u32) +} diff --git a/fancy-example/src/main.rs b/fancy-example/src/main.rs index 2ea6998..11e6fe4 100644 --- a/fancy-example/src/main.rs +++ b/fancy-example/src/main.rs @@ -1,228 +1,161 @@ -use std::hash::{Hash, Hasher}; +use std::hash::Hash; -use eframe::egui; use eframe::egui::Color32; use eframe::emath::lerp; -use egui::ecolor::Hsva; -use egui::{Align2, Area, Context, Id, Rounding, Sense, Ui, Vec2}; +use eframe::{egui, Frame}; +use egui::{Align2, Area, Context, Id, SidePanel, Ui, Vec2}; -use egui_dnd::{dnd, DragDropItem}; +use color_sort::ColorSort; +use shared_state::SharedState; +use sidebar::{Category, SideBar}; +use crate::chat::ChatExample; use crate::stargazers::Stargazers; +mod chat; +mod color_sort; +mod futures; +mod shared_state; +mod sidebar; mod stargazers; -#[derive(Clone)] -struct Color { - color: Color32, - name: &'static str, - rounded: bool, - index: usize, +pub struct App { + sidebar: SideBar, + sidebar_expanded: bool, + shared_state: SharedState, } -impl Hash for Color { - fn hash(&self, state: &mut H) { - self.index.hash(state) +impl Default for App { + fn default() -> Self { + Self::new() } } -fn dnd_ui(items: &mut [Color], ui: &mut Ui, many: bool) { - let item_size = if many { - Vec2::splat(32.0) - } else { - Vec2::new(ui.available_width(), 32.0) - }; - - let response = dnd(ui, "fancy_dnd").show_custom(|ui, iter| { - items.iter_mut().enumerate().for_each(|(index, item)| { - iter.next(ui, Id::new(item.index), index, true, |ui, item_handle| { - item_handle.ui_sized(ui, item_size, |ui, handle, state| { - ui.horizontal(|ui| { - handle.ui_sized(ui, item_size, |ui| { - let size_factor = ui.ctx().animate_value_with_time( - item.id().with("handle_anim"), - if state.dragged { 1.1 } else { 1.0 }, - 0.2, - ); - let size = 32.0; - - let (_id, response) = - ui.allocate_exact_size(Vec2::splat(size), Sense::click()); - - if response.clicked() { - item.rounded = !item.rounded; - } - let rect = response.rect; - - let x = ui.ctx().animate_bool(item.id(), item.rounded); - let rounding = x * 16.0 + 1.0; - - ui.painter().rect_filled( - rect.shrink(x * 4.0 * size_factor) - .shrink(rect.width() * (1.0 - size_factor)), - Rounding::same(rounding), - item.color, - ); - - if !many { - ui.heading(item.name); - } - }); - }); - }) - }) - }); - }); - - response.update_vec(items); - - if let Some(reason) = response.cancellation_reason() { - println!("Drag has been cancelled because of {:?}", reason); +impl App { + pub fn new() -> Self { + Self { + sidebar: SideBar::new(vec![ + Category { + name: "Drag and Drop".to_string(), + examples: vec![ + Box::new(ColorSort::vertical()), + Box::new(ColorSort::wrapped()), + Box::new(Stargazers::new()), + ], + }, + Category { + name: "Infinite Scroll".to_string(), + examples: vec![Box::new(ChatExample::new())], + }, + ]), + shared_state: SharedState::new(), + sidebar_expanded: false, + } } } -fn colors() -> Vec { - vec![ - Color { - name: "Panic Purple", - color: egui::hex_color!("642CA9"), - rounded: false, - index: 0, - }, - Color { - name: "Generic Green", - color: egui::hex_color!("2A9D8F"), - rounded: false, - index: 1, - }, - Color { - name: "Ownership Orange*", - color: egui::hex_color!("E9C46A"), - rounded: false, - index: 2, - }, - ] -} - -fn many_colors() -> Vec { - let colors = 21; - - (0..colors) - .map(|i| { - let hue = i as f32 / colors as f32; - let color = Color32::from(Hsva::new(hue, 0.8, 0.8, 1.0)); - Color { - name: "Generic Green", - color, - rounded: false, - index: i, - } - }) - .collect() -} +impl eframe::App for App { + fn update(&mut self, ctx: &Context, _frame: &mut Frame) { + let width = ctx.screen_rect().width(); + let collapsible_sidebar = width < 800.0; + let is_expanded = !collapsible_sidebar || self.sidebar_expanded; + + SidePanel::left("sidebar") + .resizable(false) + .exact_width(110.0) + .show_animated(ctx, is_expanded, |ui| { + if self.sidebar.ui(ui) { + self.sidebar_expanded = false; + } + }); -fn app(ctx: &Context, demo: &mut Demo, items: &mut Vec, stargazers: &mut Stargazers) { - egui::CentralPanel::default().frame(egui::Frame::none() - .fill(ctx.style().visuals.panel_fill.gamma_multiply(0.7)) - ).show(ctx, |ui| { - if items.len() == 3 { - vertex_gradient( - ui, - &Gradient( - items - .iter() - .map(|c| c.color) - .collect(), - ), - ); - } + let example = self.sidebar.active_example_mut(); - Area::new("content") - .anchor(Align2::CENTER_CENTER, Vec2::ZERO) + egui::CentralPanel::default() + .frame(egui::Frame::none().fill(ctx.style().visuals.panel_fill.gamma_multiply(0.7))) .show(ctx, |ui| { - ui.set_width(300.0); - - egui::Frame::none() - .fill(ui.style().visuals.panel_fill) - .rounding(4.0) - .inner_margin(20.0) - .show(ui, |ui| { - if demo == &Demo::Stargazers { - ui.heading("Stargazer Sort"); - } else { - ui.heading("Color Sort"); - } - - - ui.horizontal(|ui| { - ui.selectable_value(demo, Demo::Vertical, "Vertical"); - ui.selectable_value(demo, Demo::Horizontal, "Horizontal"); - ui.selectable_value(demo, Demo::Stargazers, "Stargazers"); - }); - - if demo == &Demo::Vertical && items.len() > 3 { - *items = colors(); - } - if demo == &Demo::Horizontal && items.len() == 3 { - *items = many_colors(); - } - - ui.add_space(5.0); - - if demo == &Demo::Stargazers { - stargazers.stargazers_ui(ui); - } else { - let many = items.len() > 3; - - ui.spacing_mut().item_spacing.x = ui.spacing().item_spacing.y; - if many { - ui.horizontal_wrapped(|ui| { - dnd_ui(items, ui, many); - }); - } else { - dnd_ui(items, ui, many); - } - - ui.add_space(5.0); - if !many { - ui.small("* it's actually yellow"); - } else { - ui.small(" "); - } + vertex_gradient( + ui, + &Gradient( + self.shared_state + .background_colors + .iter() + .map(|c| c.color) + .collect(), + ), + ); + + if collapsible_sidebar { + ui.add_space(16.0); + ui.horizontal(|ui| { + ui.add_space(16.0); + if ui.add(egui::Button::new("☰")).clicked() { + self.sidebar_expanded = !self.sidebar_expanded; } - - ui.separator(); - - ui.label("This is a demo for egui_dnd, a drag and drop sorting library for egui."); - - ui.hyperlink_to("View on GitHub", "https://github.com/lucasmerlin/hello_egui/tree/main/crates/egui_dnd"); - ui.hyperlink_to("View on Crates.io", "https://crates.io/crates/egui_dnd"); - ui.hyperlink_to("View on docs.rs", "https://docs.rs/egui_dnd"); }); + } + + if !(collapsible_sidebar && is_expanded) { + example.ui(ui, &mut self.shared_state); + } }); - }); + } +} + +pub fn demo_area(ui: &mut Ui, title: &str, width: f32, content: impl FnOnce(&mut Ui)) { + Area::new(Id::new(title)) + .anchor(Align2::CENTER_CENTER, Vec2::ZERO) + .show(ui.ctx(), |ui| { + let width = f32::min(ui.available_width() - 20.0, width); + ui.set_width(width); + + egui::Frame::none() + .fill(ui.style().visuals.panel_fill) + .rounding(4.0) + .inner_margin(20.0) + .show(ui, |ui| { + ui.heading(title); + ui.add_space(5.0); + + content(ui); + }); + }); } #[cfg(not(target_arch = "wasm32"))] fn main() -> eframe::Result<()> { - let mut items = colors(); - let mut stargazers = Stargazers::new(); - let mut demo = Demo::Vertical; + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .expect("Unable to create Runtime"); + + // Enter the runtime so that `tokio::spawn` is available immediately. + let _enter = rt.enter(); + + // Execute the runtime in its own thread. + // The future doesn't have to do anything. In this example, it just sleeps forever. + std::thread::spawn(move || { + rt.block_on(async { + loop { + tokio::time::sleep(std::time::Duration::from_secs(3600)).await; + } + }) + }); - eframe::run_simple_native("Dnd Example App", Default::default(), move |ctx, _frame| { - egui_extras::install_image_loaders(ctx); - app(ctx, &mut demo, &mut items, &mut stargazers); - }) + eframe::run_native( + "Dnd Example App", + Default::default(), + Box::new(move |ctx| { + egui_extras::install_image_loaders(&ctx.egui_ctx); + Box::new(App::new()) as Box + }), + ) } // when compiling to web using trunk. #[cfg(target_arch = "wasm32")] fn main() { let web_options = eframe::WebOptions::default(); - let items = colors(); - let stargazers = Stargazers::new(); - let demo = Demo::Vertical; - wasm_bindgen_futures::spawn_local(async { eframe::WebRunner::new() .start( @@ -230,32 +163,17 @@ fn main() { web_options, Box::new(|a| { egui_extras::install_image_loaders(&a.egui_ctx); - Box::new(App(items, stargazers, demo)) + Box::new(App::new()) as Box }), ) .await .expect("failed to start eframe"); }); - - struct App(Vec, Stargazers, Demo); - - impl eframe::App for App { - fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) { - app(ctx, &mut self.2, &mut self.0, &mut self.1); - } - } } #[derive(Clone, Hash, PartialEq, Eq)] struct Gradient(pub Vec); -#[derive(Clone, Hash, PartialEq, Eq)] -enum Demo { - Horizontal, - Vertical, - Stargazers, -} - // taken from the egui demo fn vertex_gradient(ui: &mut Ui, gradient: &Gradient) { use egui::epaint::*; diff --git a/fancy-example/src/shared_state.rs b/fancy-example/src/shared_state.rs new file mode 100644 index 0000000..709f91a --- /dev/null +++ b/fancy-example/src/shared_state.rs @@ -0,0 +1,36 @@ +use crate::color_sort::Color; + +pub struct SharedState { + pub background_colors: Vec, +} + +impl SharedState { + pub fn new() -> Self { + Self { + background_colors: colors(), + } + } +} + +fn colors() -> Vec { + vec![ + Color { + name: "Panic Purple", + color: egui::hex_color!("642CA9"), + rounded: false, + index: 0, + }, + Color { + name: "Generic Green", + color: egui::hex_color!("2A9D8F"), + rounded: false, + index: 1, + }, + Color { + name: "Ownership Orange*", + color: egui::hex_color!("E9C46A"), + rounded: false, + index: 2, + }, + ] +} diff --git a/fancy-example/src/sidebar.rs b/fancy-example/src/sidebar.rs new file mode 100644 index 0000000..7d55e82 --- /dev/null +++ b/fancy-example/src/sidebar.rs @@ -0,0 +1,63 @@ +use crate::shared_state::SharedState; +use egui::{Align, Layout, Ui}; + +pub trait Example { + fn name(&self) -> &'static str; + + fn ui(&mut self, ui: &mut Ui, shared_state: &mut SharedState); +} + +pub struct Category { + pub name: String, + pub examples: Vec>, +} + +pub struct SideBar { + categories: Vec, + active_category: usize, + active_example: usize, +} + +impl SideBar { + pub fn new(categories: Vec) -> Self { + Self { + categories, + active_category: 0, + active_example: 0, + } + } + + pub fn ui(&mut self, ui: &mut Ui) -> bool { + let mut clicked = false; + ui.with_layout(Layout::top_down_justified(Align::Min), |ui| { + ui.add_space(4.0); + ui.heading("hello_egui"); + ui.add_space(4.0); + + for (category_idx, category) in &mut self.categories.iter_mut().enumerate() { + ui.small(&category.name); + for (example_idx, example) in category.examples.iter_mut().enumerate() { + if ui.button(example.name()).clicked() { + self.active_category = category_idx; + self.active_example = example_idx; + clicked = true; + } + } + } + }); + + ui.with_layout(Layout::bottom_up(Align::Center), |ui| { + ui.add_space(8.0); + ui.hyperlink_to( + "GitHub: hello_egui", + "https://github.com/lucasmerlin/hello_egui", + ); + }); + + clicked + } + + pub fn active_example_mut(&mut self) -> &mut dyn Example { + &mut *self.categories[self.active_category].examples[self.active_example] + } +} diff --git a/fancy-example/src/stargazers.rs b/fancy-example/src/stargazers.rs index 0180e5f..563f032 100644 --- a/fancy-example/src/stargazers.rs +++ b/fancy-example/src/stargazers.rs @@ -5,6 +5,8 @@ use egui::{Frame, Id, Image, ScrollArea, Ui, Vec2}; use ehttp::Request; use serde::Deserialize; +use crate::demo_area; +use crate::sidebar::Example; use egui_dnd::{dnd, DragDropConfig}; use egui_infinite_scroll::InfiniteScroll; @@ -25,6 +27,16 @@ pub struct Stargazers { infinite_scroll: InfiniteScroll, } +impl Example for Stargazers { + fn name(&self) -> &'static str { + "Stargazers" + } + + fn ui(&mut self, ui: &mut Ui, _shared_state: &mut crate::shared_state::SharedState) { + self.stargazers_ui(ui); + } +} + impl Stargazers { pub fn new() -> Self { Self { @@ -48,25 +60,37 @@ impl Stargazers { } pub fn stargazers_ui(&mut self, ui: &mut Ui) { - ScrollArea::vertical() - .max_height(250.0) - .auto_shrink([false, false]) - .show(ui, |ui| { - ui.horizontal_wrapped(|ui| { - ui.spacing_mut().item_spacing.x = 0.0; - ui.label("Like"); - ui.hyperlink_to( - " egui_dnd on GitHub ", - "https://github.com/lucasmerlin/hello_egui/tree/main/crates/egui_dnd", - ); - ui.label("to be listed here!"); - }); - ui.horizontal_wrapped(|ui| { - ui.label("On mobile you can drag to scroll and hold + drag to sort items."); + demo_area(ui, self.name(), 300.0, |ui| { + ScrollArea::vertical() + .max_height(250.0) + .auto_shrink([false, false]) + .show(ui, |ui| { + ui.horizontal_wrapped(|ui| { + ui.spacing_mut().item_spacing.x = 0.0; + ui.label("Like"); + ui.hyperlink_to( + " egui_dnd on GitHub ", + "https://github.com/lucasmerlin/hello_egui/tree/main/crates/egui_dnd", + ); + ui.label("to be listed here!"); + }); + ui.horizontal_wrapped(|ui| { + ui.label("On mobile you can drag to scroll and hold + drag to sort items."); + }); + self.stargazers_dnd_ui(ui); }); - self.stargazers_dnd_ui(ui); - }); + ui.separator(); + + ui.label("This is a demo for egui_dnd, a drag and drop sorting library for egui."); + + ui.hyperlink_to( + "View on GitHub", + "https://github.com/lucasmerlin/hello_egui/tree/main/crates/egui_dnd", + ); + ui.hyperlink_to("View on Crates.io", "https://crates.io/crates/egui_dnd"); + ui.hyperlink_to("View on docs.rs", "https://docs.rs/egui_dnd"); + }); } pub fn stargazers_dnd_ui(&mut self, ui: &mut Ui) {