├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .vscode └── settings.json ├── Cargo.lock ├── Cargo.toml ├── LICENSE.txt ├── README.md ├── examples ├── hello_colors │ ├── Cargo.toml │ ├── README.md │ ├── data │ │ └── Inter-Medium.otf │ └── src │ │ ├── app.rs │ │ ├── interface.rs │ │ └── main.rs └── local_scope │ ├── Cargo.toml │ └── src │ ├── app.rs │ └── main.rs ├── media ├── animated_circles.png ├── egui_colors_demo.png ├── egui_colors_light.png ├── egui_colors_v0.5.0.png └── egui_isohedral.png └── src ├── animator.rs ├── apca.rs ├── color_space.rs ├── lib.rs ├── scales.rs ├── tokens.rs └── utils.rs /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | ci: 7 | name: ${{ matrix.os }} 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [ubuntu-latest, windows-latest, macos-latest] 12 | 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v3 16 | 17 | - name: cargo build 18 | run: cargo build 19 | 20 | - name: cargo test 21 | run: cargo test 22 | 23 | - name: cargo fmt 24 | run: cargo fmt --all -- --check 25 | 26 | - name: cargo clippy 27 | run: cargo clippy -- -D warnings 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | .DS_Store 4 | Cargo.lock 5 | 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.check.command": "clippy", 3 | "editor.formatOnSave": true 4 | } -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "ab_glyph" 7 | version = "0.2.28" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" 10 | dependencies = [ 11 | "ab_glyph_rasterizer", 12 | "owned_ttf_parser", 13 | ] 14 | 15 | [[package]] 16 | name = "ab_glyph_rasterizer" 17 | version = "0.1.8" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" 20 | 21 | [[package]] 22 | name = "accesskit" 23 | version = "0.17.1" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "d3d3b8f9bae46a948369bc4a03e815d4ed6d616bd00de4051133a5019dc31c5a" 26 | 27 | [[package]] 28 | name = "accesskit_atspi_common" 29 | version = "0.10.1" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "7c5dd55e6e94949498698daf4d48fb5659e824d7abec0d394089656ceaf99d4f" 32 | dependencies = [ 33 | "accesskit", 34 | "accesskit_consumer", 35 | "atspi-common", 36 | "serde", 37 | "thiserror 1.0.69", 38 | "zvariant", 39 | ] 40 | 41 | [[package]] 42 | name = "accesskit_consumer" 43 | version = "0.26.0" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "f47983a1084940ba9a39c077a8c63e55c619388be5476ac04c804cfbd1e63459" 46 | dependencies = [ 47 | "accesskit", 48 | "hashbrown 0.15.2", 49 | "immutable-chunkmap", 50 | ] 51 | 52 | [[package]] 53 | name = "accesskit_macos" 54 | version = "0.18.1" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "7329821f3bd1101e03a7d2e03bd339e3ac0dc64c70b4c9f9ae1949e3ba8dece1" 57 | dependencies = [ 58 | "accesskit", 59 | "accesskit_consumer", 60 | "hashbrown 0.15.2", 61 | "objc2", 62 | "objc2-app-kit", 63 | "objc2-foundation", 64 | ] 65 | 66 | [[package]] 67 | name = "accesskit_unix" 68 | version = "0.13.1" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "fcee751cc20d88678c33edaf9c07e8b693cd02819fe89053776f5313492273f5" 71 | dependencies = [ 72 | "accesskit", 73 | "accesskit_atspi_common", 74 | "async-channel", 75 | "async-executor", 76 | "async-task", 77 | "atspi", 78 | "futures-lite", 79 | "futures-util", 80 | "serde", 81 | "zbus", 82 | ] 83 | 84 | [[package]] 85 | name = "accesskit_windows" 86 | version = "0.24.1" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "24fcd5d23d70670992b823e735e859374d694a3d12bfd8dd32bd3bd8bedb5d81" 89 | dependencies = [ 90 | "accesskit", 91 | "accesskit_consumer", 92 | "hashbrown 0.15.2", 93 | "paste", 94 | "static_assertions", 95 | "windows", 96 | "windows-core", 97 | ] 98 | 99 | [[package]] 100 | name = "accesskit_winit" 101 | version = "0.23.1" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "6a6a48dad5530b6deb9fc7a52cc6c3bf72cdd9eb8157ac9d32d69f2427a5e879" 104 | dependencies = [ 105 | "accesskit", 106 | "accesskit_macos", 107 | "accesskit_unix", 108 | "accesskit_windows", 109 | "raw-window-handle", 110 | "winit", 111 | ] 112 | 113 | [[package]] 114 | name = "adler" 115 | version = "1.0.2" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 118 | 119 | [[package]] 120 | name = "adler2" 121 | version = "2.0.0" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 124 | 125 | [[package]] 126 | name = "ahash" 127 | version = "0.8.11" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 130 | dependencies = [ 131 | "cfg-if", 132 | "getrandom", 133 | "once_cell", 134 | "version_check", 135 | "zerocopy", 136 | ] 137 | 138 | [[package]] 139 | name = "allocator-api2" 140 | version = "0.2.18" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" 143 | 144 | [[package]] 145 | name = "android-activity" 146 | version = "0.6.0" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" 149 | dependencies = [ 150 | "android-properties", 151 | "bitflags 2.8.0", 152 | "cc", 153 | "cesu8", 154 | "jni", 155 | "jni-sys", 156 | "libc", 157 | "log", 158 | "ndk", 159 | "ndk-context", 160 | "ndk-sys 0.6.0+11769913", 161 | "num_enum", 162 | "thiserror 1.0.69", 163 | ] 164 | 165 | [[package]] 166 | name = "android-properties" 167 | version = "0.2.2" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" 170 | 171 | [[package]] 172 | name = "android_system_properties" 173 | version = "0.1.5" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 176 | dependencies = [ 177 | "libc", 178 | ] 179 | 180 | [[package]] 181 | name = "arboard" 182 | version = "3.4.1" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "df099ccb16cd014ff054ac1bf392c67feeef57164b05c42f037cd40f5d4357f4" 185 | dependencies = [ 186 | "clipboard-win", 187 | "core-graphics", 188 | "image", 189 | "log", 190 | "objc2", 191 | "objc2-app-kit", 192 | "objc2-foundation", 193 | "parking_lot", 194 | "windows-sys 0.48.0", 195 | "x11rb", 196 | ] 197 | 198 | [[package]] 199 | name = "arrayref" 200 | version = "0.3.9" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" 203 | 204 | [[package]] 205 | name = "arrayvec" 206 | version = "0.7.6" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 209 | 210 | [[package]] 211 | name = "as-raw-xcb-connection" 212 | version = "1.0.1" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" 215 | 216 | [[package]] 217 | name = "ash" 218 | version = "0.38.0+1.3.281" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" 221 | dependencies = [ 222 | "libloading", 223 | ] 224 | 225 | [[package]] 226 | name = "async-broadcast" 227 | version = "0.7.1" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" 230 | dependencies = [ 231 | "event-listener", 232 | "event-listener-strategy", 233 | "futures-core", 234 | "pin-project-lite", 235 | ] 236 | 237 | [[package]] 238 | name = "async-channel" 239 | version = "2.3.1" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" 242 | dependencies = [ 243 | "concurrent-queue", 244 | "event-listener-strategy", 245 | "futures-core", 246 | "pin-project-lite", 247 | ] 248 | 249 | [[package]] 250 | name = "async-executor" 251 | version = "1.13.1" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" 254 | dependencies = [ 255 | "async-task", 256 | "concurrent-queue", 257 | "fastrand", 258 | "futures-lite", 259 | "slab", 260 | ] 261 | 262 | [[package]] 263 | name = "async-fs" 264 | version = "2.1.2" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a" 267 | dependencies = [ 268 | "async-lock", 269 | "blocking", 270 | "futures-lite", 271 | ] 272 | 273 | [[package]] 274 | name = "async-io" 275 | version = "2.3.4" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" 278 | dependencies = [ 279 | "async-lock", 280 | "cfg-if", 281 | "concurrent-queue", 282 | "futures-io", 283 | "futures-lite", 284 | "parking", 285 | "polling", 286 | "rustix", 287 | "slab", 288 | "tracing", 289 | "windows-sys 0.59.0", 290 | ] 291 | 292 | [[package]] 293 | name = "async-lock" 294 | version = "3.4.0" 295 | source = "registry+https://github.com/rust-lang/crates.io-index" 296 | checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" 297 | dependencies = [ 298 | "event-listener", 299 | "event-listener-strategy", 300 | "pin-project-lite", 301 | ] 302 | 303 | [[package]] 304 | name = "async-process" 305 | version = "2.3.0" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" 308 | dependencies = [ 309 | "async-channel", 310 | "async-io", 311 | "async-lock", 312 | "async-signal", 313 | "async-task", 314 | "blocking", 315 | "cfg-if", 316 | "event-listener", 317 | "futures-lite", 318 | "rustix", 319 | "tracing", 320 | ] 321 | 322 | [[package]] 323 | name = "async-recursion" 324 | version = "1.1.1" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" 327 | dependencies = [ 328 | "proc-macro2", 329 | "quote", 330 | "syn", 331 | ] 332 | 333 | [[package]] 334 | name = "async-signal" 335 | version = "0.2.10" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" 338 | dependencies = [ 339 | "async-io", 340 | "async-lock", 341 | "atomic-waker", 342 | "cfg-if", 343 | "futures-core", 344 | "futures-io", 345 | "rustix", 346 | "signal-hook-registry", 347 | "slab", 348 | "windows-sys 0.59.0", 349 | ] 350 | 351 | [[package]] 352 | name = "async-task" 353 | version = "4.7.1" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" 356 | 357 | [[package]] 358 | name = "async-trait" 359 | version = "0.1.83" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" 362 | dependencies = [ 363 | "proc-macro2", 364 | "quote", 365 | "syn", 366 | ] 367 | 368 | [[package]] 369 | name = "atomic-waker" 370 | version = "1.1.2" 371 | source = "registry+https://github.com/rust-lang/crates.io-index" 372 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 373 | 374 | [[package]] 375 | name = "atspi" 376 | version = "0.22.0" 377 | source = "registry+https://github.com/rust-lang/crates.io-index" 378 | checksum = "be534b16650e35237bb1ed189ba2aab86ce65e88cc84c66f4935ba38575cecbf" 379 | dependencies = [ 380 | "atspi-common", 381 | "atspi-connection", 382 | "atspi-proxies", 383 | ] 384 | 385 | [[package]] 386 | name = "atspi-common" 387 | version = "0.6.0" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "1909ed2dc01d0a17505d89311d192518507e8a056a48148e3598fef5e7bb6ba7" 390 | dependencies = [ 391 | "enumflags2", 392 | "serde", 393 | "static_assertions", 394 | "zbus", 395 | "zbus-lockstep", 396 | "zbus-lockstep-macros", 397 | "zbus_names", 398 | "zvariant", 399 | ] 400 | 401 | [[package]] 402 | name = "atspi-connection" 403 | version = "0.6.0" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "430c5960624a4baaa511c9c0fcc2218e3b58f5dbcc47e6190cafee344b873333" 406 | dependencies = [ 407 | "atspi-common", 408 | "atspi-proxies", 409 | "futures-lite", 410 | "zbus", 411 | ] 412 | 413 | [[package]] 414 | name = "atspi-proxies" 415 | version = "0.6.0" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "a5e6c5de3e524cf967569722446bcd458d5032348554d9a17d7d72b041ab7496" 418 | dependencies = [ 419 | "atspi-common", 420 | "serde", 421 | "zbus", 422 | "zvariant", 423 | ] 424 | 425 | [[package]] 426 | name = "autocfg" 427 | version = "1.4.0" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 430 | 431 | [[package]] 432 | name = "bit-set" 433 | version = "0.8.0" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" 436 | dependencies = [ 437 | "bit-vec", 438 | ] 439 | 440 | [[package]] 441 | name = "bit-vec" 442 | version = "0.8.0" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" 445 | 446 | [[package]] 447 | name = "bitflags" 448 | version = "1.3.2" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 451 | 452 | [[package]] 453 | name = "bitflags" 454 | version = "2.8.0" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" 457 | dependencies = [ 458 | "serde", 459 | ] 460 | 461 | [[package]] 462 | name = "block" 463 | version = "0.1.6" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 466 | 467 | [[package]] 468 | name = "block-buffer" 469 | version = "0.10.4" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 472 | dependencies = [ 473 | "generic-array", 474 | ] 475 | 476 | [[package]] 477 | name = "block2" 478 | version = "0.5.1" 479 | source = "registry+https://github.com/rust-lang/crates.io-index" 480 | checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" 481 | dependencies = [ 482 | "objc2", 483 | ] 484 | 485 | [[package]] 486 | name = "blocking" 487 | version = "1.6.1" 488 | source = "registry+https://github.com/rust-lang/crates.io-index" 489 | checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" 490 | dependencies = [ 491 | "async-channel", 492 | "async-task", 493 | "futures-io", 494 | "futures-lite", 495 | "piper", 496 | ] 497 | 498 | [[package]] 499 | name = "bumpalo" 500 | version = "3.16.0" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 503 | 504 | [[package]] 505 | name = "bytemuck" 506 | version = "1.21.0" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" 509 | dependencies = [ 510 | "bytemuck_derive", 511 | ] 512 | 513 | [[package]] 514 | name = "bytemuck_derive" 515 | version = "1.7.1" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" 518 | dependencies = [ 519 | "proc-macro2", 520 | "quote", 521 | "syn", 522 | ] 523 | 524 | [[package]] 525 | name = "byteorder" 526 | version = "1.5.0" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 529 | 530 | [[package]] 531 | name = "byteorder-lite" 532 | version = "0.1.0" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" 535 | 536 | [[package]] 537 | name = "bytes" 538 | version = "1.7.2" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" 541 | 542 | [[package]] 543 | name = "calloop" 544 | version = "0.13.0" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" 547 | dependencies = [ 548 | "bitflags 2.8.0", 549 | "log", 550 | "polling", 551 | "rustix", 552 | "slab", 553 | "thiserror 1.0.69", 554 | ] 555 | 556 | [[package]] 557 | name = "calloop-wayland-source" 558 | version = "0.3.0" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" 561 | dependencies = [ 562 | "calloop", 563 | "rustix", 564 | "wayland-backend", 565 | "wayland-client", 566 | ] 567 | 568 | [[package]] 569 | name = "cc" 570 | version = "1.1.21" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" 573 | dependencies = [ 574 | "jobserver", 575 | "libc", 576 | "shlex", 577 | ] 578 | 579 | [[package]] 580 | name = "cesu8" 581 | version = "1.1.0" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 584 | 585 | [[package]] 586 | name = "cfg-if" 587 | version = "1.0.0" 588 | source = "registry+https://github.com/rust-lang/crates.io-index" 589 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 590 | 591 | [[package]] 592 | name = "cfg_aliases" 593 | version = "0.2.1" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 596 | 597 | [[package]] 598 | name = "cgl" 599 | version = "0.3.2" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" 602 | dependencies = [ 603 | "libc", 604 | ] 605 | 606 | [[package]] 607 | name = "clipboard-win" 608 | version = "5.4.0" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" 611 | dependencies = [ 612 | "error-code", 613 | ] 614 | 615 | [[package]] 616 | name = "codespan-reporting" 617 | version = "0.11.1" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 620 | dependencies = [ 621 | "termcolor", 622 | "unicode-width", 623 | ] 624 | 625 | [[package]] 626 | name = "color-hex" 627 | version = "0.2.0" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "ecdffb913a326b6c642290a0d0ec8e8d6597291acdc07cc4c9cb4b3635d44cf9" 630 | 631 | [[package]] 632 | name = "combine" 633 | version = "4.6.7" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" 636 | dependencies = [ 637 | "bytes", 638 | "memchr", 639 | ] 640 | 641 | [[package]] 642 | name = "concurrent-queue" 643 | version = "2.5.0" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 646 | dependencies = [ 647 | "crossbeam-utils", 648 | ] 649 | 650 | [[package]] 651 | name = "core-foundation" 652 | version = "0.9.4" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 655 | dependencies = [ 656 | "core-foundation-sys", 657 | "libc", 658 | ] 659 | 660 | [[package]] 661 | name = "core-foundation" 662 | version = "0.10.0" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" 665 | dependencies = [ 666 | "core-foundation-sys", 667 | "libc", 668 | ] 669 | 670 | [[package]] 671 | name = "core-foundation-sys" 672 | version = "0.8.7" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 675 | 676 | [[package]] 677 | name = "core-graphics" 678 | version = "0.23.2" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" 681 | dependencies = [ 682 | "bitflags 1.3.2", 683 | "core-foundation 0.9.4", 684 | "core-graphics-types", 685 | "foreign-types", 686 | "libc", 687 | ] 688 | 689 | [[package]] 690 | name = "core-graphics-types" 691 | version = "0.1.3" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" 694 | dependencies = [ 695 | "bitflags 1.3.2", 696 | "core-foundation 0.9.4", 697 | "libc", 698 | ] 699 | 700 | [[package]] 701 | name = "cpufeatures" 702 | version = "0.2.14" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" 705 | dependencies = [ 706 | "libc", 707 | ] 708 | 709 | [[package]] 710 | name = "crc32fast" 711 | version = "1.4.2" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 714 | dependencies = [ 715 | "cfg-if", 716 | ] 717 | 718 | [[package]] 719 | name = "crossbeam-utils" 720 | version = "0.8.20" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 723 | 724 | [[package]] 725 | name = "crypto-common" 726 | version = "0.1.6" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 729 | dependencies = [ 730 | "generic-array", 731 | "typenum", 732 | ] 733 | 734 | [[package]] 735 | name = "cursor-icon" 736 | version = "1.1.0" 737 | source = "registry+https://github.com/rust-lang/crates.io-index" 738 | checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" 739 | 740 | [[package]] 741 | name = "digest" 742 | version = "0.10.7" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 745 | dependencies = [ 746 | "block-buffer", 747 | "crypto-common", 748 | ] 749 | 750 | [[package]] 751 | name = "dispatch" 752 | version = "0.2.0" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" 755 | 756 | [[package]] 757 | name = "dlib" 758 | version = "0.5.2" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" 761 | dependencies = [ 762 | "libloading", 763 | ] 764 | 765 | [[package]] 766 | name = "document-features" 767 | version = "0.2.10" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" 770 | dependencies = [ 771 | "litrs", 772 | ] 773 | 774 | [[package]] 775 | name = "downcast-rs" 776 | version = "1.2.1" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" 779 | 780 | [[package]] 781 | name = "dpi" 782 | version = "0.1.1" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" 785 | 786 | [[package]] 787 | name = "ecolor" 788 | version = "0.31.1" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "bc4feb366740ded31a004a0e4452fbf84e80ef432ecf8314c485210229672fd1" 791 | dependencies = [ 792 | "bytemuck", 793 | "color-hex", 794 | "emath", 795 | ] 796 | 797 | [[package]] 798 | name = "eframe" 799 | version = "0.31.1" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | checksum = "d0dfe0859f3fb1bc6424c57d41e10e9093fe938f426b691e42272c2f336d915c" 802 | dependencies = [ 803 | "ahash", 804 | "bytemuck", 805 | "document-features", 806 | "egui", 807 | "egui-wgpu", 808 | "egui-winit", 809 | "egui_glow", 810 | "glow", 811 | "glutin", 812 | "glutin-winit", 813 | "image", 814 | "js-sys", 815 | "log", 816 | "objc2", 817 | "objc2-app-kit", 818 | "objc2-foundation", 819 | "parking_lot", 820 | "percent-encoding", 821 | "profiling", 822 | "raw-window-handle", 823 | "static_assertions", 824 | "wasm-bindgen", 825 | "wasm-bindgen-futures", 826 | "web-sys", 827 | "web-time", 828 | "winapi", 829 | "windows-sys 0.59.0", 830 | "winit", 831 | ] 832 | 833 | [[package]] 834 | name = "egui" 835 | version = "0.31.1" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "25dd34cec49ab55d85ebf70139cb1ccd29c977ef6b6ba4fe85489d6877ee9ef3" 838 | dependencies = [ 839 | "accesskit", 840 | "ahash", 841 | "bitflags 2.8.0", 842 | "emath", 843 | "epaint", 844 | "log", 845 | "nohash-hasher", 846 | "profiling", 847 | ] 848 | 849 | [[package]] 850 | name = "egui-wgpu" 851 | version = "0.31.1" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | checksum = "d319dfef570f699b6e9114e235e862a2ddcf75f0d1a061de9e1328d92146d820" 854 | dependencies = [ 855 | "ahash", 856 | "bytemuck", 857 | "document-features", 858 | "egui", 859 | "epaint", 860 | "log", 861 | "profiling", 862 | "thiserror 1.0.69", 863 | "type-map", 864 | "web-time", 865 | "wgpu", 866 | "winit", 867 | ] 868 | 869 | [[package]] 870 | name = "egui-winit" 871 | version = "0.31.1" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "7d9dfbb78fe4eb9c3a39ad528b90ee5915c252e77bbab9d4ebc576541ab67e13" 874 | dependencies = [ 875 | "accesskit_winit", 876 | "ahash", 877 | "arboard", 878 | "bytemuck", 879 | "egui", 880 | "log", 881 | "profiling", 882 | "raw-window-handle", 883 | "smithay-clipboard", 884 | "web-time", 885 | "webbrowser", 886 | "winit", 887 | ] 888 | 889 | [[package]] 890 | name = "egui_colors" 891 | version = "0.8.0" 892 | dependencies = [ 893 | "egui", 894 | "serde", 895 | ] 896 | 897 | [[package]] 898 | name = "egui_demo_lib" 899 | version = "0.31.1" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "b415b910b6525b5dfded8f406d04032b87348836fb7f7cc711fc6bfdb830a9c5" 902 | dependencies = [ 903 | "egui", 904 | "egui_extras", 905 | "unicode_names2", 906 | ] 907 | 908 | [[package]] 909 | name = "egui_extras" 910 | version = "0.31.1" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "624659a2e972a46f4d5f646557906c55f1cd5a0836eddbe610fdf1afba1b4226" 913 | dependencies = [ 914 | "ahash", 915 | "egui", 916 | "enum-map", 917 | "log", 918 | "mime_guess2", 919 | "profiling", 920 | ] 921 | 922 | [[package]] 923 | name = "egui_glow" 924 | version = "0.31.1" 925 | source = "registry+https://github.com/rust-lang/crates.io-index" 926 | checksum = "910906e3f042ea6d2378ec12a6fd07698e14ddae68aed2d819ffe944a73aab9e" 927 | dependencies = [ 928 | "ahash", 929 | "bytemuck", 930 | "egui", 931 | "glow", 932 | "log", 933 | "memoffset", 934 | "profiling", 935 | "wasm-bindgen", 936 | "web-sys", 937 | "winit", 938 | ] 939 | 940 | [[package]] 941 | name = "emath" 942 | version = "0.31.1" 943 | source = "registry+https://github.com/rust-lang/crates.io-index" 944 | checksum = "9e4cadcff7a5353ba72b7fea76bf2122b5ebdbc68e8155aa56dfdea90083fe1b" 945 | dependencies = [ 946 | "bytemuck", 947 | ] 948 | 949 | [[package]] 950 | name = "endi" 951 | version = "1.1.0" 952 | source = "registry+https://github.com/rust-lang/crates.io-index" 953 | checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" 954 | 955 | [[package]] 956 | name = "enum-map" 957 | version = "2.7.3" 958 | source = "registry+https://github.com/rust-lang/crates.io-index" 959 | checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" 960 | dependencies = [ 961 | "enum-map-derive", 962 | "serde", 963 | ] 964 | 965 | [[package]] 966 | name = "enum-map-derive" 967 | version = "0.17.0" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" 970 | dependencies = [ 971 | "proc-macro2", 972 | "quote", 973 | "syn", 974 | ] 975 | 976 | [[package]] 977 | name = "enumflags2" 978 | version = "0.7.10" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" 981 | dependencies = [ 982 | "enumflags2_derive", 983 | "serde", 984 | ] 985 | 986 | [[package]] 987 | name = "enumflags2_derive" 988 | version = "0.7.10" 989 | source = "registry+https://github.com/rust-lang/crates.io-index" 990 | checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" 991 | dependencies = [ 992 | "proc-macro2", 993 | "quote", 994 | "syn", 995 | ] 996 | 997 | [[package]] 998 | name = "epaint" 999 | version = "0.31.1" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "41fcc0f5a7c613afd2dee5e4b30c3e6acafb8ad6f0edb06068811f708a67c562" 1002 | dependencies = [ 1003 | "ab_glyph", 1004 | "ahash", 1005 | "bytemuck", 1006 | "ecolor", 1007 | "emath", 1008 | "epaint_default_fonts", 1009 | "log", 1010 | "nohash-hasher", 1011 | "parking_lot", 1012 | "profiling", 1013 | ] 1014 | 1015 | [[package]] 1016 | name = "epaint_default_fonts" 1017 | version = "0.31.1" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "fc7e7a64c02cf7a5b51e745a9e45f60660a286f151c238b9d397b3e923f5082f" 1020 | 1021 | [[package]] 1022 | name = "equivalent" 1023 | version = "1.0.1" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 1026 | 1027 | [[package]] 1028 | name = "errno" 1029 | version = "0.3.9" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 1032 | dependencies = [ 1033 | "libc", 1034 | "windows-sys 0.52.0", 1035 | ] 1036 | 1037 | [[package]] 1038 | name = "error-code" 1039 | version = "3.3.1" 1040 | source = "registry+https://github.com/rust-lang/crates.io-index" 1041 | checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" 1042 | 1043 | [[package]] 1044 | name = "event-listener" 1045 | version = "5.3.1" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" 1048 | dependencies = [ 1049 | "concurrent-queue", 1050 | "parking", 1051 | "pin-project-lite", 1052 | ] 1053 | 1054 | [[package]] 1055 | name = "event-listener-strategy" 1056 | version = "0.5.2" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" 1059 | dependencies = [ 1060 | "event-listener", 1061 | "pin-project-lite", 1062 | ] 1063 | 1064 | [[package]] 1065 | name = "fastrand" 1066 | version = "2.1.1" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" 1069 | 1070 | [[package]] 1071 | name = "fdeflate" 1072 | version = "0.3.5" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | checksum = "d8090f921a24b04994d9929e204f50b498a33ea6ba559ffaa05e04f7ee7fb5ab" 1075 | dependencies = [ 1076 | "simd-adler32", 1077 | ] 1078 | 1079 | [[package]] 1080 | name = "flate2" 1081 | version = "1.0.34" 1082 | source = "registry+https://github.com/rust-lang/crates.io-index" 1083 | checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" 1084 | dependencies = [ 1085 | "crc32fast", 1086 | "miniz_oxide 0.8.0", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "foldhash" 1091 | version = "0.1.3" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" 1094 | 1095 | [[package]] 1096 | name = "foreign-types" 1097 | version = "0.5.0" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" 1100 | dependencies = [ 1101 | "foreign-types-macros", 1102 | "foreign-types-shared", 1103 | ] 1104 | 1105 | [[package]] 1106 | name = "foreign-types-macros" 1107 | version = "0.2.3" 1108 | source = "registry+https://github.com/rust-lang/crates.io-index" 1109 | checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" 1110 | dependencies = [ 1111 | "proc-macro2", 1112 | "quote", 1113 | "syn", 1114 | ] 1115 | 1116 | [[package]] 1117 | name = "foreign-types-shared" 1118 | version = "0.3.1" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" 1121 | 1122 | [[package]] 1123 | name = "form_urlencoded" 1124 | version = "1.2.1" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 1127 | dependencies = [ 1128 | "percent-encoding", 1129 | ] 1130 | 1131 | [[package]] 1132 | name = "futures-core" 1133 | version = "0.3.30" 1134 | source = "registry+https://github.com/rust-lang/crates.io-index" 1135 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 1136 | 1137 | [[package]] 1138 | name = "futures-io" 1139 | version = "0.3.30" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 1142 | 1143 | [[package]] 1144 | name = "futures-lite" 1145 | version = "2.3.0" 1146 | source = "registry+https://github.com/rust-lang/crates.io-index" 1147 | checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" 1148 | dependencies = [ 1149 | "fastrand", 1150 | "futures-core", 1151 | "futures-io", 1152 | "parking", 1153 | "pin-project-lite", 1154 | ] 1155 | 1156 | [[package]] 1157 | name = "futures-macro" 1158 | version = "0.3.30" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 1161 | dependencies = [ 1162 | "proc-macro2", 1163 | "quote", 1164 | "syn", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "futures-sink" 1169 | version = "0.3.30" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 1172 | 1173 | [[package]] 1174 | name = "futures-task" 1175 | version = "0.3.30" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 1178 | 1179 | [[package]] 1180 | name = "futures-util" 1181 | version = "0.3.30" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 1184 | dependencies = [ 1185 | "futures-core", 1186 | "futures-io", 1187 | "futures-macro", 1188 | "futures-sink", 1189 | "futures-task", 1190 | "memchr", 1191 | "pin-project-lite", 1192 | "pin-utils", 1193 | "slab", 1194 | ] 1195 | 1196 | [[package]] 1197 | name = "generic-array" 1198 | version = "0.14.7" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 1201 | dependencies = [ 1202 | "typenum", 1203 | "version_check", 1204 | ] 1205 | 1206 | [[package]] 1207 | name = "gethostname" 1208 | version = "0.4.3" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" 1211 | dependencies = [ 1212 | "libc", 1213 | "windows-targets 0.48.5", 1214 | ] 1215 | 1216 | [[package]] 1217 | name = "getrandom" 1218 | version = "0.2.15" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 1221 | dependencies = [ 1222 | "cfg-if", 1223 | "libc", 1224 | "wasi", 1225 | ] 1226 | 1227 | [[package]] 1228 | name = "gl_generator" 1229 | version = "0.14.0" 1230 | source = "registry+https://github.com/rust-lang/crates.io-index" 1231 | checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" 1232 | dependencies = [ 1233 | "khronos_api", 1234 | "log", 1235 | "xml-rs", 1236 | ] 1237 | 1238 | [[package]] 1239 | name = "glow" 1240 | version = "0.16.0" 1241 | source = "registry+https://github.com/rust-lang/crates.io-index" 1242 | checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" 1243 | dependencies = [ 1244 | "js-sys", 1245 | "slotmap", 1246 | "wasm-bindgen", 1247 | "web-sys", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "glutin" 1252 | version = "0.32.1" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "ec69412a0bf07ea7607e638b415447857a808846c2b685a43c8aa18bc6d5e499" 1255 | dependencies = [ 1256 | "bitflags 2.8.0", 1257 | "cfg_aliases", 1258 | "cgl", 1259 | "core-foundation 0.9.4", 1260 | "dispatch", 1261 | "glutin_egl_sys", 1262 | "glutin_glx_sys", 1263 | "glutin_wgl_sys", 1264 | "libloading", 1265 | "objc2", 1266 | "objc2-app-kit", 1267 | "objc2-foundation", 1268 | "once_cell", 1269 | "raw-window-handle", 1270 | "wayland-sys", 1271 | "windows-sys 0.52.0", 1272 | "x11-dl", 1273 | ] 1274 | 1275 | [[package]] 1276 | name = "glutin-winit" 1277 | version = "0.5.0" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" 1280 | dependencies = [ 1281 | "cfg_aliases", 1282 | "glutin", 1283 | "raw-window-handle", 1284 | "winit", 1285 | ] 1286 | 1287 | [[package]] 1288 | name = "glutin_egl_sys" 1289 | version = "0.7.0" 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" 1291 | checksum = "cae99fff4d2850dbe6fb8c1fa8e4fead5525bab715beaacfccf3fb994e01c827" 1292 | dependencies = [ 1293 | "gl_generator", 1294 | "windows-sys 0.52.0", 1295 | ] 1296 | 1297 | [[package]] 1298 | name = "glutin_glx_sys" 1299 | version = "0.6.0" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "9c2b2d3918e76e18e08796b55eb64e8fe6ec67d5a6b2e2a7e2edce224ad24c63" 1302 | dependencies = [ 1303 | "gl_generator", 1304 | "x11-dl", 1305 | ] 1306 | 1307 | [[package]] 1308 | name = "glutin_wgl_sys" 1309 | version = "0.6.0" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | checksum = "0a4e1951bbd9434a81aa496fe59ccc2235af3820d27b85f9314e279609211e2c" 1312 | dependencies = [ 1313 | "gl_generator", 1314 | ] 1315 | 1316 | [[package]] 1317 | name = "gpu-alloc" 1318 | version = "0.6.0" 1319 | source = "registry+https://github.com/rust-lang/crates.io-index" 1320 | checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" 1321 | dependencies = [ 1322 | "bitflags 2.8.0", 1323 | "gpu-alloc-types", 1324 | ] 1325 | 1326 | [[package]] 1327 | name = "gpu-alloc-types" 1328 | version = "0.3.0" 1329 | source = "registry+https://github.com/rust-lang/crates.io-index" 1330 | checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" 1331 | dependencies = [ 1332 | "bitflags 2.8.0", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "gpu-descriptor" 1337 | version = "0.3.0" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "9c08c1f623a8d0b722b8b99f821eb0ba672a1618f0d3b16ddbee1cedd2dd8557" 1340 | dependencies = [ 1341 | "bitflags 2.8.0", 1342 | "gpu-descriptor-types", 1343 | "hashbrown 0.14.5", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "gpu-descriptor-types" 1348 | version = "0.2.0" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" 1351 | dependencies = [ 1352 | "bitflags 2.8.0", 1353 | ] 1354 | 1355 | [[package]] 1356 | name = "hashbrown" 1357 | version = "0.14.5" 1358 | source = "registry+https://github.com/rust-lang/crates.io-index" 1359 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 1360 | dependencies = [ 1361 | "ahash", 1362 | "allocator-api2", 1363 | ] 1364 | 1365 | [[package]] 1366 | name = "hashbrown" 1367 | version = "0.15.2" 1368 | source = "registry+https://github.com/rust-lang/crates.io-index" 1369 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 1370 | dependencies = [ 1371 | "foldhash", 1372 | ] 1373 | 1374 | [[package]] 1375 | name = "heck" 1376 | version = "0.5.0" 1377 | source = "registry+https://github.com/rust-lang/crates.io-index" 1378 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 1379 | 1380 | [[package]] 1381 | name = "hello_colors" 1382 | version = "0.1.0" 1383 | dependencies = [ 1384 | "eframe", 1385 | "egui_colors", 1386 | "egui_demo_lib", 1387 | ] 1388 | 1389 | [[package]] 1390 | name = "hermit-abi" 1391 | version = "0.4.0" 1392 | source = "registry+https://github.com/rust-lang/crates.io-index" 1393 | checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" 1394 | 1395 | [[package]] 1396 | name = "hex" 1397 | version = "0.4.3" 1398 | source = "registry+https://github.com/rust-lang/crates.io-index" 1399 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 1400 | 1401 | [[package]] 1402 | name = "hexf-parse" 1403 | version = "0.2.1" 1404 | source = "registry+https://github.com/rust-lang/crates.io-index" 1405 | checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" 1406 | 1407 | [[package]] 1408 | name = "home" 1409 | version = "0.5.9" 1410 | source = "registry+https://github.com/rust-lang/crates.io-index" 1411 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" 1412 | dependencies = [ 1413 | "windows-sys 0.52.0", 1414 | ] 1415 | 1416 | [[package]] 1417 | name = "idna" 1418 | version = "0.5.0" 1419 | source = "registry+https://github.com/rust-lang/crates.io-index" 1420 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 1421 | dependencies = [ 1422 | "unicode-bidi", 1423 | "unicode-normalization", 1424 | ] 1425 | 1426 | [[package]] 1427 | name = "image" 1428 | version = "0.25.2" 1429 | source = "registry+https://github.com/rust-lang/crates.io-index" 1430 | checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10" 1431 | dependencies = [ 1432 | "bytemuck", 1433 | "byteorder-lite", 1434 | "num-traits", 1435 | "png", 1436 | "tiff", 1437 | ] 1438 | 1439 | [[package]] 1440 | name = "immutable-chunkmap" 1441 | version = "2.0.6" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "12f97096f508d54f8f8ab8957862eee2ccd628847b6217af1a335e1c44dee578" 1444 | dependencies = [ 1445 | "arrayvec", 1446 | ] 1447 | 1448 | [[package]] 1449 | name = "indexmap" 1450 | version = "2.5.0" 1451 | source = "registry+https://github.com/rust-lang/crates.io-index" 1452 | checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" 1453 | dependencies = [ 1454 | "equivalent", 1455 | "hashbrown 0.14.5", 1456 | ] 1457 | 1458 | [[package]] 1459 | name = "jni" 1460 | version = "0.21.1" 1461 | source = "registry+https://github.com/rust-lang/crates.io-index" 1462 | checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" 1463 | dependencies = [ 1464 | "cesu8", 1465 | "cfg-if", 1466 | "combine", 1467 | "jni-sys", 1468 | "log", 1469 | "thiserror 1.0.69", 1470 | "walkdir", 1471 | "windows-sys 0.45.0", 1472 | ] 1473 | 1474 | [[package]] 1475 | name = "jni-sys" 1476 | version = "0.3.0" 1477 | source = "registry+https://github.com/rust-lang/crates.io-index" 1478 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 1479 | 1480 | [[package]] 1481 | name = "jobserver" 1482 | version = "0.1.32" 1483 | source = "registry+https://github.com/rust-lang/crates.io-index" 1484 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 1485 | dependencies = [ 1486 | "libc", 1487 | ] 1488 | 1489 | [[package]] 1490 | name = "jpeg-decoder" 1491 | version = "0.3.1" 1492 | source = "registry+https://github.com/rust-lang/crates.io-index" 1493 | checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" 1494 | 1495 | [[package]] 1496 | name = "js-sys" 1497 | version = "0.3.76" 1498 | source = "registry+https://github.com/rust-lang/crates.io-index" 1499 | checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" 1500 | dependencies = [ 1501 | "once_cell", 1502 | "wasm-bindgen", 1503 | ] 1504 | 1505 | [[package]] 1506 | name = "khronos-egl" 1507 | version = "6.0.0" 1508 | source = "registry+https://github.com/rust-lang/crates.io-index" 1509 | checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" 1510 | dependencies = [ 1511 | "libc", 1512 | "libloading", 1513 | "pkg-config", 1514 | ] 1515 | 1516 | [[package]] 1517 | name = "khronos_api" 1518 | version = "3.1.0" 1519 | source = "registry+https://github.com/rust-lang/crates.io-index" 1520 | checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" 1521 | 1522 | [[package]] 1523 | name = "libc" 1524 | version = "0.2.159" 1525 | source = "registry+https://github.com/rust-lang/crates.io-index" 1526 | checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" 1527 | 1528 | [[package]] 1529 | name = "libloading" 1530 | version = "0.8.5" 1531 | source = "registry+https://github.com/rust-lang/crates.io-index" 1532 | checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" 1533 | dependencies = [ 1534 | "cfg-if", 1535 | "windows-targets 0.52.6", 1536 | ] 1537 | 1538 | [[package]] 1539 | name = "libredox" 1540 | version = "0.0.2" 1541 | source = "registry+https://github.com/rust-lang/crates.io-index" 1542 | checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" 1543 | dependencies = [ 1544 | "bitflags 2.8.0", 1545 | "libc", 1546 | "redox_syscall 0.4.1", 1547 | ] 1548 | 1549 | [[package]] 1550 | name = "linux-raw-sys" 1551 | version = "0.4.14" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 1554 | 1555 | [[package]] 1556 | name = "litrs" 1557 | version = "0.4.1" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" 1560 | 1561 | [[package]] 1562 | name = "local_scope" 1563 | version = "0.1.0" 1564 | dependencies = [ 1565 | "eframe", 1566 | "egui_colors", 1567 | ] 1568 | 1569 | [[package]] 1570 | name = "lock_api" 1571 | version = "0.4.12" 1572 | source = "registry+https://github.com/rust-lang/crates.io-index" 1573 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1574 | dependencies = [ 1575 | "autocfg", 1576 | "scopeguard", 1577 | ] 1578 | 1579 | [[package]] 1580 | name = "log" 1581 | version = "0.4.22" 1582 | source = "registry+https://github.com/rust-lang/crates.io-index" 1583 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 1584 | 1585 | [[package]] 1586 | name = "malloc_buf" 1587 | version = "0.0.6" 1588 | source = "registry+https://github.com/rust-lang/crates.io-index" 1589 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1590 | dependencies = [ 1591 | "libc", 1592 | ] 1593 | 1594 | [[package]] 1595 | name = "memchr" 1596 | version = "2.7.4" 1597 | source = "registry+https://github.com/rust-lang/crates.io-index" 1598 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1599 | 1600 | [[package]] 1601 | name = "memmap2" 1602 | version = "0.9.5" 1603 | source = "registry+https://github.com/rust-lang/crates.io-index" 1604 | checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" 1605 | dependencies = [ 1606 | "libc", 1607 | ] 1608 | 1609 | [[package]] 1610 | name = "memoffset" 1611 | version = "0.9.1" 1612 | source = "registry+https://github.com/rust-lang/crates.io-index" 1613 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 1614 | dependencies = [ 1615 | "autocfg", 1616 | ] 1617 | 1618 | [[package]] 1619 | name = "metal" 1620 | version = "0.31.0" 1621 | source = "registry+https://github.com/rust-lang/crates.io-index" 1622 | checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" 1623 | dependencies = [ 1624 | "bitflags 2.8.0", 1625 | "block", 1626 | "core-graphics-types", 1627 | "foreign-types", 1628 | "log", 1629 | "objc", 1630 | "paste", 1631 | ] 1632 | 1633 | [[package]] 1634 | name = "mime" 1635 | version = "0.3.17" 1636 | source = "registry+https://github.com/rust-lang/crates.io-index" 1637 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1638 | 1639 | [[package]] 1640 | name = "mime_guess2" 1641 | version = "2.0.5" 1642 | source = "registry+https://github.com/rust-lang/crates.io-index" 1643 | checksum = "25a3333bb1609500601edc766a39b4c1772874a4ce26022f4d866854dc020c41" 1644 | dependencies = [ 1645 | "mime", 1646 | "unicase", 1647 | ] 1648 | 1649 | [[package]] 1650 | name = "miniz_oxide" 1651 | version = "0.7.4" 1652 | source = "registry+https://github.com/rust-lang/crates.io-index" 1653 | checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" 1654 | dependencies = [ 1655 | "adler", 1656 | "simd-adler32", 1657 | ] 1658 | 1659 | [[package]] 1660 | name = "miniz_oxide" 1661 | version = "0.8.0" 1662 | source = "registry+https://github.com/rust-lang/crates.io-index" 1663 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 1664 | dependencies = [ 1665 | "adler2", 1666 | ] 1667 | 1668 | [[package]] 1669 | name = "naga" 1670 | version = "24.0.0" 1671 | source = "registry+https://github.com/rust-lang/crates.io-index" 1672 | checksum = "e380993072e52eef724eddfcde0ed013b0c023c3f0417336ed041aa9f076994e" 1673 | dependencies = [ 1674 | "arrayvec", 1675 | "bit-set", 1676 | "bitflags 2.8.0", 1677 | "cfg_aliases", 1678 | "codespan-reporting", 1679 | "hexf-parse", 1680 | "indexmap", 1681 | "log", 1682 | "rustc-hash", 1683 | "spirv", 1684 | "strum", 1685 | "termcolor", 1686 | "thiserror 2.0.11", 1687 | "unicode-xid", 1688 | ] 1689 | 1690 | [[package]] 1691 | name = "ndk" 1692 | version = "0.9.0" 1693 | source = "registry+https://github.com/rust-lang/crates.io-index" 1694 | checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" 1695 | dependencies = [ 1696 | "bitflags 2.8.0", 1697 | "jni-sys", 1698 | "log", 1699 | "ndk-sys 0.6.0+11769913", 1700 | "num_enum", 1701 | "raw-window-handle", 1702 | "thiserror 1.0.69", 1703 | ] 1704 | 1705 | [[package]] 1706 | name = "ndk-context" 1707 | version = "0.1.1" 1708 | source = "registry+https://github.com/rust-lang/crates.io-index" 1709 | checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 1710 | 1711 | [[package]] 1712 | name = "ndk-sys" 1713 | version = "0.5.0+25.2.9519653" 1714 | source = "registry+https://github.com/rust-lang/crates.io-index" 1715 | checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" 1716 | dependencies = [ 1717 | "jni-sys", 1718 | ] 1719 | 1720 | [[package]] 1721 | name = "ndk-sys" 1722 | version = "0.6.0+11769913" 1723 | source = "registry+https://github.com/rust-lang/crates.io-index" 1724 | checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" 1725 | dependencies = [ 1726 | "jni-sys", 1727 | ] 1728 | 1729 | [[package]] 1730 | name = "nix" 1731 | version = "0.29.0" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" 1734 | dependencies = [ 1735 | "bitflags 2.8.0", 1736 | "cfg-if", 1737 | "cfg_aliases", 1738 | "libc", 1739 | "memoffset", 1740 | ] 1741 | 1742 | [[package]] 1743 | name = "nohash-hasher" 1744 | version = "0.2.0" 1745 | source = "registry+https://github.com/rust-lang/crates.io-index" 1746 | checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" 1747 | 1748 | [[package]] 1749 | name = "num-traits" 1750 | version = "0.2.19" 1751 | source = "registry+https://github.com/rust-lang/crates.io-index" 1752 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1753 | dependencies = [ 1754 | "autocfg", 1755 | ] 1756 | 1757 | [[package]] 1758 | name = "num_enum" 1759 | version = "0.7.3" 1760 | source = "registry+https://github.com/rust-lang/crates.io-index" 1761 | checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" 1762 | dependencies = [ 1763 | "num_enum_derive", 1764 | ] 1765 | 1766 | [[package]] 1767 | name = "num_enum_derive" 1768 | version = "0.7.3" 1769 | source = "registry+https://github.com/rust-lang/crates.io-index" 1770 | checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" 1771 | dependencies = [ 1772 | "proc-macro-crate", 1773 | "proc-macro2", 1774 | "quote", 1775 | "syn", 1776 | ] 1777 | 1778 | [[package]] 1779 | name = "objc" 1780 | version = "0.2.7" 1781 | source = "registry+https://github.com/rust-lang/crates.io-index" 1782 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 1783 | dependencies = [ 1784 | "malloc_buf", 1785 | ] 1786 | 1787 | [[package]] 1788 | name = "objc-sys" 1789 | version = "0.3.5" 1790 | source = "registry+https://github.com/rust-lang/crates.io-index" 1791 | checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" 1792 | 1793 | [[package]] 1794 | name = "objc2" 1795 | version = "0.5.2" 1796 | source = "registry+https://github.com/rust-lang/crates.io-index" 1797 | checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" 1798 | dependencies = [ 1799 | "objc-sys", 1800 | "objc2-encode", 1801 | ] 1802 | 1803 | [[package]] 1804 | name = "objc2-app-kit" 1805 | version = "0.2.2" 1806 | source = "registry+https://github.com/rust-lang/crates.io-index" 1807 | checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" 1808 | dependencies = [ 1809 | "bitflags 2.8.0", 1810 | "block2", 1811 | "libc", 1812 | "objc2", 1813 | "objc2-core-data", 1814 | "objc2-core-image", 1815 | "objc2-foundation", 1816 | "objc2-quartz-core", 1817 | ] 1818 | 1819 | [[package]] 1820 | name = "objc2-cloud-kit" 1821 | version = "0.2.2" 1822 | source = "registry+https://github.com/rust-lang/crates.io-index" 1823 | checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" 1824 | dependencies = [ 1825 | "bitflags 2.8.0", 1826 | "block2", 1827 | "objc2", 1828 | "objc2-core-location", 1829 | "objc2-foundation", 1830 | ] 1831 | 1832 | [[package]] 1833 | name = "objc2-contacts" 1834 | version = "0.2.2" 1835 | source = "registry+https://github.com/rust-lang/crates.io-index" 1836 | checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" 1837 | dependencies = [ 1838 | "block2", 1839 | "objc2", 1840 | "objc2-foundation", 1841 | ] 1842 | 1843 | [[package]] 1844 | name = "objc2-core-data" 1845 | version = "0.2.2" 1846 | source = "registry+https://github.com/rust-lang/crates.io-index" 1847 | checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" 1848 | dependencies = [ 1849 | "bitflags 2.8.0", 1850 | "block2", 1851 | "objc2", 1852 | "objc2-foundation", 1853 | ] 1854 | 1855 | [[package]] 1856 | name = "objc2-core-image" 1857 | version = "0.2.2" 1858 | source = "registry+https://github.com/rust-lang/crates.io-index" 1859 | checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" 1860 | dependencies = [ 1861 | "block2", 1862 | "objc2", 1863 | "objc2-foundation", 1864 | "objc2-metal", 1865 | ] 1866 | 1867 | [[package]] 1868 | name = "objc2-core-location" 1869 | version = "0.2.2" 1870 | source = "registry+https://github.com/rust-lang/crates.io-index" 1871 | checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" 1872 | dependencies = [ 1873 | "block2", 1874 | "objc2", 1875 | "objc2-contacts", 1876 | "objc2-foundation", 1877 | ] 1878 | 1879 | [[package]] 1880 | name = "objc2-encode" 1881 | version = "4.0.3" 1882 | source = "registry+https://github.com/rust-lang/crates.io-index" 1883 | checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" 1884 | 1885 | [[package]] 1886 | name = "objc2-foundation" 1887 | version = "0.2.2" 1888 | source = "registry+https://github.com/rust-lang/crates.io-index" 1889 | checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" 1890 | dependencies = [ 1891 | "bitflags 2.8.0", 1892 | "block2", 1893 | "dispatch", 1894 | "libc", 1895 | "objc2", 1896 | ] 1897 | 1898 | [[package]] 1899 | name = "objc2-link-presentation" 1900 | version = "0.2.2" 1901 | source = "registry+https://github.com/rust-lang/crates.io-index" 1902 | checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" 1903 | dependencies = [ 1904 | "block2", 1905 | "objc2", 1906 | "objc2-app-kit", 1907 | "objc2-foundation", 1908 | ] 1909 | 1910 | [[package]] 1911 | name = "objc2-metal" 1912 | version = "0.2.2" 1913 | source = "registry+https://github.com/rust-lang/crates.io-index" 1914 | checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" 1915 | dependencies = [ 1916 | "bitflags 2.8.0", 1917 | "block2", 1918 | "objc2", 1919 | "objc2-foundation", 1920 | ] 1921 | 1922 | [[package]] 1923 | name = "objc2-quartz-core" 1924 | version = "0.2.2" 1925 | source = "registry+https://github.com/rust-lang/crates.io-index" 1926 | checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" 1927 | dependencies = [ 1928 | "bitflags 2.8.0", 1929 | "block2", 1930 | "objc2", 1931 | "objc2-foundation", 1932 | "objc2-metal", 1933 | ] 1934 | 1935 | [[package]] 1936 | name = "objc2-symbols" 1937 | version = "0.2.2" 1938 | source = "registry+https://github.com/rust-lang/crates.io-index" 1939 | checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" 1940 | dependencies = [ 1941 | "objc2", 1942 | "objc2-foundation", 1943 | ] 1944 | 1945 | [[package]] 1946 | name = "objc2-ui-kit" 1947 | version = "0.2.2" 1948 | source = "registry+https://github.com/rust-lang/crates.io-index" 1949 | checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" 1950 | dependencies = [ 1951 | "bitflags 2.8.0", 1952 | "block2", 1953 | "objc2", 1954 | "objc2-cloud-kit", 1955 | "objc2-core-data", 1956 | "objc2-core-image", 1957 | "objc2-core-location", 1958 | "objc2-foundation", 1959 | "objc2-link-presentation", 1960 | "objc2-quartz-core", 1961 | "objc2-symbols", 1962 | "objc2-uniform-type-identifiers", 1963 | "objc2-user-notifications", 1964 | ] 1965 | 1966 | [[package]] 1967 | name = "objc2-uniform-type-identifiers" 1968 | version = "0.2.2" 1969 | source = "registry+https://github.com/rust-lang/crates.io-index" 1970 | checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" 1971 | dependencies = [ 1972 | "block2", 1973 | "objc2", 1974 | "objc2-foundation", 1975 | ] 1976 | 1977 | [[package]] 1978 | name = "objc2-user-notifications" 1979 | version = "0.2.2" 1980 | source = "registry+https://github.com/rust-lang/crates.io-index" 1981 | checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" 1982 | dependencies = [ 1983 | "bitflags 2.8.0", 1984 | "block2", 1985 | "objc2", 1986 | "objc2-core-location", 1987 | "objc2-foundation", 1988 | ] 1989 | 1990 | [[package]] 1991 | name = "once_cell" 1992 | version = "1.20.2" 1993 | source = "registry+https://github.com/rust-lang/crates.io-index" 1994 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 1995 | 1996 | [[package]] 1997 | name = "orbclient" 1998 | version = "0.3.47" 1999 | source = "registry+https://github.com/rust-lang/crates.io-index" 2000 | checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" 2001 | dependencies = [ 2002 | "libredox", 2003 | ] 2004 | 2005 | [[package]] 2006 | name = "ordered-float" 2007 | version = "4.6.0" 2008 | source = "registry+https://github.com/rust-lang/crates.io-index" 2009 | checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" 2010 | dependencies = [ 2011 | "num-traits", 2012 | ] 2013 | 2014 | [[package]] 2015 | name = "ordered-stream" 2016 | version = "0.2.0" 2017 | source = "registry+https://github.com/rust-lang/crates.io-index" 2018 | checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" 2019 | dependencies = [ 2020 | "futures-core", 2021 | "pin-project-lite", 2022 | ] 2023 | 2024 | [[package]] 2025 | name = "owned_ttf_parser" 2026 | version = "0.24.0" 2027 | source = "registry+https://github.com/rust-lang/crates.io-index" 2028 | checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" 2029 | dependencies = [ 2030 | "ttf-parser", 2031 | ] 2032 | 2033 | [[package]] 2034 | name = "parking" 2035 | version = "2.2.1" 2036 | source = "registry+https://github.com/rust-lang/crates.io-index" 2037 | checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 2038 | 2039 | [[package]] 2040 | name = "parking_lot" 2041 | version = "0.12.3" 2042 | source = "registry+https://github.com/rust-lang/crates.io-index" 2043 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 2044 | dependencies = [ 2045 | "lock_api", 2046 | "parking_lot_core", 2047 | ] 2048 | 2049 | [[package]] 2050 | name = "parking_lot_core" 2051 | version = "0.9.10" 2052 | source = "registry+https://github.com/rust-lang/crates.io-index" 2053 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 2054 | dependencies = [ 2055 | "cfg-if", 2056 | "libc", 2057 | "redox_syscall 0.5.6", 2058 | "smallvec", 2059 | "windows-targets 0.52.6", 2060 | ] 2061 | 2062 | [[package]] 2063 | name = "paste" 2064 | version = "1.0.15" 2065 | source = "registry+https://github.com/rust-lang/crates.io-index" 2066 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 2067 | 2068 | [[package]] 2069 | name = "percent-encoding" 2070 | version = "2.3.1" 2071 | source = "registry+https://github.com/rust-lang/crates.io-index" 2072 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 2073 | 2074 | [[package]] 2075 | name = "pin-project" 2076 | version = "1.1.5" 2077 | source = "registry+https://github.com/rust-lang/crates.io-index" 2078 | checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" 2079 | dependencies = [ 2080 | "pin-project-internal", 2081 | ] 2082 | 2083 | [[package]] 2084 | name = "pin-project-internal" 2085 | version = "1.1.5" 2086 | source = "registry+https://github.com/rust-lang/crates.io-index" 2087 | checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" 2088 | dependencies = [ 2089 | "proc-macro2", 2090 | "quote", 2091 | "syn", 2092 | ] 2093 | 2094 | [[package]] 2095 | name = "pin-project-lite" 2096 | version = "0.2.14" 2097 | source = "registry+https://github.com/rust-lang/crates.io-index" 2098 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 2099 | 2100 | [[package]] 2101 | name = "pin-utils" 2102 | version = "0.1.0" 2103 | source = "registry+https://github.com/rust-lang/crates.io-index" 2104 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 2105 | 2106 | [[package]] 2107 | name = "piper" 2108 | version = "0.2.4" 2109 | source = "registry+https://github.com/rust-lang/crates.io-index" 2110 | checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" 2111 | dependencies = [ 2112 | "atomic-waker", 2113 | "fastrand", 2114 | "futures-io", 2115 | ] 2116 | 2117 | [[package]] 2118 | name = "pkg-config" 2119 | version = "0.3.31" 2120 | source = "registry+https://github.com/rust-lang/crates.io-index" 2121 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 2122 | 2123 | [[package]] 2124 | name = "png" 2125 | version = "0.17.13" 2126 | source = "registry+https://github.com/rust-lang/crates.io-index" 2127 | checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" 2128 | dependencies = [ 2129 | "bitflags 1.3.2", 2130 | "crc32fast", 2131 | "fdeflate", 2132 | "flate2", 2133 | "miniz_oxide 0.7.4", 2134 | ] 2135 | 2136 | [[package]] 2137 | name = "polling" 2138 | version = "3.7.3" 2139 | source = "registry+https://github.com/rust-lang/crates.io-index" 2140 | checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" 2141 | dependencies = [ 2142 | "cfg-if", 2143 | "concurrent-queue", 2144 | "hermit-abi", 2145 | "pin-project-lite", 2146 | "rustix", 2147 | "tracing", 2148 | "windows-sys 0.59.0", 2149 | ] 2150 | 2151 | [[package]] 2152 | name = "ppv-lite86" 2153 | version = "0.2.20" 2154 | source = "registry+https://github.com/rust-lang/crates.io-index" 2155 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 2156 | dependencies = [ 2157 | "zerocopy", 2158 | ] 2159 | 2160 | [[package]] 2161 | name = "proc-macro-crate" 2162 | version = "3.2.0" 2163 | source = "registry+https://github.com/rust-lang/crates.io-index" 2164 | checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" 2165 | dependencies = [ 2166 | "toml_edit", 2167 | ] 2168 | 2169 | [[package]] 2170 | name = "proc-macro2" 2171 | version = "1.0.92" 2172 | source = "registry+https://github.com/rust-lang/crates.io-index" 2173 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 2174 | dependencies = [ 2175 | "unicode-ident", 2176 | ] 2177 | 2178 | [[package]] 2179 | name = "profiling" 2180 | version = "1.0.16" 2181 | source = "registry+https://github.com/rust-lang/crates.io-index" 2182 | checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" 2183 | 2184 | [[package]] 2185 | name = "quick-xml" 2186 | version = "0.30.0" 2187 | source = "registry+https://github.com/rust-lang/crates.io-index" 2188 | checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" 2189 | dependencies = [ 2190 | "memchr", 2191 | "serde", 2192 | ] 2193 | 2194 | [[package]] 2195 | name = "quick-xml" 2196 | version = "0.36.2" 2197 | source = "registry+https://github.com/rust-lang/crates.io-index" 2198 | checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" 2199 | dependencies = [ 2200 | "memchr", 2201 | ] 2202 | 2203 | [[package]] 2204 | name = "quote" 2205 | version = "1.0.37" 2206 | source = "registry+https://github.com/rust-lang/crates.io-index" 2207 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 2208 | dependencies = [ 2209 | "proc-macro2", 2210 | ] 2211 | 2212 | [[package]] 2213 | name = "rand" 2214 | version = "0.8.5" 2215 | source = "registry+https://github.com/rust-lang/crates.io-index" 2216 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 2217 | dependencies = [ 2218 | "libc", 2219 | "rand_chacha", 2220 | "rand_core", 2221 | ] 2222 | 2223 | [[package]] 2224 | name = "rand_chacha" 2225 | version = "0.3.1" 2226 | source = "registry+https://github.com/rust-lang/crates.io-index" 2227 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 2228 | dependencies = [ 2229 | "ppv-lite86", 2230 | "rand_core", 2231 | ] 2232 | 2233 | [[package]] 2234 | name = "rand_core" 2235 | version = "0.6.4" 2236 | source = "registry+https://github.com/rust-lang/crates.io-index" 2237 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 2238 | dependencies = [ 2239 | "getrandom", 2240 | ] 2241 | 2242 | [[package]] 2243 | name = "raw-window-handle" 2244 | version = "0.6.2" 2245 | source = "registry+https://github.com/rust-lang/crates.io-index" 2246 | checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" 2247 | 2248 | [[package]] 2249 | name = "redox_syscall" 2250 | version = "0.4.1" 2251 | source = "registry+https://github.com/rust-lang/crates.io-index" 2252 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 2253 | dependencies = [ 2254 | "bitflags 1.3.2", 2255 | ] 2256 | 2257 | [[package]] 2258 | name = "redox_syscall" 2259 | version = "0.5.6" 2260 | source = "registry+https://github.com/rust-lang/crates.io-index" 2261 | checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b" 2262 | dependencies = [ 2263 | "bitflags 2.8.0", 2264 | ] 2265 | 2266 | [[package]] 2267 | name = "renderdoc-sys" 2268 | version = "1.1.0" 2269 | source = "registry+https://github.com/rust-lang/crates.io-index" 2270 | checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" 2271 | 2272 | [[package]] 2273 | name = "rustc-hash" 2274 | version = "1.1.0" 2275 | source = "registry+https://github.com/rust-lang/crates.io-index" 2276 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 2277 | 2278 | [[package]] 2279 | name = "rustix" 2280 | version = "0.38.37" 2281 | source = "registry+https://github.com/rust-lang/crates.io-index" 2282 | checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" 2283 | dependencies = [ 2284 | "bitflags 2.8.0", 2285 | "errno", 2286 | "libc", 2287 | "linux-raw-sys", 2288 | "windows-sys 0.52.0", 2289 | ] 2290 | 2291 | [[package]] 2292 | name = "rustversion" 2293 | version = "1.0.19" 2294 | source = "registry+https://github.com/rust-lang/crates.io-index" 2295 | checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" 2296 | 2297 | [[package]] 2298 | name = "same-file" 2299 | version = "1.0.6" 2300 | source = "registry+https://github.com/rust-lang/crates.io-index" 2301 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 2302 | dependencies = [ 2303 | "winapi-util", 2304 | ] 2305 | 2306 | [[package]] 2307 | name = "scoped-tls" 2308 | version = "1.0.1" 2309 | source = "registry+https://github.com/rust-lang/crates.io-index" 2310 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 2311 | 2312 | [[package]] 2313 | name = "scopeguard" 2314 | version = "1.2.0" 2315 | source = "registry+https://github.com/rust-lang/crates.io-index" 2316 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 2317 | 2318 | [[package]] 2319 | name = "sctk-adwaita" 2320 | version = "0.10.1" 2321 | source = "registry+https://github.com/rust-lang/crates.io-index" 2322 | checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" 2323 | dependencies = [ 2324 | "ab_glyph", 2325 | "log", 2326 | "memmap2", 2327 | "smithay-client-toolkit", 2328 | "tiny-skia", 2329 | ] 2330 | 2331 | [[package]] 2332 | name = "serde" 2333 | version = "1.0.210" 2334 | source = "registry+https://github.com/rust-lang/crates.io-index" 2335 | checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 2336 | dependencies = [ 2337 | "serde_derive", 2338 | ] 2339 | 2340 | [[package]] 2341 | name = "serde_derive" 2342 | version = "1.0.210" 2343 | source = "registry+https://github.com/rust-lang/crates.io-index" 2344 | checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 2345 | dependencies = [ 2346 | "proc-macro2", 2347 | "quote", 2348 | "syn", 2349 | ] 2350 | 2351 | [[package]] 2352 | name = "serde_repr" 2353 | version = "0.1.19" 2354 | source = "registry+https://github.com/rust-lang/crates.io-index" 2355 | checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" 2356 | dependencies = [ 2357 | "proc-macro2", 2358 | "quote", 2359 | "syn", 2360 | ] 2361 | 2362 | [[package]] 2363 | name = "sha1" 2364 | version = "0.10.6" 2365 | source = "registry+https://github.com/rust-lang/crates.io-index" 2366 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 2367 | dependencies = [ 2368 | "cfg-if", 2369 | "cpufeatures", 2370 | "digest", 2371 | ] 2372 | 2373 | [[package]] 2374 | name = "shlex" 2375 | version = "1.3.0" 2376 | source = "registry+https://github.com/rust-lang/crates.io-index" 2377 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 2378 | 2379 | [[package]] 2380 | name = "signal-hook-registry" 2381 | version = "1.4.2" 2382 | source = "registry+https://github.com/rust-lang/crates.io-index" 2383 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 2384 | dependencies = [ 2385 | "libc", 2386 | ] 2387 | 2388 | [[package]] 2389 | name = "simd-adler32" 2390 | version = "0.3.7" 2391 | source = "registry+https://github.com/rust-lang/crates.io-index" 2392 | checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 2393 | 2394 | [[package]] 2395 | name = "slab" 2396 | version = "0.4.9" 2397 | source = "registry+https://github.com/rust-lang/crates.io-index" 2398 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 2399 | dependencies = [ 2400 | "autocfg", 2401 | ] 2402 | 2403 | [[package]] 2404 | name = "slotmap" 2405 | version = "1.0.7" 2406 | source = "registry+https://github.com/rust-lang/crates.io-index" 2407 | checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" 2408 | dependencies = [ 2409 | "version_check", 2410 | ] 2411 | 2412 | [[package]] 2413 | name = "smallvec" 2414 | version = "1.13.2" 2415 | source = "registry+https://github.com/rust-lang/crates.io-index" 2416 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 2417 | 2418 | [[package]] 2419 | name = "smithay-client-toolkit" 2420 | version = "0.19.2" 2421 | source = "registry+https://github.com/rust-lang/crates.io-index" 2422 | checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" 2423 | dependencies = [ 2424 | "bitflags 2.8.0", 2425 | "calloop", 2426 | "calloop-wayland-source", 2427 | "cursor-icon", 2428 | "libc", 2429 | "log", 2430 | "memmap2", 2431 | "rustix", 2432 | "thiserror 1.0.69", 2433 | "wayland-backend", 2434 | "wayland-client", 2435 | "wayland-csd-frame", 2436 | "wayland-cursor", 2437 | "wayland-protocols", 2438 | "wayland-protocols-wlr", 2439 | "wayland-scanner", 2440 | "xkeysym", 2441 | ] 2442 | 2443 | [[package]] 2444 | name = "smithay-clipboard" 2445 | version = "0.7.2" 2446 | source = "registry+https://github.com/rust-lang/crates.io-index" 2447 | checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" 2448 | dependencies = [ 2449 | "libc", 2450 | "smithay-client-toolkit", 2451 | "wayland-backend", 2452 | ] 2453 | 2454 | [[package]] 2455 | name = "smol_str" 2456 | version = "0.2.2" 2457 | source = "registry+https://github.com/rust-lang/crates.io-index" 2458 | checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead" 2459 | dependencies = [ 2460 | "serde", 2461 | ] 2462 | 2463 | [[package]] 2464 | name = "spirv" 2465 | version = "0.3.0+sdk-1.3.268.0" 2466 | source = "registry+https://github.com/rust-lang/crates.io-index" 2467 | checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" 2468 | dependencies = [ 2469 | "bitflags 2.8.0", 2470 | ] 2471 | 2472 | [[package]] 2473 | name = "static_assertions" 2474 | version = "1.1.0" 2475 | source = "registry+https://github.com/rust-lang/crates.io-index" 2476 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 2477 | 2478 | [[package]] 2479 | name = "strict-num" 2480 | version = "0.1.1" 2481 | source = "registry+https://github.com/rust-lang/crates.io-index" 2482 | checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" 2483 | 2484 | [[package]] 2485 | name = "strum" 2486 | version = "0.26.3" 2487 | source = "registry+https://github.com/rust-lang/crates.io-index" 2488 | checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" 2489 | dependencies = [ 2490 | "strum_macros", 2491 | ] 2492 | 2493 | [[package]] 2494 | name = "strum_macros" 2495 | version = "0.26.4" 2496 | source = "registry+https://github.com/rust-lang/crates.io-index" 2497 | checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" 2498 | dependencies = [ 2499 | "heck", 2500 | "proc-macro2", 2501 | "quote", 2502 | "rustversion", 2503 | "syn", 2504 | ] 2505 | 2506 | [[package]] 2507 | name = "syn" 2508 | version = "2.0.90" 2509 | source = "registry+https://github.com/rust-lang/crates.io-index" 2510 | checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" 2511 | dependencies = [ 2512 | "proc-macro2", 2513 | "quote", 2514 | "unicode-ident", 2515 | ] 2516 | 2517 | [[package]] 2518 | name = "tempfile" 2519 | version = "3.12.0" 2520 | source = "registry+https://github.com/rust-lang/crates.io-index" 2521 | checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" 2522 | dependencies = [ 2523 | "cfg-if", 2524 | "fastrand", 2525 | "once_cell", 2526 | "rustix", 2527 | "windows-sys 0.59.0", 2528 | ] 2529 | 2530 | [[package]] 2531 | name = "termcolor" 2532 | version = "1.4.1" 2533 | source = "registry+https://github.com/rust-lang/crates.io-index" 2534 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 2535 | dependencies = [ 2536 | "winapi-util", 2537 | ] 2538 | 2539 | [[package]] 2540 | name = "thiserror" 2541 | version = "1.0.69" 2542 | source = "registry+https://github.com/rust-lang/crates.io-index" 2543 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 2544 | dependencies = [ 2545 | "thiserror-impl 1.0.69", 2546 | ] 2547 | 2548 | [[package]] 2549 | name = "thiserror" 2550 | version = "2.0.11" 2551 | source = "registry+https://github.com/rust-lang/crates.io-index" 2552 | checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" 2553 | dependencies = [ 2554 | "thiserror-impl 2.0.11", 2555 | ] 2556 | 2557 | [[package]] 2558 | name = "thiserror-impl" 2559 | version = "1.0.69" 2560 | source = "registry+https://github.com/rust-lang/crates.io-index" 2561 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 2562 | dependencies = [ 2563 | "proc-macro2", 2564 | "quote", 2565 | "syn", 2566 | ] 2567 | 2568 | [[package]] 2569 | name = "thiserror-impl" 2570 | version = "2.0.11" 2571 | source = "registry+https://github.com/rust-lang/crates.io-index" 2572 | checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" 2573 | dependencies = [ 2574 | "proc-macro2", 2575 | "quote", 2576 | "syn", 2577 | ] 2578 | 2579 | [[package]] 2580 | name = "tiff" 2581 | version = "0.9.1" 2582 | source = "registry+https://github.com/rust-lang/crates.io-index" 2583 | checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" 2584 | dependencies = [ 2585 | "flate2", 2586 | "jpeg-decoder", 2587 | "weezl", 2588 | ] 2589 | 2590 | [[package]] 2591 | name = "tiny-skia" 2592 | version = "0.11.4" 2593 | source = "registry+https://github.com/rust-lang/crates.io-index" 2594 | checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" 2595 | dependencies = [ 2596 | "arrayref", 2597 | "arrayvec", 2598 | "bytemuck", 2599 | "cfg-if", 2600 | "log", 2601 | "tiny-skia-path", 2602 | ] 2603 | 2604 | [[package]] 2605 | name = "tiny-skia-path" 2606 | version = "0.11.4" 2607 | source = "registry+https://github.com/rust-lang/crates.io-index" 2608 | checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" 2609 | dependencies = [ 2610 | "arrayref", 2611 | "bytemuck", 2612 | "strict-num", 2613 | ] 2614 | 2615 | [[package]] 2616 | name = "tinyvec" 2617 | version = "1.8.0" 2618 | source = "registry+https://github.com/rust-lang/crates.io-index" 2619 | checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" 2620 | dependencies = [ 2621 | "tinyvec_macros", 2622 | ] 2623 | 2624 | [[package]] 2625 | name = "tinyvec_macros" 2626 | version = "0.1.1" 2627 | source = "registry+https://github.com/rust-lang/crates.io-index" 2628 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 2629 | 2630 | [[package]] 2631 | name = "toml_datetime" 2632 | version = "0.6.8" 2633 | source = "registry+https://github.com/rust-lang/crates.io-index" 2634 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 2635 | 2636 | [[package]] 2637 | name = "toml_edit" 2638 | version = "0.22.22" 2639 | source = "registry+https://github.com/rust-lang/crates.io-index" 2640 | checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" 2641 | dependencies = [ 2642 | "indexmap", 2643 | "toml_datetime", 2644 | "winnow", 2645 | ] 2646 | 2647 | [[package]] 2648 | name = "tracing" 2649 | version = "0.1.40" 2650 | source = "registry+https://github.com/rust-lang/crates.io-index" 2651 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 2652 | dependencies = [ 2653 | "pin-project-lite", 2654 | "tracing-attributes", 2655 | "tracing-core", 2656 | ] 2657 | 2658 | [[package]] 2659 | name = "tracing-attributes" 2660 | version = "0.1.27" 2661 | source = "registry+https://github.com/rust-lang/crates.io-index" 2662 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 2663 | dependencies = [ 2664 | "proc-macro2", 2665 | "quote", 2666 | "syn", 2667 | ] 2668 | 2669 | [[package]] 2670 | name = "tracing-core" 2671 | version = "0.1.32" 2672 | source = "registry+https://github.com/rust-lang/crates.io-index" 2673 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 2674 | dependencies = [ 2675 | "once_cell", 2676 | ] 2677 | 2678 | [[package]] 2679 | name = "ttf-parser" 2680 | version = "0.24.1" 2681 | source = "registry+https://github.com/rust-lang/crates.io-index" 2682 | checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a" 2683 | 2684 | [[package]] 2685 | name = "type-map" 2686 | version = "0.5.0" 2687 | source = "registry+https://github.com/rust-lang/crates.io-index" 2688 | checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f" 2689 | dependencies = [ 2690 | "rustc-hash", 2691 | ] 2692 | 2693 | [[package]] 2694 | name = "typenum" 2695 | version = "1.17.0" 2696 | source = "registry+https://github.com/rust-lang/crates.io-index" 2697 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2698 | 2699 | [[package]] 2700 | name = "uds_windows" 2701 | version = "1.1.0" 2702 | source = "registry+https://github.com/rust-lang/crates.io-index" 2703 | checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" 2704 | dependencies = [ 2705 | "memoffset", 2706 | "tempfile", 2707 | "winapi", 2708 | ] 2709 | 2710 | [[package]] 2711 | name = "unicase" 2712 | version = "2.7.0" 2713 | source = "registry+https://github.com/rust-lang/crates.io-index" 2714 | checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" 2715 | dependencies = [ 2716 | "version_check", 2717 | ] 2718 | 2719 | [[package]] 2720 | name = "unicode-bidi" 2721 | version = "0.3.15" 2722 | source = "registry+https://github.com/rust-lang/crates.io-index" 2723 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 2724 | 2725 | [[package]] 2726 | name = "unicode-ident" 2727 | version = "1.0.13" 2728 | source = "registry+https://github.com/rust-lang/crates.io-index" 2729 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 2730 | 2731 | [[package]] 2732 | name = "unicode-normalization" 2733 | version = "0.1.24" 2734 | source = "registry+https://github.com/rust-lang/crates.io-index" 2735 | checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" 2736 | dependencies = [ 2737 | "tinyvec", 2738 | ] 2739 | 2740 | [[package]] 2741 | name = "unicode-segmentation" 2742 | version = "1.12.0" 2743 | source = "registry+https://github.com/rust-lang/crates.io-index" 2744 | checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 2745 | 2746 | [[package]] 2747 | name = "unicode-width" 2748 | version = "0.1.14" 2749 | source = "registry+https://github.com/rust-lang/crates.io-index" 2750 | checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 2751 | 2752 | [[package]] 2753 | name = "unicode-xid" 2754 | version = "0.2.6" 2755 | source = "registry+https://github.com/rust-lang/crates.io-index" 2756 | checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" 2757 | 2758 | [[package]] 2759 | name = "unicode_names2" 2760 | version = "0.6.0" 2761 | source = "registry+https://github.com/rust-lang/crates.io-index" 2762 | checksum = "446c96c6dd42604779487f0a981060717156648c1706aa1f464677f03c6cc059" 2763 | 2764 | [[package]] 2765 | name = "url" 2766 | version = "2.5.2" 2767 | source = "registry+https://github.com/rust-lang/crates.io-index" 2768 | checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" 2769 | dependencies = [ 2770 | "form_urlencoded", 2771 | "idna", 2772 | "percent-encoding", 2773 | ] 2774 | 2775 | [[package]] 2776 | name = "version_check" 2777 | version = "0.9.5" 2778 | source = "registry+https://github.com/rust-lang/crates.io-index" 2779 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2780 | 2781 | [[package]] 2782 | name = "walkdir" 2783 | version = "2.5.0" 2784 | source = "registry+https://github.com/rust-lang/crates.io-index" 2785 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 2786 | dependencies = [ 2787 | "same-file", 2788 | "winapi-util", 2789 | ] 2790 | 2791 | [[package]] 2792 | name = "wasi" 2793 | version = "0.11.0+wasi-snapshot-preview1" 2794 | source = "registry+https://github.com/rust-lang/crates.io-index" 2795 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2796 | 2797 | [[package]] 2798 | name = "wasm-bindgen" 2799 | version = "0.2.99" 2800 | source = "registry+https://github.com/rust-lang/crates.io-index" 2801 | checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" 2802 | dependencies = [ 2803 | "cfg-if", 2804 | "once_cell", 2805 | "wasm-bindgen-macro", 2806 | ] 2807 | 2808 | [[package]] 2809 | name = "wasm-bindgen-backend" 2810 | version = "0.2.99" 2811 | source = "registry+https://github.com/rust-lang/crates.io-index" 2812 | checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" 2813 | dependencies = [ 2814 | "bumpalo", 2815 | "log", 2816 | "proc-macro2", 2817 | "quote", 2818 | "syn", 2819 | "wasm-bindgen-shared", 2820 | ] 2821 | 2822 | [[package]] 2823 | name = "wasm-bindgen-futures" 2824 | version = "0.4.49" 2825 | source = "registry+https://github.com/rust-lang/crates.io-index" 2826 | checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" 2827 | dependencies = [ 2828 | "cfg-if", 2829 | "js-sys", 2830 | "once_cell", 2831 | "wasm-bindgen", 2832 | "web-sys", 2833 | ] 2834 | 2835 | [[package]] 2836 | name = "wasm-bindgen-macro" 2837 | version = "0.2.99" 2838 | source = "registry+https://github.com/rust-lang/crates.io-index" 2839 | checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" 2840 | dependencies = [ 2841 | "quote", 2842 | "wasm-bindgen-macro-support", 2843 | ] 2844 | 2845 | [[package]] 2846 | name = "wasm-bindgen-macro-support" 2847 | version = "0.2.99" 2848 | source = "registry+https://github.com/rust-lang/crates.io-index" 2849 | checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" 2850 | dependencies = [ 2851 | "proc-macro2", 2852 | "quote", 2853 | "syn", 2854 | "wasm-bindgen-backend", 2855 | "wasm-bindgen-shared", 2856 | ] 2857 | 2858 | [[package]] 2859 | name = "wasm-bindgen-shared" 2860 | version = "0.2.99" 2861 | source = "registry+https://github.com/rust-lang/crates.io-index" 2862 | checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" 2863 | 2864 | [[package]] 2865 | name = "wayland-backend" 2866 | version = "0.3.7" 2867 | source = "registry+https://github.com/rust-lang/crates.io-index" 2868 | checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" 2869 | dependencies = [ 2870 | "cc", 2871 | "downcast-rs", 2872 | "rustix", 2873 | "scoped-tls", 2874 | "smallvec", 2875 | "wayland-sys", 2876 | ] 2877 | 2878 | [[package]] 2879 | name = "wayland-client" 2880 | version = "0.31.6" 2881 | source = "registry+https://github.com/rust-lang/crates.io-index" 2882 | checksum = "e3f45d1222915ef1fd2057220c1d9d9624b7654443ea35c3877f7a52bd0a5a2d" 2883 | dependencies = [ 2884 | "bitflags 2.8.0", 2885 | "rustix", 2886 | "wayland-backend", 2887 | "wayland-scanner", 2888 | ] 2889 | 2890 | [[package]] 2891 | name = "wayland-csd-frame" 2892 | version = "0.3.0" 2893 | source = "registry+https://github.com/rust-lang/crates.io-index" 2894 | checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" 2895 | dependencies = [ 2896 | "bitflags 2.8.0", 2897 | "cursor-icon", 2898 | "wayland-backend", 2899 | ] 2900 | 2901 | [[package]] 2902 | name = "wayland-cursor" 2903 | version = "0.31.6" 2904 | source = "registry+https://github.com/rust-lang/crates.io-index" 2905 | checksum = "3a94697e66e76c85923b0d28a0c251e8f0666f58fc47d316c0f4da6da75d37cb" 2906 | dependencies = [ 2907 | "rustix", 2908 | "wayland-client", 2909 | "xcursor", 2910 | ] 2911 | 2912 | [[package]] 2913 | name = "wayland-protocols" 2914 | version = "0.32.4" 2915 | source = "registry+https://github.com/rust-lang/crates.io-index" 2916 | checksum = "2b5755d77ae9040bb872a25026555ce4cb0ae75fd923e90d25fba07d81057de0" 2917 | dependencies = [ 2918 | "bitflags 2.8.0", 2919 | "wayland-backend", 2920 | "wayland-client", 2921 | "wayland-scanner", 2922 | ] 2923 | 2924 | [[package]] 2925 | name = "wayland-protocols-plasma" 2926 | version = "0.3.4" 2927 | source = "registry+https://github.com/rust-lang/crates.io-index" 2928 | checksum = "8a0a41a6875e585172495f7a96dfa42ca7e0213868f4f15c313f7c33221a7eff" 2929 | dependencies = [ 2930 | "bitflags 2.8.0", 2931 | "wayland-backend", 2932 | "wayland-client", 2933 | "wayland-protocols", 2934 | "wayland-scanner", 2935 | ] 2936 | 2937 | [[package]] 2938 | name = "wayland-protocols-wlr" 2939 | version = "0.3.4" 2940 | source = "registry+https://github.com/rust-lang/crates.io-index" 2941 | checksum = "dad87b5fd1b1d3ca2f792df8f686a2a11e3fe1077b71096f7a175ab699f89109" 2942 | dependencies = [ 2943 | "bitflags 2.8.0", 2944 | "wayland-backend", 2945 | "wayland-client", 2946 | "wayland-protocols", 2947 | "wayland-scanner", 2948 | ] 2949 | 2950 | [[package]] 2951 | name = "wayland-scanner" 2952 | version = "0.31.5" 2953 | source = "registry+https://github.com/rust-lang/crates.io-index" 2954 | checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" 2955 | dependencies = [ 2956 | "proc-macro2", 2957 | "quick-xml 0.36.2", 2958 | "quote", 2959 | ] 2960 | 2961 | [[package]] 2962 | name = "wayland-sys" 2963 | version = "0.31.5" 2964 | source = "registry+https://github.com/rust-lang/crates.io-index" 2965 | checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" 2966 | dependencies = [ 2967 | "dlib", 2968 | "log", 2969 | "once_cell", 2970 | "pkg-config", 2971 | ] 2972 | 2973 | [[package]] 2974 | name = "web-sys" 2975 | version = "0.3.76" 2976 | source = "registry+https://github.com/rust-lang/crates.io-index" 2977 | checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" 2978 | dependencies = [ 2979 | "js-sys", 2980 | "wasm-bindgen", 2981 | ] 2982 | 2983 | [[package]] 2984 | name = "web-time" 2985 | version = "1.1.0" 2986 | source = "registry+https://github.com/rust-lang/crates.io-index" 2987 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 2988 | dependencies = [ 2989 | "js-sys", 2990 | "wasm-bindgen", 2991 | ] 2992 | 2993 | [[package]] 2994 | name = "webbrowser" 2995 | version = "1.0.2" 2996 | source = "registry+https://github.com/rust-lang/crates.io-index" 2997 | checksum = "2e5f07fb9bc8de2ddfe6b24a71a75430673fd679e568c48b52716cef1cfae923" 2998 | dependencies = [ 2999 | "block2", 3000 | "core-foundation 0.10.0", 3001 | "home", 3002 | "jni", 3003 | "log", 3004 | "ndk-context", 3005 | "objc2", 3006 | "objc2-foundation", 3007 | "url", 3008 | "web-sys", 3009 | ] 3010 | 3011 | [[package]] 3012 | name = "weezl" 3013 | version = "0.1.8" 3014 | source = "registry+https://github.com/rust-lang/crates.io-index" 3015 | checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" 3016 | 3017 | [[package]] 3018 | name = "wgpu" 3019 | version = "24.0.1" 3020 | source = "registry+https://github.com/rust-lang/crates.io-index" 3021 | checksum = "47f55718f85c2fa756edffa0e7f0e0a60aba463d1362b57e23123c58f035e4b6" 3022 | dependencies = [ 3023 | "arrayvec", 3024 | "bitflags 2.8.0", 3025 | "cfg_aliases", 3026 | "document-features", 3027 | "js-sys", 3028 | "log", 3029 | "parking_lot", 3030 | "profiling", 3031 | "raw-window-handle", 3032 | "smallvec", 3033 | "static_assertions", 3034 | "wasm-bindgen", 3035 | "wasm-bindgen-futures", 3036 | "web-sys", 3037 | "wgpu-core", 3038 | "wgpu-hal", 3039 | "wgpu-types", 3040 | ] 3041 | 3042 | [[package]] 3043 | name = "wgpu-core" 3044 | version = "24.0.0" 3045 | source = "registry+https://github.com/rust-lang/crates.io-index" 3046 | checksum = "82a39b8842dc9ffcbe34346e3ab6d496b32a47f6497e119d762c97fcaae3cb37" 3047 | dependencies = [ 3048 | "arrayvec", 3049 | "bit-vec", 3050 | "bitflags 2.8.0", 3051 | "cfg_aliases", 3052 | "document-features", 3053 | "indexmap", 3054 | "log", 3055 | "naga", 3056 | "once_cell", 3057 | "parking_lot", 3058 | "profiling", 3059 | "raw-window-handle", 3060 | "rustc-hash", 3061 | "smallvec", 3062 | "thiserror 2.0.11", 3063 | "wgpu-hal", 3064 | "wgpu-types", 3065 | ] 3066 | 3067 | [[package]] 3068 | name = "wgpu-hal" 3069 | version = "24.0.0" 3070 | source = "registry+https://github.com/rust-lang/crates.io-index" 3071 | checksum = "5a782e5056b060b0b4010881d1decddd059e44f2ecd01e2db2971b48ad3627e5" 3072 | dependencies = [ 3073 | "android_system_properties", 3074 | "arrayvec", 3075 | "ash", 3076 | "bitflags 2.8.0", 3077 | "bytemuck", 3078 | "cfg_aliases", 3079 | "core-graphics-types", 3080 | "glow", 3081 | "glutin_wgl_sys", 3082 | "gpu-alloc", 3083 | "gpu-descriptor", 3084 | "js-sys", 3085 | "khronos-egl", 3086 | "libc", 3087 | "libloading", 3088 | "log", 3089 | "metal", 3090 | "naga", 3091 | "ndk-sys 0.5.0+25.2.9519653", 3092 | "objc", 3093 | "once_cell", 3094 | "ordered-float", 3095 | "parking_lot", 3096 | "profiling", 3097 | "raw-window-handle", 3098 | "renderdoc-sys", 3099 | "rustc-hash", 3100 | "smallvec", 3101 | "thiserror 2.0.11", 3102 | "wasm-bindgen", 3103 | "web-sys", 3104 | "wgpu-types", 3105 | "windows", 3106 | ] 3107 | 3108 | [[package]] 3109 | name = "wgpu-types" 3110 | version = "24.0.0" 3111 | source = "registry+https://github.com/rust-lang/crates.io-index" 3112 | checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c" 3113 | dependencies = [ 3114 | "bitflags 2.8.0", 3115 | "js-sys", 3116 | "log", 3117 | "web-sys", 3118 | ] 3119 | 3120 | [[package]] 3121 | name = "winapi" 3122 | version = "0.3.9" 3123 | source = "registry+https://github.com/rust-lang/crates.io-index" 3124 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 3125 | dependencies = [ 3126 | "winapi-i686-pc-windows-gnu", 3127 | "winapi-x86_64-pc-windows-gnu", 3128 | ] 3129 | 3130 | [[package]] 3131 | name = "winapi-i686-pc-windows-gnu" 3132 | version = "0.4.0" 3133 | source = "registry+https://github.com/rust-lang/crates.io-index" 3134 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 3135 | 3136 | [[package]] 3137 | name = "winapi-util" 3138 | version = "0.1.9" 3139 | source = "registry+https://github.com/rust-lang/crates.io-index" 3140 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 3141 | dependencies = [ 3142 | "windows-sys 0.59.0", 3143 | ] 3144 | 3145 | [[package]] 3146 | name = "winapi-x86_64-pc-windows-gnu" 3147 | version = "0.4.0" 3148 | source = "registry+https://github.com/rust-lang/crates.io-index" 3149 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 3150 | 3151 | [[package]] 3152 | name = "windows" 3153 | version = "0.58.0" 3154 | source = "registry+https://github.com/rust-lang/crates.io-index" 3155 | checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" 3156 | dependencies = [ 3157 | "windows-core", 3158 | "windows-targets 0.52.6", 3159 | ] 3160 | 3161 | [[package]] 3162 | name = "windows-core" 3163 | version = "0.58.0" 3164 | source = "registry+https://github.com/rust-lang/crates.io-index" 3165 | checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" 3166 | dependencies = [ 3167 | "windows-implement", 3168 | "windows-interface", 3169 | "windows-result", 3170 | "windows-strings", 3171 | "windows-targets 0.52.6", 3172 | ] 3173 | 3174 | [[package]] 3175 | name = "windows-implement" 3176 | version = "0.58.0" 3177 | source = "registry+https://github.com/rust-lang/crates.io-index" 3178 | checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" 3179 | dependencies = [ 3180 | "proc-macro2", 3181 | "quote", 3182 | "syn", 3183 | ] 3184 | 3185 | [[package]] 3186 | name = "windows-interface" 3187 | version = "0.58.0" 3188 | source = "registry+https://github.com/rust-lang/crates.io-index" 3189 | checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" 3190 | dependencies = [ 3191 | "proc-macro2", 3192 | "quote", 3193 | "syn", 3194 | ] 3195 | 3196 | [[package]] 3197 | name = "windows-result" 3198 | version = "0.2.0" 3199 | source = "registry+https://github.com/rust-lang/crates.io-index" 3200 | checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" 3201 | dependencies = [ 3202 | "windows-targets 0.52.6", 3203 | ] 3204 | 3205 | [[package]] 3206 | name = "windows-strings" 3207 | version = "0.1.0" 3208 | source = "registry+https://github.com/rust-lang/crates.io-index" 3209 | checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" 3210 | dependencies = [ 3211 | "windows-result", 3212 | "windows-targets 0.52.6", 3213 | ] 3214 | 3215 | [[package]] 3216 | name = "windows-sys" 3217 | version = "0.45.0" 3218 | source = "registry+https://github.com/rust-lang/crates.io-index" 3219 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 3220 | dependencies = [ 3221 | "windows-targets 0.42.2", 3222 | ] 3223 | 3224 | [[package]] 3225 | name = "windows-sys" 3226 | version = "0.48.0" 3227 | source = "registry+https://github.com/rust-lang/crates.io-index" 3228 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 3229 | dependencies = [ 3230 | "windows-targets 0.48.5", 3231 | ] 3232 | 3233 | [[package]] 3234 | name = "windows-sys" 3235 | version = "0.52.0" 3236 | source = "registry+https://github.com/rust-lang/crates.io-index" 3237 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 3238 | dependencies = [ 3239 | "windows-targets 0.52.6", 3240 | ] 3241 | 3242 | [[package]] 3243 | name = "windows-sys" 3244 | version = "0.59.0" 3245 | source = "registry+https://github.com/rust-lang/crates.io-index" 3246 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 3247 | dependencies = [ 3248 | "windows-targets 0.52.6", 3249 | ] 3250 | 3251 | [[package]] 3252 | name = "windows-targets" 3253 | version = "0.42.2" 3254 | source = "registry+https://github.com/rust-lang/crates.io-index" 3255 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 3256 | dependencies = [ 3257 | "windows_aarch64_gnullvm 0.42.2", 3258 | "windows_aarch64_msvc 0.42.2", 3259 | "windows_i686_gnu 0.42.2", 3260 | "windows_i686_msvc 0.42.2", 3261 | "windows_x86_64_gnu 0.42.2", 3262 | "windows_x86_64_gnullvm 0.42.2", 3263 | "windows_x86_64_msvc 0.42.2", 3264 | ] 3265 | 3266 | [[package]] 3267 | name = "windows-targets" 3268 | version = "0.48.5" 3269 | source = "registry+https://github.com/rust-lang/crates.io-index" 3270 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 3271 | dependencies = [ 3272 | "windows_aarch64_gnullvm 0.48.5", 3273 | "windows_aarch64_msvc 0.48.5", 3274 | "windows_i686_gnu 0.48.5", 3275 | "windows_i686_msvc 0.48.5", 3276 | "windows_x86_64_gnu 0.48.5", 3277 | "windows_x86_64_gnullvm 0.48.5", 3278 | "windows_x86_64_msvc 0.48.5", 3279 | ] 3280 | 3281 | [[package]] 3282 | name = "windows-targets" 3283 | version = "0.52.6" 3284 | source = "registry+https://github.com/rust-lang/crates.io-index" 3285 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 3286 | dependencies = [ 3287 | "windows_aarch64_gnullvm 0.52.6", 3288 | "windows_aarch64_msvc 0.52.6", 3289 | "windows_i686_gnu 0.52.6", 3290 | "windows_i686_gnullvm", 3291 | "windows_i686_msvc 0.52.6", 3292 | "windows_x86_64_gnu 0.52.6", 3293 | "windows_x86_64_gnullvm 0.52.6", 3294 | "windows_x86_64_msvc 0.52.6", 3295 | ] 3296 | 3297 | [[package]] 3298 | name = "windows_aarch64_gnullvm" 3299 | version = "0.42.2" 3300 | source = "registry+https://github.com/rust-lang/crates.io-index" 3301 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 3302 | 3303 | [[package]] 3304 | name = "windows_aarch64_gnullvm" 3305 | version = "0.48.5" 3306 | source = "registry+https://github.com/rust-lang/crates.io-index" 3307 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 3308 | 3309 | [[package]] 3310 | name = "windows_aarch64_gnullvm" 3311 | version = "0.52.6" 3312 | source = "registry+https://github.com/rust-lang/crates.io-index" 3313 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 3314 | 3315 | [[package]] 3316 | name = "windows_aarch64_msvc" 3317 | version = "0.42.2" 3318 | source = "registry+https://github.com/rust-lang/crates.io-index" 3319 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 3320 | 3321 | [[package]] 3322 | name = "windows_aarch64_msvc" 3323 | version = "0.48.5" 3324 | source = "registry+https://github.com/rust-lang/crates.io-index" 3325 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 3326 | 3327 | [[package]] 3328 | name = "windows_aarch64_msvc" 3329 | version = "0.52.6" 3330 | source = "registry+https://github.com/rust-lang/crates.io-index" 3331 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 3332 | 3333 | [[package]] 3334 | name = "windows_i686_gnu" 3335 | version = "0.42.2" 3336 | source = "registry+https://github.com/rust-lang/crates.io-index" 3337 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 3338 | 3339 | [[package]] 3340 | name = "windows_i686_gnu" 3341 | version = "0.48.5" 3342 | source = "registry+https://github.com/rust-lang/crates.io-index" 3343 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 3344 | 3345 | [[package]] 3346 | name = "windows_i686_gnu" 3347 | version = "0.52.6" 3348 | source = "registry+https://github.com/rust-lang/crates.io-index" 3349 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 3350 | 3351 | [[package]] 3352 | name = "windows_i686_gnullvm" 3353 | version = "0.52.6" 3354 | source = "registry+https://github.com/rust-lang/crates.io-index" 3355 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 3356 | 3357 | [[package]] 3358 | name = "windows_i686_msvc" 3359 | version = "0.42.2" 3360 | source = "registry+https://github.com/rust-lang/crates.io-index" 3361 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 3362 | 3363 | [[package]] 3364 | name = "windows_i686_msvc" 3365 | version = "0.48.5" 3366 | source = "registry+https://github.com/rust-lang/crates.io-index" 3367 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 3368 | 3369 | [[package]] 3370 | name = "windows_i686_msvc" 3371 | version = "0.52.6" 3372 | source = "registry+https://github.com/rust-lang/crates.io-index" 3373 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 3374 | 3375 | [[package]] 3376 | name = "windows_x86_64_gnu" 3377 | version = "0.42.2" 3378 | source = "registry+https://github.com/rust-lang/crates.io-index" 3379 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 3380 | 3381 | [[package]] 3382 | name = "windows_x86_64_gnu" 3383 | version = "0.48.5" 3384 | source = "registry+https://github.com/rust-lang/crates.io-index" 3385 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 3386 | 3387 | [[package]] 3388 | name = "windows_x86_64_gnu" 3389 | version = "0.52.6" 3390 | source = "registry+https://github.com/rust-lang/crates.io-index" 3391 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 3392 | 3393 | [[package]] 3394 | name = "windows_x86_64_gnullvm" 3395 | version = "0.42.2" 3396 | source = "registry+https://github.com/rust-lang/crates.io-index" 3397 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 3398 | 3399 | [[package]] 3400 | name = "windows_x86_64_gnullvm" 3401 | version = "0.48.5" 3402 | source = "registry+https://github.com/rust-lang/crates.io-index" 3403 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 3404 | 3405 | [[package]] 3406 | name = "windows_x86_64_gnullvm" 3407 | version = "0.52.6" 3408 | source = "registry+https://github.com/rust-lang/crates.io-index" 3409 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 3410 | 3411 | [[package]] 3412 | name = "windows_x86_64_msvc" 3413 | version = "0.42.2" 3414 | source = "registry+https://github.com/rust-lang/crates.io-index" 3415 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 3416 | 3417 | [[package]] 3418 | name = "windows_x86_64_msvc" 3419 | version = "0.48.5" 3420 | source = "registry+https://github.com/rust-lang/crates.io-index" 3421 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 3422 | 3423 | [[package]] 3424 | name = "windows_x86_64_msvc" 3425 | version = "0.52.6" 3426 | source = "registry+https://github.com/rust-lang/crates.io-index" 3427 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 3428 | 3429 | [[package]] 3430 | name = "winit" 3431 | version = "0.30.8" 3432 | source = "registry+https://github.com/rust-lang/crates.io-index" 3433 | checksum = "f5d74280aabb958072864bff6cfbcf9025cf8bfacdde5e32b5e12920ef703b0f" 3434 | dependencies = [ 3435 | "ahash", 3436 | "android-activity", 3437 | "atomic-waker", 3438 | "bitflags 2.8.0", 3439 | "block2", 3440 | "bytemuck", 3441 | "calloop", 3442 | "cfg_aliases", 3443 | "concurrent-queue", 3444 | "core-foundation 0.9.4", 3445 | "core-graphics", 3446 | "cursor-icon", 3447 | "dpi", 3448 | "js-sys", 3449 | "libc", 3450 | "memmap2", 3451 | "ndk", 3452 | "objc2", 3453 | "objc2-app-kit", 3454 | "objc2-foundation", 3455 | "objc2-ui-kit", 3456 | "orbclient", 3457 | "percent-encoding", 3458 | "pin-project", 3459 | "raw-window-handle", 3460 | "redox_syscall 0.4.1", 3461 | "rustix", 3462 | "sctk-adwaita", 3463 | "smithay-client-toolkit", 3464 | "smol_str", 3465 | "tracing", 3466 | "unicode-segmentation", 3467 | "wasm-bindgen", 3468 | "wasm-bindgen-futures", 3469 | "wayland-backend", 3470 | "wayland-client", 3471 | "wayland-protocols", 3472 | "wayland-protocols-plasma", 3473 | "web-sys", 3474 | "web-time", 3475 | "windows-sys 0.52.0", 3476 | "x11-dl", 3477 | "x11rb", 3478 | "xkbcommon-dl", 3479 | ] 3480 | 3481 | [[package]] 3482 | name = "winnow" 3483 | version = "0.6.20" 3484 | source = "registry+https://github.com/rust-lang/crates.io-index" 3485 | checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" 3486 | dependencies = [ 3487 | "memchr", 3488 | ] 3489 | 3490 | [[package]] 3491 | name = "x11-dl" 3492 | version = "2.21.0" 3493 | source = "registry+https://github.com/rust-lang/crates.io-index" 3494 | checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" 3495 | dependencies = [ 3496 | "libc", 3497 | "once_cell", 3498 | "pkg-config", 3499 | ] 3500 | 3501 | [[package]] 3502 | name = "x11rb" 3503 | version = "0.13.1" 3504 | source = "registry+https://github.com/rust-lang/crates.io-index" 3505 | checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" 3506 | dependencies = [ 3507 | "as-raw-xcb-connection", 3508 | "gethostname", 3509 | "libc", 3510 | "libloading", 3511 | "once_cell", 3512 | "rustix", 3513 | "x11rb-protocol", 3514 | ] 3515 | 3516 | [[package]] 3517 | name = "x11rb-protocol" 3518 | version = "0.13.1" 3519 | source = "registry+https://github.com/rust-lang/crates.io-index" 3520 | checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" 3521 | 3522 | [[package]] 3523 | name = "xcursor" 3524 | version = "0.3.8" 3525 | source = "registry+https://github.com/rust-lang/crates.io-index" 3526 | checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" 3527 | 3528 | [[package]] 3529 | name = "xdg-home" 3530 | version = "1.3.0" 3531 | source = "registry+https://github.com/rust-lang/crates.io-index" 3532 | checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" 3533 | dependencies = [ 3534 | "libc", 3535 | "windows-sys 0.59.0", 3536 | ] 3537 | 3538 | [[package]] 3539 | name = "xkbcommon-dl" 3540 | version = "0.4.2" 3541 | source = "registry+https://github.com/rust-lang/crates.io-index" 3542 | checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" 3543 | dependencies = [ 3544 | "bitflags 2.8.0", 3545 | "dlib", 3546 | "log", 3547 | "once_cell", 3548 | "xkeysym", 3549 | ] 3550 | 3551 | [[package]] 3552 | name = "xkeysym" 3553 | version = "0.2.1" 3554 | source = "registry+https://github.com/rust-lang/crates.io-index" 3555 | checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" 3556 | 3557 | [[package]] 3558 | name = "xml-rs" 3559 | version = "0.8.22" 3560 | source = "registry+https://github.com/rust-lang/crates.io-index" 3561 | checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" 3562 | 3563 | [[package]] 3564 | name = "zbus" 3565 | version = "4.4.0" 3566 | source = "registry+https://github.com/rust-lang/crates.io-index" 3567 | checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" 3568 | dependencies = [ 3569 | "async-broadcast", 3570 | "async-executor", 3571 | "async-fs", 3572 | "async-io", 3573 | "async-lock", 3574 | "async-process", 3575 | "async-recursion", 3576 | "async-task", 3577 | "async-trait", 3578 | "blocking", 3579 | "enumflags2", 3580 | "event-listener", 3581 | "futures-core", 3582 | "futures-sink", 3583 | "futures-util", 3584 | "hex", 3585 | "nix", 3586 | "ordered-stream", 3587 | "rand", 3588 | "serde", 3589 | "serde_repr", 3590 | "sha1", 3591 | "static_assertions", 3592 | "tracing", 3593 | "uds_windows", 3594 | "windows-sys 0.52.0", 3595 | "xdg-home", 3596 | "zbus_macros", 3597 | "zbus_names", 3598 | "zvariant", 3599 | ] 3600 | 3601 | [[package]] 3602 | name = "zbus-lockstep" 3603 | version = "0.4.4" 3604 | source = "registry+https://github.com/rust-lang/crates.io-index" 3605 | checksum = "4ca2c5dceb099bddaade154055c926bb8ae507a18756ba1d8963fd7b51d8ed1d" 3606 | dependencies = [ 3607 | "zbus_xml", 3608 | "zvariant", 3609 | ] 3610 | 3611 | [[package]] 3612 | name = "zbus-lockstep-macros" 3613 | version = "0.4.4" 3614 | source = "registry+https://github.com/rust-lang/crates.io-index" 3615 | checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce" 3616 | dependencies = [ 3617 | "proc-macro2", 3618 | "quote", 3619 | "syn", 3620 | "zbus-lockstep", 3621 | "zbus_xml", 3622 | "zvariant", 3623 | ] 3624 | 3625 | [[package]] 3626 | name = "zbus_macros" 3627 | version = "4.4.0" 3628 | source = "registry+https://github.com/rust-lang/crates.io-index" 3629 | checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" 3630 | dependencies = [ 3631 | "proc-macro-crate", 3632 | "proc-macro2", 3633 | "quote", 3634 | "syn", 3635 | "zvariant_utils", 3636 | ] 3637 | 3638 | [[package]] 3639 | name = "zbus_names" 3640 | version = "3.0.0" 3641 | source = "registry+https://github.com/rust-lang/crates.io-index" 3642 | checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" 3643 | dependencies = [ 3644 | "serde", 3645 | "static_assertions", 3646 | "zvariant", 3647 | ] 3648 | 3649 | [[package]] 3650 | name = "zbus_xml" 3651 | version = "4.0.0" 3652 | source = "registry+https://github.com/rust-lang/crates.io-index" 3653 | checksum = "ab3f374552b954f6abb4bd6ce979e6c9b38fb9d0cd7cc68a7d796e70c9f3a233" 3654 | dependencies = [ 3655 | "quick-xml 0.30.0", 3656 | "serde", 3657 | "static_assertions", 3658 | "zbus_names", 3659 | "zvariant", 3660 | ] 3661 | 3662 | [[package]] 3663 | name = "zerocopy" 3664 | version = "0.7.35" 3665 | source = "registry+https://github.com/rust-lang/crates.io-index" 3666 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 3667 | dependencies = [ 3668 | "byteorder", 3669 | "zerocopy-derive", 3670 | ] 3671 | 3672 | [[package]] 3673 | name = "zerocopy-derive" 3674 | version = "0.7.35" 3675 | source = "registry+https://github.com/rust-lang/crates.io-index" 3676 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 3677 | dependencies = [ 3678 | "proc-macro2", 3679 | "quote", 3680 | "syn", 3681 | ] 3682 | 3683 | [[package]] 3684 | name = "zvariant" 3685 | version = "4.2.0" 3686 | source = "registry+https://github.com/rust-lang/crates.io-index" 3687 | checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" 3688 | dependencies = [ 3689 | "endi", 3690 | "enumflags2", 3691 | "serde", 3692 | "static_assertions", 3693 | "zvariant_derive", 3694 | ] 3695 | 3696 | [[package]] 3697 | name = "zvariant_derive" 3698 | version = "4.2.0" 3699 | source = "registry+https://github.com/rust-lang/crates.io-index" 3700 | checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" 3701 | dependencies = [ 3702 | "proc-macro-crate", 3703 | "proc-macro2", 3704 | "quote", 3705 | "syn", 3706 | "zvariant_utils", 3707 | ] 3708 | 3709 | [[package]] 3710 | name = "zvariant_utils" 3711 | version = "2.1.0" 3712 | source = "registry+https://github.com/rust-lang/crates.io-index" 3713 | checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" 3714 | dependencies = [ 3715 | "proc-macro2", 3716 | "quote", 3717 | "syn", 3718 | ] 3719 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "egui_colors" 3 | version = "0.8.0" 4 | authors = ["Frank van Gompel"] 5 | edition = "2021" 6 | license = "MIT" 7 | description = "Experimental color styling toolkit for egui" 8 | repository = "https://github.com/frankvgompel/egui_colors" 9 | keywords = ["graphics", "egui", "styling", "colors", "gui"] 10 | categories = ["gui", "graphics"] 11 | exclude = ["examples", "media"] 12 | 13 | [workspace] 14 | members = ["examples/hello_colors", "examples/local_scope"] 15 | 16 | [dependencies] 17 | egui = { version = "0.31.1", default-features = false } 18 | serde = { version = "1", optional = true, default-features = false, features = ["derive"] } 19 | 20 | [features] 21 | serde = ["dep:serde"] 22 | 23 | [lints.rust] 24 | unsafe_code = "forbid" 25 | 26 | [lints.clippy] 27 | nursery = { level = "deny", priority = 0 } 28 | pedantic = { level = "deny", priority = 1 } 29 | enum_glob_use = { level = "deny", priority = 2 } 30 | module_name_repetitions = { level = "allow", priority = 3 } 31 | cast_precision_loss = { level = "allow", priority = 4 } 32 | cast_possible_truncation = { level = "allow", priority = 5 } 33 | cast_sign_loss = { level = "allow", priority = 6 } 34 | out_of_bounds_indexing = { level = "allow", priority = 7 } 35 | perf = { level = "warn", priority = 8 } 36 | style = { level = "warn", priority = 9 } 37 | unwrap_used = { level = "deny", priority = 10 } 38 | expect_used = { level = "deny", priority = 11 } 39 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Frank van Gompel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # egui_colors 2 | 3 | Experimental toolkit to explore color styling in [`egui`](https://github.com/emilk/egui) 4 | 5 | Based on the [`Radix`](https://www.radix-ui.com/colors/docs/palette-composition/understanding-the-scale) 6 | system, which defines 12 functional UI elements, and maps them to a color scale. 7 | 8 | Scales (both light and dark mode) are computed and based on luminosity contrast algorithm defined by [`APCA`](https://github.com/Myndex). Every scale uses one predefined [u8; 3] rgb color that is used as an accent color (if suitable). Colors are manipulated in Linear Srgb and [OkHsl](https://bottosson.github.io/posts/colorpicker/). 9 | 10 | 12 | ![example_image](media/animated_circles.png) 13 | from Demo [animated_circles](https://github.com/frankvgompel/animated_circles) 14 | 15 | ![example_image](media/egui_isohedral.png) 16 | from Demo [egui_isohedral](https://github.com/frankvgompel/egui_isohedral) 17 | 18 | ![example_image](media/egui_colors_v0.5.0.png) 19 | 20 | 21 | ## General Remarks 22 | 23 | Although it is perfectly possible to use egui_colors to style your egui app, it's intended use is to explore the styling landscape and see where egui's and users needs lie. 24 | 25 | The default egui font might not be suited (too thin) for this system. The example 'hello_colors` uses the Rerun one: 'inter_medium'. 26 | 27 | 28 | ## Usage 29 | 30 | 31 | Basic setting of theme. 32 | 33 | ```rust 34 | use egui_color::{Colorix; ThemeColor}; 35 | 36 | // Define a colorix field in your egui App 37 | #[derive(Default)] 38 | struct App { 39 | colorix: Colorix, 40 | ... 41 | } 42 | // Choose a light or dark theme. 43 | // initialize the Colorix with a theme 44 | // A `ThemeColor` is an enum with several preset colors and one Custom. 45 | // You must choose from 3 different scopes: global, local or extra_scale 46 | impl App { 47 | fn new(ctx: &egui::Context) -> Self { 48 | ctx.set_theme(egui::Theme::Dark); 49 | let yellow_theme = [ThemeColor::Custom([232, 210, 7]); 12] 50 | let colorix = Colorix::global(ctx, yellow_theme); 51 | Self { 52 | colorix, 53 | ..Default::default() 54 | } 55 | } 56 | } 57 | ``` 58 | 59 | Several utility tools are available. 60 | ```rust 61 | // use the provided function 'light_dark_toggle_button' for switching between light and dark mode. Don't use one from egui, it will revert to the egui theme. 62 | app.colorix.light_dark_toggle_button(ui, 14.); 63 | 64 | // A color picker for a custom color. 65 | // NOTE: the color picker is clamped to suitable ranges. 66 | // If the selected color's contrast is not sufficient, it will be replaced by a more saturated version. 67 | app.colorix.custom_picker(ui); 68 | // A helper to select the 12 elements and functionality to copy theme to clipboard 69 | app.colorix.ui_combo_12(ui); 70 | 71 | // dropdown with themes. It is possible to add custom themes to the list 72 | // with an Option<(Vec<&str>, Vec<[ThemeColor; 12]>)> 73 | let names = vec!["YellowGreen"]; 74 | let themes = vec![[ThemeColor::Custom([178, 194, 31]); 12]]; 75 | let custom = Some((names, themes)); 76 | 77 | // if you want to display custom themes only, set bool to `true` 78 | app.colorix.themes_dropdown(ui, custom, false); 79 | 80 | // Possibility to use a background gradient. 81 | app.colorix.draw_background(ctx, false); 82 | 83 | ``` 84 | Custom components can be set with `colorix.tokens` 85 | 86 | ## Animation 87 | 88 | For animation the colorix instance needs to be initialized with the `animated()` function. When `global` or `extra_scale` is selected, the `set_animator()` function should be set in the egui `update()` function. The `local` scope needs the `update_locally()` in the egui `update()`. 89 | ```rust 90 | use egui_color::{Colorix; ThemeColor}; 91 | 92 | // Define a colorix field in your egui App 93 | #[derive(Default)] 94 | struct App { 95 | colorix: Colorix, 96 | ... 97 | } 98 | // Set the animator with the `animated()` function. 99 | // Default animation time (1.0) can be changed with `set_time()` 100 | impl App { 101 | fn new(ctx: &egui::Context) -> Self { 102 | ctx.set_theme(egui::Theme::Dark); 103 | let yellow_theme = [ThemeColor::Custom([232, 210, 7]); 12] 104 | let colorix = Colorix::global(ctx, yellow_theme).animated().set_time(2.0); 105 | Self { 106 | colorix, 107 | ..Default::default() 108 | } 109 | } 110 | } 111 | ``` 112 | Custom animated color components can be set with `colorix.animator.animated_tokens`. 113 | 114 | To animate a theme change, use 115 | ```rust 116 | update_theme(ctx, utils::EGUI_THEME) 117 | ``` 118 | 119 | 120 | ## Features 121 | 122 | * serde: Implement `serde::Deserialize` and `serde::Serialize` on `ThemeColor` 123 | 124 | ## Examples 125 | See the example [hello_colors](https://github.com/frankvgompel/egui_colors/tree/master/examples/hello_colors) 126 | or [local_scope](https://github.com/frankvgompel/egui_colors/tree/master/examples/local_scope) 127 | 128 | Another [example](https://github.com/crumblingstatue/mpv-egui-musicplayer/commit/2e77b7f7c729f7fd55e652f78826e1f417ad3eaa) from an experienced user how to set up `egui_colors` 129 | 130 | Or see the demos 131 | [animated_circles](https://github.com/frankvgompel/animated_circles) or [egui_isohedral](https://github.com/frankvgompel/egui_isohedral) -------------------------------------------------------------------------------- /examples/hello_colors/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello_colors" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | 7 | [dependencies] 8 | eframe = "0.31.1" 9 | egui_demo_lib = "0.31.1" 10 | egui_colors = { path = "../../../egui_colors" } 11 | 12 | -------------------------------------------------------------------------------- /examples/hello_colors/README.md: -------------------------------------------------------------------------------- 1 | # Hello Colors 2 | Example demonstrates how to use egui_colors 3 | 4 | ## run 5 | ```bash 6 | cargo run --release -p hello_colors 7 | ``` -------------------------------------------------------------------------------- /examples/hello_colors/data/Inter-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frankvgompel/egui_colors/209289e0c07885355f644f883015172a0ab67fff/examples/hello_colors/data/Inter-Medium.otf -------------------------------------------------------------------------------- /examples/hello_colors/src/app.rs: -------------------------------------------------------------------------------- 1 | //#![allow(dead_code)] 2 | use crate::interface; 3 | use eframe::egui; 4 | use egui_colors::{utils, Colorix}; 5 | use egui_demo_lib::DemoWindows; 6 | use std::sync::Arc; 7 | 8 | #[derive(Default)] 9 | pub struct App { 10 | pub colorix: Colorix, 11 | pub util_bools: [bool; 12], 12 | pub demo: DemoWindows, 13 | } 14 | 15 | impl eframe::App for App { 16 | fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { 17 | interface::draw_interface(self, ctx); 18 | } 19 | } 20 | 21 | impl App { 22 | fn new(ctx: &egui::Context) -> Self { 23 | ctx.set_theme(egui::Theme::Light); 24 | let colorix = Colorix::global(ctx, utils::EGUI_THEME); 25 | Self { 26 | colorix, 27 | ..Default::default() 28 | } 29 | } 30 | } 31 | 32 | pub fn init() -> Result<(), eframe::Error> { 33 | let options = eframe::NativeOptions { 34 | viewport: egui::ViewportBuilder::default().with_maximized(true), 35 | ..Default::default() 36 | }; 37 | let mut fonts = egui::FontDefinitions::default(); 38 | 39 | fonts.font_data.insert( 40 | "inter_medium".to_owned(), 41 | Arc::new(egui::FontData::from_static(include_bytes!( 42 | "../data/Inter-Medium.otf" 43 | ))), 44 | ); // .ttf and .otf supported 45 | 46 | // Put my font first (highest priority): 47 | fonts 48 | .families 49 | .get_mut(&egui::FontFamily::Proportional) 50 | .unwrap() 51 | .insert(0, "inter_medium".to_owned()); 52 | 53 | // Put my font as last fallback for monospace: 54 | // fonts.families.get_mut(&egui::FontFamily::Monospace).unwrap() 55 | // .push("inter_medium".to_owned()); 56 | eframe::run_native( 57 | "Egui Colors Demo", 58 | options, 59 | Box::new(|cc| { 60 | cc.egui_ctx.set_fonts(fonts); 61 | cc.egui_ctx.style_mut(|style| { 62 | style.spacing.item_spacing = egui::vec2(5.0, 8.0); 63 | style.spacing.window_margin = egui::Margin::same(20); 64 | }); 65 | Ok(Box::new(App::new(&cc.egui_ctx.clone()))) 66 | }), 67 | ) 68 | } 69 | -------------------------------------------------------------------------------- /examples/hello_colors/src/interface.rs: -------------------------------------------------------------------------------- 1 | use crate::app::App; 2 | use eframe::egui; 3 | use egui_colors::tokens::ThemeColor; 4 | 5 | pub fn draw_interface(app: &mut App, ctx: &egui::Context) { 6 | let names = vec!["Yellow", "YellowGreen", "Muted Purple"]; 7 | let themes = vec![ 8 | [ThemeColor::Custom([232, 210, 7]); 12], 9 | [ThemeColor::Custom([178, 194, 31]); 12], 10 | [ThemeColor::Custom([95, 78, 163]); 12], 11 | ]; 12 | let custom = Some((names, themes)); 13 | egui::TopBottomPanel::top("t_panel").show(ctx, |ui| { 14 | ui.horizontal_wrapped(|ui| { 15 | app.colorix.light_dark_toggle_button(ui, 14.); 16 | ui.separator(); 17 | ui.toggle_value(&mut app.util_bools[0], "Background Gradient"); 18 | ui.separator(); 19 | app.colorix.themes_dropdown(ui, custom, false); 20 | }); 21 | }); 22 | egui::SidePanel::left("left panel").show(ctx, |ui| { 23 | if app.util_bools[0] { 24 | app.colorix.draw_background(ctx, false); 25 | } 26 | ui.add_space(20.); 27 | app.colorix.custom_picker(ui); 28 | ui.add_space(20.); 29 | app.colorix.ui_combo_12(ui, true); 30 | }); 31 | app.demo.ui(ctx); 32 | egui::CentralPanel::default().show(ctx, |_ui| { 33 | if app.util_bools[0] { 34 | app.colorix.draw_background(ctx, false); 35 | } 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /examples/hello_colors/src/main.rs: -------------------------------------------------------------------------------- 1 | mod app; 2 | mod interface; 3 | 4 | fn main() -> Result<(), eframe::Error> { 5 | app::init() 6 | } 7 | -------------------------------------------------------------------------------- /examples/local_scope/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "local_scope" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | eframe = "0.31.1" 8 | egui_colors = { path = "../../../egui_colors" } 9 | -------------------------------------------------------------------------------- /examples/local_scope/src/app.rs: -------------------------------------------------------------------------------- 1 | use eframe::egui; 2 | use egui_colors::{utils, Colorix}; 3 | 4 | #[derive(Default)] 5 | pub struct App { 6 | pub colorix: Colorix, 7 | pub colorix2: Colorix, 8 | } 9 | 10 | impl eframe::App for App { 11 | fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { 12 | self.colorix.set_animator(ctx); 13 | egui::SidePanel::left("left panel").show(ctx, |ui| { 14 | self.colorix.light_dark_toggle_button(ui, 14.); 15 | ui.add_space(10.); 16 | self.colorix.themes_dropdown(ui, None, false); 17 | ui.add_space(10.); 18 | self.colorix.ui_combo_12(ui, false); 19 | }); 20 | egui::CentralPanel::default() 21 | .frame(egui::Frame { 22 | inner_margin: egui::Margin::same(8), 23 | fill: self.colorix2.animator.animated_tokens.subtle_background(), 24 | ..Default::default() 25 | }) 26 | .show(ctx, |ui| { 27 | if ui.button("init local colorix").clicked() { 28 | self.colorix2 = Colorix::local(ui, utils::COOL).animated(); 29 | } 30 | self.colorix2.update_locally(ui); 31 | ui.add_space(10.); 32 | self.colorix2.themes_dropdown(ui, None, false); 33 | ui.add_space(10.); 34 | self.colorix2.ui_combo_12(ui, false); 35 | ui.add_space(10.); 36 | if ui.button("Click for dark").clicked() { 37 | self.colorix2.set_dark(ui); 38 | }; 39 | if ui.button("Click for light").clicked() { 40 | self.colorix2.set_light(ui) 41 | }; 42 | }); 43 | } 44 | } 45 | impl App { 46 | pub fn new(cc: &eframe::CreationContext<'_>) -> Self { 47 | cc.egui_ctx.set_theme(egui::Theme::Light); 48 | let colorix = Colorix::global(&cc.egui_ctx, utils::EGUI_THEME).animated(); 49 | Self { 50 | colorix, 51 | ..Default::default() 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /examples/local_scope/src/main.rs: -------------------------------------------------------------------------------- 1 | mod app; 2 | use app::App; 3 | use eframe::egui; 4 | 5 | pub fn main() -> Result<(), eframe::Error> { 6 | let options = eframe::NativeOptions { 7 | viewport: egui::ViewportBuilder::default().with_maximized(true), 8 | ..Default::default() 9 | }; 10 | eframe::run_native( 11 | "Local Scope Example", 12 | options, 13 | Box::new(|cc| Ok(Box::new(App::new(cc)))), 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /media/animated_circles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frankvgompel/egui_colors/209289e0c07885355f644f883015172a0ab67fff/media/animated_circles.png -------------------------------------------------------------------------------- /media/egui_colors_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frankvgompel/egui_colors/209289e0c07885355f644f883015172a0ab67fff/media/egui_colors_demo.png -------------------------------------------------------------------------------- /media/egui_colors_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frankvgompel/egui_colors/209289e0c07885355f644f883015172a0ab67fff/media/egui_colors_light.png -------------------------------------------------------------------------------- /media/egui_colors_v0.5.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frankvgompel/egui_colors/209289e0c07885355f644f883015172a0ab67fff/media/egui_colors_v0.5.0.png -------------------------------------------------------------------------------- /media/egui_isohedral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frankvgompel/egui_colors/209289e0c07885355f644f883015172a0ab67fff/media/egui_isohedral.png -------------------------------------------------------------------------------- /src/animator.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::too_many_lines)] 2 | #![allow(clippy::semicolon_if_nothing_returned)] 3 | #![allow(clippy::float_cmp)] 4 | 5 | use crate::{tokens::ColorTokens, ApplyTo}; 6 | use egui::{Color32, Context, Id, Style, Ui}; 7 | 8 | #[allow(clippy::many_single_char_names)] 9 | fn interpolate_color(start: Color32, end: Color32, interpolation: f32) -> Color32 { 10 | let r = egui::lerp(f32::from(start.r())..=f32::from(end.r()), interpolation) as u8; 11 | let g = egui::lerp(f32::from(start.g())..=f32::from(end.g()), interpolation) as u8; 12 | let b = egui::lerp(f32::from(start.b())..=f32::from(end.b()), interpolation) as u8; 13 | let a = egui::lerp(f32::from(start.a())..=f32::from(end.a()), interpolation) as u8; 14 | Color32::from_rgba_premultiplied(r, g, b, a) 15 | } 16 | 17 | #[derive(Debug, Default, Clone)] 18 | pub struct ColorAnimator { 19 | pub(crate) anim_id: Option, 20 | pub progress: f32, 21 | animation_time: f32, 22 | token_shift: bool, 23 | pub(crate) animation_done: bool, 24 | animation_in_progress: bool, 25 | values_1: [Color32; 3], 26 | values_2: [Color32; 3], 27 | pub tokenshifts: [Color32; 3], 28 | tokens: ColorTokens, 29 | pub animated_tokens: ColorTokens, 30 | shadow: Color32, 31 | s1: Color32, 32 | s2: Color32, 33 | pub(crate) apply_to: ApplyTo, 34 | } 35 | 36 | impl ColorAnimator { 37 | pub(crate) const fn new(tokens: ColorTokens) -> Self { 38 | Self { 39 | anim_id: None, 40 | progress: 0.0, 41 | animation_time: 1., 42 | token_shift: true, 43 | animation_done: true, 44 | animation_in_progress: false, 45 | values_1: [Color32::TRANSPARENT; 3], 46 | values_2: [Color32::TRANSPARENT; 3], 47 | tokenshifts: [Color32::TRANSPARENT; 3], 48 | tokens, 49 | animated_tokens: tokens, 50 | shadow: Color32::TRANSPARENT, 51 | s1: Color32::from_black_alpha(25), 52 | s2: Color32::from_black_alpha(96), 53 | apply_to: ApplyTo::Global, 54 | } 55 | } 56 | 57 | pub(crate) fn set_animate( 58 | &mut self, 59 | ctx: Option<&Context>, 60 | ui: Option<&mut Ui>, 61 | tokens: ColorTokens, 62 | ) { 63 | if let Some(ctx) = ctx { 64 | if self.anim_id.is_none() { 65 | self.create_id(ctx); 66 | } else { 67 | self.animate(Some(ctx), None, tokens); 68 | } 69 | } else if let Some(ui) = ui { 70 | if self.anim_id.is_none() { 71 | let anim_id = ui.id(); 72 | self.anim_id = Some(anim_id); 73 | ui.ctx().animate_value_with_time(anim_id, 0.0, 0.0); 74 | } else { 75 | self.animate(None, Some(ui), tokens); 76 | } 77 | } 78 | } 79 | pub(crate) const fn set_time(&mut self, new_time: f32) { 80 | self.animation_time = new_time; 81 | } 82 | pub(crate) fn create_id(&mut self, ctx: &Context) { 83 | let anim_id = egui::Id::new("Color animator"); 84 | ctx.animate_value_with_time(anim_id, 0.0, 0.0); 85 | self.anim_id = Some(anim_id); 86 | } 87 | pub(crate) fn start(&mut self, ctx: &Context) { 88 | self.animation_done = false; 89 | if self.animation_in_progress { 90 | self.restart(ctx); 91 | } else { 92 | self.animation_done = false; 93 | self.animation_in_progress = true; 94 | } 95 | } 96 | // if animation in progress and needs a restart 97 | pub fn restart(&mut self, ctx: &Context) { 98 | self.animation_done = true; 99 | self.animation_in_progress = false; 100 | self.tokens = self.animated_tokens; 101 | if let Some(anim_id) = self.anim_id { 102 | ctx.animate_value_with_time(anim_id, 0.0, 0.0); 103 | } 104 | self.token_shift = !self.token_shift; 105 | self.start(ctx); 106 | } 107 | 108 | pub(crate) fn animate( 109 | &mut self, 110 | ctx: Option<&Context>, 111 | ui: Option<&mut Ui>, 112 | tokens: ColorTokens, 113 | ) { 114 | if self.animation_done { 115 | match self.apply_to { 116 | #[allow(clippy::needless_return)] 117 | ApplyTo::Global | ApplyTo::ExtraScale => return, 118 | // if animation done, local ui needs to keep updating every frame 119 | ApplyTo::Local => { 120 | if let Some(ui) = ui { 121 | self.apply_local_ui(ui.style_mut()); 122 | } 123 | } 124 | } 125 | } else { 126 | let Some(anim_id) = self.anim_id else { return }; 127 | 128 | if let Some(ctx) = ctx { 129 | let shadow = if ctx.style().visuals.dark_mode { 130 | self.s2 131 | } else { 132 | self.s1 133 | }; 134 | self.progress = ctx.animate_value_with_time(anim_id, 1.0, self.animation_time); 135 | ctx.style_mut(|style| self.set_egui_animation(style, tokens, shadow)); 136 | if self.progress == 1.0 { 137 | ctx.animate_value_with_time(anim_id, 0.0, 0.0); 138 | } 139 | } else if let Some(ui) = ui { 140 | let shadow = if ui.style_mut().visuals.dark_mode { 141 | self.s2 142 | } else { 143 | self.s1 144 | }; 145 | self.progress = ui 146 | .ctx() 147 | .animate_value_with_time(anim_id, 1.0, self.animation_time); 148 | self.set_egui_animation(ui.style_mut(), tokens, shadow); 149 | if self.progress == 1.0 { 150 | ui.ctx().animate_value_with_time(anim_id, 0.0, 0.0); 151 | } 152 | } 153 | } 154 | } 155 | fn set_egui_animation(&mut self, style: &mut Style, tokens: ColorTokens, shadow: Color32) { 156 | let indices = [[6, 0, 7], [8, 8, 6]]; 157 | 158 | self.values_1 159 | .iter_mut() 160 | .enumerate() 161 | .for_each(|(i, v)| *v = self.animated_tokens.get_token(indices[0][i])); 162 | self.values_2 163 | .iter_mut() 164 | .enumerate() 165 | .for_each(|(i, v)| *v = self.animated_tokens.get_token(indices[1][i])); 166 | 167 | let (start_values, end_values) = if self.token_shift { 168 | (&self.values_1, &self.values_2) 169 | } else { 170 | (&self.values_2, &self.values_1) 171 | }; 172 | self.tokenshifts.iter_mut().enumerate().for_each(|(i, v)| { 173 | *v = interpolate_color(start_values[i], end_values[i], self.progress) 174 | }); 175 | 176 | self.animated_tokens.app_background = interpolate_color( 177 | self.tokens.app_background, 178 | tokens.app_background, 179 | self.progress, 180 | ); 181 | self.animated_tokens.subtle_background = interpolate_color( 182 | self.tokens.subtle_background, 183 | tokens.subtle_background, 184 | self.progress, 185 | ); 186 | self.animated_tokens.ui_element_background = interpolate_color( 187 | self.tokens.ui_element_background, 188 | tokens.ui_element_background, 189 | self.progress, 190 | ); 191 | self.animated_tokens.hovered_ui_element_background = interpolate_color( 192 | self.tokens.hovered_ui_element_background, 193 | tokens.hovered_ui_element_background, 194 | self.progress, 195 | ); 196 | self.animated_tokens.active_ui_element_background = interpolate_color( 197 | self.tokens.active_ui_element_background, 198 | tokens.active_ui_element_background, 199 | self.progress, 200 | ); 201 | self.animated_tokens.subtle_borders_and_separators = interpolate_color( 202 | self.tokens.subtle_borders_and_separators, 203 | tokens.subtle_borders_and_separators, 204 | self.progress, 205 | ); 206 | self.animated_tokens.ui_element_border_and_focus_rings = interpolate_color( 207 | self.tokens.ui_element_border_and_focus_rings, 208 | tokens.ui_element_border_and_focus_rings, 209 | self.progress, 210 | ); 211 | self.animated_tokens.hovered_ui_element_border = interpolate_color( 212 | self.tokens.hovered_ui_element_border, 213 | tokens.hovered_ui_element_border, 214 | self.progress, 215 | ); 216 | self.animated_tokens.solid_backgrounds = interpolate_color( 217 | self.tokens.solid_backgrounds, 218 | tokens.solid_backgrounds, 219 | self.progress, 220 | ); 221 | self.animated_tokens.hovered_solid_backgrounds = interpolate_color( 222 | self.tokens.hovered_solid_backgrounds, 223 | tokens.hovered_solid_backgrounds, 224 | self.progress, 225 | ); 226 | self.animated_tokens.low_contrast_text = interpolate_color( 227 | self.tokens.low_contrast_text, 228 | tokens.low_contrast_text, 229 | self.progress, 230 | ); 231 | self.animated_tokens.high_contrast_text = interpolate_color( 232 | self.tokens.high_contrast_text, 233 | tokens.high_contrast_text, 234 | self.progress, 235 | ); 236 | self.animated_tokens.on_accent = 237 | interpolate_color(self.tokens.on_accent, tokens.on_accent, self.progress); 238 | self.shadow = interpolate_color(self.shadow, shadow, self.progress); 239 | 240 | match self.apply_to { 241 | ApplyTo::Global | ApplyTo::Local => { 242 | style.visuals.text_cursor.stroke.color = self.animated_tokens.low_contrast_text; 243 | style.visuals.selection.bg_fill = self.animated_tokens.solid_backgrounds; 244 | style.visuals.selection.stroke.color = self.animated_tokens.on_accent; 245 | style.visuals.widgets.noninteractive.weak_bg_fill = 246 | self.animated_tokens.subtle_background; 247 | style.visuals.widgets.noninteractive.bg_fill = 248 | self.animated_tokens.subtle_background; 249 | style.visuals.widgets.noninteractive.bg_stroke.color = 250 | self.animated_tokens.subtle_borders_and_separators; // separators, indentation lines 251 | style.visuals.widgets.noninteractive.fg_stroke.color = 252 | self.animated_tokens.low_contrast_text; // normal text color; 253 | style.visuals.widgets.inactive.weak_bg_fill = 254 | self.animated_tokens.ui_element_background; // button background 255 | style.visuals.widgets.inactive.bg_fill = self.animated_tokens.ui_element_background; // checkbox background 256 | style.visuals.widgets.inactive.bg_stroke.color = 257 | self.animated_tokens.ui_element_background; 258 | style.visuals.widgets.inactive.fg_stroke.color = 259 | self.animated_tokens.low_contrast_text; // button text 260 | style.visuals.widgets.hovered.weak_bg_fill = 261 | self.animated_tokens.hovered_ui_element_background; 262 | style.visuals.widgets.hovered.bg_fill = 263 | self.animated_tokens.hovered_ui_element_background; 264 | style.visuals.widgets.hovered.bg_stroke.color = 265 | self.animated_tokens.hovered_ui_element_border; // e.g. hover over window edge or button 266 | style.visuals.widgets.hovered.fg_stroke.color = 267 | self.animated_tokens.high_contrast_text; 268 | style.visuals.widgets.active.weak_bg_fill = 269 | self.animated_tokens.active_ui_element_background; 270 | style.visuals.widgets.active.bg_fill = 271 | self.animated_tokens.active_ui_element_background; 272 | style.visuals.widgets.active.bg_stroke.color = 273 | self.animated_tokens.ui_element_border_and_focus_rings; 274 | style.visuals.widgets.active.fg_stroke.color = 275 | self.animated_tokens.high_contrast_text; 276 | style.visuals.widgets.open.weak_bg_fill = 277 | self.animated_tokens.active_ui_element_background; 278 | style.visuals.widgets.open.bg_fill = 279 | self.animated_tokens.active_ui_element_background; 280 | style.visuals.widgets.open.bg_stroke.color = 281 | self.animated_tokens.ui_element_border_and_focus_rings; 282 | style.visuals.widgets.open.fg_stroke.color = 283 | self.animated_tokens.high_contrast_text; 284 | style.visuals.extreme_bg_color = self.animated_tokens.app_background; // e.g. TextEdit background 285 | style.visuals.faint_bg_color = self.animated_tokens.app_background; // striped grid is originally from_additive_luminance(5) 286 | style.visuals.code_bg_color = self.animated_tokens.ui_element_background; 287 | style.visuals.window_fill = self.animated_tokens.subtle_background; 288 | style.visuals.window_stroke.color = 289 | self.animated_tokens.subtle_borders_and_separators; 290 | style.visuals.panel_fill = self.animated_tokens.subtle_background; 291 | style.visuals.hyperlink_color = self.animated_tokens.hovered_solid_backgrounds; 292 | style.visuals.window_shadow.color = self.shadow; 293 | 294 | // reset old values and flag of animate value 295 | if self.progress == 1.0 { 296 | self.tokens = self.animated_tokens; 297 | self.animation_done = true; 298 | self.animation_in_progress = false; 299 | self.token_shift = !self.token_shift; 300 | } 301 | } 302 | ApplyTo::ExtraScale => { 303 | if self.progress == 1.0 { 304 | self.tokens = self.animated_tokens; 305 | self.animation_done = true; 306 | self.animation_in_progress = false; 307 | self.token_shift = !self.token_shift; 308 | } 309 | } 310 | } 311 | } 312 | const fn apply_local_ui(&self, style: &mut egui::style::Style) { 313 | style.visuals.text_cursor.stroke.color = self.animated_tokens.low_contrast_text; 314 | style.visuals.selection.bg_fill = self.animated_tokens.solid_backgrounds; 315 | style.visuals.selection.stroke.color = self.animated_tokens.on_accent; 316 | style.visuals.widgets.noninteractive.weak_bg_fill = self.animated_tokens.subtle_background; 317 | style.visuals.widgets.noninteractive.bg_fill = self.animated_tokens.subtle_background; 318 | style.visuals.widgets.noninteractive.bg_stroke.color = 319 | self.animated_tokens.subtle_borders_and_separators; // separators, indentation lines 320 | style.visuals.widgets.noninteractive.fg_stroke.color = 321 | self.animated_tokens.low_contrast_text; // normal text color; 322 | style.visuals.widgets.inactive.weak_bg_fill = self.animated_tokens.ui_element_background; // button background 323 | style.visuals.widgets.inactive.bg_fill = self.animated_tokens.ui_element_background; // checkbox background 324 | style.visuals.widgets.inactive.bg_stroke.color = self.animated_tokens.ui_element_background; 325 | style.visuals.widgets.inactive.fg_stroke.color = self.animated_tokens.low_contrast_text; // button text 326 | style.visuals.widgets.hovered.weak_bg_fill = 327 | self.animated_tokens.hovered_ui_element_background; 328 | style.visuals.widgets.hovered.bg_fill = self.animated_tokens.hovered_ui_element_background; 329 | style.visuals.widgets.hovered.bg_stroke.color = 330 | self.animated_tokens.hovered_ui_element_border; // e.g. hover over window edge or button 331 | style.visuals.widgets.hovered.fg_stroke.color = self.animated_tokens.high_contrast_text; 332 | style.visuals.widgets.active.weak_bg_fill = 333 | self.animated_tokens.active_ui_element_background; 334 | style.visuals.widgets.active.bg_fill = self.animated_tokens.active_ui_element_background; 335 | style.visuals.widgets.active.bg_stroke.color = 336 | self.animated_tokens.ui_element_border_and_focus_rings; 337 | style.visuals.widgets.active.fg_stroke.color = self.animated_tokens.high_contrast_text; 338 | style.visuals.widgets.open.weak_bg_fill = self.animated_tokens.active_ui_element_background; 339 | style.visuals.widgets.open.bg_fill = self.animated_tokens.active_ui_element_background; 340 | style.visuals.widgets.open.bg_stroke.color = 341 | self.animated_tokens.ui_element_border_and_focus_rings; 342 | style.visuals.widgets.open.fg_stroke.color = self.animated_tokens.high_contrast_text; 343 | style.visuals.extreme_bg_color = self.animated_tokens.app_background; // e.g. TextEdit background 344 | style.visuals.faint_bg_color = self.animated_tokens.app_background; // striped grid is originally from_additive_luminance(5) 345 | style.visuals.code_bg_color = self.animated_tokens.ui_element_background; 346 | style.visuals.window_fill = self.animated_tokens.subtle_background; 347 | style.visuals.window_stroke.color = self.animated_tokens.subtle_borders_and_separators; 348 | style.visuals.panel_fill = self.animated_tokens.subtle_background; 349 | style.visuals.hyperlink_color = self.animated_tokens.hovered_solid_backgrounds; 350 | style.visuals.window_shadow.color = self.shadow; 351 | } 352 | } 353 | -------------------------------------------------------------------------------- /src/apca.rs: -------------------------------------------------------------------------------- 1 | // originals 2 | const S_TRC: f32 = 2.4; 3 | const N_TX: f32 = 0.57; 4 | const N_BG: f32 = 0.56; 5 | const R_TX: f32 = 0.62; 6 | const R_BG: f32 = 0.65; 7 | // clamps &ramp; Scalers 8 | const B_CLIP: f32 = 1.414; 9 | const B_THRSH: f32 = 0.022; 10 | const W_SCALE: f32 = 1.14; 11 | const W_OFFSET: f32 = 0.027; 12 | const W_CLAMP: f32 = 0.1; 13 | 14 | // sRGB coefficients 15 | const S_RCO: f32 = 0.212_672_9; 16 | const S_GCO: f32 = 0.715_152_2; 17 | const S_BCO: f32 = 0.072_175_0; 18 | 19 | fn fsc(y: f32) -> f32 { 20 | if y < B_THRSH { 21 | y + (B_THRSH - y).powf(B_CLIP) 22 | } else if y < 0.0 { 23 | 0.0 24 | } else { 25 | y 26 | } 27 | } 28 | 29 | fn determine_cw(y_txt: f32, y_bg: f32) -> f32 { 30 | // normal polarity (dark text; light bg) 31 | if y_bg > y_txt { 32 | (y_bg.powf(N_BG) - y_txt.powf(N_TX)) * W_SCALE 33 | } 34 | // reverse polarity 35 | else { 36 | (y_bg.powf(R_BG) - y_txt.powf(R_TX)) * W_SCALE 37 | } 38 | } 39 | 40 | fn clamp_contrast(cw: f32) -> f32 { 41 | if cw.abs() < W_CLAMP { 42 | 0.0 43 | } else if cw > 0.0 { 44 | cw - W_OFFSET 45 | } else { 46 | cw + W_OFFSET 47 | } 48 | } 49 | 50 | pub fn estimate_lc(rgb_txt: egui::Color32, rgb_bg: egui::Color32) -> f32 { 51 | let r = (f32::from(rgb_txt.r()) / 255.0).powf(S_TRC) * S_RCO; 52 | let g = (f32::from(rgb_txt.g()) / 255.0).powf(S_TRC) * S_GCO; 53 | let b = (f32::from(rgb_txt.b()) / 255.0).powf(S_TRC) * S_BCO; 54 | 55 | let y = r + g + b; 56 | 57 | let r2 = (f32::from(rgb_bg.r()) / 255.0).powf(S_TRC) * 0.212_672_9; 58 | let g2 = (f32::from(rgb_bg.g()) / 255.0).powf(S_TRC) * 0.715_152_2; 59 | let b2 = (f32::from(rgb_bg.b()) / 255.0).powf(S_TRC) * 0.072_175_0; 60 | 61 | let y2 = r2 + g2 + b2; 62 | 63 | let y_txt = fsc(y); 64 | let y_bg = fsc(y2); 65 | 66 | let cw = determine_cw(y_txt, y_bg); 67 | let s_apc = clamp_contrast(cw); 68 | s_apc * 100.0 69 | } 70 | -------------------------------------------------------------------------------- /src/color_space.rs: -------------------------------------------------------------------------------- 1 | // OkHsl color space copyright by Björn Ottosson https://bottosson.github.io/posts/colorpicker/ 2 | #![allow(clippy::suboptimal_flops)] 3 | #![allow(clippy::use_self)] 4 | #![allow(clippy::many_single_char_names)] 5 | #![allow(clippy::similar_names)] 6 | #![allow(clippy::useless_let_if_seq)] 7 | 8 | use std::f32::consts::PI; 9 | 10 | #[derive(Debug, Default, Clone, Copy)] 11 | pub struct LinSrgb { 12 | red: f32, 13 | green: f32, 14 | blue: f32, 15 | } 16 | 17 | impl LinSrgb { 18 | pub const fn new(red: f32, green: f32, blue: f32) -> Self { 19 | Self { red, green, blue } 20 | } 21 | pub fn lighten(&self, factor: f32) -> Self { 22 | Self { 23 | red: (self.red + factor * (1. - self.red)).clamp(0., 1.), 24 | green: (self.green + factor * (1. - self.green)).clamp(0., 1.), 25 | blue: (self.blue + factor * (1. - self.blue)).clamp(0., 1.), 26 | } 27 | } 28 | pub fn to_okhsl(self) -> Okhsl { 29 | let oklab = linear_srgb_to_oklab(self); 30 | oklab_to_okhsl(oklab) 31 | } 32 | pub fn darken(&self, factor: f32) -> Self { 33 | Self { 34 | red: (self.red - factor * (self.red)).clamp(0., 1.), 35 | green: (self.green - factor * (self.green)).clamp(0., 1.), 36 | blue: (self.blue - factor * (self.blue)).clamp(0., 1.), 37 | } 38 | } 39 | #[allow(clippy::wrong_self_convention)] 40 | fn from_linear(&self) -> [u8; 3] { 41 | [ 42 | gamma_u8_from_linear_f32(self.red), 43 | gamma_u8_from_linear_f32(self.green), 44 | gamma_u8_from_linear_f32(self.blue), 45 | ] 46 | } 47 | pub fn into_linear(rgb: [u8; 3]) -> Self { 48 | let r = linear_f32_from_gamma_u8(rgb[0]); 49 | let g = linear_f32_from_gamma_u8(rgb[1]); 50 | let b = linear_f32_from_gamma_u8(rgb[2]); 51 | Self::new(r, g, b) 52 | } 53 | } 54 | 55 | fn linear_f32_from_gamma_u8(s: u8) -> f32 { 56 | if s <= 10 { 57 | f32::from(s) / 3294.6 58 | } else { 59 | ((f32::from(s) + 14.025) / 269.025).powf(2.4) 60 | } 61 | } 62 | 63 | fn gamma_u8_from_linear_f32(l: f32) -> u8 { 64 | if l <= 0.0 { 65 | 0 66 | } else if l <= 0.003_130_8 { 67 | fast_round(3294.6 * l) 68 | } else if l <= 1.0 { 69 | fast_round(269.025 * l.powf(1.0 / 2.4) - 14.025) 70 | } else { 71 | 255 72 | } 73 | } 74 | fn fast_round(r: f32) -> u8 { 75 | (r + 0.5) as _ 76 | } 77 | pub fn from_degrees(hue: f32) -> f32 { 78 | (hue / 360.).clamp(0., 1.) 79 | } 80 | 81 | #[derive(Copy, Clone, Debug, PartialOrd, PartialEq)] 82 | struct Oklab { 83 | l: f32, 84 | a: f32, 85 | b: f32, 86 | } 87 | 88 | impl Oklab { 89 | fn to_linear_srgb(self) -> LinSrgb { 90 | let l_ = 0.215_803_76_f32.mul_add(self.b, 0.396_337_78_f32.mul_add(self.a, self.l)); 91 | let m_ = (-0.063_854_17_f32).mul_add(self.b, (-0.105_561_346_f32).mul_add(self.a, self.l)); 92 | let s_ = (-1.291_485_5_f32).mul_add(self.b, (-0.089_484_18_f32).mul_add(self.a, self.l)); 93 | 94 | let l = l_ * l_ * l_; 95 | let m = m_ * m_ * m_; 96 | let s = s_ * s_ * s_; 97 | 98 | LinSrgb { 99 | red: 0.230_969_94_f32.mul_add(s, 4.076_741_7_f32.mul_add(l, -3.307_711_6 * m)), 100 | green: (-0.341_319_38_f32).mul_add(s, (-1.268_438_f32).mul_add(l, 2.609_757_4 * m)), 101 | blue: 1.707_614_7_f32.mul_add(s, (-0.004_196_086_3_f32).mul_add(l, -0.703_418_6 * m)), 102 | } 103 | } 104 | } 105 | 106 | #[derive(Debug, Copy, Clone, Default)] 107 | pub struct Okhsl { 108 | pub hue: f32, 109 | pub saturation: f32, 110 | pub lightness: f32, 111 | } 112 | 113 | impl Okhsl { 114 | fn to_oklab(self) -> Oklab { 115 | okhsl_to_oklab(self) 116 | } 117 | pub fn lighten(&self, factor: f32) -> Okhsl { 118 | Okhsl { 119 | hue: self.hue, 120 | saturation: self.saturation, 121 | lightness: (self.lightness + factor * (1. - self.lightness)).clamp(0., 1.), 122 | } 123 | } 124 | pub fn darken(&self, factor: f32) -> Okhsl { 125 | Okhsl { 126 | hue: self.hue, 127 | saturation: self.saturation, 128 | lightness: (self.lightness - factor * self.lightness).clamp(0., 1.), 129 | } 130 | } 131 | pub fn from_color(rgb: LinSrgb) -> Okhsl { 132 | rgb.to_okhsl() 133 | } 134 | pub fn as_degrees(&self) -> f32 { 135 | let hue = self.hue; 136 | (hue * 360.).clamp(0., 360.) 137 | } 138 | pub fn to_srgb(self) -> LinSrgb { 139 | let oklab = self.to_oklab(); 140 | oklab.to_linear_srgb() 141 | } 142 | pub fn to_u8(self) -> [u8; 3] { 143 | let rgb = self.to_srgb(); 144 | rgb.from_linear() 145 | } 146 | } 147 | 148 | fn linear_srgb_to_oklab(c: LinSrgb) -> Oklab { 149 | let l = 0.051_445_995_f32.mul_add( 150 | c.blue, 151 | 0.412_221_46_f32.mul_add(c.red, 0.536_332_55 * c.green), 152 | ); 153 | let m = 0.107_396_96_f32.mul_add( 154 | c.blue, 155 | 0.211_903_5_f32.mul_add(c.red, 0.680_699_5 * c.green), 156 | ); 157 | let s = 0.629_978_7_f32.mul_add( 158 | c.blue, 159 | 0.088_302_46_f32.mul_add(c.red, 0.281_718_85 * c.green), 160 | ); 161 | 162 | let l_ = l.cbrt(); 163 | let m_ = m.cbrt(); 164 | let s_ = s.cbrt(); 165 | 166 | Oklab { 167 | l: (-0.004_072_047_f32).mul_add(s_, 0.210_454_26_f32.mul_add(l_, 0.793_617_8 * m_)), 168 | a: 0.450_593_7_f32.mul_add(s_, 1.977_998_5_f32.mul_add(l_, -2.428_592_2 * m_)), 169 | b: (-0.808_675_77_f32).mul_add(s_, 0.025_904_037_f32.mul_add(l_, 0.782_771_77 * m_)), 170 | } 171 | } 172 | fn compute_max_saturation(a: f32, b: f32) -> f32 { 173 | let [k0, k1, k2, k3, k4, wl, wm, ws] = 174 | if (-1.881_703_3_f32).mul_add(a, -(0.809_364_9 * b)) > 1.0 { 175 | [ 176 | 1.190_862_8, 177 | 1.765_767_3, 178 | 0.596_626_4, 179 | 0.755_152, 180 | 0.567_712_4, 181 | 4.076_741_7, 182 | -3.307_711_6, 183 | 0.230_969_94, 184 | ] 185 | } else if 1.814_441_1_f32.mul_add(a, -(1.194_452_8 * b)) > 1.0 { 186 | [ 187 | 0.739_565_15, 188 | -0.459_544_04, 189 | 0.082_854_27, 190 | 0.125_410_7, 191 | 0.145_032_04, 192 | -1.268_438, 193 | 2.609_757_4, 194 | -0.341_319_38, 195 | ] 196 | } else { 197 | [ 198 | 1.357_336_5, 199 | -0.009_157_99, 200 | -1.151_302_1, 201 | -0.505_596_06, 202 | 0.006_921_67, 203 | -0.004_196_086_3, 204 | -0.703_418_6, 205 | 1.707_614_7, 206 | ] 207 | }; 208 | let mut saturation = (k4 * a).mul_add(b, (k3 * a).mul_add(a, k2.mul_add(b, k1.mul_add(a, k0)))); 209 | 210 | let k_l = 0.396_337_78_f32.mul_add(a, 0.215_803_76 * b); 211 | let k_m = (-0.105_561_346_f32).mul_add(a, -(0.063_854_17 * b)); 212 | let k_s = (-0.089_484_18_f32).mul_add(a, -(1.291_485_5 * b)); 213 | 214 | { 215 | let l_ = saturation.mul_add(k_l, 1.); 216 | let m_ = saturation.mul_add(k_m, 1.); 217 | let s_ = saturation.mul_add(k_s, 1.); 218 | 219 | let l = l_ * l_ * l_; 220 | let m = m_ * m_ * m_; 221 | let s = s_ * s_ * s_; 222 | 223 | let l_d_s = 3. * (k_l * l_) * l_; 224 | let m_d_s = 3. * (k_m * m_) * m_; 225 | let s_d_s = 3. * (k_s * s_) * s_; 226 | 227 | let l_d_s2 = 6. * k_l * (k_l * l_); 228 | let m_d_s2 = 6. * k_m * (k_m * m_); 229 | let s_d_s2 = 6. * k_s * (k_s * s_); 230 | 231 | let f = ws.mul_add(s, wl.mul_add(l, wm * m)); 232 | let f1 = ws.mul_add(s_d_s, wl.mul_add(l_d_s, wm * m_d_s)); 233 | debug_assert!(f1 != 0.); 234 | let f2 = ws.mul_add(s_d_s2, wl.mul_add(l_d_s2, wm * m_d_s2)); 235 | 236 | let div = f1.mul_add(f1, -(0.5 * f * f2)); 237 | saturation -= f * f1 / div; 238 | } 239 | saturation 240 | } 241 | fn find_cusp(a: f32, b: f32) -> [f32; 2] { 242 | let s_cusp = compute_max_saturation(a, b); 243 | let l_cusp = scale_l(1.0, s_cusp, a, b); 244 | [l_cusp, (l_cusp * s_cusp)] 245 | } 246 | fn find_gamut_intersection( 247 | a: f32, 248 | b: f32, 249 | l_1: f32, 250 | c_1: f32, 251 | l_0: f32, 252 | cusp: Option<[f32; 2]>, 253 | ) -> f32 { 254 | let [cusp_l, cusp_c] = cusp.unwrap_or_else(|| find_cusp(a, b)); 255 | let mut t; 256 | if (l_1 - l_0).mul_add(cusp_c, -((cusp_l - l_0) * c_1)) <= 0.0 { 257 | t = cusp_c * l_0 / c_1.mul_add(cusp_l, cusp_c * (l_0 - l_1)); 258 | } else { 259 | t = cusp_c * (l_0 - 1.0) / c_1.mul_add(cusp_l - 1.0, cusp_c * (l_0 - l_1)); 260 | { 261 | let d_l = l_1 - l_0; 262 | let d_c = c_1; 263 | 264 | let k_l = 0.3963_3778_f32.mul_add(a, 0.2158_0376 * b); 265 | let k_m = (-0.1055_6134_6_f32).mul_add(a, -(0.0638_5417 * b)); 266 | let k_s = (-0.0894_8418_f32).mul_add(a, -(1.2914_855 * b)); 267 | 268 | let l_dt = d_c.mul_add(k_l, d_l); 269 | let m_dt = d_c.mul_add(k_m, d_l); 270 | let s_dt = d_c.mul_add(k_s, d_l); 271 | { 272 | let l = l_0.mul_add(1. - t, t * l_1); 273 | let c = t * c_1; 274 | 275 | let l_ = c.mul_add(k_l, l); 276 | let m_ = c.mul_add(k_m, l); 277 | let s_ = c.mul_add(k_s, l); 278 | 279 | let l = l_ * l_ * l_; 280 | let m = m_ * m_ * m_; 281 | let s = s_ * s_ * s_; 282 | 283 | let ldt = 3. * (l_dt * l_) * l_; 284 | let mdt = 3. * (m_dt * m_) * m_; 285 | let sdt = 3. * (s_dt * s_) * s_; 286 | 287 | let ldt2 = 6. * l_dt * (l_dt * l_); 288 | let mdt2 = 6. * m_dt * (m_dt * m_); 289 | let sdt2 = 6. * s_dt * (s_dt * s_); 290 | 291 | let r = 292 | 0.2309_6994_f32.mul_add(s, 4.0767_417_f32.mul_add(l, -(3.3077_116 * m))) - 1.; 293 | let r1 = 294 | 0.2309_6994_f32.mul_add(sdt, 4.0767_417_f32.mul_add(ldt, -(3.3077_116 * mdt))); 295 | let r2 = 0.2309_6994_f32 296 | .mul_add(sdt2, 4.0767_417_f32.mul_add(ldt2, -(3.3077_116 * mdt2))); 297 | 298 | let u_r = r1 / r1.mul_add(r1, -(0.5 * r * r2)); 299 | let t_r = -r * u_r; 300 | 301 | let g = 302 | 0.3413_1938_f32.mul_add(-s, (-1.2684_38_f32).mul_add(l, 2.6097_574 * m)) - 1.; 303 | let g1 = 304 | 0.3413_1938_f32.mul_add(-sdt, (-1.2684_38_f32).mul_add(ldt, 2.6097_574 * mdt)); 305 | let g2 = 0.3413_1938_f32 306 | .mul_add(-sdt2, (-1.268_438_f32).mul_add(ldt2, 2.6097_574 * mdt2)); 307 | 308 | let u_g = g1 / g1.mul_add(g1, -(0.5 * g * g2)); 309 | let t_g = -g * u_g; 310 | 311 | let b = 1.7076_147_f32 312 | .mul_add(s, (-0.0041_9608_63_f32).mul_add(l, -(0.7034_186 * m))) 313 | - 1.; 314 | let b1 = 1.7076_147_f32 315 | .mul_add(sdt, (-0.0041_9608_63_f32).mul_add(ldt, -(0.7034_186 * mdt))); 316 | let b2 = 1.7076_147_f32.mul_add( 317 | sdt2, 318 | (-0.0041_9608_63_f32).mul_add(ldt2, -(0.7034_186 * mdt2)), 319 | ); 320 | 321 | let u_b = b1 / b1.mul_add(b1, -(0.5 * b * b2)); 322 | let t_b = -b * u_b; 323 | 324 | let t_r = if u_r >= 0.0 { t_r } else { 10e5 }; 325 | let t_g = if u_g >= 0.0 { t_g } else { 10e5 }; 326 | let t_b = if u_b >= 0.0 { t_b } else { 10e5 }; 327 | 328 | t += t_r.min(t_g.min(t_b)); 329 | } 330 | } 331 | } 332 | t 333 | } 334 | fn toe(x: f32) -> f32 { 335 | let k_1: f32 = 0.206; 336 | let k_2: f32 = 0.03; 337 | let k_3: f32 = (1. + k_1) / (1. + k_2); 338 | 0.5 * (k_3.mul_add(x, -k_1) 339 | + k_3 340 | .mul_add(x, -k_1) 341 | .mul_add(k_3.mul_add(x, -k_1), 4. * k_2 * (k_3 * x)) 342 | .sqrt()) 343 | } 344 | fn toe_inv(x: f32) -> f32 { 345 | let k_1 = 0.206; 346 | let k_2 = 0.03; 347 | let k_3 = (1. + k_1) / (1. + k_2); 348 | x.mul_add(x, k_1 * x) / (k_3 * (x + k_2)) 349 | } 350 | fn st_mid(a_: f32, b_: f32) -> [f32; 2] { 351 | debug_assert!(a_.is_finite()); 352 | debug_assert!(b_.is_finite()); 353 | let s_mid = 0.1151_6993 354 | + 1. / a_.mul_add( 355 | a_.mul_add( 356 | a_.mul_add( 357 | 4.69891_f32.mul_add(a_, 5.3877_08_f32.mul_add(b_, -4.2489_457)), 358 | 10.02301_f32.mul_add(-b_, -2.1370_494), 359 | ), 360 | 1.751_984_f32.mul_add(b_, -2.1955_736), 361 | ), 362 | 4.1590_123_f32.mul_add(b_, 7.4477_897), 363 | ); 364 | 365 | let t_mid = 0.1123_9642 366 | + 1. / a_.mul_add( 367 | a_.mul_add( 368 | a_.mul_add( 369 | 0.146_618_72_f32.mul_add(-a_, 0.453_995_68_f32.mul_add(-b_, 0.002_992_15)), 370 | 0.612_239_9_f32.mul_add(b_, -0.270_879_43), 371 | ), 372 | 0.901_481_2_f32.mul_add(b_, 0.403_706_12), 373 | ), 374 | 0.681_243_8_f32.mul_add(-b_, 1.613_203_2), 375 | ); 376 | [s_mid, t_mid] 377 | } 378 | fn st_max(a_: f32, b_: f32, cusp: Option<[f32; 2]>) -> [f32; 2] { 379 | let [l, c] = cusp.unwrap_or_else(|| find_cusp(a_, b_)); 380 | [c / l, c / (1. - l)] 381 | } 382 | fn get_cs(l: f32, a_: f32, b_: f32) -> [f32; 3] { 383 | let cusp = find_cusp(a_, b_); 384 | let c_max = find_gamut_intersection(a_, b_, l, 1.0, l, Some(cusp)); 385 | let [s_max, t_max] = st_max(a_, b_, Some(cusp)); 386 | let [s_mid, t_mid] = st_mid(a_, b_); 387 | 388 | let k = c_max / (l * s_max).min((1. - l) * t_max); 389 | let c_mid = { 390 | let c_a = l * s_mid; 391 | let c_b = (1. - l) * t_mid; 392 | let ca4 = (c_a * c_a) * (c_a * c_a); 393 | let cb4 = (c_b * c_b) * (c_b * c_b); 394 | 395 | 0.9 * k * ((1. / (1. / ca4 + 1. / cb4)).sqrt()).sqrt() 396 | }; 397 | let c_0 = { 398 | let c_a = l * 0.4; 399 | let c_b = (1. - l) * 0.8; 400 | 401 | (1. / (1. / (c_a * c_a) + 1. / (c_b * c_b))).sqrt() 402 | }; 403 | [c_0, c_mid, c_max] 404 | } 405 | fn okhsl_to_oklab( 406 | Okhsl { 407 | hue: h, 408 | saturation: s, 409 | lightness: l, 410 | }: Okhsl, 411 | ) -> Oklab { 412 | if l <= 0. || l >= 1. { 413 | return Oklab { l, a: 0., b: 0. }; 414 | } 415 | let a_ = (2. * PI * h).cos(); 416 | let b_ = (2. * PI * h).sin(); 417 | let l = toe_inv(l); 418 | 419 | let [c_0, c_mid, c_max] = get_cs(l, a_, b_); 420 | let t; 421 | let k_0; 422 | let k_1; 423 | let k_2; 424 | if s < 0.8 { 425 | t = 1.25 * s; 426 | k_0 = 0.; 427 | k_1 = 0.8 * c_0; 428 | k_2 = 1. - k_1 / c_mid; 429 | } else { 430 | t = 5. * (s - 0.8); 431 | k_0 = c_mid; 432 | k_1 = 0.2 * (c_mid * c_mid) * (1.25 * 1.25) / c_0; 433 | k_2 = 1. - k_1 / (c_max - c_mid); 434 | } 435 | let c = k_0 + t * k_1 / k_2.mul_add(-t, 1.); 436 | Oklab { 437 | l, 438 | a: c * a_, 439 | b: c * b_, 440 | } 441 | } 442 | fn oklab_to_okhsl(Oklab { l, a, b }: Oklab) -> Okhsl { 443 | if !(l > 0. && l < 1. && (a != 0. || b != 0.)) { 444 | return Okhsl { 445 | hue: 0., 446 | saturation: 0., 447 | lightness: l, 448 | }; 449 | } 450 | let (h, a_, b_, c) = hue(b, a); 451 | let [c_0, c_mid, c_max] = get_cs(l, a_, b_); 452 | let s = if c < c_mid { 453 | let k_0 = 0.; 454 | let k_1 = 0.8 * c_0; 455 | let k_2 = 1. - k_1 / c_mid; 456 | let t = (c - k_0) / k_2.mul_add(c - k_0, k_1); 457 | t * 0.8 458 | } else { 459 | let k_0 = c_mid; 460 | let k_1 = 0.2 * (c_mid * c_mid) * (1.25 * 1.25) / c_0; 461 | let k_2 = 1. - k_1 / (c_max - c_mid); 462 | let t = (c - k_0) / k_2.mul_add(c - k_0, k_1); 463 | 0.2_f32.mul_add(t, 0.8) 464 | }; 465 | Okhsl { 466 | hue: h, 467 | saturation: s, 468 | lightness: toe(l), 469 | } 470 | } 471 | fn hue(b: f32, a: f32) -> (f32, f32, f32, f32) { 472 | let h = (0.5 * (-b).atan2(-a)).mul_add(1. / PI, 0.5); 473 | let c = a.hypot(b); 474 | let a_ = a * (1. / c); 475 | let b_ = b * (1. / c); 476 | (h, a_, b_, c) 477 | } 478 | fn scale_l(l_vt: f32, c_vt: f32, a_: f32, b_: f32) -> f32 { 479 | let rgb_scale = (Oklab { 480 | l: l_vt, 481 | a: a_ * c_vt, 482 | b: b_ * c_vt, 483 | }) 484 | .to_linear_srgb(); 485 | let rgb_max = rgb_scale 486 | .red 487 | .max(rgb_scale.green) 488 | .max(rgb_scale.blue.max(0.)); 489 | (1. / rgb_max).cbrt() 490 | } 491 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # egui Colors 2 | //! 3 | //! Experimental toolkit to explore color styling in [`egui`](https://github.com/emilk/egui) 4 | //! 5 | //! Based on the [`Radix`](https://www.radix-ui.com/colors/docs/palette-composition/understanding-the-scale) system which maps a color scale to 12 functional 6 | //! UI elements. 7 | //! Scales (both light and dark mode) are computed with luminosity contrast algorithm defined by [`APCA`](https://github.com/Myndex). 8 | //! Every scale uses one predefined `[u8; 3]` rgb color that is used as an accent color (if suitable). 9 | //! 10 | //! 11 | 12 | pub(crate) mod animator; 13 | pub(crate) mod apca; 14 | pub(crate) mod color_space; 15 | pub(crate) mod scales; 16 | pub mod tokens; 17 | /// Some predefined themes 18 | pub mod utils; 19 | 20 | use animator::ColorAnimator; 21 | use egui::{Context, Ui}; 22 | use scales::Scales; 23 | use std::sync::Arc; 24 | use tokens::{ColorTokens, ThemeColor}; 25 | use utils::{LABELS, THEMES, THEME_NAMES}; 26 | 27 | /// A set of colors that are used together to set a visual feel for the ui 28 | pub type Theme = [ThemeColor; 12]; 29 | 30 | #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] 31 | pub(crate) enum ApplyTo { 32 | Global, 33 | Local, 34 | #[default] 35 | ExtraScale, 36 | } 37 | 38 | /// The Colorix type is the main entry to this crate. 39 | /// 40 | /// # Examples 41 | /// 42 | /// ``` 43 | /// use egui::Context; 44 | /// use egui_colors::{Colorix, tokens::ThemeColor}; 45 | /// //Define a colorix field in your egui App 46 | /// #[derive(Default)] 47 | /// struct App { 48 | /// colorix: Colorix, 49 | /// //..Default::default() 50 | /// } 51 | /// // initialize the Colorix with a theme 52 | /// // a color theme is defined as [ThemeColor; 12] 53 | /// // a ThemeColor is an enum with several preset colors and one Custom. 54 | /// // You can choose between different scopes: global, local or extra_set. 55 | /// impl App { 56 | /// fn new(ctx: &Context) -> Self { 57 | /// let yellow_theme = [ThemeColor::Custom([232, 210, 7]); 12]; 58 | /// let colorix = Colorix::global(ctx, yellow_theme); 59 | /// Self { 60 | /// colorix, 61 | /// ..Default::default() 62 | /// } 63 | /// } 64 | /// } 65 | /// ``` 66 | #[derive(Debug, Default, Clone)] 67 | pub struct Colorix { 68 | pub tokens: ColorTokens, 69 | pub(crate) theme: Theme, 70 | theme_index: usize, 71 | pub(crate) scales: Scales, 72 | animated: bool, 73 | pub animator: ColorAnimator, 74 | pub(crate) apply_to: ApplyTo, 75 | } 76 | 77 | impl Colorix { 78 | #[must_use] 79 | pub fn global(ctx: &Context, theme: Theme) -> Self { 80 | let mut colorix = Self { 81 | theme, 82 | ..Default::default() 83 | }; 84 | let mode = ctx.style().visuals.dark_mode; 85 | colorix.apply_to = ApplyTo::Global; 86 | colorix.tokens.apply_to = ApplyTo::Global; 87 | colorix.set_colorix_mode(mode); 88 | colorix.get_theme_index(); 89 | colorix.update_colors(Some(ctx), None); 90 | colorix 91 | } 92 | /// Initialize a Colorix instance that applies to local ui. 93 | /// It needs an `update_locally(ui)` in the egui `update` function to work. 94 | pub fn local(ui: &mut Ui, theme: Theme) -> Self { 95 | let mut colorix = Self { 96 | theme, 97 | ..Default::default() 98 | }; 99 | let mode = ui.ctx().style().visuals.dark_mode; 100 | colorix.set_colorix_mode(mode); 101 | colorix.get_theme_index(); 102 | colorix.apply_to = ApplyTo::Local; 103 | colorix.tokens.apply_to = ApplyTo::Local; 104 | colorix.update_colors(None, Some(ui)); 105 | colorix 106 | } 107 | /// Initialize a colorix to provide extra scale. It doesn't apply to any ui. 108 | #[must_use] 109 | pub fn extra_scale(ctx: &Context, theme: Theme) -> Self { 110 | let mut colorix = Self { 111 | theme, 112 | ..Default::default() 113 | }; 114 | let mode = ctx.style().visuals.dark_mode; 115 | colorix.set_colorix_mode(mode); 116 | colorix.get_theme_index(); 117 | colorix.apply_to = ApplyTo::ExtraScale; 118 | colorix.tokens.apply_to = ApplyTo::ExtraScale; 119 | colorix.update_colors(Some(ctx), None); 120 | colorix 121 | } 122 | #[must_use] 123 | pub fn local_from_style(theme: Theme, dark_mode: bool) -> Self { 124 | let mut colorix = Self::default(); 125 | colorix.set_colorix_mode(dark_mode); 126 | colorix.theme = theme; 127 | colorix.apply_to = ApplyTo::Local; 128 | colorix.tokens.apply_to = ApplyTo::Local; 129 | colorix.update_colors(None, None); 130 | colorix 131 | } 132 | /// Set animator 133 | /// # Example 134 | /// 135 | /// ```ignore 136 | /// impl App { 137 | /// fn new(ctx: &Context) -> Self { 138 | /// let yellow_theme = [ThemeColor::Custom([232, 210, 7]); 12]; 139 | /// let colorix = Colorix::global(ctx, yellow_theme).animated().set_time(2.0); 140 | /// Self { 141 | /// colorix, 142 | /// ..Default::default() 143 | /// } 144 | /// } 145 | /// } 146 | /// ``` 147 | #[must_use] 148 | pub const fn animated(mut self) -> Self { 149 | self.animated = true; 150 | self.init_animator(); 151 | self 152 | } 153 | /// Change the default time (1.0) of the animation. 154 | #[must_use] 155 | pub const fn set_time(mut self, new_time: f32) -> Self { 156 | if self.animated { 157 | self.animator.set_time(new_time); 158 | } 159 | self 160 | } 161 | 162 | /// sets new theme and animates towards it. 163 | pub fn update_theme(&mut self, ctx: &egui::Context, theme: Theme) { 164 | self.theme = theme; 165 | self.get_theme_index(); 166 | self.update_colors(Some(ctx), None); 167 | } 168 | // starts animation; has only visible effect on the tokenshifts. 169 | pub fn shift_tokens(&mut self, ctx: &egui::Context) { 170 | self.animator.start(ctx); 171 | } 172 | #[must_use] 173 | pub const fn dark_mode(&self) -> bool { 174 | self.scales.dark_mode 175 | } 176 | 177 | const fn init_animator(&mut self) { 178 | self.animator = ColorAnimator::new(self.tokens); 179 | self.animator.apply_to = self.apply_to; 180 | } 181 | 182 | /// Necessary to engage the color animation 183 | /// works only for global ui and `extra_scale` 184 | pub fn set_animator(&mut self, ctx: &Context) { 185 | match self.apply_to { 186 | ApplyTo::Global | ApplyTo::ExtraScale => { 187 | if self.animated { 188 | self.animator.set_animate(Some(ctx), None, self.tokens); 189 | } 190 | } 191 | ApplyTo::Local => {} 192 | } 193 | } 194 | 195 | fn get_theme_index(&mut self) { 196 | if let Some(i) = THEMES.iter().position(|t| t == &self.theme) { 197 | self.theme_index = i; 198 | } 199 | } 200 | /// create theme based on 1 custom color from color picker 201 | pub fn twelve_from_custom(&mut self, ui: &mut Ui) { 202 | self.theme = [ThemeColor::Custom(self.scales.custom()); 12]; 203 | self.match_and_update_colors(ui); 204 | } 205 | 206 | fn match_and_update_colors(&mut self, ui: &mut Ui) { 207 | match self.apply_to { 208 | ApplyTo::Global | ApplyTo::ExtraScale => { 209 | self.update_colors(Some(ui.ctx()), None); 210 | } 211 | ApplyTo::Local => { 212 | self.update_colors(None, Some(ui)); 213 | } 214 | } 215 | } 216 | const fn set_colorix_mode(&mut self, mode: bool) { 217 | self.scales.dark_mode = mode; 218 | self.tokens.dark_mode = mode; 219 | } 220 | /// If you initialize a Colorix instance with a `local` scope, this needs to be placed 221 | /// inside the egui `update` fn. 222 | pub fn update_locally(&mut self, ui: &mut Ui) { 223 | if self.apply_to == ApplyTo::Local { 224 | if self.animated { 225 | self.animator.set_animate(None, Some(ui), self.tokens); 226 | } else { 227 | self.update_colors(None, Some(ui)); 228 | } 229 | } 230 | } 231 | 232 | fn set_ui_mode(&self, ui: &mut Ui, mode: bool) { 233 | match self.apply_to { 234 | ApplyTo::Global => ui.ctx().style_mut(|style| style.visuals.dark_mode = mode), 235 | ApplyTo::Local => ui.style_mut().visuals.dark_mode = mode, 236 | ApplyTo::ExtraScale => {} 237 | } 238 | } 239 | /// Change the color mode to dark. 240 | pub fn set_dark(&mut self, ui: &mut Ui) { 241 | self.set_colorix_mode(true); 242 | self.set_ui_mode(ui, true); 243 | self.match_and_update_colors(ui); 244 | } 245 | /// Change the color mode to light. 246 | pub fn set_light(&mut self, ui: &mut Ui) { 247 | self.set_colorix_mode(false); 248 | self.set_ui_mode(ui, false); 249 | self.match_and_update_colors(ui); 250 | } 251 | 252 | fn process_theme(&mut self) { 253 | let mut processed: Vec = vec![]; 254 | for (i, v) in self.theme.iter().enumerate() { 255 | if !processed.contains(&i) { 256 | self.scales.process_color(*v); 257 | self.tokens.update_schema(i, self.scales.scale[i]); 258 | if i < self.theme.len() { 259 | for (j, w) in self.theme[i + 1..].iter().enumerate() { 260 | if w == v { 261 | self.tokens 262 | .update_schema(j + i + 1, self.scales.scale[j + i + 1]); 263 | processed.push(j + i + 1); 264 | } 265 | } 266 | } 267 | } 268 | } 269 | } 270 | 271 | fn match_egui_visuals(&self, ui: &mut Ui) { 272 | match self.apply_to { 273 | ApplyTo::Global => self.tokens.set_ctx_visuals(ui.ctx()), 274 | ApplyTo::Local => self.tokens.set_ui_visuals(ui), 275 | ApplyTo::ExtraScale => {} 276 | } 277 | } 278 | 279 | fn update_color(&mut self, ui: &mut Ui, i: usize) { 280 | self.scales.process_color(self.theme[i]); 281 | self.tokens.update_schema(i, self.scales.scale[i]); 282 | self.tokens.color_on_accent(); 283 | if self.animated { 284 | self.animator.start(ui.ctx()); 285 | } else { 286 | self.match_egui_visuals(ui); 287 | } 288 | } 289 | 290 | fn update_colors(&mut self, ctx: Option<&Context>, ui: Option<&mut Ui>) { 291 | if self.animated { 292 | self.process_theme(); 293 | self.tokens.color_on_accent(); 294 | if let Some(ctx) = ctx { 295 | self.animator.start(ctx); 296 | } else if let Some(ui) = ui { 297 | self.animator.start(ui.ctx()); 298 | } 299 | } else { 300 | self.process_theme(); 301 | self.tokens.color_on_accent(); 302 | if let Some(ctx) = ctx { 303 | if self.apply_to != ApplyTo::ExtraScale { 304 | self.tokens.set_ctx_visuals(ctx); 305 | } 306 | } else if let Some(ui) = ui { 307 | self.tokens.set_ui_visuals(ui); 308 | } 309 | } 310 | } 311 | 312 | /// WARNING: don't use the `light_dark` buttons that egui provides. 313 | /// That will override the themes from this crate. It needs the size for the button in f32 314 | pub fn light_dark_toggle_button(&mut self, ui: &mut Ui, size: f32) { 315 | #![allow(clippy::collapsible_else_if)] 316 | if self.dark_mode() { 317 | if ui 318 | .add( 319 | egui::Button::new(egui::RichText::new("☀").size(size)) 320 | .frame(false), 321 | ) 322 | .on_hover_text("Switch to light mode") 323 | .clicked() 324 | { 325 | self.set_colorix_mode(false); 326 | self.set_ui_mode(ui, false); 327 | self.match_and_update_colors(ui); 328 | } 329 | } else { 330 | if ui 331 | .add( 332 | egui::Button::new(egui::RichText::new("🌙").size(size)) 333 | .frame(false), 334 | ) 335 | .on_hover_text("Switch to dark mode") 336 | .clicked() 337 | { 338 | self.set_colorix_mode(true); 339 | self.set_ui_mode(ui, true); 340 | self.match_and_update_colors(ui); 341 | } 342 | } 343 | } 344 | 345 | /// Choose from a list of preset themes. It is possible to add custom themes. 346 | /// NOTE: custom values chosen without the custom color picker are not recommended! 347 | /// 348 | /// # Examples 349 | /// 350 | /// ```ignore 351 | /// use egui_colors::tokens::ThemeColor; 352 | /// let names = vec!["YellowGreen"]; 353 | /// let themes = vec![[ThemeColor::Custom([178, 194, 31]); 12]]; 354 | /// let custom = Some((names, themes)); 355 | /// 356 | /// // if you want to display custom themes only, set `custom_only` to `true` 357 | /// app.colorix.themes_dropdown(ui, custom, false); 358 | /// ``` 359 | pub fn themes_dropdown( 360 | &mut self, 361 | ui: &mut Ui, 362 | custom_themes: Option<(Vec<&str>, Vec)>, 363 | custom_only: bool, 364 | ) { 365 | let combi_themes: Vec; 366 | let combi_names: Vec<&str>; 367 | 368 | if let Some(custom) = custom_themes { 369 | let (names, themes) = custom; 370 | if custom_only { 371 | combi_themes = themes; 372 | combi_names = names; 373 | } else { 374 | combi_themes = THEMES.iter().copied().chain(themes).collect(); 375 | combi_names = THEME_NAMES.iter().copied().chain(names).collect(); 376 | } 377 | } else { 378 | combi_names = THEME_NAMES.to_vec(); 379 | combi_themes = THEMES.to_vec(); 380 | } 381 | egui::ComboBox::from_id_salt(ui.id()) 382 | .selected_text(combi_names[self.theme_index]) 383 | .show_ui(ui, |ui| { 384 | for i in 0..combi_themes.len() { 385 | if ui 386 | .selectable_value(&mut self.theme, combi_themes[i], combi_names[i]) 387 | .clicked() 388 | { 389 | self.theme_index = i; 390 | self.match_and_update_colors(ui); 391 | } 392 | } 393 | }); 394 | } 395 | /// A widget with 12 dropdown menus of the UI elements (`ColorTokens`) that can be set. 396 | pub fn ui_combo_12(&mut self, ui: &mut Ui, copy: bool) { 397 | let dropdown_colors: [ThemeColor; 23] = [ 398 | ThemeColor::Gray, 399 | ThemeColor::EguiBlue, 400 | ThemeColor::Tomato, 401 | ThemeColor::Red, 402 | ThemeColor::Ruby, 403 | ThemeColor::Crimson, 404 | ThemeColor::Pink, 405 | ThemeColor::Plum, 406 | ThemeColor::Purple, 407 | ThemeColor::Violet, 408 | ThemeColor::Iris, 409 | ThemeColor::Indigo, 410 | ThemeColor::Blue, 411 | ThemeColor::Cyan, 412 | ThemeColor::Teal, 413 | ThemeColor::Jade, 414 | ThemeColor::Green, 415 | ThemeColor::Grass, 416 | ThemeColor::Brown, 417 | ThemeColor::Bronze, 418 | ThemeColor::Gold, 419 | ThemeColor::Orange, 420 | ThemeColor::Custom(self.scales.custom()), 421 | ]; 422 | ui.vertical(|ui| { 423 | for (i, label) in LABELS.iter().enumerate() { 424 | ui.horizontal(|ui| { 425 | let color_edit_size = egui::vec2(40.0, 18.0); 426 | if let Some(ThemeColor::Custom(rgb)) = self.theme.get_mut(i) { 427 | let re = ui.color_edit_button_srgb(rgb); 428 | if re.changed() { 429 | self.update_color(ui, i); 430 | } 431 | } else { 432 | // Allocate a color edit button's worth of space for non-custom presets, 433 | // for alignment purposes. 434 | ui.add_space(color_edit_size.x + ui.style().spacing.item_spacing.x); 435 | } 436 | let color = if self.animated { 437 | self.animator.animated_tokens.get_token(i) 438 | } else { 439 | self.tokens.get_token(i) 440 | }; 441 | egui::widgets::color_picker::show_color(ui, color, color_edit_size); 442 | egui::ComboBox::from_label(*label) 443 | .selected_text(self.theme[i].label()) 444 | .show_ui(ui, |ui| { 445 | for preset in dropdown_colors { 446 | if ui 447 | .selectable_value(&mut self.theme[i], preset, preset.label()) 448 | .clicked() 449 | { 450 | self.update_color(ui, i); 451 | } 452 | } 453 | }); 454 | }); 455 | } 456 | }); 457 | if copy { 458 | ui.add_space(10.); 459 | if ui.button("Copy theme to clipboard").clicked() { 460 | ui.ctx().copy_text(format!("{:#?}", self.theme)); 461 | } 462 | } 463 | } 464 | 465 | /// NOTE: values are clamped for useability. 466 | /// Creating custom themes outside these values is not recommended. 467 | pub fn custom_picker(&mut self, ui: &mut Ui) { 468 | if egui::color_picker::color_edit_button_hsva( 469 | ui, 470 | &mut self.scales.custom, 471 | egui::color_picker::Alpha::Opaque, 472 | ) 473 | .changed() 474 | { 475 | self.scales.clamp_custom(); 476 | } 477 | } 478 | 479 | /// Set a background gradient. Choose 'true' for color from `solid_backgrounds` (if animated `active_ui_element_background`) 480 | /// and 'false' for `ui_element_background` 481 | pub fn draw_background(&mut self, ctx: &Context, accent: bool) { 482 | let (ui_element, background) = if self.animated { 483 | ( 484 | self.animator.animated_tokens.ui_element_background, 485 | self.animator.animated_tokens.app_background, 486 | ) 487 | } else { 488 | ( 489 | self.tokens.ui_element_background, 490 | self.tokens.app_background, 491 | ) 492 | }; 493 | let bg = if accent { 494 | self.animator.animated_tokens.active_ui_element_background 495 | } else { 496 | ui_element 497 | }; 498 | let rect = egui::Context::available_rect(ctx); 499 | let layer_id = egui::LayerId::background(); 500 | let painter = egui::Painter::new(ctx.clone(), layer_id, rect); 501 | let mut mesh = egui::Mesh::default(); 502 | mesh.colored_vertex(rect.left_top(), background); 503 | mesh.colored_vertex(rect.right_top(), background); 504 | mesh.colored_vertex(rect.left_bottom(), bg); 505 | mesh.colored_vertex(rect.right_bottom(), bg); 506 | mesh.add_triangle(0, 1, 2); 507 | mesh.add_triangle(1, 2, 3); 508 | painter.add(egui::Shape::Mesh(Arc::new(mesh))); 509 | } 510 | /// Returns the currently set theme 511 | #[must_use] 512 | pub const fn theme(&self) -> &Theme { 513 | &self.theme 514 | } 515 | } 516 | -------------------------------------------------------------------------------- /src/scales.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::cast_lossless)] 2 | #![allow(clippy::many_single_char_names)] 3 | #![allow(clippy::suboptimal_flops)] 4 | 5 | use crate::color_space::{from_degrees, LinSrgb, Okhsl}; 6 | use crate::{apca::estimate_lc, tokens::ThemeColor}; 7 | use egui::{epaint::Hsva, Color32}; 8 | 9 | #[derive(Debug, Default, Clone)] 10 | pub struct Scales { 11 | pub custom: Hsva, 12 | pub okhsl: [Okhsl; 12], 13 | pub rgbs: [LinSrgb; 12], 14 | pub srgb: LinSrgb, 15 | pub scale: [Color32; 12], 16 | pub dark_mode: bool, 17 | } 18 | 19 | impl Scales { 20 | pub fn custom(&self) -> [u8; 3] { 21 | self.custom.to_srgb() 22 | } 23 | 24 | pub fn process_color(&mut self, v: ThemeColor) { 25 | self.srgb = v.get_srgb(); 26 | self.draw_scale(); 27 | } 28 | 29 | fn draw_scale(&mut self) { 30 | if self.dark_mode { 31 | self.dark_scale(); 32 | } else { 33 | self.light_scale(); 34 | } 35 | } 36 | 37 | pub fn clamp_custom(&mut self) { 38 | // -------- 39 | // ---- input value in color picker clamped to useable values--- 40 | // ---------------------------------------------- 41 | let v_clamp = match self.custom.s { 42 | (0.0..=0.3) => ((0.0 - 0.13) / (0.3 - 0.0) as f32).mul_add(self.custom.s - 0.0, 0.13), 43 | (0.3..=1.0) => ((0.13 - 0.0) / (1.0 - 0.3) as f32).mul_add(self.custom.s - 0.3, 0.0), 44 | _ => 0., 45 | }; 46 | let s_clamp = match self.custom.v { 47 | (0.0..=0.13) => ((0. - 0.3) / (0.13 - 0.0) as f32).mul_add(self.custom.v - 0.0, 0.3), 48 | (0.13..=1.0) => ((0.3 - 0.) / (1. - 0.13) as f32).mul_add(self.custom.v - 0.13, 0.), 49 | _ => 0., 50 | }; 51 | self.custom.v = self.custom.v.clamp(v_clamp, 0.99); 52 | self.custom.s = self.custom.s.clamp(s_clamp, 1.0); 53 | } 54 | 55 | fn light_scale(&mut self) { 56 | self.rgbs[8] = self.srgb; 57 | let hsl = Okhsl::from_color(self.srgb); 58 | let hue = hsl.as_degrees(); 59 | self.okhsl[8] = hsl; 60 | let srgb = self.srgb; 61 | 62 | let lighten_values = [0.965, 0.9, 0.82, 0.75, 0.63, 0.51, 0.39, 0.27]; 63 | let clamp_v = [0.99, 0.98, 0.97, 0.95, 0.93, 0.90, 0.88, 0.85]; 64 | let darken_values = [0.1, 0.2, 0.55]; 65 | for (i, v) in lighten_values.iter().enumerate() { 66 | self.rgbs[i] = srgb.lighten(*v); 67 | } 68 | 69 | for i in 0..12 { 70 | if (0..9).contains(&i) { 71 | self.okhsl[i] = Okhsl::from_color(self.rgbs[i]); 72 | if i != 8 { 73 | // adapt hue to compensate for temperature shift 74 | if hue > 0. && hue < 90. { 75 | self.okhsl[i].hue = 76 | from_degrees(self.okhsl[i].as_degrees() + 10_f32 - i as f32); 77 | } 78 | if hue > 200. && hue < 280. { 79 | self.okhsl[i].hue = 80 | from_degrees(self.okhsl[i].as_degrees() - 10_f32 - i as f32); 81 | } 82 | } 83 | } 84 | if (9..12).contains(&i) { 85 | self.okhsl[i] = Okhsl::from_color(srgb).darken(darken_values[i - 9]); 86 | } 87 | if i != 8 { 88 | // enhance saturation for all values (except orginal) and diminish for certain hues (greenish) 89 | let hue = hue as u8; 90 | let sat_val = match hue { 91 | 159..=216 => ((hue - 159) as f32 / 58_f32) * 0.25, 92 | 100..=158 => ((158 - hue) as f32 / 58_f32) * 0.25, 93 | _ => 0.25, 94 | }; 95 | let sat_clamp = match hue { 96 | 100..=158 => ((hue - 100) as f32 / 58_f32) * 0.12, 97 | 159..=217 => ((217 - hue) as f32 / 58_f32) * 0.12, 98 | _ => 0.0, 99 | }; 100 | if hsl.saturation > 0.01 && hsl.lightness > 0.01 { 101 | self.okhsl[i].saturation = 102 | (hsl.saturation * hsl.lightness + sat_val).clamp(0.1, 1.0 - sat_clamp); 103 | } 104 | if i < 8 && hsl.lightness > 0.79 { 105 | self.okhsl[i].lightness = 106 | self.okhsl[i].lightness.clamp(clamp_v[i] - 0.8, clamp_v[i]); 107 | } 108 | } 109 | } 110 | self.okhsl[10].lightness = self.okhsl[10].lightness.clamp(0.43, 0.50); 111 | self.okhsl[11].lightness *= 0.9; 112 | 113 | let [x, y, z] = hsl.to_u8(); 114 | let lc = estimate_lc(Color32::WHITE, Color32::from_rgb(x, y, z)); 115 | if lc > -46. { 116 | self.okhsl[8].lightness = 0.68; 117 | self.okhsl[9].lightness = self.okhsl[8].lightness * 0.9; 118 | self.okhsl[9].saturation = self.okhsl[8].saturation * 0.9; 119 | // } 120 | } else { 121 | self.okhsl[9].saturation = self.okhsl[8].saturation; 122 | } 123 | 124 | for i in 0..12 { 125 | let [r, g, b]: [u8; 3] = self.okhsl[i].to_u8(); 126 | self.scale[i] = Color32::from_rgb(r, g, b); 127 | } 128 | } 129 | 130 | pub fn dark_scale(&mut self) { 131 | self.rgbs[8] = self.srgb; 132 | let hsl = Okhsl::from_color(self.srgb); 133 | let hue = hsl.as_degrees(); 134 | self.okhsl[8] = hsl; 135 | 136 | let darken_values = [0.975, 0.96, 0.93, 0.89, 0.83, 0.75, 0.64, 0.39]; 137 | let clamp_s = [0.3, 0.5, 0.8, 1., 1., 0.95, 0.7, 0.8]; 138 | let clamp_s2 = [0.14, 0.16, 0.44, 0.62, 0.61, 0.56, 0.52, 0.51]; 139 | let clamp_l = [0.08, 0.10, 0.15, 0.19, 0.23, 0.29, 0.36, 0.47]; 140 | let lighten_values = [0.095, 0.45, 0.75]; 141 | 142 | for i in 0..8 { 143 | self.rgbs[i] = self.srgb.darken(darken_values[i]); 144 | self.okhsl[i] = Okhsl::from_color(self.rgbs[i]); 145 | if (259.0..=323.).contains(&hue) { 146 | self.okhsl[i] = self.okhsl[i].lighten((i + 1) as f32 * 0.011); 147 | } 148 | if (323.0..=350.).contains(&hue) && i == (6 | 7) { 149 | self.okhsl[i] = self.okhsl[i].lighten((i + 1) as f32 * 0.01); 150 | } 151 | self.okhsl[i].saturation *= 1.0 + ((1.0 - hsl.saturation) * 2.); 152 | 153 | if hsl.saturation > 0.36 { 154 | self.okhsl[i].saturation = self.okhsl[i].saturation.clamp( 155 | clamp_s2[i], 156 | (hsl.saturation * clamp_s[i]).clamp(clamp_s2[i] + 0.01, 1.0), 157 | ); 158 | } else { 159 | self.okhsl[i].saturation = self.okhsl[i] 160 | .saturation 161 | .clamp(0.0, hsl.saturation * clamp_s[i]); 162 | } 163 | self.okhsl[i].lightness = self.okhsl[i].lightness.clamp( 164 | clamp_l[i], 165 | (clamp_l[i] * (1.71 - hsl.saturation)).clamp(clamp_l[i] + 0.01, 1.0), 166 | ); 167 | } 168 | for i in 9..12 { 169 | self.okhsl[i] = hsl.lighten(lighten_values[i - 9]); 170 | if (0.0..=90.).contains(&hue) | (300.0..=350.).contains(&hue) { 171 | self.okhsl[i].hue = 172 | from_degrees(self.okhsl[i].as_degrees() + 2_f32 * (i - 8) as f32); 173 | } 174 | if (100.0..=280.).contains(&hue) { 175 | self.okhsl[i].hue = 176 | from_degrees(self.okhsl[i].as_degrees() - 2_f32 * (i - 8) as f32); 177 | } 178 | } 179 | self.okhsl[10].lightness = self.okhsl[10].lightness.clamp(0.73, 1.0); 180 | self.okhsl[11].lightness = self.okhsl[11].lightness.clamp(0.88, 1.0); 181 | if (115.0..=220.).contains(&hue) { 182 | self.okhsl[11].saturation = self.okhsl[11].saturation.clamp(0.0, hsl.saturation * 0.75); 183 | self.okhsl[10].saturation = self.okhsl[10].saturation.clamp(0.0, hsl.saturation * 0.9); 184 | } 185 | let [x, y, z] = hsl.to_u8(); 186 | let lc = estimate_lc(Color32::WHITE, Color32::from_rgb(x, y, z)); 187 | if lc < -95.4 { 188 | self.okhsl[8] = hsl.lighten(0.3); 189 | self.okhsl[8].saturation = (hsl.saturation * 1.25).clamp(0., 1.); 190 | self.okhsl[9] = self.okhsl[9].lighten(0.25); 191 | self.okhsl[9].saturation = hsl.saturation; 192 | } 193 | (0..12).for_each(|i| { 194 | let [r, g, b]: [u8; 3] = self.okhsl[i].to_u8(); 195 | self.scale[i] = Color32::from_rgb(r, g, b); 196 | }); 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /src/tokens.rs: -------------------------------------------------------------------------------- 1 | use crate::color_space::LinSrgb; 2 | use crate::{apca::estimate_lc, ApplyTo}; 3 | use egui::{self, Color32, Context, Ui}; 4 | 5 | /// The functional UI elements mapped to a scale 6 | #[derive(Default, Debug, Clone, Copy)] 7 | pub struct ColorTokens { 8 | pub(crate) app_background: Color32, 9 | pub(crate) subtle_background: Color32, 10 | pub(crate) ui_element_background: Color32, 11 | pub(crate) hovered_ui_element_background: Color32, 12 | pub(crate) active_ui_element_background: Color32, 13 | pub(crate) subtle_borders_and_separators: Color32, 14 | pub(crate) ui_element_border_and_focus_rings: Color32, 15 | pub(crate) hovered_ui_element_border: Color32, 16 | pub(crate) solid_backgrounds: Color32, 17 | pub(crate) hovered_solid_backgrounds: Color32, 18 | pub(crate) low_contrast_text: Color32, 19 | pub(crate) high_contrast_text: Color32, 20 | pub(crate) inverse_color: bool, 21 | pub(crate) on_accent: Color32, 22 | pub(crate) dark_mode: bool, 23 | pub(crate) apply_to: ApplyTo, 24 | } 25 | 26 | impl ColorTokens { 27 | #[must_use] 28 | pub const fn app_background(&self) -> Color32 { 29 | self.app_background 30 | } 31 | #[must_use] 32 | pub const fn subtle_background(&self) -> Color32 { 33 | self.subtle_background 34 | } 35 | #[must_use] 36 | pub const fn ui_element_background(&self) -> Color32 { 37 | self.ui_element_background 38 | } 39 | #[must_use] 40 | pub const fn hovered_ui_element_background(&self) -> Color32 { 41 | self.hovered_ui_element_background 42 | } 43 | #[must_use] 44 | pub const fn active_ui_element_background(&self) -> Color32 { 45 | self.active_ui_element_background 46 | } 47 | #[must_use] 48 | pub const fn subtle_borders_and_separators(&self) -> Color32 { 49 | self.subtle_borders_and_separators 50 | } 51 | #[must_use] 52 | pub const fn ui_element_border_and_focus_rings(&self) -> Color32 { 53 | self.ui_element_border_and_focus_rings 54 | } 55 | #[must_use] 56 | pub const fn hovered_ui_element_border(&self) -> Color32 { 57 | self.hovered_ui_element_border 58 | } 59 | #[must_use] 60 | pub const fn solid_backgrounds(&self) -> Color32 { 61 | self.solid_backgrounds 62 | } 63 | #[must_use] 64 | pub const fn hovered_solid_backgrounds(&self) -> Color32 { 65 | self.hovered_solid_backgrounds 66 | } 67 | #[must_use] 68 | pub const fn low_contrast_text(&self) -> Color32 { 69 | self.low_contrast_text 70 | } 71 | #[must_use] 72 | pub const fn high_contrast_text(&self) -> Color32 { 73 | self.high_contrast_text 74 | } 75 | #[must_use] 76 | pub const fn inverse_color(&self) -> bool { 77 | self.inverse_color 78 | } 79 | #[must_use] 80 | pub const fn on_accent(&self) -> Color32 { 81 | self.on_accent 82 | } 83 | 84 | pub(crate) fn color_on_accent(&mut self) { 85 | let lc = estimate_lc(egui::Color32::WHITE, self.solid_backgrounds); 86 | if lc > -46. { 87 | self.inverse_color = true; 88 | let mut hsva: egui::ecolor::Hsva = self.solid_backgrounds.into(); 89 | hsva.s = 0.7; 90 | hsva.v = 0.01; 91 | self.on_accent = hsva.into(); 92 | } else { 93 | self.on_accent = egui::Color32::WHITE; 94 | } 95 | } 96 | 97 | pub(crate) const fn update_schema(&mut self, i: usize, fill: Color32) { 98 | match i { 99 | 0 => self.app_background = fill, 100 | 1 => self.subtle_background = fill, 101 | 2 => self.ui_element_background = fill, 102 | 3 => self.hovered_ui_element_background = fill, 103 | 4 => self.active_ui_element_background = fill, 104 | 5 => self.subtle_borders_and_separators = fill, 105 | 6 => self.ui_element_border_and_focus_rings = fill, 106 | 7 => self.hovered_ui_element_border = fill, 107 | 8 => self.solid_backgrounds = fill, 108 | 9 => self.hovered_solid_backgrounds = fill, 109 | 10 => self.low_contrast_text = fill, 110 | 11 => self.high_contrast_text = fill, 111 | _ => {} 112 | } 113 | } 114 | pub(crate) const fn get_token(&self, i: usize) -> Color32 { 115 | match i { 116 | 0 => self.app_background, 117 | 1 => self.subtle_background, 118 | 2 => self.ui_element_background, 119 | 3 => self.hovered_ui_element_background, 120 | 4 => self.active_ui_element_background, 121 | 5 => self.subtle_borders_and_separators, 122 | 6 => self.ui_element_border_and_focus_rings, 123 | 7 => self.hovered_ui_element_border, 124 | 8 => self.solid_backgrounds, 125 | 9 => self.hovered_solid_backgrounds, 126 | 10 => self.low_contrast_text, 127 | 11 => self.high_contrast_text, 128 | _ => Color32::TRANSPARENT, 129 | } 130 | } 131 | 132 | pub(crate) fn set_ctx_visuals(&self, ctx: &Context) { 133 | ctx.style_mut(|style| self.set_egui_style(style)); 134 | } 135 | pub(crate) fn set_ui_visuals(&self, ui: &mut Ui) { 136 | self.set_egui_style(ui.style_mut()); 137 | } 138 | 139 | pub fn set_egui_style(&self, style: &mut egui::style::Style) { 140 | let shadow = if self.dark_mode { 141 | Color32::from_black_alpha(96) 142 | } else { 143 | Color32::from_black_alpha(25) 144 | }; 145 | if self.apply_to != ApplyTo::ExtraScale { 146 | style.visuals.text_cursor.stroke.color = self.low_contrast_text; 147 | style.visuals.selection.bg_fill = self.solid_backgrounds; 148 | style.visuals.selection.stroke.color = self.on_accent; 149 | style.visuals.widgets.noninteractive.weak_bg_fill = self.subtle_background; 150 | style.visuals.widgets.noninteractive.bg_fill = self.subtle_background; 151 | style.visuals.widgets.noninteractive.bg_stroke.color = 152 | self.subtle_borders_and_separators; // separators, indentation lines 153 | style.visuals.widgets.noninteractive.fg_stroke.color = self.low_contrast_text; // normal text color; 154 | style.visuals.widgets.inactive.weak_bg_fill = self.ui_element_background; // button background 155 | style.visuals.widgets.inactive.bg_fill = self.ui_element_background; // checkbox background 156 | style.visuals.widgets.inactive.bg_stroke.color = self.ui_element_background; 157 | style.visuals.widgets.inactive.fg_stroke.color = self.low_contrast_text; // button text 158 | style.visuals.widgets.hovered.weak_bg_fill = self.hovered_ui_element_background; 159 | style.visuals.widgets.hovered.bg_fill = self.hovered_ui_element_background; 160 | style.visuals.widgets.hovered.bg_stroke.color = self.hovered_ui_element_border; // e.g. hover over window edge or button 161 | style.visuals.widgets.hovered.fg_stroke.color = self.high_contrast_text; 162 | style.visuals.widgets.active.weak_bg_fill = self.active_ui_element_background; 163 | style.visuals.widgets.active.bg_fill = self.active_ui_element_background; 164 | style.visuals.widgets.active.bg_stroke.color = self.ui_element_border_and_focus_rings; 165 | style.visuals.widgets.active.fg_stroke.color = self.high_contrast_text; 166 | style.visuals.widgets.open.weak_bg_fill = self.active_ui_element_background; 167 | style.visuals.widgets.open.bg_fill = self.active_ui_element_background; 168 | style.visuals.widgets.open.bg_stroke.color = self.ui_element_border_and_focus_rings; 169 | style.visuals.widgets.open.fg_stroke.color = self.high_contrast_text; 170 | style.visuals.extreme_bg_color = self.app_background; // e.g. TextEdit background 171 | style.visuals.faint_bg_color = self.app_background; // striped grid is originally from_additive_luminance(5) 172 | style.visuals.code_bg_color = self.ui_element_background; 173 | style.visuals.window_fill = self.subtle_background; 174 | style.visuals.window_stroke.color = self.subtle_borders_and_separators; 175 | style.visuals.panel_fill = self.subtle_background; 176 | style.visuals.hyperlink_color = self.hovered_solid_backgrounds; 177 | style.visuals.window_shadow.color = shadow; 178 | } 179 | } 180 | } 181 | 182 | /// A theme is basically a `[ThemeColor; 12]`. 183 | /// 184 | /// # Examples 185 | /// ``` 186 | /// use egui_colors::tokens::ThemeColor; 187 | /// let mut my_theme = [ThemeColor::Indigo; 12]; 188 | /// my_theme[11] = ThemeColor::Custom([23, 45, 77]); 189 | /// ``` 190 | #[derive(Default, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] 191 | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 192 | pub enum ThemeColor { 193 | #[default] 194 | Gray, 195 | EguiBlue, 196 | Tomato, 197 | Red, 198 | Ruby, 199 | Crimson, 200 | Pink, 201 | Plum, 202 | Purple, 203 | Violet, 204 | Iris, 205 | Indigo, 206 | Blue, 207 | Cyan, 208 | Teal, 209 | Jade, 210 | Green, 211 | Grass, 212 | Brown, 213 | Bronze, 214 | Gold, 215 | Orange, 216 | Custom([u8; 3]), 217 | } 218 | 219 | impl ThemeColor { 220 | pub(crate) fn get_srgb(self) -> LinSrgb { 221 | LinSrgb::into_linear(self.rgb()) 222 | } 223 | /// Returns the rgb values of this preset. 224 | /// 225 | /// Useful for example if you want to serialize the color theme. 226 | #[must_use] 227 | pub const fn rgb(&self) -> [u8; 3] { 228 | match *self { 229 | Self::Gray => [117, 117, 117], 230 | Self::EguiBlue => [0, 109, 143], 231 | Self::Tomato => [229, 77, 46], 232 | Self::Red => [229, 72, 77], 233 | Self::Ruby => [229, 70, 102], 234 | Self::Crimson => [233, 61, 130], 235 | Self::Pink => [214, 64, 159], 236 | Self::Plum => [171, 74, 186], 237 | Self::Purple => [142, 78, 198], 238 | Self::Violet => [110, 86, 207], 239 | Self::Iris => [91, 91, 214], 240 | Self::Indigo => [62, 99, 214], 241 | Self::Blue => [0, 144, 255], 242 | Self::Cyan => [0, 162, 199], 243 | Self::Teal => [18, 165, 148], 244 | Self::Jade => [41, 163, 131], 245 | Self::Green => [48, 164, 108], 246 | Self::Grass => [70, 167, 88], 247 | Self::Brown => [173, 127, 88], 248 | Self::Bronze => [161, 128, 114], 249 | Self::Gold => [151, 131, 101], 250 | Self::Orange => [247, 107, 21], 251 | Self::Custom([r, g, b]) => [r, g, b], 252 | } 253 | } 254 | #[allow(clippy::must_use_candidate)] 255 | pub const fn label(self) -> &'static str { 256 | match self { 257 | Self::Gray => "Gray", 258 | Self::EguiBlue => "EguiBlue", 259 | Self::Tomato => "Tomato", 260 | Self::Red => "Red", 261 | Self::Ruby => "Ruby", 262 | Self::Crimson => "Crimson", 263 | Self::Pink => "Pink", 264 | Self::Plum => "Plum", 265 | Self::Purple => "Purple", 266 | Self::Violet => "Violet", 267 | Self::Iris => "Iris", 268 | Self::Indigo => "Indigo", 269 | Self::Blue => "Blue", 270 | Self::Cyan => "Cyan", 271 | Self::Teal => "Teal", 272 | Self::Jade => "Jade", 273 | Self::Green => "Green", 274 | Self::Grass => "Grass", 275 | Self::Brown => "Brown", 276 | Self::Bronze => "Bronze", 277 | Self::Gold => "Gold", 278 | Self::Orange => "Orange", 279 | Self::Custom(_) => "Custom", 280 | } 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | use crate::{tokens::ThemeColor, Theme}; 2 | 3 | pub const VERMILLION: Theme = [ 4 | ThemeColor::Gold, 5 | ThemeColor::Gold, 6 | ThemeColor::Gold, 7 | ThemeColor::Gray, 8 | ThemeColor::Gray, 9 | ThemeColor::Gray, 10 | ThemeColor::Cyan, 11 | ThemeColor::Cyan, 12 | ThemeColor::Custom([232, 67, 0]), 13 | ThemeColor::Custom([232, 67, 0]), 14 | ThemeColor::Gray, 15 | ThemeColor::Cyan, 16 | ]; 17 | 18 | pub const EGUI_THEME: Theme = [ 19 | ThemeColor::Gray, 20 | ThemeColor::Gray, 21 | ThemeColor::Gray, 22 | ThemeColor::Gray, 23 | ThemeColor::Gray, 24 | ThemeColor::Gray, 25 | ThemeColor::Gray, 26 | ThemeColor::Gray, 27 | ThemeColor::EguiBlue, 28 | ThemeColor::EguiBlue, 29 | ThemeColor::Gray, 30 | ThemeColor::Gray, 31 | ]; 32 | 33 | pub const OFFICE_GRAY: Theme = [ 34 | ThemeColor::Custom([140, 149, 138]), 35 | ThemeColor::Custom([140, 149, 138]), 36 | ThemeColor::Custom([140, 149, 138]), 37 | ThemeColor::Custom([122, 166, 168]), 38 | ThemeColor::Gray, 39 | ThemeColor::Custom([122, 166, 168]), 40 | ThemeColor::Custom([122, 166, 168]), 41 | ThemeColor::Custom([122, 166, 168]), 42 | ThemeColor::Custom([59, 71, 97]), 43 | ThemeColor::Custom([59, 71, 97]), 44 | ThemeColor::Custom([185, 178, 168]), 45 | ThemeColor::Custom([185, 178, 168]), 46 | ]; 47 | 48 | pub const INDIGO_JADE: Theme = [ 49 | ThemeColor::Gray, 50 | ThemeColor::Gray, 51 | ThemeColor::Indigo, 52 | ThemeColor::Gray, 53 | ThemeColor::Gray, 54 | ThemeColor::Gray, 55 | ThemeColor::Gray, 56 | ThemeColor::Jade, 57 | ThemeColor::Jade, 58 | ThemeColor::Jade, 59 | ThemeColor::Gray, 60 | ThemeColor::Gray, 61 | ]; 62 | 63 | pub const GRASS_BRONZE: Theme = [ 64 | ThemeColor::Gray, 65 | ThemeColor::Gray, 66 | ThemeColor::Grass, 67 | ThemeColor::Bronze, 68 | ThemeColor::Bronze, 69 | ThemeColor::Gray, 70 | ThemeColor::Gray, 71 | ThemeColor::Green, 72 | ThemeColor::Bronze, 73 | ThemeColor::Bronze, 74 | ThemeColor::Gray, 75 | ThemeColor::Gray, 76 | ]; 77 | 78 | pub const WARM: Theme = [ 79 | ThemeColor::Gray, 80 | ThemeColor::Gray, 81 | ThemeColor::Orange, 82 | ThemeColor::Gold, 83 | ThemeColor::Gold, 84 | ThemeColor::Gold, 85 | ThemeColor::Red, 86 | ThemeColor::Red, 87 | ThemeColor::Gold, 88 | ThemeColor::Gold, 89 | ThemeColor::Gray, 90 | ThemeColor::Teal, 91 | ]; 92 | 93 | pub const COOL: Theme = [ 94 | ThemeColor::Gray, 95 | ThemeColor::Indigo, 96 | ThemeColor::Indigo, 97 | ThemeColor::Iris, 98 | ThemeColor::Indigo, 99 | ThemeColor::Gray, 100 | ThemeColor::Iris, 101 | ThemeColor::Indigo, 102 | ThemeColor::Blue, 103 | ThemeColor::Indigo, 104 | ThemeColor::Orange, 105 | ThemeColor::Gray, 106 | ]; 107 | 108 | pub const SEVENTIES: Theme = [ 109 | ThemeColor::Custom([95, 78, 163]), 110 | ThemeColor::Pink, 111 | ThemeColor::Pink, 112 | ThemeColor::Custom([95, 78, 163]), 113 | ThemeColor::Custom([95, 78, 163]), 114 | ThemeColor::Custom([254, 180, 0]), 115 | ThemeColor::Custom([95, 78, 163]), 116 | ThemeColor::Custom([95, 78, 163]), 117 | ThemeColor::Custom([254, 180, 0]), 118 | ThemeColor::Custom([254, 180, 0]), 119 | ThemeColor::Gray, 120 | ThemeColor::Gray, 121 | ]; 122 | 123 | pub const THEMES: [Theme; 8] = [ 124 | EGUI_THEME, 125 | INDIGO_JADE, 126 | GRASS_BRONZE, 127 | WARM, 128 | COOL, 129 | SEVENTIES, 130 | OFFICE_GRAY, 131 | VERMILLION, 132 | ]; 133 | 134 | pub(crate) const LABELS: [&str; 12] = [ 135 | "app background", 136 | "subtle background", 137 | "ui element background", 138 | "hovered ui element background", 139 | "active ui element background", 140 | "subtle borders and separators", 141 | "ui element border and focus rings", 142 | "hovered ui element border", 143 | "solid backgrounds", 144 | "hovered solid backgrounds", 145 | "low contrast text", 146 | "high contrast text", 147 | ]; 148 | 149 | pub(crate) const THEME_NAMES: [&str; 8] = [ 150 | "Egui", 151 | "Indigo/jade", 152 | "Grass/bronze", 153 | "Warm", 154 | "Cool", 155 | "Seventies", 156 | "Office Gray", 157 | "Vermillion", 158 | ]; 159 | --------------------------------------------------------------------------------