mirror of
https://github.com/storytold/soundcraft.git
synced 2026-10-27 12:06:51 -06:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fb33855dc |
Generated
+18
-226
@@ -753,15 +753,6 @@ dependencies = [
|
||||
"error-code",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
|
||||
dependencies = [
|
||||
"thiserror 2.0.21",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.13.1"
|
||||
@@ -943,40 +934,12 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "craft-docpath"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0"
|
||||
|
||||
[[package]]
|
||||
name = "craft-fonts-build"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0"
|
||||
|
||||
[[package]]
|
||||
name = "craft-i18n"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0"
|
||||
dependencies = [
|
||||
"fixed_decimal",
|
||||
"icu_decimal",
|
||||
"icu_locale_core",
|
||||
"icu_locale_fallback",
|
||||
"icu_normalizer",
|
||||
"icu_plurals",
|
||||
"icu_properties",
|
||||
"icu_provider",
|
||||
"icu_provider_adapters",
|
||||
"icu_provider_blob",
|
||||
"log",
|
||||
"objc2-foundation 0.3.2",
|
||||
"sys-locale",
|
||||
"unicode-bidi",
|
||||
"windows-registry",
|
||||
"writeable",
|
||||
]
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=db19c373c8d59a545972ca340987aecfb3611a4b#db19c373c8d59a545972ca340987aecfb3611a4b"
|
||||
|
||||
[[package]]
|
||||
name = "craft-media"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=db19c373c8d59a545972ca340987aecfb3611a4b#db19c373c8d59a545972ca340987aecfb3611a4b"
|
||||
dependencies = [
|
||||
"thiserror 2.0.21",
|
||||
]
|
||||
@@ -984,28 +947,20 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "craft-ui"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=db19c373c8d59a545972ca340987aecfb3611a4b#db19c373c8d59a545972ca340987aecfb3611a4b"
|
||||
dependencies = [
|
||||
"craft-fonts-build",
|
||||
"craft-i18n",
|
||||
"egui",
|
||||
"epaint",
|
||||
"js-sys",
|
||||
"log",
|
||||
"objc2 0.6.5",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-foundation 0.3.2",
|
||||
"serde",
|
||||
"skrifa",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "craft-update"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=db19c373c8d59a545972ca340987aecfb3611a4b#db19c373c8d59a545972ca340987aecfb3611a4b"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"dunce",
|
||||
@@ -1505,17 +1460,6 @@ version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48"
|
||||
|
||||
[[package]]
|
||||
name = "fixed_decimal"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2214fb00f669ee96bee5bb29dfb1ddabe058b2bc426817efc79afa03c9bc55ae"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"smallvec",
|
||||
"writeable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.5.7"
|
||||
@@ -1943,9 +1887,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||
|
||||
[[package]]
|
||||
name = "icu_collections"
|
||||
version = "2.3.0"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513"
|
||||
checksum = "fe090a42a0d3140fed8c63263ed1fecc02422cb2f4bfe55cd8de2de1b8e105dd"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"potential_utf",
|
||||
@@ -1955,111 +1899,44 @@ dependencies = [
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_decimal"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9eb8f655bba2d0c0459e43a5b0e6cd3cd388109898fb3d85d048165e8b0abd08"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"fixed_decimal",
|
||||
"icu_locale_core",
|
||||
"icu_pattern",
|
||||
"icu_plurals",
|
||||
"icu_provider",
|
||||
"serde",
|
||||
"writeable",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locale_core"
|
||||
version = "2.3.0"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb"
|
||||
checksum = "25d29b57c17c6528d0dc4c2141cfa2d08200465acb537a3909c8b9b8a4a984c0"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"litemap",
|
||||
"serde",
|
||||
"tinystr",
|
||||
"writeable",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locale_fallback"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "251af8e57c9400e3eb58242fe5b8b1152b2a64fdf4cf632f923c38ccee6f2fa9"
|
||||
dependencies = [
|
||||
"icu_locale_core",
|
||||
"icu_locale_fallback_data",
|
||||
"icu_provider",
|
||||
"potential_utf",
|
||||
"tinystr",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_locale_fallback_data"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "decf2a22ec8fa68f1a0c1129a3f8583f8f8bc24e8b9ccbe98ead99f62a4dc3a8"
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer"
|
||||
version = "2.3.0"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f"
|
||||
checksum = "404a3b8c486f205c87fe7f23ab6894d84a4ad76d6e4671ae1981ba7def87c599"
|
||||
dependencies = [
|
||||
"icu_collections",
|
||||
"icu_normalizer_data",
|
||||
"icu_properties",
|
||||
"icu_provider",
|
||||
"smallvec",
|
||||
"utf16_iter",
|
||||
"utf8_iter",
|
||||
"write16",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_normalizer_data"
|
||||
version = "2.3.0"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0"
|
||||
|
||||
[[package]]
|
||||
name = "icu_pattern"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc43ce0e76ee8cb0482dc6e2dbb9b76278e8038f45daabf2a2877577e2ceb18f"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"either",
|
||||
"serde",
|
||||
"writeable",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_plurals"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e475e6766ef87b1d3c1f97be6363995b0bfaeddbc789671615df598a97ff0593"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"fixed_decimal",
|
||||
"icu_provider",
|
||||
"serde",
|
||||
"zerovec",
|
||||
]
|
||||
checksum = "20f0088bfb7441f7a37fa0c9e20cb1e9cba1cac6b9ce8cd2a6dc44294f8e8cbc"
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties"
|
||||
version = "2.3.0"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148"
|
||||
checksum = "2ea83d991c56158f7cf898bf86436c1dfe7c07ee82fe88951f2695c9f37a379f"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_collections",
|
||||
@@ -2072,21 +1949,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "icu_properties_data"
|
||||
version = "2.3.0"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa"
|
||||
checksum = "b98f29af82d02b163fe50161388350e743bb3107cc8e8c2f7314cb505faddfcf"
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider"
|
||||
version = "2.3.1"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73"
|
||||
checksum = "413099315636c588ee8f011190b329b971a09a8fae9d157e01dcae8379468514"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"icu_locale_core",
|
||||
"postcard",
|
||||
"serde",
|
||||
"stable_deref_trait",
|
||||
"writeable",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
@@ -2094,30 +1968,6 @@ dependencies = [
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider_adapters"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df887bc4f55dbc773c7c45a0c7dfa75be886f7b7812830a71ab7271cc1801820"
|
||||
dependencies = [
|
||||
"icu_locale_fallback",
|
||||
"icu_provider",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icu_provider_blob"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5916b44fac319d3f58e4d8d805a627df19e27937b582cd99fcde3bb6b7ce1b0e"
|
||||
dependencies = [
|
||||
"icu_provider",
|
||||
"postcard",
|
||||
"serde",
|
||||
"writeable",
|
||||
"zerotrie",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "1.1.0"
|
||||
@@ -2409,9 +2259,6 @@ name = "litemap"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
@@ -3341,24 +3188,12 @@ dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "postcard"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
|
||||
dependencies = [
|
||||
"cobs",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "potential_utf"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"writeable",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
@@ -4652,18 +4487,6 @@ dependencies = [
|
||||
"syn 3.0.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys-locale"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.46"
|
||||
@@ -4787,7 +4610,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abc840c238154d58f9e86b2792261edfde565a17696e1cda1a449de27979801a"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"serde_core",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
@@ -5025,12 +4847,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf16_iter"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
|
||||
|
||||
[[package]]
|
||||
name = "utf8-zero"
|
||||
version = "0.8.1"
|
||||
@@ -5657,17 +5473,6 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-registry"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.4.1"
|
||||
@@ -5895,20 +5700,11 @@ dependencies = [
|
||||
"wayland-protocols-wlr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "write16"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11-dl"
|
||||
@@ -6163,11 +5959,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"litemap",
|
||||
"serde_core",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6176,7 +5969,6 @@ version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f58a2799cfe9a1670c7ea8edbd52ef8edb93cb37a7f83bf31ba9e35d9dae6a40"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"yoke",
|
||||
"zerofrom",
|
||||
"zerovec-derive",
|
||||
|
||||
+7
-5
@@ -45,14 +45,14 @@ zip = { version = "9", default-features = false }
|
||||
cpal = "0.18"
|
||||
|
||||
# Which file paths stored in a session may be opened.
|
||||
craft-docpath = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0" }
|
||||
craft-docpath = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "db19c373c8d59a545972ca340987aecfb3611a4b" }
|
||||
|
||||
# Video containers and bitstreams, shared with the other craft apps.
|
||||
craft-media = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0" }
|
||||
craft-update = { version = "=0.1.0", git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0", features = ["egui"] }
|
||||
craft-media = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "db19c373c8d59a545972ca340987aecfb3611a4b" }
|
||||
craft-update = { version = "=0.1.0", git = "https://github.com/storytold/craft-libs", rev = "db19c373c8d59a545972ca340987aecfb3611a4b", features = ["egui"] }
|
||||
|
||||
# ui
|
||||
craft-ui = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0", features = ["serde"] }
|
||||
craft-ui = { version = "0.1.0", git = "https://github.com/storytold/craft-libs", rev = "db19c373c8d59a545972ca340987aecfb3611a4b", features = ["serde"] }
|
||||
egui = { version = "0.37" }
|
||||
eframe = { version = "0.37", default-features = false }
|
||||
# Monotonic clock on native and the browser (the `web_time::Instant` panics-free equivalent).
|
||||
@@ -65,9 +65,11 @@ image = { version = "0.25", default-features = false, features = ["png"] }
|
||||
unsafe_code = "forbid"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
cognitive_complexity = "deny"
|
||||
wildcard_imports = "deny"
|
||||
dbg_macro = "warn"
|
||||
todo = "warn"
|
||||
too_many_arguments = "allow"
|
||||
too_many_arguments = "deny"
|
||||
type_complexity = "allow"
|
||||
|
||||
[profile.dev.package."*"]
|
||||
|
||||
+1
-4
@@ -2,7 +2,4 @@ allow-unwrap-in-tests = true
|
||||
allow-expect-in-tests = true
|
||||
allow-panic-in-tests = true
|
||||
allow-indexing-slicing-in-tests = true
|
||||
|
||||
disallowed-types = [
|
||||
{ path = "egui::ComboBox", reason = "use craft_ui::ComboBox: egui's combo box menu can't grow back while open (egui#5225)" },
|
||||
]
|
||||
cognitive-complexity-threshold = 30
|
||||
|
||||
@@ -20,7 +20,9 @@ log.workspace = true
|
||||
unsafe_code = "deny"
|
||||
|
||||
[lints.clippy]
|
||||
cognitive_complexity = "deny"
|
||||
wildcard_imports = "deny"
|
||||
dbg_macro = "warn"
|
||||
todo = "warn"
|
||||
too_many_arguments = "allow"
|
||||
too_many_arguments = "deny"
|
||||
type_complexity = "allow"
|
||||
|
||||
@@ -32,7 +32,9 @@ libloading = "0.9"
|
||||
unsafe_code = "deny"
|
||||
|
||||
[lints.clippy]
|
||||
cognitive_complexity = "deny"
|
||||
wildcard_imports = "deny"
|
||||
dbg_macro = "warn"
|
||||
todo = "warn"
|
||||
too_many_arguments = "allow"
|
||||
too_many_arguments = "deny"
|
||||
type_complexity = "allow"
|
||||
|
||||
@@ -221,7 +221,7 @@ fn contributors_toolbar(ui: &mut egui::Ui, v: &mut View) {
|
||||
}
|
||||
ui.separator();
|
||||
let sort = ui.label("Sort");
|
||||
let combo = craft_ui::ComboBox::from_id_salt("credits_sort").selected_text(v.key.label().0).show_ui(ui, |ui| {
|
||||
let combo = egui::ComboBox::from_id_salt("credits_sort").selected_text(v.key.label().0).show_ui(ui, |ui| {
|
||||
for k in SortKey::ALL {
|
||||
if ui.selectable_label(v.key == k, k.label().0).clicked() {
|
||||
v.key = k;
|
||||
|
||||
@@ -331,13 +331,13 @@ pub fn show(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
let create = ui.label("Create");
|
||||
ui.add(egui::DragValue::new(count).range(1..=128)).labelled_by(create.id);
|
||||
ui.label("new");
|
||||
let fmt = craft_ui::ComboBox::from_id_salt("nt_fmt").selected_text(format.as_str()).show_ui(ui, |ui| {
|
||||
let fmt = egui::ComboBox::from_id_salt("nt_fmt").selected_text(format.as_str()).show_ui(ui, |ui| {
|
||||
for f in soundcraft_model::ChannelFormat::ALL {
|
||||
ui.selectable_value(format, f.label().to_string(), f.label());
|
||||
}
|
||||
});
|
||||
fmt.response.accessible_name("Channel format");
|
||||
let kind_combo = craft_ui::ComboBox::from_id_salt("nt_kind")
|
||||
let kind_combo = egui::ComboBox::from_id_salt("nt_kind")
|
||||
.selected_text(soundcraft_model::TrackKind::from_id(kind).map_or("Audio Track", |k| k.label()))
|
||||
.show_ui(ui, |ui| {
|
||||
for k in soundcraft_model::TrackKind::ALL {
|
||||
@@ -349,7 +349,7 @@ pub fn show(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
});
|
||||
kind_combo.response.accessible_name("Track kind");
|
||||
ui.label("in");
|
||||
let tb = craft_ui::ComboBox::from_id_salt("nt_tb").selected_text(if timebase == "ticks" { "Ticks" } else { "Samples" }).show_ui(
|
||||
let tb = egui::ComboBox::from_id_salt("nt_tb").selected_text(if timebase == "ticks" { "Ticks" } else { "Samples" }).show_ui(
|
||||
ui,
|
||||
|ui| {
|
||||
ui.selectable_value(timebase, "samples".to_string(), "Samples");
|
||||
@@ -372,7 +372,7 @@ pub fn show(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
ui.label("Name");
|
||||
crate::widgets::named_text_field(ui.text_edit_singleline(name), "Name");
|
||||
});
|
||||
craft_ui::ComboBox::from_label("Sample Rate").selected_text(format!("{sample_rate} Hz")).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Sample Rate").selected_text(format!("{sample_rate} Hz")).show_ui(ui, |ui| {
|
||||
for r in soundcraft_time::SampleRate::COMMON {
|
||||
ui.selectable_value(sample_rate, r, format!("{r} Hz"));
|
||||
}
|
||||
@@ -403,12 +403,12 @@ pub fn show(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
}
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
craft_ui::ComboBox::from_label("Format").selected_text(format.to_uppercase()).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Format").selected_text(format.to_uppercase()).show_ui(ui, |ui| {
|
||||
for f in ["wav", "aiff", "flac"] {
|
||||
ui.selectable_value(format, f.to_string(), f.to_uppercase());
|
||||
}
|
||||
});
|
||||
craft_ui::ComboBox::from_label("Bit Depth").selected_text(format!("{bit_depth}-bit")).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Bit Depth").selected_text(format!("{bit_depth}-bit")).show_ui(ui, |ui| {
|
||||
for b in ["16", "24", "32f"] {
|
||||
ui.selectable_value(bit_depth, b.to_string(), format!("{b}-bit"));
|
||||
}
|
||||
@@ -621,12 +621,12 @@ pub fn show(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
}
|
||||
}
|
||||
Dialog::Session { frame_rate, bit_depth } => {
|
||||
craft_ui::ComboBox::from_label("Timecode Rate").selected_text(frame_rate.as_str()).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Timecode Rate").selected_text(frame_rate.as_str()).show_ui(ui, |ui| {
|
||||
for r in soundcraft_time::FrameRate::ALL {
|
||||
ui.selectable_value(frame_rate, r.label().to_string(), r.label());
|
||||
}
|
||||
});
|
||||
craft_ui::ComboBox::from_label("Bit Depth").selected_text(bit_depth.as_str()).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Bit Depth").selected_text(bit_depth.as_str()).show_ui(ui, |ui| {
|
||||
for b in ["16", "24", "32f"] {
|
||||
ui.selectable_value(bit_depth, b.to_string(), b);
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ fn tempo_ops(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
return;
|
||||
}
|
||||
egui::Window::new("Tempo Operations").open(&mut open).default_size(vec2(360.0, 200.0)).show(ctx, |ui| {
|
||||
craft_ui::ComboBox::from_label("Curve").selected_text(app.ops.tempo_curve.clone()).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Curve").selected_text(app.ops.tempo_curve.clone()).show_ui(ui, |ui| {
|
||||
for c in ["constant", "linear", "parabolic", "s-curve", "scale", "stretch"] {
|
||||
ui.selectable_value(&mut app.ops.tempo_curve, c.to_string(), c);
|
||||
}
|
||||
@@ -183,7 +183,7 @@ fn time_ops(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
return;
|
||||
}
|
||||
egui::Window::new("Time Operations").open(&mut open).default_size(vec2(360.0, 200.0)).show(ctx, |ui| {
|
||||
craft_ui::ComboBox::from_label("Operation").selected_text(app.ops.time_op.clone()).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Operation").selected_text(app.ops.time_op.clone()).show_ui(ui, |ui| {
|
||||
for c in ["insert", "cut", "change meter", "move song start"] {
|
||||
ui.selectable_value(&mut app.ops.time_op, c.to_string(), c);
|
||||
}
|
||||
@@ -193,7 +193,7 @@ fn time_ops(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
ui.horizontal(|ui| {
|
||||
ui.add(egui::DragValue::new(&mut app.ops.meter_num).range(1..=64)).accessible_name("Meter numerator");
|
||||
ui.label("/");
|
||||
let den = craft_ui::ComboBox::from_id_salt("den").selected_text(app.ops.meter_den.to_string()).show_ui(ui, |ui| {
|
||||
let den = egui::ComboBox::from_id_salt("den").selected_text(app.ops.meter_den.to_string()).show_ui(ui, |ui| {
|
||||
for d in [2u32, 4, 8, 16] {
|
||||
ui.selectable_value(&mut app.ops.meter_den, d, d.to_string());
|
||||
}
|
||||
@@ -228,14 +228,14 @@ fn midi_ops(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
return;
|
||||
}
|
||||
egui::Window::new("MIDI Operations").open(&mut open).default_size(vec2(360.0, 220.0)).show(ctx, |ui| {
|
||||
craft_ui::ComboBox::from_label("Operation").selected_text(app.ops.midi_op.clone()).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Operation").selected_text(app.ops.midi_op.clone()).show_ui(ui, |ui| {
|
||||
for c in ["quantize", "transpose", "change velocity", "flatten performance", "restore performance"] {
|
||||
ui.selectable_value(&mut app.ops.midi_op, c.to_string(), c);
|
||||
}
|
||||
});
|
||||
match app.ops.midi_op.as_str() {
|
||||
"quantize" => {
|
||||
craft_ui::ComboBox::from_label("Grid").selected_text(app.ops.quant_grid.clone()).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Grid").selected_text(app.ops.quant_grid.clone()).show_ui(ui, |ui| {
|
||||
for g in ["1/4", "1/8", "1/8t", "1/16", "1/16t", "1/32"] {
|
||||
ui.selectable_value(&mut app.ops.quant_grid, g.to_string(), g);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ fn original_time_stamp_row(ui: &mut Ui, s: &Session, d: &mut Spot, at: Samples)
|
||||
pub fn fields(ui: &mut Ui, s: &Session, d: &mut Spot) {
|
||||
egui::Grid::new("spot").num_columns(2).spacing(vec2(10.0, 6.0)).show(ui, |ui| {
|
||||
let scale = ui.label("Time Scale");
|
||||
let time_scale = craft_ui::ComboBox::from_id_salt("spot_scale").selected_text(d.format.label()).show_ui(ui, |ui| {
|
||||
let time_scale = egui::ComboBox::from_id_salt("spot_scale").selected_text(d.format.label()).show_ui(ui, |ui| {
|
||||
for f in TimeFormat::ALL {
|
||||
ui.selectable_value(&mut d.format, f, f.label());
|
||||
}
|
||||
|
||||
@@ -197,24 +197,7 @@ impl MenuSearch {
|
||||
|
||||
/// `n` matches in a scrolling list, each drawn by `row` (told whether it is highlighted);
|
||||
/// returns the one clicked, or the highlighted one on Enter.
|
||||
pub(super) fn rows(&self, ui: &mut Ui, n: usize, max_height: f32, row: impl FnMut(&mut Ui, usize, bool) -> bool) -> Option<usize> {
|
||||
let row_h = ui.spacing().interact_size.y;
|
||||
egui::ScrollArea::vertical()
|
||||
.id_salt(self.id.with("rows"))
|
||||
.max_height(max_height)
|
||||
.show_rows(ui, row_h, n, |ui, range| self.list_rows(ui, range, n, row))
|
||||
.inner
|
||||
}
|
||||
|
||||
/// The rows of `range` out of `n` matches, drawn into a list that scrolls and virtualises
|
||||
/// itself (a shared dropdown menu's list); `rows` is the same list in a scroll area of its own.
|
||||
pub(super) fn list_rows(
|
||||
&self,
|
||||
ui: &mut Ui,
|
||||
range: std::ops::Range<usize>,
|
||||
n: usize,
|
||||
mut row: impl FnMut(&mut Ui, usize, bool) -> bool,
|
||||
) -> Option<usize> {
|
||||
pub(super) fn rows(&self, ui: &mut Ui, n: usize, max_height: f32, mut row: impl FnMut(&mut Ui, usize, bool) -> bool) -> Option<usize> {
|
||||
let [up, down, enter] = self.keys;
|
||||
let typing = self.typing();
|
||||
let highlight = match (up, down) {
|
||||
@@ -227,15 +210,17 @@ impl MenuSearch {
|
||||
let mut picked = (typing && enter && n > 0).then_some(highlight);
|
||||
let row_h = ui.spacing().interact_size.y;
|
||||
let step = row_h + ui.spacing().item_spacing.y;
|
||||
if typing && (up || down) {
|
||||
let top = ui.max_rect().top() + (highlight as f32 - range.start as f32) * step;
|
||||
ui.scroll_to_rect(Rect::from_min_size(pos2(ui.max_rect().left(), top), vec2(1.0, row_h)), None);
|
||||
}
|
||||
for i in range {
|
||||
if row(ui, i, typing && i == highlight) {
|
||||
picked = Some(i);
|
||||
egui::ScrollArea::vertical().id_salt(self.id.with("rows")).max_height(max_height).show_rows(ui, row_h, n, |ui, range| {
|
||||
if typing && (up || down) {
|
||||
let top = ui.max_rect().top() + (highlight as f32 - range.start as f32) * step;
|
||||
ui.scroll_to_rect(Rect::from_min_size(pos2(ui.max_rect().left(), top), vec2(1.0, row_h)), None);
|
||||
}
|
||||
}
|
||||
for i in range {
|
||||
if row(ui, i, typing && i == highlight) {
|
||||
picked = Some(i);
|
||||
}
|
||||
}
|
||||
});
|
||||
picked
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ use super::plugin_menu::{MenuSearch, menu_row};
|
||||
use super::routing::route_name;
|
||||
use super::slots::{COMPACT_SLOT, Mark, empty_slot, level_icon, used_slot};
|
||||
use super::*;
|
||||
use craft_ui::combo::Menu;
|
||||
|
||||
/// Draw one send slot: the route area picks a destination, while the level area opens or edits the send level.
|
||||
pub(crate) fn send_slot(app: &mut SoundApp, ui: &mut Ui, track: &Track, slot: usize, r: Rect) {
|
||||
@@ -54,8 +53,30 @@ pub(crate) fn send_slot(app: &mut SoundApp, ui: &mut Ui, track: &Track, slot: us
|
||||
}
|
||||
None => empty_slot(ui.painter(), r, ui.rect_contains_pointer(r), mark),
|
||||
}
|
||||
let current = snd.as_ref().map(|send| (send.target.clone(), route_name(app, &send.target)));
|
||||
send_route_menu(app, ui, &route_resp, id, slot, current);
|
||||
if let Some(send) = &snd {
|
||||
egui::Popup::menu(&route_resp).close_behavior(egui::PopupCloseBehavior::CloseOnClickOutside).show(|ui| {
|
||||
ui.set_min_width(250.0);
|
||||
ui.horizontal(|ui| {
|
||||
ui.strong(format!("Send {}", (b'A' + slot as u8) as char));
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||
ui.label(egui::RichText::new(route_name(app, &send.target)).color(Tokens::current().counter_text));
|
||||
});
|
||||
});
|
||||
ui.label(egui::RichText::new("DESTINATION").size(8.0).color(Tokens::current().text_dim));
|
||||
send_route_menu(app, ui, id, slot, Some(&send.target));
|
||||
ui.separator();
|
||||
if ui.button("Remove send").clicked() {
|
||||
let _ = app.run("mix.send_remove", json!({"track": id.0, "slot": slot}));
|
||||
ui.close();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
egui::Popup::menu(&route_resp).close_behavior(egui::PopupCloseBehavior::CloseOnClickOutside).show(|ui| {
|
||||
ui.set_min_width(250.0);
|
||||
ui.strong(format!("Send {} · Choose destination", (b'A' + slot as u8) as char));
|
||||
send_route_menu(app, ui, id, slot, None);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// The Send window, as in Pro Tools: one send's fader, level, pan, Mute and Pre-fader. Clicking a
|
||||
@@ -320,143 +341,30 @@ fn send_level_scale(ui: &mut Ui, db: f32) {
|
||||
ui.painter().line_segment([pos2(x, r.min.y), pos2(x, line_y + 3.0)], Stroke::new(2.0, t.counter_text));
|
||||
}
|
||||
|
||||
/// What the send menu's footer was used for.
|
||||
enum SendFooter {
|
||||
NewBus,
|
||||
RemoveSend,
|
||||
}
|
||||
|
||||
/// The send's destination menu: a title and the bus search on top, the matching buses in a list
|
||||
/// that scrolls, "new bus..." (and "Remove send" for an existing send) fixed under it.
|
||||
/// `current` is the send's destination and its name, if the slot has a send.
|
||||
fn send_route_menu(app: &mut SoundApp, ui: &Ui, field: &egui::Response, id: TrackId, slot: usize, current: Option<(Route, String)>) {
|
||||
/// Searchable bus destination list with a New Bus action for a send.
|
||||
fn send_route_menu(app: &mut SoundApp, ui: &mut Ui, id: TrackId, slot: usize, current: Option<&Route>) {
|
||||
let busses = app.engine.session().busses.clone();
|
||||
let which = (b'A' + slot as u8) as char;
|
||||
let has_send = current.is_some();
|
||||
let header = |ui: &mut Ui| {
|
||||
ui.set_min_width(250.0);
|
||||
match ¤t {
|
||||
Some((_, name)) => {
|
||||
ui.horizontal(|ui| {
|
||||
ui.strong(format!("Send {which}"));
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
|
||||
ui.label(egui::RichText::new(name).color(Tokens::current().counter_text));
|
||||
});
|
||||
});
|
||||
ui.label(egui::RichText::new("DESTINATION").size(8.0).color(Tokens::current().text_dim));
|
||||
}
|
||||
None => {
|
||||
ui.strong(format!("Send {which} · Choose destination"));
|
||||
}
|
||||
}
|
||||
let search = MenuSearch::show(ui, egui::Id::unique(("send-bus-search", id.0, slot)), "Search buses…");
|
||||
let visible: Vec<_> = busses.iter().filter(|bus| search.matches(&bus.name)).collect();
|
||||
(search, visible)
|
||||
};
|
||||
let target = current.as_ref().map(|(route, _)| route);
|
||||
let row_h = ui.spacing().interact_size.y;
|
||||
let shown = Menu::new(ui, field).height(260.0).close_behavior(egui::PopupCloseBehavior::CloseOnClickOutside).show_rows_with_header_footer(
|
||||
header,
|
||||
row_h,
|
||||
|(_, visible)| visible.len(),
|
||||
|ui, range, (search, visible)| {
|
||||
let n = visible.len();
|
||||
let picked = search.list_rows(ui, range, n, |ui, i, highlighted| {
|
||||
let is_current = matches!(target, Some(Route::Bus(bus_id)) if *bus_id == visible[i].id);
|
||||
menu_row(ui, highlighted || (is_current && !search.typing()), &visible[i].name)
|
||||
});
|
||||
picked.map(|i| {
|
||||
ui.close();
|
||||
visible[i].name.clone()
|
||||
})
|
||||
},
|
||||
|ui| {
|
||||
if ui.button("new bus...").clicked() {
|
||||
ui.close();
|
||||
return Some(SendFooter::NewBus);
|
||||
}
|
||||
if has_send && ui.button("Remove send").clicked() {
|
||||
ui.close();
|
||||
return Some(SendFooter::RemoveSend);
|
||||
}
|
||||
None
|
||||
},
|
||||
);
|
||||
let Some((picked, footer)) = shown else { return };
|
||||
if let Some(bus) = picked {
|
||||
let _ = app.run("mix.send", json!({"track": id.0, "slot": slot, "bus": bus}));
|
||||
let search = MenuSearch::show(ui, egui::Id::unique(("send-bus-search", id.0, slot)), "Search buses…");
|
||||
let visible: Vec<_> = busses.iter().filter(|bus| search.matches(&bus.name)).collect();
|
||||
let picked = search.rows(ui, visible.len(), 260.0, |ui, i, highlighted| {
|
||||
let current = matches!(current, Some(Route::Bus(bus_id)) if *bus_id == visible[i].id);
|
||||
menu_row(ui, highlighted || (current && !search.typing()), &visible[i].name)
|
||||
});
|
||||
if let Some(i) = picked {
|
||||
let _ = app.run("mix.send", json!({"track": id.0, "slot": slot, "bus": visible[i].name}));
|
||||
ui.close();
|
||||
}
|
||||
match footer {
|
||||
Some(SendFooter::NewBus) => {
|
||||
let mut n = busses.len() + 1;
|
||||
while busses.iter().any(|bus| bus.name.eq_ignore_ascii_case(&format!("Bus {n}")))
|
||||
|| app.engine.session().track_by_name(&format!("Bus {n}")).is_some()
|
||||
{
|
||||
n += 1;
|
||||
}
|
||||
if app.run("mix.new_bus", json!({"name": format!("Bus {n}")})).is_ok() {
|
||||
let _ = app.run("mix.send", json!({"track": id.0, "slot": slot, "bus": format!("Bus {n}")}));
|
||||
}
|
||||
ui.separator();
|
||||
if ui.button("new bus...").clicked() {
|
||||
let mut n = busses.len() + 1;
|
||||
while busses.iter().any(|bus| bus.name.eq_ignore_ascii_case(&format!("Bus {n}")))
|
||||
|| app.engine.session().track_by_name(&format!("Bus {n}")).is_some()
|
||||
{
|
||||
n += 1;
|
||||
}
|
||||
Some(SendFooter::RemoveSend) => {
|
||||
let _ = app.run("mix.send_remove", json!({"track": id.0, "slot": slot}));
|
||||
if app.run("mix.new_bus", json!({"name": format!("Bus {n}")})).is_ok() {
|
||||
let _ = app.run("mix.send", json!({"track": id.0, "slot": slot, "bus": format!("Bus {n}")}));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::Services;
|
||||
use egui_kittest::{Harness, kittest::Queryable};
|
||||
|
||||
/// Filtering the destination list to nothing shrinks the menu; clearing the filter grows it
|
||||
/// back, with the search field in the same place and the footer under the list.
|
||||
#[test]
|
||||
fn the_send_destination_menu_grows_back_when_the_search_is_cleared() {
|
||||
let mut app = SoundApp::new(soundcraft_engine::demo::demo_engine(), None, Services::default());
|
||||
for n in 0..30 {
|
||||
app.run("mix.new_bus", json!({"name": format!("Aux {n}")})).unwrap();
|
||||
}
|
||||
let kick = app.engine.session().track_by_name("Kick").unwrap().id;
|
||||
app.run("mix.send", json!({"track": kick.0, "slot": 0, "bus": "Aux 0"})).unwrap();
|
||||
let _palette = crate::theme::lock_test_palette();
|
||||
let mut ready = false;
|
||||
let mut h = Harness::builder().with_size(vec2(600.0, 800.0)).build_ui_state(
|
||||
move |ui, (app, kick): &mut (SoundApp, TrackId)| {
|
||||
if !ready {
|
||||
crate::fonts::install(ui.ctx());
|
||||
crate::theme::apply(ui.ctx(), false);
|
||||
ready = true;
|
||||
return;
|
||||
}
|
||||
let track = app.engine.session().track(*kick).cloned().unwrap();
|
||||
let r = Rect::from_min_size(ui.max_rect().min + vec2(20.0, 20.0), vec2(120.0, 24.0));
|
||||
send_slot(app, ui, &track, 0, r);
|
||||
},
|
||||
(app, kick),
|
||||
);
|
||||
h.run();
|
||||
h.get_by_label("Send A for Kick").click();
|
||||
h.run();
|
||||
let field = |h: &Harness<'_, (SoundApp, TrackId)>| h.get_by_role(egui::accesskit::Role::TextInput).rect();
|
||||
let footer = |h: &Harness<'_, (SoundApp, TrackId)>| h.get_by_label("Remove send").rect();
|
||||
let (search, full) = (field(&h), footer(&h));
|
||||
assert!(h.query_by_label("new bus...").is_some(), "the footer lists new bus...");
|
||||
assert!(full.top() > search.bottom() + 150.0, "the list sits between the search and the footer: {search:?} {full:?}");
|
||||
|
||||
h.get_by_role(egui::accesskit::Role::TextInput).type_text("zzzz");
|
||||
h.run();
|
||||
let none = footer(&h);
|
||||
assert!(none.top() < full.top() - 100.0, "no matches shrink the menu: {none:?} vs {full:?}");
|
||||
assert_eq!(field(&h), search, "the search field stays put");
|
||||
|
||||
for _ in 0..4 {
|
||||
h.key_press(egui::Key::Backspace);
|
||||
h.run();
|
||||
}
|
||||
assert_eq!(field(&h), search, "the search field stays put");
|
||||
assert!((footer(&h).top() - full.top()).abs() < 1.0, "cleared, the footer is back under the full list: {:?} vs {full:?}", footer(&h));
|
||||
ui.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ fn ui_customization(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
);
|
||||
crate::widgets::checkbox(ui, &mut app.extra.reduce_motion, "Reduce motion");
|
||||
let mut chosen = None;
|
||||
craft_ui::ComboBox::from_label("Theme").selected_text(app.ui.theme.label()).show_ui(ui, |ui| {
|
||||
egui::ComboBox::from_label("Theme").selected_text(app.ui.theme.label()).show_ui(ui, |ui| {
|
||||
for mode in crate::theme::ThemeMode::ALL {
|
||||
if ui.selectable_label(app.ui.theme == mode, mode.label()).clicked() {
|
||||
chosen = Some(mode);
|
||||
|
||||
@@ -70,7 +70,7 @@ pub(super) fn plugin_windows(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
let mut x = v;
|
||||
let resp = if !p.choices.is_empty() {
|
||||
let mut idx = x.round().max(0.0) as usize;
|
||||
let r = craft_ui::ComboBox::from_id_salt(("pc", tid.0, slot, p.id))
|
||||
let r = egui::ComboBox::from_id_salt(("pc", tid.0, slot, p.id))
|
||||
.selected_text(p.choices.get(idx).copied().unwrap_or("?"))
|
||||
.show_ui(ui, |ui| {
|
||||
for (i, c) in p.choices.iter().enumerate() {
|
||||
|
||||
@@ -452,7 +452,7 @@ fn chosen_device<'a>(devices: &'a [DeviceInfo], name: Option<&str>) -> Option<&'
|
||||
fn device_combo(ui: &mut egui::Ui, id: &str, name: &str, value: &mut Option<String>, devices: &[DeviceInfo]) {
|
||||
let default = devices.iter().find(|d| d.is_default).map_or("none".to_string(), |d| d.name.clone());
|
||||
let shown = value.clone().unwrap_or_else(|| format!("Default ({default})"));
|
||||
let combo = craft_ui::ComboBox::from_id_salt(id).width(300.0).selected_text(shown).show_ui(ui, |ui| {
|
||||
let combo = egui::ComboBox::from_id_salt(id).width(300.0).selected_text(shown).show_ui(ui, |ui| {
|
||||
ui.selectable_value(value, None, format!("Default ({default})"));
|
||||
for d in devices {
|
||||
ui.selectable_value(value, Some(d.name.clone()), format!("{} ({} ch)", d.name, d.max_channels));
|
||||
@@ -464,7 +464,7 @@ fn device_combo(ui: &mut egui::Ui, id: &str, name: &str, value: &mut Option<Stri
|
||||
/// Optional-number picker with a Device default entry and a unit, labelled for accessibility.
|
||||
fn number_combo(ui: &mut egui::Ui, id: &str, name: &str, value: &mut Option<u32>, options: &[u32], unit: &str) {
|
||||
let shown = value.map_or("Device default".to_string(), |v| format!("{v} {unit}"));
|
||||
let combo = craft_ui::ComboBox::from_id_salt(id).width(300.0).selected_text(shown).show_ui(ui, |ui| {
|
||||
let combo = egui::ComboBox::from_id_salt(id).width(300.0).selected_text(shown).show_ui(ui, |ui| {
|
||||
ui.selectable_value(value, None, "Device default");
|
||||
for v in options {
|
||||
ui.selectable_value(value, Some(*v), format!("{v} {unit}"));
|
||||
@@ -490,7 +490,7 @@ pub fn playback_engine(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
let system_label = ui.label("Audio system");
|
||||
let def = systems.iter().find(|s| s.is_default).map_or("none".to_string(), |s| s.name.clone());
|
||||
let shown = draft.system.clone().unwrap_or_else(|| format!("Default ({def})"));
|
||||
let system = craft_ui::ComboBox::from_id_salt("pe-system").width(300.0).selected_text(shown).show_ui(ui, |ui| {
|
||||
let system = egui::ComboBox::from_id_salt("pe-system").width(300.0).selected_text(shown).show_ui(ui, |ui| {
|
||||
let before = draft.system.clone();
|
||||
ui.selectable_value(&mut draft.system, None, format!("Default ({def})"));
|
||||
for s in systems.iter() {
|
||||
@@ -654,7 +654,7 @@ pub fn io_setup(app: &mut SoundApp, ctx: &egui::Context) {
|
||||
let main = app.engine.session().main_format();
|
||||
ui.horizontal(|ui| {
|
||||
let main_label = ui.label("Main output");
|
||||
let format = craft_ui::ComboBox::from_id_salt("main_output_format").selected_text(main.label()).show_ui(ui, |ui| {
|
||||
let format = egui::ComboBox::from_id_salt("main_output_format").selected_text(main.label()).show_ui(ui, |ui| {
|
||||
for f in soundcraft_model::ChannelFormat::ALL.into_iter().filter(|f| (2..=16).contains(&f.channels())) {
|
||||
if ui.selectable_label(f == main, f.label()).clicked() && f != main {
|
||||
let _ = app.run("setup.main_format", json!({"format": f.label()}));
|
||||
|
||||
@@ -54,7 +54,9 @@ harness = false
|
||||
unsafe_code = "deny"
|
||||
|
||||
[lints.clippy]
|
||||
cognitive_complexity = "deny"
|
||||
wildcard_imports = "deny"
|
||||
dbg_macro = "warn"
|
||||
todo = "warn"
|
||||
too_many_arguments = "allow"
|
||||
too_many_arguments = "deny"
|
||||
type_complexity = "allow"
|
||||
|
||||
Reference in New Issue
Block a user