diff --git a/.vscode/settings.json b/.vscode/settings.json
index f2468ad8..4ac13f83 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -22,7 +22,8 @@
"image cache",
"tilemap",
"config",
- "audio"
+ "audio",
+ "i18"
],
"rust-analyzer.showUnlinkedFileNotification": false,
"rust-analyzer.cargo.extraEnv": {
diff --git a/Cargo.lock b/Cargo.lock
index 5463b600..55c2b8c7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -185,9 +185,9 @@ dependencies = [
[[package]]
name = "aho-corasick"
-version = "1.0.4"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a"
+checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab"
dependencies = [
"memchr",
]
@@ -275,22 +275,27 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "arboard"
-version = "3.2.0"
+version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6041616acea41d67c4a984709ddab1587fd0b10efe5cc563fee954d2f011854"
+checksum = "ac57f2b058a76363e357c056e4f74f1945bf734d37b8b3ef49066c4787dde0fc"
dependencies = [
"clipboard-win",
"log",
"objc",
"objc-foundation",
"objc_id",
- "once_cell",
"parking_lot",
"thiserror",
"winapi",
"x11rb",
]
+[[package]]
+name = "arc-swap"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
+
[[package]]
name = "arrayref"
version = "0.3.7"
@@ -435,13 +440,13 @@ dependencies = [
[[package]]
name = "async-recursion"
-version = "1.0.4"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba"
+checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -484,7 +489,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -579,9 +584,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
-version = "0.21.2"
+version = "0.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
+checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2"
[[package]]
name = "bincode"
@@ -594,11 +599,11 @@ dependencies = [
[[package]]
name = "bindgen"
-version = "0.64.0"
+version = "0.68.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4"
+checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.0",
"cexpr",
"clang-sys",
"lazy_static",
@@ -609,7 +614,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
- "syn 1.0.109",
+ "syn 2.0.37",
]
[[package]]
@@ -708,9 +713,9 @@ dependencies = [
[[package]]
name = "bumpalo"
-version = "3.13.0"
+version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
+checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "bytemuck"
@@ -723,13 +728,13 @@ dependencies = [
[[package]]
name = "bytemuck_derive"
-version = "1.4.1"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192"
+checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -746,15 +751,15 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "bytes"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
+checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
[[package]]
name = "cairo-sys-rs"
-version = "0.18.0"
+version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd4d115132e01c0165e3bf5f56aedee8980b0b96ede4eb000b693c05a8adb8ff"
+checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51"
dependencies = [
"libc",
"system-deps",
@@ -816,9 +821,9 @@ dependencies = [
[[package]]
name = "cfg-expr"
-version = "0.15.4"
+version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b40ccee03b5175c18cde8f37e7d2a33bcef6f8ec8f7cc0d81090d1bb380949c9"
+checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3"
dependencies = [
"smallvec",
"target-lexicon",
@@ -900,15 +905,14 @@ dependencies = [
[[package]]
name = "cocoa-foundation"
-version = "0.1.1"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "931d3837c286f56e3c58423ce4eba12d08db2374461a785c86f672b08b5650d6"
+checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7"
dependencies = [
"bitflags 1.3.2",
"block",
"core-foundation",
"core-graphics-types",
- "foreign-types",
"libc",
"objc",
]
@@ -968,7 +972,7 @@ version = "4.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4"
dependencies = [
- "bytes 1.4.0",
+ "bytes 1.5.0",
"memchr",
]
@@ -1094,9 +1098,9 @@ dependencies = [
[[package]]
name = "coreaudio-sys"
-version = "0.2.12"
+version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f034b2258e6c4ade2f73bf87b21047567fb913ee9550837c2316d139b0262b24"
+checksum = "d8478e5bdad14dce236b9898ea002eabfa87cbe14f0aa538dbe3b6a4bec4332d"
dependencies = [
"bindgen",
]
@@ -1294,9 +1298,9 @@ dependencies = [
[[package]]
name = "curl-sys"
-version = "0.4.65+curl-8.2.1"
+version = "0.4.66+curl-8.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "961ba061c9ef2fe34bbd12b807152d96f0badd2bebe7b90ce6c8c8b7572a0986"
+checksum = "70c44a72e830f0e40ad90dda8a6ab6ed6314d39776599a58a2e5e37fbc6db5b9"
dependencies = [
"cc",
"libc",
@@ -1305,7 +1309,7 @@ dependencies = [
"openssl-sys",
"pkg-config",
"vcpkg",
- "winapi",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -1321,9 +1325,9 @@ dependencies = [
[[package]]
name = "dashmap"
-version = "5.5.1"
+version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edd72493923899c6f10c641bdbdeddc7183d6396641d99c1a0d1597f37f92e28"
+checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [
"cfg-if",
"hashbrown 0.14.0",
@@ -1439,6 +1443,17 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
+[[package]]
+name = "displaydoc"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.37",
+]
+
[[package]]
name = "dlib"
version = "0.5.2"
@@ -1450,9 +1465,9 @@ dependencies = [
[[package]]
name = "dlv-list"
-version = "0.5.0"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d529fd73d344663edfd598ccb3f344e46034db51ebd103518eae34338248ad73"
+checksum = "8aead04dc46b5f263c25721cf25c9e595951d15055f8063f92392fa0d7f64cf4"
dependencies = [
"const-random",
]
@@ -1560,7 +1575,7 @@ dependencies = [
"epaint",
"log",
"thiserror",
- "type-map",
+ "type-map 0.5.0",
"wgpu",
"winit",
]
@@ -1657,14 +1672,14 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
name = "enumflags2"
-version = "0.7.7"
+version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2"
+checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939"
dependencies = [
"enumflags2_derive",
"serde",
@@ -1672,24 +1687,24 @@ dependencies = [
[[package]]
name = "enumflags2_derive"
-version = "0.7.7"
+version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745"
+checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
name = "enumn"
-version = "0.1.11"
+version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b893c4eb2dc092c811165f84dc7447fae16fb66521717968c34c509b39b1a5c5"
+checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -1718,9 +1733,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
-version = "0.3.2"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
+checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
dependencies = [
"errno-dragonfly",
"libc",
@@ -1755,12 +1770,12 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "exr"
-version = "1.7.0"
+version = "1.71.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1e481eb11a482815d3e9d618db8c42a93207134662873809335a92327440c18"
+checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8"
dependencies = [
"bit_field",
- "flume 0.10.14",
+ "flume 0.11.0",
"half",
"lebe",
"miniz_oxide 0.7.1",
@@ -1835,6 +1850,15 @@ dependencies = [
"windows-sys 0.48.0",
]
+[[package]]
+name = "find-crate"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59a98bbaacea1c0eb6a0876280051b892eb73594fd90cf3b20e9c817029c57d2"
+dependencies = [
+ "toml 0.5.11",
+]
+
[[package]]
name = "finl_unicode"
version = "1.2.0"
@@ -1863,6 +1887,50 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
+[[package]]
+name = "fluent"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61f69378194459db76abd2ce3952b790db103ceb003008d3d50d97c41ff847a7"
+dependencies = [
+ "fluent-bundle",
+ "unic-langid",
+]
+
+[[package]]
+name = "fluent-bundle"
+version = "0.15.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd"
+dependencies = [
+ "fluent-langneg",
+ "fluent-syntax",
+ "intl-memoizer",
+ "intl_pluralrules",
+ "rustc-hash",
+ "self_cell",
+ "smallvec",
+ "unic-langid",
+]
+
+[[package]]
+name = "fluent-langneg"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c4ad0989667548f06ccd0e306ed56b61bd4d35458d54df5ec7587c0e8ed5e94"
+dependencies = [
+ "unic-langid",
+]
+
+[[package]]
+name = "fluent-syntax"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78"
+dependencies = [
+ "thiserror",
+]
+
[[package]]
name = "flume"
version = "0.9.2"
@@ -1876,14 +1944,10 @@ dependencies = [
[[package]]
name = "flume"
-version = "0.10.14"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
+checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
- "futures-core",
- "futures-sink",
- "nanorand",
- "pin-project",
"spin",
]
@@ -1997,7 +2061,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -2098,10 +2162,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
"cfg-if",
- "js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
- "wasm-bindgen",
]
[[package]]
@@ -2178,9 +2240,9 @@ dependencies = [
[[package]]
name = "glam"
-version = "0.24.1"
+version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "42218cb640844e3872cc3c153dc975229e080a6c4733b34709ef445610550226"
+checksum = "b5418c17512bdf42730f9032c74e1ae39afc408745ebb2acf72fbc4691c17945"
dependencies = [
"bytemuck",
]
@@ -2423,9 +2485,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
-version = "0.3.2"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
+checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
name = "hex"
@@ -2480,7 +2542,7 @@ version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
dependencies = [
- "bytes 1.4.0",
+ "bytes 1.5.0",
"fnv",
"itoa",
]
@@ -2530,6 +2592,76 @@ dependencies = [
"libm",
]
+[[package]]
+name = "i18n-config"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c9ce3c48cbc21fd5b22b9331f32b5b51f6ad85d969b99e793427332e76e7640"
+dependencies = [
+ "log",
+ "serde",
+ "serde_derive",
+ "thiserror",
+ "toml 0.8.0",
+ "unic-langid",
+]
+
+[[package]]
+name = "i18n-embed"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26261c73a1670a3f632a8765bb6b22c62fc391f3ddc805b87fd00cd6158e4456"
+dependencies = [
+ "arc-swap",
+ "fluent",
+ "fluent-langneg",
+ "fluent-syntax",
+ "i18n-embed-impl",
+ "intl-memoizer",
+ "lazy_static",
+ "locale_config",
+ "log",
+ "parking_lot",
+ "rust-embed",
+ "thiserror",
+ "unic-langid",
+ "walkdir",
+]
+
+[[package]]
+name = "i18n-embed-fl"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fc1f8715195dffc4caddcf1cf3128da15fe5d8a137606ea8856c9300047d5a2"
+dependencies = [
+ "dashmap",
+ "find-crate",
+ "fluent",
+ "fluent-syntax",
+ "i18n-config",
+ "i18n-embed",
+ "lazy_static",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 2.0.37",
+ "unic-langid",
+]
+
+[[package]]
+name = "i18n-embed-impl"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2a4d5bff745c9a6e1459c490059281b353a4ab0a4e1e58b3eeeaef71f97d07b"
+dependencies = [
+ "find-crate",
+ "i18n-config",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.37",
+]
+
[[package]]
name = "idna"
version = "0.4.0"
@@ -2648,6 +2780,25 @@ dependencies = [
"web-sys",
]
+[[package]]
+name = "intl-memoizer"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f"
+dependencies = [
+ "type-map 0.4.0",
+ "unic-langid",
+]
+
+[[package]]
+name = "intl_pluralrules"
+version = "7.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
+dependencies = [
+ "unic-langid",
+]
+
[[package]]
name = "io-lifetimes"
version = "1.0.11"
@@ -2875,9 +3026,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.147"
+version = "0.2.148"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
[[package]]
name = "libloading"
@@ -2950,9 +3101,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "linux-raw-sys"
-version = "0.4.5"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
+checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
[[package]]
name = "litrs"
@@ -2960,6 +3111,32 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9275e0933cf8bb20f008924c0cb07a0692fe54d8064996520bf998de9eb79aa"
+[[package]]
+name = "locale-codes"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1f4cc9d2da40c19763d5dd398baf388f2cc1473ca3d53c578c75e9ad0402324"
+dependencies = [
+ "lazy_static",
+ "log",
+ "regex",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "locale_config"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d2c35b16f4483f6c26f0e4e9550717a2f6575bcd6f12a53ff0c490a94a6934"
+dependencies = [
+ "lazy_static",
+ "objc",
+ "objc-foundation",
+ "regex",
+ "winapi",
+]
+
[[package]]
name = "lock_api"
version = "0.4.10"
@@ -3014,8 +3191,11 @@ dependencies = [
"futures",
"git-version",
"glam",
+ "i18n-embed",
+ "i18n-embed-fl",
"image 0.24.7",
"itertools",
+ "locale-codes",
"luminol-term",
"notify",
"num_enum 0.7.0",
@@ -3029,6 +3209,7 @@ dependencies = [
"rmxp-types",
"rodio",
"ron",
+ "rust-embed",
"rust-ini",
"rustysynth",
"serde",
@@ -3089,9 +3270,9 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.5.0"
+version = "2.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
[[package]]
name = "memmap2"
@@ -3169,7 +3350,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -3246,15 +3427,6 @@ dependencies = [
"unicode-xid",
]
-[[package]]
-name = "nanorand"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
-dependencies = [
- "getrandom 0.2.10",
-]
-
[[package]]
name = "ndk"
version = "0.7.0"
@@ -3325,15 +3497,14 @@ dependencies = [
[[package]]
name = "nix"
-version = "0.26.2"
+version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
+checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
dependencies = [
"bitflags 1.3.2",
"cfg-if",
"libc",
"memoffset 0.7.1",
- "static_assertions",
]
[[package]]
@@ -3422,16 +3593,6 @@ dependencies = [
"autocfg",
]
-[[package]]
-name = "num_cpus"
-version = "1.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
-dependencies = [
- "hermit-abi",
- "libc",
-]
-
[[package]]
name = "num_enum"
version = "0.5.11"
@@ -3480,7 +3641,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -3492,7 +3653,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -3562,9 +3723,9 @@ dependencies = [
[[package]]
name = "object"
-version = "0.32.0"
+version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe"
+checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
dependencies = [
"memchr",
]
@@ -3621,9 +3782,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
-version = "0.9.91"
+version = "0.9.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac"
+checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
dependencies = [
"cc",
"libc",
@@ -3691,7 +3852,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -3779,19 +3940,20 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]]
name = "pest"
-version = "2.7.2"
+version = "2.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a"
+checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33"
dependencies = [
+ "memchr",
"thiserror",
"ucd-trie",
]
[[package]]
name = "pest_derive"
-version = "2.7.2"
+version = "2.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853"
+checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a"
dependencies = [
"pest",
"pest_generator",
@@ -3799,22 +3961,22 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.7.2"
+version = "2.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929"
+checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141"
dependencies = [
"pest",
"pest_meta",
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
name = "pest_meta"
-version = "2.7.2"
+version = "2.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48"
+checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f"
dependencies = [
"once_cell",
"pest",
@@ -3880,7 +4042,7 @@ dependencies = [
"phf_shared 0.11.2",
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -3924,7 +4086,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -3951,12 +4113,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdc0001cfea3db57a2e24bc0d818e9e20e554b5f97fabb9bc231dc240269ae06"
dependencies = [
- "base64 0.21.2",
+ "base64 0.21.4",
"indexmap 1.9.3",
"line-wrap",
"quick-xml",
"serde",
- "time 0.3.27",
+ "time 0.3.29",
]
[[package]]
@@ -4049,7 +4211,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919"
dependencies = [
"once_cell",
- "toml_edit",
+ "toml_edit 0.19.15",
]
[[package]]
@@ -4084,18 +4246,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]]
name = "proc-macro2"
-version = "1.0.66"
+version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
+checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
dependencies = [
"unicode-ident",
]
[[package]]
name = "profiling"
-version = "1.0.9"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46b2164ebdb1dfeec5e337be164292351e11daf63a05174c6776b2f47460f0c9"
+checksum = "f89dff0959d98c9758c88826cc002e2c3d0b9dfac4139711d1f30de442f1139b"
[[package]]
name = "qoi"
@@ -4209,9 +4371,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
[[package]]
name = "rayon"
-version = "1.7.0"
+version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
+checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
dependencies = [
"either",
"rayon-core",
@@ -4219,14 +4381,12 @@ dependencies = [
[[package]]
name = "rayon-core"
-version = "1.11.0"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
+checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
dependencies = [
- "crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
- "num_cpus",
]
[[package]]
@@ -4266,9 +4426,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.9.3"
+version = "1.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a"
+checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
dependencies = [
"aho-corasick",
"memchr",
@@ -4278,9 +4438,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.3.6"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69"
+checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
dependencies = [
"aho-corasick",
"memchr",
@@ -4289,9 +4449,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.7.4"
+version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
+checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "renderdoc-sys"
@@ -4382,7 +4542,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
dependencies = [
- "base64 0.21.2",
+ "base64 0.21.4",
"bitflags 2.4.0",
"serde",
"serde_derive",
@@ -4397,6 +4557,40 @@ dependencies = [
"xmlparser",
]
+[[package]]
+name = "rust-embed"
+version = "8.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1e7d90385b59f0a6bf3d3b757f3ca4ece2048265d70db20a2016043d4509a40"
+dependencies = [
+ "rust-embed-impl",
+ "rust-embed-utils",
+ "walkdir",
+]
+
+[[package]]
+name = "rust-embed-impl"
+version = "8.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c3d8c6fd84090ae348e63a84336b112b5c3918b3bf0493a581f7bd8ee623c29"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "rust-embed-utils",
+ "syn 2.0.37",
+ "walkdir",
+]
+
+[[package]]
+name = "rust-embed-utils"
+version = "8.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "873feff8cb7bf86fdf0a71bb21c95159f4e4a37dd7a4bd1855a940909b583ada"
+dependencies = [
+ "sha2 0.10.7",
+ "walkdir",
+]
+
[[package]]
name = "rust-ini"
version = "0.19.0"
@@ -4444,14 +4638,14 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.38.8"
+version = "0.38.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
+checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f"
dependencies = [
"bitflags 2.4.0",
"errno",
"libc",
- "linux-raw-sys 0.4.5",
+ "linux-raw-sys 0.4.7",
"windows-sys 0.48.0",
]
@@ -4463,9 +4657,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "rustysynth"
-version = "1.2.1"
+version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b916492c4bdd1dba14c92761cc855f9ef12f3c7e4ef18cab07ee49e784c1c66b"
+checksum = "a2316fb90175e4f747331f29c9275aaddf2868b355472e94a3b82ad235a719b5"
[[package]]
name = "ryu"
@@ -4522,6 +4716,12 @@ dependencies = [
"tiny-skia",
]
+[[package]]
+name = "self_cell"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"
+
[[package]]
name = "semver"
version = "0.9.0"
@@ -4557,29 +4757,29 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.187"
+version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30a7fe14252655bd1e578af19f5fa00fe02fd0013b100ca6b49fde31c41bae4c"
+checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.187"
+version = "1.0.188"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e46b2a6ca578b3f1d4501b12f78ed4692006d79d82a1a7c561c12dbc3d625eb8"
+checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
name = "serde_json"
-version = "1.0.105"
+version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
+checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
dependencies = [
"itoa",
"ryu",
@@ -4605,7 +4805,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -4682,9 +4882,9 @@ dependencies = [
[[package]]
name = "sha1"
-version = "0.10.5"
+version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -4748,9 +4948,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
[[package]]
name = "shlex"
-version = "1.1.0"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
+checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380"
[[package]]
name = "signal-hook"
@@ -4834,15 +5034,15 @@ dependencies = [
[[package]]
name = "smallvec"
-version = "1.11.0"
+version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
+checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
[[package]]
name = "smithay-client-toolkit"
-version = "0.16.0"
+version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454"
+checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9"
dependencies = [
"bitflags 1.3.2",
"calloop",
@@ -5044,7 +5244,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -5148,9 +5348,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.29"
+version = "2.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
+checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
dependencies = [
"proc-macro2",
"quote",
@@ -5187,7 +5387,7 @@ dependencies = [
"cfg-expr",
"heck",
"pkg-config",
- "toml 0.7.6",
+ "toml 0.7.8",
"version-compare",
]
@@ -5206,15 +5406,15 @@ dependencies = [
"cfg-if",
"fastrand 2.0.0",
"redox_syscall 0.3.5",
- "rustix 0.38.8",
+ "rustix 0.38.14",
"windows-sys 0.48.0",
]
[[package]]
name = "termcolor"
-version = "1.2.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64"
dependencies = [
"winapi-util",
]
@@ -5256,7 +5456,7 @@ version = "0.22.0"
source = "git+https://github.com/wez/wezterm?rev=3666303c7b26c6c966b3f136dbb954686d334cc3#3666303c7b26c6c966b3f136dbb954686d334cc3"
dependencies = [
"anyhow",
- "base64 0.21.2",
+ "base64 0.21.4",
"bitflags 1.3.2",
"filedescriptor",
"finl_unicode",
@@ -5295,22 +5495,22 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.47"
+version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f"
+checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.47"
+version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
+checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -5373,22 +5573,22 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.27"
+version = "0.3.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07"
+checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe"
dependencies = [
"deranged",
"itoa",
"serde",
"time-core",
- "time-macros 0.2.13",
+ "time-macros 0.2.15",
]
[[package]]
name = "time-core"
-version = "0.1.1"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
@@ -5402,9 +5602,9 @@ dependencies = [
[[package]]
name = "time-macros"
-version = "0.2.13"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9"
+checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
dependencies = [
"time-core",
]
@@ -5456,6 +5656,15 @@ dependencies = [
"strict-num",
]
+[[package]]
+name = "tinystr"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b07bb54ef1f8ff27564b08b861144d3b8d40263efe07684f64987f4c0d044e3e"
+dependencies = [
+ "displaydoc",
+]
+
[[package]]
name = "tinyvec"
version = "1.6.0"
@@ -5482,14 +5691,26 @@ dependencies = [
[[package]]
name = "toml"
-version = "0.7.6"
+version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542"
+checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
- "toml_edit",
+ "toml_edit 0.19.15",
+]
+
+[[package]]
+name = "toml"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c226a7bba6d859b63c92c4b4fe69c5b6b72d0cb897dbc8e6012298e6154cb56e"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit 0.20.0",
]
[[package]]
@@ -5503,9 +5724,22 @@ dependencies = [
[[package]]
name = "toml_edit"
-version = "0.19.14"
+version = "0.19.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
+dependencies = [
+ "indexmap 2.0.0",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
+checksum = "8ff63e60a958cefbb518ae1fd6566af80d9d4be430a33f3723dfc47d1d411d95"
dependencies = [
"indexmap 2.0.0",
"serde",
@@ -5535,7 +5769,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
]
[[package]]
@@ -5595,9 +5829,18 @@ dependencies = [
[[package]]
name = "ttf-parser"
-version = "0.19.1"
+version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33"
+checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1"
+
+[[package]]
+name = "type-map"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46"
+dependencies = [
+ "rustc-hash",
+]
[[package]]
name = "type-map"
@@ -5610,9 +5853,9 @@ dependencies = [
[[package]]
name = "typenum"
-version = "1.16.0"
+version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ucd-trie"
@@ -5630,6 +5873,25 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "unic-langid"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f"
+dependencies = [
+ "unic-langid-impl",
+]
+
+[[package]]
+name = "unic-langid-impl"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff"
+dependencies = [
+ "serde",
+ "tinystr",
+]
+
[[package]]
name = "unicase"
version = "2.7.0"
@@ -5647,9 +5909,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
[[package]]
name = "unicode-ident"
-version = "1.0.11"
+version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
@@ -5668,9 +5930,9 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-width"
-version = "0.1.10"
+version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]]
name = "unicode-xid"
@@ -5690,9 +5952,9 @@ dependencies = [
[[package]]
name = "url"
-version = "2.4.0"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
+checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
dependencies = [
"form_urlencoded",
"idna",
@@ -5788,9 +6050,9 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]]
name = "walkdir"
-version = "2.3.3"
+version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
+checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee"
dependencies = [
"same-file",
"winapi-util",
@@ -5829,7 +6091,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
"wasm-bindgen-shared",
]
@@ -5863,7 +6125,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.29",
+ "syn 2.0.37",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -6198,9 +6460,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
-version = "0.1.5"
+version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
@@ -6542,15 +6804,15 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2769203cd13a0c6015d515be729c526d041e9cf2c0cc478d57faee85f40c6dcd"
dependencies = [
- "nix 0.26.2",
+ "nix 0.26.4",
"winapi",
]
[[package]]
name = "xml-rs"
-version = "0.8.16"
+version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47430998a7b5d499ccee752b41567bc3afc57e1327dc855b1a2aa44ce29b5fa1"
+checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
[[package]]
name = "xmlparser"
@@ -6591,13 +6853,13 @@ dependencies = [
"futures-sink",
"futures-util",
"hex",
- "nix 0.26.2",
+ "nix 0.26.4",
"once_cell",
"ordered-stream",
"rand 0.8.5",
"serde",
"serde_repr",
- "sha1 0.10.5",
+ "sha1 0.10.6",
"static_assertions",
"tracing",
"uds_windows",
diff --git a/Cargo.toml b/Cargo.toml
index a4fec802..02a00356 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -97,10 +97,18 @@ luminol-term = { version = "*", path = "luminol-term" }
steamworks = { version = "0.10.0", optional = true }
crc = { version = "3.0", optional = true }
+# Internationalization and Localization
+i18n-embed = { version = "0.14.0", features = [
+ "fluent-system",
+ "desktop-requester",
+] }
+i18n-embed-fl = "0.7.0"
+locale-codes = "0.3.0"
+rust-embed = "8.0.0"
+
[features]
steamworks = ["dep:steamworks", "crc"]
-
[target.'cfg(windows)'.dependencies]
windows = { version = "0.51.1", features = ["Win32_System_Registry"] }
winreg = "0.51.0"
diff --git a/i18n.toml b/i18n.toml
new file mode 100644
index 00000000..04d478c2
--- /dev/null
+++ b/i18n.toml
@@ -0,0 +1,4 @@
+fallback_language = "en-AU"
+
+[fluent]
+assets_dir = "lang"
diff --git a/lang/en-AU/luminol.ftl b/lang/en-AU/luminol.ftl
new file mode 100644
index 00000000..e29e617e
--- /dev/null
+++ b/lang/en-AU/luminol.ftl
@@ -0,0 +1,239 @@
+# Copyright (C) 2023 Lily Lyons
+#
+# This file is part of Luminol.
+#
+# Luminol is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Luminol 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Luminol. If not, see .
+
+luminol = Luminol
+
+# General words
+start = Start
+unloaded = Unloaded
+scale = Scale
+events = Events
+fog = Fog
+new_project = New Project
+open_project = Open Project
+fullscreen = Fullscreen
+maps = Maps
+items = Items
+common_event = Common Event
+common_events = Common Events
+scripts = Scripts
+sound_test = Sound Test
+about = About
+ok = Ok
+cancel = Cancel
+apply = Apply
+name = Name
+icon = Icon
+description = Description
+scope = Scope
+occasion = Occasion
+search = Search
+code = Code
+type = Type
+parameters = Parameters
+save = Save
+position = Position
+variants = Variants
+switch = Switch
+variable = Variable
+example_allcaps = EXAMPLE
+
+# Errors
+fatal_error = Fatal Error
+deadlock_detected_title = Deadlock #{$deadlockIndex}
+deadlock_detected_description = Luminol has deadlocked! Please file an issue.
+ { $numOfDeadLocks } deadlocks detected
+thread_id = Thread Id {$id}
+
+# Tabs
+# > Started
+tab_started_title_label = Get Started
+tab_started_recent_projects_label = Recent
+# > Map
+tab_map_title_label = Map {$id}: {$name}
+tab_map_layer_section_sv = Layer {$num}
+tab_map_panorama_label = Panorama
+tab_map_dva_cb = Display Visible Area
+tab_map_pemr_cb = Preview event move routes
+tab_map_cmrp_btn = Clear move route preview
+
+# Windows
+# > About
+window_about_title_label = About
+window_about_luminol_label = About Luminol
+window_about_version_text_label = Luminol version {$version}
+window_about_description_text_label = Luminol is a FOSS version of the RPG Maker XP editor.
+window_about_authors_label = Authors:
+ {$authorsArray}
+# > Common Event Editor
+window_common_events_editing_label = Editing Common Event {$name}
+window_common_events_type_none_sv = None
+window_common_events_type_autorun_sv = Autorun
+window_common_events_type_parallel_sv = Parallel
+# > Config
+window_config_title_label = Local Luminol Config
+window_config_proj_name_label = Project name
+window_config_scripts_path_label = Scripts path
+window_config_use_ron_cb = Use RON (Rusty Object Notation)
+window_config_rgss_ver_label = RGSS Version
+window_config_playtest_exe_btn = Playtest Executable
+# > Event Editor
+window_event_title_label = Event: {$name}, {$id} in Map {$map_id}
+window_event_new_page_btn = New page
+window_event_copy_page_btn = Copy page
+window_event_paste_page_btn = Paste page
+window_event_clear_page_btn = Clear page
+window_event_tab_configuration_sv = Configuration
+window_event_tab_graphic_sv = Graphic
+window_event_tab_commands_sv = Commands
+window_event_conf_condition_label = Condition
+window_event_conf_switch_cb = Switch
+window_event_conf_variable_cb = Variable
+window_event_conf_or_above_label = or above
+window_event_conf_self_switch_cb = Self Switch
+window_event_conf_is_on_label = is on
+window_event_conf_options_label = Options
+window_event_conf_option_move_anim_cb = Move Animation
+window_event_conf_option_stop_anim_cb = Stop Animation
+window_event_conf_option_direction_fix_cb = Direction Fix
+window_event_conf_option_through_cb = Through
+window_event_conf_option_aot_cb = Always on Top
+window_event_conf_trigger_label = Trigger
+window_event_conf_trigger_action_btn_rv = Action Button
+window_event_conf_trigger_player_touch_rv = Player Touch
+window_event_conf_trigger_event_touch_rv = Event Touch
+window_event_conf_trigger_autorun_rv = Autorun
+window_event_conf_trigger_parallel_proc_rv = Parallel Process
+window_event_graphic_add_image_btn = Add image
+# > Graphic Picker
+window_graphic_picker_title_label = Graphic Picker
+# > Items
+window_items_title_label = Editing item {$name}
+window_items_change_max_btn = Change maximum...
+window_items_user_anim_field = User Animation
+window_items_target_anim_field = Target Animation
+window_items_menu_se_field = Menu Use SE
+window_items_msep_label = Menu Sound Effect Picker
+# > Map Picker
+window_map_picker_title_label = Map Picker
+window_map_picker_root_label = root
+# > Egui Inspection
+window_egui_inspec_title_label = Egui Inspection
+# > Egui Memory
+window_egui_memory_title_label = Egui Memory
+# > New Project
+window_new_proj_my_proj_str = My Project
+window_new_proj_name_label = Project Name
+window_new_proj_with_git_cb = Initialize with git repository
+window_new_proj_git_branch_label = Git Branch
+window_new_proj_rgss_runtime_label = RGSS runtime
+window_new_proj_with_exe_download_cb = Download latest version of {$variant}
+window_new_proj_dl_and_unzipping_label = Downloading & Unzipping {$current}/{$total}
+# > Script Editor
+window_script_editor_fallback_title_label = Scripts
+window_script_editor_title_label = Editing Script {$name}
+window_script_editor_insert_btn = Insert
+window_script_editor_delete_btn = Delete
+window_script_editor_new_str = New Script
+# > Sound
+window_sound_test_title_label = Sound Test
+window_sound_test_play_btn = Play
+window_sound_test_stop_btn = Stop
+window_sound_test_volume_label = Volume
+window_sound_test_pitch_label = Pitch
+# > Command Generator
+window_commandgen_title_label = Luminol Command Maker
+window_commandgen_desc_label = Description for this command
+window_commandgen_lumi_label = Lumi help text
+window_commandgen_lumi_onhover_label = This text will be shown by lumi if she's enabled
+window_commandgen_contcode_label = Cont. Code
+window_commandgen_contcode_onhover_label = Luminol will assume that any following commands with this code are a part of this one
+window_commandgen_syntax_highlighting_cb = Enable Ruby syntax highlighting
+window_commandgen_endcode_label = End Code
+window_commandgen_endcode_onhover_label = Luminol will add this command to denote the end of the branch
+window_commandgen_him_cb = Hide in menu
+window_commandgen_preview_btn = Preview UI
+window_commandgen_position_onhover_label = Position of this parameter, when not set it is assumed to be the index of the parameter
+window_commandgen_grouped_params_label = Grouped parameters
+window_commandgen_grouped_params_onhover_label = This parameter groups together other parameters
+window_commandgen_subparams_label = Subparameters
+window_commandgen_subparams_onhover_label = This parameter selects one of the following parameters
+window_commandgen_description_onhover_label = Description for this parameter
+window_commandgen_variants_onhover_label = Variants for the enum
+window_commandgen_ui_example_label = [{$code}] {$name} UI Example
+# > General
+window_untitled_title = Untitled Window
+
+# Modals
+# > Switch
+modal_switch_title_label = Switch Picker
+# > Variable
+modal_variable_title_label = Variable Picker
+
+# Top Bar
+# > File Menu
+topbar_file_section = File
+topbar_file_current_proj_label = Current project:
+ {$path}
+topbar_file_no_proj_open_label = No project open
+topbar_file_proj_config_btn = Project Config
+topbar_file_close_proj_btn = Close Project
+topbar_file_save_proj_btn = Save Project
+topbar_file_command_maker_btn = Command Maker
+topbar_file_quit_btn = Quit
+# > Appearance Menu
+topbar_appearance_section = Appearance
+topbar_appearance_egui_conf_btn = Egui Settings
+topbar_appearance_egui_catppuccin_section = Catppuccin theme
+topbar_appearance_code_theme_section = Code Theme
+topbar_appearance_code_sample_label = Code sample
+topbar_appearance_clt_btn = Clear Loaded Textures
+topbar_appearance_clt_onhover_label = You may need to reopen maps/windows for any changes to take effect.
+# > Data Menu
+topbar_data_section = Data
+# > Help Menu
+topbar_help_section = Help
+topbar_egui_inspection_btn = Egui Inspection
+topbar_egui_memory_btn = Egui Memory
+topbar_debug_on_hover_tv = Debug on hover
+# > Other UI Controls
+topbar_playtest_btn = Playtest
+topbar_terminal_btn = Terminal
+topbar_brush_label = Brush
+topbar_egui_settings_label = Egui Settings
+
+# Toast Notifications
+toast_error_load_proj = Error loading the project: {$why}
+toast_error_starting_game = Error starting game (tried steamshim.exe and then game.exe): {$why}
+toast_error_starting_shell = Error starting shell: {$why}
+toast_error_displaying_term = Error displaying terminal: {$why}
+toast_error_cannot_load_icon = Could not load `{$icon_path}` icon: {$why}
+toast_error_reading_icons = Error while reading `Graphics/Icons`: {$why}
+toast_error_creating_proj = Failed to create the project: {$why}
+toast_error_init_git = Error while initializing the git repository: {$why}
+toast_error_downloading_rgss = Error downloading {$variant}: {$why}
+toast_error_getting_body_resp = Error getting response body for {$variant}: {$why}
+toast_error_read_zip = Failed to read the zip archive for {$variant}: {$why}
+toast_error_invalid_file_path = Invalid file path {$file_path}
+toast_error_create_dir = Failed to create directory {$file_path}: {$why}
+toast_error_reading_file_data = Failed to read file data {$file_path}: {$why}
+toast_error_saving_file_data = Failed to save file data {$file_path}: {$why}
+toast_error_loading_rxdata = Failed to load {$file_path}: {$why}
+toast_info_saving_proj = Saving project...
+toast_info_saved_proj = Saved project successfully!
+toast_info_opened_proj = Opened project successfully!
+toast_info_successful_load = Successfully opened {$projectName}
\ No newline at end of file
diff --git a/src/cache/data.rs b/src/cache/data.rs
index d7d59968..180d632b 100644
--- a/src/cache/data.rs
+++ b/src/cache/data.rs
@@ -172,7 +172,6 @@ impl Cache {
tilesets,
troops,
weapons,
-
maps: Default::default(),
scripts: AtomicRefCell::new(scripts),
};
diff --git a/src/command_gen/mod.rs b/src/command_gen/mod.rs
index 1e30f480..db32d3ed 100644
--- a/src/command_gen/mod.rs
+++ b/src/command_gen/mod.rs
@@ -18,7 +18,7 @@ use command_lib::{CommandDescription, CommandKind, Index, Parameter};
use ui_example::UiExample;
-use crate::prelude::*;
+use crate::{fl, prelude::*};
pub mod parameter_ui;
pub mod ui_example;
@@ -82,7 +82,7 @@ impl CommandGeneratorWindow {
impl window::Window for CommandGeneratorWindow {
fn name(&self) -> String {
- String::from("Luminol Command Maker")
+ fl!("window_commandgen_title_label")
}
fn id(&self) -> egui::Id {
@@ -94,19 +94,20 @@ impl window::Window for CommandGeneratorWindow {
egui::ScrollArea::both().show(ui, |ui| {
let mut del_index = None;
for (idx, command) in self.commands.iter_mut().enumerate() {
- ui.push_id(command.guid, |ui| {
- let header = egui::collapsing_header::CollapsingState::load_with_default_open(
- ui.ctx(),
- format!("command_{idx}").into(),
- false,
- );
+ ui.push_id(command.guid, |ui| {
+ let header =
+ egui::collapsing_header::CollapsingState::load_with_default_open(
+ ui.ctx(),
+ format!("command_{idx}").into(),
+ false,
+ );
header
.show_header(ui, |ui| {
ui.horizontal(|ui| {
- ui.label("Name:");
+ ui.label(format!("{}:", fl!("name")));
ui.text_edit_singleline(&mut command.name);
- ui.label("Code:");
+ ui.label(format!("{}:", fl!("code")));
ui.add(egui::DragValue::new(&mut command.code));
});
@@ -122,56 +123,78 @@ impl window::Window for CommandGeneratorWindow {
}
})
.body(|ui| {
- ui.label("Description:");
+ ui.label(format!("{}:", fl!("description")));
ui.text_edit_multiline(&mut command.description)
- .on_hover_text("Description for this command");
- ui.label("Lumi help text");
- ui.text_edit_multiline(&mut command.lumi_text).on_hover_text("This text will be shown by lumi if she's enabled");
+ .on_hover_text(fl!("window_commandgen_desc_label"));
+ ui.label(fl!("window_commandgen_lumi_label"));
+ ui.text_edit_multiline(&mut command.lumi_text)
+ .on_hover_text(fl!("window_commandgen_lumi_onhover_label"));
ui.separator();
- ui.label("Type");
+ ui.label(fl!("type"));
ui.horizontal(|ui| {
ui.menu_button(
format!("{} ⏷", <&str>::from(&command.kind)),
|ui| {
for kind in CommandKind::iter() {
- let text =<&str>::from(&kind);
- ui.selectable_value(
- &mut command.kind,
- kind,
- text,
- );
+ let text = <&str>::from(&kind);
+ ui.selectable_value(&mut command.kind, kind, text);
}
},
);
match command.kind {
- CommandKind::Multi { ref mut code, ref mut highlight} =>{
- ui.label("Cont. Code").on_hover_text("Luminol will assume that any following commands with this code are a part of this one");
+ CommandKind::Multi {
+ ref mut code,
+ ref mut highlight,
+ } => {
+ ui.label(fl!("window_commandgen_contcode_label"))
+ .on_hover_text(fl!(
+ "window_commandgen_contcode_onhover_label"
+ ));
ui.add(egui::DragValue::new(code));
- ui.checkbox(highlight, "Enable ruby syntax highlighting");
+ ui.checkbox(
+ highlight,
+ fl!("window_commandgen_syntax_highlighting_cb"),
+ );
}
- CommandKind::Branch { ref mut end_code, .. } => {
- ui.label("End Code").on_hover_text("Luminol will add this command to denote the end of the branch");
+ CommandKind::Branch {
+ ref mut end_code, ..
+ } => {
+ ui.label(fl!("window_commandgen_endcode_label"))
+ .on_hover_text(fl!(
+ "window_commandgen_endcode_onhover_label"
+ ));
ui.add(egui::DragValue::new(end_code));
}
_ => {}
}
});
- ui.checkbox(&mut command.hidden, "Hide in menu");
+ ui.checkbox(&mut command.hidden, fl!("window_commandgen_him_cb"));
ui.separator();
- if let CommandKind::Single(ref mut parameters) | CommandKind::Branch { ref mut parameters, .. } = command.kind {
- ui.collapsing("Parameters", |ui| {
+ if let CommandKind::Single(ref mut parameters)
+ | CommandKind::Branch {
+ ref mut parameters, ..
+ } = command.kind
+ {
+ ui.collapsing(fl!("parameters"), |ui| {
let mut del_idx = None;
let mut passed_index = 0;
for (ele, parameter) in parameters.iter_mut().enumerate() {
- parameter_ui::parameter_ui(ui, parameter, (ele, &mut del_idx));
-
- Self::recalculate_parameter_index(parameter, &mut passed_index);
+ parameter_ui::parameter_ui(
+ ui,
+ parameter,
+ (ele, &mut del_idx),
+ );
+
+ Self::recalculate_parameter_index(
+ parameter,
+ &mut passed_index,
+ );
}
if let Some(idx) = del_idx {
@@ -192,7 +215,9 @@ impl window::Window for CommandGeneratorWindow {
}
});
- if command.parameter_count() > 0 && ui.button("Preview UI").clicked() {
+ if command.parameter_count() > 0
+ && ui.button(fl!("window_commandgen_preview_btn")).clicked()
+ {
self.ui_examples.push(UiExample::new(command));
}
@@ -206,17 +231,17 @@ impl window::Window for CommandGeneratorWindow {
ui.horizontal(|ui| {
if ui
- .button(
- egui::RichText::new("+")
- .monospace()
- .color(egui::Color32::GREEN),
- )
- .clicked()
+ .button(
+ egui::RichText::new("+")
+ .monospace()
+ .color(egui::Color32::GREEN),
+ )
+ .clicked()
{
self.commands.push(CommandDescription::default());
}
- if ui.button("Save").clicked() {
+ if ui.button(fl!("save")).clicked() {
command_db!().user = self.commands.clone();
}
});
diff --git a/src/command_gen/parameter_ui.rs b/src/command_gen/parameter_ui.rs
index f7eb7de0..0e04eda5 100644
--- a/src/command_gen/parameter_ui.rs
+++ b/src/command_gen/parameter_ui.rs
@@ -27,49 +27,54 @@ use eframe::egui;
use strum::IntoEnumIterator;
+use crate::fl;
+
pub fn parameter_ui(
ui: &mut egui::Ui,
parameter: &mut Parameter,
del_idx: (usize, &mut Option),
) {
ui.horizontal(|ui| {
- ui.menu_button(format!("{} ⏷", <&str>::from(&*parameter)), |ui| {
- for iter_kind in Parameter::iter() {
- if let Parameter::Group {ref mut guid , ..}
- | Parameter::Selection { ref mut guid, .. } = parameter {
- *guid = rand::random();
- }
- let text: &str = (&iter_kind).into();
- ui.selectable_value(parameter, iter_kind, text);
+ ui.menu_button(format!("{} ⏷", <&str>::from(&*parameter)), |ui| {
+ for iter_kind in Parameter::iter() {
+ if let Parameter::Group { ref mut guid, .. }
+ | Parameter::Selection { ref mut guid, .. } = parameter
+ {
+ *guid = rand::random();
}
- });
+ let text: &str = (&iter_kind).into();
+ ui.selectable_value(parameter, iter_kind, text);
+ }
+ });
- if let Parameter::Single { ref mut index, ..}
- | Parameter::Selection { ref mut index, .. } = parameter {
- ui.label("Position: ").on_hover_text_at_pointer("Position of this parameter, when not set it is assumed to be the index of the parameter");
- match index {
- Index::Overridden(ref mut idx) => {
- ui.add(egui::DragValue::new(idx));
- }
- Index::Assumed(ref mut assumed_idx) => {
- if ui.add(egui::DragValue::new(assumed_idx)).changed() {
- *index = Index::Overridden(*assumed_idx);
- }
+ if let Parameter::Single { ref mut index, .. }
+ | Parameter::Selection { ref mut index, .. } = parameter
+ {
+ ui.label(format!("{}: ", fl!("position")))
+ .on_hover_text_at_pointer(fl!("window_commandgen_position_onhover_label"));
+ match index {
+ Index::Overridden(ref mut idx) => {
+ ui.add(egui::DragValue::new(idx));
+ }
+ Index::Assumed(ref mut assumed_idx) => {
+ if ui.add(egui::DragValue::new(assumed_idx)).changed() {
+ *index = Index::Overridden(*assumed_idx);
}
}
}
+ }
- if ui
- .button(
- egui::RichText::new("-")
- .monospace()
- .color(egui::Color32::RED),
- )
- .clicked()
- {
- *del_idx.1 = Some(del_idx.0);
- }
- });
+ if ui
+ .button(
+ egui::RichText::new("-")
+ .monospace()
+ .color(egui::Color32::RED),
+ )
+ .clicked()
+ {
+ *del_idx.1 = Some(del_idx.0);
+ }
+ });
match parameter {
Parameter::Group {
@@ -77,7 +82,7 @@ pub fn parameter_ui(
guid,
} => {
ui.push_id(guid, |ui| {
- egui::CollapsingHeader::new("Grouped parameters")
+ egui::CollapsingHeader::new(fl!("window_commandgen_grouped_params_label"))
.default_open(true)
.show(ui, |ui| {
let mut del_idx = None;
@@ -101,7 +106,7 @@ pub fn parameter_ui(
}
})
.header_response
- .on_hover_text("This parameter groups together other parameters");
+ .on_hover_text(fl!("window_commandgen_grouped_params_onhover_label"));
});
}
Parameter::Selection {
@@ -110,7 +115,7 @@ pub fn parameter_ui(
..
} => {
ui.push_id(guid, |ui| {
- egui::CollapsingHeader::new("Subparameters")
+ egui::CollapsingHeader::new(fl!("window_commandgen_subparams_label"))
.default_open(true)
.show(ui, |ui| {
let mut del_idx = None;
@@ -142,7 +147,7 @@ pub fn parameter_ui(
}
})
.header_response
- .on_hover_text("This parameter selects one of the following parameters");
+ .on_hover_text(fl!("window_commandgen_subparams_onhover_label"));
});
}
Parameter::Single {
@@ -152,18 +157,18 @@ pub fn parameter_ui(
..
} => {
ui.horizontal(|ui| {
- ui.label("Name");
+ ui.label(fl!("name"));
ui.text_edit_singleline(name);
});
ui.horizontal(|ui| {
- ui.label("Description:");
+ ui.label(format!("{}:", fl!("description")));
ui.text_edit_singleline(description)
- .on_hover_text("Description for this parameter");
+ .on_hover_text(fl!("window_commandgen_description_onhover_label"));
});
ui.horizontal(|ui| {
- ui.label("Type: ");
+ ui.label(format!("{}: ", fl!("type")));
ui.menu_button(format!("{} ⏷", <&str>::from(&*kind)), |ui| {
for iter_kind in ParameterKind::iter() {
let text: &str = (&iter_kind).into();
@@ -173,7 +178,7 @@ pub fn parameter_ui(
});
if let ParameterKind::Enum { ref mut variants } = kind {
- egui::CollapsingHeader::new("Variants")
+ egui::CollapsingHeader::new(fl!("variants"))
.default_open(true)
.show(ui, |ui| {
let mut del_idx = None;
@@ -211,7 +216,7 @@ pub fn parameter_ui(
}
})
.header_response
- .on_disabled_hover_text("Variants for the enum");
+ .on_disabled_hover_text(fl!("window_commandgen_variants_onhover_label"));
}
}
Parameter::Dummy => {}
diff --git a/src/command_gen/ui_example.rs b/src/command_gen/ui_example.rs
index a7e19a10..b81c6154 100644
--- a/src/command_gen/ui_example.rs
+++ b/src/command_gen/ui_example.rs
@@ -25,6 +25,8 @@
use command_lib::{CommandDescription, CommandKind, Parameter, ParameterKind};
use eframe::egui;
+use crate::fl;
+
pub struct UiExample {
command: CommandDescription,
}
@@ -38,9 +40,10 @@ impl UiExample {
pub fn update(&mut self, ctx: &egui::Context) -> bool {
let mut open = true;
- egui::Window::new(format!(
- "[{}] {} UI example",
- self.command.code, self.command.name
+ egui::Window::new(fl!(
+ "window_commandgen_ui_example_label",
+ code = self.command.code,
+ name = self.command.name.clone()
))
.open(&mut open)
.show(ctx, |ui| {
@@ -104,10 +107,20 @@ impl UiExample {
match kind {
ParameterKind::Switch => {
- ui.button("Switch: [000: EXAMPLE]").clicked();
+ ui.button(format!(
+ "{}: [000: {}]",
+ fl!("switch"),
+ fl!("example_allcaps")
+ ))
+ .clicked();
}
ParameterKind::Variable => {
- ui.button("Variable [000: EXAMPLE]").clicked();
+ ui.button(format!(
+ "{} [000: {}]",
+ fl!("variable"),
+ fl!("example_allcaps")
+ ))
+ .clicked();
}
ParameterKind::String => {
ui.text_edit_singleline(&mut "".to_string());
diff --git a/src/components/top_bar.rs b/src/components/top_bar.rs
index d5054a56..aa6dd1df 100644
--- a/src/components/top_bar.rs
+++ b/src/components/top_bar.rs
@@ -22,6 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
+use crate::fl;
use crate::prelude::*;
use crate::Pencil;
@@ -41,7 +42,7 @@ impl TopBar {
let state = state!();
egui::widgets::global_dark_light_mode_switch(ui);
- ui.checkbox(&mut self.fullscreen, "Fullscreen");
+ ui.checkbox(&mut self.fullscreen, fl!("fullscreen"));
frame.set_fullscreen(self.fullscreen);
@@ -55,40 +56,40 @@ impl TopBar {
ui.separator();
- ui.menu_button("File", |ui| {
+ ui.menu_button(fl!("topbar_file_section"), |ui| {
ui.label(if let Some(path) = state.filesystem.project_path() {
- format!("Current project:\n{}", path)
+ fl!("topbar_file_current_proj_label", path = path.to_string())
} else {
- "No project open".to_string()
+ fl!("topbar_file_no_proj_open_label")
});
- if ui.button("New Project").clicked() {
+ if ui.button(fl!("new_project")).clicked() {
state.windows.add_window(new_project::Window::default());
}
- open_project |= ui.button("Open Project").clicked();
+ open_project |= ui.button(fl!("open_project")).clicked();
ui.separator();
ui.add_enabled_ui(state.filesystem.project_loaded(), |ui| {
- if ui.button("Project Config").clicked() {
+ if ui.button(fl!("topbar_file_proj_config_btn")).clicked() {
state.windows.add_window(config_window::Window {});
}
- if ui.button("Close Project").clicked() {
+ if ui.button(fl!("topbar_file_close_proj_btn")).clicked() {
state.windows.clean_windows();
state.tabs.clean_tabs(|t| !t.requires_filesystem());
state.audio.clear_sinks(); // audio loads files borrows from the filesystem. unloading while they are playing is a crash
state.filesystem.unload_project();
}
- save_project |= ui.button("Save Project").clicked();
+ save_project |= ui.button(fl!("topbar_file_save_proj_btn")).clicked();
});
ui.separator();
ui.add_enabled_ui(state.filesystem.project_loaded(), |ui| {
- if ui.button("Command Maker").clicked() {
+ if ui.button(fl!("topbar_file_command_maker_btn")).clicked() {
state
.windows
.add_window(crate::command_gen::CommandGeneratorWindow::default());
@@ -97,7 +98,7 @@ impl TopBar {
ui.separator();
- if ui.button("Quit").clicked() {
+ if ui.button(fl!("topbar_file_quit_btn")).clicked() {
frame.close();
}
});
@@ -119,27 +120,27 @@ impl TopBar {
ui.separator();
- ui.menu_button("Data", |ui| {
+ ui.menu_button(fl!("topbar_data_section"), |ui| {
ui.add_enabled_ui(state.filesystem.project_loaded(), |ui| {
- if ui.button("Maps").clicked() {
+ if ui.button(fl!("maps")).clicked() {
state.windows.add_window(map_picker::Window::default());
}
- if ui.button("Items").clicked() {
+ if ui.button(fl!("items")).clicked() {
state.windows.add_window(items::Window::default());
}
- if ui.button("Common Events").clicked() {
+ if ui.button(fl!("common_events")).clicked() {
state
.windows
.add_window(common_event_edit::Window::default());
}
- if ui.button("Scripts").clicked() {
+ if ui.button(fl!("scripts")).clicked() {
state.windows.add_window(script_edit::Window::default());
}
- if ui.button("Sound Test").clicked() {
+ if ui.button(fl!("scripts")).clicked() {
state.windows.add_window(sound_test::Window::default());
}
});
@@ -160,12 +161,12 @@ impl TopBar {
state.windows.add_window(misc::EguiInspection::default());
}
- if ui.button("Egui Memory").clicked() {
+ if ui.button(fl!("topbar_egui_memory_btn")).clicked() {
state.windows.add_window(misc::EguiMemory::default());
}
let mut debug_on_hover = ui.ctx().debug_on_hover();
- ui.toggle_value(&mut debug_on_hover, "Debug on hover");
+ ui.toggle_value(&mut debug_on_hover, fl!("topbar_debug_on_hover_tv"));
ui.ctx().set_debug_on_hover(debug_on_hover);
ui.separator();
@@ -178,7 +179,7 @@ impl TopBar {
ui.separator();
ui.add_enabled_ui(state.filesystem.project_loaded(), |ui| {
- if ui.button("Playtest").clicked() {
+ if ui.button(fl!("topbar_playtest_btn")).clicked() {
let mut cmd = luminol_term::CommandBuilder::new("steamshim");
cmd.cwd(state.filesystem.project_path().expect("project not loaded"));
@@ -191,13 +192,13 @@ impl TopBar {
match result {
Ok(w) => state.windows.add_window(w),
- Err(e) => state.toasts.error(format!(
- "error starting game (tried steamshim.exe and then game.exe): {e}"
- )),
+ Err(e) => state
+ .toasts
+ .error(fl!("toast_error_starting_game", why = e.to_string())),
}
}
- if ui.button("Terminal").clicked() {
+ if ui.button(fl!("topbar_terminal_btn")).clicked() {
#[cfg(windows)]
let shell = "powershell";
#[cfg(unix)]
@@ -207,14 +208,16 @@ impl TopBar {
match crate::windows::console::Console::new(cmd) {
Ok(w) => state.windows.add_window(w),
- Err(e) => state.toasts.error(format!("error starting shell: {e}")),
+ Err(e) => state
+ .toasts
+ .error(fl!("toast_error_starting_shell", why = e.to_string())),
}
}
});
ui.separator();
- ui.label("Brush:");
+ ui.label(format!("{}:", fl!("topbar_brush_label")));
let mut toolbar = state.toolbar.borrow_mut();
for brush in Pencil::iter() {
@@ -228,9 +231,9 @@ impl TopBar {
}
if save_project {
- state.toasts.info("Saving project...");
+ state.toasts.info(fl!("toast_info_saving_proj"));
match state.data_cache.save() {
- Ok(_) => state.toasts.info("Saved project sucessfully!"),
+ Ok(_) => state.toasts.info(fl!("toast_info_saved_proj")),
Err(e) => state.toasts.error(e),
}
}
@@ -238,7 +241,7 @@ impl TopBar {
if self.open_project_promise.is_some() {
if let Some(r) = self.open_project_promise.as_ref().unwrap().ready() {
match r {
- Ok(_) => state.toasts.info("Opened project successfully!"),
+ Ok(_) => state.toasts.info(fl!("toast_info_opened_proj")),
Err(e) => state.toasts.error(e),
}
self.open_project_promise = None;
diff --git a/src/filesystem/project.rs b/src/filesystem/project.rs
index 7db46846..3fe873fc 100644
--- a/src/filesystem/project.rs
+++ b/src/filesystem/project.rs
@@ -14,7 +14,7 @@
//
// You should have received a copy of the GNU General Public License
// along with Luminol. If not, see .
-use crate::prelude::*;
+use crate::{fl, prelude::*};
use super::FileSystem as FileSystemTrait;
use super::{archiver, host, list, path_cache, DirEntry, Error, Metadata, OpenFlags};
@@ -310,7 +310,7 @@ impl FileSystem {
let state = self.state.borrow();
match &*state {
State::Unloaded => {
- ui.label("Unloaded");
+ ui.label(fl!("unloaded"));
}
State::HostLoaded(fs) => {
ui.label("Host Filesystem Loaded");
diff --git a/src/i18n.rs b/src/i18n.rs
new file mode 100644
index 00000000..1087fd8f
--- /dev/null
+++ b/src/i18n.rs
@@ -0,0 +1,55 @@
+// Copyright (C) 2023 Lily Lyons
+//
+// This file is part of Luminol.
+//
+// Luminol is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Luminol 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Luminol. If not, see .
+use i18n_embed::{
+ fluent::{fluent_language_loader, FluentLanguageLoader},
+ DesktopLanguageRequester, I18nEmbedError,
+};
+use once_cell::sync::Lazy;
+use rust_embed::RustEmbed;
+
+#[derive(Debug, RustEmbed)]
+#[folder = "lang"]
+pub struct Localizations;
+
+static LOADER: Lazy = Lazy::new(|| {
+ let loader = fluent_language_loader!();
+ let requested_languages = DesktopLanguageRequester::requested_languages();
+ let _ = i18n_embed::select(&loader, &Localizations, &requested_languages);
+
+ loader
+});
+pub fn language_loader() -> &'static FluentLanguageLoader {
+ &LOADER
+}
+pub fn set_language(code: IsoCode) -> Result<(), I18nEmbedError> {
+ i18n_embed::select(
+ language_loader(),
+ &Localizations,
+ &[code.to_string().parse().unwrap()],
+ )?;
+ Ok(())
+}
+
+#[macro_export]
+macro_rules! fl {
+ ($message_id:literal) => {
+ i18n_embed_fl::fl!($crate::i18n::language_loader(), $message_id)
+ };
+ ($message_id:literal, $($arg:tt)*) => {
+ i18n_embed_fl::fl!($crate::i18n::language_loader(), $message_id, $($arg)*)
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 39c1fa55..31fac287 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -95,6 +95,8 @@ pub mod steam;
pub mod graphics;
+pub mod i18n;
+
pub use luminol::Luminol;
use tabs::tab::Tab;
diff --git a/src/main.rs b/src/main.rs
index 753ecdac..e2ff240e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -25,6 +25,8 @@
// Program grant you additional permission to convey the resulting work.
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
+use luminol::fl;
+
fn main() {
#[cfg(feature = "steamworks")]
if let Err(e) = luminol::steam::Steamworks::setup() {
@@ -45,26 +47,32 @@ fn main() {
std::thread::sleep(std::time::Duration::from_secs(5));
let deadlocks = parking_lot::deadlock::check_deadlock();
+
if deadlocks.is_empty() {
continue;
}
rfd::MessageDialog::new()
- .set_title("Fatal Error")
+ .set_title(fl!("fatal_error"))
.set_level(rfd::MessageLevel::Error)
- .set_description(&format!(
- "Luminol has deadlocked! Please file an issue.\n{} deadlocks detected",
- deadlocks.len()
+ .set_description(fl!(
+ "deadlock_detected_description",
+ numOfDeadLocks = deadlocks.len()
))
.show();
for (i, threads) in deadlocks.iter().enumerate() {
let mut description = String::new();
for t in threads {
- writeln!(description, "Thread Id {:#?}", t.thread_id()).unwrap();
+ writeln!(
+ description,
+ "{}",
+ fl!("thread_id", id = format!("{:#?}", t.thread_id()))
+ )
+ .unwrap();
writeln!(description, "{:#?}", t.backtrace()).unwrap();
}
rfd::MessageDialog::new()
- .set_title(&format!("Deadlock #{i}"))
+ .set_title(fl!("deadlock_detected_title", deadlockIndex = i))
.set_level(rfd::MessageLevel::Error)
.set_description(&description)
.show();
@@ -111,7 +119,7 @@ fn main() {
};
eframe::run_native(
- "Luminol",
+ &fl!("luminol"),
native_options,
Box::new(|cc| Box::new(luminol::Luminol::new(cc, std::env::args_os().nth(1)))),
)
diff --git a/src/modals/switch.rs b/src/modals/switch.rs
index 4888e6d7..c50f0c08 100644
--- a/src/modals/switch.rs
+++ b/src/modals/switch.rs
@@ -22,7 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
-use crate::prelude::*;
+use crate::{fl, prelude::*};
/// The switch picker modal.
pub struct Modal {
@@ -69,7 +69,7 @@ impl modal::Modal for Modal {
fn show(&mut self, ctx: &egui::Context, open: &mut bool, data: &mut Self::Data) {
let mut win_open = true;
- egui::Window::new("Switch Picker")
+ egui::Window::new(fl!("modal_switch_title_label"))
.id(self.id)
.resizable(false)
.open(&mut win_open)
@@ -114,8 +114,8 @@ impl modal::Modal for Modal {
});
ui.horizontal(|ui| {
- *open = !ui.button("Ok").clicked();
- *open = !ui.button("Cancel").clicked();
+ *open = !ui.button(fl!("ok")).clicked();
+ *open = !ui.button(fl!("cancel")).clicked();
if ui
.add(
@@ -127,7 +127,7 @@ impl modal::Modal for Modal {
memory.1 = memory.0;
};
egui::TextEdit::singleline(&mut memory.2)
- .hint_text("Search 🔎")
+ .hint_text(format!("{} 🔎", fl!("search")))
.show(ui);
});
diff --git a/src/modals/variable.rs b/src/modals/variable.rs
index 09cdb7d2..6d478a58 100644
--- a/src/modals/variable.rs
+++ b/src/modals/variable.rs
@@ -22,7 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
-use crate::prelude::*;
+use crate::{fl, prelude::*};
/// The variable picker modal.
pub struct Modal {
@@ -71,7 +71,7 @@ impl modal::Modal for Modal {
fn show(&mut self, ctx: &egui::Context, open: &mut bool, data: &mut Self::Data) {
let mut win_open = true;
- egui::Window::new("Variable Picker")
+ egui::Window::new(fl!("modal_variable_title_label"))
.id(self.id)
.resizable(false)
.open(&mut win_open)
@@ -130,7 +130,7 @@ impl modal::Modal for Modal {
memory.1 = memory.0;
};
egui::TextEdit::singleline(&mut memory.2)
- .hint_text("Search 🔎")
+ .hint_text(format!("{} 🔎", fl!("search")))
.show(ui);
});
diff --git a/src/prelude.rs b/src/prelude.rs
index db5b7894..f90abc3d 100644
--- a/src/prelude.rs
+++ b/src/prelude.rs
@@ -71,3 +71,5 @@ pub use rmxp_types::*;
#[cfg(feature = "steamworks")]
pub use crate::steam::Steamworks;
+
+pub use crate::fl;
diff --git a/src/tabs/map.rs b/src/tabs/map.rs
index 14295b39..82a423d7 100644
--- a/src/tabs/map.rs
+++ b/src/tabs/map.rs
@@ -23,6 +23,7 @@
// Program grant you additional permission to convey the resulting work.
#![allow(unused_imports)]
+use crate::{fl, prelude::*};
use egui::Pos2;
use std::{cell::RefMut, collections::HashMap, collections::VecDeque};
@@ -318,7 +319,11 @@ impl Tab {
impl tab::Tab for Tab {
fn name(&self) -> String {
let mapinfos = state!().data_cache.mapinfos();
- format!("Map {}: {}", self.id, mapinfos[&self.id].name)
+ fl!(
+ "tab_map_title_label",
+ id = self.id,
+ name = mapinfos[&self.id].name.clone()
+ )
}
fn id(&self) -> egui::Id {
@@ -335,7 +340,7 @@ impl tab::Tab for Tab {
ui.horizontal_wrapped(|ui| {
ui.add(
egui::Slider::new(&mut self.view.scale, 15.0..=300.)
- .text("Scale")
+ .text(fl!("scale"))
.fixed_decimals(0),
);
@@ -344,15 +349,19 @@ impl tab::Tab for Tab {
ui.menu_button(
// Format the text based on what layer is selected.
match self.view.selected_layer {
- SelectedLayer::Events => "Events ⏷".to_string(),
- SelectedLayer::Tiles(layer) => format!("Layer {} ⏷", layer + 1),
+ SelectedLayer::Events => format!("{} ⏷", fl!("events")),
+ SelectedLayer::Tiles(layer) => {
+ format!("{} ⏷", fl!("tab_map_layer_section_sv", num = layer))
+ }
},
|ui| {
// TODO: Add layer enable button
// Display all layers.
ui.columns(2, |columns| {
columns[1].visuals_mut().button_frame = true;
- columns[0].label(egui::RichText::new("Panorama").underline());
+ columns[0].label(
+ egui::RichText::new(fl!("tab_map_panorama_label")).underline(),
+ );
columns[1].checkbox(&mut self.view.map.pano_enabled, "👁");
for (index, layer) in
@@ -361,7 +370,7 @@ impl tab::Tab for Tab {
columns[0].selectable_value(
&mut self.view.selected_layer,
SelectedLayer::Tiles(index),
- format!("Layer {}", index + 1),
+ fl!("tab_map_layer_section_sv", num = (index + 1)),
);
columns[1].checkbox(layer, "👁");
}
@@ -370,7 +379,7 @@ impl tab::Tab for Tab {
columns[0].selectable_value(
&mut self.view.selected_layer,
SelectedLayer::Events,
- egui::RichText::new("Events").italics(),
+ egui::RichText::new(fl!("events")).italics(),
);
columns[1].checkbox(&mut self.view.event_enabled, "👁");
@@ -382,9 +391,9 @@ impl tab::Tab for Tab {
ui.separator();
- ui.checkbox(&mut self.view.visible_display, "Display Visible Area")
+ ui.checkbox(&mut self.view.visible_display, fl!("tab_map_dva_cb"))
.on_hover_text("Display the visible area in-game (640x480)");
- ui.checkbox(&mut self.view.move_preview, "Preview event move routes")
+ ui.checkbox(&mut self.view.move_preview, fl!("tab_map_pemr_cb"))
.on_hover_text("Preview event page move routes");
ui.checkbox(&mut self.view.snap_to_grid, "Snap to grid")
.on_hover_text("Snap's the viewport to the tile grid");
@@ -399,8 +408,7 @@ impl tab::Tab for Tab {
self.tilemap.save_to_disk();
}
- if map.preview_move_route.is_some()
- && ui.button("Clear move route preview").clicked()
+ if map.preview_move_route.is_some() && ui.button(fl!("tab_map_cmrp_btn")).clicked()
{
map.preview_move_route = None;
}
diff --git a/src/tabs/started.rs b/src/tabs/started.rs
index f7002963..6f370892 100644
--- a/src/tabs/started.rs
+++ b/src/tabs/started.rs
@@ -22,7 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
-use crate::prelude::*;
+use crate::{fl, prelude::*};
/// The Luminol "get started screen" similar to vscode's.
#[derive(Default)]
@@ -44,7 +44,7 @@ impl Tab {
impl tab::Tab for Tab {
fn name(&self) -> String {
- "Get Started".to_string()
+ fl!("tab_started_title_label")
}
fn id(&self) -> egui::Id {
@@ -54,14 +54,14 @@ impl tab::Tab for Tab {
fn show(&mut self, ui: &mut egui::Ui) {
let state = state!();
ui.label(
- egui::RichText::new("Luminol")
+ egui::RichText::new(fl!("luminol"))
.size(40.)
.color(egui::Color32::LIGHT_GRAY),
);
ui.add_space(100.);
- ui.heading("Start");
+ ui.heading(fl!("start"));
if self
.load_project_promise
@@ -71,7 +71,7 @@ impl tab::Tab for Tab {
ui.spinner();
} else {
if ui
- .button(egui::RichText::new("New Project").size(20.))
+ .button(egui::RichText::new(fl!("new_project")).size(20.))
.clicked()
{
state!()
@@ -79,21 +79,19 @@ impl tab::Tab for Tab {
.add_window(crate::windows::new_project::Window::default());
}
if ui
- .button(egui::RichText::new("Open Project").size(20.))
+ .button(egui::RichText::new(fl!("open_project")).size(20.))
.clicked()
{
self.load_project_promise = Some(Promise::spawn_local(async move {
if let Err(e) = state.filesystem.spawn_project_file_picker().await {
- state
- .toasts
- .error(format!("Error loading the project: {e}"));
+ state.toasts.error(fl!("toast_error_load_proj", why = e));
}
}));
}
ui.add_space(100.);
- ui.heading("Recent");
+ ui.heading(fl!("tab_started_recent_projects_label"));
for path in &global_config!().recent_projects {
if ui.button(path).clicked() {
@@ -101,16 +99,15 @@ impl tab::Tab for Tab {
self.load_project_promise = Some(Promise::spawn_local(async move {
if let Err(why) = state.filesystem.load_project(path) {
- state
- .toasts
- .error(format!("Error loading the project: {why}"));
+ state.toasts.error(fl!("toast_error_load_proj", why = why));
} else {
- state!().toasts.info(format!(
- "Successfully opened {:?}",
- state!()
+ state!().toasts.info(fl!(
+ "toast_info_successful_load",
+ projectName = state!()
.filesystem
.project_path()
.expect("project not open")
+ .to_string()
));
}
}));
diff --git a/src/windows/about.rs b/src/windows/about.rs
index 081e0678..ad63e339 100644
--- a/src/windows/about.rs
+++ b/src/windows/about.rs
@@ -22,6 +22,8 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
+use crate::fl;
+
/// A basic about window.
/// Shows some info on Luminol, along with an icon.
pub struct Window {
@@ -42,7 +44,7 @@ impl Default for Window {
impl super::window::Window for Window {
fn name(&self) -> String {
- "About".to_string()
+ fl!("window_about_title_label")
}
fn id(&self) -> egui::Id {
@@ -51,7 +53,7 @@ impl super::window::Window for Window {
fn show(&mut self, ctx: &egui::Context, open: &mut bool) {
// Show the window. Name it "About Luminol"
- egui::Window::new("About Luminol")
+ egui::Window::new(fl!("window_about_luminol_label"))
// Open is passed in. egui sets it to false if the window is closed.
.open(open)
.resizable(false)
@@ -59,19 +61,22 @@ impl super::window::Window for Window {
// Center the widgets vertically for cleanliness.
ui.vertical_centered(|ui| {
self.icon.show_scaled(ui, 0.5); // We scale the icon down since it's pretty huge.
- ui.heading("Luminol");
+ ui.heading(fl!("luminol"));
ui.separator();
- ui.label(format!("Luminol version {}", env!("CARGO_PKG_VERSION")));
+ ui.label(fl!(
+ "window_about_version_text_label",
+ version = env!("CARGO_PKG_VERSION")
+ ));
ui.label(format!("git-rev {}", git_version::git_version!()));
ui.separator();
- ui.label("Luminol is a FOSS version of the RPG Maker XP editor.");
+ ui.label(fl!("window_about_description_text_label"));
ui.separator();
- ui.label(format!(
- "Authors: \n{}",
- env!("CARGO_PKG_AUTHORS").replace(':', "\n")
+ ui.label(fl!(
+ "window_about_authors_label",
+ authorsArray = env!("CARGO_PKG_AUTHORS").replace(':', "\n")
))
})
});
diff --git a/src/windows/common_event_edit.rs b/src/windows/common_event_edit.rs
index 7b4a972b..20cc7f50 100644
--- a/src/windows/common_event_edit.rs
+++ b/src/windows/common_event_edit.rs
@@ -22,7 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
-use crate::prelude::*;
+use crate::{fl, prelude::*};
/// The common event editor.
pub struct Window {
@@ -43,8 +43,8 @@ impl window::Window for Window {
fn name(&self) -> String {
self.tabs
.focused_name()
- .map_or("Common Events".to_string(), |name| {
- format!("Editing Common Event {name}")
+ .map_or(fl!("common_events"), |name| {
+ fl!("window_common_events_editing_label", name = name)
})
}
@@ -120,9 +120,13 @@ impl tab::Tab for CommonEventTab {
fn show(&mut self, ui: &mut egui::Ui) {
ui.horizontal(|ui| {
- let trigger_types = ["None", "Autorun", "Parallel"];
+ let trigger_types = [
+ fl!("window_common_events_type_none_sv"),
+ fl!("window_common_events_type_autorun_sv"),
+ fl!("window_common_events_type_parallel_sv"),
+ ];
egui::ComboBox::new(format!("common_event_{}_trigger", self.event.id), "Trigger")
- .selected_text(trigger_types[self.event.trigger])
+ .selected_text(trigger_types[self.event.trigger].clone())
.show_ui(ui, |ui| {
for (ele, trigger) in trigger_types.into_iter().enumerate() {
ui.selectable_value(&mut self.event.trigger, ele, trigger);
@@ -136,16 +140,16 @@ impl tab::Tab for CommonEventTab {
let mut save_event = false;
- if ui.button("Ok").clicked() {
+ if ui.button(fl!("ok")).clicked() {
save_event = true;
self.force_close = true;
}
- if ui.button("Cancel").clicked() {
+ if ui.button(fl!("cancel")).clicked() {
self.force_close = true;
}
- if ui.button("Apply").clicked() {
+ if ui.button(fl!("apply")).clicked() {
save_event = true;
}
@@ -155,7 +159,7 @@ impl tab::Tab for CommonEventTab {
common_events[self.event.id - 1] = self.event.clone();
}
- ui.label("Name");
+ ui.label(fl!("name"));
ui.text_edit_singleline(&mut self.event.name);
});
diff --git a/src/windows/config_window.rs b/src/windows/config_window.rs
index 58e5ae81..c715aee6 100644
--- a/src/windows/config_window.rs
+++ b/src/windows/config_window.rs
@@ -22,7 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
-use crate::prelude::*;
+use crate::{fl, prelude::*};
/// The confg window
pub struct Window {}
@@ -31,7 +31,7 @@ impl Window {}
impl window::Window for Window {
fn name(&self) -> String {
- "Local Luminol Config".to_string()
+ fl!("window_config_title_label")
}
fn id(&self) -> egui::Id {
@@ -42,12 +42,12 @@ impl window::Window for Window {
egui::Window::new(self.name()).open(open).show(ctx, |ui| {
let mut config = project_config!();
- ui.label("Project name");
+ ui.label(fl!("window_config_proj_name_label"));
ui.text_edit_singleline(&mut config.project_name);
- ui.label("Scripts path");
+ ui.label(fl!("window_config_scripts_path_label"));
ui.text_edit_singleline(&mut config.scripts_path);
- ui.checkbox(&mut config.use_ron, "Use RON (Rusty Object Notation)");
- egui::ComboBox::from_label("RGSS Version")
+ ui.checkbox(&mut config.use_ron, fl!("window_config_use_ron_cb"));
+ egui::ComboBox::from_label(fl!("window_config_rgss_ver_label"))
.selected_text(config.rgss_ver.to_string())
.show_ui(ui, |ui| {
for ver in config::RGSSVer::iter() {
@@ -55,7 +55,7 @@ impl window::Window for Window {
}
});
- ui.label("Playtest Executable");
+ ui.label(fl!("window_config_playtest_exe_btn"));
ui.text_edit_singleline(&mut config.playtest_exe);
});
}
diff --git a/src/windows/console.rs b/src/windows/console.rs
index 831a86db..252afe97 100644
--- a/src/windows/console.rs
+++ b/src/windows/console.rs
@@ -22,6 +22,8 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
+use crate::fl;
+
pub struct Console {
term: luminol_term::Terminal,
}
@@ -56,7 +58,7 @@ impl super::window::Window for Console {
if let Err(e) = self.term.ui(ui) {
crate::state!()
.toasts
- .error(format!("error displaying terminal: {e:?}"));
+ .error(fl!("toast_error_displaying_term", why = e.to_string()));
}
});
}
diff --git a/src/windows/event_edit.rs b/src/windows/event_edit.rs
index cf740f20..2e323e2d 100644
--- a/src/windows/event_edit.rs
+++ b/src/windows/event_edit.rs
@@ -22,7 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
-use crate::prelude::*;
+use crate::{fl, prelude::*};
/// The event editor window.
pub struct Window {
@@ -80,10 +80,10 @@ impl window::Window for Window {
ui.horizontal(|ui| {
ui.text_edit_singleline(&mut event.name);
- ui.button("New page").clicked();
- ui.button("Copy page").clicked();
- ui.button("Paste page").clicked();
- ui.button("Clear page").clicked();
+ ui.button(fl!("window_event_new_page_btn")).clicked();
+ ui.button(fl!("window_event_copy_page_btn")).clicked();
+ ui.button(fl!("window_event_paste_page_btn")).clicked();
+ ui.button(fl!("window_event_clear_page_btn")).clicked();
});
ui.separator();
@@ -102,9 +102,21 @@ impl window::Window for Window {
ui.separator();
ui.horizontal(|ui| {
- ui.selectable_value(&mut self.viewed_tab, 0, "Configuration");
- ui.selectable_value(&mut self.viewed_tab, 1, "Graphic");
- ui.selectable_value(&mut self.viewed_tab, 2, "Commands");
+ ui.selectable_value(
+ &mut self.viewed_tab,
+ 0,
+ fl!("window_event_tab_configuration_sv"),
+ );
+ ui.selectable_value(
+ &mut self.viewed_tab,
+ 1,
+ fl!("window_event_tab_graphic_sv"),
+ );
+ ui.selectable_value(
+ &mut self.viewed_tab,
+ 2,
+ fl!("window_event_tab_commands_sv"),
+ );
});
ui.separator();
@@ -115,10 +127,13 @@ impl window::Window for Window {
0 => {
ui.horizontal(|ui| {
ui.vertical(|ui| {
- ui.label("Condition");
+ ui.label(fl!("window_event_conf_condition_label"));
ui.group(|ui| {
ui.horizontal(|ui| {
- ui.checkbox(&mut page.condition.switch1_valid, "Switch");
+ ui.checkbox(
+ &mut page.condition.switch1_valid,
+ fl!("window_event_conf_switch_cb"),
+ );
ui.add_enabled_ui(page.condition.switch1_valid, |ui| {
switch::Modal::new(
@@ -137,7 +152,10 @@ impl window::Window for Window {
});
ui.horizontal(|ui| {
- ui.checkbox(&mut page.condition.switch2_valid, "Switch");
+ ui.checkbox(
+ &mut page.condition.switch2_valid,
+ fl!("window_event_conf_switch_cb"),
+ );
ui.add_enabled_ui(page.condition.switch2_valid, |ui| {
switch::Modal::new(
@@ -156,7 +174,10 @@ impl window::Window for Window {
});
ui.horizontal(|ui| {
- ui.checkbox(&mut page.condition.variable_valid, "Variable");
+ ui.checkbox(
+ &mut page.condition.variable_valid,
+ fl!("window_event_conf_variable_cb"),
+ );
ui.add_enabled_ui(page.condition.variable_valid, |ui| {
variable::Modal::new(
@@ -179,13 +200,13 @@ impl window::Window for Window {
&mut page.condition.variable_value,
),
);
- ui.label("or above");
+ ui.label(fl!("window_event_conf_or_above_label"));
});
ui.horizontal(|ui| {
ui.checkbox(
&mut page.condition.self_switch_valid,
- "Self Switch",
+ fl!("window_event_conf_self_switch_cb"),
);
ui.add_enabled_ui(page.condition.self_switch_valid, |ui| {
egui::ComboBox::new(
@@ -193,7 +214,7 @@ impl window::Window for Window {
"event_{}_{}_self_switch_combo",
self.id, self.map_id
),
- "is on",
+ fl!("window_event_conf_is_on_label"),
)
.selected_text(page.condition.self_switch_ch.clone())
.show_ui(
@@ -264,27 +285,58 @@ impl window::Window for Window {
ui.horizontal(|ui| {
ui.vertical(|ui| {
- ui.label("Options");
+ ui.label(fl!("window_event_conf_options_label"));
ui.group(|ui| {
- ui.checkbox(&mut page.step_anime, "Move Animation");
- ui.checkbox(&mut page.walk_anime, "Stop Animation");
- ui.checkbox(&mut page.direction_fix, "Direction Fix");
- ui.checkbox(&mut page.through, "Through");
- ui.checkbox(&mut page.always_on_top, "Always on Top");
+ ui.checkbox(
+ &mut page.step_anime,
+ fl!("window_event_conf_option_move_anim_cb"),
+ );
+ ui.checkbox(
+ &mut page.walk_anime,
+ fl!("window_event_conf_option_stop_anim_cb"),
+ );
+ ui.checkbox(
+ &mut page.direction_fix,
+ fl!("window_event_conf_option_direction_fix_cb"),
+ );
+ ui.checkbox(
+ &mut page.through,
+ fl!("window_event_conf_option_through_cb"),
+ );
+ ui.checkbox(
+ &mut page.always_on_top,
+ fl!("window_event_conf_option_aot_cb"),
+ );
});
});
ui.vertical(|ui| {
- ui.label("Trigger");
+ ui.label(fl!("window_event_conf_trigger_label"));
ui.group(|ui| {
- ui.radio_value(&mut page.trigger, 0, "Action Button");
- ui.radio_value(&mut page.trigger, 1, "Player Touch");
- ui.radio_value(&mut page.trigger, 2, "Event Touch");
- ui.radio_value(&mut page.trigger, 3, "Autorun");
+ ui.radio_value(
+ &mut page.trigger,
+ 0,
+ fl!("window_event_conf_trigger_action_btn_rv"),
+ );
+ ui.radio_value(
+ &mut page.trigger,
+ 1,
+ fl!("window_event_conf_trigger_player_touch_rv"),
+ );
+ ui.radio_value(
+ &mut page.trigger,
+ 2,
+ fl!("window_event_conf_trigger_event_touch_rv"),
+ );
+ ui.radio_value(
+ &mut page.trigger,
+ 3,
+ fl!("window_event_conf_trigger_autorun_rv"),
+ );
ui.radio_value(
&mut page.trigger,
4,
- "Parallel Process",
+ fl!("window_event_conf_trigger_parallel_proc_rv"),
);
});
})
@@ -314,9 +366,9 @@ impl window::Window for Window {
ui.separator();
ui.horizontal(|ui| {
- let ok_clicked = ui.button("Ok").clicked();
- let apply_clicked = ui.button("Apply").clicked();
- let cancel_clicked = ui.button("Cancel").clicked();
+ let ok_clicked = ui.button(fl!("ok")).clicked();
+ let apply_clicked = ui.button(fl!("apply")).clicked();
+ let cancel_clicked = ui.button(fl!("cancel")).clicked();
if apply_clicked || ok_clicked {
//let mut map = state!().data_cache.map(self.map_id);
diff --git a/src/windows/graphic_picker.rs b/src/windows/graphic_picker.rs
index 3d71c401..350f8fd9 100644
--- a/src/windows/graphic_picker.rs
+++ b/src/windows/graphic_picker.rs
@@ -22,7 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
-use crate::prelude::*;
+use crate::{fl, prelude::*};
pub struct Graphic {
pub name: String,
@@ -48,9 +48,11 @@ impl Window {
{
Ok(ri) => ri,
Err(why) => {
- state!()
- .toasts
- .error(format!("Cannot load `{icon_path}` icon: {why}"));
+ state!().toasts.error(fl!(
+ "toast_error_cannot_load_icon",
+ icon_path = icon_path.to_string(),
+ why = why.to_string()
+ ));
continue;
}
};
@@ -73,7 +75,7 @@ impl Window {
}
pub fn show(&mut self, ctx: &egui::Context, open: &mut bool, graphic_icon: &mut String) {
- egui::Window::new("Graphic Picker")
+ egui::Window::new(fl!("window_graphic_picker_title_label"))
.id(egui::Id::new("icon_picker"))
.resize(|res| res.min_width(480.))
.open(open)
diff --git a/src/windows/items.rs b/src/windows/items.rs
index 1f1dd1df..ab6610ee 100644
--- a/src/windows/items.rs
+++ b/src/windows/items.rs
@@ -41,7 +41,6 @@ pub struct Window {
impl Default for Window {
fn default() -> Self {
let items = state!().data_cache.items().clone();
-
Self {
items,
selected_item: 0,
@@ -56,7 +55,10 @@ impl Default for Window {
impl window::Window for Window {
fn name(&self) -> String {
- format!("Editing item {}", self.items[self.selected_item].name)
+ fl!(
+ "window_items_title_label",
+ name = self.items[self.selected_item].name.clone()
+ )
}
fn id(&self) -> egui::Id {
@@ -91,7 +93,7 @@ impl window::Window for Window {
.open(open)
.show(ctx, |ui| {
egui::SidePanel::left(egui::Id::new("item_edit_sidepanel")).show_inside(ui, |ui| {
- ui.label("Items");
+ ui.label(fl!("items"));
egui::ScrollArea::both().max_height(600.).show_rows(
ui,
ui.text_style_height(&egui::TextStyle::Body),
@@ -107,21 +109,21 @@ impl window::Window for Window {
},
);
- if ui.button("Change maximum...").clicked() {
+ if ui.button(fl!("window_items_change_max_btn")).clicked() {
eprintln!("`Change maximum...` button trigger");
}
});
let selected_item = &mut self.items[self.selected_item];
egui::Grid::new("item_edit_central_grid").show(ui, |ui| {
ui.add(Field::new(
- "Name",
+ fl!("name"),
egui::TextEdit::singleline(&mut selected_item.name),
));
ui.end_row();
ui.add(Field::new(
- "Description",
+ fl!("description"),
egui::TextEdit::singleline(&mut selected_item.description),
));
ui.end_row();
@@ -130,7 +132,7 @@ impl window::Window for Window {
});
if self.menu_se_picker_open {
- egui::Window::new("Menu Sound Effect Picker")
+ egui::Window::new(fl!("window_items_msep_label"))
.id(egui::Id::new("menu_se_picker"))
.show(ctx, |ui| {
self.menu_se_picker.ui(ui);
diff --git a/src/windows/map_picker.rs b/src/windows/map_picker.rs
index 80d01c41..e7e39d65 100644
--- a/src/windows/map_picker.rs
+++ b/src/windows/map_picker.rs
@@ -92,7 +92,7 @@ impl window::Window for Window {
fn show(&mut self, ctx: &egui::Context, open: &mut bool) {
let mut window_open = true;
- egui::Window::new("Map Picker")
+ egui::Window::new(fl!("window_map_picker_title_label"))
.open(&mut window_open)
.show(ctx, |ui| {
egui::ScrollArea::both()
@@ -113,7 +113,7 @@ impl window::Window for Window {
children_data.entry(0).or_default(); // If there is no `0` entry (i.e. there are no maps) then add one.
// Now we can actually render all maps.
- egui::CollapsingHeader::new("root")
+ egui::CollapsingHeader::new(fl!("window_map_picker_root_label"))
.default_open(true)
.show(ui, |ui| {
// There will always be a map `0`.
diff --git a/src/windows/misc.rs b/src/windows/misc.rs
index 3b4780cd..ef5c563d 100644
--- a/src/windows/misc.rs
+++ b/src/windows/misc.rs
@@ -22,6 +22,8 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
+use crate::fl;
+
use super::window::Window;
use crate::prelude::*;
/// Egui inspection window.
@@ -30,7 +32,7 @@ pub struct EguiInspection {}
impl Window for EguiInspection {
fn name(&self) -> String {
- "Egui Inspection".to_string()
+ fl!("window_egui_inspec_title_label")
}
fn id(&self) -> egui::Id {
@@ -50,7 +52,7 @@ pub struct EguiMemory {}
impl Window for EguiMemory {
fn name(&self) -> String {
- "Egui Memory".to_string()
+ fl!("window_egui_memory_title_label")
}
fn id(&self) -> egui::Id {
diff --git a/src/windows/new_project.rs b/src/windows/new_project.rs
index 7945a2b1..c111c120 100644
--- a/src/windows/new_project.rs
+++ b/src/windows/new_project.rs
@@ -22,7 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
-use crate::prelude::*;
+use crate::{fl, prelude::*};
use config::{RGSSVer, RMVer};
use std::io::Read;
@@ -52,7 +52,7 @@ struct Progress {
impl Default for Window {
fn default() -> Self {
Self {
- name: "My Project".to_string(),
+ name: fl!("window_new_proj_my_proj_str"),
rgss_ver: RGSSVer::RGSS1,
editor_ver: RMVer::XP,
project_promise: None,
@@ -66,7 +66,7 @@ impl Default for Window {
impl window::Window for Window {
fn name(&self) -> String {
- "New Project".to_string()
+ fl!("new_project")
}
fn id(&self) -> egui::Id {
@@ -79,16 +79,16 @@ impl window::Window for Window {
.open(&mut win_open)
.show(ctx, |ui| {
ui.add_enabled_ui(self.project_promise.is_none(), |ui| {
- ui.label("Project Name");
+ ui.label(fl!("window_new_proj_name_label"));
ui.text_edit_singleline(&mut self.name);
- ui.checkbox(&mut self.init_git, "Initialize with git repository");
+ ui.checkbox(&mut self.init_git, fl!("window_new_proj_with_git_cb"));
ui.add_enabled_ui(self.init_git, |ui| {
- ui.label("Git Branch");
+ ui.label(fl!("window_new_proj_git_branch_label"));
ui.text_edit_singleline(&mut self.git_branch_name);
});
- egui::ComboBox::from_label("RGSS runtime")
+ egui::ComboBox::from_label(fl!("window_new_proj_rgss_runtime_label"))
.selected_text(self.rgss_ver.to_string())
.show_ui(ui, |ui| {
for ver in RGSSVer::iter() {
@@ -102,7 +102,10 @@ impl window::Window for Window {
) {
ui.checkbox(
&mut self.download_executable,
- format!("Download latest version of {}", self.rgss_ver),
+ fl!(
+ "window_new_proj_with_exe_download_cb",
+ variant = self.rgss_ver.to_string()
+ ),
);
}
});
@@ -115,19 +118,20 @@ impl window::Window for Window {
match res {
Ok(_) => *open = false,
Err(e) => {
- state!()
- .toasts
- .error(format!("Failed to create project: {e}"));
+ state!().toasts.error(fl!(
+ "toast_error_creating_proj",
+ why = e.to_string()
+ ));
self.project_promise = None;
}
}
}
if self.progress.zip_total.load(Ordering::Relaxed) != 0 {
- ui.label(format!(
- "Downloadind & Unzipping {}/{}",
- self.progress.zip_current.load(Ordering::Relaxed) + 1,
- self.progress.zip_total.load(Ordering::Relaxed)
+ ui.label(fl!(
+ "window_new_proj_dl_and_unzipping_label",
+ current = (self.progress.zip_current.load(Ordering::Relaxed) + 1),
+ total = self.progress.zip_total.load(Ordering::Relaxed)
));
}
@@ -145,7 +149,7 @@ impl window::Window for Window {
});
}
} else {
- if ui.button("Ok").clicked() {
+ if ui.button(fl!("ok")).clicked() {
let rgss_ver = self.rgss_ver;
let config = config::project::Config {
project_name: self.name.clone(),
@@ -180,13 +184,15 @@ impl window::Window for Window {
{
Ok(mut c) => {
if let Err(e) = c.wait() {
- state.toasts.error(format!(
- "Failed to initialize git repository {e}"
+ state.toasts.error(fl!(
+ "toast_error_init_git",
+ why = e.to_string()
));
}
}
- Err(e) => state.toasts.error(format!(
- "Failed to initialize git repository {e}"
+ Err(e) => state.toasts.error(fl!(
+ "toast_error_init_git",
+ why = e.to_string()
)),
}
}
@@ -202,7 +208,7 @@ impl window::Window for Window {
result
}));
}
- if ui.button("Cancel").clicked() {
+ if ui.button(fl!("cancel")).clicked() {
*open = false;
}
}
@@ -249,16 +255,29 @@ impl Window {
progress.zip_current.store(index, Ordering::Relaxed);
progress.total_progress.store(0, Ordering::Relaxed);
- let mut response =
- zip_response.map_err(|e| format!("Error downloading {rgss_ver}: {e}"))?;
-
- let bytes = response
- .body_bytes()
- .await
- .map_err(|e| format!("Error getting response body for {rgss_ver}: {e}"))?;
-
- let mut archive = zip::ZipArchive::new(std::io::Cursor::new(bytes))
- .map_err(|e| format!("Failed to read zip archive for {rgss_ver}: {e}"))?;
+ let mut response = zip_response.map_err(|e| {
+ fl!(
+ "toast_error_downloading_rgss",
+ variant = rgss_ver.to_string(),
+ why = e.to_string()
+ )
+ })?;
+
+ let bytes = response.body_bytes().await.map_err(|e| {
+ fl!(
+ "toast_error_getting_body_resp",
+ variant = rgss_ver.to_string(),
+ why = e.to_string()
+ )
+ })?;
+
+ let mut archive = zip::ZipArchive::new(std::io::Cursor::new(bytes)).map_err(|e| {
+ fl!(
+ "toast_error_read_zip",
+ variant = rgss_ver.to_string(),
+ why = e.to_string()
+ )
+ })?;
progress
.total_progress
.store(archive.len(), Ordering::Relaxed);
@@ -276,9 +295,10 @@ impl Window {
let file_path = file_path
.strip_prefix("mkxp-z_2.4.0/")
.unwrap_or(&file_path);
- let file_path = file_path
- .to_str()
- .ok_or(format!("Invalid file path {file_path:#?}"))?;
+ let file_path = file_path.to_str().ok_or(fl!(
+ "toast_error_invalid_file_path",
+ file_path = file_path.to_string_lossy()
+ ))?;
if file_path.is_empty()
|| state
@@ -290,19 +310,31 @@ impl Window {
}
if file.is_dir() {
- state
- .filesystem
- .create_dir(file_path)
- .map_err(|e| format!("Failed to create directory {file_path}: {e}"))?;
+ state.filesystem.create_dir(file_path).map_err(|e| {
+ fl!(
+ "toast_error_create_dir",
+ file_path = file_path,
+ why = e.to_string()
+ )
+ })?;
} else {
let mut bytes = Vec::new();
file.read_to_end(&mut bytes)
.map_err(|e| e.to_string())
- .map_err(|e| format!("Failed to read file data {file_path}: {e}"))?;
- state
- .filesystem
- .write(file_path, bytes)
- .map_err(|e| format!("Failed to save file data {file_path}: {e}"))?;
+ .map_err(|e| {
+ fl!(
+ "toast_error_reading_file_data",
+ file_path = file_path,
+ why = e
+ )
+ })?;
+ state.filesystem.write(file_path, bytes).map_err(|e| {
+ fl!(
+ "toast_error_saving_file_data",
+ file_path = file_path,
+ why = e.to_string()
+ )
+ })?;
}
}
}
diff --git a/src/windows/script_edit.rs b/src/windows/script_edit.rs
index 3d637794..d8378ae0 100644
--- a/src/windows/script_edit.rs
+++ b/src/windows/script_edit.rs
@@ -41,8 +41,8 @@ impl window::Window for Window {
fn name(&self) -> String {
self.tabs
.focused_name()
- .map_or("Scripts".to_string(), |name| {
- format!("Editing Script {name}")
+ .map_or(fl!("window_script_editor_fallback_title_label"), |name| {
+ fl!("window_script_editor_title_label", name = name)
})
}
@@ -69,12 +69,18 @@ impl window::Window for Window {
let response = ui
.text_edit_singleline(&mut script.name)
.context_menu(|ui| {
- if ui.button("Insert").clicked() {
+ if ui
+ .button(fl!("window_script_editor_insert_btn"))
+ .clicked()
+ {
insert_index = Some(index);
}
ui.add_enabled_ui(scripts_len > 1, |ui| {
- if ui.button("Delete").clicked() {
+ if ui
+ .button(fl!("window_script_editor_delete_btn"))
+ .clicked()
+ {
del_index = Some(index);
}
});
@@ -90,7 +96,7 @@ impl window::Window for Window {
scripts.insert(
index,
rpg::Script {
- name: "New Script".to_string(),
+ name: fl!("window_script_editor_new_str"),
script_text: String::new(),
},
);
@@ -142,16 +148,16 @@ impl tab::Tab for ScriptTab {
ui.horizontal(|ui| {
let mut save_script = false;
- if ui.button("Ok").clicked() {
+ if ui.button(fl!("ok")).clicked() {
save_script = true;
self.force_close = true;
}
- if ui.button("Cancel").clicked() {
+ if ui.button(fl!("cancel")).clicked() {
self.force_close = true;
}
- if ui.button("Apply").clicked() {
+ if ui.button(fl!("apply")).clicked() {
save_script = true;
}
diff --git a/src/windows/sound_test.rs b/src/windows/sound_test.rs
index bc0edd3a..a3930f7a 100644
--- a/src/windows/sound_test.rs
+++ b/src/windows/sound_test.rs
@@ -22,7 +22,7 @@
// terms of the Steamworks API by Valve Corporation, the licensors of this
// Program grant you additional permission to convey the resulting work.
-use crate::prelude::*;
+use crate::{fl, prelude::*};
/// A tab for a sound (be it BGM, ME, SE, etc)
/// Optionally can be in 'picker' mode to pick a sound effect.
@@ -60,7 +60,9 @@ impl SoundTab {
.show_inside(ui, |ui| {
ui.vertical(|ui| {
ui.horizontal(|ui| {
- if ui.button("Play").clicked() && !self.selected_track.as_str().is_empty() {
+ if ui.button(fl!("window_sound_test_play_btn")).clicked()
+ && !self.selected_track.as_str().is_empty()
+ {
let path = format!("Audio/{}/{}", self.source, &self.selected_track);
let pitch = self.pitch;
let volume = self.volume;
@@ -72,7 +74,7 @@ impl SoundTab {
}
}
- if ui.button("Stop").clicked() {
+ if ui.button(fl!("window_sound_test_stop_btn")).clicked() {
// Stop sound.
state!().audio.stop(&self.source);
}
@@ -85,7 +87,7 @@ impl SoundTab {
.add(
egui::Slider::new(&mut self.volume, 0..=100)
.orientation(egui::SliderOrientation::Vertical)
- .text("Volume"),
+ .text(fl!("window_sound_test_volume_label")),
)
.changed()
{
@@ -97,7 +99,7 @@ impl SoundTab {
.add(
egui::Slider::new(&mut self.pitch, 50..=150)
.orientation(egui::SliderOrientation::Vertical)
- .text("Pitch"),
+ .text(fl!("window_sound_test_pitch_label")),
)
.changed()
{
@@ -107,8 +109,8 @@ impl SoundTab {
if self.picker {
ui.horizontal(|ui| {
- if ui.button("Cancel").clicked() {}
- if ui.button("Ok").clicked() {}
+ if ui.button(fl!("cancel")).clicked() {}
+ if ui.button(fl!("ok")).clicked() {}
});
}
});
@@ -184,31 +186,33 @@ impl super::window::Window for Window {
}
fn show(&mut self, ctx: &egui::Context, open: &mut bool) {
- egui::Window::new("Sound Test").open(open).show(ctx, |ui| {
- egui::TopBottomPanel::top("sound_test_selector").show_inside(ui, |ui| {
- // Display the tab selector.
- ui.horizontal_wrapped(|ui| {
- for source in &self.sources {
- if ui
- .selectable_label(
- source.source == self.selected_source,
- source.source.to_string(),
- )
- .clicked()
- {
- self.selected_source = source.source;
+ egui::Window::new(fl!("window_sound_test_title_label"))
+ .open(open)
+ .show(ctx, |ui| {
+ egui::TopBottomPanel::top("sound_test_selector").show_inside(ui, |ui| {
+ // Display the tab selector.
+ ui.horizontal_wrapped(|ui| {
+ for source in &self.sources {
+ if ui
+ .selectable_label(
+ source.source == self.selected_source,
+ source.source.to_string(),
+ )
+ .clicked()
+ {
+ self.selected_source = source.source;
+ }
}
- }
- })
- });
+ })
+ });
- // We should be finding something. The unwrap is safe here.
- self.sources
- .iter_mut()
- .find(|t| t.source == self.selected_source)
- .unwrap()
- .ui(ui);
- });
+ // We should be finding something. The unwrap is safe here.
+ self.sources
+ .iter_mut()
+ .find(|t| t.source == self.selected_source)
+ .unwrap()
+ .ui(ui);
+ });
}
// Technically we don't need the cache, but we do rely on the project being open.
diff --git a/src/windows/window.rs b/src/windows/window.rs
index d4e2c8ea..3b562aee 100644
--- a/src/windows/window.rs
+++ b/src/windows/window.rs
@@ -24,6 +24,8 @@
use parking_lot::Mutex;
+use crate::fl;
+
/// A window management system to handle heap allocated windows
///
/// Will deny any duplicated window titles and is not specialized like modals
@@ -77,7 +79,7 @@ pub trait Window {
/// Optionally used as the title of the window.
fn name(&self) -> String {
- "Untitled Window".to_string()
+ fl!("window_untitled_title")
}
/// Required to prevent duplication.