summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPolesznyák Márk László <116908301+pml68@users.noreply.github.com>2024-10-24 23:18:46 +0200
committerGitHub <noreply@github.com>2024-10-24 23:18:46 +0200
commitb351dd45dcd4b4c9142f069c62b51159c00922bf (patch)
treed2f24b449c3f82a9f844ce35198bad351c2ca8af
parentMerge pull request #1 from pml68/feat/codegen (diff)
parentfeat: implement d&d for existing elements (diff)
downloadiced-builder-b351dd45dcd4b4c9142f069c62b51159c00922bf.tar.gz
Merge pull request #2 from pml68/feat/drag-and-drop
Drag & Drop done
-rw-r--r--.gitignore3
-rw-r--r--Cargo.lock1804
-rw-r--r--Cargo.toml22
-rw-r--r--iced_builder/Cargo.toml25
-rw-r--r--iced_builder/fonts/icons.ttf (renamed from fonts/icons.ttf)bin6352 -> 6352 bytes
-rw-r--r--iced_builder/src/lib.rs91
-rw-r--r--iced_builder/src/main.rs415
-rw-r--r--iced_builder/src/types/element_name.rs86
-rw-r--r--iced_builder/src/types/mod.rs9
-rw-r--r--iced_builder/src/types/project.rs137
-rwxr-xr-xiced_builder/src/types/rendered_element.rs430
-rw-r--r--iced_drop/.gitignore3
-rw-r--r--iced_drop/Cargo.toml8
-rw-r--r--iced_drop/LICENSE21
-rw-r--r--iced_drop/README.md75
-rw-r--r--iced_drop/src/lib.rs53
-rw-r--r--iced_drop/src/widget.rs2
-rw-r--r--iced_drop/src/widget/droppable.rs499
-rw-r--r--iced_drop/src/widget/operation.rs1
-rw-r--r--iced_drop/src/widget/operation/drop.rs90
-rw-r--r--src/codegen/mod.rs160
-rw-r--r--src/lib.rs0
-rw-r--r--src/main.rs301
-rw-r--r--src/types/mod.rs25
-rw-r--r--src/types/rendered_element.rs47
25 files changed, 3220 insertions, 1087 deletions
diff --git a/.gitignore b/.gitignore
index 2f7896d..9545d1d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-target/
+**/target/
+**/*.json
diff --git a/Cargo.lock b/Cargo.lock
index b519b92..d65a742 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -20,9 +20,9 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046"
[[package]]
name = "addr2line"
-version = "0.22.0"
+version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
+checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
dependencies = [
"gimli",
]
@@ -41,6 +41,17 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[package]]
name = "ahash"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "ahash"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
@@ -60,9 +71,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "android-activity"
-version = "0.5.2"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289"
+checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046"
dependencies = [
"android-properties",
"bitflags 2.6.0",
@@ -74,7 +85,7 @@ dependencies = [
"log",
"ndk",
"ndk-context",
- "ndk-sys",
+ "ndk-sys 0.6.0+11769913",
"num_enum",
"thiserror",
]
@@ -105,9 +116,9 @@ dependencies = [
[[package]]
name = "arrayref"
-version = "0.3.8"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a"
+checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
[[package]]
name = "arrayvec"
@@ -131,6 +142,182 @@ dependencies = [
]
[[package]]
+name = "ashpd"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfe7e0dd0ac5a401dc116ed9f9119cf9decc625600474cb41f0fc0a0050abc9a"
+dependencies = [
+ "async-fs",
+ "async-net",
+ "enumflags2",
+ "futures-channel",
+ "futures-util",
+ "rand",
+ "raw-window-handle",
+ "serde",
+ "serde_repr",
+ "url",
+ "wayland-backend",
+ "wayland-client",
+ "wayland-protocols",
+ "zbus",
+]
+
+[[package]]
+name = "async-broadcast"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e"
+dependencies = [
+ "event-listener",
+ "event-listener-strategy",
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-channel"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
+dependencies = [
+ "concurrent-queue",
+ "event-listener-strategy",
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-executor"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
+dependencies = [
+ "async-task",
+ "concurrent-queue",
+ "fastrand",
+ "futures-lite",
+ "slab",
+]
+
+[[package]]
+name = "async-fs"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
+dependencies = [
+ "async-lock",
+ "blocking",
+ "futures-lite",
+]
+
+[[package]]
+name = "async-io"
+version = "2.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8"
+dependencies = [
+ "async-lock",
+ "cfg-if",
+ "concurrent-queue",
+ "futures-io",
+ "futures-lite",
+ "parking",
+ "polling",
+ "rustix",
+ "slab",
+ "tracing",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "async-lock"
+version = "3.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
+dependencies = [
+ "event-listener",
+ "event-listener-strategy",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-net"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
+dependencies = [
+ "async-io",
+ "blocking",
+ "futures-lite",
+]
+
+[[package]]
+name = "async-process"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb"
+dependencies = [
+ "async-channel",
+ "async-io",
+ "async-lock",
+ "async-signal",
+ "async-task",
+ "blocking",
+ "cfg-if",
+ "event-listener",
+ "futures-lite",
+ "rustix",
+ "tracing",
+]
+
+[[package]]
+name = "async-recursion"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+]
+
+[[package]]
+name = "async-signal"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3"
+dependencies = [
+ "async-io",
+ "async-lock",
+ "atomic-waker",
+ "cfg-if",
+ "futures-core",
+ "futures-io",
+ "rustix",
+ "signal-hook-registry",
+ "slab",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "async-task"
+version = "4.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
+
+[[package]]
+name = "async-trait"
+version = "0.1.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+]
+
+[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -138,23 +325,23 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "autocfg"
-version = "1.3.0"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "backtrace"
-version = "0.3.73"
+version = "0.3.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
+checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
dependencies = [
"addr2line",
- "cc",
"cfg-if",
"libc",
- "miniz_oxide 0.7.4",
+ "miniz_oxide 0.8.0",
"object",
"rustc-demangle",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -165,12 +352,6 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
-version = "0.21.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
-
-[[package]]
-name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
@@ -234,31 +415,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]]
-name = "block-sys"
-version = "0.2.1"
+name = "block-buffer"
+version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
- "objc-sys",
+ "generic-array",
]
[[package]]
name = "block2"
-version = "0.3.0"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68"
+checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
dependencies = [
- "block-sys",
- "objc2 0.4.1",
+ "objc2",
]
[[package]]
-name = "block2"
-version = "0.5.1"
+name = "blocking"
+version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
+checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea"
dependencies = [
- "objc2 0.5.2",
+ "async-channel",
+ "async-task",
+ "futures-io",
+ "futures-lite",
+ "piper",
]
[[package]]
@@ -275,9 +459,9 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
[[package]]
name = "bytemuck"
-version = "1.17.0"
+version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31"
+checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae"
dependencies = [
"bytemuck_derive",
]
@@ -290,7 +474,7 @@ checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
@@ -301,23 +485,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bytes"
-version = "1.7.1"
+version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
-
-[[package]]
-name = "calloop"
-version = "0.12.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298"
-dependencies = [
- "bitflags 2.6.0",
- "log",
- "polling",
- "rustix",
- "slab",
- "thiserror",
-]
+checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3"
[[package]]
name = "calloop"
@@ -335,23 +505,11 @@ dependencies = [
[[package]]
name = "calloop-wayland-source"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02"
-dependencies = [
- "calloop 0.12.4",
- "rustix",
- "wayland-backend",
- "wayland-client",
-]
-
-[[package]]
-name = "calloop-wayland-source"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20"
dependencies = [
- "calloop 0.13.0",
+ "calloop",
"rustix",
"wayland-backend",
"wayland-client",
@@ -359,9 +517,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.1.14"
+version = "1.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50d2eb3cd3d1bf4529e31c215ee6f93ec5a3d536d9f578f93d9d33ee19562932"
+checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938"
dependencies = [
"jobserver",
"libc",
@@ -403,13 +561,13 @@ dependencies = [
[[package]]
name = "clipboard_macos"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "145a7f9e9b89453bc0a5e32d166456405d389cea5b578f57f1274b1397588a95"
+checksum = "9b7f4aaa047ba3c3630b080bb9860894732ff23e2aee290a418909aa6d5df38f"
dependencies = [
- "objc",
- "objc-foundation",
- "objc_id",
+ "objc2",
+ "objc2-app-kit",
+ "objc2-foundation",
]
[[package]]
@@ -508,6 +666,16 @@ dependencies = [
]
[[package]]
+name = "core-foundation"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -520,8 +688,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
dependencies = [
"bitflags 1.3.2",
- "core-foundation",
- "core-graphics-types",
+ "core-foundation 0.9.4",
+ "core-graphics-types 0.1.3",
+ "foreign-types",
+ "libc",
+]
+
+[[package]]
+name = "core-graphics"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1"
+dependencies = [
+ "bitflags 2.6.0",
+ "core-foundation 0.10.0",
+ "core-graphics-types 0.2.0",
"foreign-types",
"libc",
]
@@ -533,25 +714,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
dependencies = [
"bitflags 1.3.2",
- "core-foundation",
+ "core-foundation 0.9.4",
+ "libc",
+]
+
+[[package]]
+name = "core-graphics-types"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb"
+dependencies = [
+ "bitflags 2.6.0",
+ "core-foundation 0.10.0",
"libc",
]
[[package]]
name = "cosmic-text"
-version = "0.10.0"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75acbfb314aeb4f5210d379af45ed1ec2c98c7f1790bf57b8a4c562ac0c51b71"
+checksum = "59fd57d82eb4bfe7ffa9b1cec0c05e2fd378155b47f255a67983cb4afe0e80c2"
dependencies = [
- "fontdb",
- "libm",
+ "bitflags 2.6.0",
+ "fontdb 0.16.2",
"log",
"rangemap",
- "rustc-hash",
- "rustybuzz 0.11.0",
+ "rayon",
+ "rustc-hash 1.1.0",
+ "rustybuzz",
"self_cell",
"swash",
"sys-locale",
+ "ttf-parser 0.21.1",
"unicode-bidi",
"unicode-linebreak",
"unicode-script",
@@ -559,6 +753,15 @@ dependencies = [
]
[[package]]
+name = "cpufeatures"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -599,6 +802,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
name = "ctor-lite"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -622,12 +835,34 @@ dependencies = [
]
[[package]]
+name = "dark-light"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a76fa97167fa740dcdbfe18e8895601e1bc36525f09b044e00916e717c03a3c"
+dependencies = [
+ "dconf_rs",
+ "detect-desktop-environment",
+ "dirs",
+ "objc",
+ "rust-ini",
+ "web-sys",
+ "winreg",
+ "zbus",
+]
+
+[[package]]
name = "data-url"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
[[package]]
+name = "dconf_rs"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7046468a81e6a002061c01e6a7c83139daf91b11c30e66795b13217c2d885c8b"
+
+[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -637,6 +872,42 @@ dependencies = [
]
[[package]]
+name = "detect-desktop-environment"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21d8ad60dd5b13a4ee6bd8fa2d5d88965c597c67bce32b5fc49c94f55cb50810"
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
+[[package]]
+name = "dirs"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
+dependencies = [
+ "dirs-sys",
+]
+
+[[package]]
+name = "dirs-sys"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
+dependencies = [
+ "libc",
+ "redox_users",
+ "winapi",
+]
+
+[[package]]
name = "dispatch"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -652,12 +923,24 @@ dependencies = [
]
[[package]]
+name = "dlv-list"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
+
+[[package]]
name = "downcast-rs"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
[[package]]
+name = "dpi"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53"
+
+[[package]]
name = "drm"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -703,6 +986,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
+name = "endi"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
+
+[[package]]
+name = "enumflags2"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d"
+dependencies = [
+ "enumflags2_derive",
+ "serde",
+]
+
+[[package]]
+name = "enumflags2_derive"
+version = "0.7.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+]
+
+[[package]]
name = "equivalent"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -720,9 +1030,9 @@ dependencies = [
[[package]]
name = "error-code"
-version = "3.2.0"
+version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b"
+checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f"
[[package]]
name = "etagere"
@@ -736,14 +1046,35 @@ dependencies = [
[[package]]
name = "euclid"
-version = "0.22.10"
+version = "0.22.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0f0eb73b934648cd7a4a61f1b15391cd95dab0b4da6e2e66c2a072c144b4a20"
+checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48"
dependencies = [
"num-traits",
]
[[package]]
+name = "event-listener"
+version = "5.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba"
+dependencies = [
+ "concurrent-queue",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "event-listener-strategy"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1"
+dependencies = [
+ "event-listener",
+ "pin-project-lite",
+]
+
+[[package]]
name = "exr"
version = "1.72.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -767,24 +1098,24 @@ checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1"
[[package]]
name = "fastrand"
-version = "2.1.0"
+version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
[[package]]
name = "fdeflate"
-version = "0.3.4"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
+checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab"
dependencies = [
"simd-adler32",
]
[[package]]
name = "flate2"
-version = "1.0.32"
+version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c0596c1eac1f9e04ed902702e9878208b336edc9d6fddc8a48387349bab3666"
+checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0"
dependencies = [
"crc32fast",
"miniz_oxide 0.8.0",
@@ -832,21 +1163,35 @@ version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1fcfcd44ca6e90c921fee9fa665d530b21ef1327a4c1a6c5250ea44b776ada7"
dependencies = [
- "roxmltree 0.20.0",
+ "roxmltree",
]
[[package]]
name = "fontdb"
-version = "0.15.0"
+version = "0.16.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3"
+dependencies = [
+ "fontconfig-parser",
+ "log",
+ "memmap2",
+ "slotmap",
+ "tinyvec",
+ "ttf-parser 0.20.0",
+]
+
+[[package]]
+name = "fontdb"
+version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "020e203f177c0fb250fb19455a252e838d2bbbce1f80f25ecc42402aafa8cd38"
+checksum = "e32eac81c1135c1df01d4e6d4233c47ba11f6a6d07f33e0bba09d18797077770"
dependencies = [
"fontconfig-parser",
"log",
- "memmap2 0.8.0",
+ "memmap2",
"slotmap",
"tinyvec",
- "ttf-parser 0.19.2",
+ "ttf-parser 0.21.1",
]
[[package]]
@@ -867,7 +1212,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
@@ -877,6 +1222,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
[[package]]
+name = "form_urlencoded"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
name = "futures"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -926,6 +1280,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
+name = "futures-lite"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5"
+dependencies = [
+ "fastrand",
+ "futures-core",
+ "futures-io",
+ "parking",
+ "pin-project-lite",
+]
+
+[[package]]
name = "futures-macro"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -933,7 +1300,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
@@ -967,6 +1334,16 @@ dependencies = [
]
[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
name = "gethostname"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -989,16 +1366,6 @@ dependencies = [
[[package]]
name = "gif"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045"
-dependencies = [
- "color_quant",
- "weezl",
-]
-
-[[package]]
-name = "gif"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
@@ -1009,9 +1376,9 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.29.0"
+version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
+checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
[[package]]
name = "gl_generator"
@@ -1052,18 +1419,6 @@ dependencies = [
]
[[package]]
-name = "glyphon"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a62d0338e4056db6a73221c2fb2e30619452f6ea9651bac4110f51b0f7a7581"
-dependencies = [
- "cosmic-text",
- "etagere",
- "lru",
- "wgpu",
-]
-
-[[package]]
name = "gpu-alloc"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1103,7 +1458,7 @@ checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c"
dependencies = [
"bitflags 2.6.0",
"gpu-descriptor-types",
- "hashbrown",
+ "hashbrown 0.14.5",
]
[[package]]
@@ -1137,15 +1492,30 @@ dependencies = [
[[package]]
name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+dependencies = [
+ "ahash 0.7.8",
+]
+
+[[package]]
+name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
- "ahash",
+ "ahash 0.8.11",
"allocator-api2",
]
[[package]]
+name = "hashbrown"
+version = "0.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb"
+
+[[package]]
name = "hassle-rs"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1173,6 +1543,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
name = "hexf-parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1180,9 +1556,9 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]]
name = "iced"
-version = "0.12.1"
+version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d4eb0fbbefb8c428b70680e77ed9013887b17c1d6be366b40f264f956d1a096"
+checksum = "88acfabc84ec077eaf9ede3457ffa3a104626d79022a9bf7f296093b1d60c73f"
dependencies = [
"iced_core",
"iced_futures",
@@ -1195,63 +1571,101 @@ dependencies = [
]
[[package]]
-name = "iced-builder"
-version = "0.1.0"
+name = "iced_aw"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42e05df3019f20c6decea93d035b32a2afc7b329d89cc5a68cca097d0e0a1889"
dependencies = [
+ "cfg-if",
"iced",
- "iced_aw",
- "rust-format",
- "tokio",
- "unique_id",
+ "iced_fonts",
]
[[package]]
-name = "iced_aw"
-version = "0.9.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e68c330918a95bd73176206d65b84efe9aee6581da0e6dea0390cd146d7214c"
+name = "iced_builder"
+version = "0.1.0"
dependencies = [
- "cfg-if",
"iced",
+ "iced_aw",
+ "iced_drop",
+ "indexmap",
+ "rfd",
+ "rust-format",
+ "serde",
+ "serde_json",
+ "tokio",
+ "unique_id",
]
[[package]]
name = "iced_core"
-version = "0.12.3"
+version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d7e6bbd197f311ed3d8b71651876b0ce01318fde52cda862a9a7a4373c9b930"
+checksum = "0013a238275494641bf8f1732a23a808196540dc67b22ff97099c044ae4c8a1c"
dependencies = [
"bitflags 2.6.0",
+ "bytes",
+ "dark-light",
"glam",
"log",
"num-traits",
+ "once_cell",
"palette",
- "raw-window-handle",
+ "rustc-hash 2.0.0",
"smol_str",
"thiserror",
"web-time",
- "xxhash-rust",
+]
+
+[[package]]
+name = "iced_drop"
+version = "0.1.0"
+dependencies = [
+ "iced",
+]
+
+[[package]]
+name = "iced_fonts"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df7deb0800a850ee25c8a42559f72c0f249e577feb3aad37b9b65dc1e517e52a"
+dependencies = [
+ "iced_core",
]
[[package]]
name = "iced_futures"
-version = "0.12.0"
+version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "370bad88fb3832cbeeb3fa6c486b4701fb7e8da32a753b3101d4ce81fc1d9497"
+checksum = "0c04a6745ba2e80f32cf01e034fd00d853aa4f4cd8b91888099cb7aaee0d5d7c"
dependencies = [
"futures",
"iced_core",
"log",
+ "rustc-hash 2.0.0",
"tokio",
"wasm-bindgen-futures",
"wasm-timer",
]
[[package]]
+name = "iced_glyphon"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41c3bb56f1820ca252bc1d0994ece33d233a55657c0c263ea7cb16895adbde82"
+dependencies = [
+ "cosmic-text",
+ "etagere",
+ "lru",
+ "rustc-hash 2.0.0",
+ "wgpu",
+]
+
+[[package]]
name = "iced_graphics"
-version = "0.12.1"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a044c193ef0840eacabfa05424717331d1fc5b3ecb9a89316200c75da2ba9a4"
+checksum = "ba25a18cfa6d5cc160aca7e1b34f73ccdff21680fa8702168c09739767b6c66f"
dependencies = [
"bitflags 2.6.0",
"bytemuck",
@@ -1265,17 +1679,16 @@ dependencies = [
"lyon_path",
"once_cell",
"raw-window-handle",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"thiserror",
"unicode-segmentation",
- "xxhash-rust",
]
[[package]]
name = "iced_highlighter"
-version = "0.12.0"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1d27d1e5f526255ad4902907509f9ff9e98a40653dd31df36aba38d7c3905ad"
+checksum = "bad88b25a1328cd4bb0b72d8e20f8207c0433649dc788f67e911423b9406f45c"
dependencies = [
"iced_core",
"once_cell",
@@ -1284,9 +1697,9 @@ dependencies = [
[[package]]
name = "iced_renderer"
-version = "0.12.1"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c281e03001d566058f53dec9325bbe61c62da715341206d2627f57a3ecc7f69"
+checksum = "73558208059f9e622df2bf434e044ee2f838ce75201a023cf0ca3e1244f46c2a"
dependencies = [
"iced_graphics",
"iced_tiny_skia",
@@ -1297,10 +1710,11 @@ dependencies = [
[[package]]
name = "iced_runtime"
-version = "0.12.1"
+version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a79f852c01cc6d61663c94379cb3974ac3ad315a28c504e847d573e094f46822"
+checksum = "348b5b2c61c934d88ca3b0ed1ed913291e923d086a66fa288ce9669da9ef62b5"
dependencies = [
+ "bytes",
"iced_core",
"iced_futures",
"raw-window-handle",
@@ -1308,21 +1722,10 @@ dependencies = [
]
[[package]]
-name = "iced_style"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ea42a740915d2a5a9ff9c3aa0bca28b16e9fb660bc8f675eed71d186cadb579"
-dependencies = [
- "iced_core",
- "once_cell",
- "palette",
-]
-
-[[package]]
name = "iced_tiny_skia"
-version = "0.12.1"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c2228781f4d381a1cbbd7905a9f077351aa8d37269094021d5d9e779f130aff"
+checksum = "c625d368284fcc43b0b36b176f76eff1abebe7959dd58bd8ce6897d641962a50"
dependencies = [
"bytemuck",
"cosmic-text",
@@ -1330,59 +1733,64 @@ dependencies = [
"kurbo 0.10.4",
"log",
"resvg",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"softbuffer",
"tiny-skia",
- "xxhash-rust",
]
[[package]]
name = "iced_wgpu"
-version = "0.12.1"
+version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3c243b6700452886aac1ee1987e84d9fb43b56b53fea9a1eb67713fd0fde244"
+checksum = "15708887133671d2bcc6c1d01d1f176f43a64d6cdc3b2bf893396c3ee498295f"
dependencies = [
"bitflags 2.6.0",
"bytemuck",
"futures",
"glam",
- "glyphon",
"guillotiere",
+ "iced_glyphon",
"iced_graphics",
"log",
"lyon",
"once_cell",
"resvg",
+ "rustc-hash 2.0.0",
+ "thiserror",
"wgpu",
]
[[package]]
name = "iced_widget"
-version = "0.12.3"
+version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e01b2212adecf1cb80e2267f302c0e0c263e55f97812056949199ccf9f0b908"
+checksum = "81429e1b950b0e4bca65be4c4278fea6678ea782030a411778f26fa9f8983e1d"
dependencies = [
+ "iced_highlighter",
"iced_renderer",
"iced_runtime",
- "iced_style",
"num-traits",
+ "once_cell",
"qrcode",
+ "rustc-hash 2.0.0",
"thiserror",
"unicode-segmentation",
]
[[package]]
name = "iced_winit"
-version = "0.12.2"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "63f66831d0e399b93f631739121a6171780d344b275d56808b9504d8ca75c7d2"
+checksum = "f44cd4e1c594b6334f409282937bf972ba14d31fedf03c23aa595d982a2fda28"
dependencies = [
+ "iced_futures",
"iced_graphics",
"iced_runtime",
- "iced_style",
"log",
+ "rustc-hash 2.0.0",
"thiserror",
"tracing",
+ "wasm-bindgen-futures",
"web-sys",
"winapi",
"window_clipboard",
@@ -1390,14 +1798,13 @@ dependencies = [
]
[[package]]
-name = "icrate"
-version = "0.0.4"
+name = "idna"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319"
+checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
- "block2 0.3.0",
- "dispatch",
- "objc2 0.4.1",
+ "unicode-bidi",
+ "unicode-normalization",
]
[[package]]
@@ -1410,7 +1817,7 @@ dependencies = [
"byteorder",
"color_quant",
"exr",
- "gif 0.13.1",
+ "gif",
"jpeg-decoder",
"num-traits",
"png",
@@ -1426,12 +1833,13 @@ checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
[[package]]
name = "indexmap"
-version = "2.4.0"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
+checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
dependencies = [
"equivalent",
- "hashbrown",
+ "hashbrown 0.15.0",
+ "serde",
]
[[package]]
@@ -1526,18 +1934,19 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "kurbo"
-version = "0.9.5"
+version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b"
+checksum = "1618d4ebd923e97d67e7cd363d80aef35fe961005cbbbb3d2dad8bdd1bc63440"
dependencies = [
"arrayvec",
+ "smallvec",
]
[[package]]
name = "kurbo"
-version = "0.10.4"
+version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1618d4ebd923e97d67e7cd363d80aef35fe961005cbbbb3d2dad8bdd1bc63440"
+checksum = "89234b2cc610a7dd927ebde6b41dd1a5d4214cffaef4cf1fb2195d592f92518f"
dependencies = [
"arrayvec",
"smallvec",
@@ -1557,9 +1966,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libc"
-version = "0.2.158"
+version = "0.2.159"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
+checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
[[package]]
name = "libloading"
@@ -1599,6 +2008,16 @@ dependencies = [
]
[[package]]
+name = "libredox"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
+dependencies = [
+ "bitflags 2.6.0",
+ "libc",
+]
+
+[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1637,9 +2056,6 @@ name = "lru"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904"
-dependencies = [
- "hashbrown",
-]
[[package]]
name = "lyon"
@@ -1710,20 +2126,20 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "memmap2"
-version = "0.8.0"
+version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed"
+checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
dependencies = [
"libc",
]
[[package]]
-name = "memmap2"
-version = "0.9.4"
+name = "memoffset"
+version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
+checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
- "libc",
+ "autocfg",
]
[[package]]
@@ -1734,7 +2150,7 @@ checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25"
dependencies = [
"bitflags 2.6.0",
"block",
- "core-graphics-types",
+ "core-graphics-types 0.1.3",
"foreign-types",
"log",
"objc",
@@ -1748,7 +2164,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
- "simd-adler32",
]
[[package]]
@@ -1758,6 +2173,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
dependencies = [
"adler2",
+ "simd-adler32",
]
[[package]]
@@ -1779,7 +2195,7 @@ dependencies = [
"indexmap",
"log",
"num-traits",
- "rustc-hash",
+ "rustc-hash 1.1.0",
"spirv",
"termcolor",
"thiserror",
@@ -1788,14 +2204,14 @@ dependencies = [
[[package]]
name = "ndk"
-version = "0.8.0"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7"
+checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4"
dependencies = [
"bitflags 2.6.0",
"jni-sys",
"log",
- "ndk-sys",
+ "ndk-sys 0.6.0+11769913",
"num_enum",
"raw-window-handle",
"thiserror",
@@ -1817,6 +2233,28 @@ dependencies = [
]
[[package]]
+name = "ndk-sys"
+version = "0.6.0+11769913"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873"
+dependencies = [
+ "jni-sys",
+]
+
+[[package]]
+name = "nix"
+version = "0.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
+dependencies = [
+ "bitflags 2.6.0",
+ "cfg-if",
+ "cfg_aliases 0.2.1",
+ "libc",
+ "memoffset",
+]
+
+[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1860,7 +2298,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
@@ -1874,17 +2312,6 @@ dependencies = [
]
[[package]]
-name = "objc-foundation"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
-dependencies = [
- "block",
- "objc",
- "objc_id",
-]
-
-[[package]]
name = "objc-sys"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1892,22 +2319,12 @@ checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
[[package]]
name = "objc2"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d"
-dependencies = [
- "objc-sys",
- "objc2-encode 3.0.0",
-]
-
-[[package]]
-name = "objc2"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
dependencies = [
"objc-sys",
- "objc2-encode 4.0.3",
+ "objc2-encode",
]
[[package]]
@@ -1917,9 +2334,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
dependencies = [
"bitflags 2.6.0",
- "block2 0.5.1",
+ "block2",
"libc",
- "objc2 0.5.2",
+ "objc2",
"objc2-core-data",
"objc2-core-image",
"objc2-foundation",
@@ -1927,14 +2344,38 @@ dependencies = [
]
[[package]]
+name = "objc2-cloud-kit"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
+dependencies = [
+ "bitflags 2.6.0",
+ "block2",
+ "objc2",
+ "objc2-core-location",
+ "objc2-foundation",
+]
+
+[[package]]
+name = "objc2-contacts"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
+dependencies = [
+ "block2",
+ "objc2",
+ "objc2-foundation",
+]
+
+[[package]]
name = "objc2-core-data"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
dependencies = [
"bitflags 2.6.0",
- "block2 0.5.1",
- "objc2 0.5.2",
+ "block2",
+ "objc2",
"objc2-foundation",
]
@@ -1944,17 +2385,23 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80"
dependencies = [
- "block2 0.5.1",
- "objc2 0.5.2",
+ "block2",
+ "objc2",
"objc2-foundation",
"objc2-metal",
]
[[package]]
-name = "objc2-encode"
-version = "3.0.0"
+name = "objc2-core-location"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666"
+checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
+dependencies = [
+ "block2",
+ "objc2",
+ "objc2-contacts",
+ "objc2-foundation",
+]
[[package]]
name = "objc2-encode"
@@ -1969,10 +2416,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [
"bitflags 2.6.0",
- "block2 0.5.1",
+ "block2",
"dispatch",
"libc",
- "objc2 0.5.2",
+ "objc2",
+]
+
+[[package]]
+name = "objc2-link-presentation"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
+dependencies = [
+ "block2",
+ "objc2",
+ "objc2-app-kit",
+ "objc2-foundation",
]
[[package]]
@@ -1982,8 +2441,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
dependencies = [
"bitflags 2.6.0",
- "block2 0.5.1",
- "objc2 0.5.2",
+ "block2",
+ "objc2",
"objc2-foundation",
]
@@ -1994,44 +2453,93 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
dependencies = [
"bitflags 2.6.0",
- "block2 0.5.1",
- "objc2 0.5.2",
+ "block2",
+ "objc2",
"objc2-foundation",
"objc2-metal",
]
[[package]]
-name = "objc_exception"
-version = "0.1.2"
+name = "objc2-symbols"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4"
+checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc"
dependencies = [
- "cc",
+ "objc2",
+ "objc2-foundation",
]
[[package]]
-name = "objc_id"
-version = "0.1.1"
+name = "objc2-ui-kit"
+version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
+checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
dependencies = [
- "objc",
+ "bitflags 2.6.0",
+ "block2",
+ "objc2",
+ "objc2-cloud-kit",
+ "objc2-core-data",
+ "objc2-core-image",
+ "objc2-core-location",
+ "objc2-foundation",
+ "objc2-link-presentation",
+ "objc2-quartz-core",
+ "objc2-symbols",
+ "objc2-uniform-type-identifiers",
+ "objc2-user-notifications",
+]
+
+[[package]]
+name = "objc2-uniform-type-identifiers"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
+dependencies = [
+ "block2",
+ "objc2",
+ "objc2-foundation",
+]
+
+[[package]]
+name = "objc2-user-notifications"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
+dependencies = [
+ "bitflags 2.6.0",
+ "block2",
+ "objc2",
+ "objc2-core-location",
+ "objc2-foundation",
+]
+
+[[package]]
+name = "objc_exception"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4"
+dependencies = [
+ "cc",
]
[[package]]
name = "object"
-version = "0.36.3"
+version = "0.36.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9"
+checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
-version = "1.19.0"
+version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
+dependencies = [
+ "portable-atomic",
+]
[[package]]
name = "onig"
@@ -2061,7 +2569,27 @@ version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166"
dependencies = [
- "libredox",
+ "libredox 0.0.2",
+]
+
+[[package]]
+name = "ordered-multimap"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a"
+dependencies = [
+ "dlv-list",
+ "hashbrown 0.12.3",
+]
+
+[[package]]
+name = "ordered-stream"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
]
[[package]]
@@ -2094,10 +2622,16 @@ dependencies = [
"by_address",
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
+name = "parking"
+version = "2.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
+
+[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2140,7 +2674,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall 0.5.3",
+ "redox_syscall 0.5.7",
"smallvec",
"windows-targets 0.52.6",
]
@@ -2187,7 +2721,7 @@ dependencies = [
"phf_shared",
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
@@ -2196,7 +2730,7 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
dependencies = [
- "siphasher",
+ "siphasher 0.3.11",
]
[[package]]
@@ -2206,6 +2740,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
+name = "pin-project"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+]
+
+[[package]]
name = "pin-project-lite"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2218,10 +2772,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
+name = "piper"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
+dependencies = [
+ "atomic-waker",
+ "fastrand",
+ "futures-io",
+]
+
+[[package]]
name = "pkg-config"
-version = "0.3.30"
+version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
+checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "plist"
@@ -2238,15 +2803,15 @@ dependencies = [
[[package]]
name = "png"
-version = "0.17.13"
+version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
+checksum = "52f9d46a34a05a6a57566bc2bfae066ef07585a6e3fa30fbbdff5936380623f0"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
"fdeflate",
"flate2",
- "miniz_oxide 0.7.4",
+ "miniz_oxide 0.8.0",
]
[[package]]
@@ -2265,12 +2830,33 @@ dependencies = [
]
[[package]]
+name = "pollster"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
+
+[[package]]
+name = "portable-atomic"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
+
+[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
+name = "ppv-lite86"
+version = "0.2.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+dependencies = [
+ "zerocopy",
+]
+
+[[package]]
name = "presser"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2278,9 +2864,9 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
[[package]]
name = "proc-macro-crate"
-version = "3.1.0"
+version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
+checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
dependencies = [
"toml_edit",
]
@@ -2326,9 +2912,9 @@ dependencies = [
[[package]]
name = "quick-xml"
-version = "0.34.0"
+version = "0.36.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4"
+checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe"
dependencies = [
"memchr",
]
@@ -2348,6 +2934,18 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
"rand_core",
]
@@ -2356,6 +2954,9 @@ name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
[[package]]
name = "range-alloc"
@@ -2396,12 +2997,6 @@ dependencies = [
]
[[package]]
-name = "rctree"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f"
-
-[[package]]
name = "read-fonts"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2422,36 +3017,38 @@ dependencies = [
[[package]]
name = "redox_syscall"
-version = "0.3.5"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_syscall"
-version = "0.4.1"
+version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
+checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.6.0",
]
[[package]]
-name = "redox_syscall"
-version = "0.5.3"
+name = "redox_users"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
+checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
- "bitflags 2.6.0",
+ "getrandom",
+ "libredox 0.1.3",
+ "thiserror",
]
[[package]]
name = "regex-syntax"
-version = "0.8.4"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "renderdoc-sys"
@@ -2461,15 +3058,14 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "resvg"
-version = "0.36.0"
+version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc7980f653f9a7db31acff916a262c3b78c562919263edea29bf41a056e20497"
+checksum = "944d052815156ac8fa77eaac055220e95ba0b01fa8887108ca710c03805d9051"
dependencies = [
- "gif 0.12.0",
+ "gif",
"jpeg-decoder",
"log",
"pico-args",
- "png",
"rgb",
"svgtypes",
"tiny-skia",
@@ -2477,21 +3073,34 @@ dependencies = [
]
[[package]]
-name = "rgb"
-version = "0.8.48"
+name = "rfd"
+version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f86ae463694029097b846d8f99fd5536740602ae00022c0c50c5600720b2f71"
+checksum = "8af382a047821a08aa6bfc09ab0d80ff48d45d8726f7cd8e44891f7cb4a4278e"
dependencies = [
- "bytemuck",
+ "ashpd",
+ "block2",
+ "js-sys",
+ "log",
+ "objc2",
+ "objc2-app-kit",
+ "objc2-foundation",
+ "pollster",
+ "raw-window-handle",
+ "urlencoding",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "windows-sys 0.48.0",
]
[[package]]
-name = "roxmltree"
-version = "0.18.1"
+name = "rgb"
+version = "0.8.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "862340e351ce1b271a378ec53f304a5558f7db87f3769dc655a8f6ecbb68b302"
+checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
dependencies = [
- "xmlparser",
+ "bytemuck",
]
[[package]]
@@ -2507,6 +3116,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60e7c00b6c3bf5e38a880eec01d7e829d12ca682079f8238a464def3c4b31627"
[[package]]
+name = "rust-ini"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
+dependencies = [
+ "cfg-if",
+ "ordered-multimap",
+]
+
+[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2519,10 +3138,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
+name = "rustc-hash"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
+
+[[package]]
name = "rustix"
-version = "0.38.34"
+version = "0.38.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
dependencies = [
"bitflags 2.6.0",
"errno",
@@ -2533,31 +3158,15 @@ dependencies = [
[[package]]
name = "rustybuzz"
-version = "0.10.0"
+version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71cd15fef9112a1f94ac64b58d1e4628192631ad6af4dc69997f995459c874e7"
+checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c"
dependencies = [
- "bitflags 1.3.2",
- "bytemuck",
- "smallvec",
- "ttf-parser 0.19.2",
- "unicode-bidi-mirroring",
- "unicode-ccc",
- "unicode-properties",
- "unicode-script",
-]
-
-[[package]]
-name = "rustybuzz"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ee8fe2a8461a0854a37101fe7a1b13998d0cfa987e43248e81d2a5f4570f6fa"
-dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.6.0",
"bytemuck",
"libm",
"smallvec",
- "ttf-parser 0.20.0",
+ "ttf-parser 0.21.1",
"unicode-bidi-mirroring",
"unicode-ccc",
"unicode-properties",
@@ -2593,14 +3202,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sctk-adwaita"
-version = "0.8.3"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70b31447ca297092c5a9916fc3b955203157b37c19ca8edde4f52e9843e602c7"
+checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec"
dependencies = [
"ab_glyph",
"log",
- "memmap2 0.9.4",
- "smithay-client-toolkit 0.18.1",
+ "memmap2",
+ "smithay-client-toolkit",
"tiny-skia",
]
@@ -2612,29 +3221,29 @@ checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a"
[[package]]
name = "serde"
-version = "1.0.208"
+version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
+checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.208"
+version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
+checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
name = "serde_json"
-version = "1.0.127"
+version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad"
+checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
dependencies = [
"itoa",
"memchr",
@@ -2643,12 +3252,43 @@ dependencies = [
]
[[package]]
+name = "serde_repr"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+]
+
+[[package]]
+name = "sha1"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
+name = "signal-hook-registry"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "simd-adler32"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2670,6 +3310,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]]
+name = "siphasher"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
+
+[[package]]
name = "skrifa"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2705,50 +3351,25 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "smithay-client-toolkit"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a"
-dependencies = [
- "bitflags 2.6.0",
- "calloop 0.12.4",
- "calloop-wayland-source 0.2.0",
- "cursor-icon",
- "libc",
- "log",
- "memmap2 0.9.4",
- "rustix",
- "thiserror",
- "wayland-backend",
- "wayland-client",
- "wayland-csd-frame",
- "wayland-cursor",
- "wayland-protocols 0.31.2",
- "wayland-protocols-wlr 0.2.0",
- "wayland-scanner",
- "xkeysym",
-]
-
-[[package]]
-name = "smithay-client-toolkit"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016"
dependencies = [
"bitflags 2.6.0",
- "calloop 0.13.0",
- "calloop-wayland-source 0.3.0",
+ "calloop",
+ "calloop-wayland-source",
"cursor-icon",
"libc",
"log",
- "memmap2 0.9.4",
+ "memmap2",
"rustix",
"thiserror",
"wayland-backend",
"wayland-client",
"wayland-csd-frame",
"wayland-cursor",
- "wayland-protocols 0.32.3",
- "wayland-protocols-wlr 0.3.3",
+ "wayland-protocols",
+ "wayland-protocols-wlr",
"wayland-scanner",
"xkeysym",
]
@@ -2760,7 +3381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846"
dependencies = [
"libc",
- "smithay-client-toolkit 0.19.2",
+ "smithay-client-toolkit",
"wayland-backend",
]
@@ -2775,26 +3396,25 @@ dependencies = [
[[package]]
name = "softbuffer"
-version = "0.4.5"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d623bff5d06f60d738990980d782c8c866997d9194cfe79ecad00aa2f76826dd"
+checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08"
dependencies = [
"as-raw-xcb-connection",
"bytemuck",
"cfg_aliases 0.2.1",
- "core-graphics",
+ "core-graphics 0.24.0",
"drm",
"fastrand",
"foreign-types",
"js-sys",
"log",
- "memmap2 0.9.4",
- "objc2 0.5.2",
- "objc2-app-kit",
+ "memmap2",
+ "objc2",
"objc2-foundation",
"objc2-quartz-core",
"raw-window-handle",
- "redox_syscall 0.5.3",
+ "redox_syscall 0.5.7",
"rustix",
"tiny-xlib",
"wasm-bindgen",
@@ -2802,7 +3422,7 @@ dependencies = [
"wayland-client",
"wayland-sys",
"web-sys",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
"x11rb",
]
@@ -2847,12 +3467,12 @@ checksum = "20e16a0f46cf5fd675563ef54f26e83e20f2366bcf027bcb3cc3ed2b98aaf2ca"
[[package]]
name = "svgtypes"
-version = "0.12.0"
+version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71499ff2d42f59d26edb21369a308ede691421f79ebc0f001e2b1fd3a7c9e52"
+checksum = "794de53cc48eaabeed0ab6a3404a65f40b3e38c067e4435883a65d2aa4ca000e"
dependencies = [
- "kurbo 0.9.5",
- "siphasher",
+ "kurbo 0.11.1",
+ "siphasher 1.0.1",
]
[[package]]
@@ -2879,9 +3499,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.75"
+version = "2.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
+checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
dependencies = [
"proc-macro2",
"quote",
@@ -2920,6 +3540,19 @@ dependencies = [
]
[[package]]
+name = "tempfile"
+version = "3.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "once_cell",
+ "rustix",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2930,22 +3563,22 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.63"
+version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
+checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.63"
+version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
+checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
@@ -3062,9 +3695,9 @@ checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
[[package]]
name = "toml_edit"
-version = "0.21.1"
+version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
+checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [
"indexmap",
"toml_datetime",
@@ -3090,7 +3723,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
@@ -3104,15 +3737,15 @@ dependencies = [
[[package]]
name = "ttf-parser"
-version = "0.19.2"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1"
+checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
[[package]]
name = "ttf-parser"
-version = "0.20.0"
+version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
+checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"
[[package]]
name = "ttf-parser"
@@ -3121,28 +3754,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a"
[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+[[package]]
+name = "uds_windows"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
+dependencies = [
+ "memoffset",
+ "tempfile",
+ "winapi",
+]
+
+[[package]]
name = "unicode-bidi"
-version = "0.3.15"
+version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
+checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893"
[[package]]
name = "unicode-bidi-mirroring"
-version = "0.1.0"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56d12260fb92d52f9008be7e4bca09f584780eb2266dc8fecc6a192bec561694"
+checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86"
[[package]]
name = "unicode-ccc"
-version = "0.1.2"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc2520efa644f8268dce4dcd3050eaa7fc044fca03961e9998ac7e2e92b77cf1"
+checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656"
[[package]]
name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-linebreak"
@@ -3151,22 +3801,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
[[package]]
+name = "unicode-normalization"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
name = "unicode-properties"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524"
+checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
[[package]]
name = "unicode-script"
-version = "0.5.6"
+version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd"
+checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f"
[[package]]
name = "unicode-segmentation"
-version = "1.11.0"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
+checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "unicode-vo"
@@ -3176,15 +3835,15 @@ checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94"
[[package]]
name = "unicode-width"
-version = "0.1.13"
+version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "unicode-xid"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
+checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "unique_id"
@@ -3198,64 +3857,48 @@ dependencies = [
]
[[package]]
-name = "usvg"
-version = "0.36.0"
+name = "url"
+version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c51daa774fe9ee5efcf7b4fec13019b8119cda764d9a8b5b06df02bb1445c656"
+checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
dependencies = [
- "base64 0.21.7",
- "log",
- "pico-args",
- "usvg-parser",
- "usvg-text-layout",
- "usvg-tree",
- "xmlwriter",
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
]
[[package]]
-name = "usvg-parser"
-version = "0.36.0"
+name = "urlencoding"
+version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45c88a5ffaa338f0e978ecf3d4e00d8f9f493e29bed0752e1a808a1db16afc40"
+checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
+
+[[package]]
+name = "usvg"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b84ea542ae85c715f07b082438a4231c3760539d902e11d093847a0b22963032"
dependencies = [
+ "base64 0.22.1",
"data-url",
"flate2",
+ "fontdb 0.18.0",
"imagesize",
- "kurbo 0.9.5",
+ "kurbo 0.11.1",
"log",
- "roxmltree 0.18.1",
+ "pico-args",
+ "roxmltree",
+ "rustybuzz",
"simplecss",
- "siphasher",
+ "siphasher 1.0.1",
+ "strict-num",
"svgtypes",
- "usvg-tree",
-]
-
-[[package]]
-name = "usvg-text-layout"
-version = "0.36.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4d2374378cb7a3fb8f33894e0fdb8625e1bbc4f25312db8d91f862130b541593"
-dependencies = [
- "fontdb",
- "kurbo 0.9.5",
- "log",
- "rustybuzz 0.10.0",
+ "tiny-skia-path",
"unicode-bidi",
"unicode-script",
"unicode-vo",
- "usvg-tree",
-]
-
-[[package]]
-name = "usvg-tree"
-version = "0.36.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cacb0c5edeaf3e80e5afcf5b0d4004cc1d36318befc9a7c6606507e5d0f4062"
-dependencies = [
- "rctree",
- "strict-num",
- "svgtypes",
- "tiny-skia-path",
+ "xmlwriter",
]
[[package]]
@@ -3311,7 +3954,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
"wasm-bindgen-shared",
]
@@ -3345,7 +3988,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -3373,9 +4016,9 @@ dependencies = [
[[package]]
name = "wayland-backend"
-version = "0.3.6"
+version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993"
+checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6"
dependencies = [
"cc",
"downcast-rs",
@@ -3387,9 +4030,9 @@ dependencies = [
[[package]]
name = "wayland-client"
-version = "0.31.5"
+version = "0.31.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943"
+checksum = "e3f45d1222915ef1fd2057220c1d9d9624b7654443ea35c3877f7a52bd0a5a2d"
dependencies = [
"bitflags 2.6.0",
"rustix",
@@ -3410,9 +4053,9 @@ dependencies = [
[[package]]
name = "wayland-cursor"
-version = "0.31.5"
+version = "0.31.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95"
+checksum = "3a94697e66e76c85923b0d28a0c251e8f0666f58fc47d316c0f4da6da75d37cb"
dependencies = [
"rustix",
"wayland-client",
@@ -3421,21 +4064,9 @@ dependencies = [
[[package]]
name = "wayland-protocols"
-version = "0.31.2"
+version = "0.32.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4"
-dependencies = [
- "bitflags 2.6.0",
- "wayland-backend",
- "wayland-client",
- "wayland-scanner",
-]
-
-[[package]]
-name = "wayland-protocols"
-version = "0.32.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa"
+checksum = "2b5755d77ae9040bb872a25026555ce4cb0ae75fd923e90d25fba07d81057de0"
dependencies = [
"bitflags 2.6.0",
"wayland-backend",
@@ -3445,59 +4076,46 @@ dependencies = [
[[package]]
name = "wayland-protocols-plasma"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479"
-dependencies = [
- "bitflags 2.6.0",
- "wayland-backend",
- "wayland-client",
- "wayland-protocols 0.31.2",
- "wayland-scanner",
-]
-
-[[package]]
-name = "wayland-protocols-wlr"
-version = "0.2.0"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6"
+checksum = "8a0a41a6875e585172495f7a96dfa42ca7e0213868f4f15c313f7c33221a7eff"
dependencies = [
"bitflags 2.6.0",
"wayland-backend",
"wayland-client",
- "wayland-protocols 0.31.2",
+ "wayland-protocols",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols-wlr"
-version = "0.3.3"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953"
+checksum = "dad87b5fd1b1d3ca2f792df8f686a2a11e3fe1077b71096f7a175ab699f89109"
dependencies = [
"bitflags 2.6.0",
"wayland-backend",
"wayland-client",
- "wayland-protocols 0.32.3",
+ "wayland-protocols",
"wayland-scanner",
]
[[package]]
name = "wayland-scanner"
-version = "0.31.4"
+version = "0.31.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6"
+checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3"
dependencies = [
"proc-macro2",
- "quick-xml 0.34.0",
+ "quick-xml 0.36.2",
"quote",
]
[[package]]
name = "wayland-sys"
-version = "0.31.4"
+version = "0.31.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148"
+checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09"
dependencies = [
"dlib",
"log",
@@ -3507,9 +4125,9 @@ dependencies = [
[[package]]
name = "web-sys"
-version = "0.3.67"
+version = "0.3.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed"
+checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -3517,9 +4135,9 @@ dependencies = [
[[package]]
name = "web-time"
-version = "0.2.4"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0"
+checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -3574,7 +4192,7 @@ dependencies = [
"parking_lot 0.12.3",
"profiling",
"raw-window-handle",
- "rustc-hash",
+ "rustc-hash 1.1.0",
"smallvec",
"thiserror",
"web-sys",
@@ -3595,7 +4213,7 @@ dependencies = [
"bitflags 2.6.0",
"block",
"cfg_aliases 0.1.1",
- "core-graphics-types",
+ "core-graphics-types 0.1.3",
"d3d12",
"glow",
"glutin_wgl_sys",
@@ -3610,7 +4228,7 @@ dependencies = [
"log",
"metal",
"naga",
- "ndk-sys",
+ "ndk-sys 0.5.0+25.2.9519653",
"objc",
"once_cell",
"parking_lot 0.12.3",
@@ -3618,7 +4236,7 @@ dependencies = [
"range-alloc",
"raw-window-handle",
"renderdoc-sys",
- "rustc-hash",
+ "rustc-hash 1.1.0",
"smallvec",
"thiserror",
"wasm-bindgen",
@@ -3924,47 +4542,51 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winit"
-version = "0.29.15"
+version = "0.30.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca"
+checksum = "0be9e76a1f1077e04a411f0b989cbd3c93339e1771cb41e71ac4aee95bfd2c67"
dependencies = [
- "ahash",
+ "ahash 0.8.11",
"android-activity",
"atomic-waker",
"bitflags 2.6.0",
+ "block2",
"bytemuck",
- "calloop 0.12.4",
- "cfg_aliases 0.1.1",
- "core-foundation",
- "core-graphics",
+ "calloop",
+ "cfg_aliases 0.2.1",
+ "concurrent-queue",
+ "core-foundation 0.9.4",
+ "core-graphics 0.23.2",
"cursor-icon",
- "icrate",
+ "dpi",
"js-sys",
"libc",
- "log",
- "memmap2 0.9.4",
+ "memmap2",
"ndk",
- "ndk-sys",
- "objc2 0.4.1",
- "once_cell",
+ "objc2",
+ "objc2-app-kit",
+ "objc2-foundation",
+ "objc2-ui-kit",
"orbclient",
"percent-encoding",
+ "pin-project",
"raw-window-handle",
- "redox_syscall 0.3.5",
+ "redox_syscall 0.4.1",
"rustix",
"sctk-adwaita",
- "smithay-client-toolkit 0.18.1",
+ "smithay-client-toolkit",
"smol_str",
+ "tracing",
"unicode-segmentation",
"wasm-bindgen",
"wasm-bindgen-futures",
"wayland-backend",
"wayland-client",
- "wayland-protocols 0.31.2",
+ "wayland-protocols",
"wayland-protocols-plasma",
"web-sys",
"web-time",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
"x11-dl",
"x11rb",
"xkbcommon-dl",
@@ -3972,14 +4594,23 @@ dependencies = [
[[package]]
name = "winnow"
-version = "0.5.40"
+version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
+checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
dependencies = [
"memchr",
]
[[package]]
+name = "winreg"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
name = "x11-dl"
version = "2.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4018,6 +4649,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61"
[[package]]
+name = "xdg-home"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6"
+dependencies = [
+ "libc",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
name = "xkbcommon-dl"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4038,15 +4679,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56"
[[package]]
name = "xml-rs"
-version = "0.8.21"
+version = "0.8.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601"
-
-[[package]]
-name = "xmlparser"
-version = "0.13.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
+checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26"
[[package]]
name = "xmlwriter"
@@ -4055,12 +4690,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
[[package]]
-name = "xxhash-rust"
-version = "0.8.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984"
-
-[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4076,6 +4705,68 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1"
[[package]]
+name = "zbus"
+version = "4.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
+dependencies = [
+ "async-broadcast",
+ "async-executor",
+ "async-fs",
+ "async-io",
+ "async-lock",
+ "async-process",
+ "async-recursion",
+ "async-task",
+ "async-trait",
+ "blocking",
+ "enumflags2",
+ "event-listener",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "hex",
+ "nix",
+ "ordered-stream",
+ "rand",
+ "serde",
+ "serde_repr",
+ "sha1",
+ "static_assertions",
+ "tracing",
+ "uds_windows",
+ "windows-sys 0.52.0",
+ "xdg-home",
+ "zbus_macros",
+ "zbus_names",
+ "zvariant",
+]
+
+[[package]]
+name = "zbus_macros"
+version = "4.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zbus_names"
+version = "3.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
+dependencies = [
+ "serde",
+ "static_assertions",
+ "zvariant",
+]
+
+[[package]]
name = "zeno"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4087,6 +4778,7 @@ version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
+ "byteorder",
"zerocopy-derive",
]
@@ -4098,7 +4790,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.75",
+ "syn 2.0.79",
]
[[package]]
@@ -4109,3 +4801,41 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
dependencies = [
"simd-adler32",
]
+
+[[package]]
+name = "zvariant"
+version = "4.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe"
+dependencies = [
+ "endi",
+ "enumflags2",
+ "serde",
+ "static_assertions",
+ "url",
+ "zvariant_derive",
+]
+
+[[package]]
+name = "zvariant_derive"
+version = "4.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+ "zvariant_utils",
+]
+
+[[package]]
+name = "zvariant_utils"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.79",
+]
diff --git a/Cargo.toml b/Cargo.toml
index 301ecfe..64f9037 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,16 +1,6 @@
-[package]
-name = "iced-builder"
-description = "GUI builder for iced, built with iced."
-version = "0.1.0"
-edition = "2021"
-authors = ["pml68 <contact@pml68.me>"]
-repository = "https://github.com/pml68/iced-builder"
-license = "GPL-3.0-or-later"
-keywords = ["gui", "iced"]
-
-[dependencies]
-iced = { version = "0.12.1", features = [ "image","svg","canvas","qr_code","advanced","tokio","highlighter"] }
-iced_aw = { version = "0.9.3", default-features = false, features = ["menu","color_picker"] }
-tokio = { version = "1.40.0", features = ["fs"] }
-rust-format = "0.3.4"
-unique_id = "0.1.5"
+[workspace]
+resolver = "2"
+members = [
+ "iced_drop",
+ "iced_builder"
+]
diff --git a/iced_builder/Cargo.toml b/iced_builder/Cargo.toml
new file mode 100644
index 0000000..d788bc2
--- /dev/null
+++ b/iced_builder/Cargo.toml
@@ -0,0 +1,25 @@
+[package]
+name = "iced_builder"
+description = "GUI builder for iced, built with iced."
+version = "0.1.0"
+edition = "2021"
+authors = ["pml68 <contact@pml68.me>"]
+repository = "https://github.com/pml68/iced-builder"
+license = "GPL-3.0-or-later"
+keywords = ["gui", "iced"]
+
+[dependencies]
+iced = { version = "0.13.1", features = [ "image","svg","canvas","qr_code","advanced","tokio","highlighter"] }
+iced_aw = { version = "0.11.0", default-features = false, features = ["menu","color_picker"] }
+iced_drop = { path = "../iced_drop" }
+serde = { version = "1.0.210", features = ["derive"] }
+serde_json = "1.0.128"
+tokio = { version = "1.40.0", features = ["fs"] }
+rfd = "0.15.0"
+rust-format = "0.3.4"
+unique_id = "0.1.5"
+indexmap = { version = "2.6.0", features = ["serde"] }
+
+[[bin]]
+name = "iced-builder"
+path = "src/main.rs"
diff --git a/fonts/icons.ttf b/iced_builder/fonts/icons.ttf
index 393c692..393c692 100644
--- a/fonts/icons.ttf
+++ b/iced_builder/fonts/icons.ttf
Binary files differ
diff --git a/iced_builder/src/lib.rs b/iced_builder/src/lib.rs
new file mode 100644
index 0000000..420b14c
--- /dev/null
+++ b/iced_builder/src/lib.rs
@@ -0,0 +1,91 @@
+pub mod types;
+
+use std::path::PathBuf;
+
+use iced::widget::{pane_grid, text_editor};
+use types::{
+ element_name::ElementName, project::Project, rendered_element::RenderedElement, DesignerPage,
+};
+
+#[derive(Debug, Clone)]
+pub enum Error {
+ IOError(std::io::ErrorKind),
+ SerdeError(String),
+ FormatError(String),
+ NonExistentElement,
+ DialogClosed,
+ String(String),
+}
+
+impl std::fmt::Display for Error {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::SerdeError(string) | Self::FormatError(string) | Self::String(string) => {
+ write!(f, "{}", string)
+ }
+ Self::IOError(kind) => {
+ write!(f, "{}", kind)
+ }
+ Self::NonExistentElement => {
+ write!(f, "The element tree contains no matching element.")
+ }
+ Self::DialogClosed => {
+ write!(
+ f,
+ "The file dialog has been closed without selecting a valid option."
+ )
+ }
+ }
+ }
+}
+
+impl From<std::io::Error> for Error {
+ fn from(value: std::io::Error) -> Self {
+ Self::IOError(value.kind())
+ }
+}
+
+impl From<serde_json::Error> for Error {
+ fn from(value: serde_json::Error) -> Self {
+ Self::SerdeError(value.to_string())
+ }
+}
+
+impl From<rust_format::Error> for Error {
+ fn from(value: rust_format::Error) -> Self {
+ Self::FormatError(value.to_string())
+ }
+}
+
+impl From<&'static str> for Error {
+ fn from(value: &'static str) -> Self {
+ Self::String(value.to_owned())
+ }
+}
+
+#[derive(Debug, Clone)]
+pub enum Message {
+ ToggleTheme,
+ CopyCode,
+ SwitchPage(DesignerPage),
+ EditorAction(text_editor::Action),
+ RefreshEditorContent,
+ DropNewElement(ElementName, iced::Point, iced::Rectangle),
+ HandleNew(
+ ElementName,
+ Vec<(iced::advanced::widget::Id, iced::Rectangle)>,
+ ),
+ MoveElement(RenderedElement, iced::Point, iced::Rectangle),
+ HandleMove(
+ RenderedElement,
+ Vec<(iced::advanced::widget::Id, iced::Rectangle)>,
+ ),
+ PaneResized(pane_grid::ResizeEvent),
+ PaneClicked(pane_grid::Pane),
+ PaneDragged(pane_grid::DragEvent),
+ NewFile,
+ OpenFile,
+ FileOpened(Result<(PathBuf, Project), Error>),
+ SaveFile,
+ FileSaved(Result<PathBuf, Error>),
+}
diff --git a/iced_builder/src/main.rs b/iced_builder/src/main.rs
new file mode 100644
index 0000000..fc7f18c
--- /dev/null
+++ b/iced_builder/src/main.rs
@@ -0,0 +1,415 @@
+use std::path::PathBuf;
+
+use iced::{
+ advanced::widget::Id,
+ clipboard, highlighter, keyboard,
+ widget::{
+ button, column, container,
+ pane_grid::{self, Pane, PaneGrid},
+ row, text, text_editor, themer, tooltip, Column, Space,
+ },
+ Alignment, Element, Font, Length, Settings, Task, Theme,
+};
+use iced_builder::types::{
+ element_name::ElementName, project::Project, rendered_element::ActionKind, DesignerPage,
+};
+use iced_builder::Message;
+use iced_drop::droppable;
+
+fn main() -> iced::Result {
+ iced::application(App::title, App::update, App::view)
+ .settings(Settings {
+ fonts: vec![include_bytes!("../fonts/icons.ttf").as_slice().into()],
+ ..Settings::default()
+ })
+ .theme(App::theme)
+ .subscription(App::subscription)
+ .run_with(App::new)
+}
+
+struct App {
+ is_dirty: bool,
+ is_loading: bool,
+ project_path: Option<PathBuf>,
+ project: Project,
+ dark_theme: bool,
+ pane_state: pane_grid::State<Panes>,
+ focus: Option<Pane>,
+ designer_page: DesignerPage,
+ element_list: Vec<ElementName>,
+ editor_content: text_editor::Content,
+}
+
+#[derive(Clone, Copy, Debug)]
+enum Panes {
+ Designer,
+ ElementList,
+}
+
+impl App {
+ fn new() -> (Self, Task<Message>) {
+ let state = pane_grid::State::with_configuration(pane_grid::Configuration::Split {
+ axis: pane_grid::Axis::Vertical,
+ ratio: 0.8,
+ a: Box::new(pane_grid::Configuration::Pane(Panes::Designer)),
+ b: Box::new(pane_grid::Configuration::Pane(Panes::ElementList)),
+ });
+ (
+ Self {
+ is_dirty: false,
+ is_loading: false,
+ project_path: None,
+ project: Project::new(),
+ dark_theme: true,
+ pane_state: state,
+ focus: None,
+ designer_page: DesignerPage::Designer,
+ element_list: ElementName::ALL.to_vec(),
+ editor_content: text_editor::Content::new(),
+ },
+ Task::none(),
+ )
+ }
+
+ fn title(&self) -> String {
+ let saved_state = if !self.is_dirty { "" } else { " *" };
+
+ let project_name = match &self.project.title {
+ Some(n) => {
+ format!(
+ " - {}",
+ if n.len() > 60 {
+ format!("...{}", &n[n.len() - 40..])
+ } else {
+ n.to_owned()
+ }
+ )
+ }
+ None => "".to_owned(),
+ };
+
+ format!("iced Builder{project_name}{saved_state}")
+ }
+
+ fn theme(&self) -> iced::Theme {
+ if self.dark_theme {
+ Theme::SolarizedDark
+ } else {
+ Theme::SolarizedLight
+ }
+ }
+
+ fn update(&mut self, message: Message) -> Task<Message> {
+ match message {
+ Message::ToggleTheme => self.dark_theme = !self.dark_theme,
+ Message::CopyCode => return clipboard::write(self.editor_content.text()),
+ Message::SwitchPage(page) => self.designer_page = page,
+ Message::EditorAction(action) => {
+ if let text_editor::Action::Scroll { lines: _ } = action {
+ self.editor_content.perform(action);
+ }
+ }
+ Message::RefreshEditorContent => {
+ let code = self
+ .project
+ .clone()
+ .app_code()
+ .unwrap_or_else(|err| err.to_string());
+ self.editor_content = text_editor::Content::with_text(&code);
+ }
+ Message::DropNewElement(name, point, _) => {
+ return iced_drop::zones_on_point(
+ move |zones| Message::HandleNew(name.clone(), zones),
+ point,
+ None,
+ None,
+ )
+ .into()
+ }
+ Message::HandleNew(name, zones) => {
+ let ids: Vec<Id> = zones.into_iter().map(|z| z.0).collect();
+ if ids.len() > 0 {
+ let action = ActionKind::new(ids, &mut self.project.content.clone(), None);
+ let result = name.handle_action(self.project.content.as_mut(), action);
+ if let Ok(Some(ref element)) = result {
+ self.project.content = Some(element.clone());
+ }
+ println!("{:?}", result);
+ }
+
+ return Task::done(Message::RefreshEditorContent);
+ }
+ Message::MoveElement(element, point, _) => {
+ return iced_drop::zones_on_point(
+ move |zones| Message::HandleMove(element.clone(), zones),
+ point,
+ None,
+ None,
+ )
+ .into()
+ }
+ Message::HandleMove(element, zones) => {
+ let ids: Vec<Id> = zones.into_iter().map(|z| z.0).collect();
+ if ids.len() > 0 {
+ let action = ActionKind::new(
+ ids,
+ &mut self.project.content.clone(),
+ Some(element.get_id()),
+ );
+ let result = element.handle_action(self.project.content.as_mut(), action);
+
+ println!("{result:?}");
+ }
+
+ return Task::done(Message::RefreshEditorContent);
+ }
+ Message::PaneResized(pane_grid::ResizeEvent { split, ratio }) => {
+ self.pane_state.resize(split, ratio);
+ }
+ Message::PaneClicked(pane) => {
+ self.focus = Some(pane);
+ }
+ Message::PaneDragged(pane_grid::DragEvent::Dropped { pane, target }) => {
+ self.pane_state.drop(pane, target);
+ }
+ Message::PaneDragged(_) => {}
+ Message::NewFile => {
+ if !self.is_loading {
+ self.project = Project::new();
+ self.project_path = None;
+ self.editor_content = text_editor::Content::new();
+ }
+ }
+ Message::OpenFile => {
+ if !self.is_loading {
+ self.is_loading = true;
+
+ return Task::perform(Project::from_file(), Message::FileOpened);
+ }
+ }
+ Message::FileOpened(result) => {
+ self.is_loading = false;
+ self.is_dirty = false;
+
+ if let Ok((path, project)) = result {
+ self.project = project.clone();
+ self.project_path = Some(path);
+ self.editor_content = text_editor::Content::with_text(
+ &project.app_code().unwrap_or_else(|err| err.to_string()),
+ );
+ }
+ }
+ Message::SaveFile => {
+ if !self.is_loading {
+ self.is_loading = true;
+
+ return Task::perform(
+ self.project
+ .clone()
+ .write_to_file(self.project_path.clone()),
+ Message::FileSaved,
+ );
+ }
+ }
+ Message::FileSaved(result) => {
+ self.is_loading = false;
+
+ if let Ok(path) = result {
+ self.project_path = Some(path);
+ self.is_dirty = false;
+ }
+ }
+ }
+
+ Task::none()
+ }
+
+ fn subscription(&self) -> iced::Subscription<Message> {
+ keyboard::on_key_press(|key, modifiers| match key.as_ref() {
+ keyboard::Key::Character("o") if modifiers.command() => Some(Message::OpenFile),
+ keyboard::Key::Character("s") if modifiers.command() => Some(Message::SaveFile),
+ keyboard::Key::Character("n") if modifiers.command() => Some(Message::NewFile),
+ _ => None,
+ })
+ }
+
+ fn view(&self) -> Element<Message> {
+ let header = row![button("Toggle Theme")
+ .on_press(Message::ToggleTheme)
+ .padding(5)]
+ .width(200);
+ let pane_grid = PaneGrid::new(&self.pane_state, |id, pane, _is_maximized| {
+ let is_focused = Some(id) == self.focus;
+ match pane {
+ Panes::Designer => match &self.designer_page {
+ DesignerPage::Designer => {
+ let el_tree = match self.project.content.clone() {
+ Some(tree) => tree.as_element(),
+ None => text("Open a project or begin creating one").into(),
+ };
+ let content = container(themer(self.project.get_theme(), el_tree))
+ .id(iced::widget::container::Id::new("drop_zone"))
+ .height(Length::Fill)
+ .width(Length::Fill);
+ let title = row![
+ text("Designer"),
+ Space::with_width(Length::Fill),
+ button("Switch to Code view")
+ .on_press(Message::SwitchPage(DesignerPage::CodeView)),
+ ]
+ .align_y(Alignment::Center);
+ let title_bar = pane_grid::TitleBar::new(title)
+ .padding(10)
+ .style(style::title_bar);
+ pane_grid::Content::new(content)
+ .title_bar(title_bar)
+ .style(if is_focused {
+ style::pane_focused
+ } else {
+ style::pane_active
+ })
+ }
+ DesignerPage::CodeView => {
+ let title = row![
+ text("Generated Code"),
+ Space::with_width(Length::Fill),
+ tooltip(
+ button(
+ container(
+ text('\u{0e801}').font(Font::with_name("editor-icons"))
+ )
+ .center_x(30)
+ )
+ .on_press(Message::CopyCode),
+ "Copy code to clipboard",
+ tooltip::Position::FollowCursor
+ ),
+ Space::with_width(20),
+ button("Switch to Designer view")
+ .on_press(Message::SwitchPage(DesignerPage::Designer))
+ ]
+ .align_y(Alignment::Center);
+ let title_bar = pane_grid::TitleBar::new(title)
+ .padding(10)
+ .style(style::title_bar);
+ pane_grid::Content::new(
+ text_editor(&self.editor_content)
+ .on_action(Message::EditorAction)
+ .highlight(
+ "rs",
+ if self.dark_theme {
+ highlighter::Theme::SolarizedDark
+ } else {
+ highlighter::Theme::InspiredGitHub
+ },
+ )
+ .height(Length::Fill)
+ .padding(20),
+ )
+ .title_bar(title_bar)
+ .style(if is_focused {
+ style::pane_focused
+ } else {
+ style::pane_active
+ })
+ }
+ },
+ Panes::ElementList => {
+ let items_list = items_list_view(self.element_list.clone());
+ let content = column![items_list]
+ .align_x(Alignment::Center)
+ .height(Length::Fill)
+ .width(Length::Fill);
+ let title = text("Element List");
+ let title_bar = pane_grid::TitleBar::new(title)
+ .padding(10)
+ .style(style::title_bar);
+ pane_grid::Content::new(content)
+ .title_bar(title_bar)
+ .style(if is_focused {
+ style::pane_focused
+ } else {
+ style::pane_active
+ })
+ }
+ }
+ })
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .spacing(10)
+ .on_resize(10, Message::PaneResized)
+ .on_click(Message::PaneClicked)
+ .on_drag(Message::PaneDragged);
+
+ let content = Column::new()
+ .push(header)
+ .push(pane_grid)
+ .spacing(5)
+ .align_x(Alignment::Center)
+ .width(Length::Fill);
+
+ container(content).height(Length::Fill).into()
+ }
+}
+
+fn items_list_view<'a>(items: Vec<ElementName>) -> Element<'a, Message> {
+ let mut column = Column::new()
+ .spacing(20)
+ .align_x(Alignment::Center)
+ .width(Length::Fill);
+
+ for item in items {
+ column = column.push(
+ droppable(text(item.clone().to_string()))
+ .on_drop(move |point, rect| Message::DropNewElement(item.clone(), point, rect)),
+ );
+ }
+
+ container(column)
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .into()
+}
+
+mod style {
+ use iced::widget::container::Style;
+ use iced::{Border, Theme};
+
+ pub fn title_bar(theme: &Theme) -> Style {
+ let palette = theme.extended_palette();
+
+ Style {
+ text_color: Some(palette.background.strong.text),
+ background: Some(palette.background.strong.color.into()),
+ ..Default::default()
+ }
+ }
+
+ pub fn pane_active(theme: &Theme) -> Style {
+ let palette = theme.extended_palette();
+
+ Style {
+ background: Some(palette.background.weak.color.into()),
+ border: Border {
+ width: 1.0,
+ color: palette.background.strong.color,
+ ..Border::default()
+ },
+ ..Default::default()
+ }
+ }
+
+ pub fn pane_focused(theme: &Theme) -> Style {
+ let palette = theme.extended_palette();
+
+ Style {
+ background: Some(palette.background.weak.color.into()),
+ border: Border {
+ width: 4.0,
+ color: palette.background.strong.color,
+ ..Border::default()
+ },
+ ..Default::default()
+ }
+ }
+}
diff --git a/iced_builder/src/types/element_name.rs b/iced_builder/src/types/element_name.rs
new file mode 100644
index 0000000..8d00814
--- /dev/null
+++ b/iced_builder/src/types/element_name.rs
@@ -0,0 +1,86 @@
+use serde::{Deserialize, Serialize};
+
+use crate::Error;
+
+use super::rendered_element::{
+ button, column, container, image, row, svg, text, ActionKind, RenderedElement,
+};
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub enum ElementName {
+ Text(String),
+ Button(String),
+ SVG(String),
+ Image(String),
+ Container,
+ Row,
+ Column,
+}
+
+impl ElementName {
+ pub const ALL: [Self; 7] = [
+ Self::Text(String::new()),
+ Self::Button(String::new()),
+ Self::SVG(String::new()),
+ Self::Image(String::new()),
+ Self::Container,
+ Self::Row,
+ Self::Column,
+ ];
+
+ pub fn handle_action(
+ &self,
+ element_tree: Option<&mut RenderedElement>,
+ action: ActionKind,
+ ) -> Result<Option<RenderedElement>, Error> {
+ let element = match self {
+ Self::Text(_) => text(""),
+ Self::Button(_) => button(""),
+ Self::SVG(_) => svg(""),
+ Self::Image(_) => image(""),
+ Self::Container => container(None),
+ Self::Row => row(None),
+ Self::Column => column(None),
+ };
+ match action {
+ ActionKind::Stop => Ok(None),
+ ActionKind::AddNew => Ok(Some(element)),
+ ActionKind::PushFront(id) => {
+ element_tree
+ .ok_or("The action was of kind `PushFront`, but no element tree was provided.")?
+ .find_by_id(id)
+ .ok_or(Error::NonExistentElement)?
+ .push_front(&element);
+ Ok(None)
+ }
+ ActionKind::InsertAfter(parent_id, child_id) => {
+ element_tree
+ .ok_or(
+ "The action was of kind `InsertAfter`, but no element tree was provided.",
+ )?
+ .find_by_id(parent_id)
+ .ok_or(Error::NonExistentElement)?
+ .insert_after(child_id, &element);
+ Ok(None)
+ }
+ }
+ }
+}
+
+impl std::fmt::Display for ElementName {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(
+ f,
+ "{}",
+ match self {
+ Self::Text(_) => "Text",
+ Self::Button(_) => "Button",
+ Self::SVG(_) => "SVG",
+ Self::Image(_) => "Image",
+ Self::Container => "Container",
+ Self::Row => "Row",
+ Self::Column => "Column",
+ }
+ )
+ }
+}
diff --git a/iced_builder/src/types/mod.rs b/iced_builder/src/types/mod.rs
new file mode 100644
index 0000000..a48a2d8
--- /dev/null
+++ b/iced_builder/src/types/mod.rs
@@ -0,0 +1,9 @@
+pub mod element_name;
+pub mod project;
+pub mod rendered_element;
+
+#[derive(Debug, Clone)]
+pub enum DesignerPage {
+ Designer,
+ CodeView,
+}
diff --git a/iced_builder/src/types/project.rs b/iced_builder/src/types/project.rs
new file mode 100644
index 0000000..0e0442a
--- /dev/null
+++ b/iced_builder/src/types/project.rs
@@ -0,0 +1,137 @@
+use rust_format::{Config, Edition, Formatter, RustFmt};
+use std::path::{Path, PathBuf};
+
+use iced::Theme;
+use serde::{Deserialize, Serialize};
+
+use crate::Error;
+
+use super::rendered_element::RenderedElement;
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct Project {
+ pub title: Option<String>,
+ pub theme: Option<String>,
+ pub content: Option<RenderedElement>,
+}
+
+impl Project {
+ pub fn new() -> Self {
+ Self {
+ title: None,
+ theme: None,
+ content: None,
+ }
+ }
+
+ pub fn get_theme(&self) -> Theme {
+ match &self.theme {
+ Some(theme) => match theme.as_str() {
+ "Light" => Theme::Light,
+ "Dark" => Theme::Dark,
+ "Dracula" => Theme::Dracula,
+ "Nord" => Theme::Nord,
+ "Solarized Light" => Theme::SolarizedLight,
+ "Solarized Dark" => Theme::SolarizedDark,
+ "Gruvbox Light" => Theme::GruvboxLight,
+ "Gruvbox Dark" => Theme::GruvboxDark,
+ "Catppuccin Latte" => Theme::CatppuccinLatte,
+ "Catppuccin Frappé" => Theme::CatppuccinFrappe,
+ "Catppuccin Macchiato" => Theme::CatppuccinMacchiato,
+ "Catppuccin Mocha" => Theme::CatppuccinMocha,
+ "Tokyo Night" => Theme::TokyoNight,
+ "Tokyo Night Storm" => Theme::TokyoNightStorm,
+ "Tokyo Night Light" => Theme::TokyoNightLight,
+ "Kanagawa Wave" => Theme::KanagawaWave,
+ "Kanagawa Dragon" => Theme::KanagawaDragon,
+ "Kanagawa Lotus" => Theme::KanagawaLotus,
+ "Moonfly" => Theme::Moonfly,
+ "Nightfly" => Theme::Nightfly,
+ "Oxocarbon" => Theme::Oxocarbon,
+ "Ferra" => Theme::Ferra,
+ _ => Theme::Dark,
+ },
+ None => Theme::Dark,
+ }
+ }
+
+ pub async fn from_file() -> Result<(PathBuf, Self), Error> {
+ let picked_file = rfd::AsyncFileDialog::new()
+ .set_title("Open a JSON file...")
+ .add_filter("*.JSON, *.json", &["JSON", "json"])
+ .pick_file()
+ .await
+ .ok_or(Error::DialogClosed)?;
+
+ let path = picked_file.path().to_owned();
+
+ let contents = tokio::fs::read_to_string(&path).await?;
+ let element: Self = serde_json::from_str(&contents)?;
+
+ Ok((path, element))
+ }
+
+ pub async fn write_to_file(self, path: Option<PathBuf>) -> Result<PathBuf, Error> {
+ let path = if let Some(p) = path {
+ p
+ } else {
+ rfd::AsyncFileDialog::new()
+ .set_title("Save to JSON file...")
+ .add_filter("*.JSON, *.json", &["JSON", "json"])
+ .save_file()
+ .await
+ .as_ref()
+ .map(rfd::FileHandle::path)
+ .map(Path::to_owned)
+ .ok_or(Error::DialogClosed)?
+ };
+
+ let contents = serde_json::to_string(&self.clone())?;
+ tokio::fs::write(&path, contents).await?;
+
+ Ok(path)
+ }
+
+ pub fn app_code(self) -> Result<String, Error> {
+ match &self.content {
+ Some(el) => {
+ let (imports, view) = el.codegen();
+ let mut app_code = format!("use iced::{{widget::{{{imports}}},Element}};");
+
+ app_code = format!(
+ r#"// Automatically generated by iced Builder
+ {app_code}
+
+ fn main() -> iced::Result {{
+ iced::run("{}", State::update, State::view)
+ }}
+
+ #[derive(Default)]
+ struct State;
+
+ #[derive(Debug, Clone)]
+ enum Message {{}}
+
+ impl State {{
+ fn update(&mut self, _message: Message) {{}}
+
+ fn view(&self) -> Element<Message> {{
+ {view}.into()
+ }}
+ }}"#,
+ match &self.title {
+ Some(t) => t,
+ None => "New app",
+ }
+ );
+ let config = Config::new_str()
+ .edition(Edition::Rust2021)
+ .option("trailing_comma", "Never")
+ .option("imports_granularity", "Crate");
+ let rustfmt = RustFmt::from_config(config);
+ Ok(rustfmt.format_str(app_code)?)
+ }
+ None => Err("No element tree present".into()),
+ }
+ }
+}
diff --git a/iced_builder/src/types/rendered_element.rs b/iced_builder/src/types/rendered_element.rs
new file mode 100755
index 0000000..e2bebfa
--- /dev/null
+++ b/iced_builder/src/types/rendered_element.rs
@@ -0,0 +1,430 @@
+use indexmap::IndexMap;
+
+use iced::advanced::widget::Id;
+use iced::{widget, Element, Length};
+use serde::{Deserialize, Serialize};
+use unique_id::{string::StringGenerator, Generator};
+
+use crate::{Error, Message};
+
+use super::element_name::ElementName;
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+pub struct RenderedElement {
+ id: String,
+ pub child_elements: Option<Vec<RenderedElement>>,
+ pub name: ElementName,
+ pub options: IndexMap<String, Option<String>>,
+}
+
+impl RenderedElement {
+ fn new(name: ElementName) -> Self {
+ let gen = StringGenerator::default();
+ Self {
+ id: gen.next_id(),
+ child_elements: None,
+ name,
+ options: IndexMap::new(),
+ }
+ }
+
+ fn with(name: ElementName, child_elements: Vec<RenderedElement>) -> Self {
+ let gen = StringGenerator::default();
+ Self {
+ id: gen.next_id(),
+ child_elements: Some(child_elements),
+ name,
+ options: IndexMap::new(),
+ }
+ }
+
+ pub fn get_id(&self) -> Id {
+ Id::new(self.id.clone())
+ }
+
+ pub fn find_by_id(&mut self, id: Id) -> Option<&mut Self> {
+ if self.get_id() == id.clone() {
+ return Some(self);
+ } else if let Some(child_elements) = self.child_elements.as_mut() {
+ for element in child_elements {
+ let element = element.find_by_id(id.clone());
+ if element.is_some() {
+ return element;
+ }
+ }
+ return None;
+ } else {
+ return None;
+ }
+ }
+
+ pub fn find_parent(&mut self, child_element: &RenderedElement) -> Option<&mut Self> {
+ if child_element == self {
+ return Some(self);
+ } else if self.child_elements.is_some() {
+ if self
+ .child_elements
+ .clone()
+ .unwrap_or(vec![])
+ .contains(child_element)
+ {
+ return Some(self);
+ } else {
+ if let Some(child_elements) = self.child_elements.as_mut() {
+ for element in child_elements {
+ let element = element.find_parent(child_element);
+ if element.is_some() {
+ return element;
+ }
+ }
+ }
+ return None;
+ }
+ } else {
+ return None;
+ }
+ }
+
+ pub fn is_parent(&self) -> bool {
+ self.child_elements.is_some()
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.child_elements == Some(vec![])
+ }
+
+ pub fn remove(&mut self, element: &RenderedElement) {
+ if let Some(child_elements) = self.child_elements.as_mut() {
+ if let Some(index) = child_elements.iter().position(|x| x == element) {
+ child_elements.remove(index);
+ }
+ }
+ }
+
+ pub fn push_front(&mut self, element: &RenderedElement) {
+ if let Some(child_elements) = self.child_elements.as_mut() {
+ child_elements.insert(0, element.clone());
+ }
+ }
+
+ pub fn insert_after(&mut self, id: Id, element: &RenderedElement) {
+ if let Some(child_elements) = self.child_elements.as_mut() {
+ if let Some(index) = child_elements
+ .iter()
+ .position(|x| Id::new(x.id.clone()) == id)
+ {
+ child_elements.insert(index + 1, element.clone());
+ } else {
+ child_elements.push(element.clone());
+ }
+ }
+ }
+
+ pub fn handle_action(
+ &self,
+ element_tree: Option<&mut RenderedElement>,
+ action: ActionKind,
+ ) -> Result<(), Error> {
+ let element_tree = element_tree.unwrap();
+
+ match action {
+ ActionKind::Stop => Ok(()),
+ ActionKind::AddNew => Err(
+ "The action was of kind `AddNew`, but invoking it on an existing element tree is not possible.".into(),
+ ),
+ ActionKind::PushFront(id) => {
+ let old_parent = element_tree.find_parent(self).unwrap();
+ old_parent.remove(self);
+
+ let new_parent = element_tree.find_by_id(id).unwrap();
+ new_parent.push_front(self);
+
+ Ok(())
+ }
+ ActionKind::InsertAfter(parent_id, target_id) => {
+ let old_parent = element_tree.find_parent(self).unwrap();
+ old_parent.remove(self);
+
+ let new_parent = element_tree.find_by_id(parent_id).unwrap();
+ new_parent.insert_after(target_id, self);
+
+ Ok(())
+ }
+ }
+ }
+
+ fn preset_options(mut self, options: Vec<&str>) -> Self {
+ for opt in options {
+ self.options.insert(opt.to_owned(), None);
+ }
+ self
+ }
+
+ pub fn option<'a>(&mut self, option: &'a str, value: &'a str) -> Self {
+ self.options
+ .entry(option.to_owned())
+ .and_modify(|opt| *opt = Some(value.to_owned()));
+ self.clone()
+ }
+
+ pub fn as_element<'a>(self) -> Element<'a, Message> {
+ let mut children = widget::column![];
+
+ if let Some(els) = self.child_elements.clone() {
+ for el in els {
+ children = children.push(el.clone().as_element());
+ }
+ }
+ iced_drop::droppable(
+ widget::container(
+ widget::column![widget::text(self.name.clone().to_string()), children]
+ .width(Length::Fill),
+ )
+ .padding(10)
+ .style(widget::container::bordered_box),
+ )
+ .id(self.get_id())
+ .drag_hide(true)
+ .on_drop(move |point, rect| Message::MoveElement(self.clone(), point, rect))
+ .into()
+ }
+
+ fn props_codegen(&self) -> String {
+ let mut props_string = String::new();
+
+ for (k, v) in self.options.clone() {
+ if let Some(v) = v {
+ props_string = format!("{props_string}.{k}({v})");
+ }
+ }
+
+ props_string
+ }
+
+ pub fn codegen(&self) -> (String, String) {
+ let mut imports = String::new();
+ let mut view = String::new();
+ let props = self.props_codegen();
+
+ let mut elements = String::new();
+
+ if let Some(els) = &self.child_elements {
+ for element in els {
+ let (c_imports, children) = element.codegen();
+ imports = format!("{imports}{c_imports}");
+ elements = format!("{elements}{},", children);
+ }
+ }
+
+ match &self.name {
+ ElementName::Container => {
+ imports = format!("{imports}container,");
+ view = format!("{view}\ncontainer({elements}){props}");
+ }
+ ElementName::Row => {
+ imports = format!("{imports}row,");
+ view = format!("{view}\nrow![{elements}]{props}");
+ }
+ ElementName::Column => {
+ imports = format!("{imports}column,");
+ view = format!("{view}\ncolumn![{elements}]{props}");
+ }
+ ElementName::Text(string) => {
+ imports = format!("{imports}text,");
+ view = format!(
+ "{view}\ntext(\"{}\"){props}",
+ if *string == String::new() {
+ "New Text"
+ } else {
+ string
+ }
+ );
+ }
+ ElementName::Button(string) => {
+ imports = format!("{imports}button,");
+ view = format!(
+ "{view}\nbutton(\"{}\"){props}",
+ if *string == String::new() {
+ "New Button"
+ } else {
+ string
+ }
+ );
+ }
+ ElementName::Image(path) => {
+ imports = format!("{imports}image,");
+ view = format!("{view}\nimage(\"{path}\"){props}");
+ }
+ ElementName::SVG(path) => {
+ imports = format!("{imports}svg,");
+ view = format!("{view}\nsvg(\"{path}\"){props}");
+ }
+ }
+
+ (imports, view)
+ }
+
+ pub fn test() -> RenderedElement {
+ let text1 = text("wow").option("height", "120.5").option("width", "230");
+
+ let element = container(Some(row(Some(vec![
+ text1,
+ text("heh"),
+ svg("/mnt/drive_d/git/obs-website/src/lib/assets/bars-solid.svg"),
+ ]))));
+
+ element
+ }
+}
+
+impl std::fmt::Display for RenderedElement {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ let mut has_props = false;
+ f.pad("")?;
+ f.write_fmt(format_args!("{:?}\n", self.name))?;
+ f.pad("")?;
+ f.write_str("Options: (")?;
+ for (k, v) in &self.options {
+ if let Some(value) = v {
+ has_props = true;
+ f.write_fmt(format_args!(
+ "\n{:width$.precision$}{}: {}",
+ "",
+ k,
+ value,
+ width = f.width().unwrap_or(0) + f.precision().unwrap_or(0),
+ precision = f.precision().unwrap_or(0)
+ ))?;
+ }
+ }
+ if has_props {
+ f.write_str("\n")?;
+ f.pad("")?;
+ }
+ f.write_str(")")?;
+ if let Some(els) = &self.child_elements {
+ f.write_str(" {\n")?;
+ for el in els {
+ f.write_fmt(format_args!(
+ "\n{:width$.precision$}\n",
+ el,
+ width = f.width().unwrap_or(0) + f.precision().unwrap_or(0),
+ precision = f.precision().unwrap_or(0)
+ ))?;
+ }
+ f.pad("")?;
+ f.write_str("}")?;
+ }
+ Ok(())
+ }
+}
+
+#[derive(Debug, Clone)]
+pub enum ActionKind {
+ AddNew,
+ PushFront(Id),
+ InsertAfter(Id, Id),
+ Stop,
+}
+
+impl ActionKind {
+ pub fn new(
+ ids: Vec<Id>,
+ element_tree: &mut Option<RenderedElement>,
+ source_id: Option<Id>,
+ ) -> Self {
+ let mut action = Self::Stop;
+ if ids.len() == 1 {
+ if element_tree.is_none() {
+ action = Self::AddNew;
+ }
+ } else {
+ let id: Id = match source_id {
+ Some(id) if ids.contains(&id) => {
+ let element_id = ids[ids.iter().position(|x| *x == id).unwrap()].clone();
+ if ids.len() > 2 && ids[ids.clone().len() - 1] == element_id {
+ return Self::Stop;
+ }
+ element_id
+ }
+ _ => ids.last().cloned().unwrap(),
+ };
+ let element = element_tree
+ .as_mut()
+ .unwrap()
+ .find_by_id(id.clone())
+ .unwrap();
+
+ match (
+ element.is_parent(),
+ element.name == ElementName::Container && !element.is_empty(),
+ ) {
+ (true, false) => {
+ action = Self::PushFront(id);
+ }
+ _ if ids.len() > 2 => {
+ let parent = element_tree
+ .as_mut()
+ .unwrap()
+ .find_by_id(ids[&ids.len() - 2].clone())
+ .unwrap();
+
+ if parent.name == ElementName::Container
+ && parent.child_elements != Some(vec![])
+ {
+ action = Self::Stop;
+ } else {
+ action = Self::InsertAfter(
+ ids[&ids.len() - 2].clone(),
+ ids[&ids.len() - 1].clone(),
+ );
+ }
+ }
+ _ => {}
+ }
+ }
+ action
+ }
+}
+
+pub fn text(text: &str) -> RenderedElement {
+ RenderedElement::new(ElementName::Text(text.to_owned())).preset_options(vec![
+ "size",
+ "line_height",
+ "width",
+ "height",
+ ])
+}
+
+pub fn button(text: &str) -> RenderedElement {
+ RenderedElement::new(ElementName::Button(text.to_owned()))
+}
+
+pub fn svg(path: &str) -> RenderedElement {
+ RenderedElement::new(ElementName::SVG(path.to_owned()))
+}
+
+pub fn image(path: &str) -> RenderedElement {
+ RenderedElement::new(ElementName::Image(path.to_owned()))
+}
+
+pub fn container(content: Option<RenderedElement>) -> RenderedElement {
+ match content {
+ Some(el) => RenderedElement::with(ElementName::Container, vec![el]),
+ None => RenderedElement::with(ElementName::Container, vec![]),
+ }
+}
+
+pub fn row(child_elements: Option<Vec<RenderedElement>>) -> RenderedElement {
+ match child_elements {
+ Some(els) => RenderedElement::with(ElementName::Row, els),
+ None => RenderedElement::with(ElementName::Row, vec![]),
+ }
+}
+
+pub fn column(child_elements: Option<Vec<RenderedElement>>) -> RenderedElement {
+ match child_elements {
+ Some(els) => RenderedElement::with(ElementName::Column, els),
+ None => RenderedElement::with(ElementName::Column, vec![]),
+ }
+}
diff --git a/iced_drop/.gitignore b/iced_drop/.gitignore
new file mode 100644
index 0000000..ff0d847
--- /dev/null
+++ b/iced_drop/.gitignore
@@ -0,0 +1,3 @@
+/target
+/.vscode
+Cargo.lock
diff --git a/iced_drop/Cargo.toml b/iced_drop/Cargo.toml
new file mode 100644
index 0000000..40beeb0
--- /dev/null
+++ b/iced_drop/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "iced_drop"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies.iced]
+version = "0.13.1"
+features = ["advanced"]
diff --git a/iced_drop/LICENSE b/iced_drop/LICENSE
new file mode 100644
index 0000000..89d9fee
--- /dev/null
+++ b/iced_drop/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 jhannyj
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/iced_drop/README.md b/iced_drop/README.md
new file mode 100644
index 0000000..3768d54
--- /dev/null
+++ b/iced_drop/README.md
@@ -0,0 +1,75 @@
+# iced_drop
+
+# Modified to use iced 0.13.1 for compatibility
+
+A small library which provides a custom widget and operation to make drag and drop easier to implement in [iced](https://github.com/iced-rs/iced/tree/master)
+
+## Usage
+
+To add drag and drog functionality, first define two messages with the following format
+
+```rust
+enum Message {
+ Drop(iced::Point, iced::Rectangle)
+ HandleZones(Vec<(iced::advanced::widget::Id, iced::Rectangle)>)
+}
+```
+
+The `Drop` message will be sent when the droppable is being dragged, and the left mouse button is released. This message provides the mouse position and layout boundaries of the droppable at the release point.
+
+The `HandleZones` message will be sent after an operation that finds the drop zones under the mouse position. It provides the Id and bounds for each drop zone.
+
+Next, create create a droppable in the view method and assign the on_drop message. The dropopable function takes an `impl Into<Element>` object, so it's easy to make a droppable from any iced widget.
+
+```rust
+iced_drop::droppable("Drop me!").on_drop(Message::Drop);
+```
+
+Next, create a "drop zone." A drop zone is any widget that operates like a container andhas some assigned Id. It's important that the widget is assigned some Id or it won't be recognized as a drop zone.
+
+```rust
+iced::widget::container("Drop zone")
+ .id(iced::widget::container::Id::new("drop_zone"));
+```
+
+Finally, handle the updates of the drop messages
+
+```rust
+match message {
+ Message::Drop(cursor_pos, _) => {
+ return iced_drop::zones_on_point(
+ Message::HandleZonesFound,
+ point,
+ None,
+ None,
+ );
+ }
+ Message::HandleZones(zones) => {
+ println!("{:?}", zones)
+ }
+}
+```
+
+On Drop, we return a widget operation that looks for drop zones under the cursor_pos. When this operation finishes, it returns the zones found and sends the `HandleZones` message. In this example, we only defined one zone, so the zones vector will either be empty if the droppable was not dropped on the zone, or it will contain the `drop_zone`
+
+## Examples
+
+There are two examples: color, todo.
+
+The color example is a very basic drag/drop showcase where the user can drag colors into zones and change the zone's color. I would start here.
+
+[Link to video](https://drive.google.com/file/d/1K1CCi2Lc90IUyDufsvoUBZmUCbeg6_Fi/view?usp=sharing)
+
+To run this examples: `cargo run -p color`
+
+The todo example is a basic todo board application similar to Trello. This is a much much more complex example as it handles custom highlighting and nested droppables, but it just shows you can make some pretty cool things with iced.
+
+[Link to video](https://drive.google.com/file/d/1MLOCk4Imd_oUnrTj_psbpYbwua976HmR/view?usp=sharing)
+
+To run this example try: `cargo run -p todo`
+
+Note: the todo example might also be a good example on how one can use operations. Check examples/todo/src/operation.rs. I didn't find any other examples of this in the iced repo except for the built in focus operations.
+
+## Future Development
+
+Right now it's a little annoying having to work with iced's Id type. At some point, I will work on a drop_zone widget that can take some generic clonable type as an id, and I will create a seperate find_zones operation that will return a list of this custom Id. This should make it easier to determine which drop zones were found.
diff --git a/iced_drop/src/lib.rs b/iced_drop/src/lib.rs
new file mode 100644
index 0000000..9906cbe
--- /dev/null
+++ b/iced_drop/src/lib.rs
@@ -0,0 +1,53 @@
+pub mod widget;
+
+use iced::{
+ advanced::widget::{operate, Id},
+ advanced::{graphics::futures::MaybeSend, renderer},
+ task::Task,
+ Element, Point, Rectangle,
+};
+
+use widget::droppable::*;
+use widget::operation::drop;
+
+pub fn droppable<'a, Message, Theme, Renderer>(
+ content: impl Into<Element<'a, Message, Theme, Renderer>>,
+) -> Droppable<'a, Message, Theme, Renderer>
+where
+ Message: Clone,
+ Renderer: renderer::Renderer,
+{
+ Droppable::new(content)
+}
+
+pub fn zones_on_point<T, MF>(
+ msg: MF,
+ point: Point,
+ options: Option<Vec<Id>>,
+ depth: Option<usize>,
+) -> Task<T>
+where
+ T: Send + 'static,
+ MF: Fn(Vec<(Id, Rectangle)>) -> T + MaybeSend + Sync + Clone + 'static,
+{
+ operate(drop::find_zones(
+ move |bounds| bounds.contains(point),
+ options,
+ depth,
+ ))
+ .map(move |id| msg(id))
+}
+
+pub fn find_zones<Message, MF, F>(
+ msg: MF,
+ filter: F,
+ options: Option<Vec<Id>>,
+ depth: Option<usize>,
+) -> Task<Message>
+where
+ Message: Send + 'static,
+ MF: Fn(Vec<(Id, Rectangle)>) -> Message + MaybeSend + Sync + Clone + 'static,
+ F: Fn(&Rectangle) -> bool + Send + 'static,
+{
+ operate(drop::find_zones(filter, options, depth)).map(move |id| msg(id))
+}
diff --git a/iced_drop/src/widget.rs b/iced_drop/src/widget.rs
new file mode 100644
index 0000000..6b3fed2
--- /dev/null
+++ b/iced_drop/src/widget.rs
@@ -0,0 +1,2 @@
+pub mod droppable;
+pub mod operation;
diff --git a/iced_drop/src/widget/droppable.rs b/iced_drop/src/widget/droppable.rs
new file mode 100644
index 0000000..80d8600
--- /dev/null
+++ b/iced_drop/src/widget/droppable.rs
@@ -0,0 +1,499 @@
+//! Encapsulates a widget that can be dragged and dropped.
+use std::fmt::Debug;
+use std::vec;
+
+use iced::advanced::widget::{Operation, Tree, Widget};
+use iced::advanced::{self, layout, mouse, overlay, renderer, Layout};
+use iced::event::Status;
+use iced::{Element, Point, Rectangle, Size, Vector};
+
+/// An element that can be dragged and dropped on a [`DropZone`]
+pub struct Droppable<'a, Message, Theme = iced::Theme, Renderer = iced::Renderer>
+where
+ Message: Clone,
+ Renderer: renderer::Renderer,
+{
+ content: Element<'a, Message, Theme, Renderer>,
+ id: Option<iced::advanced::widget::Id>,
+ on_click: Option<Message>,
+ on_drop: Option<Box<dyn Fn(Point, Rectangle) -> Message + 'a>>,
+ on_drag: Option<Box<dyn Fn(Point, Rectangle) -> Message + 'a>>,
+ on_cancel: Option<Message>,
+ drag_mode: Option<(bool, bool)>,
+ drag_overlay: bool,
+ drag_hide: bool,
+ drag_center: bool,
+ drag_size: Option<Size>,
+ reset_delay: usize,
+}
+
+impl<'a, Message, Theme, Renderer> Droppable<'a, Message, Theme, Renderer>
+where
+ Message: Clone,
+ Renderer: renderer::Renderer,
+{
+ /// Creates a new [`Droppable`].
+ pub fn new(content: impl Into<Element<'a, Message, Theme, Renderer>>) -> Self {
+ Self {
+ content: content.into(),
+ id: None,
+ on_click: None,
+ on_drop: None,
+ on_drag: None,
+ on_cancel: None,
+ drag_mode: Some((true, true)),
+ drag_overlay: true,
+ drag_hide: false,
+ drag_center: false,
+ drag_size: None,
+ reset_delay: 0,
+ }
+ }
+
+ /// Sets the unique identifier of the [`Droppable`].
+ pub fn id(mut self, id: iced::advanced::widget::Id) -> Self {
+ self.id = Some(id);
+ self
+ }
+
+ /// Sets the message that will be produced when the [`Droppable`] is clicked.
+ pub fn on_click(mut self, message: Message) -> Self {
+ self.on_click = Some(message);
+ self
+ }
+
+ /// Sets the message that will be produced when the [`Droppable`] is dropped on a [`DropZone`].
+ ///
+ /// Unless this is set, the [`Droppable`] will be disabled.
+ pub fn on_drop<F>(mut self, message: F) -> Self
+ where
+ F: Fn(Point, Rectangle) -> Message + 'a,
+ {
+ self.on_drop = Some(Box::new(message));
+ self
+ }
+
+ /// Sets the message that will be produced when the [`Droppable`] is dragged.
+ pub fn on_drag<F>(mut self, message: F) -> Self
+ where
+ F: Fn(Point, Rectangle) -> Message + 'a,
+ {
+ self.on_drag = Some(Box::new(message));
+ self
+ }
+
+ /// Sets the message that will be produced when the user right clicks while dragging the [`Droppable`].
+ pub fn on_cancel(mut self, message: Message) -> Self {
+ self.on_cancel = Some(message);
+ self
+ }
+
+ /// Sets whether the [`Droppable`] should be drawn under the cursor while dragging.
+ pub fn drag_overlay(mut self, drag_overlay: bool) -> Self {
+ self.drag_overlay = drag_overlay;
+ self
+ }
+
+ /// Sets whether the [`Droppable`] should be hidden while dragging.
+ pub fn drag_hide(mut self, drag_hide: bool) -> Self {
+ self.drag_hide = drag_hide;
+ self
+ }
+
+ /// Sets whether the [`Droppable`] should be centered on the cursor while dragging.
+ pub fn drag_center(mut self, drag_center: bool) -> Self {
+ self.drag_center = drag_center;
+ self
+ }
+
+ // Sets whether the [`Droppable`] can be dragged along individual axes.
+ pub fn drag_mode(mut self, drag_x: bool, drag_y: bool) -> Self {
+ self.drag_mode = Some((drag_x, drag_y));
+ self
+ }
+
+ /// Sets whether the [`Droppable`] should be be resized to a given size while dragging.
+ pub fn drag_size(mut self, hide_size: Size) -> Self {
+ self.drag_size = Some(hide_size);
+ self
+ }
+
+ /// Sets the number of frames/layout calls to wait before resetting the size of the [`Droppable`] after dropping.
+ ///
+ /// This is useful for cases where the [`Droppable`] is being moved to a new location after some widget operation.
+ /// In this case, the [`Droppable`] will mainting the 'drag_size' for the given number of frames before resetting to its original size.
+ /// This prevents the [`Droppable`] from 'jumping' back to its original size before the new location is rendered which
+ /// prevents flickering.
+ ///
+ /// Warning: this should only be set if there's is some noticeble flickering when the [`Droppable`] is dropped. That is, if the
+ /// [`Droppable`] returns to its original size before it's moved to it's new location.
+ pub fn reset_delay(mut self, reset_delay: usize) -> Self {
+ self.reset_delay = reset_delay;
+ self
+ }
+}
+
+impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
+ for Droppable<'a, Message, Theme, Renderer>
+where
+ Message: Clone,
+ Renderer: renderer::Renderer,
+{
+ fn state(&self) -> iced::advanced::widget::tree::State {
+ advanced::widget::tree::State::new(State::default())
+ }
+
+ fn tag(&self) -> iced::advanced::widget::tree::Tag {
+ advanced::widget::tree::Tag::of::<State>()
+ }
+
+ fn children(&self) -> Vec<iced::advanced::widget::Tree> {
+ vec![advanced::widget::Tree::new(&self.content)]
+ }
+
+ fn diff(&self, tree: &mut iced::advanced::widget::Tree) {
+ tree.diff_children(std::slice::from_ref(&self.content))
+ }
+
+ fn size(&self) -> iced::Size<iced::Length> {
+ self.content.as_widget().size()
+ }
+
+ fn on_event(
+ &mut self,
+ tree: &mut iced::advanced::widget::Tree,
+ event: iced::Event,
+ layout: iced::advanced::Layout<'_>,
+ cursor: iced::advanced::mouse::Cursor,
+ _renderer: &Renderer,
+ _clipboard: &mut dyn iced::advanced::Clipboard,
+ shell: &mut iced::advanced::Shell<'_, Message>,
+ _viewport: &iced::Rectangle,
+ ) -> iced::advanced::graphics::core::event::Status {
+ // handle the on event of the content first, in case that the droppable is nested
+ let status = self.content.as_widget_mut().on_event(
+ &mut tree.children[0],
+ event.clone(),
+ layout,
+ cursor,
+ _renderer,
+ _clipboard,
+ shell,
+ _viewport,
+ );
+ // this should really only be captured if the droppable is nested or it contains some other
+ // widget that captures the event
+ if status == Status::Captured {
+ return status;
+ };
+
+ if let Some(on_drop) = self.on_drop.as_deref() {
+ let state = tree.state.downcast_mut::<State>();
+ if let iced::Event::Mouse(mouse) = event {
+ match mouse {
+ mouse::Event::ButtonPressed(btn) => {
+ if btn == mouse::Button::Left && cursor.is_over(layout.bounds()) {
+ // select the droppable and store the position of the widget before dragging
+ state.action = Action::Select(cursor.position().unwrap());
+ let bounds = layout.bounds();
+ state.widget_pos = bounds.position();
+ state.overlay_bounds.width = bounds.width;
+ state.overlay_bounds.height = bounds.height;
+
+ if let Some(on_click) = self.on_click.clone() {
+ shell.publish(on_click);
+ }
+ return Status::Captured;
+ } else if btn == mouse::Button::Right {
+ if let Action::Drag(_, _) = state.action {
+ shell.invalidate_layout();
+ state.action = Action::None;
+ if let Some(on_cancel) = self.on_cancel.clone() {
+ shell.publish(on_cancel);
+ }
+ }
+ }
+ }
+ mouse::Event::CursorMoved { mut position } => match state.action {
+ Action::Select(start) | Action::Drag(start, _) => {
+ // calculate the new position of the widget after dragging
+
+ if let Some((drag_x, drag_y)) = self.drag_mode {
+ position = Point {
+ x: if drag_x { position.x } else { start.x },
+ y: if drag_y { position.y } else { start.y },
+ };
+ }
+
+ state.action = Action::Drag(start, position);
+ // update the position of the overlay since the cursor was moved
+ if self.drag_center {
+ state.overlay_bounds.x =
+ position.x - state.overlay_bounds.width / 2.0;
+ state.overlay_bounds.y =
+ position.y - state.overlay_bounds.height / 2.0;
+ } else {
+ state.overlay_bounds.x = state.widget_pos.x + position.x - start.x;
+ state.overlay_bounds.y = state.widget_pos.y + position.y - start.y;
+ }
+ // send on drag msg
+ if let Some(on_drag) = self.on_drag.as_deref() {
+ let message = (on_drag)(position, state.overlay_bounds);
+ shell.publish(message);
+ }
+ }
+ _ => (),
+ },
+ mouse::Event::ButtonReleased(btn) => {
+ if btn == mouse::Button::Left {
+ match state.action {
+ Action::Select(_) => {
+ state.action = Action::None;
+ }
+ Action::Drag(_, current) => {
+ // send on drop msg
+ let message = (on_drop)(current, state.overlay_bounds);
+ shell.publish(message);
+
+ if self.reset_delay == 0 {
+ state.action = Action::None;
+ } else {
+ state.action = Action::Wait(self.reset_delay);
+ }
+ }
+ _ => (),
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+ Status::Ignored
+ }
+
+ fn layout(
+ &self,
+ tree: &mut iced::advanced::widget::Tree,
+ renderer: &Renderer,
+ limits: &iced::advanced::layout::Limits,
+ ) -> iced::advanced::layout::Node {
+ let state: &mut State = tree.state.downcast_mut::<State>();
+ let content_node = self
+ .content
+ .as_widget()
+ .layout(&mut tree.children[0], renderer, limits);
+
+ // Adjust the size of the original widget if it's being dragged or we're wating to reset the size
+ if let Some(new_size) = self.drag_size {
+ match state.action {
+ Action::Drag(_, _) => {
+ return iced::advanced::layout::Node::with_children(
+ new_size,
+ content_node.children().to_vec(),
+ );
+ }
+ Action::Wait(reveal_index) => {
+ if reveal_index <= 1 {
+ state.action = Action::None;
+ } else {
+ state.action = Action::Wait(reveal_index - 1);
+ }
+
+ return iced::advanced::layout::Node::with_children(
+ new_size,
+ content_node.children().to_vec(),
+ );
+ }
+ _ => (),
+ }
+ }
+
+ content_node
+ }
+
+ fn operate(
+ &self,
+ tree: &mut Tree,
+ layout: Layout<'_>,
+ renderer: &Renderer,
+ operation: &mut dyn Operation,
+ ) {
+ let state = tree.state.downcast_mut::<State>();
+ operation.custom(state, self.id.as_ref());
+ operation.container(self.id.as_ref(), layout.bounds(), &mut |operation| {
+ self.content
+ .as_widget()
+ .operate(&mut tree.children[0], layout, renderer, operation);
+ });
+ }
+
+ fn draw(
+ &self,
+ tree: &iced::advanced::widget::Tree,
+ renderer: &mut Renderer,
+ theme: &Theme,
+ style: &renderer::Style,
+ layout: iced::advanced::Layout<'_>,
+ cursor: iced::advanced::mouse::Cursor,
+ viewport: &iced::Rectangle,
+ ) {
+ let state: &State = tree.state.downcast_ref::<State>();
+ if let Action::Drag(_, _) = state.action {
+ if self.drag_hide {
+ return;
+ }
+ }
+
+ self.content.as_widget().draw(
+ &tree.children[0],
+ renderer,
+ theme,
+ style,
+ layout,
+ cursor,
+ &viewport,
+ );
+ }
+
+ fn overlay<'b>(
+ &'b mut self,
+ tree: &'b mut Tree,
+ layout: Layout<'_>,
+ renderer: &Renderer,
+ _translation: Vector,
+ ) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
+ let state: &mut State = tree.state.downcast_mut::<State>();
+ let mut children = tree.children.iter_mut();
+ if self.drag_overlay {
+ if let Action::Drag(_, _) = state.action {
+ return Some(overlay::Element::new(Box::new(Overlay {
+ content: &self.content,
+ tree: children.next().unwrap(),
+ overlay_bounds: state.overlay_bounds,
+ })));
+ }
+ }
+ self.content.as_widget_mut().overlay(
+ children.next().unwrap(),
+ layout,
+ renderer,
+ _translation,
+ )
+ }
+
+ fn mouse_interaction(
+ &self,
+ tree: &iced::advanced::widget::Tree,
+ layout: iced::advanced::Layout<'_>,
+ cursor: iced::advanced::mouse::Cursor,
+ _viewport: &iced::Rectangle,
+ _renderer: &Renderer,
+ ) -> iced::advanced::mouse::Interaction {
+ let child_interact = self.content.as_widget().mouse_interaction(
+ &tree.children[0],
+ layout,
+ cursor,
+ _viewport,
+ _renderer,
+ );
+ if child_interact != mouse::Interaction::default() {
+ return child_interact;
+ }
+
+ let state = tree.state.downcast_ref::<State>();
+
+ if self.on_drop.is_none() {
+ return mouse::Interaction::NotAllowed;
+ }
+ if let Action::Drag(_, _) = state.action {
+ return mouse::Interaction::Grabbing;
+ }
+ if cursor.is_over(layout.bounds()) {
+ return mouse::Interaction::Pointer;
+ }
+ mouse::Interaction::default()
+ }
+}
+
+impl<'a, Message, Theme, Renderer> From<Droppable<'a, Message, Theme, Renderer>>
+ for Element<'a, Message, Theme, Renderer>
+where
+ Message: 'a + Clone,
+ Theme: 'a,
+ Renderer: 'a + renderer::Renderer,
+{
+ fn from(
+ droppable: Droppable<'a, Message, Theme, Renderer>,
+ ) -> Element<'a, Message, Theme, Renderer> {
+ Element::new(droppable)
+ }
+}
+
+#[derive(Default, Clone, Copy, PartialEq, Debug)]
+pub struct State {
+ widget_pos: Point,
+ overlay_bounds: Rectangle,
+ action: Action,
+}
+
+#[derive(Default, Clone, Copy, PartialEq, Debug)]
+pub enum Action {
+ #[default]
+ None,
+ /// (point clicked)
+ Select(Point),
+ /// (start pos, current pos)
+ Drag(Point, Point),
+ /// (frames to wait)
+ Wait(usize),
+}
+
+struct Overlay<'a, 'b, Message, Theme, Renderer>
+where
+ Renderer: renderer::Renderer,
+{
+ content: &'b Element<'a, Message, Theme, Renderer>,
+ tree: &'b mut advanced::widget::Tree,
+ overlay_bounds: Rectangle,
+}
+
+impl<'a, 'b, Message, Theme, Renderer> overlay::Overlay<Message, Theme, Renderer>
+ for Overlay<'a, 'b, Message, Theme, Renderer>
+where
+ Renderer: renderer::Renderer,
+{
+ fn layout(&mut self, renderer: &Renderer, _bounds: Size) -> layout::Node {
+ Widget::<Message, Theme, Renderer>::layout(
+ self.content.as_widget(),
+ self.tree,
+ renderer,
+ &layout::Limits::new(Size::ZERO, self.overlay_bounds.size()),
+ )
+ .move_to(self.overlay_bounds.position())
+ }
+
+ fn draw(
+ &self,
+ renderer: &mut Renderer,
+ theme: &Theme,
+ inherited_style: &renderer::Style,
+ layout: Layout<'_>,
+ cursor_position: mouse::Cursor,
+ ) {
+ Widget::<Message, Theme, Renderer>::draw(
+ self.content.as_widget(),
+ self.tree,
+ renderer,
+ theme,
+ inherited_style,
+ layout,
+ cursor_position,
+ &Rectangle::with_size(Size::INFINITY),
+ );
+ }
+
+ fn is_over(&self, _layout: Layout<'_>, _renderer: &Renderer, _cursor_position: Point) -> bool {
+ false
+ }
+}
diff --git a/iced_drop/src/widget/operation.rs b/iced_drop/src/widget/operation.rs
new file mode 100644
index 0000000..3d7dcff
--- /dev/null
+++ b/iced_drop/src/widget/operation.rs
@@ -0,0 +1 @@
+pub mod drop;
diff --git a/iced_drop/src/widget/operation/drop.rs b/iced_drop/src/widget/operation/drop.rs
new file mode 100644
index 0000000..a76181c
--- /dev/null
+++ b/iced_drop/src/widget/operation/drop.rs
@@ -0,0 +1,90 @@
+use iced::{
+ advanced::widget::{
+ operation::{Outcome, Scrollable},
+ Id, Operation,
+ },
+ Rectangle, Vector,
+};
+
+/// Produces an [`Operation`] that will find the drop zones that pass a filter on the zone's bounds.
+/// For any drop zone to be considered, the Element must have some Id.
+/// If `options` is `None`, all drop zones will be considered.
+/// Depth determines how how deep into nested drop zones to go.
+/// If 'depth' is `None`, nested dropzones will be fully explored
+pub fn find_zones<F>(
+ filter: F,
+ options: Option<Vec<Id>>,
+ depth: Option<usize>,
+) -> impl Operation<Vec<(Id, Rectangle)>>
+where
+ F: Fn(&Rectangle) -> bool + Send + 'static,
+{
+ struct FindDropZone<F> {
+ filter: F,
+ options: Option<Vec<Id>>,
+ zones: Vec<(Id, Rectangle)>,
+ max_depth: Option<usize>,
+ c_depth: usize,
+ offset: Vector,
+ }
+
+ impl<F> Operation<Vec<(Id, Rectangle)>> for FindDropZone<F>
+ where
+ F: Fn(&Rectangle) -> bool + Send + 'static,
+ {
+ fn container(
+ &mut self,
+ id: Option<&Id>,
+ bounds: iced::Rectangle,
+ operate_on_children: &mut dyn FnMut(&mut dyn Operation<Vec<(Id, Rectangle)>>),
+ ) {
+ match id {
+ Some(id) => {
+ let is_option = match &self.options {
+ Some(options) => options.contains(id),
+ None => true,
+ };
+ let bounds = bounds - self.offset;
+ if is_option && (self.filter)(&bounds) {
+ self.c_depth += 1;
+ self.zones.push((id.clone(), bounds));
+ }
+ }
+ None => (),
+ }
+ let goto_next = match &self.max_depth {
+ Some(m_depth) => self.c_depth < *m_depth,
+ None => true,
+ };
+ if goto_next {
+ operate_on_children(self);
+ }
+ }
+
+ fn finish(&self) -> Outcome<Vec<(Id, Rectangle)>> {
+ Outcome::Some(self.zones.clone())
+ }
+
+ fn scrollable(
+ &mut self,
+ _state: &mut dyn Scrollable,
+ _id: Option<&Id>,
+ bounds: Rectangle,
+ _content_bounds: Rectangle,
+ translation: Vector,
+ ) {
+ if (self.filter)(&bounds) {
+ self.offset = self.offset + translation;
+ }
+ }
+ }
+
+ FindDropZone {
+ filter,
+ options,
+ zones: vec![],
+ max_depth: depth,
+ c_depth: 0,
+ offset: Vector { x: 0.0, y: 0.0 },
+ }
+}
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
deleted file mode 100644
index 2dd9cff..0000000
--- a/src/codegen/mod.rs
+++ /dev/null
@@ -1,160 +0,0 @@
-use std::path::PathBuf;
-
-use rust_format::{Config, Edition, Formatter, RustFmt};
-
-use crate::types::{rendered_element::RenderedElement, ElementName};
-
-impl RenderedElement {
- fn props_codegen(&self) -> String {
- let mut props_string = String::new();
-
- for (k, v) in self.props.clone() {
- props_string = format!("{props_string}.{k}({v})");
- }
-
- props_string
- }
-
- fn codegen(&self) -> (String, String) {
- let mut imports = String::new();
- let mut view = String::new();
- let props = self.props_codegen();
-
- let mut elements = String::new();
-
- match self.name {
- ElementName::Column | ElementName::Row | ElementName::Container => {
- for element in &self.child_elements {
- let (c_imports, children) = element.codegen();
- imports = format!("{imports}{c_imports}");
- elements = format!("{elements}{},", children);
- }
- }
- _ => {}
- }
-
- match &self.name {
- ElementName::Container => {
- imports = format!("{imports}container,");
- view = if self.child_elements.len() < 2 {
- format!("{view}\ncontainer({elements}){props}")
- } else {
- format!("{view}\ncontainer(){props}")
- };
- }
- ElementName::Row => {
- imports = format!("{imports}row,");
- view = format!("{view}\nrow![{elements}]{props}");
- }
- ElementName::Column => {
- imports = format!("{imports}column,");
- view = format!("{view}\ncolumn![{elements}]{props}");
- }
- ElementName::Text(string) => {
- imports = format!("{imports}text,");
- view = format!(
- "{view}\ntext(\"{}\"){props}",
- if *string == String::new() {
- "New Text"
- } else {
- string
- }
- );
- }
- ElementName::Button(string) => {
- imports = format!("{imports}button,");
- view = format!(
- "{view}\nbutton(\"{}\"){props}",
- if *string == String::new() {
- "New Button"
- } else {
- string
- }
- );
- }
- ElementName::Image(path) => {
- imports = format!("{imports}image,");
- view = format!("{view}\nimage(\"{}\"){props}", path.display().to_string());
- }
- ElementName::SVG(path) => {
- imports = format!("{imports}svg,");
- view = format!("{view}\nsvg(\"{}\"){props}", path.display().to_string());
- }
- }
-
- (imports, view)
- }
-
- pub fn app_code(
- &self,
- title: &str,
- theme: Option<iced::Theme>,
- ) -> Result<String, Box<dyn std::error::Error>> {
- let (imports, view) = self.codegen();
- let mut app_code = format!("use iced::{{widget::{{{imports}}},Sandbox,Settings,Element}};");
-
- app_code = format!(
- r#"{app_code}
-
- fn main() -> iced::Result {{
- App::run(Settings::default())
- }}
-
- struct App;
-
- impl Sandbox for App {{
- type Message = ();
-
- fn new() -> Self {{
- Self {{}}
- }}
-
- fn title(&self) -> String {{
- "{title}".into()
- }}
-
- fn theme(&self) -> iced::Theme {{
- iced::Theme::{}
- }}
-
- fn update(&mut self, message: Self::Message) {{
-
- }}
-
- fn view(&self) -> Element<Self::Message> {{
- {view}.into()
- }}
- }}"#,
- if let Some(c) = theme {
- c.to_string().replace(' ', "")
- } else {
- "default()".to_owned()
- }
- );
- let config = Config::new_str()
- .edition(Edition::Rust2021)
- .option("trailing_comma", "Never")
- .option("imports_granularity", "Crate");
- let rustfmt = RustFmt::from_config(config);
- Ok(rustfmt.format_str(app_code)?)
- }
-
- pub fn test() -> String {
- let mut text1 = RenderedElement::new(ElementName::Text("wow"));
- text1.set_property("height", "120.5");
- text1.set_property("width", "230");
-
- let element = RenderedElement::new(ElementName::Container).push(RenderedElement::from_vec(
- ElementName::Row,
- vec![
- text1,
- RenderedElement::new(ElementName::Text("heh")),
- RenderedElement::new(ElementName::SVG(PathBuf::from(
- "/mnt/drive_d/git/obs-website/src/lib/assets/bars-solid.svg",
- ))),
- ],
- ));
-
- element.app_code("new app", None).unwrap()
- }
-}
diff --git a/src/lib.rs b/src/lib.rs
deleted file mode 100644
index e69de29..0000000
--- a/src/lib.rs
+++ /dev/null
diff --git a/src/main.rs b/src/main.rs
deleted file mode 100644
index d3fafc6..0000000
--- a/src/main.rs
+++ /dev/null
@@ -1,301 +0,0 @@
-mod codegen;
-mod types;
-
-use iced::{
- clipboard, executor,
- highlighter::{self, Highlighter},
- theme,
- widget::{
- button, column, container,
- pane_grid::{self, Pane, PaneGrid},
- row, text, text_editor, tooltip, Column, Space,
- },
- Alignment, Application, Color, Command, Element, Font, Length, Settings,
-};
-use types::{rendered_element::RenderedElement, DesignerPage, DesignerState};
-
-fn main() -> iced::Result {
- App::run(Settings {
- fonts: vec![include_bytes!("../fonts/icons.ttf").as_slice().into()],
- ..Settings::default()
- })
-}
-
-struct App {
- is_saved: bool,
- current_project: Option<String>,
- dark_theme: bool,
- pane_state: pane_grid::State<Panes>,
- focus: Option<Pane>,
- designer_state: DesignerState,
- element_list: Vec<String>,
- editor_content: text_editor::Content,
-}
-
-#[derive(Debug, Clone)]
-enum Message {
- ToggleTheme,
- CopyCode,
- Resized(pane_grid::ResizeEvent),
- Clicked(pane_grid::Pane),
-}
-
-#[derive(Clone, Debug)]
-enum Panes {
- Designer,
- ElementList,
-}
-
-impl Application for App {
- type Message = Message;
- type Theme = theme::Theme;
- type Executor = executor::Default;
- type Flags = ();
-
- fn new(_flags: ()) -> (Self, Command<Message>) {
- let state = pane_grid::State::with_configuration(pane_grid::Configuration::Split {
- axis: pane_grid::Axis::Vertical,
- ratio: 0.8,
- a: Box::new(pane_grid::Configuration::Pane(Panes::Designer)),
- b: Box::new(pane_grid::Configuration::Pane(Panes::ElementList)),
- });
- (
- Self {
- is_saved: true,
- current_project: None,
- dark_theme: true,
- pane_state: state,
- focus: None,
- designer_state: DesignerState {
- designer_content: vec![],
- designer_page: DesignerPage::CodeView,
- },
- element_list: vec!["Column", "Row", "PickList", "PaneGrid", "Button", "Text"]
- .into_iter()
- .map(|c| c.to_owned())
- .collect(),
- editor_content: text_editor::Content::with_text(&RenderedElement::test()),
- },
- Command::none(),
- )
- }
-
- fn title(&self) -> String {
- let saved_state = if self.is_saved { "" } else { " *" };
-
- let project_name = match &self.current_project {
- Some(n) => format!(" - {n}"),
- None => "".to_owned(),
- };
-
- format!("iced Builder{project_name}{saved_state}")
- }
-
- fn theme(&self) -> iced::Theme {
- if self.dark_theme {
- theme::Theme::CatppuccinMocha
- } else {
- theme::Theme::CatppuccinLatte
- }
- }
-
- fn update(&mut self, message: Message) -> Command<Message> {
- match message {
- Message::ToggleTheme => self.dark_theme = !self.dark_theme,
- Message::CopyCode => return clipboard::write(self.editor_content.text()),
- Message::Resized(pane_grid::ResizeEvent { split, ratio }) => {
- self.pane_state.resize(split, ratio);
- }
- Message::Clicked(pane) => {
- self.focus = Some(pane);
- }
- }
-
- Command::none()
- }
-
- fn view(&self) -> Element<Message> {
- let header = row![button("Toggle Theme")
- .on_press(Message::ToggleTheme)
- .padding(5)]
- .width(200);
- let pane_grid = PaneGrid::new(&self.pane_state, |id, pane, _is_maximized| {
- let is_focused = Some(id) == self.focus;
- match pane {
- Panes::Designer => match self.designer_state.designer_page {
- DesignerPage::Designer => {
- let content = column![text("Designer"),]
- .align_items(Alignment::Center)
- .height(Length::Fill)
- .width(Length::Fill);
- let title = text("Designer").style(if is_focused {
- PANE_ID_COLOR_FOCUSED
- } else {
- PANE_ID_COLOR_UNFOCUSED
- });
- let title_bar = pane_grid::TitleBar::new(title)
- .padding(10)
- .style(style::title_bar);
- pane_grid::Content::new(content)
- .title_bar(title_bar)
- .style(if is_focused {
- style::pane_focused
- } else {
- style::pane_active
- })
- }
- DesignerPage::CodeView => {
- let title = row![
- text("Generated Code").style(if is_focused {
- PANE_ID_COLOR_FOCUSED
- } else {
- PANE_ID_COLOR_UNFOCUSED
- }),
- Space::with_width(Length::Fill),
- tooltip(
- button(
- container(
- text('\u{0e801}').font(Font::with_name("editor-icons"))
- )
- .width(30)
- .center_x()
- )
- .on_press(Message::CopyCode),
- "Copy code to clipboard",
- tooltip::Position::Left
- )
- ];
- let title_bar = pane_grid::TitleBar::new(title)
- .padding(10)
- .style(style::title_bar);
- pane_grid::Content::new(
- text_editor(&self.editor_content)
- .highlight::<Highlighter>(
- highlighter::Settings {
- theme: highlighter::Theme::Base16Mocha,
- extension: "rs".to_string(),
- },
- |highlight, _theme| highlight.to_format(),
- )
- .height(Length::Fill)
- .padding(20),
- )
- .title_bar(title_bar)
- .style(if is_focused {
- style::pane_focused
- } else {
- style::pane_active
- })
- }
- },
- Panes::ElementList => {
- let items_list = items_list_view(&self.element_list);
- let content = column![items_list]
- .align_items(Alignment::Center)
- .height(Length::Fill)
- .width(Length::Fill);
- let title = text("Element List").style(if is_focused {
- PANE_ID_COLOR_FOCUSED
- } else {
- PANE_ID_COLOR_UNFOCUSED
- });
- let title_bar = pane_grid::TitleBar::new(title)
- .padding(10)
- .style(style::title_bar);
- pane_grid::Content::new(content)
- .title_bar(title_bar)
- .style(if is_focused {
- style::pane_focused
- } else {
- style::pane_active
- })
- }
- }
- })
- .width(Length::Fill)
- .height(Length::Fill)
- .spacing(10)
- .on_resize(10, Message::Resized)
- .on_click(Message::Clicked);
-
- let content = Column::new()
- .push(header)
- .push(pane_grid)
- .spacing(5)
- .align_items(Alignment::Center)
- .width(Length::Fill);
-
- container(content).height(Length::Fill).into()
- }
-}
-
-const fn from_grayscale(grayscale: f32) -> Color {
- Color {
- r: grayscale,
- g: grayscale,
- b: grayscale,
- a: 1.0,
- }
-}
-
-// #ffffff
-const PANE_ID_COLOR_FOCUSED: Color = from_grayscale(1.0);
-
-// #e8e8e8
-const PANE_ID_COLOR_UNFOCUSED: Color = from_grayscale(0xE8 as f32 / 255.0);
-
-fn items_list_view(items: &Vec<String>) -> Element<'static, Message> {
- let mut column = Column::new()
- .spacing(20)
- .align_items(Alignment::Center)
- .width(Length::Fill);
-
- for value in items {
- column = column.push(text(value));
- }
-
- container(column).height(250.0).width(300).into()
-}
-
-mod style {
- use iced::widget::container;
- use iced::{Border, Theme};
-
- pub fn title_bar(theme: &Theme) -> container::Appearance {
- let palette = theme.extended_palette();
-
- container::Appearance {
- text_color: Some(palette.background.strong.text),
- background: Some(palette.background.strong.color.into()),
- ..Default::default()
- }
- }
-
- pub fn pane_active(theme: &Theme) -> container::Appearance {
- let palette = theme.extended_palette();
-
- container::Appearance {
- background: Some(palette.background.weak.color.into()),
- border: Border {
- width: 1.0,
- color: palette.background.strong.color,
- ..Border::default()
- },
- ..Default::default()
- }
- }
-
- pub fn pane_focused(theme: &Theme) -> container::Appearance {
- let palette = theme.extended_palette();
-
- container::Appearance {
- background: Some(palette.background.weak.color.into()),
- border: Border {
- width: 4.0,
- color: palette.background.strong.color,
- ..Border::default()
- },
- ..Default::default()
- }
- }
-}
diff --git a/src/types/mod.rs b/src/types/mod.rs
deleted file mode 100644
index 7a04d79..0000000
--- a/src/types/mod.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-pub mod rendered_element;
-
-use rendered_element::RenderedElement;
-use std::path::PathBuf;
-
-pub struct DesignerState {
- pub designer_content: Vec<RenderedElement>,
- pub designer_page: DesignerPage,
-}
-
-#[derive(Debug)]
-pub enum ElementName {
- Text(&'static str),
- Button(&'static str),
- SVG(PathBuf),
- Image(PathBuf),
- Container,
- Row,
- Column,
-}
-
-pub enum DesignerPage {
- Designer,
- CodeView,
-}
diff --git a/src/types/rendered_element.rs b/src/types/rendered_element.rs
deleted file mode 100644
index f05594d..0000000
--- a/src/types/rendered_element.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-use std::collections::HashMap;
-
-use unique_id::{string::StringGenerator, Generator};
-
-use iced::advanced::widget::Id;
-
-use super::ElementName;
-
-#[derive(Debug)]
-pub struct RenderedElement {
- pub id: Id,
- pub child_elements: Vec<RenderedElement>,
- pub name: ElementName,
- pub props: HashMap<&'static str, &'static str>,
-}
-
-impl RenderedElement {
- pub fn new(name: ElementName) -> Self {
- let gen = StringGenerator::default();
- Self {
- id: Id::new(gen.next_id()),
- child_elements: vec![],
- name,
- props: HashMap::new(),
- }
- }
-
- pub fn from_vec(name: ElementName, child_elements: Vec<RenderedElement>) -> Self {
- let gen = StringGenerator::default();
- Self {
- id: Id::new(gen.next_id()),
- child_elements,
- name,
- props: HashMap::new(),
- }
- }
-
- pub fn push(mut self, element: RenderedElement) -> Self {
- self.child_elements.push(element);
- self
- }
-
- pub fn set_property(&mut self, prop: &'static str, value: &'static str) {
- let prop_ref = self.props.entry(prop).or_insert(value);
- *prop_ref = value;
- }
-}