diff --git a/Cargo.lock b/Cargo.lock index 8a2aee3..55ea40e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,6 +126,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + [[package]] name = "allocator-api2" version = "0.2.18" @@ -210,6 +216,18 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + [[package]] name = "arboard" version = "3.4.0" @@ -225,6 +243,17 @@ dependencies = [ "x11rb", ] +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -427,29 +456,6 @@ dependencies = [ "syn 2.0.66", ] -[[package]] -name = "atk" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4af014b17dd80e8af9fa689b2d4a211ddba6eb583c1622f35d0cb543f6b17e4" -dependencies = [ - "atk-sys", - "glib", - "libc", -] - -[[package]] -name = "atk-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "251e0b7d90e33e0ba930891a505a9a35ece37b2dd37a14f3ffc306c13b980009" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -510,6 +516,29 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + [[package]] name = "axum" version = "0.7.5" @@ -627,6 +656,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -638,9 +673,12 @@ name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" -dependencies = [ - "serde", -] + +[[package]] +name = "bitstream-io" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c12d1856e42f0d817a835fe55853957c85c8c8a470114029143d3f12671446e" [[package]] name = "block" @@ -727,6 +765,12 @@ dependencies = [ "piper", ] +[[package]] +name = "built" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6a6c0b39c38fd754ac338b00a88066436389c0f029da5d37d1e01091d9b7c17" + [[package]] name = "bumpalo" version = "3.13.0" @@ -759,37 +803,18 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" -[[package]] -name = "cairo-rs" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" -dependencies = [ - "bitflags 2.5.0", - "cairo-sys-rs", - "glib", - "libc", - "once_cell", - "thiserror", -] - -[[package]] -name = "cairo-sys-rs" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - [[package]] name = "calloop" version = "0.12.4" @@ -1107,10 +1132,20 @@ dependencies = [ ] [[package]] -name = "crossbeam-channel" -version = "0.5.13" +name = "crossbeam-deque" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ "crossbeam-utils", ] @@ -1121,6 +1156,12 @@ version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -1164,27 +1205,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - [[package]] name = "dispatch" version = "0.2.0" @@ -1252,7 +1272,7 @@ dependencies = [ "glow", "glutin", "glutin-winit", - "image", + "image 0.24.9", "js-sys", "log", "objc", @@ -1334,6 +1354,12 @@ dependencies = [ "winit 0.29.15", ] +[[package]] +name = "either" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" + [[package]] name = "emath" version = "0.27.2" @@ -1480,6 +1506,22 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "exr" +version = "1.72.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -1504,16 +1546,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "field-offset" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" -dependencies = [ - "memoffset 0.9.1", - "rustc_version", -] - [[package]] name = "flate2" version = "1.0.30" @@ -1524,6 +1556,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1581,17 +1622,6 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" -[[package]] -name = "futures-executor" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - [[package]] name = "futures-io" version = "0.3.30" @@ -1626,17 +1656,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "futures-macro" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "futures-sink" version = "0.3.30" @@ -1657,7 +1676,6 @@ checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", "futures-io", - "futures-macro", "futures-sink", "futures-task", "memchr", @@ -1666,64 +1684,6 @@ dependencies = [ "slab", ] -[[package]] -name = "gdk" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5ba081bdef3b75ebcdbfc953699ed2d7417d6bd853347a42a37d76406a33646" -dependencies = [ - "cairo-rs", - "gdk-pixbuf", - "gdk-sys", - "gio", - "glib", - "libc", - "pango", -] - -[[package]] -name = "gdk-pixbuf" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" -dependencies = [ - "gdk-pixbuf-sys", - "gio", - "glib", - "libc", - "once_cell", -] - -[[package]] -name = "gdk-pixbuf-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" -dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "gdk-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31ff856cb3386dae1703a920f803abafcc580e9b5f711ca62ed1620c25b51ff2" -dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "pkg-config", - "system-deps", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1755,44 +1715,22 @@ dependencies = [ "wasi", ] +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" -[[package]] -name = "gio" -version = "0.18.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-util", - "gio-sys", - "glib", - "libc", - "once_cell", - "pin-project-lite", - "smallvec", - "thiserror", -] - -[[package]] -name = "gio-sys" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", - "winapi", -] - [[package]] name = "gl_generator" version = "0.14.0" @@ -1804,53 +1742,6 @@ dependencies = [ "xml-rs", ] -[[package]] -name = "glib" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" -dependencies = [ - "bitflags 2.5.0", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", - "libc", - "memchr", - "once_cell", - "smallvec", - "thiserror", -] - -[[package]] -name = "glib-macros" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" -dependencies = [ - "heck 0.4.1", - "proc-macro-crate 2.0.2", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.66", -] - -[[package]] -name = "glib-sys" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" -dependencies = [ - "libc", - "system-deps", -] - [[package]] name = "glob" version = "0.3.1" @@ -1934,17 +1825,6 @@ dependencies = [ "gl_generator", ] -[[package]] -name = "gobject-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" -dependencies = [ - "glib-sys", - "libc", - "system-deps", -] - [[package]] name = "gpu-alloc" version = "0.6.0" @@ -1998,55 +1878,13 @@ dependencies = [ ] [[package]] -name = "gtk" -version = "0.18.1" +name = "half" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93c4f5e0e20b60e10631a5f06da7fe3dda744b05ad0ea71fee2f47adf865890c" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" dependencies = [ - "atk", - "cairo-rs", - "field-offset", - "futures-channel", - "gdk", - "gdk-pixbuf", - "gio", - "glib", - "gtk-sys", - "gtk3-macros", - "libc", - "pango", - "pkg-config", -] - -[[package]] -name = "gtk-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771437bf1de2c1c0b496c11505bdf748e26066bbe942dfc8f614c9460f6d7722" -dependencies = [ - "atk-sys", - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "system-deps", -] - -[[package]] -name = "gtk3-macros" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6063efb63db582968fb7df72e1ae68aa6360dcfb0a75143f34fc7d616bad75e" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.66", + "cfg-if", + "crunchy", ] [[package]] @@ -2074,12 +1912,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -2243,6 +2075,45 @@ dependencies = [ "png", ] +[[package]] +name = "image" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d" +dependencies = [ + "byteorder-lite", + "thiserror", +] + +[[package]] +name = "imgref" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" + [[package]] name = "indexmap" version = "2.0.0" @@ -2262,6 +2133,17 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -2273,6 +2155,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -2310,6 +2201,12 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.69" @@ -2319,17 +2216,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "keyboard-types" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" -dependencies = [ - "bitflags 2.5.0", - "serde", - "unicode-segmentation", -] - [[package]] name = "khronos-egl" version = "6.0.0" @@ -2359,6 +2245,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "lewton" version = "0.10.2" @@ -2370,36 +2262,23 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "libappindicator" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" -dependencies = [ - "glib", - "gtk", - "gtk-sys", - "libappindicator-sys", - "log", -] - -[[package]] -name = "libappindicator-sys" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" -dependencies = [ - "gtk-sys", - "libloading 0.7.4", - "once_cell", -] - [[package]] name = "libc" version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2431,35 +2310,6 @@ dependencies = [ "redox_syscall 0.4.1", ] -[[package]] -name = "libredox" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" -dependencies = [ - "bitflags 2.5.0", - "libc", -] - -[[package]] -name = "libxdo" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00333b8756a3d28e78def82067a377de7fa61b24909000aeaa2b446a948d14db" -dependencies = [ - "libxdo-sys", -] - -[[package]] -name = "libxdo-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db23b9e7e2b7831bbd8aac0bbeeeb7b68cbebc162b227e7052e8e55829a09212" -dependencies = [ - "libc", - "x11", -] - [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -2494,6 +2344,15 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "mach" version = "0.3.2" @@ -2527,6 +2386,16 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "memchr" version = "2.7.2" @@ -2663,25 +2532,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "muda" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b959f97c97044e4c96e32e1db292a7d594449546a3c6b77ae613dc3a5b5145" -dependencies = [ - "cocoa", - "crossbeam-channel", - "dpi", - "gtk", - "keyboard-types", - "libxdo", - "objc", - "once_cell", - "png", - "thiserror", - "windows-sys 0.52.0", -] - [[package]] name = "naga" version = "0.19.2" @@ -2757,6 +2607,12 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + [[package]] name = "nix" version = "0.26.4" @@ -2785,6 +2641,22 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-derive" version = "0.4.2" @@ -2797,10 +2669,30 @@ dependencies = [ ] [[package]] -name = "num-traits" -version = "0.2.15" +name = "num-integer" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -3064,19 +2956,13 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - [[package]] name = "orbclient" version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" dependencies = [ - "libredox 0.0.2", + "libredox", ] [[package]] @@ -3104,31 +2990,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c10569378a1dacd9f30dbe7ae49e054d2c45dc2f8ee49899903e09c3924e8b6f" -[[package]] -name = "pango" -version = "0.18.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" -dependencies = [ - "gio", - "glib", - "libc", - "once_cell", - "pango-sys", -] - -[[package]] -name = "pango-sys" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - [[package]] name = "parking" version = "2.2.0" @@ -3301,30 +3162,6 @@ dependencies = [ "toml_edit 0.20.2", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.85" @@ -3339,6 +3176,34 @@ name = "profiling" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" +dependencies = [ + "quote", + "syn 2.0.66", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" @@ -3388,6 +3253,56 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand", + "rand_chacha", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc13288f5ab39e6d7c9d501759712e6969fcc9734220846fc9ed26cae2cc4234" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -3400,6 +3315,26 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -3418,17 +3353,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_users" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" -dependencies = [ - "getrandom", - "libredox 0.1.3", - "thiserror", -] - [[package]] name = "regex" version = "1.9.1" @@ -3464,6 +3388,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "rgb" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +dependencies = [ + "bytemuck", +] + [[package]] name = "rodio" version = "0.18.1" @@ -3702,6 +3635,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "slab" version = "0.4.9" @@ -3803,6 +3745,7 @@ dependencies = [ "eframe", "embed-resource", "enigo", + "image 0.25.1", "log", "minijinja", "minimp3", @@ -3812,15 +3755,22 @@ dependencies = [ "regex", "rodio", "serde", - "strinto", "tokio", - "tray-icon", "tray-item", "windows 0.57.0", "winit 0.30.0", "xxhash-rust", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + [[package]] name = "spirv" version = "0.3.0+sdk-1.3.268.0" @@ -3842,14 +3792,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" -[[package]] -name = "strinto" -version = "0.1.0" -dependencies = [ - "quote", - "syn 2.0.66", -] - [[package]] name = "symphonia" version = "0.5.3" @@ -3941,7 +3883,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" dependencies = [ "cfg-expr", - "heck 0.5.0", + "heck", "pkg-config", "toml", "version-compare", @@ -3994,6 +3936,17 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "tiny-skia" version = "0.11.4" @@ -4170,25 +4123,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "tray-icon" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ad8319cca93189ea9ab1b290de0595960529750b6b8b501a399ed1ec3775d60" -dependencies = [ - "cocoa", - "core-graphics", - "crossbeam-channel", - "dirs", - "libappindicator", - "muda", - "objc", - "once_cell", - "png", - "thiserror", - "windows-sys 0.52.0", -] - [[package]] name = "tray-item" version = "0.10.0" @@ -4287,6 +4221,17 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + [[package]] name = "version-compare" version = "0.2.0" @@ -4563,6 +4508,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "wgpu" version = "0.19.4" @@ -5194,16 +5145,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "x11" -version = "2.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" -dependencies = [ - "libc", - "pkg-config", -] - [[package]] name = "x11-dl" version = "2.21.0" @@ -5380,6 +5321,30 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" +dependencies = [ + "zune-core", +] + [[package]] name = "zvariant" version = "3.15.2" diff --git a/Cargo.toml b/Cargo.toml index 910746e..6346f59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,18 +21,16 @@ rodio = "0.18.1" serde = { version = "1.0.171", features = ["derive"] } tokio = { version = "1.29.1", features = ["full"] } xxhash-rust = { version = "0.8.6", features = ["xxh3", "const_xxh3"] } -strinto = { path = "./strinto" } eframe = "0.27.2" tray-item = "0.10" -winit = "0.30" once_cell = "1.19.0" -tray-icon = "0.14.3" raw-window-handle = "0.6.2" +image = "0.25.1" -[build-dependencies] -embed-resource = "2.3" +[target.'cfg(windows)'.dependencies] +winit = "0.30" -[dependencies.windows] +[target.'cfg(windows)'.dependencies.windows] version = "0.57.0" features = [ "Data_Xml_Dom", @@ -40,4 +38,18 @@ features = [ "Win32_Security", "Win32_System_Threading", "Win32_UI_WindowsAndMessaging", + + "Win32_System_LibraryLoader", + "Win32_Graphics_Gdi", + "Win32_UI_Input_KeyboardAndMouse", + + "Win32_UI_Controls", + "Win32_Graphics_Dwm", + "Win32_UI_Shell", ] + +#[target.'cfg(windows)'.dependencies.windows-sys] +#version = "0.52.0" + +[target.'cfg(windows)'.build-dependencies] +embed-resource = "2.3" diff --git a/build.rs b/build.rs index b7ea7d5..79a065a 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,8 @@ +#[cfg(windows)] extern crate embed_resource; fn main() { - embed_resource::compile("soundboard.rc", embed_resource::NONE); + if cfg!(target_os = "windows") { + embed_resource::compile("soundboard.rc", embed_resource::NONE); + } } diff --git a/icons/soundboard.ico b/icons/soundboard.ico new file mode 100644 index 0000000..76428a6 Binary files /dev/null and b/icons/soundboard.ico differ diff --git a/soundboard.rc b/soundboard.rc index 5c701b4..0256017 100644 --- a/soundboard.rc +++ b/soundboard.rc @@ -1 +1 @@ -icon-red ICON "icons/icon-red.ico" \ No newline at end of file +icon-soundboard ICON "icons/soundboard.ico" \ No newline at end of file diff --git a/src/bin/strinto_declarative.rs b/src/bin/strinto_declarative.rs deleted file mode 100644 index 502c6e4..0000000 --- a/src/bin/strinto_declarative.rs +++ /dev/null @@ -1,68 +0,0 @@ -/// -/// Trying to get around "".into() for String values. -/// Or "".to_owned(). -/// Or String::from(""). -/// Or "".to_string(). -/// Choose your church. -/// -/// This is as far as you will get declaratively. - -#[macro_export] -macro_rules! strinto { - ($struct:ident { $($field:ident : $value:expr),* $(,)? }) => { - $struct { - $( - $field: $crate::strinto!(@convert $value), - )* - } - }; - - (@convert $value:literal) => { - match () { - _ if stringify!($value).starts_with("\"") => { - $value.to_string() - }, - _ => $value.into(), // <-- no getting rid of the into! - } - }; -} - -struct SomeStruct { - first_name: String, - //last_name: String, // NOPE because of @convert. - //age: usize, // reason of .into() in the first place. -} - -pub fn main() { - let x = strinto!(SomeStruct { - first_name: "First", - //last_name: String::from("Last"), // NOPE 2. - //age: 1, // NOPE 1. But I went further. - }); -} - -// while this compiles for only &str "", it is also useless compared to into! -// the reason is, that you cannot type check in the declarative macros. -// while yes, you would conditionally run stringify!($value) in the match, but the match expansion -// will always lead you to type errors if you don't do an .into() in the other arm. -// also in the end it fails to compile for anything but all members of the struct being Strings. - -// the last idea was going with a helper trait, but that will bleed into the runtime code, and yet again only work on pure String structs. - -// I guess I have to embrace String::from(), .to_string(), .to_owned(), .into() madness, for something every human reader can deduce in a second, -// if you would just implicitly convert &str to String if literally written in the code. - -// It is kinda amusing, that the other solution, to use new() kind of turns me off, because I cannot be explicit about the parameter name in the call. -// I would literally love the option to be more explicit in function param names. - -// while builder patterns feel a bit bloated for static runtime options, i will probably look into automations for that. - -// this is probably the only aesthetic decision in rust I probably will hate forever. -// It does not make sense, Strings as literals already are special in your code. -// Because numbers are as well, you dont have to write 123.into() either. -// I know I probably made some really harsh logical mistakes in my opinion here, and maybe it can be proven, that I am wrong, and I would love to hear that -// However it kind of feels like an excuse to not simplify assigning declaratively written &str to Strings in the code. - -// And it makes sense to be explicit about creating a String Buffer sometimes, but it does not make sense mostly. - -// Anyway, I will still try a procedural macro for this, just for fun. diff --git a/src/bin/ui_icon.rs b/src/bin/ui_icon.rs new file mode 100644 index 0000000..164d3c1 --- /dev/null +++ b/src/bin/ui_icon.rs @@ -0,0 +1,251 @@ +use eframe::{egui, NativeOptions}; +use std::{ffi::OsStr, os::windows::ffi::OsStrExt, ptr}; +use windows::{ + core::PCWSTR, + Win32::{ + System::LibraryLoader::GetModuleHandleW, + UI::WindowsAndMessaging::{LoadImageW, IMAGE_ICON, LR_DEFAULTCOLOR}, + }, +}; + +// https://github.com/emilk/egui/issues/920 + +#[tokio::main] +async fn main() { + // Run the UI on the main thread + run_ui(); +} + +fn run_ui() { + let app = NativeApp {}; + + // Attempt to load the icon from resources + let icon_handle = match load_icon_from_resource("icon-soundboard") { + Ok(handle) => Some(handle as isize), + Err(e) => { + eprintln!("Failed to load icon: {}", e); + None + } + }; + + // load from icon resource, cross platform. + // let icon = load_icon_static(); + // load from exe resource + let icon = from_windows::load_app_icon("icon-soundboard"); + + let native_options = NativeOptions { + viewport: egui::ViewportBuilder::default().with_icon(icon), + ..Default::default() + }; + + eframe::run_native( + "Custom window frame", // unused title + native_options, + Box::new(|_cc| Box::new(app)), + ) + .unwrap(); +} +struct NativeApp {} + +impl eframe::App for NativeApp { + fn update(&mut self, ctx: &eframe::egui::Context, frame: &mut eframe::Frame) { + egui::CentralPanel::default().show(ctx, |ui| { + ui.heading("Testing Software"); + + ui.horizontal(|ui| { + ui.label("Blah:"); + }); + + if ui.button("Apply").clicked() { + eprintln!("Apply clicked"); + } + }); + } +} + +fn to_wstring(str: &str) -> Vec { + OsStr::new(str) + .encode_wide() + .chain(Some(0).into_iter()) + .collect::>() +} + +fn load_icon_from_resource(resource_name: &str) -> Result { + let icon = unsafe { + let hmodule = if let Ok(hmodule) = GetModuleHandleW(None) { + hmodule + } else { + return Err("Error getting windows module handle".to_owned()); + }; + let handle = if let Ok(handle) = LoadImageW( + hmodule, + PCWSTR(to_wstring(resource_name).as_ptr()), + IMAGE_ICON, + 64, + 64, + LR_DEFAULTCOLOR, + ) { + handle + } else { + return Err("Error getting image handle".to_owned()); + }; + + handle + }; + Ok(icon.0) +} + +fn load_icon(path: &str) -> egui::IconData { + let (icon_rgba, icon_width, icon_height) = { + let image = image::open(path) + .expect("Failed to open icon path") + .into_rgba8(); + let (width, height) = image.dimensions(); + let rgba = image.into_raw(); + (rgba, width, height) + }; + + egui::IconData { + rgba: icon_rgba, + width: icon_width, + height: icon_height, + } +} + +pub(crate) fn load_icon_static() -> egui::IconData { + let (icon_rgba, icon_width, icon_height) = { + let icon = include_bytes!("../../icons/soundboard.ico"); + let image = image::load_from_memory(icon) + .expect("Failed to open icon path") + .into_rgba8(); + let (width, height) = image.dimensions(); + let rgba = image.into_raw(); + (rgba, width, height) + }; + + egui::IconData { + rgba: icon_rgba, + width: icon_width, + height: icon_height, + } +} + +mod from_windows { + use std::{ffi::OsStr, os::windows::ffi::OsStrExt, ptr}; + + use eframe::egui; + use windows::{ + core::PCWSTR, + Win32::{ + Graphics::Gdi::{ + CreateCompatibleDC, DeleteDC, GetDIBits, GetObjectA, SelectObject, BITMAP, + BITMAPINFO, BITMAPINFOHEADER, DIB_RGB_COLORS, + }, + System::LibraryLoader::GetModuleHandleW, + UI::WindowsAndMessaging::{ + GetIconInfo, LoadImageW, HICON, ICONINFO, IMAGE_ICON, LR_DEFAULTCOLOR, + }, + }, + }; + + fn to_wstring(str: &str) -> Vec { + OsStr::new(str) + .encode_wide() + .chain(Some(0).into_iter()) + .collect::>() + } + + // Grab the icon from the exe and hand it over to egui + pub fn load_app_icon(icon_name: &str) -> egui::IconData { + let (mut buffer, width, height) = unsafe { + let resource_name = to_wstring(icon_name); + let h_instance = GetModuleHandleW(None).unwrap(); + let icon = LoadImageW( + h_instance, + PCWSTR(resource_name.as_ptr()), + IMAGE_ICON, + 512, + 512, + LR_DEFAULTCOLOR, + ) + .unwrap(); + + let mut icon_info = ICONINFO::default(); + GetIconInfo(HICON(icon.0), &mut icon_info as *mut _).expect("Failed to load icon info"); + + let mut bitmap = BITMAP::default(); + GetObjectA( + icon_info.hbmColor, + std::mem::size_of::() as i32, + Some(&mut bitmap as *mut _ as *mut _), + ); + + let width = bitmap.bmWidth; + let height = bitmap.bmHeight; + + let b_size = (width * height * 4) as usize; + let mut buffer = Vec::::with_capacity(b_size); + + let h_dc = CreateCompatibleDC(None); + let h_bitmap = SelectObject(h_dc, icon_info.hbmColor); + + let mut bitmap_info = BITMAPINFO::default(); + bitmap_info.bmiHeader.biSize = std::mem::size_of::() as u32; + bitmap_info.bmiHeader.biWidth = width; + bitmap_info.bmiHeader.biHeight = height; + bitmap_info.bmiHeader.biPlanes = 1; + bitmap_info.bmiHeader.biBitCount = 32; + bitmap_info.bmiHeader.biCompression = 0; + bitmap_info.bmiHeader.biSizeImage = 0; + + let res = GetDIBits( + h_dc, + icon_info.hbmColor, + 0, + height as u32, + Some(buffer.spare_capacity_mut().as_mut_ptr() as *mut _), + &mut bitmap_info as *mut _, + DIB_RGB_COLORS, + ); + if res == 0 { + panic!("Failed to get RGB DI bits"); + } + + SelectObject(h_dc, h_bitmap); + let _ = DeleteDC(h_dc); + + assert_eq!( + bitmap_info.bmiHeader.biSizeImage as usize, b_size, + "returned biSizeImage must equal to b_size" + ); + + // set the new size + buffer.set_len(bitmap_info.bmiHeader.biSizeImage as usize); + + (buffer, width as u32, height as u32) + }; + + // RGBA -> BGRA + for pixel in buffer.as_mut_slice().chunks_mut(4) { + pixel.swap(0, 2); + } + + // Flip the image vertically + let row_size = width as usize * 4; // number of pixels in each row + let row_count = buffer.len() as usize / row_size; // number of rows in the image + for row in 0..row_count / 2 { + // loop through half of the rows + let start = row * row_size; // index of the start of the current row + let end = (row_count - row - 1) * row_size; // index of the end of the current row + for i in 0..row_size { + buffer.swap(start + i, end + i); + } + } + + egui::IconData { + rgba: buffer, + width, + height, + } + } +} diff --git a/src/bin/ui_test.rs b/src/bin/ui_test.rs index 405e51f..2a34ba6 100644 --- a/src/bin/ui_test.rs +++ b/src/bin/ui_test.rs @@ -1,7 +1,4 @@ -use axum::{ - routing::{self, get}, - Router, -}; +use axum::{routing::get, Router}; use eframe::egui; use serde::{Deserialize, Serialize}; use std::{ diff --git a/src/bin/ui_tray_icon.rs b/src/bin/ui_tray_icon.rs index 9fc8c29..90abac8 100644 --- a/src/bin/ui_tray_icon.rs +++ b/src/bin/ui_tray_icon.rs @@ -1,7 +1,4 @@ -use axum::{ - routing::{self, get}, - Router, -}; +use axum::{routing::get, Router}; use eframe::egui; use serde::{Deserialize, Serialize}; use std::{ @@ -56,7 +53,11 @@ async fn main() { // Set up the system tray icon let (tray_tx, tray_rx) = std::sync::mpsc::channel(); - let mut tray = TrayItem::new("App Name", tray_item::IconSource::Resource("icon-red")).unwrap(); + let mut tray = TrayItem::new( + "App Name", + tray_item::IconSource::Resource("icon-soundboard"), + ) + .unwrap(); tray.add_label("Server Control").unwrap(); tray.add_menu_item("Show/Hide", { let tray_tx = tray_tx.clone(); diff --git a/src/icon.rs b/src/icon.rs new file mode 100644 index 0000000..08dbcbc --- /dev/null +++ b/src/icon.rs @@ -0,0 +1,144 @@ +// https://github.com/emilk/egui/issues/920 + +#[cfg(not(windows))] +pub fn load_app_icon(_icon_name: &str) -> eframe::egui::IconData { + let (icon_rgba, icon_width, icon_height) = { + let icon = include_bytes!("../../icons/soundboard.ico"); + let image = image::load_from_memory(icon) + .expect("Failed to open icon path") + .into_rgba8(); + let (width, height) = image.dimensions(); + let rgba = image.into_raw(); + (rgba, width, height) + }; + + eframe::egui::IconData { + rgba: icon_rgba, + width: icon_width, + height: icon_height, + } +} + +#[cfg(windows)] +pub use from_windows::load_app_icon; + +#[cfg(windows)] +mod from_windows { + use std::{ffi::OsStr, os::windows::ffi::OsStrExt}; + + use eframe::egui; + use windows::{ + core::PCWSTR, + Win32::{ + Graphics::Gdi::{ + CreateCompatibleDC, DeleteDC, GetDIBits, GetObjectA, SelectObject, BITMAP, + BITMAPINFO, BITMAPINFOHEADER, DIB_RGB_COLORS, + }, + System::LibraryLoader::GetModuleHandleW, + UI::WindowsAndMessaging::{ + GetIconInfo, LoadImageW, HICON, ICONINFO, IMAGE_ICON, LR_DEFAULTCOLOR, + }, + }, + }; + + fn to_wstring(str: &str) -> Vec { + OsStr::new(str) + .encode_wide() + .chain(Some(0).into_iter()) + .collect::>() + } + + // Grab the icon from the exe and hand it over to egui + pub fn load_app_icon(icon_name: &str) -> egui::IconData { + let (mut buffer, width, height) = unsafe { + let resource_name = to_wstring(icon_name); + let h_instance = GetModuleHandleW(None).unwrap(); + let icon = LoadImageW( + h_instance, + PCWSTR(resource_name.as_ptr()), + IMAGE_ICON, + 512, + 512, + LR_DEFAULTCOLOR, + ) + .unwrap(); + + let mut icon_info = ICONINFO::default(); + GetIconInfo(HICON(icon.0), &mut icon_info as *mut _).expect("Failed to load icon info"); + + let mut bitmap = BITMAP::default(); + GetObjectA( + icon_info.hbmColor, + std::mem::size_of::() as i32, + Some(&mut bitmap as *mut _ as *mut _), + ); + + let width = bitmap.bmWidth; + let height = bitmap.bmHeight; + + let b_size = (width * height * 4) as usize; + let mut buffer = Vec::::with_capacity(b_size); + + let h_dc = CreateCompatibleDC(None); + let h_bitmap = SelectObject(h_dc, icon_info.hbmColor); + + let mut bitmap_info = BITMAPINFO::default(); + bitmap_info.bmiHeader.biSize = std::mem::size_of::() as u32; + bitmap_info.bmiHeader.biWidth = width; + bitmap_info.bmiHeader.biHeight = height; + bitmap_info.bmiHeader.biPlanes = 1; + bitmap_info.bmiHeader.biBitCount = 32; + bitmap_info.bmiHeader.biCompression = 0; + bitmap_info.bmiHeader.biSizeImage = 0; + + let res = GetDIBits( + h_dc, + icon_info.hbmColor, + 0, + height as u32, + Some(buffer.spare_capacity_mut().as_mut_ptr() as *mut _), + &mut bitmap_info as *mut _, + DIB_RGB_COLORS, + ); + if res == 0 { + panic!("Failed to get RGB DI bits"); + } + + SelectObject(h_dc, h_bitmap); + let _ = DeleteDC(h_dc); + + assert_eq!( + bitmap_info.bmiHeader.biSizeImage as usize, b_size, + "returned biSizeImage must equal to b_size" + ); + + // set the new size + buffer.set_len(bitmap_info.bmiHeader.biSizeImage as usize); + + (buffer, width as u32, height as u32) + }; + + // RGBA -> BGRA + for pixel in buffer.as_mut_slice().chunks_mut(4) { + pixel.swap(0, 2); + } + + // Flip the image vertically + let row_size = width as usize * 4; // number of pixels in each row + let row_count = buffer.len() as usize / row_size; // number of rows in the image + for row in 0..row_count / 2 { + // loop through half of the rows + let start = row * row_size; // index of the start of the current row + let end = (row_count - row - 1) * row_size; // index of the end of the current row + for i in 0..row_size { + buffer.swap(start + i, end + i); + } + } + + egui::IconData { + rgba: buffer, + width, + height, + } + } +} diff --git a/src/main.rs b/src/main.rs index f16d74c..afe537a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ use dotenvy::dotenv; use vbplay::{example_handler, DeviceSelection, SoundDecoder}; mod handlers; +mod icon; mod server; mod soundclips; mod state; @@ -36,7 +37,7 @@ fn main() { let audio = Arc::new(Mutex::new(audio)); let server_settings = Arc::new(Mutex::new(server::ServerSettings { - port: "3000".to_string(), + port: "3311".to_string(), })); let should_run = Arc::new(Mutex::new(true)); diff --git a/src/ui.rs b/src/ui.rs index 3f02b25..25c7f81 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -15,7 +15,13 @@ pub fn run_ui( static VISIBLE: once_cell::sync::Lazy> = once_cell::sync::Lazy::new(|| Mutex::new(true)); - let native_options = eframe::NativeOptions::default(); + let icon = crate::icon::load_app_icon("icon-soundboard"); + + let native_options = eframe::NativeOptions { + viewport: egui::ViewportBuilder::default().with_icon(icon), + ..Default::default() + }; + eframe::run_native( "App", native_options, @@ -23,38 +29,44 @@ pub fn run_ui( // Set up the tray icon event handler let window_handle = cc.window_handle().unwrap(); let window_handle = window_handle.as_raw(); - let mut tray = - TrayItem::new("Soundboard", tray_item::IconSource::Resource("icon-red")).unwrap(); + let mut tray = TrayItem::new( + "Soundboard", + tray_item::IconSource::Resource("icon-soundboard"), + ) + .unwrap(); if let RawWindowHandle::Win32(handle) = window_handle { - // Windows Only. - use windows::Win32::Foundation::HWND; - use windows::Win32::UI::WindowsAndMessaging::{ - ShowWindow, - SW_HIDE, - SW_RESTORE, // SW_SHOWDEFAULT, SW_SHOWNORMAL, - }; + #[cfg(windows)] + { + // Windows Only. + use windows::Win32::Foundation::HWND; + use windows::Win32::UI::WindowsAndMessaging::{ + ShowWindow, + SW_HIDE, + SW_RESTORE, // SW_SHOWDEFAULT, SW_SHOWNORMAL, + }; - tray.add_label("Server Control").unwrap(); + tray.add_label("Server Control").unwrap(); - tray.add_menu_item("Show/Hide", { - move || { - let mut visible_lock = VISIBLE.lock().unwrap(); - let window_handle = HWND(handle.hwnd.into()); + tray.add_menu_item("Show/Hide", { + move || { + let mut visible_lock = VISIBLE.lock().unwrap(); + let window_handle = HWND(handle.hwnd.into()); - if *visible_lock { - unsafe { - _ = ShowWindow(window_handle, SW_HIDE); + if *visible_lock { + unsafe { + _ = ShowWindow(window_handle, SW_HIDE); + } + *visible_lock = false; + } else { + unsafe { + _ = ShowWindow(window_handle, SW_RESTORE); + } + *visible_lock = true; } - *visible_lock = false; - } else { - unsafe { - _ = ShowWindow(window_handle, SW_RESTORE); - } - *visible_lock = true; } - } - }) - .unwrap(); + }) + .unwrap(); + } } else { println!("Unsupported platform for tray icon."); } @@ -62,7 +74,7 @@ pub fn run_ui( let my_tx = tx.clone(); tray.add_menu_item("Quit", move || { my_tx.try_send(ServerMessage::Shutdown).unwrap(); - //std::process::exit(0); + std::process::exit(0); }) .unwrap(); diff --git a/src/vbplay.rs b/src/vbplay.rs index 89ece08..2f8f2a3 100644 --- a/src/vbplay.rs +++ b/src/vbplay.rs @@ -200,7 +200,7 @@ pub fn audio_thread( error!("Mutex Lock Failure while trying to play sound.") } } - Command::PlayWhilePressing(file_name, press_button) => { + Command::PlayWhilePressing(file_name, _press_button) => { if let Ok(sink) = sink_mutex.lock() { play_file(&sink, file_name, &select_decoder); } else { @@ -239,7 +239,7 @@ pub fn audio_thread( tx } -fn detect_decoder(file_name: &str, sound_decoder: &SoundDecoder) -> SoundDecoder { +fn detect_decoder(_file_name: &str, sound_decoder: &SoundDecoder) -> SoundDecoder { // TODO: File detection via ending or whitelisting? // This function MUST NOT return SoundDecoder::Detect match sound_decoder { diff --git a/strinto/.gitignore b/strinto/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/strinto/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/strinto/Cargo.lock b/strinto/Cargo.lock deleted file mode 100644 index 7f8aab3..0000000 --- a/strinto/Cargo.lock +++ /dev/null @@ -1,47 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "proc-macro2" -version = "1.0.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "strinto" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "2.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/strinto/Cargo.toml b/strinto/Cargo.toml deleted file mode 100644 index d47f7cc..0000000 --- a/strinto/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "strinto" -version = "0.1.0" -edition = "2021" - -[lib] -proc-macro = true - -[dependencies] -syn = { version = "2.0", features = ["full"] } -quote = "1.0" - -[dev-dependencies] -proc-macro2 = "1.0" diff --git a/strinto/src/lib.rs b/strinto/src/lib.rs deleted file mode 100644 index b147e4d..0000000 --- a/strinto/src/lib.rs +++ /dev/null @@ -1,62 +0,0 @@ -extern crate proc_macro; -use proc_macro::TokenStream; -use quote::quote; -use syn::{parse_macro_input, Expr, ExprStruct}; - -/// # literal strings in a struct insantiation are converted .into(). -/// -/// ```rust -/// use strinto::strinto; -/// #[derive(Debug)] -/// struct TestStruct { -/// name: String, -/// title: String, -/// description: String, -/// age: usize, -/// } -/// -/// let descr = "description"; -/// -/// let output = strinto!(TestStruct { -/// name: "John", // Literal string. -/// title: String::from("Wicked"), -/// description: descr.to_string(), -/// age: 30, -/// }); -/// -/// let output_string = format!("{:?}", output); -/// assert_eq!( -/// output_string, -/// "TestStruct { name: \"John\", title: \"Wicked\", description: \"description\", age: 30 }" -/// ); -/// ``` - -#[proc_macro] -pub fn strinto(input: TokenStream) -> TokenStream { - let expr_struct = parse_macro_input!(input as ExprStruct); - - // Extract struct name and fields - let struct_name = &expr_struct.path; - let fields = expr_struct.fields.iter().map(|field| { - let field_name = field.member.clone(); - let field_value = &field.expr; - // Determine if the field value is a string literal and transform it - if let Expr::Lit(expr_lit) = field_value { - if let syn::Lit::Str(_) = expr_lit.lit { - quote! { #field_name: #field_value.into() } - } else { - quote! { #field_name: #field_value } - } - } else { - quote! { #field_name: #field_value } - } - }); - - let expanded = quote! { - #struct_name { - #(#fields,)* - } - }; - - expanded.into() -}