diff --git a/Cargo.lock b/Cargo.lock index f9538111b344f10a16d119db7963e67bf40c8126..c691068fd7ce25fda1545214e7f6dfd2bc2faf27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,12 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ab_glyph" -version = "0.2.28" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -20,52 +20,55 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "accesskit" -version = "0.14.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cf780eb737f2d4a49ffbd512324d53ad089070f813f7be7f99dbd5123a7f448" +checksum = "d3d3b8f9bae46a948369bc4a03e815d4ed6d616bd00de4051133a5019dc31c5a" [[package]] name = "accesskit_consumer" -version = "0.22.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdfa1638ddd6eb9c752def95568df8b3ad832df252e9156d2eb783b201ca8a9" +checksum = "f47983a1084940ba9a39c077a8c63e55c619388be5476ac04c804cfbd1e63459" dependencies = [ "accesskit", + "hashbrown 0.15.2", "immutable-chunkmap", ] [[package]] name = "accesskit_macos" -version = "0.15.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c236a84ff1111defc280cee755eaa953d0b24398786851b9d28322c6d3bb1ebd" +checksum = "7329821f3bd1101e03a7d2e03bd339e3ac0dc64c70b4c9f9ae1949e3ba8dece1" dependencies = [ "accesskit", "accesskit_consumer", + "hashbrown 0.15.2", "objc2", "objc2-app-kit", "objc2-foundation", - "once_cell", ] [[package]] name = "accesskit_windows" -version = "0.20.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7f43d24b16b3e76bef248124fbfd2493c3a9860edb5aae1010c890e826de5e" +checksum = "24fcd5d23d70670992b823e735e859374d694a3d12bfd8dd32bd3bd8bedb5d81" dependencies = [ "accesskit", "accesskit_consumer", + "hashbrown 0.15.2", "paste", "static_assertions", - "windows 0.54.0", + "windows", + "windows-core", ] [[package]] name = "accesskit_winit" -version = "0.20.4" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755535e6bf711a42dac28b888b884b10fc00ff4010d9d3bd871c5f5beae5aa78" +checksum = "6a6a48dad5530b6deb9fc7a52cc6c3bf72cdd9eb8157ac9d32d69f2427a5e879" dependencies = [ "accesskit", "accesskit_macos", @@ -93,6 +96,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "const-random", "getrandom", "once_cell", "version_check", @@ -209,7 +213,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -232,11 +236,22 @@ checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" [[package]] name = "ash" -version = "0.37.3+1.3.251" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + +[[package]] +name = "assert_type_match" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +checksum = "f548ad2c4031f2902e3edc1f29c29e835829437de49562d8eb5dc5584d3a1043" dependencies = [ - "libloading 0.7.4", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -308,6 +323,12 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "atomicow" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467163b50876d3a4a44da5f4dbd417537e522fc059ede8d518d57941cfb3d745" + [[package]] name = "autocfg" version = "1.3.0" @@ -345,30 +366,76 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bevy" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ece0d8dde51890fb52dcba5b04fd1c657617a4022908c327b2d6e83d173a32" +checksum = "b6a01cd51a5cd310e4e7aa6e1560b1aabf29efc6a095a01e6daa8bf0a19f1fea" dependencies = [ "bevy_internal", ] +[[package]] +name = "bevy-inspector-egui" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd64580f4496ed987c6231c6a7d833068914331a9084bf5a3dd9dcbc66fd8a73" +dependencies = [ + "bevy-inspector-egui-derive", + "bevy_app", + "bevy_asset", + "bevy_color", + "bevy_core", + "bevy_core_pipeline", + "bevy_ecs", + "bevy_egui", + "bevy_hierarchy", + "bevy_image", + "bevy_log", + "bevy_math", + "bevy_pbr", + "bevy_reflect", + "bevy_render", + "bevy_state", + "bevy_time", + "bevy_utils", + "bevy_window", + "bytemuck", + "disqualified", + "egui", + "fuzzy-matcher", + "image", + "smallvec", + "winit", +] + +[[package]] +name = "bevy-inspector-egui-derive" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3afc67826e0a4347414545e022e748f42550a577a502b26af44e6d03742c9266" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "bevy_a11y" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d84e0ae7155afa21c4926fb8b89ebe0cbd66239ac817fdb834025327c4089b" +checksum = "82c66b5bc82a2660a5663d85b3354ddb72c8ab2c443989333cbea146f39a4e9a" dependencies = [ "accesskit", "bevy_app", "bevy_derive", "bevy_ecs", + "bevy_reflect", ] [[package]] name = "bevy_app" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0af99549f5de61cc91c8c23303b13aa07f97b73fbace39695dee0a0a32cec9d4" +checksum = "652574e4c10efcfa70f98036709dd5b67e5cb8d46c58087ef48c2ac6b62df9da" dependencies = [ "bevy_derive", "bevy_ecs", @@ -376,38 +443,44 @@ dependencies = [ "bevy_tasks", "bevy_utils", "console_error_panic_hook", + "ctrlc", + "derive_more", "downcast-rs", - "thiserror", "wasm-bindgen", "web-sys", ] [[package]] name = "bevy_asset" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6533d17f13b44ea4fb5177f83b0900269ed13c0fd45772ccffd19a69980647ec" +checksum = "4d7d501eda01be6d500d843a06d9b9800c3f0fffaae3c29d17d9e4e172c28d37" dependencies = [ "async-broadcast", "async-fs", "async-lock", + "atomicow", "bevy_app", "bevy_asset_macros", "bevy_ecs", "bevy_reflect", "bevy_tasks", "bevy_utils", - "bevy_winit", + "bevy_window", + "bitflags 2.6.0", "blake3", "crossbeam-channel", + "derive_more", + "disqualified", "downcast-rs", + "either", "futures-io", "futures-lite", "js-sys", "parking_lot", "ron", "serde", - "thiserror", + "stackfuture", "uuid", "wasm-bindgen", "wasm-bindgen-futures", @@ -416,36 +489,36 @@ dependencies = [ [[package]] name = "bevy_asset_macros" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b0e132a89e254c0f5c8bc8deebb0f2490f5662f4aa2215a6996701446d6a7b" +checksum = "7474b77fc27db11ec03d49ca04f1a7471f369dc373fd5e091a12ad7ab533d8c8" dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "bevy_color" -version = "0.14.2" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82c031f121b8d72e7637c94ef139097613bd32935784d36728f83e77cfdf26f4" +checksum = "87bccacba27db37375eb97ffc86e91a7d95db3f5faa6a834fa7306db02cde327" dependencies = [ "bevy_math", "bevy_reflect", "bytemuck", + "derive_more", "encase", "serde", - "thiserror", "wgpu-types", ] [[package]] name = "bevy_core" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccc7118a2865267136afb5e6a2c0aed30994e522f298b2ba0b088878e6ddf59" +checksum = "ecccf7be33330f58d4c7033b212a25c414d388e3a8d55b61331346da5dbabf22" dependencies = [ "bevy_app", "bevy_ecs", @@ -457,9 +530,9 @@ dependencies = [ [[package]] name = "bevy_core_pipeline" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559ad1dc48c3fa6bbace503df2fe44a7de38c8dfe11bee911ec0ffaf93e3e57d" +checksum = "8a3fb9f84fa60c2006d4a15e039c3d08d4d10599441b9175907341a77a69d627" dependencies = [ "bevy_app", "bevy_asset", @@ -467,26 +540,28 @@ dependencies = [ "bevy_core", "bevy_derive", "bevy_ecs", + "bevy_image", "bevy_math", "bevy_reflect", "bevy_render", "bevy_transform", "bevy_utils", + "bevy_window", "bitflags 2.6.0", + "derive_more", "nonmax", "radsort", "serde", "smallvec", - "thiserror", ] [[package]] name = "bevy_cosmic_edit" -version = "0.25.0" +version = "0.26.0" dependencies = [ "arboard", "bevy", - "cosmic-text", + "bevy_editor_pls", "crossbeam-channel", "document-features", "image", @@ -501,20 +576,20 @@ dependencies = [ [[package]] name = "bevy_derive" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8675f337f374b2b8ae90539982b947d171f9adb302d00c032b823bd5231f8978" +checksum = "e141b7eda52a23bb88740b37a291e26394524cb9ee3b034c7014669671fc2bb5" dependencies = [ "bevy_macro_utils", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "bevy_diagnostic" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdcc1d7ba5797e4285a7867227134d4cabaaf8cabfb7cdc42eb697d3b3db0460" +checksum = "fa97748337405089edfb2857f7608f21bcc648a7ad272c9209808aad252ed542" dependencies = [ "bevy_app", "bevy_core", @@ -527,9 +602,9 @@ dependencies = [ [[package]] name = "bevy_ecs" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3eed7f144811946ebfa1c740da9e3bcd6dd2dd4da844eda085249d29bc9fef" +checksum = "cb4c4b60d2a712c6d5cbe610bac7ecf0838fc56a095fd5b15f30230873e84f15" dependencies = [ "bevy_ecs_macros", "bevy_ptr", @@ -538,30 +613,106 @@ dependencies = [ "bevy_utils", "bitflags 2.6.0", "concurrent-queue", + "derive_more", + "disqualified", "fixedbitset 0.5.7", "nonmax", "petgraph", "serde", - "thiserror", + "smallvec", ] [[package]] name = "bevy_ecs_macros" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d523630f2eb9fde6727e6c5ea48fa708079c5345da21ffeb1a4bd8ca761830da" +checksum = "cb4296b3254b8bd29769f6a4512731b2e6c4b163343ca18b72316927315b6096" dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.76", + "syn", +] + +[[package]] +name = "bevy_editor_pls" +version = "0.11.0" +source = "git+https://github.com/ActuallyHappening/bevy_editor_pls.git#2e57ce6e49cf0963903922770ccbc2e32353564c" +dependencies = [ + "bevy", + "bevy_editor_pls_core", + "bevy_editor_pls_default_windows", + "egui", + "transform-gizmo-bevy", +] + +[[package]] +name = "bevy_editor_pls_core" +version = "0.11.0" +source = "git+https://github.com/ActuallyHappening/bevy_editor_pls.git#2e57ce6e49cf0963903922770ccbc2e32353564c" +dependencies = [ + "bevy", + "bevy-inspector-egui", + "egui_dock", + "indexmap", +] + +[[package]] +name = "bevy_editor_pls_default_windows" +version = "0.11.0" +source = "git+https://github.com/ActuallyHappening/bevy_editor_pls.git#2e57ce6e49cf0963903922770ccbc2e32353564c" +dependencies = [ + "bevy", + "bevy-inspector-egui", + "bevy_editor_pls_core", + "bevy_mod_debugdump", + "indexmap", + "opener", + "pretty-type-name", + "transform-gizmo-bevy", +] + +[[package]] +name = "bevy_egui" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "954fbe8551af4b40767ea9390ec7d32fe1070a6ab55d524cf0868c17f8469a55" +dependencies = [ + "arboard", + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_input", + "bevy_log", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_time", + "bevy_utils", + "bevy_window", + "bevy_winit", + "bytemuck", + "crossbeam-channel", + "egui", + "encase", + "js-sys", + "log", + "thread_local", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webbrowser", + "wgpu-types", + "winit", ] [[package]] name = "bevy_encase_derive" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a20ec101b103f430481112591e280a8fc3f2db6741579f885595372073b749b" +checksum = "bfe562b883fb652acde84cb6bb01cbc9f23c377e411f1484467ecfdd3a3d234e" dependencies = [ "bevy_macro_utils", "encase_derive_impl", @@ -569,9 +720,9 @@ dependencies = [ [[package]] name = "bevy_gizmos" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248324352331d719071b0d1545a43e3d63470f4730e75312edee575f210d3a77" +checksum = "e1c82341f6a3517efeeeef2fe68135ac3a91b11b6e369fc1a07f6e9a4b462b57" dependencies = [ "bevy_app", "bevy_asset", @@ -579,7 +730,9 @@ dependencies = [ "bevy_core_pipeline", "bevy_ecs", "bevy_gizmos_macros", + "bevy_image", "bevy_math", + "bevy_pbr", "bevy_reflect", "bevy_render", "bevy_sprite", @@ -591,50 +744,72 @@ dependencies = [ [[package]] name = "bevy_gizmos_macros" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbe1708bb0e45a1d0fe0f32e998557689231dfe7bdae62083326e8008e97de23" +checksum = "9454ac9f0a2141900ef9f3482af9333e490d5546bbea3cab63a777447d35beed" dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "bevy_hierarchy" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb332d2789442ca1577c765977bafefea1dcd4db29479713ec8c6932dfb82cdb" +checksum = "6fe0b538beea7edbf30a6062242b99e67ff3bfa716566aacf91d5b5e027f02a2" dependencies = [ "bevy_app", "bevy_core", "bevy_ecs", "bevy_reflect", "bevy_utils", + "disqualified", "smallvec", ] +[[package]] +name = "bevy_image" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db46fa6a2f9e20435f3231710abbb136d2cc0a376f3f8e6ecfe071e286f5a246" +dependencies = [ + "bevy_asset", + "bevy_color", + "bevy_math", + "bevy_reflect", + "bevy_utils", + "bitflags 2.6.0", + "bytemuck", + "derive_more", + "futures-lite", + "image", + "serde", + "wgpu", +] + [[package]] name = "bevy_input" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9ce5f27a8729b473205b01927cd6a5c4898a004cb8fcffa7c896e19ba999d98" +checksum = "46b4ea60095d1a1851e40cb12481ad3d5d234e14376d6b73142a85586c266b74" dependencies = [ "bevy_app", + "bevy_core", "bevy_ecs", "bevy_math", "bevy_reflect", "bevy_utils", + "derive_more", "smol_str", - "thiserror", ] [[package]] name = "bevy_internal" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2463102e46d7d67440dbfe3bc97d34bf529c93191c4f4bb41395f4982062ff3" +checksum = "d4237e6e9b03902321032f00f931f18a4a211093bd9a7cf81276a0228a2a4417" dependencies = [ "bevy_a11y", "bevy_app", @@ -647,10 +822,12 @@ dependencies = [ "bevy_ecs", "bevy_gizmos", "bevy_hierarchy", + "bevy_image", "bevy_input", "bevy_log", "bevy_math", "bevy_pbr", + "bevy_picking", "bevy_ptr", "bevy_reflect", "bevy_render", @@ -668,59 +845,102 @@ dependencies = [ [[package]] name = "bevy_log" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f2c0c374af59007396793a51f747f6b10d74ca4acfb080ce0ade267118827b" +checksum = "1a0bdb42b00ac3752f0d6f531fbda8abf313603157a7b3163da8529412119a0a" dependencies = [ "android_log-sys", "bevy_app", "bevy_ecs", "bevy_utils", "tracing-log", + "tracing-oslog", "tracing-subscriber", "tracing-wasm", ] [[package]] name = "bevy_macro_utils" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ec4a585ec2a6dedd4f4143c07219d120ae142121929f0d83e68d82a452cdc9b" +checksum = "3954dbb56a66a6c09c783e767f6ceca0dc0492c22e536e2aeaefb5545eac33c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", "toml_edit 0.22.20", ] [[package]] name = "bevy_math" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40253578fe83a5ffe5f4fcb4dfa196b7d9c50f36dc8efaa231a53344bf4b3e57" +checksum = "9ae26f952598e293acac783d947b21af1809673cbeba25d76b969a56f287160b" dependencies = [ "bevy_reflect", + "derive_more", "glam", + "itertools 0.13.0", "rand", + "rand_distr", "serde", "smallvec", - "thiserror", +] + +[[package]] +name = "bevy_mesh" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c324d45ca0043a4696d7324b569de65be17066ed3a97dd42205bc28693d20b5" +dependencies = [ + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_math", + "bevy_mikktspace", + "bevy_reflect", + "bevy_transform", + "bevy_utils", + "bitflags 2.6.0", + "bytemuck", + "derive_more", + "hexasphere", + "serde", + "wgpu", ] [[package]] name = "bevy_mikktspace" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a1ad15685c6035e01bdc9d5ea082558ef1438e9d40d69fc552857dd7e83e71" +checksum = "da5ea3ad25d74ea36ea45418ad799f135d046db35c322b9704c4a8934eb65ce9" dependencies = [ "glam", ] +[[package]] +name = "bevy_mod_debugdump" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2855a39000ecb45c94f1b44ca14133398b8e6c6a0913d80d932037b7c1c016f5" +dependencies = [ + "bevy_app", + "bevy_color", + "bevy_ecs", + "bevy_render", + "bevy_utils", + "lexopt", + "once_cell", + "petgraph", + "pretty-type-name", +] + [[package]] name = "bevy_pbr" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "588998ba295db4a14dec54e571f272490f2885e5aaac59191fb4fa32a25835d0" +checksum = "01b3bd8e646ddd3f27743b712957d2990d7361eb21044accc47c4f66711bf2cb" dependencies = [ "bevy_app", "bevy_asset", @@ -728,6 +948,7 @@ dependencies = [ "bevy_core_pipeline", "bevy_derive", "bevy_ecs", + "bevy_image", "bevy_math", "bevy_reflect", "bevy_render", @@ -736,6 +957,7 @@ dependencies = [ "bevy_window", "bitflags 2.6.0", "bytemuck", + "derive_more", "fixedbitset 0.5.7", "nonmax", "radsort", @@ -743,49 +965,73 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "bevy_picking" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a137ed706574dc4a01cac527eb2c44a0b0e477d5bce3afc892a9ee95ee0078" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_derive", + "bevy_ecs", + "bevy_hierarchy", + "bevy_input", + "bevy_math", + "bevy_reflect", + "bevy_render", + "bevy_time", + "bevy_transform", + "bevy_utils", + "bevy_window", + "uuid", +] + [[package]] name = "bevy_ptr" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ed72afbb6249a6803a3ed7bd2f68ff080d9392f550475e050b34c1e1c1e3e8f" +checksum = "2af9e30b40fb3f0a80a658419f670f2de1e743efcaca1952c43cdcc923287944" [[package]] name = "bevy_reflect" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb37e8fc3c61d04da480c95cc8c303aa7781afed6be01dae333b336af493c38e" +checksum = "52a37e2ae5ed62df4a0e3f958076effe280b39bc81fe878587350897a89332a2" dependencies = [ + "assert_type_match", "bevy_ptr", "bevy_reflect_derive", "bevy_utils", + "derive_more", + "disqualified", "downcast-rs", "erased-serde", "glam", "serde", "smallvec", "smol_str", - "thiserror", "uuid", ] [[package]] name = "bevy_reflect_derive" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc00d5086f5bf534b4c2dbeba549a6b8d3223515f3cb5ba4fdaabe953ec6cea" +checksum = "94c683fc68c75fc26f90bb1e529590095380d7cec66f6610dbe6b93d9fd26f94" dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.76", + "syn", "uuid", ] [[package]] name = "bevy_render" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f570f36154296ae5377587d5ef19e1feb4c5734923785c571f55a9fff091701" +checksum = "d188f392edf4edcae53dfda07f3ec618a7a704183ec3f2e8504657a9fb940c8a" dependencies = [ "async-channel", "bevy_app", @@ -797,8 +1043,9 @@ dependencies = [ "bevy_ecs", "bevy_encase_derive", "bevy_hierarchy", + "bevy_image", "bevy_math", - "bevy_mikktspace", + "bevy_mesh", "bevy_reflect", "bevy_render_macros", "bevy_tasks", @@ -806,22 +1053,21 @@ dependencies = [ "bevy_transform", "bevy_utils", "bevy_window", - "bitflags 2.6.0", "bytemuck", "codespan-reporting", + "derive_more", "downcast-rs", "encase", "futures-lite", - "hexasphere", "image", "js-sys", "naga", "naga_oil", "nonmax", + "offset-allocator", "send_wrapper", "serde", "smallvec", - "thiserror", "wasm-bindgen", "web-sys", "wgpu", @@ -829,21 +1075,21 @@ dependencies = [ [[package]] name = "bevy_render_macros" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe2d5008c7b4a8a516ef7b58452b8e40e4c2317068fc7505398bedf34e8d45f7" +checksum = "4ab37ee2945f93e9ba8daf91cd968b4cba9c677ac51d349dd8512a107a9a5d92" dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "bevy_scene" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3910087f6fc45e7833fb62e4de282c36a7012ff381c0584eb2cc84dede02e72f" +checksum = "0e883fd3c6d6e7761f1fe662e79bc7bdc7e917e73e7bfc434b1d16d2a5852119" dependencies = [ "bevy_app", "bevy_asset", @@ -854,16 +1100,16 @@ dependencies = [ "bevy_render", "bevy_transform", "bevy_utils", + "derive_more", "serde", - "thiserror", "uuid", ] [[package]] name = "bevy_sprite" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffdfb9a18968c8606286b6be83c9323ff9008b5cc043a23a3ecc95ff72fb20c" +checksum = "e975abc3f3f3432d6ad86ae32de804e96d7faf59d27f32b065b5ddc1e73ed7e1" dependencies = [ "bevy_app", "bevy_asset", @@ -871,42 +1117,76 @@ dependencies = [ "bevy_core_pipeline", "bevy_derive", "bevy_ecs", + "bevy_image", "bevy_math", + "bevy_picking", "bevy_reflect", "bevy_render", "bevy_transform", "bevy_utils", + "bevy_window", "bitflags 2.6.0", "bytemuck", + "derive_more", "fixedbitset 0.5.7", "guillotiere", + "nonmax", "radsort", "rectangle-pack", - "thiserror", ] [[package]] -name = "bevy_tasks" -version = "0.14.1" +name = "bevy_state" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "036ec832197eae51b8a842220d2df03591dff75b4566dcf0f81153bbcb2b593b" +dependencies = [ + "bevy_app", + "bevy_ecs", + "bevy_hierarchy", + "bevy_reflect", + "bevy_state_macros", + "bevy_utils", +] + +[[package]] +name = "bevy_state_macros" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f5414c3f49c96e02ceccf5fa12fb6cfbf8b271d2a820902d6f622e9c2fa681" +checksum = "2828eb6762af9eccfebb5e4a0e56dbc4bd07bf3192083fa3e8525cfdb3e95add" +dependencies = [ + "bevy_macro_utils", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "bevy_tasks" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5171c605b462b4e3249e01986505e62e3933aa27642a9f793c841814fcbbfb4f" dependencies = [ "async-executor", + "futures-channel", "futures-lite", + "pin-project", "wasm-bindgen-futures", ] [[package]] name = "bevy_text" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e77dd86def15f5380e6e7c178ec54e5e356b3f464e2ad35794a08d5ecb82e4" +checksum = "4fb000b2abad9f82f7a137fac7e0e3d2c6488cbf8dd9ddbb68f9a6b7e7af8d84" dependencies = [ - "ab_glyph", "bevy_app", "bevy_asset", "bevy_color", + "bevy_derive", "bevy_ecs", + "bevy_hierarchy", + "bevy_image", "bevy_math", "bevy_reflect", "bevy_render", @@ -914,45 +1194,48 @@ dependencies = [ "bevy_transform", "bevy_utils", "bevy_window", - "glyph_brush_layout", + "cosmic-text", + "derive_more", "serde", - "thiserror", + "smallvec", + "sys-locale", + "unicode-bidi", ] [[package]] name = "bevy_time" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3fb18cfac62098e07786e422e84b4f45f469f27ccb5b572b409500bef465f33" +checksum = "291b6993b899c04554fc034ebb9e0d7fde9cb9b2fb58dcd912bfa6247abdedbb" dependencies = [ "bevy_app", "bevy_ecs", "bevy_reflect", "bevy_utils", "crossbeam-channel", - "thiserror", ] [[package]] name = "bevy_transform" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ff09cea0dd0d4e6a3ed5f7dcbd4fbbcec07e518ceb64a4c8a75dedbe294ab60" +checksum = "dc35665624d0c728107ab0920d5ad2d352362b906a8c376eaf375ec9c751faf4" dependencies = [ "bevy_app", "bevy_ecs", "bevy_hierarchy", "bevy_math", "bevy_reflect", - "thiserror", + "derive_more", ] [[package]] name = "bevy_ui" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50684629a03b7d4891b5953e84dd971c7a8bbd290751bab5ce06e119b692220b" +checksum = "43da3326aa592d6f6326e31893901bf17cd6957ded4e0ea02bc54652e5624b7f" dependencies = [ + "accesskit", "bevy_a11y", "bevy_app", "bevy_asset", @@ -961,8 +1244,10 @@ dependencies = [ "bevy_derive", "bevy_ecs", "bevy_hierarchy", + "bevy_image", "bevy_input", "bevy_math", + "bevy_picking", "bevy_reflect", "bevy_render", "bevy_sprite", @@ -971,22 +1256,22 @@ dependencies = [ "bevy_utils", "bevy_window", "bytemuck", + "derive_more", "nonmax", "smallvec", "taffy", - "thiserror", ] [[package]] name = "bevy_utils" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6efbe5a621b56cc4ffa41074929eca84107e242302496b9bb7550675e6bf2e7" +checksum = "a0a48bad33c385a7818b7683a16c8b5c6930eded05cd3f176264fc1f5acea473" dependencies = [ "ahash", "bevy_utils_proc_macros", "getrandom", - "hashbrown", + "hashbrown 0.14.5", "thread_local", "tracing", "web-time", @@ -994,24 +1279,26 @@ dependencies = [ [[package]] name = "bevy_utils_proc_macros" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a1e91b4294cad2d08620ac062509395d4f65247b636946d6497eaeccf4dbfd" +checksum = "3dfd8d4a525b8f04f85863e45ccad3e922d4c11ed4a8d54f7f62a40bf83fb90f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "bevy_window" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba11880f05a3b267ecfa4149fe789b0c046c35fd8418dd8899fad3a4359c986" +checksum = "05f3520279aae65935d6a84443202c154ead3abebf8dae906d095665162de358" dependencies = [ + "android-activity", "bevy_a11y", "bevy_app", "bevy_ecs", + "bevy_input", "bevy_math", "bevy_reflect", "bevy_utils", @@ -1021,17 +1308,20 @@ dependencies = [ [[package]] name = "bevy_winit" -version = "0.14.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5aeb4b2e3b1ece189fcf37ea2de625ceab93e6ac2a14d4b15b0393351e4c18b" +checksum = "581bb2249a82285707e0977a9a1c79a2248ede587fcb289708faa03a82ebfa7f" dependencies = [ + "accesskit", "accesskit_winit", "approx", "bevy_a11y", "bevy_app", + "bevy_asset", "bevy_derive", "bevy_ecs", "bevy_hierarchy", + "bevy_image", "bevy_input", "bevy_log", "bevy_math", @@ -1039,21 +1329,52 @@ dependencies = [ "bevy_tasks", "bevy_utils", "bevy_window", + "bytemuck", "cfg-if", "crossbeam-channel", "raw-window-handle", "wasm-bindgen", "web-sys", + "wgpu-types", "winit", ] +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + [[package]] name = "bit-set" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "bit-vec", + "bit-vec 0.6.3", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec 0.8.0", ] [[package]] @@ -1062,6 +1383,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bit_field" version = "0.10.2" @@ -1130,6 +1457,17 @@ dependencies = [ "piper", ] +[[package]] +name = "bstr" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" +dependencies = [ + "memchr", + "regex-automata 0.4.7", + "serde", +] + [[package]] name = "built" version = "0.7.4" @@ -1144,9 +1482,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.17.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] @@ -1159,7 +1497,7 @@ checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -1194,6 +1532,18 @@ dependencies = [ "thiserror", ] +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", +] + [[package]] name = "cc" version = "1.1.14" @@ -1211,6 +1561,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-expr" version = "0.15.8" @@ -1239,6 +1598,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clipboard-win" version = "5.4.0" @@ -1264,37 +1634,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" -[[package]] -name = "com" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" -dependencies = [ - "com_macros", -] - -[[package]] -name = "com_macros" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" -dependencies = [ - "com_macros_support", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "com_macros_support" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "combine" version = "4.6.7" @@ -1342,6 +1681,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b13ea120a812beba79e34316b3942a857c86ec1593cb34f27bb28272ce2cca" +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + [[package]] name = "const_panic" version = "0.2.9" @@ -1379,6 +1738,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1392,7 +1761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "core-graphics-types", "foreign-types", "libc", @@ -1405,7 +1774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "libc", ] @@ -1481,6 +1850,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "ctrlc" +version = "3.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +dependencies = [ + "nix", + "windows-sys 0.59.0", +] + [[package]] name = "cursor-icon" version = "1.1.0" @@ -1488,14 +1867,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" [[package]] -name = "d3d12" -version = "0.20.0" +name = "darling" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28bfe653d79bd16c77f659305b195b82bb5ce0c0eb2a4846b82ddbd77586813" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "bitflags 2.6.0", - "libloading 0.8.5", - "winapi", + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn", ] [[package]] @@ -1504,19 +1906,57 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + [[package]] name = "dispatch" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "disqualified" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9c272297e804878a2a4b707cfcfc6d2328b5bb936944613b4fdf2b9269afdfd" + [[package]] name = "dlib" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.5", + "libloading", ] [[package]] @@ -1540,17 +1980,70 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" +[[package]] +name = "duplicate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97af9b5f014e228b33e77d75ee0e6e87960124f0f4b16337b586a6bec91867b1" +dependencies = [ + "heck", + "proc-macro2", + "proc-macro2-diagnostics", +] + +[[package]] +name = "ecolor" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775cfde491852059e386c4e1deb4aef381c617dc364184c6f6afee99b87c402b" +dependencies = [ + "bytemuck", + "emath", +] + +[[package]] +name = "egui" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53eafabcce0cb2325a59a98736efe0bf060585b437763f8c476957fb274bb974" +dependencies = [ + "ahash", + "emath", + "epaint", + "nohash-hasher", +] + +[[package]] +name = "egui_dock" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fe4e3414481dea5ed59fdfa88f2e00b6ea60fbe758ca7a8636d0dbed93ab9cf" +dependencies = [ + "duplicate", + "egui", + "paste", +] + [[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "emath" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1fe0049ce51d0fb414d029e668dd72eb30bc2b739bf34296ed97bd33df544f3" +dependencies = [ + "bytemuck", +] + [[package]] name = "encase" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9299a95fa5671ddf29ecc22b00e121843a65cb9ff24911e394b4ae556baf36" +checksum = "b0a05902cf601ed11d564128448097b98ebe3c6574bd7b6a653a3d56d54aa020" dependencies = [ "const_panic", "encase_derive", @@ -1560,22 +2053,22 @@ dependencies = [ [[package]] name = "encase_derive" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e09decb3beb1fe2db6940f598957b2e1f7df6206a804d438ff6cb2a9cddc10" +checksum = "181d475b694e2dd56ae919ce7699d344d1fd259292d590c723a50d1189a2ea85" dependencies = [ "encase_derive_impl", ] [[package]] name = "encase_derive_impl" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd31dbbd9743684d339f907a87fe212cb7b51d75b9e8e74181fe363199ee9b47" +checksum = "f97b51c5cc57ef7c5f7a0c57c250251c49ee4c28f819f87ac32f4aceabc36792" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -1584,6 +2077,61 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "enum_dispatch" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "enumset" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "epaint" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a32af8da821bd4f43f2c137e295459ee2e1661d87ca8779dfa0eaf45d870e20f" +dependencies = [ + "ab_glyph", + "ahash", + "bytemuck", + "ecolor", + "emath", + "epaint_default_fonts", + "nohash-hasher", + "parking_lot", +] + +[[package]] +name = "epaint_default_fonts" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "483440db0b7993cf77a20314f08311dbe95675092405518c0677aa08c151a3ea" + [[package]] name = "equivalent" version = "1.0.1" @@ -1714,6 +2262,18 @@ dependencies = [ "spin", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "font-types" version = "0.6.0" @@ -1764,7 +2324,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -1773,6 +2333,24 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +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.30" @@ -1798,6 +2376,15 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "fuzzy-matcher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" +dependencies = [ + "thread_local", +] + [[package]] name = "gethostname" version = "0.4.3" @@ -1844,20 +2431,27 @@ dependencies = [ [[package]] name = "glam" -version = "0.27.0" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9" +checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" dependencies = [ "bytemuck", + "mint", "rand", "serde", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "glow" -version = "0.13.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483" dependencies = [ "js-sys", "slotmap", @@ -1867,24 +2461,13 @@ dependencies = [ [[package]] name = "glutin_wgl_sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" dependencies = [ "gl_generator", ] -[[package]] -name = "glyph_brush_layout" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1e288bfd2f6c0313f78bf5aa538356ad481a3bb97e9b7f93220ab0066c5992" -dependencies = [ - "ab_glyph", - "approx", - "xi-unicode", -] - [[package]] name = "gpu-alloc" version = "0.6.0" @@ -1905,117 +2488,264 @@ dependencies = [ ] [[package]] -name = "gpu-allocator" -version = "0.25.0" +name = "gpu-allocator" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +dependencies = [ + "log", + "presser", + "thiserror", + "windows", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" +dependencies = [ + "bitflags 2.6.0", + "gpu-descriptor-types", + "hashbrown 0.14.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "grid" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be136d9dacc2a13cc70bb6c8f902b414fb2641f8db1314637c6b7933411a8f82" + +[[package]] +name = "guillotiere" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782" +dependencies = [ + "euclid", + "svg_fmt", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hexasphere" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "741ab88b8cc670443da777c3daab02cebf5a3caccfc04e3c052f55c94d1643fe" +dependencies = [ + "constgebra", + "glam", +] + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "log", - "presser", - "thiserror", - "winapi", - "windows 0.52.0", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "gpu-descriptor" -version = "0.3.0" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ - "bitflags 2.6.0", - "gpu-descriptor-types", - "hashbrown", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "gpu-descriptor-types" -version = "0.2.0" +name = "icu_locid_transform" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ - "bitflags 2.6.0", + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "grid" -version = "0.14.0" +name = "icu_locid_transform_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be136d9dacc2a13cc70bb6c8f902b414fb2641f8db1314637c6b7933411a8f82" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] -name = "guillotiere" -version = "0.6.2" +name = "icu_normalizer" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ - "euclid", - "svg_fmt", + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", ] [[package]] -name = "half" -version = "2.4.1" +name = "icu_normalizer_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" -dependencies = [ - "cfg-if", - "crunchy", -] +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" [[package]] -name = "hashbrown" -version = "0.14.5" +name = "icu_properties" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ - "ahash", - "allocator-api2", - "serde", + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "hassle-rs" -version = "0.11.0" +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ - "bitflags 2.6.0", - "com", - "libc", - "libloading 0.8.5", - "thiserror", - "widestring", - "winapi", + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "heck" -version = "0.5.0" +name = "icu_provider_macros" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "hermit-abi" -version = "0.4.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "hexasphere" -version = "12.0.0" +name = "idna" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd6b038160f086b0a7496edae34169ae22f328793cbe2b627a5a3d8373748ec" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "constgebra", - "glam", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "hexf-parse" -version = "0.2.1" +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] [[package]] name = "image" @@ -2058,9 +2788,9 @@ checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" [[package]] name = "immutable-chunkmap" -version = "2.0.5" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4419f022e55cc63d5bbd6b44b71e1d226b9c9480a47824c706e9d54e5c40c5eb" +checksum = "12f97096f508d54f8f8ab8957862eee2ccd628847b6217af1a335e1c44dee578" dependencies = [ "arrayvec", ] @@ -2072,7 +2802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -2095,7 +2825,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -2107,6 +2837,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "jni" version = "0.21.1" @@ -2146,10 +2885,11 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -2160,7 +2900,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" dependencies = [ "libc", - "libloading 0.8.5", + "libloading", "pkg-config", ] @@ -2182,6 +2922,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" +[[package]] +name = "lexopt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baff4b617f7df3d896f97fe922b64817f6cd9a756bb81d40f8883f2f66dcb401" + [[package]] name = "libc" version = "0.2.158" @@ -2199,16 +2945,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - [[package]] name = "libloading" version = "0.8.5" @@ -2248,6 +2984,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "litrs" version = "0.4.1" @@ -2323,9 +3065,9 @@ dependencies = [ [[package]] name = "metal" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5637e166ea14be6063a3f8ba5ccb9a4159df7d8f6d61c02fc3d480b1f90dcfcb" +checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" dependencies = [ "bitflags 2.6.0", "block", @@ -2361,20 +3103,26 @@ dependencies = [ "adler2", ] +[[package]] +name = "mint" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e53debba6bda7a793e5f99b8dacf19e626084f525f7829104ba9898f367d85ff" + [[package]] name = "naga" -version = "0.20.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e536ae46fcab0876853bd4a632ede5df4b1c2527a58f6c5a4150fe86be858231" +checksum = "3d5941e45a15b53aad4375eedf02033adb7a28931eedc31117faffa52e6a857e" dependencies = [ "arrayvec", - "bit-set", + "bit-set 0.8.0", "bitflags 2.6.0", + "cfg_aliases 0.1.1", "codespan-reporting", "hexf-parse", "indexmap", "log", - "num-traits", "pp-rs", "rustc-hash", "spirv", @@ -2385,11 +3133,11 @@ dependencies = [ [[package]] name = "naga_oil" -version = "0.14.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "275d9720a7338eedac966141089232514c84d76a246a58ef501af88c5edf402f" +checksum = "31ea1f080bb359927cd5404d0af1e5e6758f4f2d82ecfbebb0a0c434764e40f1" dependencies = [ - "bit-set", + "bit-set 0.5.3", "codespan-reporting", "data-encoding", "indexmap", @@ -2448,6 +3196,24 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + [[package]] name = "nom" version = "7.1.3" @@ -2470,6 +3236,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" +[[package]] +name = "normpath" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2498,7 +3273,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -2528,6 +3303,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2548,7 +3324,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -2763,11 +3539,32 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "offset-allocator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e234d535da3521eb95106f40f0b73483d80bfb3aacf27c40d7e2b72f1a3e00a2" +dependencies = [ + "log", + "nonmax", +] + [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "opener" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788" +dependencies = [ + "bstr", + "normpath", + "winapi", +] [[package]] name = "orbclient" @@ -2786,11 +3583,11 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owned_ttf_parser" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" dependencies = [ - "ttf-parser 0.24.1", + "ttf-parser 0.25.1", ] [[package]] @@ -2861,7 +3658,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -2939,6 +3736,22 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" +[[package]] +name = "pretty-type-name" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f73cdaf19b52e6143685c3606206e114a4dfa969d6b14ec3894c88eb38bd4b" + +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro-crate" version = "3.1.0" @@ -2950,13 +3763,26 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", +] + [[package]] name = "profiling" version = "1.0.15" @@ -2973,7 +3799,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" dependencies = [ "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -2991,6 +3817,15 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" +[[package]] +name = "quick-xml" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.37" @@ -3036,6 +3871,16 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_distr" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" +dependencies = [ + "num-traits", + "rand", +] + [[package]] name = "range-alloc" version = "0.1.3" @@ -3062,7 +3907,7 @@ dependencies = [ "built", "cfg-if", "interpolate_name", - "itertools", + "itertools 0.12.1", "libc", "libfuzzer-sys", "log", @@ -3279,12 +4124,31 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sctk-adwaita" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] + [[package]] name = "self_cell" version = "1.0.4" @@ -3314,7 +4178,7 @@ checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] @@ -3396,6 +4260,31 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.6.0", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix", + "thiserror", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + [[package]] name = "smol_str" version = "0.2.2" @@ -3423,12 +4312,30 @@ dependencies = [ "bitflags 2.6.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stackfuture" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eae92052b72ef70dafa16eddbabffc77e5ca3574be2f7bc1127b36f0a7ad7f2" + [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" + [[package]] name = "svg_fmt" version = "0.4.3" @@ -3448,9 +4355,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.109" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -3458,14 +4365,14 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.76" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn", ] [[package]] @@ -3519,44 +4426,88 @@ dependencies = [ ] [[package]] -name = "thiserror" -version = "1.0.63" +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[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-keccak" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ - "thiserror-impl", + "crunchy", ] [[package]] -name = "thiserror-impl" -version = "1.0.63" +name = "tiny-skia" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.76", + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path", ] [[package]] -name = "thread_local" -version = "1.1.8" +name = "tiny-skia-path" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" dependencies = [ - "cfg-if", - "once_cell", + "arrayref", + "bytemuck", + "strict-num", ] [[package]] -name = "tiff" -version = "0.9.1" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", + "displaydoc", + "zerovec", ] [[package]] @@ -3621,9 +4572,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -3632,20 +4583,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -3662,6 +4613,21 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-oslog" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528bdd1f0e27b5dd9a4ededf154e824b0532731e4af73bb531de46276e0aab1e" +dependencies = [ + "bindgen", + "cc", + "cfg-if", + "once_cell", + "parking_lot", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "tracing-subscriber" version = "0.3.18" @@ -3691,6 +4657,47 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "transform-gizmo" +version = "0.5.0" +source = "git+https://github.com/ActuallyHappening/transform-gizmo.git#0f6beb350e17a18e3ae008f0d17d665d612bff7e" +dependencies = [ + "ahash", + "ecolor", + "emath", + "enum_dispatch", + "enumset", + "epaint", + "glam", + "mint", +] + +[[package]] +name = "transform-gizmo-bevy" +version = "0.5.0" +source = "git+https://github.com/ActuallyHappening/transform-gizmo.git#0f6beb350e17a18e3ae008f0d17d665d612bff7e" +dependencies = [ + "bevy_app", + "bevy_asset", + "bevy_core", + "bevy_core_pipeline", + "bevy_derive", + "bevy_ecs", + "bevy_image", + "bevy_input", + "bevy_log", + "bevy_math", + "bevy_pbr", + "bevy_reflect", + "bevy_render", + "bevy_transform", + "bevy_utils", + "bevy_window", + "bytemuck", + "transform-gizmo", + "uuid", +] + [[package]] name = "ttf-parser" version = "0.20.0" @@ -3705,9 +4712,9 @@ checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" [[package]] name = "ttf-parser" -version = "0.24.1" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" [[package]] name = "typeid" @@ -3771,9 +4778,32 @@ checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" @@ -3832,9 +4862,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", "once_cell", @@ -3843,24 +4873,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.76", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -3870,9 +4900,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3880,28 +4910,137 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" + +[[package]] +name = "wayland-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" +dependencies = [ + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" +dependencies = [ + "bitflags 2.6.0", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.6.0", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" +dependencies = [ + "rustix", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" dependencies = [ "js-sys", "wasm-bindgen", @@ -3917,6 +5056,24 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea9fe1ebb156110ff855242c1101df158b822487e4957b0556d9ffce9db0f535" +dependencies = [ + "block2", + "core-foundation 0.10.0", + "home", + "jni", + "log", + "ndk-context", + "objc2", + "objc2-foundation", + "url", + "web-sys", +] + [[package]] name = "weezl" version = "0.1.8" @@ -3925,12 +5082,11 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "wgpu" -version = "0.20.1" +version = "23.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e37c7b9921b75dfd26dd973fdcbce36f13dfa6e2dc82aece584e0ed48c355c" +checksum = "80f70000db37c469ea9d67defdc13024ddf9a5f1b89cb2941b812ad7cde1735a" dependencies = [ "arrayvec", - "cfg-if", "cfg_aliases 0.1.1", "document-features", "js-sys", @@ -3951,15 +5107,14 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.21.1" +version = "23.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50819ab545b867d8a454d1d756b90cd5f15da1f2943334ca314af10583c9d39" +checksum = "d63c3c478de8e7e01786479919c8769f62a22eec16788d8c2ac77ce2c132778a" dependencies = [ "arrayvec", - "bit-vec", + "bit-vec 0.8.0", "bitflags 2.6.0", "cfg_aliases 0.1.1", - "codespan-reporting", "document-features", "indexmap", "log", @@ -3971,36 +5126,34 @@ dependencies = [ "rustc-hash", "smallvec", "thiserror", - "web-sys", "wgpu-hal", "wgpu-types", ] [[package]] name = "wgpu-hal" -version = "0.21.1" +version = "23.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172e490a87295564f3fcc0f165798d87386f6231b04d4548bca458cbbfd63222" +checksum = "89364b8a0b211adc7b16aeaf1bd5ad4a919c1154b44c9ce27838213ba05fd821" dependencies = [ "android_system_properties", "arrayvec", "ash", - "bit-set", + "bit-set 0.8.0", "bitflags 2.6.0", "block", + "bytemuck", "cfg_aliases 0.1.1", "core-graphics-types", - "d3d12", "glow", "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hassle-rs", "js-sys", "khronos-egl", "libc", - "libloading 0.8.5", + "libloading", "log", "metal", "naga", @@ -4018,26 +5171,21 @@ dependencies = [ "wasm-bindgen", "web-sys", "wgpu-types", - "winapi", + "windows", + "windows-core", ] [[package]] name = "wgpu-types" -version = "0.20.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1353d9a46bff7f955a680577f34c69122628cc2076e1d6f3a9be6ef00ae793ef" +checksum = "610f6ff27778148c31093f3b03abc4840f9636d58d597ca2f5977433acfe0068" dependencies = [ "bitflags 2.6.0", "js-sys", "web-sys", ] -[[package]] -name = "widestring" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" - [[package]] name = "winapi" version = "0.3.9" @@ -4071,73 +5219,65 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.52.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core 0.52.0", + "windows-core", "windows-targets 0.52.6", ] [[package]] -name = "windows" -version = "0.54.0" +name = "windows-core" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-core 0.54.0", "windows-implement", "windows-interface", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" -dependencies = [ "windows-result", + "windows-strings", "windows-targets 0.52.6", ] [[package]] name = "windows-implement" -version = "0.53.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "windows-interface" -version = "0.53.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", ] [[package]] name = "windows-result" -version = "0.1.2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ + "windows-result", "windows-targets 0.52.6", ] @@ -4361,6 +5501,7 @@ version = "0.30.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0be9e76a1f1077e04a411f0b989cbd3c93339e1771cb41e71ac4aee95bfd2c67" dependencies = [ + "ahash", "android-activity", "atomic-waker", "bitflags 2.6.0", @@ -4369,12 +5510,13 @@ dependencies = [ "calloop", "cfg_aliases 0.2.1", "concurrent-queue", - "core-foundation", + "core-foundation 0.9.4", "core-graphics", "cursor-icon", "dpi", "js-sys", "libc", + "memmap2", "ndk", "objc2", "objc2-app-kit", @@ -4386,11 +5528,17 @@ dependencies = [ "raw-window-handle", "redox_syscall 0.4.1", "rustix", + "sctk-adwaita", + "smithay-client-toolkit", "smol_str", "tracing", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", "web-sys", "web-time", "windows-sys 0.52.0", @@ -4417,6 +5565,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "x11-dl" version = "2.21.0" @@ -4437,7 +5597,7 @@ dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", - "libloading 0.8.5", + "libloading", "once_cell", "rustix", "x11rb-protocol", @@ -4450,10 +5610,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" [[package]] -name = "xi-unicode" -version = "0.3.0" +name = "xcursor" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" +checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" [[package]] name = "xkbcommon-dl" @@ -4480,12 +5640,42 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yazi" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1" +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + [[package]] name = "zeno" version = "0.2.3" @@ -4510,7 +5700,50 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.76", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e06542aa2b6d636ba959ebe93a13a0d07eacd369..7c8781687b5239d0a80cd5dcd25446ce3ab24ae8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_cosmic_edit" -version = "0.25.0" +version = "0.26.0" edition = "2021" license = "MIT OR Apache-2.0" description = "Bevy cosmic-text multiline text input" @@ -11,15 +11,14 @@ keywords = ["bevy"] exclude = ["assets/*"] [features] -## Enable to avoid panicing when multiple cameras are used in the same world +## Enable to avoid panicing when multiple cameras are used in the same world. ## Requires you to add `CosmicPrimaryCamera` marker component to the primary camera multicam = [] -webgpu = ["bevy/webgpu"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bevy = { version = "0.14", default-features = false, features = [ +bevy = { version = "0.15", default-features = false, features = [ "bevy_asset", "bevy_core_pipeline", "bevy_render", @@ -28,14 +27,13 @@ bevy = { version = "0.14", default-features = false, features = [ "bevy_text", "bevy_ui", "bevy_winit", + "bevy_window", "png", "x11", "webgl2", ] } -cosmic-text = { version = "0.12.0" } -# TODO: move crossbeam to wasm32, once input.rs has separate wasm copy/paste fn unicode-segmentation = { version = "1.11.0" } - +# TODO: move crossbeam to wasm32, once input.rs has separate wasm copy/paste fn crossbeam-channel = "0.5.8" image = "0.25.1" sys-locale = "0.3.0" @@ -56,3 +54,10 @@ web-sys = { version = "0.3.70", features = [ [dev-dependencies] insta = "1.29.0" +bevy_editor_pls = "0.11.0" + +[patch.crates-io] +# remove once https://github.com/jakobhellermann/bevy_editor_pls/pull/118 lands and is published +bevy_editor_pls = { git = "https://github.com/ActuallyHappening/bevy_editor_pls.git" } +# remove once https://github.com/urholaukkarinen/transform-gizmo/pull/85 lands and is published +transform-gizmo-bevy = { git = "https://github.com/ActuallyHappening/transform-gizmo.git" } diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000000000000000000000000000000000000..8da1fe230c4ad7cd6a07bb175ec9dfd152140f4b --- /dev/null +++ b/TODO.md @@ -0,0 +1,5 @@ +Migrate to using bevy builtin CosmicFontSystem resource and CosmicBuffer component +Maintain invariant of FocusedWidget using observers, and add events for focus change + +Fix bug where clicking on a UiNode changes the editor from looking 'squished' to looking normal. +Add an xcode subcommand to run a simulated CI run for cargo fmt and lint checking diff --git a/examples/basic_sprite.rs b/examples/basic_sprite.rs index 818f24d13b0a013998933bc80504898adefd6b31..99594ba0cf265a5aa8cddfa27c5e24db7f98f6ae 100644 --- a/examples/basic_sprite.rs +++ b/examples/basic_sprite.rs @@ -1,7 +1,7 @@ use bevy::{prelude::*, window::PrimaryWindow}; use bevy_cosmic_edit::{ cosmic_text::{Attrs, Family, Metrics}, - *, + prelude::*, }; fn setup( @@ -10,34 +10,34 @@ fn setup( mut font_system: ResMut<CosmicFontSystem>, ) { let primary_window = windows.single(); - let camera_bundle = Camera2dBundle { - camera: Camera { + let camera_bundle = ( + Camera2d, + CosmicPrimaryCamera, + Camera { clear_color: ClearColorConfig::Custom(Color::WHITE), ..default() }, - ..default() - }; + ); commands.spawn(camera_bundle); let mut attrs = Attrs::new(); attrs = attrs.family(Family::Name("Victor Mono")); attrs = attrs.color(CosmicColor::rgb(0x94, 0x00, 0xD3)); - let cosmic_edit = (CosmicEditBundle { - buffer: CosmicBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text( + let cosmic_edit = ( + CosmicEditBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text( &mut font_system, "😀😀😀 x => y", attrs, ), - sprite_bundle: SpriteBundle { - sprite: Sprite { - custom_size: Some(Vec2::new(primary_window.width(), primary_window.height())), - ..default() - }, + TextEdit2d, + Sprite { + // You must specify custom size + // so the editor knows what size images to render to the sprite + custom_size: Some(Vec2::new(primary_window.width(), primary_window.height())), ..default() }, - ..default() - },); + ); let cosmic_edit = commands.spawn(cosmic_edit).id(); @@ -54,10 +54,8 @@ fn main() { App::new() .add_plugins(DefaultPlugins) - .add_plugins(CosmicEditPlugin { - font_config, - ..default() - }) + .add_plugins(bevy_editor_pls::EditorPlugin::default()) + .add_plugins(CosmicEditPlugin { font_config }) .add_systems(Startup, setup) .add_systems( Update, diff --git a/examples/basic_ui.rs b/examples/basic_ui.rs index 7a6dffa195e1574b600642bd9b0b21204fb3f0ab..ccb46256b6b5d82623a6f5928d12f57ad016bb77 100644 --- a/examples/basic_ui.rs +++ b/examples/basic_ui.rs @@ -1,17 +1,17 @@ use bevy::prelude::*; use bevy_cosmic_edit::{ cosmic_text::{Attrs, Family, Metrics}, - *, + prelude::*, }; fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { - let camera_bundle = Camera2dBundle { - camera: Camera { + let camera_bundle = ( + Camera2d, + Camera { clear_color: ClearColorConfig::Custom(bevy::color::palettes::css::PINK.into()), ..default() }, - ..default() - }; + ); commands.spawn(camera_bundle); let mut attrs = Attrs::new(); @@ -19,33 +19,20 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { attrs = attrs.color(CosmicColor::rgb(0x94, 0x00, 0xD3)); let cosmic_edit = commands - .spawn((CosmicEditBundle { - buffer: CosmicBuffer::new(&mut font_system, Metrics::new(20., 20.)).with_rich_text( + .spawn(( + TextEdit, + CosmicEditBuffer::new(&mut font_system, Metrics::new(20., 20.)).with_rich_text( &mut font_system, vec![("Banana", attrs)], attrs, ), - ..default() - },)) - .id(); - - commands - .spawn( - // Use buttonbundle for layout - // Includes Interaction and UiImage which are used by the plugin. - ButtonBundle { - style: Style { - width: Val::Percent(100.), - height: Val::Percent(100.), - ..default() - }, + Node { + width: Val::Percent(100.), + height: Val::Percent(100.), ..default() }, - ) - // point editor at this entity. - // Plugin looks for UiImage and sets it's - // texture to the editor's rendered image - .insert(CosmicSource(cosmic_edit)); + )) + .id(); commands.insert_resource(FocusedWidget(Some(cosmic_edit))); } @@ -60,10 +47,7 @@ fn main() { App::new() .add_plugins(DefaultPlugins) - .add_plugins(CosmicEditPlugin { - font_config, - ..default() - }) + .add_plugins(CosmicEditPlugin { font_config }) .add_systems(Startup, setup) .add_systems( Update, diff --git a/examples/bevy_editor_pls.rs b/examples/bevy_editor_pls.rs new file mode 100644 index 0000000000000000000000000000000000000000..5f8f5737994ee72045ca7da660773b80b916eb0d --- /dev/null +++ b/examples/bevy_editor_pls.rs @@ -0,0 +1,73 @@ +//! With [bevy_editor_pls] integration +//! Requires `multicam` features enabled + +use bevy::prelude::*; +use bevy_cosmic_edit::{ + cosmic_text::{Attrs, Family, Metrics}, + prelude::*, +}; + +fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { + let camera_bundle = ( + Camera2d, + // marker from bevy_cosmic_edit + bevy_cosmic_edit::CosmicPrimaryCamera, + // marker from bevy + // required else for some reason no UI renders to the screen + bevy::prelude::IsDefaultUiCamera, + Camera { + clear_color: ClearColorConfig::Custom(bevy::color::palettes::css::PINK.into()), + ..default() + }, + ); + commands.spawn(camera_bundle); + + let mut attrs = Attrs::new(); + attrs = attrs.family(Family::Name("Victor Mono")); + attrs = attrs.color(CosmicColor::rgb(0x94, 0x00, 0xD3)); + + let cosmic_edit = commands + .spawn(( + TextEdit, + CosmicEditBuffer::new(&mut font_system, Metrics::new(40., 40.)).with_rich_text( + &mut font_system, + vec![("Banana", attrs)], + attrs, + ), + Node { + width: Val::Percent(60.), + height: Val::Percent(60.), + top: Val::Percent(10.), + left: Val::Percent(30.), + ..default() + }, + )) + .id(); + + commands.insert_resource(FocusedWidget(Some(cosmic_edit))); +} + +fn main() { + let font_bytes: &[u8] = include_bytes!("../assets/fonts/VictorMono-Regular.ttf"); + let font_config = CosmicFontConfig { + fonts_dir_path: None, + font_bytes: Some(vec![font_bytes]), + load_system_fonts: true, + }; + + App::new() + .add_plugins(DefaultPlugins) + .add_plugins(CosmicEditPlugin { font_config }) + // add editor plugin + .add_plugins(bevy_editor_pls::EditorPlugin::default()) + .add_systems(Startup, setup) + .add_systems( + Update, + ( + print_editor_text, + change_active_editor_ui, + deselect_editor_on_esc, + ), + ) + .run(); +} diff --git a/examples/every_option.rs b/examples/every_option.rs index 1104db37bcbcc59d6d95184c44b310aa889ec76e..8f88213ad6833c2ce936b5406083af895d3290af 100644 --- a/examples/every_option.rs +++ b/examples/every_option.rs @@ -1,59 +1,46 @@ -use bevy::prelude::*; +use bevy::{prelude::*, window::SystemCursorIcon, winit::cursor::CursorIcon}; use bevy_cosmic_edit::{ cosmic_text::{Attrs, AttrsOwned, Metrics}, - *, + prelude::*, + CosmicBackgroundColor, CosmicBackgroundImage, CosmicTextAlign, CosmicWrap, CursorColor, + DefaultAttrs, HoverCursor, MaxChars, MaxLines, SelectedTextColor, SelectionColor, }; #[derive(Resource)] struct TextChangeTimer(pub Timer); fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { - commands.spawn(Camera2dBundle::default()); + commands.spawn(Camera2d); let attrs = Attrs::new().color(Color::srgb(0.27, 0.27, 0.27).to_cosmic()); - let editor = commands - .spawn(CosmicEditBundle { - buffer: CosmicBuffer::new(&mut font_system, Metrics::new(16., 16.)).with_text( + commands.spawn(( + ( + // cosmic edit components + CosmicEditBuffer::new(&mut font_system, Metrics::new(16., 16.)).with_text( &mut font_system, "Begin counting.", attrs, ), - cursor_color: CursorColor(bevy::color::palettes::css::LIME.into()), - selection_color: SelectionColor(bevy::color::palettes::css::DEEP_PINK.into()), - fill_color: CosmicBackgroundColor(bevy::color::palettes::css::YELLOW_GREEN.into()), - x_offset: XOffset::default(), - text_position: CosmicTextAlign::default(), - background_image: CosmicBackgroundImage::default(), - default_attrs: DefaultAttrs(AttrsOwned::new(attrs)), - max_chars: MaxChars(15), - max_lines: MaxLines(1), - mode: CosmicWrap::Wrap, - hover_cursor: HoverCursor(CursorIcon::Pointer), - // CosmicEdit draws to this spritebundle - sprite_bundle: SpriteBundle { - sprite: Sprite { - // when using another target like a UI element, this is overridden - custom_size: Some(Vec2::ONE * 128.0), - ..default() - }, - // this is the default behaviour for targeting UI elements. - // If wanting a sprite, define your own SpriteBundle and - // leave the visibility on. See examples/basic_sprite.rs - visibility: Visibility::Hidden, - ..default() - }, - // Computed fields - padding: Default::default(), - widget_size: Default::default(), - }) - .insert(SelectedTextColor(Color::WHITE)) - .id(); - - commands - .spawn(ButtonBundle { - border_color: bevy::color::palettes::css::LIMEGREEN.into(), - style: Style { + CursorColor(bevy::color::palettes::css::LIME.into()), + SelectionColor(bevy::color::palettes::css::DEEP_PINK.into()), + CosmicBackgroundColor(bevy::color::palettes::css::YELLOW_GREEN.into()), + CosmicTextAlign::Center { padding: 0 }, + CosmicBackgroundImage(None), + DefaultAttrs(AttrsOwned::new(attrs)), + MaxChars(15), + MaxLines(1), + CosmicWrap::Wrap, + HoverCursor(CursorIcon::System(SystemCursorIcon::Pointer)), + SelectedTextColor(Color::WHITE), + ), + ( + TextEdit, + // the image mode is optional, but due to bevy 0.15 mechanics is required to + // render the border within the `ImageNode` + // See bevy issue https://github.com/bevyengine/bevy/issues/16643#issuecomment-2518163688 + ImageNode::default().with_mode(bevy::ui::widget::NodeImageMode::Stretch), + Node { // Size and position of text box border: UiRect::all(Val::Px(4.)), width: Val::Percent(20.), @@ -62,10 +49,12 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { top: Val::Px(100.), ..default() }, - background_color: Color::WHITE.into(), - ..default() - }) - .insert(CosmicSource(editor)); + BorderColor(bevy::color::palettes::css::LIMEGREEN.into()), + BorderRadius::all(Val::Px(10.)), + // This is overriden by setting `CosmicBackgroundColor` so you don't see any white + BackgroundColor(Color::WHITE), + ), + )); commands.insert_resource(TextChangeTimer(Timer::from_seconds( 1., @@ -77,7 +66,7 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { fn text_swapper( mut timer: ResMut<TextChangeTimer>, time: Res<Time>, - mut cosmic_q: Query<(&mut CosmicBuffer, &DefaultAttrs)>, + mut cosmic_q: Query<(&mut CosmicEditBuffer, &DefaultAttrs)>, mut count: Local<usize>, mut font_system: ResMut<CosmicFontSystem>, ) { diff --git a/examples/font_per_widget.rs b/examples/font_per_widget.rs index 22856026f09565d5668acc255653242b23faef0c..caf65fda347313b57d7bb24708615a920c25c938 100644 --- a/examples/font_per_widget.rs +++ b/examples/font_per_widget.rs @@ -3,19 +3,16 @@ use bevy::prelude::*; use bevy_cosmic_edit::{ cosmic_text::{Attrs, Family, Metrics}, - *, + prelude::*, }; fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { - commands.spawn(Camera2dBundle::default()); + commands.spawn(Camera2d); let root = commands - .spawn(NodeBundle { - style: bevy::prelude::Style { - position_type: PositionType::Absolute, - width: Val::Percent(100.), - height: Val::Percent(100.), - ..default() - }, + .spawn(Node { + position_type: PositionType::Absolute, + width: Val::Percent(100.), + height: Val::Percent(100.), ..default() }) .id(); @@ -159,57 +156,42 @@ fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { ), ]; - let cosmic_edit_1 = commands - .spawn(CosmicEditBundle { - buffer: CosmicBuffer::new(&mut font_system, Metrics::new(18., 22.)).with_rich_text( + commands.entity(root).with_children(|parent| { + parent.spawn(( + CosmicEditBuffer::new(&mut font_system, Metrics::new(18., 22.)).with_rich_text( &mut font_system, lines, attrs, ), - ..default() - }) - .id(); + TextEdit, + Node { + width: Val::Percent(50.), + height: Val::Percent(100.), + ..default() + }, + BackgroundColor(Color::WHITE), + )); + }); let mut attrs_2 = Attrs::new(); attrs_2 = attrs_2.family(Family::Name("Times New Roman")); attrs_2.color_opt = Some(bevy::color::palettes::css::PURPLE.to_cosmic()); - - let cosmic_edit_2 = commands - .spawn(CosmicEditBundle { - buffer: CosmicBuffer::new(&mut font_system, Metrics::new(28., 36.)).with_text( + commands.entity(root).with_children(|parent| { + parent.spawn(( + CosmicEditBuffer::new(&mut font_system, Metrics::new(28., 36.)).with_text( &mut font_system, "Widget 2.\nClick on me =>", attrs_2, ), - ..default() - }) - .id(); - - // Spawn the CosmicEditUiBundles as children of root - commands.entity(root).with_children(|parent| { - parent - .spawn(ButtonBundle { - style: Style { - width: Val::Percent(50.), - height: Val::Percent(100.), - ..default() - }, - background_color: BackgroundColor(Color::WHITE), - ..default() - }) - .insert(CosmicSource(cosmic_edit_1)); - - parent - .spawn(ButtonBundle { - background_color: BackgroundColor(bevy::prelude::Color::WHITE.with_alpha(0.8)), - style: Style { - width: Val::Percent(50.), - height: Val::Percent(100.), - ..default() - }, + ImageNode::default(), + Button, + Node { + width: Val::Percent(50.), + height: Val::Percent(100.), ..default() - }) - .insert(CosmicSource(cosmic_edit_2)); + }, + BackgroundColor(Color::WHITE.with_alpha(0.8)), + )); }); } diff --git a/examples/image_background.rs b/examples/image_background.rs index 7df8a51f358f9ab4445676be3c358af8dedfaa1b..19ab10bd891352fe6efef2eddbe787c3417809fd 100644 --- a/examples/image_background.rs +++ b/examples/image_background.rs @@ -1,37 +1,31 @@ use bevy::prelude::*; use bevy_cosmic_edit::{ cosmic_text::{Attrs, AttrsOwned}, - *, + prelude::*, + CosmicBackgroundImage, }; fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { - commands.spawn(Camera2dBundle::default()); + commands.spawn(Camera2d); let bg_image_handle = asset_server.load("img/bevy_logo_light.png"); - let editor = commands - .spawn(CosmicEditBundle { - default_attrs: DefaultAttrs(AttrsOwned::new( - Attrs::new().color(bevy::color::palettes::basic::LIME.to_cosmic()), - )), - background_image: CosmicBackgroundImage(Some(bg_image_handle)), + commands.spawn(( + TextEdit, + CosmicEditBuffer::default(), + DefaultAttrs(AttrsOwned::new( + Attrs::new().color(bevy::color::palettes::basic::LIME.to_cosmic()), + )), + CosmicBackgroundImage(Some(bg_image_handle)), + Node { + // Size and position of text box + width: Val::Px(300.), + height: Val::Px(50.), + left: Val::Px(100.), + top: Val::Px(100.), ..default() - }) - .id(); - - commands - .spawn(ButtonBundle { - style: Style { - // Size and position of text box - width: Val::Px(300.), - height: Val::Px(50.), - left: Val::Px(100.), - top: Val::Px(100.), - ..default() - }, - ..default() - }) - .insert(CosmicSource(editor)); + }, + )); } fn main() { diff --git a/examples/multiple_sprites.rs b/examples/multiple_sprites.rs index 714b9430c514ef7cf61ef9e061d7305c113ba8b4..e787e3c15f41197b35ebd156aabaec18e6140d52 100644 --- a/examples/multiple_sprites.rs +++ b/examples/multiple_sprites.rs @@ -1,7 +1,8 @@ use bevy::{prelude::*, window::PrimaryWindow}; use bevy_cosmic_edit::{ cosmic_text::{Attrs, Family, Metrics}, - *, + prelude::*, + CosmicBackgroundColor, }; fn setup( @@ -10,66 +11,57 @@ fn setup( mut font_system: ResMut<CosmicFontSystem>, ) { let primary_window = windows.single(); - let camera_bundle = Camera2dBundle { - camera: Camera { + let camera_bundle = ( + Camera2d, + Camera { clear_color: ClearColorConfig::Custom(Color::WHITE), ..default() }, - ..default() - }; + ); commands.spawn(camera_bundle); let mut attrs = Attrs::new(); attrs = attrs.family(Family::Name("Victor Mono")); attrs = attrs.color(bevy::color::palettes::basic::PURPLE.to_cosmic()); - commands.spawn(CosmicEditBundle { - fill_color: CosmicBackgroundColor(bevy::color::palettes::css::ALICE_BLUE.into()), - buffer: CosmicBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text( + commands.spawn(( + TextEdit2d, + CosmicEditBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text( &mut font_system, "😀😀😀 x => y", attrs, ), - sprite_bundle: SpriteBundle { - sprite: Sprite { - custom_size: Some(Vec2 { - x: primary_window.width() / 2., - y: primary_window.height(), - }), - ..default() - }, - transform: Transform::from_translation(Vec3::new(-primary_window.width() / 4., 0., 1.)), + CosmicBackgroundColor(bevy::color::palettes::css::ALICE_BLUE.into()), + Sprite { + custom_size: Some(Vec2 { + x: primary_window.width() / 2., + y: primary_window.height(), + }), ..default() }, - ..default() - }); + Transform::from_translation(Vec3::new(-primary_window.width() / 4., 0., 1.)), + )); - commands.spawn(CosmicEditBundle { - fill_color: CosmicBackgroundColor( - bevy::color::palettes::basic::GRAY.with_alpha(0.5).into(), - ), - buffer: CosmicBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text( + commands.spawn(( + CosmicEditBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text( &mut font_system, "Widget_2. Click on me", attrs, ), - sprite_bundle: SpriteBundle { - sprite: Sprite { - custom_size: Some(Vec2 { - x: primary_window.width() / 2., - y: primary_window.height() / 2., - }), - ..default() - }, - transform: Transform::from_translation(Vec3::new( - primary_window.width() / 4., - -primary_window.height() / 4., - 1., - )), + CosmicBackgroundColor(bevy::color::palettes::basic::GRAY.with_alpha(0.5).into()), + Sprite { + custom_size: Some(Vec2 { + x: primary_window.width() / 2., + y: primary_window.height() / 2., + }), ..default() }, - ..default() - }); + Transform::from_translation(Vec3::new( + primary_window.width() / 4., + -primary_window.height() / 4., + 1., + )), + )); } fn main() { @@ -82,10 +74,7 @@ fn main() { App::new() .add_plugins(DefaultPlugins) - .add_plugins(CosmicEditPlugin { - font_config, - ..default() - }) + .add_plugins(CosmicEditPlugin { font_config }) .add_systems(Startup, setup) .add_systems(Update, change_active_editor_sprite) .run(); diff --git a/examples/password.rs b/examples/password.rs index d9655cc19fc95efda1674b129594e45c2c186386..e13af7ecbabe0d8ea0a68a533f0d39ca207a5880 100644 --- a/examples/password.rs +++ b/examples/password.rs @@ -1,26 +1,24 @@ use bevy::prelude::*; -use bevy_cosmic_edit::{cosmic_text::Attrs, *}; +use bevy_cosmic_edit::{ + cosmic_text::Attrs, prelude::*, CosmicWrap, InputSet, MaxLines, Password, Placeholder, +}; fn setup(mut commands: Commands) { - commands.spawn(Camera2dBundle::default()); + commands.spawn(Camera2d); // Sprite editor commands.spawn(( - CosmicEditBundle { - max_lines: MaxLines(1), - mode: CosmicWrap::InfiniteLine, - sprite_bundle: SpriteBundle { - // Sets size of text box - sprite: Sprite { - custom_size: Some(Vec2::new(300., 100.)), - ..default() - }, - // Position of text box - transform: Transform::from_xyz(0., 100., 0.), - ..default() - }, + TextEdit2d, + CosmicEditBuffer::default(), + MaxLines(1), + CosmicWrap::InfiniteLine, + // Sets size of text box + Sprite { + custom_size: Some(Vec2::new(300., 100.)), ..default() }, + // Position of text box + Transform::from_xyz(0., 100., 0.), Password::default(), Placeholder::new("Password", Attrs::new()), )); @@ -36,6 +34,7 @@ fn main() { ( change_active_editor_sprite, deselect_editor_on_esc, + // If you don't .after(InputSet) you'll just see the hashed-out safe text print_editor_text.after(InputSet), ), ) diff --git a/examples/placeholder.rs b/examples/placeholder.rs index bf099201adcfdd2e5797cb0d3f0462f962d40071..1a09fbf1e0eb43fe89967005973822988a8593e8 100644 --- a/examples/placeholder.rs +++ b/examples/placeholder.rs @@ -1,55 +1,41 @@ use bevy::prelude::*; use bevy_cosmic_edit::{ cosmic_text::{Attrs, Family, Metrics}, - *, + prelude::*, + Placeholder, }; fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { - let camera_bundle = Camera2dBundle { - camera: Camera { + let camera_bundle = ( + Camera2d, + Camera { clear_color: ClearColorConfig::Custom(bevy::color::palettes::css::PINK.into()), ..default() }, - ..default() - }; + ); commands.spawn(camera_bundle); let mut attrs = Attrs::new(); attrs = attrs.family(Family::Name("Victor Mono")); attrs = attrs.color(CosmicColor::rgb(0x94, 0x00, 0xD3)); - let cosmic_edit = - commands - .spawn(( - CosmicEditBundle { - buffer: CosmicBuffer::new(&mut font_system, Metrics::new(20., 20.)) - .with_rich_text(&mut font_system, vec![("", attrs)], attrs), - ..default() - }, - Placeholder::new( - "Placeholder", - attrs.color(bevy::color::palettes::basic::GRAY.to_cosmic()), - ), - )) - .id(); - - commands - .spawn( - // Use buttonbundle for layout - // Includes Interaction and UiImage which are used by the plugin. - ButtonBundle { - style: Style { - width: Val::Percent(100.), - height: Val::Percent(100.), - ..default() - }, - ..default() - }, - ) - // point editor at this entity. - // Plugin looks for UiImage and sets it's - // texture to the editor's rendered image - .insert(CosmicSource(cosmic_edit)); + commands.spawn(( + TextEdit, + CosmicEditBuffer::new(&mut font_system, Metrics::new(20., 20.)).with_rich_text( + &mut font_system, + vec![("", attrs)], + attrs, + ), + Placeholder::new( + "Placeholder", + attrs.color(bevy::color::palettes::basic::GRAY.to_cosmic()), + ), + Node { + width: Val::Percent(100.), + height: Val::Percent(100.), + ..default() + }, + )); } fn main() { @@ -62,10 +48,7 @@ fn main() { App::new() .add_plugins(DefaultPlugins) - .add_plugins(CosmicEditPlugin { - font_config, - ..default() - }) + .add_plugins(CosmicEditPlugin { font_config }) .add_systems(Startup, setup) .add_systems( Update, diff --git a/examples/readonly.rs b/examples/readonly.rs index 0e42c727705e35fa6dc9e0c45b22c4f7badce755..dd045354f5b47ed486572eb9b356eaaf295fc4e0 100644 --- a/examples/readonly.rs +++ b/examples/readonly.rs @@ -1,55 +1,32 @@ use bevy::prelude::*; use bevy_cosmic_edit::{ cosmic_text::{Attrs, Family, Metrics}, - *, + prelude::*, }; fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { - commands.spawn(Camera2dBundle::default()); - let root = commands - .spawn(NodeBundle { - style: Style { - display: Display::Flex, - width: Val::Percent(100.), - height: Val::Percent(100.), - ..default() - }, - ..default() - }) - .id(); + commands.spawn(Camera2d); let mut attrs = Attrs::new(); attrs = attrs.family(Family::Name("Victor Mono")); attrs = attrs.color(bevy::color::palettes::basic::PURPLE.to_cosmic()); // spawn editor - let cosmic_edit = commands - .spawn(CosmicEditBundle { - buffer: CosmicBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text( - &mut font_system, - "😀😀😀 x => y\nRead only widget", - attrs, - ), + commands.spawn(( + TextEdit, + ReadOnly, + CosmicEditBuffer::new(&mut font_system, Metrics::new(14., 18.)).with_text( + &mut font_system, + "😀😀😀 x => y\nRead only widget", + attrs, + ), + Node { + width: Val::Percent(100.), + height: Val::Percent(100.), ..default() - }) - .insert(ReadOnly) - .id(); - - // Spawn the ButtonBundle as a child of root - commands.entity(root).with_children(|parent| { - parent - .spawn(ButtonBundle { - style: Style { - width: Val::Percent(100.), - height: Val::Percent(100.), - ..default() - }, - background_color: BackgroundColor(Color::WHITE), - ..default() - }) - // add cosmic source - .insert(CosmicSource(cosmic_edit)); - }); + }, + BackgroundColor(Color::WHITE), + )); } fn main() { @@ -62,11 +39,8 @@ fn main() { App::new() .add_plugins(DefaultPlugins) - .add_plugins(CosmicEditPlugin { - font_config, - ..default() - }) + .add_plugins(CosmicEditPlugin { font_config }) .add_systems(Startup, setup) - .add_systems(Update, change_active_editor_ui) + .add_systems(Update, (change_active_editor_ui, deselect_editor_on_esc)) .run(); } diff --git a/examples/sprite_and_ui_clickable.rs b/examples/sprite_and_ui_clickable.rs index 362ce26f68d7ff48c8707811ae0cef8e5d203b9a..4a01b17fe816b3e99a363da7bc8fc401c1765b1f 100644 --- a/examples/sprite_and_ui_clickable.rs +++ b/examples/sprite_and_ui_clickable.rs @@ -1,55 +1,46 @@ use bevy::prelude::*; use bevy_cosmic_edit::{ cosmic_text::{Attrs, AttrsOwned}, - *, + prelude::*, + CosmicTextAlign, CosmicTextChanged, CosmicWrap, MaxLines, TextHoverIn, TextHoverOut, }; fn setup(mut commands: Commands) { - commands.spawn(Camera2dBundle::default()); + commands.spawn(Camera2d); - // UI editor - let ui_editor = commands - .spawn(CosmicEditBundle { - default_attrs: DefaultAttrs(AttrsOwned::new( - Attrs::new().color(bevy::color::palettes::css::LIMEGREEN.to_cosmic()), - )), - max_lines: MaxLines(1), - mode: CosmicWrap::InfiniteLine, - text_position: CosmicTextAlign::Left { padding: 5 }, + // Ui editor + commands.spawn(( + TextEdit, + CosmicEditBuffer::default(), + DefaultAttrs(AttrsOwned::new( + Attrs::new().color(bevy::color::palettes::css::LIMEGREEN.to_cosmic()), + )), + MaxLines(1), + CosmicWrap::InfiniteLine, + CosmicTextAlign::Left { padding: 5 }, + Node { + // Size and position of text box + width: Val::Px(300.), + height: Val::Px(50.), + left: Val::Px(100.), + top: Val::Px(100.), ..default() - }) - .id(); - - commands - .spawn(ButtonBundle { - style: Style { - // Size and position of text box - width: Val::Px(300.), - height: Val::Px(50.), - left: Val::Px(100.), - top: Val::Px(100.), - ..default() - }, - ..default() - }) - .insert(CosmicSource(ui_editor)); + }, + )); // Sprite editor - commands.spawn((CosmicEditBundle { - max_lines: MaxLines(1), - mode: CosmicWrap::InfiniteLine, - sprite_bundle: SpriteBundle { - // Sets size of text box - sprite: Sprite { - custom_size: Some(Vec2::new(300., 100.)), - ..default() - }, - // Position of text box - transform: Transform::from_xyz(0., 100., 0.), + commands.spawn(( + CosmicEditBuffer::default(), + MaxLines(1), + CosmicWrap::InfiniteLine, + // Sets size of text box + Sprite { + custom_size: Some(Vec2::new(300., 100.)), ..default() }, - ..default() - },)); + // Position of text box + Transform::from_xyz(0., 100., 0.), + )); } fn ev_test( diff --git a/readme.md b/readme.md index 4c5c727214407453675be6e856b30cfdb03cfaac..f5be2efe0dd0ccb8b65f9e134c59034ae5d26bf0 100644 --- a/readme.md +++ b/readme.md @@ -29,7 +29,8 @@ RUSTFLAGS=--cfg=web_sys_unstable_apis cargo r --target wasm32-unknown-unknown -- | bevy | bevy_cosmic_edit | | ------ | ---------------- | -| 0.14.0 | 0.21 - latest | +| 0.15.0 | 0.26 - latest | +| 0.14.0 | 0.21 - 0.25 | | 0.13.0 | 0.16 - 0.20 | | 0.12.* | 0.15 | | 0.11.* | 0.8 - 0.14 | diff --git a/src/buffer.rs b/src/buffer.rs index 88ae2276a5a7c15249d812431a98af4681678e4e..5205038abb4dadf033cd7a72291967bfe6115e7c 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -1,15 +1,16 @@ -use crate::*; -use bevy::{ - ecs::component::{ComponentHooks, StorageType}, +use crate::{ + cosmic_edit::{ScrollEnabled, XOffset}, prelude::*, + widget::CosmicPadding, + CosmicBackgroundColor, CosmicBackgroundImage, CosmicTextAlign, CosmicWrap, CursorColor, + HoverCursor, MaxChars, MaxLines, SelectionColor, +}; +use bevy::{ + ecs::{component::ComponentId, query::QueryData, world::DeferredWorld}, window::PrimaryWindow, }; use cosmic_text::{Attrs, AttrsOwned, Buffer, Edit, FontSystem, Metrics, Shaping}; -/// Set of all buffer setup functions. Runs in [`First`] -#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] -pub struct BufferSet; - pub(crate) struct BufferPlugin; impl Plugin for BufferPlugin { @@ -21,7 +22,7 @@ impl Plugin for BufferPlugin { set_initial_scale, set_redraw, set_editor_redraw, - swap_target_handle, + update_internal_target_handles, ) .chain(), ); @@ -40,7 +41,7 @@ impl BufferExtras for Buffer { /// * none, takes the rust magic ref to self /// /// # Returns - /// + ///input /// A [`String`] containing the cosmic text content. fn get_text(&self) -> String { let mut text = String::new(); @@ -59,39 +60,50 @@ impl BufferExtras for Buffer { } /// Component wrapper for [`Buffer`] -#[derive(Deref, DerefMut)] -pub struct CosmicBuffer(pub Buffer); - -impl Component for CosmicBuffer { - const STORAGE_TYPE: StorageType = StorageType::Table; +#[derive(Component, Deref, DerefMut)] +#[component(on_remove = remove_focus_from_entity)] +#[require( + CosmicBackgroundColor, + CursorColor, + SelectionColor, + DefaultAttrs, + CosmicBackgroundImage, + CosmicRenderOutput, + MaxLines, + MaxChars, + XOffset, + CosmicWrap, + CosmicTextAlign, + CosmicPadding, + HoverCursor, + ScrollEnabled +)] +pub struct CosmicEditBuffer(pub Buffer); - fn register_component_hooks(hooks: &mut ComponentHooks) { - hooks.on_remove(|mut world, entity, _| { - if let Some(mut focused_widget) = world.get_resource_mut::<FocusedWidget>() { - if let Some(focused) = focused_widget.0 { - if focused == entity { - focused_widget.0 = None; - } - } +fn remove_focus_from_entity(mut world: DeferredWorld, entity: Entity, _: ComponentId) { + if let Some(mut focused_widget) = world.get_resource_mut::<FocusedWidget>() { + if let Some(focused) = focused_widget.0 { + if focused == entity { + focused_widget.0 = None; } - }); + } } } -impl Default for CosmicBuffer { +impl Default for CosmicEditBuffer { fn default() -> Self { - CosmicBuffer(Buffer::new_empty(Metrics::new(20., 20.))) + CosmicEditBuffer(Buffer::new_empty(Metrics::new(20., 20.))) } } -impl<'s, 'r> CosmicBuffer { +impl<'s, 'r> CosmicEditBuffer { /// Create a new buffer with a font system pub fn new(font_system: &mut FontSystem, metrics: Metrics) -> Self { Self(Buffer::new(font_system, metrics)) } // Das a lotta boilerplate just to hide the shaping argument - /// Add text to a newly created [`CosmicBuffer`] + /// Add text to a newly created [`CosmicEditBuffer`] pub fn with_text( mut self, font_system: &mut FontSystem, @@ -102,7 +114,7 @@ impl<'s, 'r> CosmicBuffer { self } - /// Add rich text to a newly created [`CosmicBuffer`] + /// Add rich text to a newly created [`CosmicEditBuffer`] /// /// Rich text is an iterable of `(&'s str, Attrs<'r>)` pub fn with_rich_text<I>( @@ -190,10 +202,10 @@ impl<'s, 'r> CosmicBuffer { } } -/// Adds a [`FontSystem`] to a newly created [`CosmicBuffer`] if one was not provided -pub fn add_font_system( +/// Adds a [`FontSystem`] to a newly created [`CosmicEditBuffer`] if one was not provided +pub(crate) fn add_font_system( mut font_system: ResMut<CosmicFontSystem>, - mut q: Query<&mut CosmicBuffer, Added<CosmicBuffer>>, + mut q: Query<&mut CosmicEditBuffer, Added<CosmicEditBuffer>>, ) { for mut b in q.iter_mut() { if !b.lines.is_empty() { @@ -204,10 +216,10 @@ pub fn add_font_system( } } -/// Initialises [`CosmicBuffer`] scale factor -pub fn set_initial_scale( +/// Initialises [`CosmicEditBuffer`] scale factor +pub(crate) fn set_initial_scale( window_q: Query<&Window, With<PrimaryWindow>>, - mut cosmic_query: Query<&mut CosmicBuffer, Added<CosmicBuffer>>, + mut cosmic_query: Query<&mut CosmicEditBuffer, Added<CosmicEditBuffer>>, mut font_system: ResMut<CosmicFontSystem>, ) { if let Ok(window) = window_q.get_single() { @@ -220,66 +232,76 @@ pub fn set_initial_scale( } } -/// Initialises new [`CosmicBuffer`] redraw flag to true -pub fn set_redraw(mut q: Query<&mut CosmicBuffer, Added<CosmicBuffer>>) { +/// Initialises new [`CosmicEditBuffer`] redraw flag to true +pub(crate) fn set_redraw(mut q: Query<&mut CosmicEditBuffer, Added<CosmicEditBuffer>>) { for mut b in q.iter_mut() { b.set_redraw(true); } } /// Initialises new [`CosmicEditor`] redraw flag to true -pub fn set_editor_redraw(mut q: Query<&mut CosmicEditor, Added<CosmicEditor>>) { - for mut b in q.iter_mut() { - b.set_redraw(true); +pub(crate) fn set_editor_redraw(mut q: Query<&mut CosmicEditor, Added<CosmicEditor>>) { + for mut ed in q.iter_mut() { + ed.set_redraw(true); } } -/// Sets image of UI elements to the [`CosmicBuffer`] output -pub fn swap_target_handle( - source_q: Query<&Handle<Image>, With<CosmicBuffer>>, - mut dest_q: Query< - ( - Option<&mut Handle<Image>>, - Option<&mut UiImage>, - &CosmicSource, - ), - Without<CosmicBuffer>, - >, -) { - // TODO: do this once - for (dest_handle_opt, dest_ui_opt, source_entity) in dest_q.iter_mut() { - if let Ok(source_handle) = source_q.get(source_entity.0) { - if let Some(mut dest_handle) = dest_handle_opt { - *dest_handle = source_handle.clone_weak(); - } - if let Some(mut dest_ui) = dest_ui_opt { - dest_ui.texture = source_handle.clone_weak(); - } +/// Will attempt to find a place on the receiving entity to place +/// a [`Handle<Image>`] +#[derive(QueryData)] +#[query_data(mutable)] +pub(crate) struct OutputToEntity { + sprite_target: Option<&'static mut Sprite>, + image_node_target: Option<&'static mut ImageNode>, +} + +impl OutputToEntityItem<'_> { + pub fn write_image_data(&mut self, image: &Handle<Image>) { + if let Some(sprite) = self.sprite_target.as_mut() { + sprite.image = image.clone_weak(); } + if let Some(image_node) = self.image_node_target.as_mut() { + image_node.image = image.clone_weak(); + } + } +} + +/// Every frame updates the output (in [`CosmicRenderOutput`]) to its receiver +/// on the same entity, e.g. [`Sprite`] +pub(crate) fn update_internal_target_handles( + mut buffers_q: Query<(&CosmicRenderOutput, OutputToEntity), With<CosmicEditBuffer>>, +) { + for (output_data, mut output_components) in buffers_q.iter_mut() { + output_components.write_image_data(&output_data.0); } } // TODO put this on impl CosmicBuffer -pub fn get_text_size(buffer: &Buffer) -> (f32, f32) { +/// Returns in physical pixels +pub(crate) fn get_text_size(buffer: &Buffer) -> Vec2 { if buffer.layout_runs().count() == 0 { - return (0., buffer.metrics().line_height); + return Vec2::new(0., buffer.metrics().line_height); } + // get max width let width = buffer .layout_runs() .map(|run| run.line_w) .reduce(f32::max) .unwrap(); + // get total height let height = buffer.layout_runs().count() as f32 * buffer.metrics().line_height; - (width, height) + Vec2::new(width, height) } -pub fn get_y_offset_center(widget_height: f32, buffer: &Buffer) -> i32 { - let (_, text_height) = get_text_size(buffer); +/// Returns in physical pixels +pub(crate) fn get_y_offset_center(widget_height: f32, buffer: &Buffer) -> i32 { + let text_height = get_text_size(buffer).y; ((widget_height - text_height) / 2.0) as i32 } -pub fn get_x_offset_center(widget_width: f32, buffer: &Buffer) -> i32 { - let (text_width, _) = get_text_size(buffer); +/// Returns in physical pixels +pub(crate) fn get_x_offset_center(widget_width: f32, buffer: &Buffer) -> i32 { + let text_width = get_text_size(buffer).x; ((widget_width - text_width) / 2.0) as i32 } diff --git a/src/cosmic_edit.rs b/src/cosmic_edit.rs index 392bb8ea423577bf225098537bd59f1feb21266c..83aa1c012a4990aaee7550c52f823ba849036fd0 100644 --- a/src/cosmic_edit.rs +++ b/src/cosmic_edit.rs @@ -1,7 +1,19 @@ -use crate::*; -use bevy::prelude::*; +use crate::prelude::*; use cosmic_text::{Attrs, AttrsOwned, Editor, FontSystem}; +pub(crate) fn plugin(app: &mut App) { + app.register_type::<CosmicWrap>() + .register_type::<CosmicTextAlign>() + .register_type::<XOffset>() + .register_type::<CosmicBackgroundImage>() + .register_type::<CosmicBackgroundColor>() + .register_type::<CursorColor>() + .register_type::<SelectionColor>() + .register_type::<MaxLines>() + .register_type::<MaxChars>() + .register_type::<ScrollEnabled>(); +} + /// Enum representing text wrapping in a cosmic [`Buffer`] #[derive(Component, Reflect, Clone, PartialEq, Default)] pub enum CosmicWrap { @@ -10,7 +22,8 @@ pub enum CosmicWrap { Wrap, } -/// Enum representing the text alignment in a cosmic [`Buffer`] +/// Enum representing the text alignment in a cosmic [`Buffer`]. +/// Defaults to [`CosmicTextAlign::Center`] #[derive(Component, Reflect, Clone)] pub enum CosmicTextAlign { Center { padding: i32 }, @@ -24,19 +37,26 @@ impl Default for CosmicTextAlign { } } -/// Tag component to disable writing to a [`CosmicBuffer`] +/// Tag component to disable writing to a [`CosmicEditBuffer`] // TODO: Code example #[derive(Component, Default)] pub struct ReadOnly; // tag component /// Internal value used to decide what section of a [`Buffer`] to render #[derive(Component, Reflect, Debug, Default)] -pub struct XOffset { +pub(crate) struct XOffset { + /// How much space in logical units from the left of the [`Buffer`] + /// to start rendering text. pub left: f32, - pub width: f32, + + /// Width of buffer that includes text that should be rendered, + /// in logical units. + /// + /// Should only be [None] if in default state + pub width: Option<f32>, } -/// Default text attributes to be used on a [`CosmicBuffer`] +/// Default text attributes to be used on a [`CosmicEditBuffer`] #[derive(Component, Deref, DerefMut)] pub struct DefaultAttrs(pub AttrsOwned); @@ -54,19 +74,34 @@ pub struct CosmicBackgroundImage(pub Option<Handle<Image>>); #[derive(Component, Reflect, Default, Deref)] pub struct CosmicBackgroundColor(pub Color); -/// Color to be used for the text cursor -#[derive(Component, Reflect, Default, Deref)] +/// Color to be used for the text cursor. +/// Defaults to [`Color::BLACK`] +#[derive(Component, Reflect, Deref)] pub struct CursorColor(pub Color); -/// Color to be used as the selected text background -#[derive(Component, Reflect, Default, Deref)] +impl Default for CursorColor { + fn default() -> Self { + CursorColor(Color::BLACK) + } +} + +/// Color to be used as the selected text background. +/// Defaults to [`Color::GRAY`] +#[derive(Component, Reflect, Deref)] pub struct SelectionColor(pub Color); +impl Default for SelectionColor { + fn default() -> Self { + SelectionColor(bevy::color::palettes::basic::GRAY.into()) + } +} + /// Color to be used for the selected text #[derive(Component, Reflect, Default, Deref)] pub struct SelectedTextColor(pub Color); /// Maximum number of lines allowed in a buffer +// TODO: Actually test this? I'm not sure this does anything afaik #[derive(Component, Reflect, Default)] pub struct MaxLines(pub usize); @@ -75,164 +110,33 @@ pub struct MaxLines(pub usize); #[derive(Component, Reflect, Default)] pub struct MaxChars(pub usize); -/// Buffer does not respond to scroll events -#[derive(Component, Default)] -pub struct ScrollDisabled; - -/// A pointer to an entity with a [`CosmicEditBundle`], used to apply cosmic rendering to a UI -/// element. -/// -///``` -/// # use bevy::prelude::*; -/// # use bevy_cosmic_edit::*; -/// # -/// # fn setup(mut commands: Commands) { -/// // Create a new cosmic bundle -/// let cosmic_edit = commands.spawn(CosmicEditBundle::default()).id(); -/// -/// // Spawn the target bundle -/// commands -/// .spawn(ButtonBundle { -/// style: Style { -/// width: Val::Percent(100.), -/// height: Val::Percent(100.), -/// ..default() -/// }, -/// background_color: BackgroundColor(Color::WHITE), -/// ..default() -/// }) -/// // Add the source component to the target element -/// .insert(CosmicSource(cosmic_edit)); -/// # } -/// # -/// # fn main() { -/// # App::new() -/// # .add_plugins(MinimalPlugins) -/// # .add_plugins(CosmicEditPlugin::default()) -/// # .add_systems(Startup, setup); -/// # } -#[derive(Component, Reflect)] -pub struct CosmicSource(pub Entity); - -/// A bundle containing all the required components for [`CosmicBuffer`] functionality. -/// -/// Uses an invisible [`SpriteBundle`] for rendering by default, so should either be paired with another -/// entity with a [`CosmicSource`] pointing to it's entity, or have the sprite set. -/// -/// ### UI mode -/// -///``` -/// # use bevy::prelude::*; -/// # use bevy_cosmic_edit::*; -/// # -/// # fn setup(mut commands: Commands) { -/// // Create a new cosmic bundle -/// let cosmic_edit = commands.spawn(CosmicEditBundle::default()).id(); -/// -/// // Spawn the target bundle -/// commands -/// .spawn(ButtonBundle { -/// style: Style { -/// width: Val::Percent(100.), -/// height: Val::Percent(100.), -/// ..default() -/// }, -/// background_color: BackgroundColor(Color::WHITE), -/// ..default() -/// }) -/// // Add the source component to the target element -/// .insert(CosmicSource(cosmic_edit)); -/// # } -/// # -/// # fn main() { -/// # App::new() -/// # .add_plugins(MinimalPlugins) -/// # .add_plugins(CosmicEditPlugin::default()) -/// # .add_systems(Startup, setup); -/// # } -/// ``` -/// ### Sprite mode -/// ``` -/// # use bevy::prelude::*; -/// # use bevy_cosmic_edit::*; -/// # -/// # fn setup(mut commands: Commands) { -/// // Create a new cosmic bundle -/// commands.spawn(CosmicEditBundle { -/// sprite_bundle: SpriteBundle { -/// sprite: Sprite { -/// custom_size: Some(Vec2::new(300.0, 40.0)), -/// ..default() -/// }, -/// ..default() -/// }, -/// ..default() -/// }); -/// # } -/// # -/// # fn main() { -/// # App::new() -/// # .add_plugins(MinimalPlugins) -/// # .add_plugins(CosmicEditPlugin::default()) -/// # .add_systems(Startup, setup); -/// # } -#[derive(Bundle)] -pub struct CosmicEditBundle { - // cosmic bits - pub buffer: CosmicBuffer, - // render bits - pub fill_color: CosmicBackgroundColor, - pub cursor_color: CursorColor, - pub selection_color: SelectionColor, - pub default_attrs: DefaultAttrs, - pub background_image: CosmicBackgroundImage, - pub sprite_bundle: SpriteBundle, - // restriction bits - pub max_lines: MaxLines, - pub max_chars: MaxChars, - // layout bits - pub x_offset: XOffset, - pub mode: CosmicWrap, - pub text_position: CosmicTextAlign, - pub padding: CosmicPadding, - pub widget_size: CosmicWidgetSize, - pub hover_cursor: HoverCursor, +/// Should [`CosmicEditBuffer`] respond to scroll events? +#[derive(Component, Reflect, Default)] +pub enum ScrollEnabled { + #[default] + Enabled, + Disabled, } -impl Default for CosmicEditBundle { - fn default() -> Self { - CosmicEditBundle { - buffer: Default::default(), - fill_color: Default::default(), - cursor_color: CursorColor(Color::BLACK), - selection_color: SelectionColor(bevy::color::palettes::basic::GRAY.into()), - text_position: Default::default(), - default_attrs: Default::default(), - background_image: Default::default(), - max_lines: Default::default(), - max_chars: Default::default(), - mode: Default::default(), - sprite_bundle: SpriteBundle { - sprite: Sprite { - custom_size: Some(Vec2::ONE * 128.0), - ..default() - }, - visibility: Visibility::Hidden, - ..default() - }, - x_offset: Default::default(), - padding: Default::default(), - widget_size: Default::default(), - hover_cursor: Default::default(), - } +impl ScrollEnabled { + pub fn should_scroll(&self) -> bool { + matches!(self, ScrollEnabled::Enabled) } } /// Holds the font system used internally by [`cosmic_text`] +/// +/// Note: When bevy provides enough initialisation flexibility, +/// this should be merged with its builtin resource #[derive(Resource, Deref, DerefMut)] pub struct CosmicFontSystem(pub FontSystem); /// Wrapper component for an [`Editor`] with a few helpful values for cursor blinking +/// +/// [`cosmic_text::Editor`] is basically a mutable version of [`cosmic_text::Buffer`]. +/// +/// This component should be on a focussed [`CosmicEditBuffer`] +// Managed by crate::focus::add_editor_to_focussed and similar systems #[derive(Component, Deref, DerefMut)] pub struct CosmicEditor { #[deref] @@ -246,7 +150,7 @@ impl CosmicEditor { Self { editor, cursor_visible: true, - cursor_timer: Timer::new(Duration::from_millis(530), TimerMode::Repeating), + cursor_timer: Timer::new(std::time::Duration::from_millis(530), TimerMode::Repeating), } } } diff --git a/src/cursor.rs b/src/cursor.rs index ae3b250ee50fb14278d527c771eb056158a47fb2..ee3504ec5185eacd195408f41ba3422a92e7eb84 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -1,14 +1,14 @@ // This will all be rewritten soon, looking toward per-widget cursor control // Rewrite should address issue #93 too -use crate::*; -use bevy::{input::mouse::MouseMotion, prelude::*, window::PrimaryWindow}; +use crate::prelude::*; +use bevy::{ + input::mouse::MouseMotion, + window::{PrimaryWindow, SystemCursorIcon}, + winit::cursor::CursorIcon, +}; -/// System set for mouse cursor systems. Runs in [`Update`] -#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] -pub struct CursorSet; - -pub struct CursorPlugin; +pub(crate) struct CursorPlugin; /// Unit resource whose existence in the world disables the cursor plugin systems. #[derive(Resource)] @@ -18,139 +18,88 @@ impl Plugin for CursorPlugin { fn build(&self, app: &mut App) { app.add_systems( Update, - ((hover_sprites, hover_ui), change_cursor) + ( + (crate::render_targets::hover_sprites, hover_ui), + change_cursor, + ) .chain() .run_if(not(resource_exists::<CursorPluginDisabled>)), ) .add_event::<TextHoverIn>() .register_type::<TextHoverIn>() - .add_event::<TextHoverOut>(); + .add_event::<TextHoverOut>() + .register_type::<TextHoverOut>() + .register_type::<HoverCursor>(); } } +/// What cursor icon to show when hovering over a widget +/// +/// By default is [`CursorIcon::System(SystemCursorIcon::Text)`] #[derive(Component, Reflect, Deref)] pub struct HoverCursor(pub CursorIcon); impl Default for HoverCursor { fn default() -> Self { - Self(CursorIcon::Text) + Self(CursorIcon::System(SystemCursorIcon::Text)) } } /// For use with custom cursor control -/// Event is emitted when cursor enters a text widget +/// +/// Event is emitted when cursor enters a text widget. /// Event contains the cursor from the buffer's [`HoverCursor`] #[derive(Event, Reflect, Deref, Debug)] pub struct TextHoverIn(pub CursorIcon); /// For use with custom cursor control /// Event is emitted when cursor leaves a text widget -#[derive(Event, Debug)] +#[derive(Event, Reflect, Debug)] pub struct TextHoverOut; pub(crate) fn change_cursor( mut evr_hover_in: EventReader<TextHoverIn>, evr_hover_out: EventReader<TextHoverOut>, - evr_text_changed: EventReader<CosmicTextChanged>, + evr_text_changed: EventReader<crate::events::CosmicTextChanged>, evr_mouse_motion: EventReader<MouseMotion>, mouse_buttons: Res<ButtonInput<MouseButton>>, - mut windows: Query<&mut Window, With<PrimaryWindow>>, + mut windows: Query<(&mut Window, &mut CursorIcon), With<PrimaryWindow>>, ) { if windows.iter().len() == 0 { return; } - let mut window = windows.single_mut(); + let (mut window, mut window_cursor_icon) = windows.single_mut(); if let Some(ev) = evr_hover_in.read().last() { - window.cursor.icon = ev.0; + *window_cursor_icon = ev.0.clone(); } else if !evr_hover_out.is_empty() { - window.cursor.icon = CursorIcon::Default; + *window_cursor_icon = CursorIcon::System(SystemCursorIcon::Default); } if !evr_text_changed.is_empty() { - window.cursor.visible = false; + window.cursor_options.visible = false; } if mouse_buttons.get_just_pressed().len() != 0 || !evr_mouse_motion.is_empty() { - window.cursor.visible = true; - } -} - -#[cfg(feature = "multicam")] -type CameraQuery<'a, 'b, 'c, 'd> = - Query<'a, 'b, (&'c Camera, &'d GlobalTransform), With<CosmicPrimaryCamera>>; - -#[cfg(not(feature = "multicam"))] -type CameraQuery<'a, 'b, 'c, 'd> = Query<'a, 'b, (&'c Camera, &'d GlobalTransform)>; - -pub(crate) fn hover_sprites( - windows: Query<&Window, With<PrimaryWindow>>, - mut cosmic_edit_query: Query< - (&mut Sprite, &Visibility, &GlobalTransform, &HoverCursor), - With<CosmicBuffer>, - >, - camera_q: CameraQuery, - mut hovered: Local<bool>, - mut last_hovered: Local<bool>, - mut evw_hover_in: EventWriter<TextHoverIn>, - mut evw_hover_out: EventWriter<TextHoverOut>, -) { - *hovered = false; - if windows.iter().len() == 0 { - return; + window.cursor_options.visible = true; } - let window = windows.single(); - let (camera, camera_transform) = camera_q.single(); - - let mut icon = CursorIcon::Default; - - for (sprite, visibility, node_transform, hover) in &mut cosmic_edit_query.iter_mut() { - if visibility == Visibility::Hidden { - continue; - } - - let size = sprite.custom_size.unwrap_or(Vec2::ONE); - if get_node_cursor_pos( - window, - node_transform, - size, - false, - camera, - camera_transform, - ) - .is_some() - { - *hovered = true; - icon = hover.0; - } - } - - if *last_hovered != *hovered { - if *hovered { - evw_hover_in.send(TextHoverIn(icon)); - } else { - evw_hover_out.send(TextHoverOut); - } - } - - *last_hovered = *hovered; } pub(crate) fn hover_ui( - interaction_query: Query<(&Interaction, &CosmicSource), Changed<Interaction>>, - cosmic_query: Query<&HoverCursor, With<CosmicBuffer>>, + interaction_query: Query< + (&Interaction, &HoverCursor), + (With<CosmicEditBuffer>, Changed<Interaction>), + >, mut evw_hover_in: EventWriter<TextHoverIn>, mut evw_hover_out: EventWriter<TextHoverOut>, ) { - for (interaction, source) in interaction_query.iter() { + for (interaction, hover) in interaction_query.iter() { match interaction { Interaction::None => { evw_hover_out.send(TextHoverOut); } Interaction::Hovered => { - if let Ok(hover) = cosmic_query.get(source.0) { - evw_hover_in.send(TextHoverIn(hover.0)); - } + evw_hover_in.send(TextHoverIn(hover.0.clone())); } _ => {} } diff --git a/src/events.rs b/src/events.rs index 1f542b3b72242ff036a13a0112384ba91264be34..ecbb82dee72450f73ceaaa14173ec2724b6e5673 100644 --- a/src/events.rs +++ b/src/events.rs @@ -13,6 +13,7 @@ impl Plugin for EventsPlugin { } /// Text change events +/// /// Sent when text is changed in a cosmic buffer /// Contains the entity on which the text was changed, and the new text as a [`String`] #[derive(Event, Reflect, Debug)] diff --git a/src/focus.rs b/src/focus.rs index 88cf6e58fce49c5ad23fa82133975ac845b6ec7f..04df1ab53913aa697ad254726c22b834e68b9bc2 100644 --- a/src/focus.rs +++ b/src/focus.rs @@ -1,10 +1,9 @@ -use crate::*; -use bevy::prelude::*; +use crate::{prelude::*, widget::WidgetSet}; use cosmic_text::{Edit, Editor}; /// System set for focus systems. Runs in `PostUpdate` #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] -pub struct FocusSet; +pub(crate) struct FocusSet; pub(crate) struct FocusPlugin; @@ -23,14 +22,18 @@ impl Plugin for FocusPlugin { } /// Resource struct that keeps track of the currently active editor entity. +/// +/// The focussed entity must have a [`CosmicEditBuffer`], and should have a +/// [`CosmicEditor`] component as well if it can be mutated (i.e. isn't [`Readonly`]). #[derive(Resource, Reflect, Default, Deref, DerefMut)] #[reflect(Resource)] pub struct FocusedWidget(pub Option<Entity>); +/// Adds [`CosmicEditor`] by copying from existing [`CosmicEditBuffer`]. pub(crate) fn add_editor_to_focused( mut commands: Commands, active_editor: Res<FocusedWidget>, - q: Query<&CosmicBuffer, Without<CosmicEditor>>, + q: Query<&CosmicEditBuffer, Without<CosmicEditor>>, ) { if let Some(e) = active_editor.0 { let Ok(b) = q.get(e) else { @@ -42,10 +45,11 @@ pub(crate) fn add_editor_to_focused( } } +/// Removes [`CosmicEditor`] pub(crate) fn drop_editor_unfocused( mut commands: Commands, active_editor: Res<FocusedWidget>, - mut q: Query<(Entity, &mut CosmicBuffer, &CosmicEditor)>, + mut q: Query<(Entity, &mut CosmicEditBuffer, &CosmicEditor)>, ) { if active_editor.0.is_none() { for (e, mut b, ed) in q.iter_mut() { diff --git a/src/input.rs b/src/input.rs index 931028ba1917aca32240d514d71927c9b710c82d..124abfef5ef62fc599e55727cca0268bf5989850 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,21 +1,25 @@ #![allow(clippy::too_many_arguments, clippy::type_complexity)] -use crate::*; +use crate::{ + buffer::{get_x_offset_center, get_y_offset_center}, + cosmic_edit::{CosmicTextAlign, MaxChars, MaxLines, ReadOnly, ScrollEnabled, XOffset}, + events::CosmicTextChanged, + prelude::*, + CosmicWidgetSize, +}; use bevy::{ input::{ keyboard::{Key, KeyboardInput}, mouse::{MouseMotion, MouseScrollUnit, MouseWheel}, }, - prelude::*, window::PrimaryWindow, }; use cosmic_text::{Action, Cursor, Edit, Motion, Selection}; -#[cfg(target_arch = "wasm32")] -use crate::DefaultAttrs; #[cfg(target_arch = "wasm32")] use bevy::tasks::AsyncComputeTaskPool; #[cfg(target_arch = "wasm32")] +#[allow(unused_imports)] use js_sys::Promise; #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; @@ -38,24 +42,32 @@ impl Plugin for InputPlugin { .in_set(InputSet), ) .insert_resource(ClickTimer(Timer::from_seconds(0.5, TimerMode::Once))); + + #[cfg(target_arch = "wasm32")] + { + let (tx, rx) = crossbeam_channel::bounded::<WasmPaste>(1); + app.insert_resource(WasmPasteAsyncChannel { tx, rx }) + .add_systems(Update, poll_wasm_paste); + } } } /// Timer for double / triple clicks #[derive(Resource)] -pub struct ClickTimer(pub Timer); +pub(crate) struct ClickTimer(pub(crate) Timer); // TODO: hide this behind #cfg wasm, depends on wasm having own copy/paste fn /// Crossbeam channel struct for Wasm clipboard data -#[allow(dead_code)] -pub struct WasmPaste { +#[cfg_attr(not(target_arch = "wasm32"), allow(dead_code))] +pub(crate) struct WasmPaste { text: String, entity: Entity, } /// Async channel for receiving from the clipboard in Wasm +#[cfg_attr(not(target_arch = "wasm32"), allow(dead_code))] #[derive(Resource)] -pub struct WasmPasteAsyncChannel { +pub(crate) struct WasmPasteAsyncChannel { pub tx: crossbeam_channel::Sender<WasmPaste>, pub rx: crossbeam_channel::Receiver<WasmPaste>, } @@ -69,12 +81,10 @@ pub(crate) fn input_mouse( &mut CosmicEditor, &GlobalTransform, &CosmicTextAlign, - Entity, &XOffset, - &mut Sprite, - Option<&ScrollDisabled>, + &ScrollEnabled, + CosmicWidgetSize, )>, - node_q: Query<(&Node, &GlobalTransform, &CosmicSource)>, mut font_system: ResMut<CosmicFontSystem>, mut scroll_evr: EventReader<MouseWheel>, camera_q: Query<(&Camera, &GlobalTransform)>, @@ -83,12 +93,9 @@ pub(crate) fn input_mouse( time: Res<Time>, evr_mouse_motion: EventReader<MouseMotion>, ) { + // handle click timer and click_count click_timer.0.tick(time.delta()); - let Some(active_editor_entity) = active_editor.0 else { - return; - }; - if click_timer.0.finished() || !evr_mouse_motion.is_empty() { *click_count = 0; } @@ -102,6 +109,11 @@ pub(crate) fn input_mouse( *click_count = 0; } + // unwrap resources + let Some(active_editor_entity) = active_editor.0 else { + return; + }; + let Ok(primary_window) = windows.get_single() else { return; }; @@ -111,33 +123,20 @@ pub(crate) fn input_mouse( return; }; - if let Ok(( - mut editor, - sprite_transform, - text_position, - entity, - x_offset, - sprite, - scroll_disabled, - )) = editor_q.get_mut(active_editor_entity) + // TODO: generalize this over UI and sprite + if let Ok((mut editor, transform, text_position, x_offset, scroll_disabled, target_size)) = + editor_q.get_mut(active_editor_entity) { let buffer = editor.with_buffer(|b| b.clone()); - let mut is_ui_node = false; - let mut transform = sprite_transform; - let sprite_size = sprite.custom_size.expect("Must specify Sprite.custom_size"); - let (mut width, mut height) = (sprite_size.x, sprite_size.y); - - // TODO: this is bad loop nesting, rethink system with relationships in mind - for (node, node_transform, source) in node_q.iter() { - if source.0 != entity { - continue; - } - is_ui_node = true; - transform = node_transform; - width = node.size().x; - height = node.size().y; - } + // get size of render target + let Ok(source_type) = target_size.scan() else { + return; + }; + let Ok(size) = target_size.logical_size() else { + return; + }; + let (width, height) = (size.x, size.y); let shift = keys.any_pressed([KeyCode::ShiftLeft, KeyCode::ShiftRight]); @@ -159,7 +158,8 @@ pub(crate) fn input_mouse( get_y_offset_center(height * scale_factor, &buffer), ), }; - let point = |node_cursor_pos: Vec2| { + // Converts a node-relative space coordinate to a screen space physical coord + let screen_physical = |node_cursor_pos: Vec2| { ( (node_cursor_pos.x * scale_factor) as i32 - padding_x, (node_cursor_pos.y * scale_factor) as i32 - padding_y, @@ -170,15 +170,15 @@ pub(crate) fn input_mouse( editor.cursor_visible = true; editor.cursor_timer.reset(); - if let Some(node_cursor_pos) = get_node_cursor_pos( + if let Some(node_cursor_pos) = crate::render_targets::get_node_cursor_pos( primary_window, transform, Vec2::new(width, height), - is_ui_node, + source_type, camera, camera_transform, ) { - let (mut x, y) = point(node_cursor_pos); + let (mut x, y) = screen_physical(node_cursor_pos); x += x_offset.left as i32; if shift { editor.action(&mut font_system.0, Action::Drag { x, y }); @@ -210,15 +210,15 @@ pub(crate) fn input_mouse( } if buttons.pressed(MouseButton::Left) && *click_count == 0 { - if let Some(node_cursor_pos) = get_node_cursor_pos( + if let Some(node_cursor_pos) = crate::render_targets::get_node_cursor_pos( primary_window, transform, Vec2::new(width, height), - is_ui_node, + source_type, camera, camera_transform, ) { - let (mut x, y) = point(node_cursor_pos); + let (mut x, y) = screen_physical(node_cursor_pos); x += x_offset.left as i32; if active_editor.is_changed() && !shift { editor.action(&mut font_system.0, Action::Click { x, y }); @@ -229,7 +229,7 @@ pub(crate) fn input_mouse( return; } - if scroll_disabled.is_none() { + if scroll_disabled.should_scroll() { for ev in scroll_evr.read() { match ev.unit { MouseScrollUnit::Line => { @@ -255,7 +255,7 @@ pub(crate) fn input_mouse( } } -pub fn kb_move_cursor( +pub(crate) fn kb_move_cursor( active_editor: Res<FocusedWidget>, keys: Res<ButtonInput<KeyCode>>, mut cosmic_edit_query: Query<(&mut CosmicEditor,)>, @@ -408,7 +408,7 @@ pub(crate) fn kb_input_text( mut char_evr: EventReader<KeyboardInput>, mut cosmic_edit_query: Query<( &mut CosmicEditor, - &mut CosmicBuffer, + &mut CosmicEditBuffer, &MaxLines, &MaxChars, Entity, @@ -522,14 +522,14 @@ pub(crate) fn kb_input_text( } } -pub fn kb_clipboard( +pub(crate) fn kb_clipboard( active_editor: Res<FocusedWidget>, keys: Res<ButtonInput<KeyCode>>, mut evw_changed: EventWriter<CosmicTextChanged>, mut font_system: ResMut<CosmicFontSystem>, mut cosmic_edit_query: Query<( &mut CosmicEditor, - &mut CosmicBuffer, + &mut CosmicEditBuffer, &MaxLines, &MaxChars, Entity, @@ -664,13 +664,12 @@ pub fn read_clipboard_wasm() -> Promise { } #[cfg(target_arch = "wasm32")] -pub fn poll_wasm_paste( +pub(crate) fn poll_wasm_paste( channel: Res<WasmPasteAsyncChannel>, mut editor_q: Query< ( &mut CosmicEditor, - &mut CosmicBuffer, - &crate::DefaultAttrs, + &mut CosmicEditBuffer, &MaxChars, &MaxChars, ), @@ -683,11 +682,8 @@ pub fn poll_wasm_paste( match inlet { Ok(inlet) => { let entity = inlet.entity; - if let Ok((mut editor, mut buffer, attrs, max_chars, max_lines)) = - editor_q.get_mut(entity) - { + if let Ok((mut editor, buffer, max_chars, max_lines)) = editor_q.get_mut(entity) { let text = inlet.text; - let attrs = &attrs.0; for c in text.chars() { if max_chars.0 == 0 || buffer.get_text().len() < max_chars.0 { if c == 0xA as char { diff --git a/src/lib.rs b/src/lib.rs index 1568a32d633468890b5e129a9a9a146164edc20d..80524326dc1788c0e858786f55bb69a88ae744a4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,44 +11,8 @@ //! //! ï± *Warning: This plugin is currently in early development, and its API is subject to change.* //! -//! ``` -//! use bevy::prelude::*; -//! use bevy_cosmic_edit::*; -//! -//! fn setup(mut commands: Commands, mut font_system: ResMut<CosmicFontSystem>) { -//! commands.spawn(Camera2dBundle::default()); -//! -//! // Text attributes -//! let font_size = 16.0; -//! let line_height = 18.0; -//! let attrs = Attrs::new() -//! .family(Family::Monospace) -//! .color(Color::DARK_GRAY.to_cosmic()) -//! .weight(FontWeight::BOLD); -//! -//! // Spawning -//! commands.spawn(CosmicEditBundle { -//! buffer: CosmicBuffer::new(&mut font_system, Metrics::new(font_size, line_height)) -//! .with_text(&mut font_system, "Hello, Cosmic!", attrs), -//! sprite_bundle: SpriteBundle { -//! sprite: Sprite { -//! custom_size: Some(Vec2::new(300.0, 40.0)), -//! ..default() -//! }, -//! ..default() -//! }, -//! ..default() -//! }); -//! } -//! -//! fn main() { -//! App::new() -//! .add_plugins(DefaultPlugins) -//! .add_plugins(CosmicEditPlugin::default()) -//! .add_systems(Startup, setup) -//! .add_systems(Update, change_active_editor_sprite) -//! .run(); -//! } +//! ```rust,no_run +#![doc = include_str!("../examples/basic_ui.rs")] //! ``` //! //! Check the examples folder for much more! @@ -70,7 +34,9 @@ //! //! | bevy | bevy_cosmic_edit | //! | ------ | ---------------- | -//! | 0.13.0 | 0.16 - latest | +//! | 0.15.0 | 0.26 - latest | +//! | 0.14.0 | 0.21 - 0.25 | +//! | 0.13.0 | 0.16 - 0.20 | //! | 0.12.* | 0.15 | //! | 0.11.* | 0.8 - 0.14 | //! @@ -82,199 +48,66 @@ //! MIT or Apache-2.0 #![allow(clippy::type_complexity)] +pub mod prelude { + // external re-exports + pub(crate) use bevy::prelude::*; + pub(crate) use bevy::text::SwashCache; + #[cfg_attr(not(doc), allow(unused_imports))] + pub(crate) use cosmic_text::Buffer; + + // internal re-exports + pub(crate) use crate::buffer::BufferExtras as _; + pub(crate) use crate::cosmic_text; + pub(crate) use crate::primary::CosmicRenderOutput; + pub(crate) use crate::utils::*; + + // public internal re-exports + pub use crate::buffer::CosmicEditBuffer; // todo: migrate to builtin bevy CosmicBuffer + pub use crate::cosmic_edit::CosmicFontSystem; // todo: migrate to using builtin bevy cosmic font system + pub use crate::cosmic_edit::{CosmicEditor, DefaultAttrs, ReadOnly}; + pub use crate::focus::FocusedWidget; + pub use crate::primary::{CosmicEditPlugin, CosmicFontConfig, CosmicPrimaryCamera}; + pub use crate::render_targets::{TextEdit, TextEdit2d}; + pub use crate::utils::{ + change_active_editor_sprite, change_active_editor_ui, deselect_editor_on_esc, + print_editor_text, ColorExtras as _, + }; + #[doc(no_inline)] + pub use bevy::text::cosmic_text::{ + Color as CosmicColor, Style as FontStyle, Weight as FontWeight, + }; +} + +pub use bevy::text::cosmic_text; + +pub use primary::{CosmicEditPlugin, CosmicFontConfig, CosmicPrimaryCamera}; +/// Contains the library global important types you probably want to explore first +mod primary; + +pub use buffer::CosmicEditBuffer; mod buffer; +pub use cosmic_edit::{ + CosmicBackgroundColor, CosmicBackgroundImage, CosmicEditor, CosmicFontSystem, CosmicTextAlign, + CosmicWrap, CursorColor, DefaultAttrs, MaxChars, MaxLines, ReadOnly, ScrollEnabled, + SelectedTextColor, SelectionColor, +}; mod cosmic_edit; +pub use cursor::{CursorPluginDisabled, HoverCursor, TextHoverIn, TextHoverOut}; mod cursor; +pub use events::CosmicTextChanged; mod events; +pub use focus::FocusedWidget; mod focus; +pub use input::InputSet; mod input; +pub use password::Password; mod password; +pub use placeholder::Placeholder; mod placeholder; mod render; +pub use user_select::UserSelectNone; mod user_select; -mod util; +pub mod utils; mod widget; - -use std::{path::PathBuf, time::Duration}; - -use bevy::prelude::*; - -pub use buffer::*; -pub use cosmic_edit::*; -#[doc(no_inline)] -pub use cosmic_text::{self, Color as CosmicColor, Style as FontStyle, Weight as FontWeight}; -pub use cursor::*; -pub use events::*; -pub use focus::*; -pub use input::*; -pub use password::*; -pub use placeholder::*; -pub use render::*; -pub use user_select::*; -pub use util::*; -pub use widget::*; - -/// Plugin struct that adds systems and initializes resources related to cosmic edit functionality. -#[derive(Default)] -pub struct CosmicEditPlugin { - pub font_config: CosmicFontConfig, -} - -impl Plugin for CosmicEditPlugin { - fn build(&self, app: &mut App) { - let font_system = create_cosmic_font_system(self.font_config.clone()); - - app.add_plugins(( - BufferPlugin, - RenderPlugin, - WidgetPlugin, - InputPlugin, - FocusPlugin, - CursorPlugin, - PlaceholderPlugin, - PasswordPlugin, - EventsPlugin, - UserSelectPlugin, - )) - .insert_resource(CosmicFontSystem(font_system)); - - app.register_type::<CosmicWrap>() - .register_type::<CosmicTextAlign>() - .register_type::<XOffset>() - .register_type::<CosmicBackgroundImage>() - .register_type::<CosmicBackgroundColor>() - .register_type::<CursorColor>() - .register_type::<SelectionColor>() - .register_type::<MaxLines>() - .register_type::<MaxChars>() - .register_type::<CosmicSource>() - .register_type::<HoverCursor>(); - - #[cfg(target_arch = "wasm32")] - { - let (tx, rx) = crossbeam_channel::bounded::<WasmPaste>(1); - app.insert_resource(WasmPasteAsyncChannel { tx, rx }) - .add_systems(Update, poll_wasm_paste); - } - } -} - -/// Attach to primary camera, and enable the `multicam` feature to use multiple cameras. -/// Will panic if no Camera's without this component exist and the `multicam` feature is enabled. -/// -/// A very basic example which doesn't panic: -/// ```rust -/// use bevy::prelude::*; -/// use bevy_cosmic_edit::CosmicPrimaryCamera; -/// -/// fn main() { -/// App::new() -/// .add_plugins(( -/// DefaultPlugins, -/// bevy_cosmic_edit::CosmicEditPlugin::default(), -/// )) -/// .add_systems(Startup, setup) -/// .run(); -/// } -/// -/// fn setup(mut commands: Commands) { -/// commands.spawn((Camera3dBundle::default(), CosmicPrimaryCamera)); -/// commands.spawn(Camera3dBundle { -/// camera: Camera { -/// order: 2, -/// ..default() -/// }, -/// ..default() -/// }); -/// } -/// ``` -#[derive(Component, Debug, Default)] -pub struct CosmicPrimaryCamera; - -/// Resource struct that holds configuration options for cosmic fonts. -#[derive(Resource, Clone)] -pub struct CosmicFontConfig { - pub fonts_dir_path: Option<PathBuf>, - pub font_bytes: Option<Vec<&'static [u8]>>, - /// If [false], some characters (esspecially Unicode emojies) might not load properly - /// Caution: this can be relatively slow - pub load_system_fonts: bool, -} - -impl Default for CosmicFontConfig { - fn default() -> Self { - let fallback_font = include_bytes!("./font/FiraMono-Regular-subset.ttf"); - Self { - load_system_fonts: true, - font_bytes: Some(vec![fallback_font]), - fonts_dir_path: None, - } - } -} - -fn create_cosmic_font_system(cosmic_font_config: CosmicFontConfig) -> cosmic_text::FontSystem { - let locale = sys_locale::get_locale().unwrap_or_else(|| String::from("en-US")); - let mut db = cosmic_text::fontdb::Database::new(); - if let Some(dir_path) = cosmic_font_config.fonts_dir_path.clone() { - db.load_fonts_dir(dir_path); - } - if let Some(custom_font_data) = &cosmic_font_config.font_bytes { - for elem in custom_font_data { - db.load_font_data(elem.to_vec()); - } - } - if cosmic_font_config.load_system_fonts { - db.load_system_fonts(); - } - cosmic_text::FontSystem::new_with_locale_and_db(locale, db) -} - -#[cfg(test)] -mod tests { - use bevy::input::keyboard::KeyboardInput; - - use crate::*; - - use self::buffer::CosmicBuffer; - - fn test_spawn_cosmic_edit_system( - mut commands: Commands, - mut font_system: ResMut<CosmicFontSystem>, - ) { - let attrs = cosmic_text::Attrs::new(); - commands.spawn(CosmicEditBundle { - buffer: CosmicBuffer::new(&mut font_system, cosmic_text::Metrics::new(20., 20.)) - .with_rich_text(&mut font_system, vec![("Blah", attrs)], attrs), - ..Default::default() - }); - } - - #[test] - fn test_spawn_cosmic_edit() { - let mut app = App::new(); - app.add_plugins(TaskPoolPlugin::default()); - app.add_plugins(AssetPlugin::default()); - app.insert_resource(CosmicFontSystem(create_cosmic_font_system( - CosmicFontConfig::default(), - ))); - app.add_systems(Update, test_spawn_cosmic_edit_system); - - let input = ButtonInput::<KeyCode>::default(); - app.insert_resource(input); - let mouse_input: ButtonInput<MouseButton> = ButtonInput::<MouseButton>::default(); - app.insert_resource(mouse_input); - - app.add_event::<KeyboardInput>(); - - app.update(); - - let mut text_nodes_query = app.world_mut().query::<&CosmicBuffer>(); - for cosmic_editor in text_nodes_query.iter(&app.world()) { - insta::assert_debug_snapshot!(cosmic_editor - .lines - .iter() - .map(|line| line.text()) - .collect::<Vec<_>>()); - } - } -} +pub(crate) use render_targets::{ChangedCosmicWidgetSize, CosmicWidgetSize}; +pub mod render_targets; diff --git a/src/password.rs b/src/password.rs index 54a62c7c87460b3e7942c165b08c2f41ac192df2..5cd1966c346bce6594c8f6d35771c48b86eefc3f 100644 --- a/src/password.rs +++ b/src/password.rs @@ -1,5 +1,7 @@ -use crate::*; -use bevy::prelude::*; +use crate::{ + cosmic_edit::DefaultAttrs, focus::FocusSet, placeholder::Placeholder, prelude::*, + render::RenderSet, +}; use cosmic_text::{Cursor, Edit, Selection, Shaping}; use unicode_segmentation::UnicodeSegmentation; @@ -7,28 +9,31 @@ pub(crate) struct PasswordPlugin; /// System set for password blocking systems. Runs in [`PostUpdate`] #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] -pub struct PasswordSet; +pub(crate) struct PasswordSet; impl Plugin for PasswordPlugin { fn build(&self, app: &mut App) { - app.add_systems(PreUpdate, (hide_password_text.before(input_mouse),)) - .add_systems( - Update, - (restore_password_text - .before(kb_input_text) - .after(kb_move_cursor),), - ) - .add_systems( - PostUpdate, - ( - hide_password_text.before(RenderSet).in_set(PasswordSet), - restore_password_text.before(FocusSet).after(RenderSet), - ), - ); + app.add_systems( + PreUpdate, + (hide_password_text.before(crate::input::input_mouse),), + ) + .add_systems( + Update, + (restore_password_text + .before(crate::input::kb_input_text) + .after(crate::input::kb_move_cursor),), + ) + .add_systems( + PostUpdate, + ( + hide_password_text.before(RenderSet).in_set(PasswordSet), + restore_password_text.before(FocusSet).after(RenderSet), + ), + ); } } -/// Component to be added to an entity with a [`CosmicEditBundle`] to block contents with a +/// Component to be added to an entity with a [`CosmicEditBuffer`] to block contents with a /// password blocker glyph /// /// ``` @@ -37,16 +42,12 @@ impl Plugin for PasswordPlugin { /// # /// # fn setup(mut commands: Commands) { /// // Create a new cosmic bundle -/// commands.spawn((CosmicEditBundle { -/// sprite_bundle: SpriteBundle { -/// sprite: Sprite { -/// custom_size: Some(Vec2::new(300.0, 40.0)), -/// ..default() -/// }, +/// commands.spawn(( +/// CosmicEditBuffer::default(), +/// Sprite { +/// custom_size: Some(Vec2::new(300.0, 40.0)), /// ..default() /// }, -/// ..default() -/// }, /// Password::default() /// )); /// # } @@ -79,10 +80,11 @@ impl Password { } } +/// Stores [`CosmicEditBuffer`] contents into [`Password.real_text`] fn hide_password_text( mut q: Query<( &mut Password, - &mut CosmicBuffer, + &mut CosmicEditBuffer, &DefaultAttrs, Option<&mut CosmicEditor>, Option<&Placeholder>, @@ -92,6 +94,7 @@ fn hide_password_text( for (mut password, mut buffer, attrs, editor_opt, placeholder_opt) in q.iter_mut() { if let Some(placeholder) = placeholder_opt { if placeholder.is_active() { + // doesn't override placeholder continue; } } @@ -157,10 +160,11 @@ fn hide_password_text( } } +/// Replaces [`CosmicEditBuffer`] contents with [`Password.real_text`] fn restore_password_text( mut q: Query<( &Password, - &mut CosmicBuffer, + &mut CosmicEditBuffer, &DefaultAttrs, Option<&mut CosmicEditor>, Option<&Placeholder>, diff --git a/src/placeholder.rs b/src/placeholder.rs index a7b4797c9cdef71ed834359144ed23c6a1f92fc9..55d64899d554656e9b6c8413a5c70c7cdd2f9b73 100644 --- a/src/placeholder.rs +++ b/src/placeholder.rs @@ -1,24 +1,24 @@ -use crate::*; -use bevy::prelude::*; +use crate::{ + cosmic_edit::DefaultAttrs, events::CosmicTextChanged, input::InputSet, prelude::*, + render::RenderSet, +}; use cosmic_text::{Attrs, Edit}; -/// Component to be added to an entity with a [`CosmicEditBundle`] add placeholder text +/// Component to be added to an entity with a [`CosmicEditBuffer`] add placeholder text /// /// ``` /// # use bevy::prelude::*; -/// # use bevy_cosmic_edit::*; +/// # use bevy_cosmic_edit::prelude::*; +/// use bevy_cosmic_edit::Placeholder; +/// /// # fn setup(mut commands: Commands) { -/// commands.spawn((CosmicEditBundle { -/// sprite_bundle: SpriteBundle { -/// sprite: Sprite { -/// custom_size: Some(Vec2::new(300.0, 40.0)), -/// ..default() -/// }, +/// commands.spawn(( +/// CosmicEditBuffer::default(), +/// Sprite { +/// custom_size: Some(Vec2::new(300.0, 40.0)), /// ..default() /// }, -/// ..default() -/// }, -/// Placeholder::new("Email", Attrs::new().color(Color::GRAY.to_cosmic())), +/// Placeholder::new("Email", Attrs::new().color(Color::from(bevy::color::palettes::css::GRAY).to_cosmic())), /// )); /// # } /// # fn main() { @@ -71,7 +71,7 @@ impl Plugin for PlaceholderPlugin { } fn add_placeholder_to_buffer( - mut q: Query<(&mut CosmicBuffer, &mut Placeholder)>, + mut q: Query<(&mut CosmicEditBuffer, &mut Placeholder)>, mut font_system: ResMut<CosmicFontSystem>, ) { for (mut buffer, mut placeholder) in q.iter_mut() { diff --git a/src/primary.rs b/src/primary.rs new file mode 100644 index 0000000000000000000000000000000000000000..e2e41f152f29f1bd9018962f55f86342b56686c3 --- /dev/null +++ b/src/primary.rs @@ -0,0 +1,163 @@ +use std::path::PathBuf; + +use crate::prelude::*; + +/// Plugin struct that adds systems and initializes resources related to cosmic edit functionality. +#[derive(Default)] +pub struct CosmicEditPlugin { + pub font_config: CosmicFontConfig, +} + +impl Plugin for CosmicEditPlugin { + fn build(&self, app: &mut App) { + trace!("Loading cosmic edit plugin"); + let font_system = create_cosmic_font_system(self.font_config.clone()); + + app.add_plugins(( + crate::cosmic_edit::plugin, + crate::buffer::BufferPlugin, + crate::render::RenderPlugin, + crate::widget::WidgetPlugin, + crate::input::InputPlugin, + crate::focus::FocusPlugin, + crate::cursor::CursorPlugin, + crate::placeholder::PlaceholderPlugin, + crate::password::PasswordPlugin, + crate::events::EventsPlugin, + crate::user_select::UserSelectPlugin, + )) + // TODO: Use the builtin bevy CosmicFontSystem + .insert_resource(crate::cosmic_edit::CosmicFontSystem(font_system)); + + app.register_type::<CosmicRenderOutput>(); + } +} + +/// Attach to primary camera, and enable the `multicam` feature to use multiple cameras. +/// Will panic if no Camera's without this component exist and the `multicam` feature is enabled. +/// +/// A very basic example which doesn't panic: +/// ```rust,no_run +/// use bevy::prelude::*; +/// use bevy_cosmic_edit::prelude::*; +/// +/// fn main() { +/// App::new() +/// .add_plugins(( +/// DefaultPlugins, +/// CosmicEditPlugin::default(), +/// )) +/// .add_systems(Startup, setup) +/// .run(); +/// } +/// +/// fn setup(mut commands: Commands) { +/// commands.spawn((Camera3d::default(), CosmicPrimaryCamera)); +/// commands.spawn(( +/// Camera3d::default(), +/// Camera { +/// order: 2, +/// ..default() +/// }, +/// )); +/// } +/// ``` +#[derive(Component, Debug, Default)] +pub struct CosmicPrimaryCamera; + +#[cfg(feature = "multicam")] +pub(crate) type CameraFilter = With<CosmicPrimaryCamera>; + +#[cfg(not(feature = "multicam"))] +pub(crate) type CameraFilter = (); + +/// Resource struct that holds configuration options for cosmic fonts. +#[derive(Resource, Clone)] +pub struct CosmicFontConfig { + pub fonts_dir_path: Option<PathBuf>, + pub font_bytes: Option<Vec<&'static [u8]>>, + /// If [false], some characters (esspecially Unicode emojies) might not load properly + /// Caution: this can be relatively slow + pub load_system_fonts: bool, +} + +impl Default for CosmicFontConfig { + fn default() -> Self { + let fallback_font = include_bytes!("./font/FiraMono-Regular-subset.ttf"); + Self { + load_system_fonts: true, + font_bytes: Some(vec![fallback_font]), + fonts_dir_path: None, + } + } +} + +/// Used to ferry data from a [`CosmicEditBuffer`] +#[derive(Component, Reflect, Default, Debug, Deref)] +pub(crate) struct CosmicRenderOutput(pub(crate) Handle<Image>); + +fn create_cosmic_font_system(cosmic_font_config: CosmicFontConfig) -> cosmic_text::FontSystem { + let locale = sys_locale::get_locale().unwrap_or_else(|| String::from("en-US")); + let mut db = cosmic_text::fontdb::Database::new(); + if let Some(dir_path) = cosmic_font_config.fonts_dir_path.clone() { + db.load_fonts_dir(dir_path); + } + if let Some(custom_font_data) = &cosmic_font_config.font_bytes { + for elem in custom_font_data { + db.load_font_data(elem.to_vec()); + } + } + if cosmic_font_config.load_system_fonts { + db.load_system_fonts(); + } + cosmic_text::FontSystem::new_with_locale_and_db(locale, db) +} + +#[cfg(test)] +mod tests { + use bevy::input::keyboard::KeyboardInput; + + use super::*; + + fn test_spawn_cosmic_edit_system( + mut commands: Commands, + mut font_system: ResMut<CosmicFontSystem>, + ) { + let attrs = cosmic_text::Attrs::new(); + commands.spawn( + CosmicEditBuffer::new(&mut font_system, cosmic_text::Metrics::new(20., 20.)) + .with_rich_text(&mut font_system, vec![("Blah", attrs)], attrs), + ); + } + + #[test] + fn test_spawn_cosmic_edit() { + let mut app = App::new(); + app.add_plugins(TaskPoolPlugin::default()); + app.add_plugins(AssetPlugin::default()); + app.insert_resource(CosmicFontSystem(create_cosmic_font_system( + CosmicFontConfig::default(), + ))); + app.add_systems(Update, test_spawn_cosmic_edit_system); + + // todo: these lines probably won't do anything now, + // maybe we should test for something different? + let input = ButtonInput::<KeyCode>::default(); + app.insert_resource(input); + let mouse_input: ButtonInput<MouseButton> = ButtonInput::<MouseButton>::default(); + app.insert_resource(mouse_input); + + app.add_event::<KeyboardInput>(); + + app.update(); + + let mut text_nodes_query = app.world_mut().query::<&CosmicEditBuffer>(); + for cosmic_editor in text_nodes_query.iter(app.world()) { + insta::assert_debug_snapshot!(cosmic_editor + .lines + .iter() + .map(|line| line.text()) + .collect::<Vec<_>>()); + } + } +} diff --git a/src/render.rs b/src/render.rs index 0fa8a80bb957b53c33cb87f6c699fa7ba5d8c866..ecfe228917b794821a1d0455bd4919e759110517 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,32 +1,30 @@ -use crate::*; -use bevy::{prelude::*, render::render_resource::Extent3d}; -use cosmic_text::{Color, Edit, SwashCache}; +use crate::widget::CosmicPadding; +use crate::{cosmic_edit::ReadOnly, prelude::*, widget::WidgetSet}; +use crate::{cosmic_edit::*, CosmicWidgetSize}; +use bevy::render::render_resource::Extent3d; +use cosmic_text::{Color, Edit}; use image::{imageops::FilterType, GenericImageView}; /// System set for cosmic text rendering systems. Runs in [`PostUpdate`] #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] -pub struct RenderSet; +pub(crate) struct RenderSet; pub(crate) struct RenderPlugin; impl Plugin for RenderPlugin { fn build(&self, app: &mut App) { - app.insert_resource(SwashCacheState { - swash_cache: SwashCache::new(), - }) - .add_systems(Update, blink_cursor) - .add_systems( + if !app.world().contains_resource::<SwashCache>() { + app.insert_resource(SwashCache::default()); + } else { + debug!("Skipping inserting `SwashCache` resource"); + } + app.add_systems(Update, blink_cursor).add_systems( PostUpdate, (render_texture,).in_set(RenderSet).after(WidgetSet), ); } } -#[derive(Resource)] -pub(crate) struct SwashCacheState { - pub swash_cache: SwashCache, -} - pub(crate) fn blink_cursor(mut q: Query<&mut CosmicEditor, Without<ReadOnly>>, time: Res<Time>) { for mut e in q.iter_mut() { e.cursor_timer.tick(time.delta()); @@ -77,18 +75,20 @@ fn draw_pixel(buffer: &mut [u8], width: i32, height: i32, x: i32, y: i32, color: buffer[offset + 3] = (out.alpha * 255.0) as u8; } +/// Renders to the [CosmicRenderOutput] +#[allow(unused_mut)] // for .set_redraw(false) commented out fn render_texture( mut query: Query<( Option<&mut CosmicEditor>, - &mut CosmicBuffer, + &mut CosmicEditBuffer, &DefaultAttrs, &CosmicBackgroundImage, &CosmicBackgroundColor, &CursorColor, &SelectionColor, Option<&SelectedTextColor>, - &Handle<Image>, - &CosmicWidgetSize, + &CosmicRenderOutput, + CosmicWidgetSize, &CosmicPadding, &XOffset, Option<&ReadOnly>, @@ -96,7 +96,7 @@ fn render_texture( )>, mut font_system: ResMut<CosmicFontSystem>, mut images: ResMut<Assets<Image>>, - mut swash_cache_state: ResMut<SwashCacheState>, + mut swash_cache_state: ResMut<SwashCache>, ) { for ( editor, @@ -115,15 +115,28 @@ fn render_texture( position, ) in query.iter_mut() { + let Ok(size) = size.logical_size() else { + continue; + }; + + // avoids a panic + if size.x == 0. || size.y == 0. { + debug!( + message = "Size of buffer is zero, skipping", + // once = "This log only appears once" + ); + continue; + } + // Draw background - let mut pixels = vec![0; size.0.x as usize * size.0.y as usize * 4]; + let mut pixels = vec![0; size.x as usize * size.y as usize * 4]; if let Some(bg_image) = background_image.0.clone() { if let Some(image) = images.get(&bg_image) { let mut dynamic_image = image.clone().try_into_dynamic().unwrap(); - if image.size().x != size.0.x as u32 || image.size().y != size.0.y as u32 { + if image.size() != size.as_uvec2() { dynamic_image = dynamic_image.resize_to_fill( - size.0.x as u32, - size.0.y as u32, + size.x as u32, + size.y as u32, FilterType::Triangle, ); } @@ -162,8 +175,8 @@ fn render_texture( for col in 0..w as i32 { draw_pixel( &mut pixels, - size.0.x as i32, - size.0.y as i32, + size.x as i32, + size.y as i32, x + col + padding.x.max(min_pad) as i32 - x_offset.left as i32, y + row + padding.y as i32, color, @@ -195,34 +208,38 @@ fn render_texture( editor.draw( &mut font_system.0, - &mut swash_cache_state.swash_cache, + &mut swash_cache_state.0, font_color, cursor_color, selection_color, selected_text_color, draw_closure, ); - editor.set_redraw(false); + // TODO: Performance optimization, read all possible render-input + // changes and only redraw if necessary + // editor.set_redraw(false); } else { if !buffer.redraw() { continue; } buffer.draw( &mut font_system.0, - &mut swash_cache_state.swash_cache, + &mut swash_cache_state.0, font_color, draw_closure, ); - buffer.set_redraw(false); + // TODO: Performance optimization, read all possible render-input + // changes and only redraw if necessary + // buffer.set_redraw(false); } - if let Some(prev_image) = images.get_mut(canvas) { + if let Some(prev_image) = images.get_mut(&canvas.0) { prev_image.data.clear(); // Updates the stored asset image with the computed pixels prev_image.data.extend_from_slice(pixels.as_slice()); prev_image.resize(Extent3d { - width: size.0.x as u32, - height: size.0.y as u32, + width: size.x as u32, + height: size.y as u32, depth_or_array_layers: 1, }); } diff --git a/src/render_targets.rs b/src/render_targets.rs new file mode 100644 index 0000000000000000000000000000000000000000..d7ddca2649f64e48886c1b5162697ab59daddd32 --- /dev/null +++ b/src/render_targets.rs @@ -0,0 +1,242 @@ +//! Generalizes over render target implementations. +//! +//! ## Sprite: +//! Requires [`Sprite`] component and requires [`Sprite.custom_size`] to be Some( non-zero ) +//! +//! ## UI: +//! Requires [`ImageNode`] for rendering and [`Button`] for [`Interaction`]s +// TODO: Remove `CosmicWidgetSize`? + +use bevy::{ + ecs::query::{QueryData, QueryFilter}, + window::SystemCursorIcon, + winit::cursor::CursorIcon, +}; + +use crate::{prelude::*, primary::CameraFilter, HoverCursor, TextHoverIn, TextHoverOut}; + +/// The top level UI text edit component +/// +/// Adding [`TextEdit`] will pull in the required components for setting up +/// a text edit widget, notably [`CosmicEditBuffer`] +/// +/// Hopefully this API will eventually mirror [`bevy::prelude::Text`]. +/// See [`CosmicEditBuffer`] for more information. +#[derive(Component)] +#[require(ImageNode, Button, CosmicEditBuffer)] +pub struct TextEdit; + +/// The top-level 2D text edit component +/// +/// Adding [`TextEdit2d`] will pull in the required components for setting up +/// a 2D text editor using a [`Sprite`] with [`Sprite.custom_size`] set, +/// to set the size of the text editor add a [`Sprite`] component with +/// [`Sprite.custom_size`] set. +/// +/// Hopefully this API will eventually mirror [`bevy::prelude::Text2d`]. +/// See [`CosmicEditBuffer`] for more information. +#[derive(Component)] +#[require(Sprite, CosmicEditBuffer)] +pub struct TextEdit2d; + +/// TODO: Generalize implementations depending on this +/// and add 3D +pub(crate) enum SourceType { + Ui, + Sprite, +} + +#[derive(Debug)] +pub(crate) enum RenderTargetError { + /// When no recognized [`SourceType`] could be found + NoTargetsAvailable, + + /// When more than one [`SourceType`] was detected. + /// + /// This will always be thrown if more than one target type is available, + /// there is no propritisation procedure as this should be considered a + /// logic error. + MoreThanOneTargetAvailable, + + /// When a [`RenderTypeScan`] was successfully conducted yet the expected + /// [required component/s](https://docs.rs/bevy/latest/bevy/ecs/prelude/trait.Component.html#required-components) + /// were not found + RequiredComponentNotAvailable, + + /// When using [`SourceType::Sprite`], you must set [`Sprite.custom_size`] + SpriteCustomSizeNotSet, +} + +type Result<T> = core::result::Result<T, RenderTargetError>; + +#[derive(QueryData)] +pub(crate) struct RenderTypeScan { + is_sprite: Has<TextEdit2d>, + is_ui: Has<TextEdit>, +} + +impl RenderTypeScanItem<'_> { + pub fn scan(&self) -> Result<SourceType> { + match (self.is_sprite, self.is_ui) { + (true, false) => Ok(SourceType::Sprite), + (false, true) => Ok(SourceType::Ui), + (true, true) => Err(RenderTargetError::MoreThanOneTargetAvailable), + (false, false) => Err(RenderTargetError::NoTargetsAvailable), + } + } +} + +/// Query the size of a widget using any [`SourceType`] +#[derive(QueryData)] +pub(crate) struct CosmicWidgetSize { + scan: RenderTypeScan, + sprite: Option<&'static Sprite>, + ui: Option<&'static ComputedNode>, +} + +/// Allows `.scan()` to be called on a [`CosmicWidgetSize`] through deref +impl<'s> std::ops::Deref for CosmicWidgetSizeItem<'s> { + type Target = RenderTypeScanItem<'s>; + + fn deref(&self) -> &Self::Target { + &self.scan + } +} + +/// An optimization [`QueryFilter`](bevy::ecs::query::QueryFilter) +#[derive(QueryFilter)] +pub(crate) struct ChangedCosmicWidgetSize { + sprite: Changed<Sprite>, + ui: Changed<ComputedNode>, +} + +pub(crate) trait NodeSizeExt { + fn logical_size(&self) -> Vec2; +} + +impl NodeSizeExt for ComputedNode { + fn logical_size(&self) -> Vec2 { + self.size() * self.inverse_scale_factor() + } +} + +impl CosmicWidgetSizeItem<'_> { + pub fn logical_size(&self) -> Result<Vec2> { + let source_type = self.scan.scan()?; + match source_type { + SourceType::Ui => { + let ui = self + .ui + .ok_or(RenderTargetError::RequiredComponentNotAvailable)?; + Ok(ui.logical_size()) + } + SourceType::Sprite => { + let sprite = self + .sprite + .ok_or(RenderTargetError::RequiredComponentNotAvailable)?; + Ok(sprite + .custom_size + .ok_or(RenderTargetError::SpriteCustomSizeNotSet)?) + } + } + } +} + +/// Function to find the location of the mouse cursor in a cosmic widget. +/// Returns in logical pixels +// TODO: Change this to use builtin `bevy::picking` instead +pub(crate) fn get_node_cursor_pos( + window: &Window, + node_transform: &GlobalTransform, + size: Vec2, + source_type: SourceType, + camera: &Camera, + camera_transform: &GlobalTransform, +) -> Option<Vec2> { + let node_translation = node_transform.affine().translation; + let node_bounds = Rect::new( + node_translation.x - size.x / 2., + node_translation.y - size.y / 2., + node_translation.x + size.x / 2., + node_translation.y + size.y / 2., + ); + + window.cursor_position().and_then(|pos| match source_type { + SourceType::Ui => { + if node_bounds.contains(pos) { + Some(Vec2::new( + pos.x - node_bounds.min.x, + pos.y - node_bounds.min.y, + )) + } else { + None + } + } + SourceType::Sprite => camera + .viewport_to_world_2d(camera_transform, pos) + .ok() + .and_then(|pos| { + if node_bounds.contains(pos) { + Some(Vec2::new( + pos.x - node_bounds.min.x, + node_bounds.max.y - pos.y, + )) + } else { + None + } + }), + }) +} + +pub(crate) fn hover_sprites( + windows: Query<&Window, With<bevy::window::PrimaryWindow>>, + mut cosmic_edit_query: Query< + (&mut Sprite, &Visibility, &GlobalTransform, &HoverCursor), + With<CosmicEditBuffer>, + >, + camera_q: Query<(&Camera, &GlobalTransform), CameraFilter>, + mut hovered: Local<bool>, + mut last_hovered: Local<bool>, + mut evw_hover_in: EventWriter<TextHoverIn>, + mut evw_hover_out: EventWriter<TextHoverOut>, +) { + *hovered = false; + if windows.iter().len() == 0 { + return; + } + let window = windows.single(); + let (camera, camera_transform) = camera_q.single(); + + let mut icon = CursorIcon::System(SystemCursorIcon::Default); + + for (sprite, visibility, node_transform, hover) in &mut cosmic_edit_query.iter_mut() { + if visibility == Visibility::Hidden { + continue; + } + + let size = sprite.custom_size.unwrap_or(Vec2::ONE); + if crate::render_targets::get_node_cursor_pos( + window, + node_transform, + size, + SourceType::Sprite, + camera, + camera_transform, + ) + .is_some() + { + *hovered = true; + icon = hover.0.clone(); + } + } + + if *last_hovered != *hovered { + if *hovered { + evw_hover_in.send(TextHoverIn(icon)); + } else { + evw_hover_out.send(TextHoverOut); + } + } + + *last_hovered = *hovered; +} diff --git a/src/snapshots/bevy_cosmic_edit__primary__tests__spawn_cosmic_edit.snap b/src/snapshots/bevy_cosmic_edit__primary__tests__spawn_cosmic_edit.snap new file mode 100644 index 0000000000000000000000000000000000000000..7acda1ac86102cfaac40928a23421470064c255e --- /dev/null +++ b/src/snapshots/bevy_cosmic_edit__primary__tests__spawn_cosmic_edit.snap @@ -0,0 +1,8 @@ +--- +source: src/primary.rs +expression: "cosmic_editor.lines.iter().map(|line| line.text()).collect::<Vec<_>>()" +snapshot_kind: text +--- +[ + "Blah", +] diff --git a/src/snapshots/bevy_cosmic_edit__tests__spawn_cosmic_edit.snap b/src/snapshots/bevy_cosmic_edit__tests__spawn_cosmic_edit.snap deleted file mode 100644 index f8ca0193927510ea0167ad6bdaadb6d4814c733e..0000000000000000000000000000000000000000 --- a/src/snapshots/bevy_cosmic_edit__tests__spawn_cosmic_edit.snap +++ /dev/null @@ -1,8 +0,0 @@ ---- -source: crates/bevy_cosmic_edit/src/lib.rs -assertion_line: 368 -expression: "node.editor.buffer().lines.iter().map(|line| line.text()).collect::<Vec<_>>()" ---- -[ - "Blah", -] diff --git a/src/user_select.rs b/src/user_select.rs index 1c573e7118bfffb232645ed4d7a6298ba03d51ff..af9e69e215d6043b5e61f67b2e2c38bf5e236cf5 100644 --- a/src/user_select.rs +++ b/src/user_select.rs @@ -1,5 +1,4 @@ -use crate::*; -use bevy::prelude::*; +use crate::{input::InputSet, prelude::*}; use cosmic_text::Edit; pub(crate) struct UserSelectPlugin; diff --git a/src/util.rs b/src/utils.rs similarity index 63% rename from src/util.rs rename to src/utils.rs index 7c5233d08c64e7133edf7a142aee7eb7d37a0443..12e9a4b66178291783f8bba4ca0a7a7138dda6b5 100644 --- a/src/util.rs +++ b/src/utils.rs @@ -1,6 +1,9 @@ // Common functions for examples -use crate::*; -use bevy::{prelude::*, window::PrimaryWindow}; +use crate::{ + cosmic_edit::ReadOnly, prelude::*, primary::CameraFilter, ChangedCosmicWidgetSize, + CosmicWidgetSize, +}; +use bevy::{ecs::query::QueryData, window::PrimaryWindow}; use cosmic_text::Edit; /// Trait for adding color conversion from [`bevy::prelude::Color`] to [`cosmic_text::Color`] @@ -32,50 +35,6 @@ pub fn deselect_editor_on_esc(i: Res<ButtonInput<KeyCode>>, mut focus: ResMut<Fo } } -/// Function to find the location of the mouse cursor in a cosmic widget -pub fn get_node_cursor_pos( - window: &Window, - node_transform: &GlobalTransform, - size: Vec2, - is_ui_node: bool, - camera: &Camera, - camera_transform: &GlobalTransform, -) -> Option<Vec2> { - let node_translation = node_transform.affine().translation; - let node_bounds = Rect::new( - node_translation.x - size.x / 2., - node_translation.y - size.y / 2., - node_translation.x + size.x / 2., - node_translation.y + size.y / 2., - ); - - window.cursor_position().and_then(|pos| { - if is_ui_node { - if node_bounds.contains(pos) { - Some(Vec2::new( - pos.x - node_bounds.min.x, - pos.y - node_bounds.min.y, - )) - } else { - None - } - } else { - camera - .viewport_to_world_2d(camera_transform, pos) - .and_then(|pos| { - if node_bounds.contains(pos) { - Some(Vec2::new( - pos.x - node_bounds.min.x, - node_bounds.max.y - pos.y, - )) - } else { - None - } - }) - } - }) -} - /// System to allow focus on click for sprite widgets pub fn change_active_editor_sprite( mut commands: Commands, @@ -83,9 +42,9 @@ pub fn change_active_editor_sprite( buttons: Res<ButtonInput<MouseButton>>, mut cosmic_edit_query: Query< (&mut Sprite, &GlobalTransform, &Visibility, Entity), - (With<CosmicBuffer>, Without<ReadOnly>), + (With<CosmicEditBuffer>, Without<ReadOnly>), >, - camera_q: Query<(&Camera, &GlobalTransform)>, + camera_q: Query<(&Camera, &GlobalTransform), CameraFilter>, ) { let window = windows.single(); let (camera, camera_transform) = camera_q.single(); @@ -100,7 +59,7 @@ pub fn change_active_editor_sprite( let x_max = node_transform.affine().translation.x + size.x / 2.; let y_max = node_transform.affine().translation.y + size.y / 2.; if let Some(pos) = window.cursor_position() { - if let Some(pos) = camera.viewport_to_world_2d(camera_transform, pos) { + if let Ok(pos) = camera.viewport_to_world_2d(camera_transform, pos) { if x_min < pos.x && pos.x < x_max && y_min < pos.y && pos.y < y_max { commands.insert_resource(FocusedWidget(Some(entity))) }; @@ -112,15 +71,19 @@ pub fn change_active_editor_sprite( /// System to allow focus on click for UI widgets pub fn change_active_editor_ui( - mut commands: Commands, mut interaction_query: Query< - (&Interaction, &CosmicSource), - (Changed<Interaction>, Without<ReadOnly>), + (&Interaction, Entity), + ( + Changed<Interaction>, + Without<ReadOnly>, + With<CosmicEditBuffer>, + ), >, + mut focussed_widget: ResMut<FocusedWidget>, ) { - for (interaction, source) in interaction_query.iter_mut() { + for (interaction, entity) in interaction_query.iter_mut() { if let Interaction::Pressed = interaction { - commands.insert_resource(FocusedWidget(Some(source.0))); + *focussed_widget = FocusedWidget(Some(entity)); } } } @@ -145,15 +108,44 @@ pub fn print_editor_text( } } +/// Quick utility to print the name of an entity if available +#[derive(QueryData)] +struct DebugName { + name: Option<&'static Name>, + entity: Entity, +} + +impl std::fmt::Debug for DebugNameItem<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // write!(f, "{:?} {:?}", self.name, self.entity) + match self.name { + Some(name) => write!(f, "DebugName::Name({:?})", name), + None => write!(f, "Entity({:?})", self.entity), + } + } +} + +/// Debug print the size of all editors +#[allow(dead_code)] +#[allow(private_interfaces)] +pub fn print_editor_sizes( + editors: Query<(CosmicWidgetSize, DebugName), (With<CosmicEditor>, ChangedCosmicWidgetSize)>, +) { + for (size, name) in editors.iter() { + println!("Size of editor {:?} is: {:?}", name, size.logical_size()); + } +} + /// Calls javascript to get the current timestamp #[cfg(target_arch = "wasm32")] -pub fn get_timestamp() -> f64 { +pub(crate) fn get_timestamp() -> f64 { js_sys::Date::now() } /// Utility function to get the current unix timestamp #[cfg(not(target_arch = "wasm32"))] -pub fn get_timestamp() -> f64 { +#[allow(dead_code)] // idk why this isn't used +pub(crate) fn get_timestamp() -> f64 { use std::time::SystemTime; use std::time::UNIX_EPOCH; let duration = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); diff --git a/src/widget.rs b/src/widget.rs index c6410afc7442765ce75d06ebeacde31bef3a72ed..1e2d1d35132ad61afa718460a5f7c740d9e68fc7 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -1,11 +1,18 @@ -use crate::*; -use bevy::{prelude::*, window::PrimaryWindow}; +use crate::buffer::get_x_offset_center; +use crate::buffer::get_y_offset_center; +use crate::cosmic_edit::CosmicTextAlign; +use crate::cosmic_edit::CosmicWrap; +use crate::cosmic_edit::XOffset; +use crate::input::InputSet; +use crate::prelude::*; +use crate::ChangedCosmicWidgetSize; +use crate::CosmicWidgetSize; use cosmic_text::Affinity; use cosmic_text::Edit; /// System set for cosmic text layout systems. Runs in [`PostUpdate`] #[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)] -pub struct WidgetSet; +pub(crate) struct WidgetSet; pub(crate) struct WidgetPlugin; @@ -15,8 +22,7 @@ impl Plugin for WidgetPlugin { .add_systems( PostUpdate, ( - (new_image_from_default, set_sprite_size_from_ui), - set_widget_size, + new_image_from_default, set_buffer_size, set_padding, set_x_offset, @@ -25,8 +31,7 @@ impl Plugin for WidgetPlugin { .in_set(WidgetSet) .after(TransformSystem::TransformPropagate), ) - .register_type::<CosmicPadding>() - .register_type::<CosmicWidgetSize>(); + .register_type::<CosmicPadding>(); } } @@ -34,14 +39,14 @@ impl Plugin for WidgetPlugin { /// This is set programatically, not for user modification. /// To set a widget's padding, use [`CosmicTextAlign`] #[derive(Component, Reflect, Default, Deref, DerefMut, Debug)] -pub struct CosmicPadding(pub Vec2); +pub(crate) struct CosmicPadding(pub(crate) Vec2); -/// Wrapper for a [`Vec2`] describing the horizontal and vertical size of a widget. -/// This is set programatically, not for user modification. -/// To set a widget's size, use either it's [`Sprite`] dimensions or modify the target UI element's -/// size. -#[derive(Component, Reflect, Default, Deref, DerefMut)] -pub struct CosmicWidgetSize(pub Vec2); +// /// Wrapper for a [`Vec2`] describing the horizontal and vertical size of a widget. +// /// This is set programatically, not for user modification. +// /// To set a widget's size, use either it's [`Sprite`] dimensions or modify the target UI element's +// /// size. +// #[derive(Component, Reflect, Default, Deref, DerefMut)] +// pub(crate) struct CosmicWidgetSize(pub(crate) Vec2); /// Reshapes text in a [`CosmicEditor`] fn reshape(mut query: Query<&mut CosmicEditor>, mut font_system: ResMut<CosmicFontSystem>) { @@ -56,19 +61,23 @@ fn set_padding( ( &mut CosmicPadding, &CosmicTextAlign, - &CosmicBuffer, - &CosmicWidgetSize, + &CosmicEditBuffer, + CosmicWidgetSize, Option<&CosmicEditor>, ), Or<( With<CosmicEditor>, Changed<CosmicTextAlign>, - Changed<CosmicBuffer>, - Changed<CosmicWidgetSize>, + Changed<CosmicEditBuffer>, + ChangedCosmicWidgetSize, )>, >, ) { for (mut padding, position, buffer, size, editor_opt) in query.iter_mut() { + let Ok(size) = size.logical_size() else { + continue; + }; + // TODO: At least one of these clones is uneccessary let mut buffer = buffer.0.clone(); @@ -82,51 +91,38 @@ fn set_padding( padding.0 = match position { CosmicTextAlign::Center { padding: _ } => Vec2::new( - get_x_offset_center(size.0.x, &buffer) as f32, - get_y_offset_center(size.0.y, &buffer) as f32, + get_x_offset_center(size.x, &buffer) as f32, + get_y_offset_center(size.y, &buffer) as f32, ), CosmicTextAlign::TopLeft { padding } => Vec2::new(*padding as f32, *padding as f32), - CosmicTextAlign::Left { padding } => Vec2::new( - *padding as f32, - get_y_offset_center(size.0.y, &buffer) as f32, - ), + CosmicTextAlign::Left { padding } => { + Vec2::new(*padding as f32, get_y_offset_center(size.y, &buffer) as f32) + } } } } -/// Programatically sets the [`CosmicWidgetSize`] of a widget based on it's [`Sprite`] properties -fn set_widget_size( - mut query: Query<(&mut CosmicWidgetSize, &Sprite), Changed<Sprite>>, - windows: Query<&Window, With<PrimaryWindow>>, -) { - if windows.iter().len() == 0 { - return; - } - // TODO: early return if sprite size is unchanged - let scale = windows.single().scale_factor(); - for (mut size, sprite) in query.iter_mut() { - size.0 = sprite.custom_size.unwrap().ceil() * scale; - } -} - /// Sets the internal [`Buffer`]'s size according to the [`CosmicWidgetSize`] and [`CosmicTextAlign`] fn set_buffer_size( mut query: Query< ( - &mut CosmicBuffer, + &mut CosmicEditBuffer, &CosmicWrap, - &CosmicWidgetSize, + CosmicWidgetSize, &CosmicTextAlign, ), Or<( Changed<CosmicWrap>, - Changed<CosmicWidgetSize>, + ChangedCosmicWidgetSize, Changed<CosmicTextAlign>, )>, >, mut font_system: ResMut<CosmicFontSystem>, ) { for (mut buffer, mode, size, position) in query.iter_mut() { + let Ok(size) = size.logical_size() else { + continue; + }; let padding_x = match position { CosmicTextAlign::Center { padding: _ } => 0., CosmicTextAlign::TopLeft { padding } => *padding as f32, @@ -134,21 +130,22 @@ fn set_buffer_size( }; let (buffer_width, buffer_height) = match mode { - CosmicWrap::InfiniteLine => (f32::MAX, size.0.y), - CosmicWrap::Wrap => (size.0.x - padding_x, size.0.y), + CosmicWrap::InfiniteLine => (f32::MAX, size.y), + CosmicWrap::Wrap => (size.x - padding_x, size.y), }; buffer.set_size(&mut font_system.0, Some(buffer_width), Some(buffer_height)); } } -/// Instantiates a new image for a [`CosmicBuffer`] +/// Instantiates a new image for a [`CosmicEditBuffer`] fn new_image_from_default( - mut query: Query<&mut Handle<Image>, Added<CosmicBuffer>>, + mut query: Query<&mut CosmicRenderOutput, Added<CosmicEditBuffer>>, mut images: ResMut<Assets<Image>>, ) { for mut canvas in query.iter_mut() { - *canvas = images.add(Image::default()); + debug!(message = "Initializing a new canvas"); + *canvas = CosmicRenderOutput(images.add(Image::default())); } } @@ -157,30 +154,39 @@ fn set_x_offset( &mut XOffset, &CosmicWrap, &CosmicEditor, - &CosmicWidgetSize, + CosmicWidgetSize, &CosmicTextAlign, )>, ) { for (mut x_offset, mode, editor, size, position) in query.iter_mut() { + let Ok(size) = size.logical_size() else { + continue; + }; if mode != &CosmicWrap::InfiniteLine { - return; + continue; // this used to be `return` though I feel like it should be continue } let mut cursor_x = 0.; let cursor = editor.cursor(); + // counts the width of the glyphs up to the cursor in `cursor_x` if let Some(line) = editor.with_buffer(|b| b.clone()).layout_runs().next() { for (idx, glyph) in line.glyphs.iter().enumerate() { - if cursor.affinity == Affinity::Before { - if idx <= cursor.index { - cursor_x += glyph.w; - } else { - break; + match cursor.affinity { + Affinity::Before => { + if idx <= cursor.index { + cursor_x += glyph.w; + } else { + break; + } + } + Affinity::After => { + if idx < cursor.index { + cursor_x += glyph.w; + } else { + break; + } } - } else if idx < cursor.index { - cursor_x += glyph.w; - } else { - break; } } } @@ -191,11 +197,11 @@ fn set_x_offset( CosmicTextAlign::Left { padding } => *padding as f32, }; - if x_offset.width == 0. { - x_offset.width = size.x - padding_x * 2.; + if x_offset.width.is_none() { + x_offset.width = Some(size.x - padding_x * 2.); } - let right = x_offset.width + x_offset.left; + let right = x_offset.width.unwrap() + x_offset.left; if cursor_x > right { let diff = cursor_x - right; @@ -207,14 +213,3 @@ fn set_x_offset( } } } - -fn set_sprite_size_from_ui( - mut source_q: Query<&mut Sprite, With<CosmicBuffer>>, - dest_q: Query<(&Node, &CosmicSource), Changed<Node>>, -) { - for (node, source) in dest_q.iter() { - if let Ok(mut sprite) = source_q.get_mut(source.0) { - sprite.custom_size = Some(node.size().ceil().max(Vec2::ONE)); - } - } -}