From af2aaae374ddc41ffd24f0e6855e8a35f5a4edf4 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Thu, 26 Dec 2024 13:21:09 +0900 Subject: [PATCH 01/12] feat(prefs): add slint UI skeleton --- Cargo.lock | 5201 +++++++++++++++++++- Cargo.toml | 2 +- preferences/Cargo.toml | 17 + preferences/build.rs | 3 + preferences/design/chewing-editor-flow.png | Bin 0 -> 248787 bytes preferences/src/editor.rs | 224 + preferences/src/main.rs | 17 + preferences/ui/app-window.slint | 172 + preferences/ui/editor-window.slint | 237 + preferences/ui/index.slint | 4 + 10 files changed, 5623 insertions(+), 254 deletions(-) create mode 100644 preferences/Cargo.toml create mode 100644 preferences/build.rs create mode 100644 preferences/design/chewing-editor-flow.png create mode 100644 preferences/src/editor.rs create mode 100644 preferences/src/main.rs create mode 100644 preferences/ui/app-window.slint create mode 100644 preferences/ui/editor-window.slint create mode 100644 preferences/ui/index.slint diff --git a/Cargo.lock b/Cargo.lock index 6b8ef0a..607cdad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,120 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ab_glyph" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + +[[package]] +name = "accesskit" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3d3b8f9bae46a948369bc4a03e815d4ed6d616bd00de4051133a5019dc31c5a" + +[[package]] +name = "accesskit_atspi_common" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c5dd55e6e94949498698daf4d48fb5659e824d7abec0d394089656ceaf99d4f" +dependencies = [ + "accesskit", + "accesskit_consumer", + "atspi-common", + "serde", + "thiserror", + "zvariant", +] + +[[package]] +name = "accesskit_consumer" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f47983a1084940ba9a39c077a8c63e55c619388be5476ac04c804cfbd1e63459" +dependencies = [ + "accesskit", + "hashbrown 0.15.2", + "immutable-chunkmap", +] + +[[package]] +name = "accesskit_macos" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7329821f3bd1101e03a7d2e03bd339e3ac0dc64c70b4c9f9ae1949e3ba8dece1" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.15.2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "accesskit_unix" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcee751cc20d88678c33edaf9c07e8b693cd02819fe89053776f5313492273f5" +dependencies = [ + "accesskit", + "accesskit_atspi_common", + "async-channel", + "async-executor", + "async-task", + "atspi", + "futures-lite", + "futures-util", + "serde", + "zbus", +] + +[[package]] +name = "accesskit_windows" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24fcd5d23d70670992b823e735e859374d694a3d12bfd8dd32bd3bd8bedb5d81" +dependencies = [ + "accesskit", + "accesskit_consumer", + "hashbrown 0.15.2", + "paste", + "static_assertions", + "windows", + "windows-core 0.58.0", +] + +[[package]] +name = "accesskit_winit" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6a48dad5530b6deb9fc7a52cc6c3bf72cdd9eb8157ac9d32d69f2427a5e879" +dependencies = [ + "accesskit", + "accesskit_macos", + "accesskit_unix", + "accesskit_windows", + "raw-window-handle", + "winit", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "ahash" version = "0.8.11" @@ -9,11 +123,69 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android-activity" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.6.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" version = "1.0.95" @@ -21,496 +193,4537 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] -name = "bitflags" -version = "2.6.0" +name = "arrayref" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] -name = "cc" -version = "1.2.5" +name = "arrayvec" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "ashpd" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d43c03d9e36dd40cab48435be0b09646da362c278223ca535493877b2c1dee9" dependencies = [ - "shlex", + "async-fs", + "async-net", + "enumflags2", + "futures-channel", + "futures-util", + "rand", + "serde", + "serde_repr", + "url", + "zbus", ] [[package]] -name = "cfg-if" -version = "1.0.0" +name = "async-broadcast" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] [[package]] -name = "chewing" -version = "0.9.1" +name = "async-channel" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990478084d4eb9ca92513d75e780be2062dbab9dc46a3a656f622639a697d31c" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ - "der", - "directories", - "log", - "rusqlite", + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", ] [[package]] -name = "chewing_capi" -version = "0.9.1" +name = "async-executor" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf423f10275a7ccb3f268a35c4e736fa37b71485b12dc65f870e0fb0bda389f" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ - "chewing", - "env_logger", - "log", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", ] [[package]] -name = "chewing_tip" -version = "24.10.1" +name = "async-fs" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" dependencies = [ - "anyhow", - "cc", - "chewing_capi", - "embed-resource", - "getrandom", - "log", - "nine_patch_drawable", - "win_dbg_logger", - "windows", - "windows-core", + "async-lock", + "blocking", + "futures-lite", ] [[package]] -name = "der" -version = "0.7.9" +name = "async-io" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" dependencies = [ - "zeroize", + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", ] [[package]] -name = "directories" -version = "5.0.1" +name = "async-lock" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "dirs-sys", + "event-listener", + "event-listener-strategy", + "pin-project-lite", ] [[package]] -name = "dirs-sys" -version = "0.4.1" +name = "async-net" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7" dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys", + "async-io", + "blocking", + "futures-lite", ] [[package]] -name = "embed-resource" -version = "3.0.1" +name = "async-process" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4762ce03154ba57ebaeee60cc631901ceae4f18219cbb874e464347471594742" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" dependencies = [ - "cc", - "memchr", - "rustc_version", - "toml", - "vswhom", - "winreg", + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", + "tracing", ] [[package]] -name = "env_filter" -version = "0.1.3" +name = "async-recursion" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ - "log", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "env_logger" -version = "0.11.6" +name = "async-signal" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "env_filter", + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atspi" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be534b16650e35237bb1ed189ba2aab86ce65e88cc84c66f4935ba38575cecbf" +dependencies = [ + "atspi-common", + "atspi-connection", + "atspi-proxies", +] + +[[package]] +name = "atspi-common" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1909ed2dc01d0a17505d89311d192518507e8a056a48148e3598fef5e7bb6ba7" +dependencies = [ + "enumflags2", + "serde", + "static_assertions", + "zbus", + "zbus-lockstep", + "zbus-lockstep-macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "atspi-connection" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "430c5960624a4baaa511c9c0fcc2218e3b58f5dbcc47e6190cafee344b873333" +dependencies = [ + "atspi-common", + "atspi-proxies", + "futures-lite", + "zbus", +] + +[[package]] +name = "atspi-proxies" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e6c5de3e524cf967569722446bcd458d5032348554d9a17d7d72b041ab7496" +dependencies = [ + "atspi-common", + "serde", + "zbus", + "zvariant", +] + +[[package]] +name = "auto_enums" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459b77b7e855f875fd15f101064825cd79eb83185a961d66e6298560126facfb" +dependencies = [ + "derive_utils", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.12.1", + "lazy_static", + "lazycell", "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "borsh" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" +dependencies = [ + "cfg_aliases", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "by_address" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" + +[[package]] +name = "bytemuck" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" + +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.6.0", + "log", + "polling", + "rustix", + "slab", + "thiserror", +] + +[[package]] +name = "calloop" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10929724661d1c43856fd87c7a127ae944ec55579134fb485e4136fb6a46fdcb" +dependencies = [ + "bitflags 2.6.0", + "polling", + "rustix", + "slab", + "tracing", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop 0.13.0", + "rustix", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "cc" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cesu8" +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-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + +[[package]] +name = "chewing" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990478084d4eb9ca92513d75e780be2062dbab9dc46a3a656f622639a697d31c" +dependencies = [ + "der", + "directories", + "log", + "rusqlite", +] + +[[package]] +name = "chewing" +version = "0.9.1" +source = "git+https://github.com/chewing/libchewing?branch=feat-dictionary-mgmt-api#95f6eeb9e4133de6e4900f47174edfd04e564b45" +dependencies = [ + "der", + "directories", + "log", + "rusqlite", +] + +[[package]] +name = "chewing-preferences" +version = "0.1.0" +dependencies = [ + "anyhow", + "chewing 0.9.1 (git+https://github.com/chewing/libchewing?branch=feat-dictionary-mgmt-api)", + "slint", + "slint-build", +] + +[[package]] +name = "chewing_capi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf423f10275a7ccb3f268a35c4e736fa37b71485b12dc65f870e0fb0bda389f" +dependencies = [ + "chewing 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger", + "log", +] + +[[package]] +name = "chewing_tip" +version = "24.10.1" +dependencies = [ + "anyhow", + "cc", + "chewing_capi", + "embed-resource", + "getrandom", + "log", + "nine_patch_drawable", + "win_dbg_logger", + "windows", + "windows-core 0.58.0", +] + +[[package]] +name = "chrono" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[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 = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342" +dependencies = [ + "lazy-bytes-cast", + "winapi", +] + +[[package]] +name = "clru" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" + +[[package]] +name = "codemap" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e769b5c8c8283982a987c6e948e540254f1058d5a74b8794914d4ef5fc2a24" + +[[package]] +name = "codemap-diagnostic" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc20770be05b566a963bf91505e60412c4a2d016d1ef95c5512823bb085a8122" +dependencies = [ + "codemap", + "termcolor", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-field-offset" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fcde4ca1211b5a94b573083c472ee19e86b19a441913f66e1cc5c41daf0255" +dependencies = [ + "const-field-offset-macro", + "field-offset", +] + +[[package]] +name = "const-field-offset-macro" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5387f5bbc9e9e6c96436ea125afa12614cebf8ac67f49abc08c1e7a891466c90" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "copypasta" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb85422867ca93da58b7f95fb5c0c10f6183ed6e1ef8841568968a896d3a858" +dependencies = [ + "clipboard-win", + "objc", + "objc-foundation", + "objc_id", + "smithay-clipboard", + "x11-clipboard", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "core-graphics-types 0.1.3", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.10.0", + "core-graphics-types 0.2.0", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.10.0", + "libc", +] + +[[package]] +name = "core-text" +version = "20.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5" +dependencies = [ + "core-foundation 0.9.4", + "core-graphics 0.23.2", + "foreign-types", + "libc", +] + +[[package]] +name = "core_maths" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b02505ccb8c50b0aa21ace0fc08c3e53adebd4e58caa18a36152803c7709a3" +dependencies = [ + "libm", +] + +[[package]] +name = "countme" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" + +[[package]] +name = "cpp" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bcac3d8234c1fb813358e83d1bb6b0290a3d2b3b5efc6b88bfeaf9d8eec17" +dependencies = [ + "cpp_macros", +] + +[[package]] +name = "cpp_build" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f8638c97fbd79cc6fc80b616e0e74b49bac21014faed590bbc89b7e2676c90" +dependencies = [ + "cc", + "cpp_common", + "lazy_static", + "proc-macro2", + "regex", + "syn", + "unicode-xid", +] + +[[package]] +name = "cpp_common" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25fcfea2ee05889597d35e986c2ad0169694320ae5cc8f6d2640a4bb8a884560" +dependencies = [ + "lazy_static", + "proc-macro2", + "syn", +] + +[[package]] +name = "cpp_macros" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d156158fe86e274820f5a53bc9edb0885a6e7113909497aa8d883b69dd171871" +dependencies = [ + "aho-corasick", + "byteorder", + "cpp_common", + "lazy_static", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctor-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f791803201ab277ace03903de1594460708d2d54df6053f2d9e82f592b19e3b" + +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + +[[package]] +name = "data-url" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "zeroize", +] + +[[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 = "derive_utils" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65f152f4b8559c4da5d574bafc7af85454d706b4c5fe8b530d508cacbb6807ea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "directories" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +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 = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" + +[[package]] +name = "drm" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80bc8c5c6c2941f70a55c15f8d9f00f9710ebda3ffda98075f996a0e6c92756f" +dependencies = [ + "bitflags 2.6.0", + "bytemuck", + "drm-ffi", + "drm-fourcc", + "libc", + "rustix", +] + +[[package]] +name = "drm-ffi" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8e41459d99a9b529845f6d2c909eb9adf3b6d2f82635ae40be8de0601726e8b" +dependencies = [ + "drm-sys", + "rustix", +] + +[[package]] +name = "drm-fourcc" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" + +[[package]] +name = "drm-sys" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bafb66c8dbc944d69e15cfcc661df7e703beffbaec8bd63151368b06c5f9858c" +dependencies = [ + "libc", + "linux-raw-sys 0.6.5", +] + +[[package]] +name = "dwrote" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70182709525a3632b2ba96b6569225467b18ecb4a77f46d255f713a6bebf05fd" +dependencies = [ + "lazy_static", + "libc", + "serde", + "serde_derive", + "winapi", + "wio", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "embed-resource" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4762ce03154ba57ebaeee60cc631901ceae4f18219cbb874e464347471594742" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml", + "vswhom", + "winreg", +] + +[[package]] +name = "endi" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" + +[[package]] +name = "enumflags2" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", +] + +[[package]] +name = "env_logger" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +dependencies = [ + "env_filter", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "euclid" +version = "0.22.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" +dependencies = [ + "num-traits", +] + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "exr" +version = "1.73.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "femtovg" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eafc3dd3c956423a6669e1f6f9ab23261dbe45cdb24ce23dba38b0389b8a8ff8" +dependencies = [ + "bitflags 2.6.0", + "bytemuck", + "fnv", + "glow 0.15.0", + "image 0.25.5", + "imgref", + "log", + "lru", + "rgb", + "rustybuzz 0.20.1", + "slotmap", + "unicode-bidi", + "unicode-segmentation", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + +[[package]] +name = "flate2" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + +[[package]] +name = "fontconfig-parser" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1fcfcd44ca6e90c921fee9fa665d530b21ef1327a4c1a6c5250ea44b776ada7" +dependencies = [ + "roxmltree", +] + +[[package]] +name = "fontdb" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3a6f9af55fb97ad673fb7a69533eb2f967648a06fa21f8c9bb2cd6d33975716" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser 0.24.1", +] + +[[package]] +name = "fontdue" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efe23d02309319171d00d794c9ff48d4f903c0e481375b1b04b017470838af04" +dependencies = [ + "hashbrown 0.14.5", + "rayon", + "ttf-parser 0.21.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "foreign-types-shared" +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" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gbm" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa9a106f044fbd21edf2d8cc57300df1e60630e46ed4bebd59cdcbb23cfad1ce" +dependencies = [ + "bitflags 2.6.0", + "drm", + "drm-fourcc", + "gbm-sys", + "libc", +] + +[[package]] +name = "gbm-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9cc2f64de9fa707b5c6b2d2f10d7a7e49e845018a9f5685891eb40d3bab2538" +dependencies = [ + "libc", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glow" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33cd8ff5e02c1a5463ec10a846c8f3166a3ae0382ec33de6a327ea6dd61c41d" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glutin" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec69412a0bf07ea7607e638b415447857a808846c2b685a43c8aa18bc6d5e499" +dependencies = [ + "bitflags 2.6.0", + "cfg_aliases", + "cgl", + "core-foundation 0.9.4", + "dispatch", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae99fff4d2850dbe6fb8c1fa8e4fead5525bab715beaacfccf3fb994e01c827" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2b2d3918e76e18e08796b55eb64e8fe6ec67d5a6b2e2a7e2edce224ad24c63" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" +dependencies = [ + "gl_generator", +] + +[[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", + "rayon", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown 0.14.5", +] + +[[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.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "i-slint-backend-linuxkms" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2205814bb3595d50142989dc23d4c2fd679f77d2111d3ae77e72da0b320c6bb6" +dependencies = [ + "bytemuck", + "calloop 0.14.2", + "drm", + "gbm", + "glutin", + "i-slint-common", + "i-slint-core", + "i-slint-renderer-femtovg", + "input", + "memmap2", + "nix", + "raw-window-handle", + "xkbcommon", +] + +[[package]] +name = "i-slint-backend-qt" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c76a92e93fc70a88dac3bf29986dbb31d6de30834c3a8599fe4e3e4531442840" +dependencies = [ + "const-field-offset", + "cpp", + "cpp_build", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "lyon_path", + "once_cell", + "pin-project", + "pin-weak", + "qttypes", + "vtable", +] + +[[package]] +name = "i-slint-backend-selector" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13cddb850ff15d5878ffed582333b1052c2f34ef5fa8c96374556212d3dfb6f0" +dependencies = [ + "cfg-if", + "i-slint-backend-linuxkms", + "i-slint-backend-qt", + "i-slint-backend-winit", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", +] + +[[package]] +name = "i-slint-backend-winit" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43733630d6572f12212538d1e07457344f0649f64f0fd5d2508e1067fe907520" +dependencies = [ + "accesskit", + "accesskit_winit", + "ashpd", + "bytemuck", + "cfg-if", + "cfg_aliases", + "copypasta", + "derive_more", + "futures", + "glutin", + "glutin-winit", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "i-slint-renderer-femtovg", + "i-slint-renderer-skia", + "imgref", + "lyon_path", + "objc2-app-kit", + "once_cell", + "pin-weak", + "raw-window-handle", + "rgb", + "scoped-tls-hkt", + "scopeguard", + "softbuffer", + "wasm-bindgen", + "web-sys", + "winit", +] + +[[package]] +name = "i-slint-common" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c8f37e2d962b87cebc290f1d14ad86602a1feec10bea545353b817a832dc66" +dependencies = [ + "cfg-if", + "derive_more", + "fontdb", + "libloading", + "ttf-parser 0.25.1", +] + +[[package]] +name = "i-slint-compiler" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b10773b4a1ef9cc0432274311f0788a4dbb0f45d5e0c726ca39755127e04a482" +dependencies = [ + "by_address", + "codemap", + "codemap-diagnostic", + "derive_more", + "fontdue", + "i-slint-common", + "image 0.24.9", + "itertools 0.13.0", + "linked_hash_set", + "lyon_extra", + "lyon_path", + "num_enum", + "once_cell", + "polib", + "proc-macro2", + "quote", + "rayon", + "resvg", + "rowan", + "smol_str 0.3.2", + "strum", + "thiserror", + "url", +] + +[[package]] +name = "i-slint-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7be38ffa35b2fad74712d563e7ffec655988ae215e3a6cfa35d603fb6115b79" +dependencies = [ + "auto_enums", + "bitflags 2.6.0", + "bytemuck", + "cfg-if", + "chrono", + "clru", + "const-field-offset", + "derive_more", + "euclid", + "fontdue", + "i-slint-common", + "i-slint-core-macros", + "image 0.24.9", + "integer-sqrt", + "lyon_algorithms", + "lyon_extra", + "lyon_geom", + "lyon_path", + "num-traits", + "once_cell", + "pin-project", + "pin-weak", + "portable-atomic", + "raw-window-handle", + "resvg", + "rgb", + "rustybuzz 0.20.1", + "scoped-tls-hkt", + "scopeguard", + "slab", + "static_assertions", + "strum", + "sys-locale", + "unicode-linebreak", + "unicode-script", + "unicode-segmentation", + "vtable", + "wasm-bindgen", + "web-sys", + "web-time", +] + +[[package]] +name = "i-slint-core-macros" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83e6bd30e51baa7adb1c1e04111ac71713ce032ce16c36e62a334f8c45b734e" +dependencies = [ + "quote", + "serde_json", + "syn", +] + +[[package]] +name = "i-slint-renderer-femtovg" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fae14836679021643350771c909af81f2d372e020478b22353a8480e2b96576a" +dependencies = [ + "cfg-if", + "const-field-offset", + "core-foundation 0.9.4", + "core-text", + "derive_more", + "dwrote", + "femtovg", + "glow 0.15.0", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "imgref", + "lyon_path", + "once_cell", + "pin-weak", + "rgb", + "scoped-tls-hkt", + "ttf-parser 0.25.1", + "unicode-script", + "unicode-segmentation", + "wasm-bindgen", + "web-sys", + "winapi", +] + +[[package]] +name = "i-slint-renderer-skia" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36dcdbc1ca419b670e94e957a23b137739db5c7b0508c39b740e199db0eea2bb" +dependencies = [ + "bytemuck", + "cfg-if", + "cfg_aliases", + "const-field-offset", + "derive_more", + "glow 0.13.1", + "glutin", + "i-slint-common", + "i-slint-core", + "i-slint-core-macros", + "lyon_path", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-metal", + "objc2-quartz-core", + "once_cell", + "pin-weak", + "raw-window-handle", + "raw-window-metal", + "scoped-tls-hkt", + "skia-safe", + "softbuffer", + "unicode-segmentation", + "vtable", + "windows", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +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 = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "image" +version = "0.24.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-traits", + "png", + "qoi", + "tiff", +] + +[[package]] +name = "image" +version = "0.25.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" +dependencies = [ + "bytemuck", + "byteorder-lite", + "num-traits", +] + +[[package]] +name = "imagesize" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" + +[[package]] +name = "imgref" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" + +[[package]] +name = "immutable-chunkmap" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f97096f508d54f8f8ab8957862eee2ccd628847b6217af1a335e1c44dee578" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", +] + +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + +[[package]] +name = "input" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbdc09524a91f9cacd26f16734ff63d7dc650daffadd2b6f84d17a285bd875a9" +dependencies = [ + "bitflags 2.6.0", + "input-sys", + "libc", + "log", + "udev", +] + +[[package]] +name = "input-sys" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd4f5b4d1c00331c5245163aacfe5f20be75b564c7112d45893d4ae038119eb0" + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "jiff" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db69f08d4fb10524cacdb074c10b296299d71274ddbc830a8ee65666867002e9" + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "kurbo" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89234b2cc610a7dd927ebde6b41dd1a5d4214cffaef4cf1fb2195d592f92518f" +dependencies = [ + "arrayvec", + "smallvec", +] + +[[package]] +name = "lazy-bytes-cast" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall 0.5.8", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "linereader" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d921fea6860357575519aca014c6e22470585accdd543b370c404a8a72d0dd1d" +dependencies = [ + "memchr", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linked_hash_set" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae85b5be22d9843c80e5fc80e9b64c8a3b1f98f867c709956eca3efff4e92e2" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "linux-raw-sys" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" + +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" + +[[package]] +name = "lyon_algorithms" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f13c9be19d257c7d37e70608ed858e8eab4b2afcea2e3c9a622e892acbf43c08" +dependencies = [ + "lyon_path", + "num-traits", +] + +[[package]] +name = "lyon_extra" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca94c7bf1e2557c2798989c43416822c12fc5dcc5e17cc3307ef0e71894a955" +dependencies = [ + "lyon_path", + "thiserror", +] + +[[package]] +name = "lyon_geom" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8af69edc087272df438b3ee436c4bb6d7c04aa8af665cfd398feae627dbd8570" +dependencies = [ + "arrayvec", + "euclid", + "num-traits", +] + +[[package]] +name = "lyon_path" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e0b8aec2f58586f6eef237985b9a9b7cb3a3aff4417c575075cf95bf925252e" +dependencies = [ + "lyon_geom", + "num-traits", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.6.0", + "jni-sys", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nine_patch_drawable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96e2f356f3fbb4179ee2a3d76ed2881553b93213a421a28975b2ea0c8d81d15" + +[[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", + "libc", + "memoffset", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +dependencies = [ + "critical-section", + "portable-atomic", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "orbclient" +version = "0.3.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" +dependencies = [ + "libredox", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +dependencies = [ + "ttf-parser 0.25.1", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pin-weak" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b330c9d1b92dfe68442ca20b009c717d5f0b1e3cf4965e62f704c3c6e95a1305" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polib" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b393b155cf9be86249cba1b56cc81be0e6212c66d94ac0d76d37a1761f3bb1b" +dependencies = [ + "linereader", +] + +[[package]] +name = "polling" +version = "3.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "portable-atomic" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" +dependencies = [ + "critical-section", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[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.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "qttypes" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7edf5b38c97ad8900ad2a8418ee44b4adceaa866a4a3405e2f1c909871d7ebd" +dependencies = [ + "cpp", + "cpp_build", + "semver", +] + +[[package]] +name = "quick-xml" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +dependencies = [ + "memchr", + "serde", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "raw-window-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2000e45d7daa9b6d946e88dfa1d7ae330424a81918a6545741821c989eb80a9" +dependencies = [ + "objc2", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "resvg" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a325d5e8d1cebddd070b13f44cec8071594ab67d1012797c121f27a669b7958" +dependencies = [ + "log", + "pico-args", + "rgb", + "svgtypes", + "tiny-skia", + "usvg", +] + +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "rowan" +version = "0.15.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d" +dependencies = [ + "countme", + "hashbrown 0.14.5", + "rustc-hash", + "text-size", +] + +[[package]] +name = "roxmltree" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" + +[[package]] +name = "rusqlite" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" +dependencies = [ + "bitflags 2.6.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys 0.4.14", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "rustybuzz" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85d1ccd519e61834798eb52c4e886e8c2d7d698dd3d6ce0b1b47eb8557f1181" +dependencies = [ + "bitflags 2.6.0", + "bytemuck", + "core_maths", + "log", + "smallvec", + "ttf-parser 0.24.1", + "unicode-bidi-mirroring 0.3.0", + "unicode-ccc 0.3.0", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "rustybuzz" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c7c96f8a08ee34eff8857b11b49b07d71d1c3f4e88f8a88d4c9e9f90b1702" +dependencies = [ + "bitflags 2.6.0", + "bytemuck", + "core_maths", + "log", + "smallvec", + "ttf-parser 0.25.1", + "unicode-bidi-mirroring 0.4.0", + "unicode-ccc 0.4.0", + "unicode-properties", + "unicode-script", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +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 = "scoped-tls-hkt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9603871ffe5df3ac39cb624790c296dbd47a400d202f56bf3e414045099524d" + +[[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 = "semver" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" + +[[package]] +name = "serde" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simplecss" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d" +dependencies = [ + "log", +] + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "skia-bindings" +version = "0.78.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29880a81b088de322e9c5306236c70761a61b5fa4df3c15c93bad3ce890ce34c" +dependencies = [ + "bindgen", + "cc", + "flate2", + "heck", + "lazy_static", + "regex", + "serde_json", + "tar", + "toml", +] + +[[package]] +name = "skia-safe" +version = "0.78.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f15700ac678c06649077495acbba07e7ae01e5ca46b7dc18213f2c3477ada71" +dependencies = [ + "bitflags 2.6.0", + "lazy_static", + "skia-bindings", + "windows", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slint" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7fa686cfc5a16a737a6867fbff09d5d41133fc6502bf0f2be786684e9991e8b" +dependencies = [ + "const-field-offset", + "i-slint-backend-qt", + "i-slint-backend-selector", + "i-slint-core", + "i-slint-core-macros", + "i-slint-renderer-femtovg", + "num-traits", + "once_cell", + "pin-weak", + "slint-macros", + "vtable", +] + +[[package]] +name = "slint-build" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b27768c67dff5081261fba5b2a3fa0609912dfbf8a73020c60e2b6028445bc" +dependencies = [ + "i-slint-compiler", + "i-slint-core-macros", + "spin_on", + "thiserror", + "toml_edit", +] + +[[package]] +name = "slint-macros" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57966e7358ec95d69ce94ea9dab9231efcc4714fe725d3ed8c27cb8e98c792bc" +dependencies = [ + "i-slint-compiler", + "proc-macro2", + "quote", + "spin_on", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +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 0.13.0", + "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 = "smithay-clipboard" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" +dependencies = [ + "libc", + "smithay-client-toolkit", + "wayland-backend", +] + +[[package]] +name = "smol_str" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" +dependencies = [ + "serde", +] + +[[package]] +name = "smol_str" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9676b89cd56310a87b93dec47b11af744f34d5fc9f367b829474eec0a891350d" +dependencies = [ + "borsh", + "serde", +] + +[[package]] +name = "softbuffer" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08" +dependencies = [ + "as-raw-xcb-connection", + "bytemuck", + "cfg_aliases", + "core-graphics 0.24.0", + "fastrand", + "foreign-types", + "js-sys", + "log", + "memmap2", + "objc2", + "objc2-foundation", + "objc2-quartz-core", + "raw-window-handle", + "redox_syscall 0.5.8", + "rustix", + "tiny-xlib", + "wasm-bindgen", + "wayland-backend", + "wayland-client", + "wayland-sys", + "web-sys", + "windows-sys 0.59.0", + "x11rb", +] + +[[package]] +name = "spin_on" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076e103ed41b9864aa838287efe5f4e3a7a0362dd00671ae62a212e5e4612da2" +dependencies = [ + "pin-utils", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[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" +dependencies = [ + "float-cmp", +] + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "svgtypes" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794de53cc48eaabeed0ab6a3404a65f40b3e38c067e4435883a65d2aa4ca000e" +dependencies = [ + "kurbo", + "siphasher", +] + +[[package]] +name = "syn" +version = "2.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sys-locale" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" +dependencies = [ + "libc", +] + +[[package]] +name = "tar" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c65998313f8e17d0d553d28f91a0df93e4dbbbf770279c7bc21ca0f09ea1a1f6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "text-size" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" + +[[package]] +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 = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "png", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "tiny-xlib" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0324504befd01cab6e0c994f34b2ffa257849ee019d3fb3b64fb2c858887d89e" +dependencies = [ + "as-raw-xcb-connection", + "ctor-lite", + "libloading", + "pkg-config", + "tracing", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tsfreg" +version = "24.10.1" +dependencies = [ + "windows", +] + +[[package]] +name = "ttf-parser" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" + +[[package]] +name = "ttf-parser" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a" +dependencies = [ + "core_maths", +] + +[[package]] +name = "ttf-parser" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" +dependencies = [ + "core_maths", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "udev" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d5c197b95f1769931c89f85c33c407801d1fb7a311113bc0b39ad036f1bd81" +dependencies = [ + "io-lifetimes", + "libc", + "libudev-sys", + "pkg-config", +] + +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset", + "tempfile", + "winapi", ] [[package]] -name = "equivalent" -version = "1.0.1" +name = "unicode-bidi" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" [[package]] -name = "fallible-iterator" +name = "unicode-bidi-mirroring" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" +checksum = "64af057ad7466495ca113126be61838d8af947f41d93a949980b2389a118082f" [[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" +name = "unicode-bidi-mirroring" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +checksum = "5dfa6e8c60bb66d49db113e0125ee8711b7647b5579dc7f5f19c42357ed039fe" [[package]] -name = "getrandom" -version = "0.2.15" +name = "unicode-ccc" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] +checksum = "260bc6647b3893a9a90668360803a15f96b85a5257b1c3a0c3daf6ae2496de42" [[package]] -name = "hashbrown" -version = "0.14.5" +name = "unicode-ccc" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", -] +checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e" [[package]] -name = "hashbrown" -version = "0.15.2" +name = "unicode-ident" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] -name = "hashlink" -version = "0.9.1" +name = "unicode-linebreak" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" -dependencies = [ - "hashbrown 0.14.5", -] +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] -name = "indexmap" -version = "2.7.0" +name = "unicode-properties" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" -dependencies = [ - "equivalent", - "hashbrown 0.15.2", -] +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] -name = "indoc" -version = "2.0.5" +name = "unicode-script" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" +checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f" [[package]] -name = "jiff" -version = "0.1.15" +name = "unicode-segmentation" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db69f08d4fb10524cacdb074c10b296299d71274ddbc830a8ee65666867002e9" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] -name = "libc" -version = "0.2.169" +name = "unicode-vo" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" [[package]] -name = "libredox" -version = "0.1.3" +name = "unicode-xid" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ - "bitflags", - "libc", + "form_urlencoded", + "idna", + "percent-encoding", + "serde", ] [[package]] -name = "libsqlite3-sys" -version = "0.30.1" +name = "usvg" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +checksum = "7447e703d7223b067607655e625e0dbca80822880248937da65966194c4864e6" dependencies = [ - "pkg-config", - "vcpkg", + "base64", + "data-url", + "flate2", + "fontdb", + "imagesize", + "kurbo", + "log", + "pico-args", + "roxmltree", + "rustybuzz 0.18.0", + "simplecss", + "siphasher", + "strict-num", + "svgtypes", + "tiny-skia-path", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", ] [[package]] -name = "log" -version = "0.4.22" +name = "utf16_iter" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] -name = "memchr" -version = "2.7.4" +name = "utf8_iter" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] -name = "nine_patch_drawable" -version = "0.1.0" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96e2f356f3fbb4179ee2a3d76ed2881553b93213a421a28975b2ea0c8d81d15" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] -name = "once_cell" -version = "1.20.2" +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "option-ext" -version = "0.2.0" +name = "vswhom" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] [[package]] -name = "pkg-config" -version = "0.3.31" +name = "vswhom-sys" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" +dependencies = [ + "cc", + "libc", +] [[package]] -name = "proc-macro2" -version = "1.0.92" +name = "vtable" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "20b14a049c8d5d1ff811a00f65ac1454335487ed769a943c7bad89ead3573335" dependencies = [ - "unicode-ident", + "const-field-offset", + "portable-atomic", + "stable_deref_trait", + "vtable-macro", ] [[package]] -name = "quote" -version = "1.0.37" +name = "vtable-macro" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "d8502f961cf2f1359fed21a70f67c831ccb3ab9e4c0b4dd3ad40387fbe8875db" dependencies = [ "proc-macro2", + "quote", + "syn", ] [[package]] -name = "redox_users" -version = "0.4.6" +name = "walkdir" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ - "getrandom", - "libredox", - "thiserror", + "same-file", + "winapi-util", ] [[package]] -name = "rusqlite" -version = "0.32.1" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ - "bitflags", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec", + "cfg-if", + "once_cell", + "wasm-bindgen-macro", ] [[package]] -name = "rustc_version" -version = "0.4.1" +name = "wasm-bindgen-backend" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ - "semver", + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", ] [[package]] -name = "semver" -version = "1.0.24" +name = "wasm-bindgen-futures" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] [[package]] -name = "serde" -version = "1.0.216" +name = "wasm-bindgen-macro" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ - "serde_derive", + "quote", + "wasm-bindgen-macro-support", ] [[package]] -name = "serde_derive" -version = "1.0.216" +name = "wasm-bindgen-macro-support" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] -name = "serde_spanned" -version = "0.6.8" +name = "wasm-bindgen-shared" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "wayland-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" dependencies = [ - "serde", + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "wayland-client" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" +dependencies = [ + "bitflags 2.6.0", + "rustix", + "wayland-backend", + "wayland-scanner", +] [[package]] -name = "smallvec" -version = "1.13.2" +name = "wayland-csd-frame" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.6.0", + "cursor-icon", + "wayland-backend", +] [[package]] -name = "syn" -version = "2.0.91" +name = "wayland-cursor" +version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" +checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "rustix", + "wayland-client", + "xcursor", ] [[package]] -name = "thiserror" -version = "1.0.69" +name = "wayland-protocols" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" dependencies = [ - "thiserror-impl", + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", ] [[package]] -name = "thiserror-impl" -version = "1.0.69" +name = "wayland-protocols-plasma" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" dependencies = [ - "proc-macro2", - "quote", - "syn", + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] -name = "toml" -version = "0.8.19" +name = "wayland-protocols-wlr" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] -name = "toml_datetime" -version = "0.6.8" +name = "wayland-scanner" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" dependencies = [ - "serde", + "proc-macro2", + "quick-xml 0.36.2", + "quote", ] [[package]] -name = "toml_edit" -version = "0.22.22" +name = "wayland-sys" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", + "dlib", + "log", + "once_cell", + "pkg-config", ] [[package]] -name = "tsfreg" -version = "24.10.1" +name = "web-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ - "windows", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "unicode-ident" -version = "1.0.14" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] -name = "vcpkg" -version = "0.2.15" +name = "weezl" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] -name = "version_check" -version = "0.9.5" +name = "which" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] [[package]] -name = "vswhom" +name = "win_dbg_logger" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +checksum = "7d1b4c22244dc27534d81e2f6fc3efd6b20e50c010f177efc20b719ec759a779" dependencies = [ - "libc", - "vswhom-sys", + "log", ] [[package]] -name = "vswhom-sys" -version = "0.1.2" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b17ae1f6c8a2b28506cd96d412eebf83b4a0ff2cbefeeb952f2f9dfa44ba18" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "cc", - "libc", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] -name = "win_dbg_logger" -version = "0.1.0" +name = "winapi-util" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1b4c22244dc27534d81e2f6fc3efd6b20e50c010f177efc20b719ec759a779" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "log", + "windows-sys 0.48.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows" version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core", + "windows-core 0.58.0", + "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", ] @@ -568,6 +4781,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -577,6 +4799,39 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -608,6 +4863,12 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -620,6 +4881,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -632,6 +4899,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -650,6 +4923,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -662,6 +4941,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -674,6 +4959,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -686,6 +4977,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -698,6 +4995,58 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winit" +version = "0.30.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba50bc8ef4b6f1a75c9274fb95aa9a8f63fbc66c56f391bd85cf68d51e7b1a3" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.6.0", + "block2", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases", + "concurrent-queue", + "core-foundation 0.9.4", + "core-graphics 0.23.2", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix", + "sctk-adwaita", + "smithay-client-toolkit", + "smol_str 0.2.2", + "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", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + [[package]] name = "winnow" version = "0.6.20" @@ -714,7 +5063,97 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + +[[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-clipboard" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "662d74b3d77e396b8e5beb00b9cad6a9eccf40b2ef68cc858784b14c41d535a3" +dependencies = [ + "libc", + "x11rb", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys 0.4.14", + "rustix", +] + +[[package]] +name = "xcursor" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" + +[[package]] +name = "xdg-home" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" +dependencies = [ + "libc", + "windows-sys 0.59.0", ] [[package]] @@ -732,6 +5171,48 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "672423d4fea7ffa2f6c25ba60031ea13dc6258070556f125cc4d790007d4a155" +[[package]] +name = "xkbcommon" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d66ca9352cbd4eecbbc40871d8a11b4ac8107cfc528a6e14d7c19c69d0e1ac9" +dependencies = [ + "libc", + "memmap2", + "xkeysym", +] + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.6.0", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + +[[package]] +name = "xml-rs" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432" + +[[package]] +name = "xmlwriter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + [[package]] name = "xtask" version = "0.1.0" @@ -742,12 +5223,136 @@ dependencies = [ "xflags", ] +[[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 = "zbus" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix", + "ordered-stream", + "rand", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "windows-sys 0.52.0", + "xdg-home", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus-lockstep" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca2c5dceb099bddaade154055c926bb8ae507a18756ba1d8963fd7b51d8ed1d" +dependencies = [ + "zbus_xml", + "zvariant", +] + +[[package]] +name = "zbus-lockstep-macros" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "zbus-lockstep", + "zbus_xml", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + +[[package]] +name = "zbus_xml" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3f374552b954f6abb4bd6ce979e6c9b38fb9d0cd7cc68a7d796e70c9f3a233" +dependencies = [ + "quick-xml 0.30.0", + "serde", + "static_assertions", + "zbus_names", + "zvariant", +] + [[package]] name = "zerocopy" version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] @@ -762,8 +5367,98 @@ dependencies = [ "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 = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[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]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zvariant" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" +dependencies = [ + "endi", + "enumflags2", + "serde", + "static_assertions", + "url", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index eaa0581..7879080 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["chewing_tip", "tsfreg", "xtask"] +members = ["chewing_tip", "preferences", "tsfreg", "xtask"] resolver = "2" [profile.release] diff --git a/preferences/Cargo.toml b/preferences/Cargo.toml new file mode 100644 index 0000000..7690d44 --- /dev/null +++ b/preferences/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "chewing-preferences" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.95" +slint = "1.8.0" + +[dependencies.chewing] +version = "0.9.1" +features = ["sqlite"] +git = "https://github.com/chewing/libchewing" +branch = "feat-dictionary-mgmt-api" + +[build-dependencies] +slint-build = "1.8.0" diff --git a/preferences/build.rs b/preferences/build.rs new file mode 100644 index 0000000..7ed55a7 --- /dev/null +++ b/preferences/build.rs @@ -0,0 +1,3 @@ +fn main() { + slint_build::compile("ui/index.slint").expect("Slint build failed"); +} diff --git a/preferences/design/chewing-editor-flow.png b/preferences/design/chewing-editor-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..b3c843e3d0c820e5b5d56c9cdcee36c8b2e9dd58 GIT binary patch literal 248787 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

pn2RI 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

{)@04wT$U4Aks0-E!G3Gv`&H0;>6X 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 RE{ Result<()> { + let ui = EditorWindow::new()?; + + ui.set_dictionaries(dict_list_model()?); + + ui.on_info_clicked(move |row: ModelRc| { + let info_dialog = DictionaryInfoDialog::new().unwrap(); + let dict_item = row + .as_any() + .downcast_ref::() + .expect("row item should be a DictTableItemModel"); + let dict_model = ModelRc::new(DictInfoViewModel::from(dict_item)); + + let dialog_handle = info_dialog.as_weak(); + info_dialog.set_dictionary_info(dict_model); + info_dialog.on_ok_clicked(move || { + let dialog = dialog_handle.upgrade().unwrap(); + dialog.window().hide().unwrap(); + }); + info_dialog.show().unwrap(); + }); + + let ui_handle = ui.as_weak(); + ui.on_edit_dict_clicked(move |row: ModelRc| { + let dict_item = row + .as_any() + .downcast_ref::() + .expect("row item should be a DictTableItemModel"); + let dict_model = ModelRc::new(DictEditViewModel::from(dict_item)); + + let ui = ui_handle.upgrade().unwrap(); + ui.set_entries(dict_model); + }); + + ui.on_edit_entry_clicked(|phrase, bopomofo, freq| { + let edit_dialog = EditEntryDialog::new().unwrap(); + edit_dialog.set_phrase(phrase); + edit_dialog.set_bopomofo(bopomofo); + edit_dialog.set_freq(freq); + edit_dialog.show().unwrap(); + }); + + ui.run()?; + + Ok(()) +} + +fn dict_list_model() -> Result>> { + let sys_loader = SystemDictionaryLoader::new(); + let user_loader = UserDictionaryLoader::new(); + + Ok(ModelRc::new(VecModel::from_iter( + sys_loader + .load()? + .into_iter() + .map(|dict| ModelRc::new(DictTableItemModel::new("系統", dict))) + .chain( + sys_loader + .load_extra()? + .into_iter() + .map(|dict| ModelRc::new(DictTableItemModel::new("附加", dict))), + ) + .chain( + user_loader + .load() + .into_iter() + .map(|dict| ModelRc::new(DictTableItemModel::new("個人", dict))), + ), + ))) +} + +struct DictTableItemModel(&'static str, Rc>>); + +impl DictTableItemModel { + fn new(typ: &'static str, dict: Box) -> DictTableItemModel { + DictTableItemModel(typ, Rc::new(RwLock::new(dict))) + } +} + +impl Model for DictTableItemModel { + type Data = StandardListViewItem; + + fn row_count(&self) -> usize { + 2 + } + + fn row_data(&self, row: usize) -> Option { + match row { + 0 => Some(self.0.into()), + 1 => self + .1 + .read() + .ok() + .map(|dict| dict.about().name.as_str().into()), + _ => None, + } + } + + fn model_tracker(&self) -> &dyn ModelTracker { + &() + } + + fn as_any(&self) -> &dyn core::any::Any { + self + } +} + +struct DictInfoViewModel(&'static str, DictionaryInfo); + +impl From<&DictTableItemModel> for DictInfoViewModel { + fn from(value: &DictTableItemModel) -> Self { + DictInfoViewModel( + value.0, + value + .1 + .read() + .expect("should have no concurrent write") + .about(), + ) + } +} + +impl Model for DictInfoViewModel { + type Data = ModelRc; + + fn row_count(&self) -> usize { + 6 + } + + fn row_data(&self, row: usize) -> Option { + match row { + 0 => Some(ModelRc::from(["來源".into(), self.0.into()])), + 1 => Some(ModelRc::from(["名稱".into(), self.1.name.as_str().into()])), + 2 => Some(ModelRc::from([ + "版本".into(), + self.1.version.as_str().into(), + ])), + 3 => Some(ModelRc::from([ + "著作權".into(), + self.1.copyright.as_str().into(), + ])), + 4 => Some(ModelRc::from([ + "授權方式".into(), + self.1.license.as_str().into(), + ])), + 5 => Some(ModelRc::from([ + "製作軟體".into(), + self.1.software.as_str().into(), + ])), + _ => None, + } + } + + fn model_tracker(&self) -> &dyn ModelTracker { + &() + } +} + +struct DictEditViewModel { + cache: Vec<(Vec, Phrase)>, + dict: Rc>>, +} + +impl From<&DictTableItemModel> for DictEditViewModel { + fn from(value: &DictTableItemModel) -> Self { + DictEditViewModel { + cache: value + .1 + .read() + .expect("should not have concurrent writer") + .entries() + .collect(), + dict: value.1.clone(), + } + } +} + +impl Model for DictEditViewModel { + type Data = ModelRc; + + fn row_count(&self) -> usize { + self.cache.len() + } + + fn row_data(&self, row: usize) -> Option { + self.cache.get(row).map(|entry| { + ModelRc::from([ + entry.1.as_str().into(), + // FIXME + entry + .0 + .iter() + .map(|syl| syl.to_string()) + .collect::>() + .join(" ") + .as_str() + .into(), + entry.1.freq().to_string().as_str().into(), + ]) + }) + } + + fn model_tracker(&self) -> &dyn ModelTracker { + // FIXME + &() + } + + fn as_any(&self) -> &dyn core::any::Any { + self + } +} diff --git a/preferences/src/main.rs b/preferences/src/main.rs new file mode 100644 index 0000000..a0afc64 --- /dev/null +++ b/preferences/src/main.rs @@ -0,0 +1,17 @@ +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +mod editor; + +use std::env; + +slint::include_modules!(); + +fn main() -> anyhow::Result<()> { + if env::args().any(|arg| arg == "/edit" || arg == "--edit") { + editor::run()?; + } else { + let ui = AppWindow::new()?; + ui.run()?; + } + Ok(()) +} diff --git a/preferences/ui/app-window.slint b/preferences/ui/app-window.slint new file mode 100644 index 0000000..14c94af --- /dev/null +++ b/preferences/ui/app-window.slint @@ -0,0 +1,172 @@ +import { Button, VerticalBox, TabWidget, CheckBox, ComboBox, HorizontalBox, SpinBox, AboutSlint, TextEdit, StandardButton } from "std-widgets.slint"; + +export component AppWindow inherits Window { + default-font-family: "jf open 粉圓 2.0"; + default-font-weight: 500; + title: "Chewing Preferences (24.10.1.999)"; + icon: @image-url("../../icon/48_icon.png"); + max-width: 500px; + max-height: 500px; + VerticalBox { + + TabWidget { + Tab { + title: "打字行為"; + HorizontalLayout { + padding: 20px; + spacing: 20px; + VerticalLayout { + spacing: 10px; + alignment: start; + CheckBox { + text: "使用 Shift 快速切換中英文"; + } + + CheckBox { + text: "使用 CapsLock 切換中英文"; + } + + CheckBox { + text: "使用 Esc 清空編輯區字串"; + } + + CheckBox { + text: "按住 Shift 輸入全形標點符號"; + } + + CheckBox { + text: "按住 Shift 輸入大寫英文字母"; + } + + CheckBox { + text: "Ctrl + 數字儲存游標前方的詞"; + } + + CheckBox { + text: "按住 Shift 輸入快速符號"; + checked: true; + enabled: false; + } + + CheckBox { + text: "按住 Ctrl 輸入快速符號"; + enabled: false; + } + } + + VerticalLayout { + spacing: 10px; + alignment: start; + CheckBox { + text: "使用方向鍵移動游標選字"; + } + + CheckBox { + text: "按空白鍵叫出選字視窗"; + } + + CheckBox { + text: "選字完畢自動跳到下一個字"; + } + + CheckBox { + text: "預設以全形模式啟動"; + } + + CheckBox { + text: "預設以英文模式啟動"; + } + + CheckBox { + text: "預設輸出簡體中文"; + } + + Text { + text: "選字鍵:"; + } + + ComboBox { + model: ["1234567890"]; + } + + Text { + text: "模式:"; + } + + ComboBox { } + } + } + } + + Tab { + title: "界面外觀"; + VerticalBox { + alignment: start; + Text { + text: "每列顯示後選字個數"; + min-width: 140px; + } + + SpinBox { + minimum: 1; + maximum: 10; + } + + Text { + text: "每頁顯示後選字個數"; + min-width: 140px; + } + + SpinBox { + minimum: 1; + maximum: 10; + } + + Text { + text: "選字及訊息視窗文字大小"; + min-width: 140px; + } + + SpinBox { + minimum: 10; + } + } + } + + Tab { + title: "鍵盤設定"; + } + + Tab { + title: "特殊符號"; + VerticalBox { + Text { + text: "輸入中文時,按下 ` 鍵,會顯示下列的符號表:"; + } + + TextEdit { } + + Text { + text: "以上是符號表的設定檔,語法相當簡單:\n每一行的內容都是:「分類名稱」=「此分類下的所有符號」\n您也可以一行只放一個符號,則該符號會被放在最上層選單。"; + } + } + } + + Tab { + title: "關於"; + AboutSlint { } + } + } + + HorizontalBox { + alignment: end; + StandardButton { + kind: apply; + } + + StandardButton { + kind: cancel; + } + } + } +} diff --git a/preferences/ui/editor-window.slint b/preferences/ui/editor-window.slint new file mode 100644 index 0000000..816c89a --- /dev/null +++ b/preferences/ui/editor-window.slint @@ -0,0 +1,237 @@ +import { VerticalBox, StandardTableView, Button, TabWidget, HorizontalBox, LineEdit, AboutSlint, StandardButton, GridBox } from "std-widgets.slint"; + +export struct DictionaryListItem { + id: int, + type: string, + name: string, +} + +export component EditorWindow inherits Window { + default-font-family: "jf open 粉圓 2.0"; + default-font-weight: 500; + preferred-height: 500px; + + in property <[[StandardListViewItem]]> dictionaries; + in property <[[StandardListViewItem]]> entries; + out property current-row: table.current-row; + + callback info-clicked(row: [StandardListViewItem]); + callback edit-dict-clicked(row: [StandardListViewItem]); + callback edit-entry-clicked(phrase: string, bopomofo: string, freq: int); + + tabs := TabWidget { + Tab { + title: "管理"; + VerticalBox { + HorizontalBox { + alignment: start; + Button { + text: "編輯"; + enabled: root.current-row >= 0; + clicked => { + root.edit-dict-clicked(root.dictionaries[root.current-row]); + tabs.current-index = 1; + } + } + Button { + text: "內容"; + enabled: root.current-row >= 0; + clicked => { + root.info-clicked(root.dictionaries[root.current-row]); + } + } + Button { + text: "新增"; + } + Button { + text: "匯入"; + } + Button { + text: "匯出"; + } + Button { + text: "刪除"; + } + Button { + text: "重新整理"; + } + } + table := StandardTableView { + columns: [ + { title: "類型", width: 70px }, + { + title: "名稱" + } + ]; + rows: root.dictionaries; + } + } + } + Tab { + title: "編輯"; + VerticalBox { + HorizontalBox { + alignment: start; + Button { + text: "新增"; + enabled: false; + } + Button { + text: "刪除"; + enabled: false; + } + Button { + text: "復原"; + enabled: false; + } + Button { + text: "放棄"; + enabled: false; + } + Button { + text: "重新整理"; + enabled: false; + } + Button { + text: "存檔"; + enabled: false; + } + } + HorizontalBox { + LineEdit { + text: "搜尋"; + enabled: false; + } + } + StandardTableView { + columns: [{ title: "字/詞" }, { title: "注音" }, { title: "詞頻" }]; + rows: entries; + current-row-changed(current-row) => { + root.edit-entry-clicked( + root.entries[current-row][0].text, + root.entries[current-row][1].text, + root.entries[current-row][2].text.to-float() + ) + } + } + } + } + Tab { + title: "關於"; + AboutSlint {} + } + } +} + +export component DictionaryInfoDialog inherits Dialog { + default-font-family: "jf open 粉圓 2.0"; + default-font-weight: 500; + preferred-height: 400px; + + in property <[[StandardListViewItem]]> dictionary-info; + + callback ok-clicked(); + + VerticalBox { + StandardTableView { + columns: [ { title: "屬性", width: 100px }, { title: "內容" } ]; + rows: root.dictionary-info; + } + } + StandardButton { + kind: ok; + clicked => { + root.ok-clicked(); + } + } +} + +export component EditEntryDialog inherits Dialog { + default-font-family: "jf open 粉圓 2.0"; + default-font-weight: 500; + preferred-height: 400px; + + in-out property phrase; + in-out property bopomofo; + in-out property freq; + + VerticalBox { + alignment: start; + Text { + text: "字/詞:"; + } + LineEdit { + text: root.phrase; + } + Text { + text: "注音:"; + } + LineEdit { + text: root.bopomofo; + } + Text { + text: "詞頻:"; + } + LineEdit { + text: root.freq; + } + GridBox { + spacing: 5px; + Row { + Button { text: "ㄅ"; } + Button { text: "ㄉ"; } + Button { text: "ˇ"; } + Button { text: "ˋ"; } + Button { text: "ㄓ"; } + Button { text: "ˊ"; } + Button { text: "˙"; } + Button { text: "ㄚ"; } + Button { text: "ㄞ"; } + Button { text: "ㄢ"; } + Button { text: "ㄦ"; } + } + Row { + Button { text: "ㄆ"; } + Button { text: "ㄊ"; } + Button { text: "ㄍ"; } + Button { text: "ㄐ"; } + Button { text: "ㄔ"; } + Button { text: "ㄗ"; } + Button { text: "一"; } + Button { text: "ㄛ"; } + Button { text: "ㄟ"; } + Button { text: "ㄣ"; } + } + Row { + Button { text: "ㄇ"; } + Button { text: "ㄋ"; } + Button { text: "ㄎ"; } + Button { text: "ㄑ"; } + Button { text: "ㄕ"; } + Button { text: "ㄘ"; } + Button { text: "ㄨ"; } + Button { text: "ㄜ"; } + Button { text: "ㄠ"; } + Button { text: "ㄤ"; } + } + Row { + Button { text: "ㄈ"; } + Button { text: "ㄌ"; } + Button { text: "ㄏ"; } + Button { text: "ㄒ"; } + Button { text: "ㄖ"; } + Button { text: "ㄙ"; } + Button { text: "ㄩ"; } + Button { text: "ㄝ"; } + Button { text: "ㄡ"; } + Button { text: "ㄥ"; } + } + Row { + Button { text: " "; col: 2; colspan: 6; } + } + } + } + StandardButton { + kind: ok; + } +} \ No newline at end of file diff --git a/preferences/ui/index.slint b/preferences/ui/index.slint new file mode 100644 index 0000000..9076059 --- /dev/null +++ b/preferences/ui/index.slint @@ -0,0 +1,4 @@ +import { AppWindow } from "./app-window.slint"; +import { EditorWindow, DictionaryInfoDialog, EditEntryDialog } from "./editor-window.slint"; + +export { AppWindow, EditorWindow, DictionaryInfoDialog, EditEntryDialog } \ No newline at end of file From dca36a0ad41b61758c6179732715b8469f9ecd53 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Fri, 27 Dec 2024 22:50:42 +0900 Subject: [PATCH 02/12] feat(prefs): move dialog UI into the same window --- preferences/src/editor.rs | 22 +- preferences/ui/editor-window.slint | 418 +++++++++++++++-------------- preferences/ui/index.slint | 4 +- 3 files changed, 229 insertions(+), 215 deletions(-) diff --git a/preferences/src/editor.rs b/preferences/src/editor.rs index c002b8b..5fa0682 100644 --- a/preferences/src/editor.rs +++ b/preferences/src/editor.rs @@ -7,30 +7,24 @@ use chewing::dictionary::{DictionaryInfo, Phrase}; use chewing::zhuyin::Syllable; use slint::{ComponentHandle, Model, ModelRc, ModelTracker, StandardListViewItem, VecModel}; -use crate::DictionaryInfoDialog; use crate::EditorWindow; -use crate::EditEntryDialog; pub fn run() -> Result<()> { let ui = EditorWindow::new()?; ui.set_dictionaries(dict_list_model()?); + let ui_handle = ui.as_weak(); ui.on_info_clicked(move |row: ModelRc| { - let info_dialog = DictionaryInfoDialog::new().unwrap(); + // let info_dialog = DictionaryInfoDialog::new().unwrap(); let dict_item = row .as_any() .downcast_ref::() .expect("row item should be a DictTableItemModel"); let dict_model = ModelRc::new(DictInfoViewModel::from(dict_item)); - let dialog_handle = info_dialog.as_weak(); - info_dialog.set_dictionary_info(dict_model); - info_dialog.on_ok_clicked(move || { - let dialog = dialog_handle.upgrade().unwrap(); - dialog.window().hide().unwrap(); - }); - info_dialog.show().unwrap(); + let ui = ui_handle.upgrade().unwrap(); + ui.set_dictionary_info(dict_model.clone()); }); let ui_handle = ui.as_weak(); @@ -45,14 +39,6 @@ pub fn run() -> Result<()> { ui.set_entries(dict_model); }); - ui.on_edit_entry_clicked(|phrase, bopomofo, freq| { - let edit_dialog = EditEntryDialog::new().unwrap(); - edit_dialog.set_phrase(phrase); - edit_dialog.set_bopomofo(bopomofo); - edit_dialog.set_freq(freq); - edit_dialog.show().unwrap(); - }); - ui.run()?; Ok(()) diff --git a/preferences/ui/editor-window.slint b/preferences/ui/editor-window.slint index 816c89a..d08b156 100644 --- a/preferences/ui/editor-window.slint +++ b/preferences/ui/editor-window.slint @@ -6,6 +6,12 @@ export struct DictionaryListItem { name: string, } +enum SidePanel { + dict-info, + edit-entry, + hide, +} + export component EditorWindow inherits Window { default-font-family: "jf open 粉圓 2.0"; default-font-weight: 500; @@ -13,225 +19,247 @@ export component EditorWindow inherits Window { in property <[[StandardListViewItem]]> dictionaries; in property <[[StandardListViewItem]]> entries; + in property <[[StandardListViewItem]]> dictionary-info; out property current-row: table.current-row; + + property show-dict-info; + property show-edit-entry; + property side-panel; + + property phrase; + property bopomofo; + property freq; callback info-clicked(row: [StandardListViewItem]); callback edit-dict-clicked(row: [StandardListViewItem]); - callback edit-entry-clicked(phrase: string, bopomofo: string, freq: int); - tabs := TabWidget { - Tab { - title: "管理"; - VerticalBox { - HorizontalBox { - alignment: start; - Button { - text: "編輯"; - enabled: root.current-row >= 0; - clicked => { - root.edit-dict-clicked(root.dictionaries[root.current-row]); - tabs.current-index = 1; + states [ + show-dict-info when tabs.current-index == 0: { + root.side-panel: SidePanel.dict-info; + } + show-edit-entry when tabs.current-index == 1: { + root.side-panel: SidePanel.edit-entry; + } + hide when tabs.current-index == 2: { + root.side-panel: hide; + } + ] + + HorizontalBox { + tabs := TabWidget { + Tab { + title: "管理"; + VerticalBox { + HorizontalBox { + alignment: start; + Button { + text: "編輯"; + enabled: root.current-row >= 0; + clicked => { + root.edit-dict-clicked(root.dictionaries[root.current-row]); + tabs.current-index = 1; + } } - } - Button { - text: "內容"; - enabled: root.current-row >= 0; - clicked => { - root.info-clicked(root.dictionaries[root.current-row]); + Button { + text: "新增"; + } + Button { + text: "匯入"; + } + Button { + text: "匯出"; + } + Button { + text: "刪除"; + } + Button { + text: "重新整理"; } } - Button { - text: "新增"; - } - Button { - text: "匯入"; + table := StandardTableView { + columns: [ + { title: "類型", width: 70px }, + { + title: "名稱" + } + ]; + rows: root.dictionaries; + current-row-changed(current-row) => { + root.info-clicked(root.dictionaries[current-row]); + } } - Button { - text: "匯出"; + } + } + Tab { + title: "編輯"; + VerticalBox { + HorizontalBox { + alignment: start; + Button { + text: "新增"; + enabled: false; + } + Button { + text: "刪除"; + enabled: false; + } + Button { + text: "復原"; + enabled: false; + } + Button { + text: "放棄"; + enabled: false; + } + Button { + text: "重新整理"; + enabled: false; + } + Button { + text: "存檔"; + enabled: false; + } } - Button { - text: "刪除"; + HorizontalBox { + LineEdit { + text: "搜尋"; + enabled: false; + } } - Button { - text: "重新整理"; + StandardTableView { + columns: [{ title: "字/詞" }, { title: "注音" }, { title: "詞頻" }]; + rows: entries; + current-row-changed(current-row) => { + // root.edit-entry-clicked( + // root.entries[current-row][0].text, + // root.entries[current-row][1].text, + // root.entries[current-row][2].text.to-float() + // ) + root.phrase = root.entries[current-row][0].text; + root.bopomofo = root.entries[current-row][1].text; + root.freq = root.entries[current-row][2].text.to-float(); + } } } - table := StandardTableView { - columns: [ - { title: "類型", width: 70px }, - { - title: "名稱" - } - ]; - rows: root.dictionaries; + } + Tab { + title: "關於"; + AboutSlint {} + } + } + if root.side-panel == SidePanel.dict-info: HorizontalLayout { + Path { + width: 1px; + height: 100%; + stroke: Colors.lightgray; + stroke-width: 1px; + MoveTo { + x: 0; + y: 0; + } + LineTo { + x: 0; + y: 100; + } + } + VerticalBox { + StandardTableView { + columns: [ { title: "屬性", width: 100px }, { title: "內容" } ]; + rows: root.dictionary-info; } } } - Tab { - title: "編輯"; + if root.side-panel == SidePanel.edit-entry: HorizontalLayout { + Path { + width: 1px; + height: 100%; + stroke: Colors.lightgray; + stroke-width: 1px; + MoveTo { + x: 0; + y: 0; + } + LineTo { + x: 0; + y: 100; + } + } VerticalBox { - HorizontalBox { - alignment: start; - Button { - text: "新增"; - enabled: false; - } - Button { - text: "刪除"; - enabled: false; - } - Button { - text: "復原"; - enabled: false; - } - Button { - text: "放棄"; - enabled: false; + alignment: start; + Text { + text: "字/詞:"; + } + LineEdit { + text: root.phrase; + } + Text { + text: "注音:"; + } + LineEdit { + text: root.bopomofo; + } + Text { + text: "詞頻:"; + } + LineEdit { + text: root.freq; + } + GridBox { + spacing: 5px; + Row { + Button { text: "ㄅ"; } + Button { text: "ㄉ"; } + Button { text: "ˇ"; } + Button { text: "ˋ"; } + Button { text: "ㄓ"; } + Button { text: "ˊ"; } + Button { text: "˙"; } + Button { text: "ㄚ"; } + Button { text: "ㄞ"; } + Button { text: "ㄢ"; } + Button { text: "ㄦ"; } } - Button { - text: "重新整理"; - enabled: false; + Row { + Button { text: "ㄆ"; } + Button { text: "ㄊ"; } + Button { text: "ㄍ"; } + Button { text: "ㄐ"; } + Button { text: "ㄔ"; } + Button { text: "ㄗ"; } + Button { text: "一"; } + Button { text: "ㄛ"; } + Button { text: "ㄟ"; } + Button { text: "ㄣ"; } } - Button { - text: "存檔"; - enabled: false; + Row { + Button { text: "ㄇ"; } + Button { text: "ㄋ"; } + Button { text: "ㄎ"; } + Button { text: "ㄑ"; } + Button { text: "ㄕ"; } + Button { text: "ㄘ"; } + Button { text: "ㄨ"; } + Button { text: "ㄜ"; } + Button { text: "ㄠ"; } + Button { text: "ㄤ"; } } - } - HorizontalBox { - LineEdit { - text: "搜尋"; - enabled: false; + Row { + Button { text: "ㄈ"; } + Button { text: "ㄌ"; } + Button { text: "ㄏ"; } + Button { text: "ㄒ"; } + Button { text: "ㄖ"; } + Button { text: "ㄙ"; } + Button { text: "ㄩ"; } + Button { text: "ㄝ"; } + Button { text: "ㄡ"; } + Button { text: "ㄥ"; } } - } - StandardTableView { - columns: [{ title: "字/詞" }, { title: "注音" }, { title: "詞頻" }]; - rows: entries; - current-row-changed(current-row) => { - root.edit-entry-clicked( - root.entries[current-row][0].text, - root.entries[current-row][1].text, - root.entries[current-row][2].text.to-float() - ) + Row { + Button { text: " "; col: 2; colspan: 6; } } } } } - Tab { - title: "關於"; - AboutSlint {} - } - } -} - -export component DictionaryInfoDialog inherits Dialog { - default-font-family: "jf open 粉圓 2.0"; - default-font-weight: 500; - preferred-height: 400px; - - in property <[[StandardListViewItem]]> dictionary-info; - - callback ok-clicked(); - - VerticalBox { - StandardTableView { - columns: [ { title: "屬性", width: 100px }, { title: "內容" } ]; - rows: root.dictionary-info; - } - } - StandardButton { - kind: ok; - clicked => { - root.ok-clicked(); - } - } -} - -export component EditEntryDialog inherits Dialog { - default-font-family: "jf open 粉圓 2.0"; - default-font-weight: 500; - preferred-height: 400px; - - in-out property phrase; - in-out property bopomofo; - in-out property freq; - - VerticalBox { - alignment: start; - Text { - text: "字/詞:"; - } - LineEdit { - text: root.phrase; - } - Text { - text: "注音:"; - } - LineEdit { - text: root.bopomofo; - } - Text { - text: "詞頻:"; - } - LineEdit { - text: root.freq; - } - GridBox { - spacing: 5px; - Row { - Button { text: "ㄅ"; } - Button { text: "ㄉ"; } - Button { text: "ˇ"; } - Button { text: "ˋ"; } - Button { text: "ㄓ"; } - Button { text: "ˊ"; } - Button { text: "˙"; } - Button { text: "ㄚ"; } - Button { text: "ㄞ"; } - Button { text: "ㄢ"; } - Button { text: "ㄦ"; } - } - Row { - Button { text: "ㄆ"; } - Button { text: "ㄊ"; } - Button { text: "ㄍ"; } - Button { text: "ㄐ"; } - Button { text: "ㄔ"; } - Button { text: "ㄗ"; } - Button { text: "一"; } - Button { text: "ㄛ"; } - Button { text: "ㄟ"; } - Button { text: "ㄣ"; } - } - Row { - Button { text: "ㄇ"; } - Button { text: "ㄋ"; } - Button { text: "ㄎ"; } - Button { text: "ㄑ"; } - Button { text: "ㄕ"; } - Button { text: "ㄘ"; } - Button { text: "ㄨ"; } - Button { text: "ㄜ"; } - Button { text: "ㄠ"; } - Button { text: "ㄤ"; } - } - Row { - Button { text: "ㄈ"; } - Button { text: "ㄌ"; } - Button { text: "ㄏ"; } - Button { text: "ㄒ"; } - Button { text: "ㄖ"; } - Button { text: "ㄙ"; } - Button { text: "ㄩ"; } - Button { text: "ㄝ"; } - Button { text: "ㄡ"; } - Button { text: "ㄥ"; } - } - Row { - Button { text: " "; col: 2; colspan: 6; } - } - } - } - StandardButton { - kind: ok; } } \ No newline at end of file diff --git a/preferences/ui/index.slint b/preferences/ui/index.slint index 9076059..65741cc 100644 --- a/preferences/ui/index.slint +++ b/preferences/ui/index.slint @@ -1,4 +1,4 @@ import { AppWindow } from "./app-window.slint"; -import { EditorWindow, DictionaryInfoDialog, EditEntryDialog } from "./editor-window.slint"; +import { EditorWindow } from "./editor-window.slint"; -export { AppWindow, EditorWindow, DictionaryInfoDialog, EditEntryDialog } \ No newline at end of file +export { AppWindow, EditorWindow } \ No newline at end of file From 9b663a7f8353d98e1c2aa9b0171abd69f06ee8f1 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Sat, 28 Dec 2024 11:52:11 +0900 Subject: [PATCH 03/12] feat(prefs): add bopomofo keyboard widget --- preferences/ui/bopomofo-keyboard.slint | 81 ++++++++++++++++++ preferences/ui/editor-window.slint | 109 +++++++++---------------- 2 files changed, 120 insertions(+), 70 deletions(-) create mode 100644 preferences/ui/bopomofo-keyboard.slint diff --git a/preferences/ui/bopomofo-keyboard.slint b/preferences/ui/bopomofo-keyboard.slint new file mode 100644 index 0000000..cce10d5 --- /dev/null +++ b/preferences/ui/bopomofo-keyboard.slint @@ -0,0 +1,81 @@ +import { GridBox, Button, VerticalBox, HorizontalBox } from "std-widgets.slint"; + +export component BopomofoKeyboard inherits VerticalBox { + + callback clicked(text: string); + // callback backspace-clicked(); + callback clear-clicked(); + + property <[[string]]> keys: [ + [ + "ㄅ", + "ㄉ", + "ˇ", + "ˋ", + "ㄓ", + "ˊ", + "˙", + "ㄚ", + "ㄞ", + "ㄢ", + "ㄦ", + ], + ["ㄆ", "ㄊ", "ㄍ", "ㄐ", "ㄔ", "ㄗ", "一", "ㄛ", "ㄟ", "ㄣ"], + ["ㄇ", "ㄋ", "ㄎ", "ㄑ", "ㄕ", "ㄘ", "ㄨ", "ㄜ", "ㄠ", "ㄤ"], + ["ㄈ", "ㄌ", "ㄏ", "ㄒ", "ㄖ", "ㄙ", "ㄩ", "ㄝ", "ㄡ", "ㄥ"] + ]; + + for row[index] in root.keys: HorizontalLayout { + padding-left: 10px * index; + for btn in row: Rectangle { + width: 40px; + height: 30px; + if btn == "": Rectangle { } + if btn != "": Button { + text: btn; + clicked => { + root.clicked(self.text) + } + } + } + // if index == 1: Rectangle { + // width: 50px; + // height: 30px; + // Button { + // text: "⌫"; + // clicked => { + // backspace-clicked() + // } + // } + // } + } + HorizontalLayout { + Rectangle { + width: 100px; + height: 30px; + } + + Rectangle { + width: 240px; + height: 30px; + Button { + width: 100%; + text: "␣"; + clicked => { + root.clicked(self.text) + } + } + } + + Rectangle { + width: 80px; + height: 30px; + Button { + text: "清空"; + clicked => { + clear-clicked() + } + } + } + } +} diff --git a/preferences/ui/editor-window.slint b/preferences/ui/editor-window.slint index d08b156..1fa0970 100644 --- a/preferences/ui/editor-window.slint +++ b/preferences/ui/editor-window.slint @@ -1,4 +1,5 @@ import { VerticalBox, StandardTableView, Button, TabWidget, HorizontalBox, LineEdit, AboutSlint, StandardButton, GridBox } from "std-widgets.slint"; +import { BopomofoKeyboard } from "bopomofo-keyboard.slint"; export struct DictionaryListItem { id: int, @@ -16,12 +17,10 @@ export component EditorWindow inherits Window { default-font-family: "jf open 粉圓 2.0"; default-font-weight: 500; preferred-height: 500px; - in property <[[StandardListViewItem]]> dictionaries; in property <[[StandardListViewItem]]> entries; in property <[[StandardListViewItem]]> dictionary-info; out property current-row: table.current-row; - property show-dict-info; property show-edit-entry; property side-panel; @@ -60,29 +59,30 @@ export component EditorWindow inherits Window { tabs.current-index = 1; } } + Button { text: "新增"; } + Button { text: "匯入"; } + Button { text: "匯出"; } + Button { text: "刪除"; } + Button { text: "重新整理"; } } + table := StandardTableView { - columns: [ - { title: "類型", width: 70px }, - { - title: "名稱" - } - ]; + columns: [{ title: "類型", width: 70px }, { title: "名稱" }]; rows: root.dictionaries; current-row-changed(current-row) => { root.info-clicked(root.dictionaries[current-row]); @@ -90,6 +90,7 @@ export component EditorWindow inherits Window { } } } + Tab { title: "編輯"; VerticalBox { @@ -99,42 +100,44 @@ export component EditorWindow inherits Window { text: "新增"; enabled: false; } + Button { text: "刪除"; enabled: false; } + Button { text: "復原"; enabled: false; } + Button { text: "放棄"; enabled: false; } + Button { text: "重新整理"; enabled: false; } + Button { text: "存檔"; enabled: false; } } + HorizontalBox { LineEdit { - text: "搜尋"; + placeholder-text: "搜尋"; enabled: false; } } + StandardTableView { columns: [{ title: "字/詞" }, { title: "注音" }, { title: "詞頻" }]; rows: entries; current-row-changed(current-row) => { - // root.edit-entry-clicked( - // root.entries[current-row][0].text, - // root.entries[current-row][1].text, - // root.entries[current-row][2].text.to-float() - // ) root.phrase = root.entries[current-row][0].text; root.bopomofo = root.entries[current-row][1].text; root.freq = root.entries[current-row][2].text.to-float(); @@ -142,11 +145,13 @@ export component EditorWindow inherits Window { } } } + Tab { title: "關於"; - AboutSlint {} + AboutSlint { } } } + if root.side-panel == SidePanel.dict-info: HorizontalLayout { Path { width: 1px; @@ -157,14 +162,16 @@ export component EditorWindow inherits Window { x: 0; y: 0; } + LineTo { x: 0; y: 100; } } + VerticalBox { StandardTableView { - columns: [ { title: "屬性", width: 100px }, { title: "內容" } ]; + columns: [{ title: "屬性", width: 100px }, { title: "內容" } ]; rows: root.dictionary-info; } } @@ -179,87 +186,49 @@ export component EditorWindow inherits Window { x: 0; y: 0; } + LineTo { x: 0; y: 100; } } + VerticalBox { alignment: start; Text { text: "字/詞:"; } + LineEdit { text: root.phrase; } + Text { text: "注音:"; } - LineEdit { + + bopomofo := LineEdit { text: root.bopomofo; } + Text { text: "詞頻:"; } + LineEdit { text: root.freq; } - GridBox { - spacing: 5px; - Row { - Button { text: "ㄅ"; } - Button { text: "ㄉ"; } - Button { text: "ˇ"; } - Button { text: "ˋ"; } - Button { text: "ㄓ"; } - Button { text: "ˊ"; } - Button { text: "˙"; } - Button { text: "ㄚ"; } - Button { text: "ㄞ"; } - Button { text: "ㄢ"; } - Button { text: "ㄦ"; } - } - Row { - Button { text: "ㄆ"; } - Button { text: "ㄊ"; } - Button { text: "ㄍ"; } - Button { text: "ㄐ"; } - Button { text: "ㄔ"; } - Button { text: "ㄗ"; } - Button { text: "一"; } - Button { text: "ㄛ"; } - Button { text: "ㄟ"; } - Button { text: "ㄣ"; } - } - Row { - Button { text: "ㄇ"; } - Button { text: "ㄋ"; } - Button { text: "ㄎ"; } - Button { text: "ㄑ"; } - Button { text: "ㄕ"; } - Button { text: "ㄘ"; } - Button { text: "ㄨ"; } - Button { text: "ㄜ"; } - Button { text: "ㄠ"; } - Button { text: "ㄤ"; } - } - Row { - Button { text: "ㄈ"; } - Button { text: "ㄌ"; } - Button { text: "ㄏ"; } - Button { text: "ㄒ"; } - Button { text: "ㄖ"; } - Button { text: "ㄙ"; } - Button { text: "ㄩ"; } - Button { text: "ㄝ"; } - Button { text: "ㄡ"; } - Button { text: "ㄥ"; } + + BopomofoKeyboard { + clicked(text) => { + bopomofo.clear-focus(); + bopomofo.text += text; } - Row { - Button { text: " "; col: 2; colspan: 6; } + clear-clicked => { + bopomofo.text = ""; } } } } } -} \ No newline at end of file +} From c06351c442322983402af2538cfc7937fce7195c Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Sat, 28 Dec 2024 20:24:06 +0900 Subject: [PATCH 04/12] feat(prefs): implement basic dict editor --- preferences/src/editor.rs | 219 +++++++++++++++++++++--- preferences/ui/bopomofo-keyboard.slint | 19 ++- preferences/ui/editor-window.slint | 224 ++++++++++++++----------- preferences/ui/index.slint | 4 +- 4 files changed, 335 insertions(+), 131 deletions(-) diff --git a/preferences/src/editor.rs b/preferences/src/editor.rs index 5fa0682..b59de28 100644 --- a/preferences/src/editor.rs +++ b/preferences/src/editor.rs @@ -1,12 +1,19 @@ +use std::iter; use std::rc::Rc; +use std::str::FromStr; use std::sync::RwLock; -use anyhow::Result; -use chewing::dictionary::{Dictionary, SystemDictionaryLoader, UserDictionaryLoader}; +use anyhow::{anyhow, Result}; +use chewing::dictionary::{ + Dictionary, DictionaryBuilder, SystemDictionaryLoader, TrieBuilder, UserDictionaryLoader, +}; use chewing::dictionary::{DictionaryInfo, Phrase}; use chewing::zhuyin::Syllable; -use slint::{ComponentHandle, Model, ModelRc, ModelTracker, StandardListViewItem, VecModel}; +use slint::{ + ComponentHandle, Model, ModelNotify, ModelRc, ModelTracker, StandardListViewItem, VecModel, +}; +use crate::CallbackResult; use crate::EditorWindow; pub fn run() -> Result<()> { @@ -14,9 +21,15 @@ pub fn run() -> Result<()> { ui.set_dictionaries(dict_list_model()?); + let ui_handle = ui.as_weak(); + ui.on_reload_dict_info(move || { + let ui = ui_handle.upgrade().unwrap(); + // FIXME panic on error + ui.set_dictionaries(dict_list_model().expect("unable to load dict info")); + }); + let ui_handle = ui.as_weak(); ui.on_info_clicked(move |row: ModelRc| { - // let info_dialog = DictionaryInfoDialog::new().unwrap(); let dict_item = row .as_any() .downcast_ref::() @@ -39,6 +52,156 @@ pub fn run() -> Result<()> { ui.set_entries(dict_model); }); + let ui_handle = ui.as_weak(); + ui.on_edit_entry_done(move || -> CallbackResult { + let ui = ui_handle.upgrade().unwrap(); + let out_phrase = ui.get_phrase(); + let out_bopomofo = ui.get_bopomofo(); + let out_freq = ui.get_freq(); + let index = ui.get_edit_dict_current_row() as usize; + let entries_rc = ui.get_entries(); + let entry = entries_rc + .as_any() + .downcast_ref::() + .expect("entries should be a DictEditViewModel"); + if let Ok(mut cache) = entry.cache.write() { + let freq: u32 = match out_freq.parse() { + Ok(v) => v, + Err(_) => { + return CallbackResult { + ok: false, + err_msg: slint::format!("無法辨認 {out_freq} 為數字"), + } + } + }; + let phrase = Phrase::new(out_phrase.as_str(), freq); + let syllables = out_bopomofo + .replace("␣", " ") + // number one vs. bopomofo I + .replace("一", "ㄧ") + .trim() + .split_whitespace() + .map(|cluster| Syllable::from_str(&cluster)) + .collect::>(); + for err in syllables.iter() { + if err.is_err() { + dbg!(err); + } + } + if syllables.iter().any(|syl| syl.is_err()) { + let ellipsis = if out_bopomofo.len() > 20 { 3 } else { 0 }; + let sample = out_bopomofo + .chars() + .take(20) + .chain(iter::repeat_n('.', ellipsis)) + .collect::(); + return CallbackResult { + ok: false, + err_msg: slint::format!( + "{sample} 不是正確的注音\n注意:字與字之間須有 ␣ 或是空格分開" + ), + }; + } + let syllables = syllables + .into_iter() + .map(|syl| syl.unwrap()) + .collect::>(); + cache[index] = (syllables, phrase); + } + entry.tracker.row_changed(index); + CallbackResult { + ok: true, + ..Default::default() + } + }); + + let ui_handle = ui.as_weak(); + ui.on_edit_entry_new(move || { + let ui = ui_handle.upgrade().unwrap(); + let entries_rc = ui.get_entries(); + let entry = entries_rc + .as_any() + .downcast_ref::() + .expect("entries should be a DictEditViewModel"); + let _ = entry + .cache + .write() + .map(|mut cache| { + let phrase = Phrase::new("", 0); + cache.push((vec![], phrase)); + cache.len() - 1 + }) + .map(|index| { + entry.tracker.row_added(index, 1); + }); + }); + + let ui_handle = ui.as_weak(); + ui.on_edit_entry_delete(move || { + let ui = ui_handle.upgrade().unwrap(); + let index = ui.get_edit_dict_current_row() as usize; + let entries_rc = ui.get_entries(); + let entry = entries_rc + .as_any() + .downcast_ref::() + .expect("entries should be a DictEditViewModel"); + let _ = entry + .cache + .write() + .map(|mut cache| { + cache.remove(index); + }) + .map(|_| { + entry.tracker.row_removed(index, 1); + }); + }); + + let ui_handle = ui.as_weak(); + ui.on_edit_dict_save(move || -> CallbackResult { + let ui = ui_handle.upgrade().unwrap(); + let entries_rc = ui.get_entries(); + let entry = entries_rc + .as_any() + .downcast_ref::() + .expect("entries should be a DictEditViewModel"); + entry + .cache + .read() + .map_err(|_| anyhow!("should be able to read cache")) + .and_then(|cache| -> Result<()> { + entry + .dict + .read() + .map_err(|_| anyhow!("should be able to read dict")) + .and_then(|dict| -> Result<()> { + // FIXME detect original dict format + let path = dict.path().expect("dict should have file path"); + let mut builder = TrieBuilder::new(); + builder.set_info(DictionaryInfo { + software: format!( + "{} {}", + env!("CARGO_PKG_NAME"), + env!("CARGO_PKG_VERSION") + ), + ..dict.about() + })?; + for (syls, phrase) in cache.iter() { + builder.insert(&syls, phrase.clone())?; + } + builder.build(path)?; + Ok(()) + }) + }) + .map(|_| CallbackResult { + ok: true, + ..Default::default() + }) + .unwrap_or_else(|e| CallbackResult { + ok: false, + err_msg: e.to_string().into(), + }) + }); + ui.run()?; Ok(()) @@ -57,7 +220,7 @@ fn dict_list_model() -> Result>> { sys_loader .load_extra()? .into_iter() - .map(|dict| ModelRc::new(DictTableItemModel::new("附加", dict))), + .map(|dict| ModelRc::new(DictTableItemModel::new("擴充", dict))), ) .chain( user_loader @@ -156,8 +319,9 @@ impl Model for DictInfoViewModel { } struct DictEditViewModel { - cache: Vec<(Vec, Phrase)>, + cache: RwLock, Phrase)>>, dict: Rc>>, + tracker: ModelNotify, } impl From<&DictTableItemModel> for DictEditViewModel { @@ -168,8 +332,10 @@ impl From<&DictTableItemModel> for DictEditViewModel { .read() .expect("should not have concurrent writer") .entries() - .collect(), + .collect::>() + .into(), dict: value.1.clone(), + tracker: ModelNotify::default(), } } } @@ -178,30 +344,33 @@ impl Model for DictEditViewModel { type Data = ModelRc; fn row_count(&self) -> usize { - self.cache.len() + self.cache.read().expect("no concurrent writer").len() } fn row_data(&self, row: usize) -> Option { - self.cache.get(row).map(|entry| { - ModelRc::from([ - entry.1.as_str().into(), - // FIXME - entry - .0 - .iter() - .map(|syl| syl.to_string()) - .collect::>() - .join(" ") - .as_str() - .into(), - entry.1.freq().to_string().as_str().into(), - ]) - }) + self.cache + .read() + .expect("no concurrent writer") + .get(row) + .map(|entry| { + ModelRc::from([ + entry.1.as_str().into(), + // FIXME + entry + .0 + .iter() + .map(|syl| syl.to_string()) + .collect::>() + .join(" ") + .as_str() + .into(), + entry.1.freq().to_string().as_str().into(), + ]) + }) } fn model_tracker(&self) -> &dyn ModelTracker { - // FIXME - &() + &self.tracker } fn as_any(&self) -> &dyn core::any::Any { diff --git a/preferences/ui/bopomofo-keyboard.slint b/preferences/ui/bopomofo-keyboard.slint index cce10d5..b70aa21 100644 --- a/preferences/ui/bopomofo-keyboard.slint +++ b/preferences/ui/bopomofo-keyboard.slint @@ -5,6 +5,7 @@ export component BopomofoKeyboard inherits VerticalBox { callback clicked(text: string); // callback backspace-clicked(); callback clear-clicked(); + callback done(); property <[[string]]> keys: [ [ @@ -20,7 +21,7 @@ export component BopomofoKeyboard inherits VerticalBox { "ㄢ", "ㄦ", ], - ["ㄆ", "ㄊ", "ㄍ", "ㄐ", "ㄔ", "ㄗ", "一", "ㄛ", "ㄟ", "ㄣ"], + ["ㄆ", "ㄊ", "ㄍ", "ㄐ", "ㄔ", "ㄗ", "ㄧ", "ㄛ", "ㄟ", "ㄣ"], ["ㄇ", "ㄋ", "ㄎ", "ㄑ", "ㄕ", "ㄘ", "ㄨ", "ㄜ", "ㄠ", "ㄤ"], ["ㄈ", "ㄌ", "ㄏ", "ㄒ", "ㄖ", "ㄙ", "ㄩ", "ㄝ", "ㄡ", "ㄥ"] ]; @@ -51,8 +52,18 @@ export component BopomofoKeyboard inherits VerticalBox { } HorizontalLayout { Rectangle { - width: 100px; + width: 40px; + } + + Rectangle { + width: 70px; height: 30px; + Button { + text: "清空"; + clicked => { + clear-clicked() + } + } } Rectangle { @@ -71,9 +82,9 @@ export component BopomofoKeyboard inherits VerticalBox { width: 80px; height: 30px; Button { - text: "清空"; + text: "確定"; clicked => { - clear-clicked() + root.done(); } } } diff --git a/preferences/ui/editor-window.slint b/preferences/ui/editor-window.slint index 1fa0970..a92244f 100644 --- a/preferences/ui/editor-window.slint +++ b/preferences/ui/editor-window.slint @@ -1,16 +1,15 @@ import { VerticalBox, StandardTableView, Button, TabWidget, HorizontalBox, LineEdit, AboutSlint, StandardButton, GridBox } from "std-widgets.slint"; import { BopomofoKeyboard } from "bopomofo-keyboard.slint"; -export struct DictionaryListItem { - id: int, - type: string, - name: string, +export struct CallbackResult { + ok: bool, + err_msg: string, } -enum SidePanel { +enum TabState { dict-info, edit-entry, - hide, + about, } export component EditorWindow inherits Window { @@ -20,64 +19,75 @@ export component EditorWindow inherits Window { in property <[[StandardListViewItem]]> dictionaries; in property <[[StandardListViewItem]]> entries; in property <[[StandardListViewItem]]> dictionary-info; - out property current-row: table.current-row; - property show-dict-info; - property show-edit-entry; - property side-panel; - - property phrase; - property bopomofo; - property freq; - + out property edit-dict-current-row; + out property phrase; + out property bopomofo; + out property freq; + property tab-state: TabState.dict-info; + property edit-result: { ok: true }; + + callback reload-dict-info(); callback info-clicked(row: [StandardListViewItem]); callback edit-dict-clicked(row: [StandardListViewItem]); + callback edit-entry-new(); + callback edit-entry-delete(); + callback edit-entry-done() -> CallbackResult; + callback edit-dict-save() -> CallbackResult; states [ - show-dict-info when tabs.current-index == 0: { - root.side-panel: SidePanel.dict-info; - } - show-edit-entry when tabs.current-index == 1: { - root.side-panel: SidePanel.edit-entry; - } - hide when tabs.current-index == 2: { - root.side-panel: hide; + show-dict-info when tab-state == TabState.dict-info: {} + show-edit-entry when tab-state == TabState.edit-entry: {} + about when tab-state == TabState.about: { + tabs.current-index: 1; } ] HorizontalBox { tabs := TabWidget { + width: 400px; Tab { + states [ + show-dict-info when tab-state == TabState.dict-info: { + title: "管理"; + } + show-edit-entry when tab-state == TabState.edit-entry: { + title: "編輯"; + } + ] title: "管理"; - VerticalBox { + if tab-state == TabState.dict-info: VerticalBox { HorizontalBox { alignment: start; Button { text: "編輯"; - enabled: root.current-row >= 0; + enabled: table.current-row >= 0; clicked => { - root.edit-dict-clicked(root.dictionaries[root.current-row]); - tabs.current-index = 1; + root.edit-dict-clicked(root.dictionaries[table.current-row]); + tab-state = TabState.edit-entry; } } - Button { - text: "新增"; - } + // Button { + // text: "新增"; + // } - Button { - text: "匯入"; - } + // Button { + // text: "匯入"; + // } - Button { - text: "匯出"; - } + // Button { + // text: "匯出"; + // } - Button { - text: "刪除"; - } + // Button { + // text: "刪除"; + // } Button { text: "重新整理"; + clicked => { + root.reload-dict-info(); + } } } @@ -89,41 +99,39 @@ export component EditorWindow inherits Window { } } } - } - - Tab { - title: "編輯"; - VerticalBox { + if tab-state == TabState.edit-entry: VerticalBox { HorizontalBox { alignment: start; Button { text: "新增"; - enabled: false; + clicked => { + root.edit-entry-new(); + } } Button { text: "刪除"; - enabled: false; - } - - Button { - text: "復原"; - enabled: false; - } - - Button { - text: "放棄"; - enabled: false; + clicked => { + root.edit-entry-delete(); + } } Button { - text: "重新整理"; - enabled: false; + text: "放棄修改"; + clicked => { + root.tab-state = TabState.dict-info; + } } Button { text: "存檔"; - enabled: false; + clicked => { + root.edit-result = root.edit-dict-save(); + if (root.edit-result.ok) { + root.reload-dict-info(); + root.tab-state = TabState.dict-info; + } + } } } @@ -138,9 +146,10 @@ export component EditorWindow inherits Window { columns: [{ title: "字/詞" }, { title: "注音" }, { title: "詞頻" }]; rows: entries; current-row-changed(current-row) => { + root.edit-dict-current-row = current-row; root.phrase = root.entries[current-row][0].text; root.bopomofo = root.entries[current-row][1].text; - root.freq = root.entries[current-row][2].text.to-float(); + root.freq = root.entries[current-row][2].text; } } } @@ -152,7 +161,7 @@ export component EditorWindow inherits Window { } } - if root.side-panel == SidePanel.dict-info: HorizontalLayout { + if tab-state == TabState.dict-info: HorizontalLayout { Path { width: 1px; height: 100%; @@ -176,56 +185,71 @@ export component EditorWindow inherits Window { } } } - if root.side-panel == SidePanel.edit-entry: HorizontalLayout { - Path { - width: 1px; - height: 100%; - stroke: Colors.lightgray; - stroke-width: 1px; - MoveTo { - x: 0; - y: 0; - } - - LineTo { - x: 0; - y: 100; + if tab-state == TabState.edit-entry: VerticalBox { + if !root.edit-result.ok: Rectangle { + height: 40px; + border-radius: 5px; + border-width: 1px; + border-color: Colors.lightgray; + background: Colors.lightyellow; + Text { + text: root.edit-result.err-msg; } } + HorizontalLayout { + Path { + width: 1px; + height: 100%; + stroke: Colors.lightgray; + stroke-width: 1px; + MoveTo { + x: 0; + y: 0; + } - VerticalBox { - alignment: start; - Text { - text: "字/詞:"; + LineTo { + x: 0; + y: 100; + } } - LineEdit { - text: root.phrase; - } + VerticalBox { + alignment: start; + Text { + text: "字/詞:"; + } - Text { - text: "注音:"; - } + phrase := LineEdit { + text <=> root.phrase; + } - bopomofo := LineEdit { - text: root.bopomofo; - } + Text { + text: "注音:"; + } - Text { - text: "詞頻:"; - } + bopomofo := LineEdit { + text <=> root.bopomofo; + } - LineEdit { - text: root.freq; - } + Text { + text: "詞頻:"; + } - BopomofoKeyboard { - clicked(text) => { - bopomofo.clear-focus(); - bopomofo.text += text; + freq := LineEdit { + text <=> root.freq; } - clear-clicked => { - bopomofo.text = ""; + + BopomofoKeyboard { + clicked(text) => { + bopomofo.clear-focus(); + bopomofo.text += text; + } + clear-clicked => { + bopomofo.text = ""; + } + done => { + root.edit-result = root.edit-entry-done(); + } } } } diff --git a/preferences/ui/index.slint b/preferences/ui/index.slint index 65741cc..0ac1dda 100644 --- a/preferences/ui/index.slint +++ b/preferences/ui/index.slint @@ -1,4 +1,4 @@ import { AppWindow } from "./app-window.slint"; -import { EditorWindow } from "./editor-window.slint"; +import { EditorWindow, CallbackResult } from "./editor-window.slint"; -export { AppWindow, EditorWindow } \ No newline at end of file +export { AppWindow, EditorWindow, CallbackResult } \ No newline at end of file From f062402399f548b7539d14e38e6cb5973c0dae15 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Sun, 29 Dec 2024 10:28:05 +0900 Subject: [PATCH 05/12] feat(prefs): better error handling --- preferences/src/editor.rs | 15 ++++++++------- preferences/ui/editor-window.slint | 14 ++++++++++---- preferences/ui/index.slint | 4 ++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/preferences/src/editor.rs b/preferences/src/editor.rs index b59de28..3a2894b 100644 --- a/preferences/src/editor.rs +++ b/preferences/src/editor.rs @@ -14,6 +14,7 @@ use slint::{ }; use crate::CallbackResult; +use crate::ErrorKind; use crate::EditorWindow; pub fn run() -> Result<()> { @@ -69,7 +70,7 @@ pub fn run() -> Result<()> { Ok(v) => v, Err(_) => { return CallbackResult { - ok: false, + error: ErrorKind::Other, err_msg: slint::format!("無法辨認 {out_freq} 為數字"), } } @@ -96,7 +97,7 @@ pub fn run() -> Result<()> { .chain(iter::repeat_n('.', ellipsis)) .collect::(); return CallbackResult { - ok: false, + error: ErrorKind::Other, err_msg: slint::format!( "{sample} 不是正確的注音\n注意:字與字之間須有 ␣ 或是空格分開" ), @@ -110,7 +111,7 @@ pub fn run() -> Result<()> { } entry.tracker.row_changed(index); CallbackResult { - ok: true, + error: ErrorKind::Ok, ..Default::default() } }); @@ -193,12 +194,12 @@ pub fn run() -> Result<()> { }) }) .map(|_| CallbackResult { - ok: true, + error: ErrorKind::Ok, ..Default::default() }) - .unwrap_or_else(|e| CallbackResult { - ok: false, - err_msg: e.to_string().into(), + .unwrap_or_else(|_e| CallbackResult { + error: ErrorKind::Other, + err_msg: "無法寫入檔案".into(), }) }); diff --git a/preferences/ui/editor-window.slint b/preferences/ui/editor-window.slint index a92244f..9e1355c 100644 --- a/preferences/ui/editor-window.slint +++ b/preferences/ui/editor-window.slint @@ -1,8 +1,13 @@ import { VerticalBox, StandardTableView, Button, TabWidget, HorizontalBox, LineEdit, AboutSlint, StandardButton, GridBox } from "std-widgets.slint"; import { BopomofoKeyboard } from "bopomofo-keyboard.slint"; +export enum ErrorKind { + ok, + other, +} + export struct CallbackResult { - ok: bool, + error: ErrorKind, err_msg: string, } @@ -24,7 +29,7 @@ export component EditorWindow inherits Window { out property bopomofo; out property freq; property tab-state: TabState.dict-info; - property edit-result: { ok: true }; + property edit-result; callback reload-dict-info(); callback info-clicked(row: [StandardListViewItem]); @@ -120,6 +125,7 @@ export component EditorWindow inherits Window { text: "放棄修改"; clicked => { root.tab-state = TabState.dict-info; + root.edit-result = { } } } @@ -127,7 +133,7 @@ export component EditorWindow inherits Window { text: "存檔"; clicked => { root.edit-result = root.edit-dict-save(); - if (root.edit-result.ok) { + if (root.edit-result.error == ErrorKind.ok) { root.reload-dict-info(); root.tab-state = TabState.dict-info; } @@ -186,7 +192,7 @@ export component EditorWindow inherits Window { } } if tab-state == TabState.edit-entry: VerticalBox { - if !root.edit-result.ok: Rectangle { + if root.edit-result.error != ErrorKind.ok: Rectangle { height: 40px; border-radius: 5px; border-width: 1px; diff --git a/preferences/ui/index.slint b/preferences/ui/index.slint index 0ac1dda..cc69246 100644 --- a/preferences/ui/index.slint +++ b/preferences/ui/index.slint @@ -1,4 +1,4 @@ import { AppWindow } from "./app-window.slint"; -import { EditorWindow, CallbackResult } from "./editor-window.slint"; +import { EditorWindow, CallbackResult, ErrorKind } from "./editor-window.slint"; -export { AppWindow, EditorWindow, CallbackResult } \ No newline at end of file +export { AppWindow, EditorWindow, CallbackResult, ErrorKind } \ No newline at end of file From 79ea7fc96ef0ece74fd72d92bdafd4f9af4d1450 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Sun, 29 Dec 2024 11:21:57 +0900 Subject: [PATCH 06/12] feat(prefs): add about page for editor --- preferences/src/editor.rs | 1 + preferences/ui/editor-window.slint | 50 ++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/preferences/src/editor.rs b/preferences/src/editor.rs index 3a2894b..4216b88 100644 --- a/preferences/src/editor.rs +++ b/preferences/src/editor.rs @@ -20,6 +20,7 @@ use crate::EditorWindow; pub fn run() -> Result<()> { let ui = EditorWindow::new()?; + ui.set_app_version(env!("CARGO_PKG_VERSION").into()); ui.set_dictionaries(dict_list_model()?); let ui_handle = ui.as_weak(); diff --git a/preferences/ui/editor-window.slint b/preferences/ui/editor-window.slint index 9e1355c..cc86081 100644 --- a/preferences/ui/editor-window.slint +++ b/preferences/ui/editor-window.slint @@ -21,10 +21,11 @@ export component EditorWindow inherits Window { default-font-family: "jf open 粉圓 2.0"; default-font-weight: 500; preferred-height: 500px; + in property app-version: "0.0.1"; in property <[[StandardListViewItem]]> dictionaries; in property <[[StandardListViewItem]]> entries; in property <[[StandardListViewItem]]> dictionary-info; - out property edit-dict-current-row; + out property edit-dict-current-row: -1; out property phrase; out property bopomofo; out property freq; @@ -116,6 +117,7 @@ export component EditorWindow inherits Window { Button { text: "刪除"; + enabled: root.edit-dict-current-row >= 0; clicked => { root.edit-entry-delete(); } @@ -163,7 +165,51 @@ export component EditorWindow inherits Window { Tab { title: "關於"; - AboutSlint { } + VerticalBox { + alignment: start; + Text { + text: "新酷音詞庫管理程式"; + font-size: 20px; + font-weight: 800; + } + + Text { + text: "版本 " + root.app-version; + wrap: word-wrap; + } + + Text { + text: "新酷音詞庫管理程式是一個跨平台的新酷音使用者詞庫管理及編輯工具。它提供了一個簡單的方式來管理使用者詞庫。透過它,使用者可以自訂詞庫以提升輸入效率。"; + wrap: word-wrap; + } + + Text { + text: "新酷音詞庫管理程式採用 GNU 通用公眾授權條款第 3.0 版或更新版本授權 (GPL-3.0-or-later)。"; + wrap: word-wrap; + } + + Text { + text: "關於新酷音詞庫管理程式的授權詳情,請參閱 https://www.gnu.org/licenses/gpl-3.0.html 網站。"; + wrap: word-wrap; + } + + Text { + text: "版權所有© 2024 新酷音開發團隊及 GitHub 貢獻者。"; + wrap: word-wrap; + } + + Text { + text: "\n新酷音詞庫管理程式是一個開源專案,開發平台位於 https://github.com/chewing/chewing-editor。\n歡迎在 issues 提供任何建議。"; + wrap: word-wrap; + } + + Text { + text: "此版本使用開源專案 Slint 開發:"; + wrap: word-wrap; + } + + AboutSlint { } + } } } From abb643a3c929cf224633c8314d2cd268163c608a Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Sun, 29 Dec 2024 19:29:57 +0900 Subject: [PATCH 07/12] feat(prefs): implement new config app --- Cargo.lock | 1 + preferences/Cargo.toml | 4 + preferences/src/config.rs | 313 +++++++++++++++++++++++++++ preferences/src/editor.rs | 2 +- preferences/src/main.rs | 4 +- preferences/ui/app-window.slint | 172 --------------- preferences/ui/config-window.slint | 329 +++++++++++++++++++++++++++++ preferences/ui/index.slint | 4 +- 8 files changed, 652 insertions(+), 177 deletions(-) create mode 100644 preferences/src/config.rs delete mode 100644 preferences/ui/app-window.slint create mode 100644 preferences/ui/config-window.slint diff --git a/Cargo.lock b/Cargo.lock index 607cdad..96efbd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -717,6 +717,7 @@ dependencies = [ "chewing 0.9.1 (git+https://github.com/chewing/libchewing?branch=feat-dictionary-mgmt-api)", "slint", "slint-build", + "windows", ] [[package]] diff --git a/preferences/Cargo.toml b/preferences/Cargo.toml index 7690d44..731f44e 100644 --- a/preferences/Cargo.toml +++ b/preferences/Cargo.toml @@ -6,6 +6,10 @@ edition = "2021" [dependencies] anyhow = "1.0.95" slint = "1.8.0" +windows = { version = "0.58.0", features = [ + "Win32_Security", + "Win32_System_Registry", +] } [dependencies.chewing] version = "0.9.1" diff --git a/preferences/src/config.rs b/preferences/src/config.rs new file mode 100644 index 0000000..589bd56 --- /dev/null +++ b/preferences/src/config.rs @@ -0,0 +1,313 @@ +use std::{fs, path::PathBuf, time::SystemTime}; + +use anyhow::{bail, Result}; +use chewing::path::data_dir; +use slint::ComponentHandle; +use windows::{ + core::{w, PCWSTR}, + Win32::System::Registry::{ + RegCloseKey, RegCreateKeyExW, RegGetValueW, RegOpenKeyExW, RegSetValueExW, HKEY, + HKEY_CURRENT_USER, KEY_READ, KEY_WOW64_64KEY, KEY_WRITE, REG_DWORD, + REG_OPEN_CREATE_OPTIONS, RRF_RT_REG_DWORD, + }, +}; + +use crate::ConfigWindow; + +pub fn run() -> Result<()> { + let ui = ConfigWindow::new()?; + load_config(&ui)?; + + ui.on_cancel(move || { + slint::quit_event_loop().unwrap(); + }); + let ui_handle = ui.as_weak(); + ui.on_apply(move || { + let ui = ui_handle.upgrade().unwrap(); + save_config(&ui).unwrap(); + slint::quit_event_loop().unwrap(); + }); + + ui.run()?; + Ok(()) +} + +fn reg_open_key_read(hk: &mut HKEY) -> Result<()> { + unsafe { + RegOpenKeyExW( + HKEY_CURRENT_USER, + w!("Software\\ChewingTextService"), + 0, + KEY_WOW64_64KEY | KEY_READ, + hk, + ) + .ok()?; + } + Ok(()) +} + +fn reg_open_key_write(hk: &mut HKEY) -> Result<()> { + unsafe { + RegCreateKeyExW( + HKEY_CURRENT_USER, + w!("Software\\ChewingTextService"), + 0, + None, + REG_OPEN_CREATE_OPTIONS::default(), + KEY_WOW64_64KEY | KEY_READ | KEY_WRITE, + None, + hk, + None, + ) + .ok()?; + } + Ok(()) +} + +fn reg_close_key(hk: HKEY) { + unsafe { + let _ = RegCloseKey(hk); + } +} + +fn reg_get_u32(hk: HKEY, value_name: PCWSTR) -> Result { + let mut dword = 0; + let mut size = size_of::() as u32; + let pdword: *mut u32 = &mut dword; + unsafe { + RegGetValueW( + hk, + None, + value_name, + RRF_RT_REG_DWORD, + None, + Some(pdword.cast()), + Some(&mut size), + ) + .ok()?; + } + Ok(dword) +} + +fn reg_set_u32(hk: HKEY, value_name: PCWSTR, value: u32) -> Result<()> { + unsafe { + RegSetValueExW(hk, value_name, 0, REG_DWORD, Some(&value.to_ne_bytes())).ok()?; + } + Ok(()) +} + +fn reg_get_i32(hk: HKEY, value_name: PCWSTR) -> Result { + Ok(reg_get_u32(hk, value_name)? as i32) +} + +fn reg_set_i32(hk: HKEY, value_name: PCWSTR, value: i32) -> Result<()> { + Ok(reg_set_u32(hk, value_name, value as u32)?) +} + +fn reg_get_bool(hk: HKEY, value_name: PCWSTR) -> Result { + Ok(reg_get_u32(hk, value_name)? > 0) +} + +fn reg_set_bool(hk: HKEY, value_name: PCWSTR, value: bool) -> Result<()> { + Ok(reg_set_u32(hk, value_name, value as u32)?) +} + +fn default_user_symbols_dat_path() -> PathBuf { + let user_data_dir = PathBuf::from(env!("USERPROFILE")).join("ChewingTextService"); + let user_symbols_dat = data_dir().unwrap_or(user_data_dir).join("symbols.dat"); + user_symbols_dat +} + +// FIXME: provide path info from libchewing +fn user_symbols_dat_path() -> Result { + let user_data_dir = PathBuf::from(env!("USERPROFILE")).join("ChewingTextService"); + let user_symbols_dat = data_dir().unwrap_or(user_data_dir).join("symbols.dat"); + if user_symbols_dat.exists() { + return Ok(user_symbols_dat); + } + bail!("使用者符號檔不存在") +} + +// FIXME: provide path info from libchewing +fn system_symbols_dat_path() -> Result { + let prog_files_x86 = PathBuf::from(env!("ProgramFiles(x86)")) + .join("ChewingTextService\\Dictionary\\symbols.dat"); + let prog_files = + PathBuf::from(env!("ProgramFiles")).join("ChewingTextService\\Dictionary\\symbols.dat"); + if prog_files_x86.exists() { + return Ok(prog_files_x86); + } + if prog_files.exists() { + return Ok(prog_files); + } + bail!("系統詞庫不存在") +} + +fn load_config(ui: &ConfigWindow) -> Result<()> { + // Init settings to default value + ui.set_cand_per_row(3); + ui.set_switch_lang_with_shift(true); + ui.set_add_phrase_forward(true); + ui.set_advance_after_selection(true); + ui.set_font_size(16); + ui.set_conv_engine(1); + ui.set_cand_per_page(9); + ui.set_cursor_cand_list(true); + ui.set_enable_caps_lock(true); + ui.set_full_shape_symbols(true); + ui.set_easy_symbols_with_shift(true); + + if let Ok(path) = user_symbols_dat_path() { + ui.set_symbols_dat(fs::read_to_string(path)?.into()); + } else { + if let Ok(path) = system_symbols_dat_path() { + ui.set_symbols_dat(fs::read_to_string(path)?.into()); + } + } + + // Load custom value from the registry + let mut hk = Default::default(); + if reg_open_key_read(&mut hk).is_ok() { + if let Ok(value) = reg_get_i32(hk, w!("KeyboardLayout")) { + ui.set_keyboard_layout(value); + } + if let Ok(value) = reg_get_i32(hk, w!("CandPerRow")) { + ui.set_cand_per_row(value); + } + if let Ok(value) = reg_get_bool(hk, w!("DefaultEnglish")) { + ui.set_default_english(value); + } + if let Ok(value) = reg_get_bool(hk, w!("DefaultFullSpace")) { + ui.set_default_full_space(value); + } + if let Ok(value) = reg_get_bool(hk, w!("ShowCandWithSpaceKey")) { + ui.set_show_cand_with_space_key(value); + } + if let Ok(value) = reg_get_bool(hk, w!("SwitchLangWithShift")) { + ui.set_switch_lang_with_shift(value); + } + if let Ok(value) = reg_get_bool(hk, w!("OutputSimpChinese")) { + ui.set_output_simp_chinese(value); + } + if let Ok(value) = reg_get_bool(hk, w!("AddPhraseForward")) { + ui.set_add_phrase_forward(value); + } + // if let Ok(value) = reg_get_bool(hk, w!("ColorCandWnd")) { + // ui.set_color_cand_wnd(value); + // } + if let Ok(value) = reg_get_bool(hk, w!("AdvanceAfterSelection")) { + ui.set_advance_after_selection(value); + } + if let Ok(value) = reg_get_i32(hk, w!("DefFontSize")) { + ui.set_font_size(value); + } + if let Ok(value) = reg_get_i32(hk, w!("SelKeyType")) { + ui.set_sel_key_type(value); + } + if let Ok(value) = reg_get_i32(hk, w!("ConvEngine")) { + ui.set_conv_engine(value); + } + if let Ok(value) = reg_get_i32(hk, w!("SelAreaLen")) { + ui.set_cand_per_page(value); + } + if let Ok(value) = reg_get_bool(hk, w!("CursorCandList")) { + ui.set_cursor_cand_list(value); + } + if let Ok(value) = reg_get_bool(hk, w!("EnableCapsLock")) { + ui.set_enable_caps_lock(value); + } + if let Ok(value) = reg_get_bool(hk, w!("FullShapeSymbols")) { + ui.set_full_shape_symbols(value); + } + // if let Ok(value) = reg_get_bool(hk, w!("PhraseMark")) { + // ui.set_phrase_mark(value); + // } + if let Ok(value) = reg_get_bool(hk, w!("EscCleanAllBuf")) { + ui.set_esc_clean_all_buf(value); + } + if let Ok(value) = reg_get_bool(hk, w!("EasySymbolsWithShift")) { + ui.set_easy_symbols_with_shift(value); + } + if let Ok(value) = reg_get_bool(hk, w!("EasySymbolsWithCtrl")) { + ui.set_easy_symbols_with_ctrl(value); + } + if let Ok(value) = reg_get_bool(hk, w!("UpperCaseWithShift")) { + ui.set_upper_case_with_shift(value); + } + + reg_close_key(hk); + } + + Ok(()) +} + +fn save_config(ui: &ConfigWindow) -> Result<()> { + let mut hk: HKEY = Default::default(); + + if reg_open_key_write(&mut hk).is_ok() { + let _ = reg_set_i32(hk, w!("KeyboardLayout"), ui.get_keyboard_layout()); + let _ = reg_set_i32(hk, w!("CandPerRow"), ui.get_cand_per_row()); + let _ = reg_set_bool(hk, w!("DefaultEnglish"), ui.get_default_english()); + let _ = reg_set_bool(hk, w!("DefaultFullSpace"), ui.get_default_full_space()); + let _ = reg_set_bool( + hk, + w!("ShowCandWithSpaceKey"), + ui.get_show_cand_with_space_key(), + ); + let _ = reg_set_bool( + hk, + w!("SwitchLangWithShift"), + ui.get_switch_lang_with_shift(), + ); + let _ = reg_set_bool(hk, w!("OutputSimpChinese"), ui.get_output_simp_chinese()); + let _ = reg_set_bool(hk, w!("AddPhraseForward"), ui.get_add_phrase_forward()); + // let _ = reg_set_i32(hk, w!("ColorCandWnd"), ui.get_color_cand_wnd()); + let _ = reg_set_bool( + hk, + w!("AdvanceAfterSelection"), + ui.get_advance_after_selection(), + ); + let _ = reg_set_i32(hk, w!("DefFontSize"), ui.get_font_size()); + let _ = reg_set_i32(hk, w!("SelKeyType"), ui.get_sel_key_type()); + let _ = reg_set_i32(hk, w!("ConvEngine"), ui.get_conv_engine()); + let _ = reg_set_i32(hk, w!("SelAreaLen"), ui.get_cand_per_page()); + let _ = reg_set_bool(hk, w!("CursorCandList"), ui.get_cursor_cand_list()); + let _ = reg_set_bool(hk, w!("EnableCapsLock"), ui.get_enable_caps_lock()); + let _ = reg_set_bool(hk, w!("FullShapeSymbols"), ui.get_full_shape_symbols()); + // let _ = reg_set_bool(hk, w!("PhraseMark"), ui.get_phrase_mark()); + let _ = reg_set_bool(hk, w!("EscCleanAllBuf"), ui.get_esc_clean_all_buf()); + let _ = reg_set_bool( + hk, + w!("EasySymbolsWithShift"), + ui.get_easy_symbols_with_shift(), + ); + let _ = reg_set_bool( + hk, + w!("EasySymbolsWithCtrl"), + ui.get_easy_symbols_with_ctrl(), + ); + let _ = reg_set_bool(hk, w!("UpperCaseWithShift"), ui.get_upper_case_with_shift()); + let _ = reg_set_u32( + hk, + w!("ModifiedTimestamp"), + SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap_or_default() + .as_secs() as u32, + ); + + reg_close_key(hk); + } + + let sys_symbols_dat = system_symbols_dat_path() + .and_then(|path| Ok(fs::read_to_string(path)?)) + .unwrap_or_default(); + if ui.get_symbols_dat() != sys_symbols_dat { + let user_symbols_dat_path = + user_symbols_dat_path().unwrap_or_else(|_| default_user_symbols_dat_path()); + fs::create_dir_all(user_symbols_dat_path.parent().unwrap())?; + fs::write(user_symbols_dat_path, ui.get_symbols_dat())?; + } + + Ok(()) +} diff --git a/preferences/src/editor.rs b/preferences/src/editor.rs index 4216b88..5973ea8 100644 --- a/preferences/src/editor.rs +++ b/preferences/src/editor.rs @@ -14,8 +14,8 @@ use slint::{ }; use crate::CallbackResult; -use crate::ErrorKind; use crate::EditorWindow; +use crate::ErrorKind; pub fn run() -> Result<()> { let ui = EditorWindow::new()?; diff --git a/preferences/src/main.rs b/preferences/src/main.rs index a0afc64..0fbe54e 100644 --- a/preferences/src/main.rs +++ b/preferences/src/main.rs @@ -1,5 +1,6 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +mod config; mod editor; use std::env; @@ -10,8 +11,7 @@ fn main() -> anyhow::Result<()> { if env::args().any(|arg| arg == "/edit" || arg == "--edit") { editor::run()?; } else { - let ui = AppWindow::new()?; - ui.run()?; + config::run()?; } Ok(()) } diff --git a/preferences/ui/app-window.slint b/preferences/ui/app-window.slint deleted file mode 100644 index 14c94af..0000000 --- a/preferences/ui/app-window.slint +++ /dev/null @@ -1,172 +0,0 @@ -import { Button, VerticalBox, TabWidget, CheckBox, ComboBox, HorizontalBox, SpinBox, AboutSlint, TextEdit, StandardButton } from "std-widgets.slint"; - -export component AppWindow inherits Window { - default-font-family: "jf open 粉圓 2.0"; - default-font-weight: 500; - title: "Chewing Preferences (24.10.1.999)"; - icon: @image-url("../../icon/48_icon.png"); - max-width: 500px; - max-height: 500px; - VerticalBox { - - TabWidget { - Tab { - title: "打字行為"; - HorizontalLayout { - padding: 20px; - spacing: 20px; - VerticalLayout { - spacing: 10px; - alignment: start; - CheckBox { - text: "使用 Shift 快速切換中英文"; - } - - CheckBox { - text: "使用 CapsLock 切換中英文"; - } - - CheckBox { - text: "使用 Esc 清空編輯區字串"; - } - - CheckBox { - text: "按住 Shift 輸入全形標點符號"; - } - - CheckBox { - text: "按住 Shift 輸入大寫英文字母"; - } - - CheckBox { - text: "Ctrl + 數字儲存游標前方的詞"; - } - - CheckBox { - text: "按住 Shift 輸入快速符號"; - checked: true; - enabled: false; - } - - CheckBox { - text: "按住 Ctrl 輸入快速符號"; - enabled: false; - } - } - - VerticalLayout { - spacing: 10px; - alignment: start; - CheckBox { - text: "使用方向鍵移動游標選字"; - } - - CheckBox { - text: "按空白鍵叫出選字視窗"; - } - - CheckBox { - text: "選字完畢自動跳到下一個字"; - } - - CheckBox { - text: "預設以全形模式啟動"; - } - - CheckBox { - text: "預設以英文模式啟動"; - } - - CheckBox { - text: "預設輸出簡體中文"; - } - - Text { - text: "選字鍵:"; - } - - ComboBox { - model: ["1234567890"]; - } - - Text { - text: "模式:"; - } - - ComboBox { } - } - } - } - - Tab { - title: "界面外觀"; - VerticalBox { - alignment: start; - Text { - text: "每列顯示後選字個數"; - min-width: 140px; - } - - SpinBox { - minimum: 1; - maximum: 10; - } - - Text { - text: "每頁顯示後選字個數"; - min-width: 140px; - } - - SpinBox { - minimum: 1; - maximum: 10; - } - - Text { - text: "選字及訊息視窗文字大小"; - min-width: 140px; - } - - SpinBox { - minimum: 10; - } - } - } - - Tab { - title: "鍵盤設定"; - } - - Tab { - title: "特殊符號"; - VerticalBox { - Text { - text: "輸入中文時,按下 ` 鍵,會顯示下列的符號表:"; - } - - TextEdit { } - - Text { - text: "以上是符號表的設定檔,語法相當簡單:\n每一行的內容都是:「分類名稱」=「此分類下的所有符號」\n您也可以一行只放一個符號,則該符號會被放在最上層選單。"; - } - } - } - - Tab { - title: "關於"; - AboutSlint { } - } - } - - HorizontalBox { - alignment: end; - StandardButton { - kind: apply; - } - - StandardButton { - kind: cancel; - } - } - } -} diff --git a/preferences/ui/config-window.slint b/preferences/ui/config-window.slint new file mode 100644 index 0000000..c3ccbf1 --- /dev/null +++ b/preferences/ui/config-window.slint @@ -0,0 +1,329 @@ +import { Button, VerticalBox, TabWidget, CheckBox, ComboBox, HorizontalBox, SpinBox, AboutSlint, TextEdit, StandardButton } from "std-widgets.slint"; + +export component ConfigWindow inherits Window { + default-font-family: "jf open 粉圓 2.0"; + default-font-weight: 500; + title: "Chewing Preferences (24.10.1.999)"; + icon: @image-url("../../icon/48_icon.png"); + preferred-width: 500px; + preferred-height: 400px; + max-width: 500px; + max-height: 400px; + + in-out property switch-lang-with-shift; + in-out property enable-caps-lock; + in-out property esc-clean-all-buf; + in-out property full-shape-symbols; + in-out property upper-case-with-shift; + in-out property add-phrase-forward; + in-out property easy-symbols-with-shift: true; + in-out property easy-symbols-with-ctrl: false; + in-out property cursor-cand-list; + in-out property show-cand-with-space-key; + in-out property advance-after-selection; + in-out property default-full-space; + in-out property default-english; + in-out property output-simp-chinese; + in-out property sel-key-type; + in-out property conv-engine; + in-out property cand-per-row; + in-out property cand-per-page; + in-out property font-size; + in-out property keyboard-layout; + in-out property symbols-dat; + + callback apply(); + callback cancel(); + + VerticalBox { + + TabWidget { + Tab { + title: "打字行為"; + HorizontalLayout { + padding: 20px; + spacing: 20px; + VerticalLayout { + spacing: 10px; + alignment: start; + CheckBox { + text: "使用 Shift 快速切換中英文"; + checked <=> switch-lang-with-shift; + } + + CheckBox { + text: "使用 CapsLock 切換中英文"; + checked <=> enable-caps-lock; + } + + CheckBox { + text: "使用 Esc 清空編輯區字串"; + checked <=> esc-clean-all-buf; + } + + CheckBox { + text: "按住 Shift 輸入全形標點符號"; + checked <=> full-shape-symbols; + } + + CheckBox { + text: "按住 Shift 輸入大寫英文字母"; + checked <=> upper-case-with-shift; + } + + CheckBox { + text: "Ctrl + 數字儲存游標前方的詞"; + checked <=> add-phrase-forward; + } + + CheckBox { + text: "按住 Shift 輸入快速符號"; + checked <=> easy-symbols-with-shift; + enabled: false; + } + + CheckBox { + text: "按住 Ctrl 輸入快速符號"; + checked <=> easy-symbols-with-ctrl; + enabled: false; + } + } + + VerticalLayout { + spacing: 10px; + alignment: start; + CheckBox { + text: "使用方向鍵移動游標選字"; + checked <=> cursor-cand-list; + } + + CheckBox { + text: "按空白鍵叫出選字視窗"; + checked <=> show-cand-with-space-key; + } + + CheckBox { + text: "選字完畢自動跳到下一個字"; + checked <=> advance-after-selection; + } + + CheckBox { + text: "預設以全形模式啟動"; + checked <=> default-full-space; + } + + CheckBox { + text: "預設以英文模式啟動"; + checked <=> default-english; + } + + CheckBox { + text: "預設輸出簡體中文"; + checked <=> output-simp-chinese; + } + + Text { + text: "選字鍵:"; + } + + ComboBox { + model: [ + "1234567890", + "asdfghjkl;", + "asdfzxcv89", + "asdfjkl789", + "aoeuhtn789", + "1234qweras", + ]; + current-index <=> sel-key-type; + } + + Text { + text: "模式:"; + } + + ComboBox { + model: ["簡單注音", "智慧選詞", "模糊智慧選詞"]; + current-index <=> conv-engine; + } + } + } + } + + Tab { + title: "界面外觀"; + VerticalBox { + alignment: start; + Text { + text: "每列顯示後選字個數"; + min-width: 140px; + } + + SpinBox { + minimum: 1; + maximum: 10; + value <=> cand-per-row; + } + + Text { + text: "每頁顯示後選字個數"; + min-width: 140px; + } + + SpinBox { + minimum: 1; + maximum: 10; + value <=> cand-per-page; + } + + Text { + text: "選字及訊息視窗文字大小"; + min-width: 140px; + } + + SpinBox { + minimum: 4; + maximum: 64; + value <=> font-size; + } + } + } + + Tab { + title: "鍵盤設定"; + + property <[string]> layout-names: [ + "預設", + "許氏鍵盤", + "IBM", + "精業", + "倚天", + "倚天 26 鍵", + ]; + property <[string]> layout-names6: [ + "DVORAK", + "DVORAK 許氏", + "漢語拼音", + "台灣華語羅馬拼音", + "注音二式", + "CARPLX", + ]; + property <[string]> layout-names12: [ + "Colemak-DH ANSI", + "Colemak DH Orth", + "Workman", + ]; + + VerticalBox { + alignment: start; + Text { + text: "鍵盤對應"; + } + + HorizontalBox { + VerticalBox { + for layout[index] in layout-names: CheckBox { + text: layout; + property selected <=> keyboard-layout; + init => { + self.checked = selected == index; + } + changed selected => { + self.checked = selected == index; + } + toggled => { + if self.checked { + keyboard-layout = index; + } else { + keyboard-layout = 0; + } + } + } + } + + VerticalBox { + for layout[index] in layout-names6: CheckBox { + text: layout; + property selected <=> keyboard-layout; + init => { + self.checked = selected == index + 6; + } + changed selected => { + self.checked = selected == index + 6; + } + toggled => { + if self.checked { + keyboard-layout = index + 6; + } else { + keyboard-layout = 0; + } + } + } + } + + VerticalBox { + for layout[index] in layout-names12: CheckBox { + text: layout; + property selected <=> keyboard-layout; + init => { + self.checked = selected == index + 12; + } + changed selected => { + self.checked = selected == index + 12; + } + toggled => { + if self.checked { + keyboard-layout = index + 12; + } else { + keyboard-layout = 0; + } + } + } + } + } + } + } + + Tab { + title: "特殊符號"; + VerticalBox { + Text { + text: "輸入中文時,按下 ` 鍵,會顯示下列的符號表:"; + } + + TextEdit { + text <=> symbols-dat; + wrap: no-wrap; + } + + Text { + text: "以上是符號表的設定檔,語法相當簡單:\n每一行的內容都是:「分類名稱」=「此分類下的所有符號」\n您也可以一行只放一個符號,則該符號會被放在最上層選單。"; + wrap: word-wrap; + } + } + } + + Tab { + title: "關於"; + AboutSlint { } + } + } + + HorizontalBox { + alignment: end; + Button { + text: "確定"; + clicked => { + root.apply(); + } + } + + Button { + text: "取消"; + clicked => { + root.cancel(); + } + } + } + } +} diff --git a/preferences/ui/index.slint b/preferences/ui/index.slint index cc69246..fb05059 100644 --- a/preferences/ui/index.slint +++ b/preferences/ui/index.slint @@ -1,4 +1,4 @@ -import { AppWindow } from "./app-window.slint"; +import { ConfigWindow } from "./config-window.slint"; import { EditorWindow, CallbackResult, ErrorKind } from "./editor-window.slint"; -export { AppWindow, EditorWindow, CallbackResult, ErrorKind } \ No newline at end of file +export { ConfigWindow, EditorWindow, CallbackResult, ErrorKind } From 21eec74861fc0afe4a248ececb3fce32ffc08c0d Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Mon, 30 Dec 2024 12:56:03 +0900 Subject: [PATCH 08/12] feat(prefs): add about page for config window --- preferences/ui/config-window.slint | 55 ++++++++++++++++++++++++++++- preferences/ui/logo.png | Bin 0 -> 14288 bytes 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 preferences/ui/logo.png diff --git a/preferences/ui/config-window.slint b/preferences/ui/config-window.slint index c3ccbf1..c3261fa 100644 --- a/preferences/ui/config-window.slint +++ b/preferences/ui/config-window.slint @@ -305,7 +305,60 @@ export component ConfigWindow inherits Window { Tab { title: "關於"; - AboutSlint { } + VerticalBox { + HorizontalLayout { + Image { + source: @image-url("logo.png"); + } + + VerticalLayout { + Text { + text: "新酷音 - 智慧型注音輸入法"; + } + // FIXME use globals + Text { + text: "版本:24.10.1.0"; + } + + Text { + text: "發行日期:2024 年 12 月 24 日"; + } + + Text { + text: "軟體開發者:libchewing 開發團隊"; + } + + Text { + text: "授權方式:GPL-3.0-or-later"; + } + + Text { + text: "專案首頁:https://chewing.im"; + } + } + } + + Text { + text: "題字:翁政銓"; + } + + Text { + text: "新酷音原是 Linux 系統下知名的輸入法,由 gugod, jserv, kanru 等前輩,改良原本由龔律全與陳康本開發的酷音輸入法而來,有多種分支,目前已經能夠支援包括 Mac 在內的多種平台。這個 Windows 版本是由 PCMan, czchen 等人,使用 libchewing 核心,移植出 Windows TSF 版本。"; + wrap: word-wrap; + } + + Text { + text: "此設定程式使用開源專案 Slint 開發:"; + wrap: word-wrap; + } + + HorizontalLayout { + alignment: start; + AboutSlint { + width: 50%; + } + } + } } } diff --git a/preferences/ui/logo.png b/preferences/ui/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..91db568d13213463b1e071d4f3d70f69ca97a547 GIT binary patch literal 14288 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 MMdd`Qg!Kdd2i63GzyJUM literal 0 HcmV?d00001 From e3d736bbdfe5b4f1204c95eb63ef7bc980c62211 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Mon, 30 Dec 2024 14:23:52 +0900 Subject: [PATCH 09/12] feat(prefs): use assets and version string from globals --- Cargo.lock | 1 + preferences/Cargo.toml | 5 +++ preferences/build.rs | 3 ++ preferences/preferences.rc | 52 +++++++++++++++++++++++++++++ preferences/src/editor.rs | 1 - preferences/ui/config-window.slint | 11 +++--- preferences/ui/editor-window.slint | 22 ++++++++---- preferences/ui/globals.slint | 5 +++ preferences/ui/icon.png | Bin 0 -> 2559 bytes preferences/ui/version.slint | 4 +++ xtask/src/main.rs | 11 ++++++ 11 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 preferences/preferences.rc create mode 100644 preferences/ui/globals.slint create mode 100644 preferences/ui/icon.png create mode 100644 preferences/ui/version.slint diff --git a/Cargo.lock b/Cargo.lock index 96efbd8..833af9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -715,6 +715,7 @@ version = "0.1.0" dependencies = [ "anyhow", "chewing 0.9.1 (git+https://github.com/chewing/libchewing?branch=feat-dictionary-mgmt-api)", + "embed-resource", "slint", "slint-build", "windows", diff --git a/preferences/Cargo.toml b/preferences/Cargo.toml index 731f44e..b46d760 100644 --- a/preferences/Cargo.toml +++ b/preferences/Cargo.toml @@ -3,6 +3,10 @@ name = "chewing-preferences" version = "0.1.0" edition = "2021" +[[bin]] +name = "ChewingPreferences" +path = "src/main.rs" + [dependencies] anyhow = "1.0.95" slint = "1.8.0" @@ -18,4 +22,5 @@ git = "https://github.com/chewing/libchewing" branch = "feat-dictionary-mgmt-api" [build-dependencies] +embed-resource = "3.0.1" slint-build = "1.8.0" diff --git a/preferences/build.rs b/preferences/build.rs index 7ed55a7..dc6ad48 100644 --- a/preferences/build.rs +++ b/preferences/build.rs @@ -1,3 +1,6 @@ fn main() { slint_build::compile("ui/index.slint").expect("Slint build failed"); + embed_resource::compile("preferences.rc", embed_resource::NONE) + .manifest_optional() + .unwrap(); } diff --git a/preferences/preferences.rc b/preferences/preferences.rc new file mode 100644 index 0000000..4e5eff7 --- /dev/null +++ b/preferences/preferences.rc @@ -0,0 +1,52 @@ +#pragma code_page(65001) // UTF-8 + +#include + +#include "../version.rc" + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON ICON "../chewing_tip/im.chewing.Chewing.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VER_FILEVERSION + PRODUCTVERSION VER_PRODUCTVERSION + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040404b0" + BEGIN + VALUE "CompanyName", "Chewing" + VALUE "FileDescription", "新酷音輸入法設定" + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", "ChewingPreferences.exe" + VALUE "LegalCopyright", "Copyright (C) 2024" + VALUE "OriginalFilename", "ChewingPreferences.exe" + VALUE "ProductName", "新酷音輸入法設定" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x404, 1200 + END +END diff --git a/preferences/src/editor.rs b/preferences/src/editor.rs index 5973ea8..8c6cb67 100644 --- a/preferences/src/editor.rs +++ b/preferences/src/editor.rs @@ -20,7 +20,6 @@ use crate::ErrorKind; pub fn run() -> Result<()> { let ui = EditorWindow::new()?; - ui.set_app_version(env!("CARGO_PKG_VERSION").into()); ui.set_dictionaries(dict_list_model()?); let ui_handle = ui.as_weak(); diff --git a/preferences/ui/config-window.slint b/preferences/ui/config-window.slint index c3261fa..1d772ce 100644 --- a/preferences/ui/config-window.slint +++ b/preferences/ui/config-window.slint @@ -1,10 +1,11 @@ import { Button, VerticalBox, TabWidget, CheckBox, ComboBox, HorizontalBox, SpinBox, AboutSlint, TextEdit, StandardButton } from "std-widgets.slint"; +import { Assets, Version } from "globals.slint"; export component ConfigWindow inherits Window { default-font-family: "jf open 粉圓 2.0"; default-font-weight: 500; - title: "Chewing Preferences (24.10.1.999)"; - icon: @image-url("../../icon/48_icon.png"); + title: "設定新酷音輸入法 (" + Version.product-version + ")"; + icon: Assets.icon; preferred-width: 500px; preferred-height: 400px; max-width: 500px; @@ -315,13 +316,13 @@ export component ConfigWindow inherits Window { Text { text: "新酷音 - 智慧型注音輸入法"; } - // FIXME use globals + Text { - text: "版本:24.10.1.0"; + text: "版本:" + Version.product-version; } Text { - text: "發行日期:2024 年 12 月 24 日"; + text: "發行日期:" + Version.build-date; } Text { diff --git a/preferences/ui/editor-window.slint b/preferences/ui/editor-window.slint index cc86081..f46e651 100644 --- a/preferences/ui/editor-window.slint +++ b/preferences/ui/editor-window.slint @@ -1,4 +1,5 @@ import { VerticalBox, StandardTableView, Button, TabWidget, HorizontalBox, LineEdit, AboutSlint, StandardButton, GridBox } from "std-widgets.slint"; +import { Assets, Version } from "globals.slint"; import { BopomofoKeyboard } from "bopomofo-keyboard.slint"; export enum ErrorKind { @@ -18,10 +19,9 @@ enum TabState { } export component EditorWindow inherits Window { - default-font-family: "jf open 粉圓 2.0"; - default-font-weight: 500; preferred-height: 500px; - in property app-version: "0.0.1"; + title: "新酷音詞庫管理程式 (" + Version.product-version + ")"; + icon: Assets.icon; in property <[[StandardListViewItem]]> dictionaries; in property <[[StandardListViewItem]]> entries; in property <[[StandardListViewItem]]> dictionary-info; @@ -174,12 +174,17 @@ export component EditorWindow inherits Window { } Text { - text: "版本 " + root.app-version; + text: "版本:" + Version.product-version; wrap: word-wrap; } Text { - text: "新酷音詞庫管理程式是一個跨平台的新酷音使用者詞庫管理及編輯工具。它提供了一個簡單的方式來管理使用者詞庫。透過它,使用者可以自訂詞庫以提升輸入效率。"; + text: "發行日期:" + Version.build-date; + wrap: word-wrap; + } + + Text { + text: "新酷音詞庫管理程式是一個跨平台的新酷音詞庫管理及編輯工具。它提供了一個簡單的方式來管理使用者詞庫。透過它,使用者可以自訂詞庫以提升輸入效率。"; wrap: word-wrap; } @@ -199,7 +204,12 @@ export component EditorWindow inherits Window { } Text { - text: "\n新酷音詞庫管理程式是一個開源專案,開發平台位於 https://github.com/chewing/chewing-editor。\n歡迎在 issues 提供任何建議。"; + text: "新酷音詞庫管理程式是一個開源專案,開發平台位於 https://github.com/chewing/chewing-editor。歡迎在 issues 提供任何建議。"; + wrap: word-wrap; + } + + Text { + text: "特別感謝:"; wrap: word-wrap; } diff --git a/preferences/ui/globals.slint b/preferences/ui/globals.slint new file mode 100644 index 0000000..22e0c33 --- /dev/null +++ b/preferences/ui/globals.slint @@ -0,0 +1,5 @@ +export global Assets { + out property icon: @image-url("icon.png"); +} + +export * from "version.slint"; diff --git a/preferences/ui/icon.png b/preferences/ui/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..21a59ed9abb23aeffca91bf8af06e0d30b2833c5 GIT binary patch literal 2559 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 V%0>rE)HVPB002ovPDHLkV1gdpt78BF literal 0 HcmV?d00001 diff --git a/preferences/ui/version.slint b/preferences/ui/version.slint new file mode 100644 index 0000000..2261176 --- /dev/null +++ b/preferences/ui/version.slint @@ -0,0 +1,4 @@ +export global Version { + out property product-version: "24.10.1.0"; + out property build-date: "2024 年 12 月 24 日"; +} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index c08a8de..f3e9c8d 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -90,6 +90,17 @@ fn main() -> anyhow::Result<()> { "# )?; + let mut version_slint = File::create("preferences/ui/version.slint")?; + indoc::writedoc!( + version_slint, + r#" + export global Version {{ + out property product-version: "{yy}.{mm}.{rv}.{bn}"; + out property build-date: "{year} 年 {month:02} 月 {day:02} 日"; + }} + "# + )?; + let mut version_wxi = File::create("installer/version.wxi")?; indoc::writedoc!( version_wxi, From 9c2098dc031b5abc01d557d12901b4c46b436579 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Mon, 30 Dec 2024 15:19:51 +0900 Subject: [PATCH 10/12] feat(prefs): replace ChewingPreferences with chewing-preferences-rs --- CMakeLists.txt | 1 - Cargo.lock | 2 +- ChewingPreferences/AboutDialog.cpp | 66 --- ChewingPreferences/AboutDialog.h | 40 -- ChewingPreferences/CMakeLists.txt | 52 --- ChewingPreferences/ChewingPreferences.cpp | 80 ---- .../ChewingPreferences.exe.manifest | 36 -- ChewingPreferences/ChewingPreferences.rc | 402 ------------------ ChewingPreferences/ChewingPreferences.rc2 | 1 - ChewingPreferences/Dialog.cpp | 99 ----- ChewingPreferences/Dialog.h | 56 --- ChewingPreferences/KeyboardPropertyPage.cpp | 53 --- ChewingPreferences/KeyboardPropertyPage.h | 44 -- ChewingPreferences/PropertyDialog.cpp | 88 ---- ChewingPreferences/PropertyDialog.h | 52 --- ChewingPreferences/PropertyPage.cpp | 81 ---- ChewingPreferences/PropertyPage.h | 48 --- ChewingPreferences/SymbolsPropertyPage.cpp | 124 ------ ChewingPreferences/SymbolsPropertyPage.h | 47 -- ChewingPreferences/TypingPropertyPage.cpp | 94 ---- ChewingPreferences/TypingPropertyPage.h | 43 -- ChewingPreferences/UiPropertyPage.cpp | 80 ---- ChewingPreferences/UiPropertyPage.h | 44 -- ChewingPreferences/resource.h | 169 -------- chewing_tip/ChewingTextService.cpp | 9 +- chewing_tip/ChewingTextService.rc | 2 +- preferences/Cargo.toml | 2 +- preferences/src/about.rs | 15 + preferences/src/main.rs | 3 + preferences/ui/about-box.slint | 51 +++ preferences/ui/about-window.slint | 29 ++ preferences/ui/config-window.slint | 42 +- preferences/ui/index.slint | 3 +- scripts/build_installer.bat | 4 +- 34 files changed, 116 insertions(+), 1846 deletions(-) delete mode 100644 ChewingPreferences/AboutDialog.cpp delete mode 100644 ChewingPreferences/AboutDialog.h delete mode 100644 ChewingPreferences/CMakeLists.txt delete mode 100644 ChewingPreferences/ChewingPreferences.cpp delete mode 100644 ChewingPreferences/ChewingPreferences.exe.manifest delete mode 100644 ChewingPreferences/ChewingPreferences.rc delete mode 100644 ChewingPreferences/ChewingPreferences.rc2 delete mode 100644 ChewingPreferences/Dialog.cpp delete mode 100644 ChewingPreferences/Dialog.h delete mode 100644 ChewingPreferences/KeyboardPropertyPage.cpp delete mode 100644 ChewingPreferences/KeyboardPropertyPage.h delete mode 100644 ChewingPreferences/PropertyDialog.cpp delete mode 100644 ChewingPreferences/PropertyDialog.h delete mode 100644 ChewingPreferences/PropertyPage.cpp delete mode 100644 ChewingPreferences/PropertyPage.h delete mode 100644 ChewingPreferences/SymbolsPropertyPage.cpp delete mode 100644 ChewingPreferences/SymbolsPropertyPage.h delete mode 100644 ChewingPreferences/TypingPropertyPage.cpp delete mode 100644 ChewingPreferences/TypingPropertyPage.h delete mode 100644 ChewingPreferences/UiPropertyPage.cpp delete mode 100644 ChewingPreferences/UiPropertyPage.h delete mode 100644 ChewingPreferences/resource.h create mode 100644 preferences/src/about.rs create mode 100644 preferences/ui/about-box.slint create mode 100644 preferences/ui/about-window.slint diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d896ad..40e00e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.24.0) project(windows-chewing-tsf LANGUAGES CXX) add_subdirectory(libchewing) -add_subdirectory(ChewingPreferences) set(CPACK_PACKAGE_CHECKSUM SHA256) set(CPACK_PACKAGE_VERSION 24.10.1) diff --git a/Cargo.lock b/Cargo.lock index 833af9c..65db9b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -711,7 +711,7 @@ dependencies = [ [[package]] name = "chewing-preferences" -version = "0.1.0" +version = "24.10.1" dependencies = [ "anyhow", "chewing 0.9.1 (git+https://github.com/chewing/libchewing?branch=feat-dictionary-mgmt-api)", diff --git a/ChewingPreferences/AboutDialog.cpp b/ChewingPreferences/AboutDialog.cpp deleted file mode 100644 index 5fa0731..0000000 --- a/ChewingPreferences/AboutDialog.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#include "AboutDialog.h" -#include "Commctrl.h" -#include "resource.h" - -namespace Chewing { - -AboutDialog::AboutDialog(void): Ime::Dialog() { - static bool initSysLink = false; - if(!initSysLink) { - // we don't link to comctl32.dll directly since Win8 metro seems to block it. - INITCOMMONCONTROLSEX icc; - icc.dwSize = sizeof(icc); - icc.dwICC = ICC_LINK_CLASS; - // initialize syslink control - initSysLink = (bool)InitCommonControlsEx(&icc); - } -} - -AboutDialog::~AboutDialog(void) { -} - -bool AboutDialog::onInitDialog() { - return Ime::Dialog::onInitDialog(); -} - -LRESULT AboutDialog::wndProc(UINT msg, WPARAM wp, LPARAM lp) { - switch(msg) { - case WM_NOTIFY: { - NMHDR* nmhdr = (NMHDR*)lp; - switch(nmhdr->code) { - case NM_CLICK: - case NM_RETURN: { - if(nmhdr->idFrom == IDC_LGPL || nmhdr->idFrom == IDC_HOMEPAGE) { - NMLINK* link = (NMLINK*)nmhdr; - LITEM item = link->item; - ::ShellExecuteW(NULL, L"open", item.szUrl, NULL, NULL, SW_SHOWNORMAL); - } - break; - } - } - break; - } - } - return Ime::Dialog::wndProc(msg, wp, lp); -} - -} // namespace Chewing diff --git a/ChewingPreferences/AboutDialog.h b/ChewingPreferences/AboutDialog.h deleted file mode 100644 index 6381ffb..0000000 --- a/ChewingPreferences/AboutDialog.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#ifndef CHEWING_ABOUT_DIALOG_H -#define CHEWING_ABOUT_DIALOG_H -#pragma once - -#include "Dialog.h" - -namespace Chewing { - -class AboutDialog : public Ime::Dialog { -public: - AboutDialog(void); - virtual ~AboutDialog(void); - -protected: - bool onInitDialog(); - LRESULT wndProc(UINT msg, WPARAM wp, LPARAM lp); -}; - -} - -#endif diff --git a/ChewingPreferences/CMakeLists.txt b/ChewingPreferences/CMakeLists.txt deleted file mode 100644 index b90bae3..0000000 --- a/ChewingPreferences/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -cmake_minimum_required(VERSION 3.24.0) -project(ChewingPreferences LANGUAGES CXX) - -# http://www.utf8everywhere.org/ -add_definitions( - /D_UNICODE=1 /DUNICODE=1 # do Unicode build - /D_CRT_SECURE_NO_WARNINGS # disable warnings about old libc functions -) -if (MSVC) - add_compile_options(/utf-8) -endif() - -# Static link MSVC runtime -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") - -add_executable(ChewingPreferences WIN32 - # Entry point - ${PROJECT_SOURCE_DIR}/ChewingPreferences.cpp - # Configurations - ../chewing_tip/ChewingConfig.cpp - ../chewing_tip/ChewingConfig.h - # Configuration dialog - ${PROJECT_SOURCE_DIR}/Dialog.cpp - ${PROJECT_SOURCE_DIR}/Dialog.h - ${PROJECT_SOURCE_DIR}/PropertyDialog.cpp - ${PROJECT_SOURCE_DIR}/PropertyDialog.h - ${PROJECT_SOURCE_DIR}/PropertyPage.cpp - ${PROJECT_SOURCE_DIR}/PropertyPage.h - ${PROJECT_SOURCE_DIR}/TypingPropertyPage.cpp - ${PROJECT_SOURCE_DIR}/TypingPropertyPage.h - ${PROJECT_SOURCE_DIR}/UiPropertyPage.cpp - ${PROJECT_SOURCE_DIR}/UiPropertyPage.h - ${PROJECT_SOURCE_DIR}/KeyboardPropertyPage.cpp - ${PROJECT_SOURCE_DIR}/KeyboardPropertyPage.h - ${PROJECT_SOURCE_DIR}/SymbolsPropertyPage.cpp - ${PROJECT_SOURCE_DIR}/SymbolsPropertyPage.h - # About dialog - ${PROJECT_SOURCE_DIR}/AboutDialog.cpp - ${PROJECT_SOURCE_DIR}/AboutDialog.h - # resources - ${PROJECT_SOURCE_DIR}/ChewingPreferences.rc - ${PROJECT_SOURCE_DIR}/ChewingPreferences.exe.manifest - ../chewing_tip/mainicon.ico - ../chewing_tip/logo.bmp -) -target_include_directories(ChewingPreferences - PRIVATE ../chewing_tip -) -target_link_libraries(ChewingPreferences - comctl32.lib -) diff --git a/ChewingPreferences/ChewingPreferences.cpp b/ChewingPreferences/ChewingPreferences.cpp deleted file mode 100644 index 56d714c..0000000 --- a/ChewingPreferences/ChewingPreferences.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#include "TypingPropertyPage.h" -#include "UiPropertyPage.h" -#include "KeyboardPropertyPage.h" -#include "SymbolsPropertyPage.h" -#include "PropertyDialog.h" -#include "AboutDialog.h" -#include "resource.h" -#include -#include - -#include -#include - -namespace Chewing { - -static void initControls() { - INITCOMMONCONTROLSEX ic; - ic.dwSize = sizeof(ic); - ic.dwICC = ICC_UPDOWN_CLASS; - ::InitCommonControlsEx(&ic); - - // Init RichEdit 2.0 - // HMODULE riched20; - // riched20 = LoadLibraryA("RICHED20.DLL"); -} - -static void configDialog(HINSTANCE hInstance) { - initControls(); - - Config config; - config.load(); - - Ime::PropertyDialog dlg; - TypingPropertyPage* typingPage = new TypingPropertyPage(&config); - UiPropertyPage* uiPage = new UiPropertyPage(&config); - KeyboardPropertyPage* keyboardPage = new KeyboardPropertyPage(&config); - SymbolsPropertyPage* symbolsPage = new SymbolsPropertyPage(&config); - dlg.addPage(typingPage); - dlg.addPage(uiPage); - dlg.addPage(keyboardPage); - dlg.addPage(symbolsPage); - INT_PTR ret = dlg.showModal(hInstance, (LPCTSTR)IDS_CONFIG_TITLE, 0, HWND_DESKTOP); - if(ret) { // the user clicks OK button - config.save(); - } -} - -static void aboutDialog(HINSTANCE hInstance) { - AboutDialog dlg; - dlg.showModal(hInstance, IDD_ABOUT); -} - -} - -int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR cmdLine, int nShow) { - if(cmdLine && wcscmp(cmdLine, L"/about") == 0) // show about - Chewing::aboutDialog(hInstance); - else // show configuration dialog - Chewing::configDialog(hInstance); - return 0; -} diff --git a/ChewingPreferences/ChewingPreferences.exe.manifest b/ChewingPreferences/ChewingPreferences.exe.manifest deleted file mode 100644 index 8ff6e2a..0000000 --- a/ChewingPreferences/ChewingPreferences.exe.manifest +++ /dev/null @@ -1,36 +0,0 @@ - - - - Chewing preference application - - - - - - - - - - - - - - - - - - - - diff --git a/ChewingPreferences/ChewingPreferences.rc b/ChewingPreferences/ChewingPreferences.rc deleted file mode 100644 index f0e0b38..0000000 --- a/ChewingPreferences/ChewingPreferences.rc +++ /dev/null @@ -1,402 +0,0 @@ -#pragma code_page(65001) // UTF-8 - -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Chinese (Traditional, Taiwan) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHT) -LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include \0" -END - -3 TEXTINCLUDE -BEGIN - "#include ""ChewingPreferences.rc2""\0" -END - -#endif // APSTUDIO_INVOKED - -#include "../version.rc" - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_ICON ICON "../chewing_tip/im.chewing.Chewing.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION VER_FILEVERSION - PRODUCTVERSION VER_PRODUCTVERSION - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x0L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040404b0" - BEGIN - VALUE "CompanyName", "Chewing" - VALUE "FileDescription", "新酷音輸入法設定" - VALUE "FileVersion", VER_FILEVERSION_STR - VALUE "InternalName", "ChewingPreferences.exe" - VALUE "LegalCopyright", "Copyright (C) 2024" - VALUE "OriginalFilename", "ChewingPreferences.exe" - VALUE "ProductName", "新酷音輸入法設定" - VALUE "ProductVersion", VER_PRODUCTVERSION_STR - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x404, 1200 - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_COOL BITMAP "../chewing_tip/logo.bmp" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_UI DIALOGEX 0, 0, 183, 119 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "介面外觀" -FONT 9, "MS Shell Dlg", 0, 0, 0x0 -BEGIN - LTEXT "每列顯示候選字個數",IDC_STATIC,6,8,73,9 - EDITTEXT IDC_CAND_PER_ROW,87,6,59,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_CAND_PER_ROW_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,115,8,10,14 - LTEXT "每頁顯示候選字個數",IDC_STATIC,6,24,73,9 - EDITTEXT IDC_CAND_PER_PAGE,87,22,59,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_CAND_PER_PAGE_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,115,26,10,14 - LTEXT "選字及訊息視窗文字大小",IDC_STATIC,6,40,78,8 - EDITTEXT IDC_FONT_SIZE,87,38,59,14,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_FONT_SIZE_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,118,45,10,14 - CONTROL "用不同顏色顯示選字鍵和候選字",IDC_COLOR_CANDIDATE,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,7,79,128,10 - CONTROL "塊狀游標",IDC_BLOCK_CURSOR,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,6,90,48,10 - CONTROL "使用底線標示詞",IDC_PHRASE_MARK,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | WS_TABSTOP,6,101,72,10 - PUSHBUTTON "選字鍵色彩",IDC_SELKEY_COLOR,116,79,61,14,NOT WS_VISIBLE | WS_DISABLED - PUSHBUTTON "候選字色彩",IDC_CAND_COLOR2,116,94,61,14,NOT WS_VISIBLE | WS_DISABLED -END - -IDD_SYMBOLS DIALOGEX 0, 0, 222, 140 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "特殊符號" -FONT 9, "MS Shell Dlg", 400, 0, 0x88 -BEGIN - LTEXT "以上是符號表的設定檔,語法相當簡單:\n每一行的內容都是: 「分類名稱」=「此分類下的所有符號」\n您也可以一行只放一個符號,則該符號會被放在最上層選單。",IDC_STATIC,6,105,210,29 - LTEXT "輸入中文時,按下 ` 鍵,會顯示下列的符號表:",IDC_STATIC,6,6,210,8 - EDITTEXT IDC_EDIT,6,19,210,82,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_VSCROLL | WS_HSCROLL -END - -IDD_KEYBOARD DIALOGEX 0, 0, 266, 90 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_BORDER -EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "~",IDC_BUTTON1,7,7,18,16 - PUSHBUTTON "1",IDC_BUTTON2,30,7,18,16 - PUSHBUTTON "2",IDC_BUTTON3,52,7,18,16 - PUSHBUTTON "3",IDC_BUTTON4,75,7,18,16 - PUSHBUTTON "4",IDC_BUTTON5,98,7,18,16 - PUSHBUTTON "5",IDC_BUTTON6,120,7,18,16 - PUSHBUTTON "6",IDC_BUTTON7,143,7,18,16 - PUSHBUTTON "7",IDC_BUTTON8,165,7,18,16 - PUSHBUTTON "8",IDC_BUTTON9,187,7,18,16 - PUSHBUTTON "。",IDC_BUTTON10,231,67,18,16 - PUSHBUTTON "0",IDC_BUTTON11,233,7,18,16 - PUSHBUTTON "Tab",IDC_BUTTON12,7,27,26,16 - PUSHBUTTON "Caps",IDC_BUTTON13,7,47,31,16 - PUSHBUTTON "Shift",IDC_BUTTON14,7,67,36,16 - PUSHBUTTON "Q",IDC_BUTTON15,38,27,18,16 - PUSHBUTTON "W",IDC_BUTTON16,60,27,18,16 - PUSHBUTTON "E",IDC_BUTTON17,83,27,18,16 - PUSHBUTTON "R",IDC_BUTTON18,106,27,18,16 - PUSHBUTTON "T",IDC_BUTTON19,128,27,18,16 - PUSHBUTTON "Y",IDC_BUTTON20,151,27,18,16 - PUSHBUTTON "U",IDC_BUTTON21,173,27,18,16 - PUSHBUTTON "I",IDC_BUTTON22,195,27,18,16 - PUSHBUTTON "O",IDC_BUTTON23,218,27,18,16 - PUSHBUTTON "P",IDC_BUTTON24,241,27,18,16 - PUSHBUTTON "A",IDC_BUTTON25,43,47,18,16 - PUSHBUTTON "S",IDC_BUTTON26,65,47,18,16 - PUSHBUTTON "D",IDC_BUTTON27,89,47,18,16 - PUSHBUTTON "F",IDC_BUTTON28,111,47,18,16 - PUSHBUTTON "G",IDC_BUTTON29,133,47,18,16 - PUSHBUTTON "H",IDC_BUTTON30,157,47,18,16 - PUSHBUTTON "J",IDC_BUTTON31,179,47,18,16 - PUSHBUTTON "K",IDC_BUTTON32,201,47,18,16 - PUSHBUTTON "L",IDC_BUTTON33,223,47,18,16 - PUSHBUTTON "Z",IDC_BUTTON35,49,67,18,16 - PUSHBUTTON "X",IDC_BUTTON36,71,67,18,16 - PUSHBUTTON "C",IDC_BUTTON37,95,67,18,16 - PUSHBUTTON "V",IDC_BUTTON38,117,67,18,16 - PUSHBUTTON "B",IDC_BUTTON39,139,67,18,16 - PUSHBUTTON "N",IDC_BUTTON40,163,67,18,16 - PUSHBUTTON "M",IDC_BUTTON41,185,67,18,16 - PUSHBUTTON ",",IDC_BUTTON42,208,67,18,16 - PUSHBUTTON "9",IDC_BUTTON43,210,7,18,16 -END - -IDD_EZ_SYMBOLS DIALOGEX 0, 0, 237, 177 -STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "簡易符號輸入" -FONT 9, "新細明體", 0, 0, 0x0 -BEGIN - CONTROL "",IDC_EZEDIT,"RichEdit20A",ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | ES_NUMBER | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,4,3,229,118 - LTEXT "這是簡易符號輸入的設定介面。這個介面裡的一行表示一個鍵所對應的字串,例如「m 新酷音」或是「L orz」等。\n每一行的格式必須符合:「Ta Tb」。其中 Ta 與 Tb 間必須有一個半形空白字元;Ta 可以是 a-z 等字母;Tb 可以是長度 1 到 10 的任意中英文字串。",IDC_STATIC,8,127,222,49,SS_NOPREFIX -END - -IDD_ABOUT DIALOGEX 0, 0, 218, 200 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION ABOUT_CAPTION_WITH_VER -FONT 9, "MS Shell Dlg", 400, 0, 0x88 -BEGIN - CONTROL IDB_COOL,IDC_STATIC,"Static",SS_BITMAP,7,7,69,74 - LTEXT "題字:翁政銓",IDC_STATIC,7,85,49,8 - PUSHBUTTON "確定 (&O)",IDOK,83,178,50,14 - LTEXT "新酷音 - 智慧型注音輸入法",IDC_STATIC,84,7,92,8 - LTEXT ABOUT_VERSION_STR,IDC_VERSION,84,20,92,8 - LTEXT ABOUT_RELEASE_DATE_STR,IDC_RELEASE_DATE,84,33,100,8 - LTEXT "授權方式:",IDC_STATIC,84,59,35,8 - LTEXT "專案首頁:",IDC_STATIC,84,72,35,8 - LTEXT "軟體開發者:libchewing 開發團隊",IDC_STATIC,84,46,104,8 - LTEXT "新酷音原是 Linux 系統下知名的輸入法,由 gugod, jserv, kanru\n\n等前輩,改良原本由龔律全與陳康本開發的酷音輸入法而來,\n\n有多種分支,目前已經能夠支援包括 Mac 在內的多種平台。\n\n這個 Windows 版本是由 PCMan, czchen 等人,\n\n使用 libchewing 核心,移植出 Windows TSF 版本",IDC_STATIC,7,99,204,75 - CONTROL "GNU LGPL",IDC_LGPL, - "SysLink",WS_TABSTOP,121,58,45,12 - CONTROL "https://chewing.im/",IDC_HOMEPAGE, - "SysLink",WS_TABSTOP,121,72,81,12 -END - -IDD_KBLAYOUT DIALOGEX 0, 0, 256, 90 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "鍵盤設定" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - GROUPBOX "鍵盤對應",IDC_STATIC,7,7,242,104 - CONTROL "預設",IDC_KB1,"Button",BS_AUTORADIOBUTTON | WS_GROUP,16,20,47,11 - CONTROL "許氏鍵盤",IDC_KB2,"Button",BS_AUTORADIOBUTTON,16,34,50,11 - CONTROL "IBM",IDC_KB3,"Button",BS_AUTORADIOBUTTON,16,48,35,11 - CONTROL "精業",IDC_KB4,"Button",BS_AUTORADIOBUTTON,16,62,35,11 - CONTROL "倚天",IDC_KB5,"Button",BS_AUTORADIOBUTTON,16,76,35,11 - CONTROL "倚天 26 鍵",IDC_KB6,"Button",BS_AUTORADIOBUTTON,16,90,56,11 - CONTROL "DVORAK",IDC_KB7,"Button",BS_AUTORADIOBUTTON,84,20,65,11 - CONTROL "DVORAK 許氏",IDC_KB8,"Button",BS_AUTORADIOBUTTON,84,34,66,9 - CONTROL "漢語拼音",IDC_KB9,"Button",BS_AUTORADIOBUTTON,84,48,65,11 - CONTROL "台灣華語羅馬拼音",IDC_KB10,"Button",BS_AUTORADIOBUTTON,84,62,80,10 - CONTROL "注音二式",IDC_KB11,"Button",BS_AUTORADIOBUTTON,84,76,48,10 - CONTROL "CARPLX",IDC_KB12,"Button",BS_AUTORADIOBUTTON,84,90,65,10 - CONTROL "Colemak-DH ANSI",IDC_KB13,"Button",BS_AUTORADIOBUTTON,160,20,67,10 - CONTROL "Colemak DH Orth",IDC_KB14,"Button",BS_AUTORADIOBUTTON,160,34,65,10 - CONTROL "Workman",IDC_KB15,"Button",BS_AUTORADIOBUTTON,160,48,65,10 -END - -IDD_TYPING DIALOGEX 0, 0, 222, 123 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "打字行為" -FONT 9, "MS Shell Dlg", 400, 0, 0x0 -BEGIN - CONTROL "使用 Shift 快速切換中英文",IDC_ENABLE_SHIFT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,6,97,10 - CONTROL "使用 CapsLock 切換中英文",IDC_ENABLE_CAPSLOCK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,20,97,10 - CONTROL "使用 Esc 清空編輯區字串",IDC_ESC_CLEAN_ALL_BUF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,34,93,10 - CONTROL "按住 Shift 輸入全形標點符號",IDC_SHIFT_FULLSHAPE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,48,103,10 - CONTROL "按住 Shift 輸入大寫英文字母",IDC_SHIFT_UPPERCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,62,103,10 - CONTROL "按住 Shift 輸入快速符號",IDC_SHIFT_SYMBOL,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,6,90,90,10 - CONTROL "Ctrl + 數字加入游標前方的詞",IDC_ADD_PHRASE_FORWARD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,76,104,10 - CONTROL "按住 Ctrl 輸入快速符號",IDC_CTRL_SYMBOL,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,6,104,86,10 - CONTROL "使用方向鍵移動游標選字",IDC_CURSOR_CANDLIST,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,116,6,91,10 - CONTROL "按空白鍵叫出選字視窗",IDC_SPACESEL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,116,20,85,10 - CONTROL "選字完畢自動跳到下一個字",IDC_ADV_AFTER_SEL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,116,34,98,10 - CONTROL "預設以全形模式啟動",IDC_DEFAULT_FS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,116,48,78,10 - CONTROL "預設以英文模式啟動",IDC_DEFAULT_ENG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,116,62,78,10 - CONTROL "預設輸出簡體中文",IDC_DEFAULT_SIMP_CHINESE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,116,76,71,10 - LTEXT "選字鍵:",IDC_STATIC,116,90,28,8 - COMBOBOX IDC_SELKEYS,148,90,62,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "模式:",IDC_STATIC,116,104,28,8 - COMBOBOX IDC_CONV_ENGINES,148,104,62,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_UI, DIALOG - BEGIN - LEFTMARGIN, 6 - RIGHTMARGIN, 177 - TOPMARGIN, 6 - BOTTOMMARGIN, 111 - END - - IDD_SYMBOLS, DIALOG - BEGIN - LEFTMARGIN, 6 - RIGHTMARGIN, 216 - TOPMARGIN, 6 - BOTTOMMARGIN, 134 - END - - IDD_KEYBOARD, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 259 - TOPMARGIN, 7 - BOTTOMMARGIN, 83 - END - - IDD_EZ_SYMBOLS, DIALOG - BEGIN - RIGHTMARGIN, 236 - BOTTOMMARGIN, 176 - END - - IDD_ABOUT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 211 - TOPMARGIN, 7 - BOTTOMMARGIN, 192 - END - - IDD_KBLAYOUT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 249 - TOPMARGIN, 7 - BOTTOMMARGIN, 83 - END - - IDD_TYPING, DIALOG - BEGIN - LEFTMARGIN, 6 - RIGHTMARGIN, 216 - TOPMARGIN, 6 - BOTTOMMARGIN, 117 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MENU MENU -BEGIN - POPUP "POPUP" - BEGIN - MENUITEM "關於新酷音輸入法(&A)", ID_ABOUT - MENUITEM "參觀新酷音官方網站(&W)", ID_WEBSITE - MENUITEM "新酷音線上討論區(&G)", ID_GROUP - MENUITEM SEPARATOR - MENUITEM "軟體本身的建議及錯誤回報(&B)", ID_BUGREPORT - MENUITEM "注音及選字選詞錯誤回報 (&P)", ID_DICT_BUGREPORT - MENUITEM SEPARATOR - POPUP "網路辭典 (&D)" - BEGIN - MENUITEM "萌典 (moedict)", ID_MOEDICT - MENUITEM SEPARATOR - MENUITEM "教育部國語辭典", ID_DICT - MENUITEM "教育部國語辭典簡編本", ID_SIMPDICT - MENUITEM "教育部國語小字典", ID_LITTLEDICT - MENUITEM "教育部成語典", ID_PROVERBDICT - END - MENUITEM SEPARATOR - MENUITEM "新酷音使用說明 (&H)", ID_CHEWING_HELP - MENUITEM "編輯使用者詞庫 (&E)", ID_HASHED, INACTIVE - MENUITEM "設定新酷音輸入法(&C)", ID_CONFIG - END - POPUP "EDIT" - BEGIN - MENUITEM "復原 (&U)", ID_EDIT_UNDO - MENUITEM SEPARATOR - MENUITEM "剪下 (&T)", ID_EDIT_CUT - MENUITEM "複製 (&C)", ID_EDIT_COPY - MENUITEM "貼上 (&P)", ID_EDIT_PASTE - MENUITEM "刪除 (&D)", ID_EDIT_DELETE - MENUITEM SEPARATOR - MENUITEM "全選 (&A)", ID_EDIT_SELALL - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_CHEWING "新酷音輸入法" - IDS_SWITCH_SHAPE "全形/半形切換" - IDS_SWITCH_LANG "中文/英文切換" - IDS_SETTINGS "設定/工具選單" - IDS_CONFIG_TITLE PREFS_TITLE_WITH_VER -END - -#endif // Chinese (Traditional, Taiwan) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// -#include "ChewingPreferences.rc2" -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/ChewingPreferences/ChewingPreferences.rc2 b/ChewingPreferences/ChewingPreferences.rc2 deleted file mode 100644 index 2a18f41..0000000 --- a/ChewingPreferences/ChewingPreferences.rc2 +++ /dev/null @@ -1 +0,0 @@ -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "ChewingPreferences.exe.manifest" diff --git a/ChewingPreferences/Dialog.cpp b/ChewingPreferences/Dialog.cpp deleted file mode 100644 index c9b4856..0000000 --- a/ChewingPreferences/Dialog.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#include "Dialog.h" - -namespace Ime { - -std::map Dialog::hwndMap_; - -Dialog::Dialog(void): hwnd_(NULL) { -} - -Dialog::~Dialog(void) { - if(hwnd_) { - DestroyWindow(hwnd_); - } -} - -bool Dialog::Create(HINSTANCE hinstance, UINT dialogId, HWND parent) { // modaless - hwnd_ = ::CreateDialogParam(hinstance, LPCTSTR(dialogId), parent, _dlgProc, (LPARAM)this); - return hwnd_ != NULL; -} - -UINT Dialog::showModal(HINSTANCE hinstance, UINT dialogId, HWND parent) { // modal - return ::DialogBoxParam(hinstance, LPCTSTR(dialogId), parent, _dlgProc, (LPARAM)this); -} - -// static -INT_PTR CALLBACK Dialog::_dlgProc(HWND hwnd , UINT msg, WPARAM wp , LPARAM lp) { - Dialog* pThis = (Dialog*)hwndMap_[hwnd]; - if(pThis) { - INT_PTR result = pThis->wndProc(msg, wp, lp); - if(msg == WM_NCDESTROY) - hwndMap_.erase(hwnd); - return result; - } - else { - if(msg == WM_INITDIALOG) { - Dialog* pThis = (Dialog*)lp; - pThis->hwnd_ = hwnd; - hwndMap_[hwnd] = pThis; - return pThis->wndProc(msg, wp, lp); - } - } - return FALSE; -} - -// virtual -LRESULT Dialog::wndProc(UINT msg, WPARAM wp , LPARAM lp) { - switch(msg) { - case WM_COMMAND: - switch(wp) { - case IDOK: - onOK(); - return TRUE; - case IDCANCEL: - onCancel(); - return TRUE; - } - break; - case WM_INITDIALOG: - return onInitDialog(); - } - return FALSE; -} - -// virtual -bool Dialog::onInitDialog() { - return true; -} - -// virtual -void Dialog::onOK() { - endDialog(IDOK); -} - -// virtual -void Dialog::onCancel() { - endDialog(IDCANCEL); -} - -} // namespace Ime - diff --git a/ChewingPreferences/Dialog.h b/ChewingPreferences/Dialog.h deleted file mode 100644 index 7527536..0000000 --- a/ChewingPreferences/Dialog.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#ifndef IME_DIALOG_H -#define IME_DIALOG_H - -#include - -#include - -namespace Ime { - -class Dialog { -public: - Dialog(void); - virtual ~Dialog(void); - - bool Create(HINSTANCE hinstance, UINT dialogId, HWND parent = HWND_DESKTOP); // modaless - UINT showModal(HINSTANCE hinstance, UINT dialogId, HWND parent = HWND_DESKTOP); // modal - - void endDialog(UINT result) { - ::EndDialog(hwnd_, result); - } - -protected: - static INT_PTR CALLBACK _dlgProc(HWND hwnd , UINT msg, WPARAM wp , LPARAM lp); - virtual LRESULT wndProc(UINT msg, WPARAM wp , LPARAM lp); - - virtual bool onInitDialog(); - virtual void onOK(); - virtual void onCancel(); - - HWND hwnd_; - static std::map hwndMap_; -private: -}; - -} - -#endif diff --git a/ChewingPreferences/KeyboardPropertyPage.cpp b/ChewingPreferences/KeyboardPropertyPage.cpp deleted file mode 100644 index 8e7f3a0..0000000 --- a/ChewingPreferences/KeyboardPropertyPage.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#include "KeyboardPropertyPage.h" -#include "resource.h" -#include - -namespace Chewing { - -KeyboardPropertyPage::KeyboardPropertyPage(Config* config): - Ime::PropertyPage((LPCTSTR)IDD_KBLAYOUT), - config_(config) { -} - -KeyboardPropertyPage::~KeyboardPropertyPage(void) { -} - - -// virtual -bool KeyboardPropertyPage::onInitDialog() { - CheckRadioButton(hwnd_, IDC_KB1, IDC_KB15, IDC_KB1 + config_->keyboardLayout); - return PropertyPage::onInitDialog(); -} - -// virtual -void KeyboardPropertyPage::onOK() { - for(UINT id = IDC_KB1; id <= IDC_KB15; ++id) { - if(IsDlgButtonChecked(hwnd_, id)) { - config_->keyboardLayout = (id - IDC_KB1); - break; - } - } - PropertyPage::onOK(); -} - - -} // namespace Chewing diff --git a/ChewingPreferences/KeyboardPropertyPage.h b/ChewingPreferences/KeyboardPropertyPage.h deleted file mode 100644 index cae2c82..0000000 --- a/ChewingPreferences/KeyboardPropertyPage.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#ifndef CHEWING_KEYBOARD_PROPERTY_PAGE_H -#define CHEWING_KEYBOARD_PROPERTY_PAGE_H -#pragma once - -#include "PropertyPage.h" -#include "ChewingConfig.h" - -namespace Chewing { - -class KeyboardPropertyPage : public Ime::PropertyPage { -public: - KeyboardPropertyPage(Config* config); - virtual ~KeyboardPropertyPage(void); - -protected: - virtual bool onInitDialog(); - virtual void onOK(); - -private: - Config* config_; -}; - -} - -#endif diff --git a/ChewingPreferences/PropertyDialog.cpp b/ChewingPreferences/PropertyDialog.cpp deleted file mode 100644 index b31364d..0000000 --- a/ChewingPreferences/PropertyDialog.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#include "PropertyDialog.h" -#include "PropertyPage.h" -#include -#include - -using namespace std; - -namespace Ime { - -//typedef INT_PTR (WINAPI *PropertySheetFunc)(LPCPROPSHEETHEADER lppsph); -//static PropertySheetFunc g_PropertySheetW = NULL; - -PropertyDialog::PropertyDialog(void) { -} - -PropertyDialog::~PropertyDialog(void) { - if(!pages_.empty()) { - for(vector::iterator it = pages_.begin(); it != pages_.end(); ++it) { - PropertyPage* page = *it; - delete page; - } - } -} - -INT_PTR PropertyDialog::showModal(HINSTANCE hInstance, LPCTSTR captionId, LPCTSTR iconId, HWND parent, DWORD flags) { - assert(pages_.size() > 0); - - // Windows 8 does not allow linking to comctl32.dll - // when running in app containers. - // We use LoadLibrary here, but this should only be used in desktop app mode. - // if(!g_PropertySheetW) { - // HMODULE mod = ::LoadLibraryW(L"comctl32.dll"); - // g_PropertySheetW = (PropertySheetFunc)::GetProcAddress(mod, "PropertySheetW"); - // } - - PROPSHEETPAGE* pages = new PROPSHEETPAGE[pages_.size()]; - for(size_t i = 0; i < pages_.size(); ++i) { - pages_[i]->setup(pages[i]); - pages[i].hInstance = hInstance; - } - - PROPSHEETHEADER psh = {0}; - psh.dwFlags = flags; - psh.dwSize = sizeof(PROPSHEETHEADER); - psh.hInstance = hInstance; - psh.hwndParent = parent; - psh.pszIcon = (LPCTSTR)iconId; - psh.nPages = pages_.size(); - psh.ppsp = pages; - psh.pszCaption = (LPCTSTR)captionId; - - // INT_PTR result = g_PropertySheetW(&psh); - INT_PTR result =::PropertySheetW(&psh); - delete []pages; - - return result; -} - -void PropertyDialog::addPage(PropertyPage* page) { - pages_.push_back(page); -} - -void PropertyDialog::removePage(PropertyPage* page) { - vector::iterator it = std::find(pages_.begin(), pages_.end(), page); - if(it != pages_.end()) - pages_.erase(it); -} - -} // namespace Ime diff --git a/ChewingPreferences/PropertyDialog.h b/ChewingPreferences/PropertyDialog.h deleted file mode 100644 index 88c8fcb..0000000 --- a/ChewingPreferences/PropertyDialog.h +++ /dev/null @@ -1,52 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#ifndef IME_PROPERTY_DIALOG_H -#define IME_PROPERTY_DIALOG_H - -#include -#include -#include -#include "PropertyPage.h" - -namespace Ime { - -class PropertyPage; - -// Create a property sheet which contains tabbed interface -// for a configuration dialog -// This class should only be used in desktop app mode. -// Otherwise, your IME might be blocked by Windows 8. (not sure?) - -class PropertyDialog { -public: - PropertyDialog(void); - virtual ~PropertyDialog(void); - - void addPage(PropertyPage* page); - void removePage(PropertyPage* page); - INT_PTR showModal(HINSTANCE hInstance, LPCTSTR captionId = 0, LPCTSTR iconId = 0, HWND parent = HWND_DESKTOP, DWORD flags = PSH_NOAPPLYNOW | PSH_USEICONID | PSH_PROPSHEETPAGE); - -private: - std::vector pages_; -}; - -} - -#endif diff --git a/ChewingPreferences/PropertyPage.cpp b/ChewingPreferences/PropertyPage.cpp deleted file mode 100644 index b15548f..0000000 --- a/ChewingPreferences/PropertyPage.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#include "PropertyPage.h" - -namespace Ime { - -PropertyPage::PropertyPage(LPCTSTR dialogId): - Dialog(), - dialogId_(dialogId) { -} - -PropertyPage::~PropertyPage(void) { -} - -void PropertyPage::setup(PROPSHEETPAGE& page) { - memset(&page, 0, sizeof(PROPSHEETPAGE)); - page.dwSize = sizeof(PROPSHEETPAGE); - page.dwFlags = PSP_DEFAULT; - - page.pszTemplate = (LPCTSTR)dialogId_; - page.pfnDlgProc = (DLGPROC)_dlgProc; - page.lParam = (LPARAM)this; -} - -// static -INT_PTR CALLBACK PropertyPage::_dlgProc(HWND hwnd , UINT msg, WPARAM wp , LPARAM lp) { - if(msg == WM_INITDIALOG) { - PROPSHEETPAGE* page = (PROPSHEETPAGE*)lp; - PropertyPage* pThis = (PropertyPage*)page->lParam; - pThis->hwnd_ = hwnd; - hwndMap_[hwnd] = pThis; - pThis->wndProc(msg, wp, lp); - return TRUE; - } - return Dialog::_dlgProc(hwnd, msg, wp, lp); -} - -// virtual -LRESULT PropertyPage::wndProc(UINT msg, WPARAM wp, LPARAM lp) { - switch(msg) { - case WM_NOTIFY: - switch(LPNMHDR(lp)->code) { - case PSN_APPLY: - onOK(); - return TRUE; - case PSN_QUERYCANCEL: - onCancel(); - return TRUE; - } - } - return Dialog::wndProc(msg, wp, lp); -} - -// virtual -void PropertyPage::onOK() { - ::SetWindowLongPtr(hwnd_, DWLP_MSGRESULT, PSNRET_NOERROR); -} - -// virtual -void PropertyPage::onCancel() { - ::SetWindowLongPtr(hwnd_, DWLP_MSGRESULT, PSNRET_NOERROR); -} - -} // namespace Ime diff --git a/ChewingPreferences/PropertyPage.h b/ChewingPreferences/PropertyPage.h deleted file mode 100644 index 258d1d4..0000000 --- a/ChewingPreferences/PropertyPage.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#ifndef IME_PROPERTY_PAGE_H -#define IME_PROPERTY_PAGE_H - -#include "Dialog.h" -#include - -namespace Ime { - -class PropertyPage: public Dialog { -public: - friend class PropertyDialog; - - PropertyPage(LPCTSTR dialogId); - virtual ~PropertyPage(void); - -protected: - void setup(PROPSHEETPAGE& page); - static INT_PTR CALLBACK _dlgProc(HWND hwnd , UINT msg, WPARAM wp , LPARAM lp); - virtual LRESULT wndProc(UINT msg, WPARAM wp, LPARAM lp); - virtual void onOK(); - virtual void onCancel(); - -private: - LPCTSTR dialogId_; -}; - -} - -#endif diff --git a/ChewingPreferences/SymbolsPropertyPage.cpp b/ChewingPreferences/SymbolsPropertyPage.cpp deleted file mode 100644 index 8c4e76f..0000000 --- a/ChewingPreferences/SymbolsPropertyPage.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#include "SymbolsPropertyPage.h" -#include "resource.h" -#include - -namespace Chewing { - -SymbolsPropertyPage::SymbolsPropertyPage(Config* config): - Ime::PropertyPage((LPCTSTR)IDD_SYMBOLS), - config_(config) { - - wchar_t path[MAX_PATH]; - // get user profile directory - if(::GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH)) { - userDir_ = path; - userDir_ += L"\\ChewingTextService"; - } -} - -SymbolsPropertyPage::~SymbolsPropertyPage(void) { -} - -// virtual -bool SymbolsPropertyPage::onInitDialog() { - wchar_t basename[] = L"\\symbols.dat"; - std::wstring filename = userDir_ + basename; - - HANDLE file = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if(file == INVALID_HANDLE_VALUE) { - // user specific symbols file does not exists, try the built-in one in Program files - // try C:\program files (x86) first - wchar_t path[MAX_PATH]; - HRESULT result = ::SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path); - if(result != S_OK) // failed, fall back to C:\program files - result = ::SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILES, NULL, 0, path); - if(result == S_OK) { // program files folder is found - filename = path; - filename += L"\\ChewingTextService\\Dictionary"; - filename += basename; - } - file = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - } - if(file != INVALID_HANDLE_VALUE) { - DWORD size = GetFileSize(file, NULL); - char* buf = new char[size]; - DWORD rsize; - ReadFile(file, buf, size, &rsize, NULL); - CloseHandle(file); - std::wstring wstr; - int wlen = ::MultiByteToWideChar(CP_UTF8, 0, buf, size, NULL, 0); - if (wlen > 0) { - wstr.resize(wlen); - ::MultiByteToWideChar(CP_UTF8, 0, buf, size, &wstr[0], wlen); - ::SetDlgItemTextW(hwnd_, IDC_EDIT, wstr.c_str()); - } else { - ::SetDlgItemTextW(hwnd_, IDC_EDIT, L"無法讀取檔案"); - } - delete []buf; - } - return PropertyPage::onInitDialog(); -} - -// virtual -void SymbolsPropertyPage::onOK() { - // create the user directory if not exists - // NOTE: this call will fail in Windows 8 store apps - // We need a way to create the dir in desktop mode and - // set proper ACL, so later we can access it inside apps. - DWORD attributes = ::GetFileAttributesW(userDir_.c_str()); - if(attributes == INVALID_FILE_ATTRIBUTES) { - // create the directory if it does not exist - if(::GetLastError() == ERROR_FILE_NOT_FOUND) { - ::CreateDirectoryW(userDir_.c_str(), NULL); - attributes = ::GetFileAttributesW(userDir_.c_str()); - } - // make the directory hidden - if(attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_HIDDEN) == 0) - ::SetFileAttributesW(userDir_.c_str(), attributes|FILE_ATTRIBUTE_HIDDEN); - } - - // save current settings - std::wstring filename = userDir_; - filename += L"\\symbols.dat"; - HANDLE file = CreateFile(filename.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL ); - if( file != INVALID_HANDLE_VALUE ) { - HWND edit = ::GetDlgItem(hwnd_, IDC_EDIT); - int len = ::GetWindowTextLengthW(edit); - wchar_t* buf = new wchar_t[len]; - len = ::GetWindowText(edit, buf, len); - std::string ustr; - int ulen = ::WideCharToMultiByte(CP_UTF8, 0, &buf[0], len, NULL, 0, NULL, NULL); - if (ulen > 0) { - ustr.resize(ulen); - ::WideCharToMultiByte(CP_UTF8, 0, &buf[0], len, &ustr[0], ulen, NULL, NULL); - DWORD wsize; - ::WriteFile( file, ustr.c_str(), ustr.length(), &wsize, NULL ); - ::CloseHandle(file); - } - delete []buf; - } - - PropertyPage::onOK(); -} - - -} // namespace Chewing diff --git a/ChewingPreferences/SymbolsPropertyPage.h b/ChewingPreferences/SymbolsPropertyPage.h deleted file mode 100644 index 5bbb141..0000000 --- a/ChewingPreferences/SymbolsPropertyPage.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#ifndef CHEWING_SYMBOLS_PROPERTY_PAGE -#define CHEWING_SYMBOLS_PROPERTY_PAGE -#pragma once - -#include "PropertyPage.h" -#include "ChewingConfig.h" -#include - -namespace Chewing { - -class SymbolsPropertyPage : public Ime::PropertyPage { -public: - SymbolsPropertyPage(Config* config); - virtual ~SymbolsPropertyPage(void); - -protected: - virtual bool onInitDialog(); - virtual void onOK(); - -private: - Config* config_; - std::wstring userDir_; -}; - -} // namespace Chewing - -#endif - diff --git a/ChewingPreferences/TypingPropertyPage.cpp b/ChewingPreferences/TypingPropertyPage.cpp deleted file mode 100644 index 528d6a1..0000000 --- a/ChewingPreferences/TypingPropertyPage.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#include "TypingPropertyPage.h" -#include "resource.h" -#include - -namespace Chewing { - -TypingPropertyPage::TypingPropertyPage(Config* config): - Ime::PropertyPage((LPCTSTR)IDD_TYPING), - config_(config) { -} - -TypingPropertyPage::~TypingPropertyPage(void) { -} - -// virtual -bool TypingPropertyPage::onInitDialog() { - - CheckDlgButton(hwnd_, IDC_SPACESEL, config_->showCandWithSpaceKey); - CheckDlgButton(hwnd_, IDC_ENABLE_SHIFT, config_->switchLangWithShift); - CheckDlgButton(hwnd_, IDC_ADD_PHRASE_FORWARD, config_->addPhraseForward); - CheckDlgButton(hwnd_, IDC_ADV_AFTER_SEL, config_->advanceAfterSelection); - CheckDlgButton(hwnd_, IDC_CURSOR_CANDLIST, config_->cursorCandList); - CheckDlgButton(hwnd_, IDC_ENABLE_CAPSLOCK, config_->enableCapsLock); - CheckDlgButton(hwnd_, IDC_SHIFT_FULLSHAPE, config_->fullShapeSymbols); - CheckDlgButton(hwnd_, IDC_ESC_CLEAN_ALL_BUF, config_->escCleanAllBuf); - CheckDlgButton(hwnd_, IDC_SHIFT_SYMBOL, config_->easySymbolsWithShift); - CheckDlgButton(hwnd_, IDC_CTRL_SYMBOL, config_->easySymbolsWithCtrl); - CheckDlgButton(hwnd_, IDC_SHIFT_UPPERCASE, config_->upperCaseWithShift); - CheckDlgButton(hwnd_, IDC_ENABLE_Simp, config_->outputSimpChinese); - CheckDlgButton(hwnd_, IDC_DEFAULT_ENG, config_->defaultEnglish); - CheckDlgButton(hwnd_, IDC_DEFAULT_FS, config_->defaultFullSpace); - - HWND combo = GetDlgItem(hwnd_, IDC_SELKEYS); - for(const wchar_t** pselkeys = config_->selKeys; *pselkeys; ++pselkeys) - ComboBox_AddString(combo, *pselkeys); - ComboBox_SetCurSel(combo, config_->selKeyType); - - combo = GetDlgItem(hwnd_, IDC_CONV_ENGINES); - for(const wchar_t** pconvEngine = config_->convEngines; *pconvEngine; ++pconvEngine) - ComboBox_AddString(combo, *pconvEngine); - ComboBox_SetCurSel(combo, config_->convEngine); - - return PropertyPage::onInitDialog(); -} - -// virtual -void TypingPropertyPage::onOK() { - - - config_->selKeyType = ComboBox_GetCurSel(GetDlgItem(hwnd_, IDC_SELKEYS)); - if(config_->selKeyType < 0) - config_->selKeyType = 0; - - config_->convEngine = ComboBox_GetCurSel(GetDlgItem(hwnd_, IDC_CONV_ENGINES)); - if(config_->convEngine < 0) - config_->convEngine = 0; - - config_->showCandWithSpaceKey = IsDlgButtonChecked(hwnd_, IDC_SPACESEL); - config_->switchLangWithShift = IsDlgButtonChecked(hwnd_, IDC_ENABLE_SHIFT); - config_->addPhraseForward = IsDlgButtonChecked(hwnd_, IDC_ADD_PHRASE_FORWARD); - config_->advanceAfterSelection = IsDlgButtonChecked(hwnd_, IDC_ADV_AFTER_SEL); - config_->cursorCandList = IsDlgButtonChecked(hwnd_, IDC_CURSOR_CANDLIST); - config_->enableCapsLock = IsDlgButtonChecked(hwnd_, IDC_ENABLE_CAPSLOCK); - config_->fullShapeSymbols = IsDlgButtonChecked(hwnd_, IDC_SHIFT_FULLSHAPE); - config_->escCleanAllBuf = IsDlgButtonChecked(hwnd_, IDC_ESC_CLEAN_ALL_BUF); - config_->easySymbolsWithShift = IsDlgButtonChecked(hwnd_, IDC_SHIFT_SYMBOL); - config_->easySymbolsWithCtrl = IsDlgButtonChecked(hwnd_, IDC_CTRL_SYMBOL); - config_->upperCaseWithShift = IsDlgButtonChecked(hwnd_, IDC_SHIFT_UPPERCASE); - config_->outputSimpChinese = IsDlgButtonChecked(hwnd_, IDC_ENABLE_Simp); - config_->defaultEnglish = IsDlgButtonChecked(hwnd_, IDC_DEFAULT_ENG); - config_->defaultFullSpace = IsDlgButtonChecked(hwnd_, IDC_DEFAULT_FS); - PropertyPage::onOK(); -} - -} // namespace Chewing diff --git a/ChewingPreferences/TypingPropertyPage.h b/ChewingPreferences/TypingPropertyPage.h deleted file mode 100644 index 18ebd02..0000000 --- a/ChewingPreferences/TypingPropertyPage.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#ifndef CHEWING_TYPING_PROPERTY_PAGE_H -#define CHEWING_TYPING_PROPERTY_PAGE_H - -#include "PropertyPage.h" -#include "ChewingConfig.h" - -namespace Chewing { - -class TypingPropertyPage : public Ime::PropertyPage { -public: - TypingPropertyPage(Config* config); - virtual ~TypingPropertyPage(void); - -protected: - virtual bool onInitDialog(); - virtual void onOK(); - -private: - Config* config_; -}; - -} - -#endif diff --git a/ChewingPreferences/UiPropertyPage.cpp b/ChewingPreferences/UiPropertyPage.cpp deleted file mode 100644 index 85aa479..0000000 --- a/ChewingPreferences/UiPropertyPage.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#include "UiPropertyPage.h" -#include "resource.h" -#include -#include - -namespace Chewing { - -UiPropertyPage::UiPropertyPage(Config* config): - Ime::PropertyPage((LPCTSTR)IDD_UI), - config_(config) { -} - -UiPropertyPage::~UiPropertyPage(void) { -} - -// virtual -bool UiPropertyPage::onInitDialog() { - HWND spin = GetDlgItem(hwnd_, IDC_FONT_SIZE_SPIN); - ::SendMessage(spin, UDM_SETRANGE32, 4, 64); - ::SendMessage(spin, UDM_SETPOS, 0, - (LPARAM) MAKELONG ((short) config_->fontSize , 0)); - - CheckDlgButton(hwnd_, IDC_PHRASE_MARK, config_->phraseMark); - // CheckDlgButton(hwnd_, IDC_BLOCK_CURSOR, config_->ColoredCompCursor); - CheckDlgButton(hwnd_, IDC_COLOR_CANDIDATE, config_->colorCandWnd); - - spin = GetDlgItem(hwnd_, IDC_CAND_PER_ROW_SPIN); - ::SendMessage(spin, UDM_SETRANGE32, 1, 10); - ::SendMessage(spin, UDM_SETPOS, 0, - (LPARAM) MAKELONG ((short) config_->candPerRow , 0)); - - spin = GetDlgItem(hwnd_, IDC_CAND_PER_PAGE_SPIN); - ::SendMessage(spin, UDM_SETRANGE32, 7, 10); - ::SendMessage(spin, UDM_SETPOS, 0, - (LPARAM) MAKELONG ((short) config_->candPerPage , 0)); - return PropertyPage::onInitDialog(); -} - -// virtual -void UiPropertyPage::onOK() { - HWND spin = GetDlgItem(hwnd_, IDC_FONT_SIZE_SPIN); - int tFontSize = (int)::SendMessage(spin, UDM_GETPOS, 0, 0); - if(tFontSize < 4) tFontSize = 4; - if(tFontSize > 64) tFontSize = 64; - config_->fontSize = tFontSize; - - config_->phraseMark = IsDlgButtonChecked(hwnd_, IDC_PHRASE_MARK); - // config_->coloredCompCursor = IsDlgButtonChecked(hwnd_, IDC_BLOCK_CURSOR); - config_->colorCandWnd = IsDlgButtonChecked(hwnd_, IDC_COLOR_CANDIDATE); - - spin = GetDlgItem(hwnd_, IDC_CAND_PER_ROW_SPIN); - config_->candPerRow = (DWORD)::SendMessage(spin, UDM_GETPOS, 0, 0); - if(config_->candPerRow < 1) config_->candPerRow = 1; - if(config_->candPerRow > 10) config_->candPerRow = 10; - - spin = GetDlgItem(hwnd_, IDC_CAND_PER_PAGE_SPIN); - config_->candPerPage = (int)::SendMessage(spin, UDM_GETPOS, 0, 0); - PropertyPage::onOK(); -} - -} // namespace Chewing diff --git a/ChewingPreferences/UiPropertyPage.h b/ChewingPreferences/UiPropertyPage.h deleted file mode 100644 index dff3423..0000000 --- a/ChewingPreferences/UiPropertyPage.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (C) 2013 Hong Jen Yee (PCMan) -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, -// Boston, MA 02110-1301, USA. -// - -#ifndef CHEWING_UI_PROPERTY_PAGE_H -#define CHEWING_UI_PROPERTY_PAGE_H -#pragma once - -#include "PropertyPage.h" -#include "ChewingConfig.h" - -namespace Chewing { - -class UiPropertyPage : public Ime::PropertyPage { -public: - UiPropertyPage(Config* config); - virtual ~UiPropertyPage(void); - -protected: - virtual bool onInitDialog(); - virtual void onOK(); - -private: - Config* config_; -}; - -} - -#endif diff --git a/ChewingPreferences/resource.h b/ChewingPreferences/resource.h deleted file mode 100644 index d1382d9..0000000 --- a/ChewingPreferences/resource.h +++ /dev/null @@ -1,169 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by ChewingPreferences.rc -// -#define IDI_ICON 101 -#define ID_SWITCH_LANG 101 -#define IDI_ICON2 102 -#define IDS_CHEWING 102 -#define ID_SWITCH_SHAPE 102 -#define IDS_SWITCH_SHAPE 103 -#define IDI_CHI 103 -#define ID_MODE_ICON 103 -#define IDS_SWITCH_LANG 104 -#define IDI_CONFIG 104 -#define IDI_ENG 105 -#define IDS_SETTINGS 105 -#define IDI_FULL_SHAPE 106 -#define IDS_CONFIG_TITLE 106 -#define IDI_HALF_SHAPE 107 -#define IDR_MENU1 108 -#define IDR_MENU2 109 -#define IDR_MENU 109 -#define IDD_KBLAYOUT 110 -#define IDD_ABOUT 121 -#define IDB_COOL 122 -#define IDD_UI 124 -#define IDD_SYMBOLS 127 -#define IDD_KEYBOARD 135 -#define IDD_EZ_SYMBOLS 136 -#define IDD_TYPING 137 -#define IDD_TYPING1 137 -#define IDC_BUTTON1 1009 -#define IDC_CAND_PER_ROW 1010 -#define IDC_BUTTON2 1010 -#define IDC_CAND_PER_ROW_SPIN 1011 -#define IDC_BUTTON3 1011 -#define IDC_CAND_PER_PAGE 1012 -#define IDC_BUTTON4 1012 -#define IDC_BUTTON5 1013 -#define IDC_DEFAULT_ENG 1013 -#define IDC_SELKEYS 1014 -#define IDC_BUTTON6 1014 -#define IDC_SHIFT_CAPITAL 1015 -#define IDC_BUTTON7 1015 -#define IDC_RADIO5 1015 -#define IDC_CONV_ENGINES 1015 -#define IDC_CAND_COLOR2 1016 -#define IDC_SPACESEL 1016 -#define IDC_BUTTON8 1016 -#define IDC_FIX_COMPWND 1017 -#define IDC_BUTTON9 1017 -#define IDC_RADIO6 1017 -#define IDC_CHECK1 1017 -#define IDC_ADD_PHRASE_FORWARD 1018 -#define IDC_BUTTON10 1018 -#define IDC_HIDE_STATUSWND 1019 -#define IDC_BUTTON11 1019 -#define IDC_RADIO7 1019 -#define IDC_LGPL 1019 -#define IDC_DEFAULT_FS 1020 -#define IDC_BUTTON12 1020 -#define IDC_RADIO8 1020 -#define IDC_HOMEPAGE 1020 -#define IDC_ENABLE_SHIFT 1021 -#define IDC_BUTTON13 1021 -#define IDC_VERSION 1021 -#define IDC_CAND_PER_PAGE_SPIN 1022 -#define IDC_BUTTON14 1022 -#define IDC_DEFAULT_FS2 1022 -#define IDC_RELEASE_DATE 1022 -#define IDC_COLOR_CANDIDATE 1023 -#define IDC_BUTTON15 1023 -#define IDC_BLOCK_CURSOR 1024 -#define IDC_BUTTON16 1024 -#define IDC_SHIFT_SYMBOL 1024 -#define IDC_ADV_AFTER_SEL 1025 -#define IDC_BUTTON17 1025 -#define IDC_FONT_SIZE 1026 -#define IDC_BUTTON18 1026 -#define IDC_RADIO2 1026 -#define IDC_CTRL_SYMBOL 1027 -#define IDC_BUTTON19 1027 -#define IDC_EDIT1 1027 -#define IDC_FONT_SIZE_SPIN 1028 -#define IDC_ENABLE_Simp 1028 -#define IDC_BUTTON20 1028 -#define IDC_DEFAULT_SIMP_CHINESE 1028 -#define IDC_BUTTON21 1029 -#define IDC_CURSOR_CANDLIST 1029 -#define IDC_ENABLE_CAPSLOCK 1030 -#define IDC_BUTTON22 1030 -#define IDC_BUTTON23 1031 -#define IDC_SHIFT_FULLSHAPE 1031 -#define IDC_PHRASE_MARK 1032 -#define IDC_BUTTON24 1032 -#define IDC_SHIFT_FULLSHAPE2 1032 -#define IDC_SHIFT_UPPERCASE 1032 -#define IDC_ESC_CLEAN_ALL_BUF 1033 -#define IDC_EDIT 1037 -#define IDC_EZEDIT 1038 -#define IDC_BUTTON25 1053 -#define IDC_BUTTON26 1054 -#define IDC_BUTTON27 1055 -#define IDC_BUTTON28 1056 -#define IDC_BUTTON29 1057 -#define IDC_BUTTON30 1058 -#define IDC_BUTTON31 1059 -#define IDC_BUTTON32 1060 -#define IDC_BUTTON33 1061 -#define IDC_BUTTON35 1063 -#define IDC_BUTTON36 1064 -#define IDC_BUTTON37 1065 -#define IDC_BUTTON38 1066 -#define IDC_BUTTON39 1067 -#define IDC_BUTTON40 1068 -#define IDC_BUTTON41 1069 -#define IDC_BUTTON42 1073 -#define IDC_BUTTON43 1074 -#define IDC_KB1 1075 -#define IDC_KB2 1076 -#define IDC_KB3 1077 -#define IDC_KB4 1078 -#define IDC_KB5 1079 -#define IDC_KB6 1080 -#define IDC_KB7 1081 -#define IDC_KB8 1082 -#define IDC_SELKEY_COLOR 1083 -#define IDC_KB9 1084 -#define IDC_KB10 1085 -#define IDC_KB11 1086 -#define IDC_KB12 1087 -#define IDC_KB13 1088 -#define IDC_KB14 1089 -#define IDC_KB15 1090 -#define ID_SETTINGS_ 40003 -#define ID_ABOUT 40005 -#define ID_CHECK_NEW_VER 40006 -#define ID_WEBSITE 40007 -#define ID_GROUP 40008 -#define ID_BUGREPORT 40009 -#define ID_DICT_BUGREPORT 40010 -#define ID_DICT 40011 -#define ID_SIMPDICT 40012 -#define ID_LITTLEDICT 40013 -#define ID_PROVERBDICT 40014 -#define ID_CHEWING_HELP 40015 -#define ID_HASHED 40016 -#define ID_CONFIG 40017 -#define ID_EDIT_UNDO 40018 -#define ID_EDIT_CUT 40019 -#define ID_EDIT_COPY 40020 -#define ID_EDIT_PASTE 40021 -#define ID_EDIT_DELETE 40022 -#define ID_EDIT_SELALL 40023 -#define ID_40024 40024 -#define ID_MOEDICT 40025 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 111 -#define _APS_NEXT_COMMAND_VALUE 40026 -#define _APS_NEXT_CONTROL_VALUE 1028 -#define _APS_NEXT_SYMED_VALUE 104 -#endif -#endif diff --git a/chewing_tip/ChewingTextService.cpp b/chewing_tip/ChewingTextService.cpp index 9be4cc1..30b350b 100644 --- a/chewing_tip/ChewingTextService.cpp +++ b/chewing_tip/ChewingTextService.cpp @@ -628,6 +628,13 @@ STDMETHODIMP TextService::onCommand(UINT id, CommandType type) { case ID_MODE_ICON: // Windows 8 IME mode icon toggleLanguageMode(nullptr); break; + case ID_HASHED: // show config dialog + if(!isImmersive()) { // only do this in desktop app mode + std::wstring path = programDir(); + path += L"\\ChewingPreferences.exe"; + ::ShellExecuteW(HWND_DESKTOP, L"open", path.c_str(), L"--edit", NULL, SW_SHOWNORMAL); + } + break; case ID_CONFIG: // show config dialog if(!isImmersive()) { // only do this in desktop app mode std::wstring path = programDir(); @@ -643,7 +650,7 @@ STDMETHODIMP TextService::onCommand(UINT id, CommandType type) { // show about dialog std::wstring path = programDir(); path += L"\\ChewingPreferences.exe"; - ::ShellExecuteW(NULL, L"open", path.c_str(), L"/about", NULL, SW_SHOWNORMAL); + ::ShellExecuteW(NULL, L"open", path.c_str(), L"--about", NULL, SW_SHOWNORMAL); } break; case ID_WEBSITE: // visit chewing website diff --git a/chewing_tip/ChewingTextService.rc b/chewing_tip/ChewingTextService.rc index 5538579..2b51d4a 100644 --- a/chewing_tip/ChewingTextService.rc +++ b/chewing_tip/ChewingTextService.rc @@ -118,7 +118,7 @@ BEGIN MENUITEM "注音及選字選詞錯誤回報 (&P)", ID_DICT_BUGREPORT MENUITEM SEPARATOR MENUITEM "新酷音使用說明 (&H)", ID_CHEWING_HELP, INACTIVE - MENUITEM "編輯使用者詞庫 (&E)", ID_HASHED, INACTIVE + MENUITEM "編輯使用者詞庫 (&E)", ID_HASHED MENUITEM "設定新酷音輸入法(&C)", ID_CONFIG MENUITEM SEPARATOR POPUP "網路辭典 (&D)" diff --git a/preferences/Cargo.toml b/preferences/Cargo.toml index b46d760..70f67dd 100644 --- a/preferences/Cargo.toml +++ b/preferences/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chewing-preferences" -version = "0.1.0" +version = "24.10.1" edition = "2021" [[bin]] diff --git a/preferences/src/about.rs b/preferences/src/about.rs new file mode 100644 index 0000000..90ef212 --- /dev/null +++ b/preferences/src/about.rs @@ -0,0 +1,15 @@ +use anyhow::Result; +use slint::ComponentHandle; + +use crate::AboutWindow; + +pub fn run() -> Result<()> { + let ui = AboutWindow::new()?; + + ui.on_done(move || { + slint::quit_event_loop().unwrap(); + }); + + ui.run()?; + Ok(()) +} diff --git a/preferences/src/main.rs b/preferences/src/main.rs index 0fbe54e..75d62d1 100644 --- a/preferences/src/main.rs +++ b/preferences/src/main.rs @@ -2,6 +2,7 @@ mod config; mod editor; +mod about; use std::env; @@ -10,6 +11,8 @@ slint::include_modules!(); fn main() -> anyhow::Result<()> { if env::args().any(|arg| arg == "/edit" || arg == "--edit") { editor::run()?; + } else if env::args().any(|arg| arg == "/about" || arg == "--about") { + about::run()?; } else { config::run()?; } diff --git a/preferences/ui/about-box.slint b/preferences/ui/about-box.slint new file mode 100644 index 0000000..079f6ad --- /dev/null +++ b/preferences/ui/about-box.slint @@ -0,0 +1,51 @@ +import { VerticalBox } from "std-widgets.slint"; +import { Version } from "globals.slint"; + +export component AboutChewing inherits VerticalLayout { + HorizontalLayout { + spacing: 10px; + + Image { + source: @image-url("logo.png"); + } + + VerticalLayout { + Text { + text: "新酷音 - 智慧型注音輸入法"; + } + + Text { + text: "版本:" + Version.product-version; + } + + Text { + text: "發行日期:" + Version.build-date; + } + + Text { + text: "軟體開發者:libchewing 開發團隊"; + } + + Text { + text: "授權方式:GPL-3.0-or-later"; + } + + Text { + text: "專案首頁:https://chewing.im"; + } + } + } + + Text { + text: "題字:翁政銓"; + } + + Rectangle { + height: 16px; + } + + Text { + text: "新酷音原是 Linux 系統下知名的輸入法,由 gugod, jserv, kanru 等前輩,改良原本由龔律全與陳康本開發的酷音輸入法而來,有多種分支,目前已經能夠支援包括 Mac 在內的多種平台。這個 Windows 版本是由 PCMan, czchen 等人,使用 libchewing 核心,移植出 Windows TSF 版本。"; + wrap: word-wrap; + } +} diff --git a/preferences/ui/about-window.slint b/preferences/ui/about-window.slint new file mode 100644 index 0000000..4131783 --- /dev/null +++ b/preferences/ui/about-window.slint @@ -0,0 +1,29 @@ +import { Button, VerticalBox, HorizontalBox } from "std-widgets.slint"; +import { AboutChewing } from "about-box.slint"; +import { Assets, Version } from "globals.slint"; + +export component AboutWindow inherits Window { + title: "關於新酷音輸入法 (" + Version.product-version + ")"; + icon: Assets.icon; + preferred-width: 350px; + preferred-height: 300px; + max-width: 350px; + max-height: 300px; + + callback done(); + + VerticalBox { + alignment: start; + AboutChewing { } + + HorizontalBox { + alignment: end; + Button { + text: "確定"; + clicked => { + done(); + } + } + } + } +} diff --git a/preferences/ui/config-window.slint b/preferences/ui/config-window.slint index 1d772ce..6de44a5 100644 --- a/preferences/ui/config-window.slint +++ b/preferences/ui/config-window.slint @@ -1,4 +1,5 @@ import { Button, VerticalBox, TabWidget, CheckBox, ComboBox, HorizontalBox, SpinBox, AboutSlint, TextEdit, StandardButton } from "std-widgets.slint"; +import { AboutChewing } from "about-box.slint"; import { Assets, Version } from "globals.slint"; export component ConfigWindow inherits Window { @@ -307,46 +308,9 @@ export component ConfigWindow inherits Window { Tab { title: "關於"; VerticalBox { - HorizontalLayout { - Image { - source: @image-url("logo.png"); - } - - VerticalLayout { - Text { - text: "新酷音 - 智慧型注音輸入法"; - } - - Text { - text: "版本:" + Version.product-version; - } - - Text { - text: "發行日期:" + Version.build-date; - } - - Text { - text: "軟體開發者:libchewing 開發團隊"; - } - - Text { - text: "授權方式:GPL-3.0-or-later"; - } - - Text { - text: "專案首頁:https://chewing.im"; - } - } - } - - Text { - text: "題字:翁政銓"; - } + alignment: start; - Text { - text: "新酷音原是 Linux 系統下知名的輸入法,由 gugod, jserv, kanru 等前輩,改良原本由龔律全與陳康本開發的酷音輸入法而來,有多種分支,目前已經能夠支援包括 Mac 在內的多種平台。這個 Windows 版本是由 PCMan, czchen 等人,使用 libchewing 核心,移植出 Windows TSF 版本。"; - wrap: word-wrap; - } + AboutChewing { } Text { text: "此設定程式使用開源專案 Slint 開發:"; diff --git a/preferences/ui/index.slint b/preferences/ui/index.slint index fb05059..598a7c7 100644 --- a/preferences/ui/index.slint +++ b/preferences/ui/index.slint @@ -1,4 +1,5 @@ import { ConfigWindow } from "./config-window.slint"; import { EditorWindow, CallbackResult, ErrorKind } from "./editor-window.slint"; +import { AboutWindow} from "./about-window.slint"; -export { ConfigWindow, EditorWindow, CallbackResult, ErrorKind } +export { ConfigWindow, EditorWindow, CallbackResult, ErrorKind, AboutWindow } diff --git a/scripts/build_installer.bat b/scripts/build_installer.bat index eb13ccd..2df229c 100644 --- a/scripts/build_installer.bat +++ b/scripts/build_installer.bat @@ -3,10 +3,10 @@ set SQLITE3_STATIC=1 cmake -B build\x86 -A Win32 -DBUILD_TESTING=OFF -DVCPKG_TARGET_TRIPLET=x86-windows-static cmake --build build\x86 -t libchewing\data\data --config Release -cmake --build build\x86 -t ChewingPreferences --config Release cargo build -p chewing_tip --release --target x86_64-pc-windows-msvc cargo build -p chewing_tip --release --target i686-pc-windows-msvc +cargo build -p chewing-preferences --release --target i686-pc-windows-msvc cargo build -p tsfreg --release --target i686-pc-windows-msvc mkdir dist @@ -20,7 +20,7 @@ copy libchewing\data\*.dat build\installer\Dictionary\ copy build\x86\libchewing\data\*.dat build\installer\Dictionary\ mkdir build\installer\x86 copy target\i686-pc-windows-msvc\release\chewing_tip.dll build\installer\x86\ -copy build\x86\ChewingPreferences\Release\*.exe build\installer\ +copy target\i686-pc-windows-msvc\release\ChewingPreferences.exe build\installer\ copy build\x86\libchewing\chewing-cli.exe build\installer\ mkdir build\installer\x64 copy target\x86_64-pc-windows-msvc\release\chewing_tip.dll build\installer\x64 From 198572e3a22f317d965fcaa79902c785ac0acb76 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Mon, 30 Dec 2024 15:25:51 +0900 Subject: [PATCH 11/12] style(prefs): remove default font setting --- preferences/ui/config-window.slint | 2 -- 1 file changed, 2 deletions(-) diff --git a/preferences/ui/config-window.slint b/preferences/ui/config-window.slint index 6de44a5..46da04e 100644 --- a/preferences/ui/config-window.slint +++ b/preferences/ui/config-window.slint @@ -3,8 +3,6 @@ import { AboutChewing } from "about-box.slint"; import { Assets, Version } from "globals.slint"; export component ConfigWindow inherits Window { - default-font-family: "jf open 粉圓 2.0"; - default-font-weight: 500; title: "設定新酷音輸入法 (" + Version.product-version + ")"; icon: Assets.icon; preferred-width: 500px; From b8715fa51d19026e968a8a1878727ee717d2abd8 Mon Sep 17 00:00:00 2001 From: Kan-Ru Chen Date: Mon, 30 Dec 2024 15:26:06 +0900 Subject: [PATCH 12/12] build: use rust-lld by default --- .cargo/config.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.cargo/config.toml b/.cargo/config.toml index 58fdfbb..92174d9 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -3,6 +3,8 @@ xtask = "run --package xtask --" [target.i686-pc-windows-msvc] rustflags = ["-C", "target-feature=+crt-static"] +linker = "rust-lld" [target.x86_64-pc-windows-msvc] rustflags = ["-C", "target-feature=+crt-static"] +linker = "rust-lld"