aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock330
-rw-r--r--Cargo.toml12
-rw-r--r--src/actions.rs4
-rw-r--r--src/dialogs.rs12
-rw-r--r--src/file_registry.rs8
-rw-r--r--src/main.rs246
-rw-r--r--src/preferences/pages/general.rs6
-rw-r--r--src/preferences/window.rs6
8 files changed, 377 insertions, 247 deletions
diff --git a/Cargo.lock b/Cargo.lock
index f348292..7b9c063 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -24,6 +24,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
+name = "anyhow"
+version = "1.0.102"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
+
+[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -147,23 +153,23 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "dirs"
-version = "5.0.1"
+version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
+checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
-version = "0.4.1"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
+checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users",
- "windows-sys 0.48.0",
+ "windows-sys",
]
[[package]]
@@ -201,7 +207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
- "windows-sys 0.61.2",
+ "windows-sys",
]
[[package]]
@@ -209,6 +215,9 @@ name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
+dependencies = [
+ "getrandom 0.2.16",
+]
[[package]]
name = "field-offset"
@@ -244,13 +253,13 @@ checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
[[package]]
name = "flume"
-version = "0.11.1"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095"
+checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be"
dependencies = [
+ "fastrand",
"futures-core",
"futures-sink",
- "nanorand",
"spin",
]
@@ -475,8 +484,21 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
- "r-efi",
+ "r-efi 5.3.0",
+ "wasip2",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi 6.0.0",
"wasip2",
+ "wasip3",
]
[[package]]
@@ -526,7 +548,7 @@ dependencies = [
"gobject-sys",
"libc",
"system-deps",
- "windows-sys 0.61.2",
+ "windows-sys",
]
[[package]]
@@ -791,6 +813,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35e6d558e6d4c7b82bc51d9c771e7a927862a161a7d87bf2b0541450e0e20915"
[[package]]
+name = "id-arena"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
+
+[[package]]
name = "indexmap"
version = "2.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -798,6 +826,8 @@ checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
dependencies = [
"equivalent",
"hashbrown 0.16.1",
+ "serde",
+ "serde_core",
]
[[package]]
@@ -832,6 +862,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
+name = "leb128fmt"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
+
+[[package]]
name = "libadwaita"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -929,7 +965,7 @@ dependencies = [
[[package]]
name = "map"
-version = "1.0.1"
+version = "1.0.2"
dependencies = [
"cairo-rs",
"dirs",
@@ -949,9 +985,9 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.7.6"
+version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "memoffset"
@@ -973,15 +1009,6 @@ dependencies = [
]
[[package]]
-name = "nanorand"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
-dependencies = [
- "getrandom 0.2.16",
-]
-
-[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1084,6 +1111,16 @@ dependencies = [
]
[[package]]
+name = "prettyplease"
+version = "0.2.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
+dependencies = [
+ "proc-macro2",
+ "syn",
+]
+
+[[package]]
name = "proc-macro-crate"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1127,6 +1164,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
+name = "r-efi"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
+
+[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1178,13 +1221,13 @@ dependencies = [
[[package]]
name = "redox_users"
-version = "0.4.6"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
+checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
dependencies = [
"getrandom 0.2.16",
"libredox",
- "thiserror 1.0.69",
+ "thiserror",
]
[[package]]
@@ -1218,9 +1261,9 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
[[package]]
name = "relm4"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6bae902de22fd92e62641f047975abf228573425b9b8de175e8ab5b6cda10379"
+checksum = "1701679d08c984064e3e920f52ae10c8a0b522eeee223625622b23c27008a472"
dependencies = [
"flume",
"fragile",
@@ -1236,9 +1279,9 @@ dependencies = [
[[package]]
name = "relm4-components"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3155d84425d33cdc62929ed2c79bfcfdcb2fff6340c5f7041ed24b56577c9d57"
+checksum = "7051ebd4c79fd7cb37dadcb4b54573a327c6cfed0da9d326e84fb68da95a5564"
dependencies = [
"once_cell",
"relm4",
@@ -1253,9 +1296,9 @@ checksum = "37dbe7a114855a22618f0e13595ce6b3f165478c13c2dfc4f4f99614da105797"
[[package]]
name = "relm4-icons"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28869f8322ed72bed568cbb704403037ff62a66c966ded7a862ad5732f108530"
+checksum = "98d855c42d60cec35fbdf0217e2c3606fe3f8ee000fe7371c5c87e05e37e79de"
dependencies = [
"gtk4",
]
@@ -1274,9 +1317,9 @@ dependencies = [
[[package]]
name = "relm4-macros"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "175fce497fc6f11dde7ea56daa30ff7ad29a534bbc209d59d766659c880ba5f1"
+checksum = "25edbb5b2e8126975f1dd8e85c48cd310afc150beed0dc97df22247b3243971e"
dependencies = [
"proc-macro2",
"quote",
@@ -1325,7 +1368,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.61.2",
+ "windows-sys",
]
[[package]]
@@ -1501,9 +1544,9 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
[[package]]
name = "syn"
-version = "2.0.111"
+version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
+checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
@@ -1545,16 +1588,7 @@ dependencies = [
"getrandom 0.3.4",
"once_cell",
"rustix",
- "windows-sys 0.61.2",
-]
-
-[[package]]
-name = "thiserror"
-version = "1.0.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
-dependencies = [
- "thiserror-impl 1.0.69",
+ "windows-sys",
]
[[package]]
@@ -1563,18 +1597,7 @@ version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
dependencies = [
- "thiserror-impl 2.0.17",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "thiserror-impl",
]
[[package]]
@@ -1706,12 +1729,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
[[package]]
+name = "unicode-xid"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+
+[[package]]
name = "uuid"
-version = "1.19.0"
+version = "1.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
+checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37"
dependencies = [
- "getrandom 0.3.4",
+ "getrandom 0.4.2",
"js-sys",
"serde_core",
"wasm-bindgen",
@@ -1745,7 +1774,16 @@ version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
dependencies = [
- "wit-bindgen",
+ "wit-bindgen 0.46.0",
+]
+
+[[package]]
+name = "wasip3"
+version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
+dependencies = [
+ "wit-bindgen 0.51.0",
]
[[package]]
@@ -1794,6 +1832,40 @@ dependencies = [
]
[[package]]
+name = "wasm-encoder"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
+dependencies = [
+ "leb128fmt",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasm-metadata"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
+dependencies = [
+ "anyhow",
+ "indexmap",
+ "wasm-encoder",
+ "wasmparser",
+]
+
+[[package]]
+name = "wasmparser"
+version = "0.244.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
+dependencies = [
+ "bitflags",
+ "hashbrown 0.15.5",
+ "indexmap",
+ "semver",
+]
+
+[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1815,7 +1887,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
- "windows-sys 0.61.2",
+ "windows-sys",
]
[[package]]
@@ -1832,15 +1904,6 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
-dependencies = [
- "windows-targets",
-]
-
-[[package]]
-name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
@@ -1849,76 +1912,107 @@ dependencies = [
]
[[package]]
-name = "windows-targets"
-version = "0.48.5"
+name = "winnow"
+version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "memchr",
]
[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.48.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.48.5"
+name = "wit-bindgen"
+version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
[[package]]
-name = "windows_i686_msvc"
-version = "0.48.5"
+name = "wit-bindgen"
+version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
+dependencies = [
+ "wit-bindgen-rust-macro",
+]
[[package]]
-name = "windows_x86_64_gnu"
-version = "0.48.5"
+name = "wit-bindgen-core"
+version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
+dependencies = [
+ "anyhow",
+ "heck",
+ "wit-parser",
+]
[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.48.5"
+name = "wit-bindgen-rust"
+version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
+dependencies = [
+ "anyhow",
+ "heck",
+ "indexmap",
+ "prettyplease",
+ "syn",
+ "wasm-metadata",
+ "wit-bindgen-core",
+ "wit-component",
+]
[[package]]
-name = "windows_x86_64_msvc"
-version = "0.48.5"
+name = "wit-bindgen-rust-macro"
+version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
+dependencies = [
+ "anyhow",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wit-bindgen-core",
+ "wit-bindgen-rust",
+]
[[package]]
-name = "winnow"
-version = "0.7.14"
+name = "wit-component"
+version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
+checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
dependencies = [
- "memchr",
+ "anyhow",
+ "bitflags",
+ "indexmap",
+ "log",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "wasm-encoder",
+ "wasm-metadata",
+ "wasmparser",
+ "wit-parser",
]
[[package]]
-name = "wit-bindgen"
-version = "0.46.0"
+name = "wit-parser"
+version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
+checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
+dependencies = [
+ "anyhow",
+ "id-arena",
+ "indexmap",
+ "log",
+ "semver",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "unicode-xid",
+ "wasmparser",
+]
[[package]]
name = "wmap-parser"
@@ -1937,7 +2031,7 @@ dependencies = [
"once_cell",
"rustc-hash",
"tempfile",
- "thiserror 2.0.17",
+ "thiserror",
"wmap-parser",
]
diff --git a/Cargo.toml b/Cargo.toml
index ced84c2..5299cc3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,16 +9,16 @@ authors = ["Rubén Beltrán del Río <wmap@r.bdr.sh>"]
[dependencies]
cairo-rs = "0.21.5"
-dirs = "5.0"
+dirs = "6.0"
gettext-rs = { version = "0.7", features = ["gettext-system"] }
-relm4 = { version = "0.10.0", features = ["gnome_48", "libadwaita"] }
-relm4-components = "0.10.0"
-relm4-icons = "0.10.0"
-relm4-macros = "0.10.0"
+relm4 = { version = "0.10.1", features = ["gnome_48", "libadwaita"] }
+relm4-components = "0.10.1"
+relm4-icons = "0.10.1"
+relm4-macros = "0.10.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
sourceview5 = "0.10.0"
-uuid = { version = "1.0", features = ["v4", "serde"] }
+uuid = { version = "1.22", features = ["v4", "serde"] }
wmap-parser = "1.0.0"
wmap-renderer = "1.1.0"
diff --git a/src/actions.rs b/src/actions.rs
index fdea125..1d60820 100644
--- a/src/actions.rs
+++ b/src/actions.rs
@@ -60,6 +60,10 @@ pub enum Action {
MarkInitialized,
CloseWindow,
+ // Layout Transition
+ DisableHorizontalLayout,
+ EnableHorizontalLayout,
+
// Preferences
ShowPreferences,
PreferencesChanged(UserPreferences),
diff --git a/src/dialogs.rs b/src/dialogs.rs
index 242f3d6..22b12df 100644
--- a/src/dialogs.rs
+++ b/src/dialogs.rs
@@ -20,7 +20,7 @@ use std::path::PathBuf;
use gtk::prelude::*;
use relm4::gtk::gio;
-use relm4::{ComponentSender, gtk};
+use relm4::{ComponentSender, adw, gtk};
use crate::AppModel;
use crate::actions::{Action, ImageFormat};
@@ -38,7 +38,7 @@ pub fn create_file_filter() -> gtk::FileFilter {
}
/// Shows an error dialog with the given title and message.
-pub fn show_error(window: &gtk::Window, title: &str, message: &str) {
+pub fn show_error(window: &adw::Window, title: &str, message: &str) {
let dialog = gtk::AlertDialog::builder()
.modal(true)
.buttons([&tr!("dialog.action.cancel"), "Ok"])
@@ -50,7 +50,7 @@ pub fn show_error(window: &gtk::Window, title: &str, message: &str) {
/// Shows a file open dialog and handles the response.
pub fn show_open_dialog(
- window: &gtk::Window,
+ window: &adw::Window,
is_empty_document: bool,
sender: ComponentSender<AppModel>,
) {
@@ -86,7 +86,7 @@ pub fn show_open_dialog(
/// Shows a file save dialog and handles the response.
pub fn show_save_dialog(
- window: &gtk::Window,
+ window: &adw::Window,
current_file: Option<&PathBuf>,
close_after: bool,
sender: ComponentSender<AppModel>,
@@ -127,7 +127,7 @@ pub fn show_save_dialog(
/// Shows a dialog asking whether to save unsaved changes before closing.
pub fn show_unsaved_changes_dialog(
- window: &gtk::Window,
+ window: &adw::Window,
current_file: Option<PathBuf>,
sender: ComponentSender<AppModel>,
) {
@@ -184,7 +184,7 @@ fn create_image_filter(format: ImageFormat) -> gtk::FileFilter {
/// Shows an export image dialog and handles the response.
pub fn show_export_dialog(
- window: &gtk::Window,
+ window: &adw::Window,
current_file: Option<&PathBuf>,
sender: ComponentSender<AppModel>,
) {
diff --git a/src/file_registry.rs b/src/file_registry.rs
index 749697d..188e1fe 100644
--- a/src/file_registry.rs
+++ b/src/file_registry.rs
@@ -21,7 +21,7 @@ use std::cell::RefCell;
use std::path::PathBuf;
use relm4::component::Controller;
-use relm4::gtk;
+use relm4::{adw};
use crate::AppModel;
use crate::actions::Action;
@@ -31,7 +31,7 @@ thread_local! {
static WINDOW_CONTROLLERS: RefCell<Vec<Controller<AppModel>>> = const { RefCell::new(Vec::new()) };
/// Tracks which files are currently open to prevent duplicate windows.
- static OPEN_FILES: RefCell<Vec<(PathBuf, gtk::Window)>> = const { RefCell::new(Vec::new()) };
+ static OPEN_FILES: RefCell<Vec<(PathBuf, adw::Window)>> = const { RefCell::new(Vec::new()) };
/// Stores senders for all windows (including main window) to enable broadcasting.
static WINDOW_SENDERS: RefCell<Vec<relm4::Sender<Action>>> = const { RefCell::new(Vec::new()) };
@@ -45,7 +45,7 @@ pub fn store_controller(controller: Controller<AppModel>) {
}
/// Returns the window that has the given file open, if any.
-pub fn find_window_for_file(path: &PathBuf) -> Option<gtk::Window> {
+pub fn find_window_for_file(path: &PathBuf) -> Option<adw::Window> {
OPEN_FILES.with_borrow(|files| {
files
.iter()
@@ -55,7 +55,7 @@ pub fn find_window_for_file(path: &PathBuf) -> Option<gtk::Window> {
}
/// Registers a file as being open in the given window.
-pub fn register_file(path: &PathBuf, window: &gtk::Window) {
+pub fn register_file(path: &PathBuf, window: &adw::Window) {
OPEN_FILES.with_borrow_mut(|files| {
if !files.iter().any(|(file_path, _)| file_path == path) {
files.push((path.clone(), window.clone()));
diff --git a/src/main.rs b/src/main.rs
index 41d3f68..e1d3bc9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -47,8 +47,9 @@ use relm4::{
Component, ComponentController, ComponentParts, ComponentSender, RelmApp, RelmWidgetExt,
SimpleComponent,
actions::{AccelsPlus, ActionablePlus, RelmAction, RelmActionGroup},
- gtk,
+ gtk, adw
};
+use adw::prelude::*;
use sourceview5::LanguageManager;
use sourceview5::prelude::*;
use stages::{ALL_STAGE_TYPES, LocalizedStageType};
@@ -88,105 +89,12 @@ macro_rules! register_action {
let action: RelmAction<$action_type> = RelmAction::new_stateless(move |_| {
sender.input($message);
});
- $group.add_action(action);
+ $group.add_action(action.clone());
$app.set_accelerators_for_action::<$action_type>($accelerators);
+ action
}};
}
-fn setup_actions(window: &gtk::Window, sender: &ComponentSender<AppModel>) {
- let application = relm4::main_application();
- let mut action_group = RelmActionGroup::<WindowActionGroup>::new();
-
- register_action!(
- action_group,
- application,
- sender,
- ZoomInAction,
- Action::ZoomIn,
- &["<Primary>equal", "<Primary>plus"]
- );
- register_action!(
- action_group,
- application,
- sender,
- ZoomOutAction,
- Action::ZoomOut,
- &["<Primary>minus"]
- );
- register_action!(
- action_group,
- application,
- sender,
- ChangeOrientationAction,
- Action::ChangeOrientation,
- &["<Primary>l"]
- );
- register_action!(
- action_group,
- application,
- sender,
- ExportImageAction,
- Action::ExportImage,
- &["<Primary>e"]
- );
- register_action!(
- action_group,
- application,
- sender,
- NewAction,
- Action::New,
- &["<Primary>n"]
- );
- register_action!(
- action_group,
- application,
- sender,
- SaveAction,
- Action::Save { close_after: false },
- &["<Primary>s"]
- );
- register_action!(
- action_group,
- application,
- sender,
- SaveAsAction,
- Action::SaveAs { close_after: false },
- &["<Primary><Shift>s"]
- );
- register_action!(
- action_group,
- application,
- sender,
- OpenAction,
- Action::Open,
- &["<Primary>o"]
- );
- register_action!(
- action_group,
- application,
- sender,
- CloseAction,
- Action::CloseWindow,
- &["<Primary>w"]
- );
- register_action!(
- action_group,
- application,
- sender,
- PreferencesAction,
- Action::ShowPreferences,
- &["<Primary>comma"]
- );
-
- let sender = sender.clone();
- let action: RelmAction<NewFromTemplateAction> =
- RelmAction::new_with_target_value(move |_, template_id| {
- sender.input(Action::NewFromTemplateById(template_id));
- });
- action_group.add_action(action);
- action_group.register_for_widget(window);
-}
-
struct AppInit {
zoom: f64,
file_path: Option<PathBuf>,
@@ -211,12 +119,14 @@ struct AppModel {
modified: bool,
pending_load_events: RefCell<u32>,
initialized: bool,
- window: gtk::Window,
+ window: adw::Window,
preferences: preferences::UserPreferences,
preferences_window: Option<relm4::Controller<preferences::PreferencesWindow>>,
editor_css_provider: gtk::CssProvider,
templates_menu: gio::Menu,
main_menu: gio::Menu,
+ horizontal_layout_enabled: bool,
+ layout_action: RelmAction<ChangeOrientationAction>
}
impl AppModel {
@@ -487,7 +397,7 @@ impl SimpleComponent for AppModel {
view! {
#[root]
- gtk::Window {
+ adw::Window {
#[watch]
set_title: Some(&model.window_title()),
set_default_width: constants::DEFAULT_WINDOW_WIDTH,
@@ -497,10 +407,8 @@ impl SimpleComponent for AppModel {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 0,
- gtk::HeaderBar {
- pack_start = &gtk::Box {
- set_orientation: gtk::Orientation::Horizontal,
-
+ adw::HeaderBar {
+ pack_start = &adw::ToolbarView {
gtk::Button::with_label(&match model.orientation {
gtk::Orientation::Horizontal => tr!("command.view.use_vertical_layout"),
_ => tr!("command.view.use_horizontal_layout")
@@ -510,11 +418,12 @@ impl SimpleComponent for AppModel {
gtk::Orientation::Horizontal => SPLIT_VERTICAL_REGULAR,
_ => SPLIT_HORIZONTAL_REGULAR
},
+ #[watch]
+ set_visible: model.horizontal_layout_enabled,
ActionablePlus::set_stateless_action::<ChangeOrientationAction>: &(),
}
},
- pack_end = &gtk::Box {
- set_orientation: gtk::Orientation::Horizontal,
+ pack_end = &adw::ToolbarView {
gtk::Button::with_label(&tr!("command.file.export")) {
set_icon_name: IMAGE_REGULAR,
@@ -540,7 +449,7 @@ impl SimpleComponent for AppModel {
gtk::Paned {
#[watch]
- set_orientation: model.orientation,
+ set_orientation: if model.horizontal_layout_enabled { model.orientation } else { gtk::Orientation::Vertical },
set_expand: true,
#[wrap(Some)]
@@ -623,8 +532,6 @@ impl SimpleComponent for AppModel {
let (source, initial_content, current_file) = Self::init_source_buffer(&init, &sender);
- setup_actions(&root, &sender);
-
let source_view = sourceview5::View::with_buffer(&source);
source_view.set_monospace(true);
@@ -648,6 +555,100 @@ impl SimpleComponent for AppModel {
let prefs = preferences::storage::load();
let (templates_menu, main_menu) = Self::init_main_menu(&prefs);
+ // Actions
+
+ let application = relm4::main_application();
+ let mut action_group = RelmActionGroup::<WindowActionGroup>::new();
+
+ register_action!(
+ action_group,
+ application,
+ sender,
+ ZoomInAction,
+ Action::ZoomIn,
+ &["<Primary>equal", "<Primary>plus"]
+ );
+ register_action!(
+ action_group,
+ application,
+ sender,
+ ZoomOutAction,
+ Action::ZoomOut,
+ &["<Primary>minus"]
+ );
+ let layout_action = register_action!(
+ action_group,
+ application,
+ sender,
+ ChangeOrientationAction,
+ Action::ChangeOrientation,
+ &["<Primary>l"]
+ );
+ register_action!(
+ action_group,
+ application,
+ sender,
+ ExportImageAction,
+ Action::ExportImage,
+ &["<Primary>e"]
+ );
+ register_action!(
+ action_group,
+ application,
+ sender,
+ NewAction,
+ Action::New,
+ &["<Primary>n"]
+ );
+ register_action!(
+ action_group,
+ application,
+ sender,
+ SaveAction,
+ Action::Save { close_after: false },
+ &["<Primary>s"]
+ );
+ register_action!(
+ action_group,
+ application,
+ sender,
+ SaveAsAction,
+ Action::SaveAs { close_after: false },
+ &["<Primary><Shift>s"]
+ );
+ register_action!(
+ action_group,
+ application,
+ sender,
+ OpenAction,
+ Action::Open,
+ &["<Primary>o"]
+ );
+ register_action!(
+ action_group,
+ application,
+ sender,
+ CloseAction,
+ Action::CloseWindow,
+ &["<Primary>w"]
+ );
+ register_action!(
+ action_group,
+ application,
+ sender,
+ PreferencesAction,
+ Action::ShowPreferences,
+ &["<Primary>comma"]
+ );
+
+ let sender_clone = sender.clone();
+ let action: RelmAction<NewFromTemplateAction> =
+ RelmAction::new_with_target_value(move |_, template_id| {
+ sender_clone.input(Action::NewFromTemplateById(template_id));
+ });
+ action_group.add_action(action);
+ action_group.register_for_widget(&root);
+
let mut model = AppModel {
orientation: gtk::Orientation::Horizontal,
stage_type_list,
@@ -672,6 +673,8 @@ impl SimpleComponent for AppModel {
editor_css_provider,
templates_menu,
main_menu,
+ horizontal_layout_enabled: true,
+ layout_action
};
model.apply_preferences();
@@ -697,6 +700,23 @@ impl SimpleComponent for AppModel {
let widgets = view_output!();
+ // Breakpoints for Smaller Layouts
+ let breakpoint = adw::Breakpoint::new(
+ adw::BreakpointCondition::new_length(
+ adw::BreakpointConditionLengthType::MinWidth,
+ 440.0,
+ adw::LengthUnit::Sp
+ )
+ );
+ let sender_clone = sender.clone();
+ breakpoint.connect_apply(move |_| {
+ sender_clone.input(Action::EnableHorizontalLayout);
+ });
+ let sender_clone = sender.clone();
+ breakpoint.connect_unapply(move |_| {
+ sender_clone.input(Action::DisableHorizontalLayout);
+ });
+ root.add_breakpoint(breakpoint);
ComponentParts { model, widgets }
}
@@ -764,6 +784,18 @@ impl SimpleComponent for AppModel {
Action::MarkInitialized => self.initialized = true,
+ // Layout Transition
+ Action::DisableHorizontalLayout => {
+ self.horizontal_layout_enabled = false;
+ self.layout_action.set_enabled(false);
+ },
+ Action::EnableHorizontalLayout => {
+ self.horizontal_layout_enabled = true;
+ self.layout_action.set_enabled(true);
+ },
+
+ // Preferences
+
Action::ShowPreferences => {
if self.preferences_window.is_none() {
let controller = preferences::PreferencesWindow::builder()
diff --git a/src/preferences/pages/general.rs b/src/preferences/pages/general.rs
index d1596c4..e65ede6 100644
--- a/src/preferences/pages/general.rs
+++ b/src/preferences/pages/general.rs
@@ -17,7 +17,7 @@
use gtk::FileFilter;
use gtk::prelude::*;
use relm4::Sender;
-use relm4::gtk;
+use relm4::{adw, gtk};
use crate::tr;
@@ -92,7 +92,7 @@ impl GeneralPage {
}
}
-pub fn show_export_dialog(sender: &Sender<PreferencesInput>, window: &gtk::Window) {
+pub fn show_export_dialog(sender: &Sender<PreferencesInput>, window: &adw::Window) {
let filter = FileFilter::new();
filter.add_pattern("*.json");
filter.set_name(Some(&tr!("dialog.file_type.json")));
@@ -118,7 +118,7 @@ pub fn show_export_dialog(sender: &Sender<PreferencesInput>, window: &gtk::Windo
});
}
-pub fn show_import_dialog(sender: &Sender<PreferencesInput>, window: &gtk::Window) {
+pub fn show_import_dialog(sender: &Sender<PreferencesInput>, window: &adw::Window) {
let filter = FileFilter::new();
filter.add_pattern("*.json");
filter.set_name(Some(&tr!("dialog.file_type.json")));
diff --git a/src/preferences/window.rs b/src/preferences/window.rs
index 0997716..b7db8c5 100644
--- a/src/preferences/window.rs
+++ b/src/preferences/window.rs
@@ -20,7 +20,7 @@
use std::path::PathBuf;
use gtk::prelude::*;
-use relm4::{ComponentParts, ComponentSender, SimpleComponent, gtk};
+use relm4::{ComponentParts, ComponentSender, SimpleComponent, adw, gtk};
use crate::tr;
@@ -85,7 +85,7 @@ pub enum PreferencesOutput {
pub struct PreferencesWindow {
preferences: UserPreferences,
- window: gtk::Window,
+ window: adw::Window,
// Widget references for pages
general_page: general::GeneralPage,
editor_page: editor::EditorPage,
@@ -101,7 +101,7 @@ impl SimpleComponent for PreferencesWindow {
type Output = PreferencesOutput;
view! {
- gtk::Window {
+ adw::Window {
set_title: Some(&tr!("preferences.title")),
set_default_width: 700,
set_default_height: 500,