From 2c9edcc3942e2f4fc1f90f62943b601aabce2ca8 Mon Sep 17 00:00:00 2001 From: aiongg <67543387+aiongg@users.noreply.github.com> Date: Tue, 27 Oct 2026 10:26:51 -0400 Subject: [PATCH] refactor(ui): use craft-ui's ComboBox for every dropdown (#1457) * ui: use craft_ui::ComboBox so dropdown menus grow back (egui#5225); repin craft-libs * chore(deps): craft-libs 60d60d48 (dropdown fixes) * chore(deps): craft-libs 6af63481 (dropdown fixes) * chore(deps): craft-libs 4d7b82f7 (dropdown fixes) * chore(deps): craft-libs 92d392cf (#387 merged) * chore(xtask): pdf-deps expects craft-libs 92d392cf --- Cargo.lock | 229 +++++++++++++++++++++- Cargo.toml | 9 +- clippy.toml | 3 + crates/ui-egui/Cargo.toml | 1 + crates/ui-egui/src/backstage/info.rs | 4 +- crates/ui-egui/src/backstage/print.rs | 10 +- crates/ui-egui/src/dialogs.rs | 2 +- crates/ui-egui/src/dialogs/body.rs | 29 +-- crates/ui-egui/src/dialogs/credits.rs | 2 +- crates/ui-egui/src/dialogs/date_time.rs | 2 +- crates/ui-egui/src/dialogs/export.rs | 2 +- crates/ui-egui/src/dialogs/font.rs | 4 +- crates/ui-egui/src/dialogs/paragraph.rs | 25 +-- crates/ui-egui/src/dialogs/photo_album.rs | 2 +- crates/ui-egui/src/dialogs/theme_fonts.rs | 2 +- crates/ui-egui/src/panels/background.rs | 4 +- crates/ui-egui/src/panels/fillui.rs | 2 +- crates/ui-egui/src/panels/format_shape.rs | 6 +- crates/ui-egui/src/ribbon/transitions.rs | 2 +- xtask/src/pdf_deps.rs | 2 +- 20 files changed, 285 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0986dafc..01a92e4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -642,6 +642,15 @@ 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" @@ -811,10 +820,38 @@ dependencies = [ "libc", ] +[[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", +] + [[package]] name = "craft-media" version = "0.1.0" -source = "git+https://github.com/storytold/craft-libs?rev=f0ad6c1e1d297908915f4be315b0fcfc9be7b5d4#f0ad6c1e1d297908915f4be315b0fcfc9be7b5d4" +source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0" dependencies = [ "thiserror 2.0.21", ] @@ -822,16 +859,36 @@ dependencies = [ [[package]] name = "craft-pdf" version = "0.1.0" -source = "git+https://github.com/storytold/craft-libs?rev=9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef#9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef" +source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0" dependencies = [ "krilla", "thiserror 2.0.21", ] +[[package]] +name = "craft-ui" +version = "0.1.0" +source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0" +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", + "skrifa 0.44.0", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "craft-update" version = "0.1.0" -source = "git+https://github.com/storytold/craft-libs?rev=495e5971bc024aa96e6ed318cb6e7cd3a0103184#495e5971bc024aa96e6ed318cb6e7cd3a0103184" +source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0" dependencies = [ "chrono", "dunce", @@ -1205,6 +1262,7 @@ dependencies = [ name = "deckcraft-ui-egui" version = "0.11.1" dependencies = [ + "craft-ui", "craft-update", "deckcraft-anim", "deckcraft-color", @@ -1680,6 +1738,17 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aedcfb3409746eddb02b9e19ebda1c3394f759a152e48ee875a0844d1b955484" +[[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" @@ -2250,6 +2319,23 @@ 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" @@ -2258,11 +2344,32 @@ checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" 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" @@ -2274,6 +2381,9 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", + "utf16_iter", + "utf8_iter", + "write16", "zerovec", ] @@ -2283,6 +2393,32 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" +[[package]] +name = "icu_pattern" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b3db611446bd92c246b03e4aa0bafa71ddb194af431ddbb42b9d70e4bfce1a0" +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", +] + [[package]] name = "icu_properties" version = "2.3.0" @@ -2312,6 +2448,9 @@ checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" dependencies = [ "displaydoc", "icu_locale_core", + "postcard", + "serde", + "stable_deref_trait", "writeable", "yoke", "zerofrom", @@ -2319,6 +2458,30 @@ 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" @@ -2544,7 +2707,7 @@ dependencies = [ [[package]] name = "krilla" version = "0.8.2" -source = "git+https://github.com/storytold/craft-libs?rev=9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef#9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef" +source = "git+https://github.com/storytold/craft-libs?rev=92d392cff132eaf53e13afff77f38b5c11b73aa0#92d392cff132eaf53e13afff77f38b5c11b73aa0" dependencies = [ "base64 0.22.1", "bumpalo", @@ -2645,6 +2808,9 @@ name = "litemap" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" +dependencies = [ + "serde_core", +] [[package]] name = "litrs" @@ -3562,12 +3728,24 @@ 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", ] @@ -4524,6 +4702,18 @@ dependencies = [ "syn 3.0.6", ] +[[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" @@ -4667,6 +4857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" dependencies = [ "displaydoc", + "serde_core", "zerovec", ] @@ -4920,6 +5111,12 @@ 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" @@ -5567,6 +5764,17 @@ 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 0.4.1", + "windows-strings", +] + [[package]] name = "windows-result" version = "0.1.2" @@ -5882,11 +6090,20 @@ dependencies = [ "read-fonts 0.39.2", ] +[[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" @@ -6147,8 +6364,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ "displaydoc", + "litemap", + "serde_core", "yoke", "zerofrom", + "zerovec", ] [[package]] @@ -6157,6 +6377,7 @@ version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" dependencies = [ + "serde", "yoke", "zerofrom", "zerovec-derive", diff --git a/Cargo.toml b/Cargo.toml index fb54bd62..d9b947c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,9 +59,10 @@ harfrust = "0.13" vello_cpu = "0.2" vello_common = { version = "0.2", default-features = false } image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp", "gif", "tiff", "bmp"] } -craft-media = { git = "https://github.com/storytold/craft-libs", rev = "f0ad6c1e1d297908915f4be315b0fcfc9be7b5d4", version = "=0.1.0", default-features = false } -craft-pdf = { git = "https://github.com/storytold/craft-libs", rev = "9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef", version = "=0.1.0", default-features = false, features = ["write", "write-simple-text"] } -craft-update = { git = "https://github.com/storytold/craft-libs", version = "=0.1.0", rev = "495e5971bc024aa96e6ed318cb6e7cd3a0103184", features = ["egui"] } +craft-media = { git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0", version = "=0.1.0", default-features = false } +craft-pdf = { git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0", version = "=0.1.0", default-features = false, features = ["write", "write-simple-text"] } +craft-update = { git = "https://github.com/storytold/craft-libs", version = "=0.1.0", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0", features = ["egui"] } +craft-ui = { git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0", version = "=0.1.0" } i_overlay = "9" quick-xml = "0.41" zip = { version = "3", default-features = false, features = ["deflate"] } @@ -105,7 +106,7 @@ codegen-units = 16 debug = 0 [patch.crates-io] -krilla = { git = "https://github.com/storytold/craft-libs", rev = "9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef", version = "=0.8.2" } +krilla = { git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0", version = "=0.8.2" } ecolor = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" } emath = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" } epaint = { git = "https://github.com/storytold/egui.git", rev = "6d518fc799681571963842f95b55a6b68431b15a" } diff --git a/clippy.toml b/clippy.toml index 4b6c79f5..287e14ed 100644 --- a/clippy.toml +++ b/clippy.toml @@ -2,3 +2,6 @@ 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)" }, +] diff --git a/crates/ui-egui/Cargo.toml b/crates/ui-egui/Cargo.toml index 2cf3c2f1..88b9f770 100644 --- a/crates/ui-egui/Cargo.toml +++ b/crates/ui-egui/Cargo.toml @@ -19,6 +19,7 @@ deckcraft-anim = { workspace = true } deckcraft-engine = { workspace = true } deckcraft-media = { workspace = true } egui = { workspace = true, features = ["default_fonts", "monochrome_emoji_fonts"] } +craft-ui = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } log = { workspace = true } diff --git a/crates/ui-egui/src/backstage/info.rs b/crates/ui-egui/src/backstage/info.rs index e1e23027..e00acdd6 100644 --- a/crates/ui-egui/src/backstage/info.rs +++ b/crates/ui-egui/src/backstage/info.rs @@ -154,7 +154,7 @@ pub(super) fn save_as(app: &mut SlideApp, ui: &mut Ui, bs: &mut Backstage, out: ui.add_space(14.0); let current = SAVE_TYPES.iter().find(|s| s.0 == bs.file_type).map_or(SAVE_TYPES[0].1, |s| s.1); ui.horizontal(|ui| { - egui::ComboBox::from_id_salt("backstage_save_type") + craft_ui::ComboBox::from_id_salt("backstage_save_type") .width(340.0) .selected_text(current) .show_ui(ui, |ui| { @@ -198,7 +198,7 @@ pub(super) fn account(app: &mut SlideApp, ui: &mut Ui) { ui.set_width(340.0); heading(ui, "Appearance"); let dark = app.ui.brightness == theme::Brightness::Dark; - egui::ComboBox::from_id_salt("backstage_appearance") + craft_ui::ComboBox::from_id_salt("backstage_appearance") .width(260.0) .selected_text(if dark { "Dark" } else { "Light" }) .show_ui(ui, |ui| { diff --git a/crates/ui-egui/src/backstage/print.rs b/crates/ui-egui/src/backstage/print.rs index 9ebf15c5..1e997049 100644 --- a/crates/ui-egui/src/backstage/print.rs +++ b/crates/ui-egui/src/backstage/print.rs @@ -93,7 +93,7 @@ pub(super) fn print(app: &mut SlideApp, ui: &mut Ui, bs: &mut Backstage) { PrintScope::Current => "Print Current Slide", PrintScope::Custom => "Custom Range", }; - let combo = egui::ComboBox::from_id_salt("backstage_print_scope").width(240.0).selected_text(scope).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt("backstage_print_scope").width(240.0).selected_text(scope).show_ui(ui, |ui| { for (s, label) in [(PrintScope::All, "Print All Slides"), (PrintScope::Current, "Print Current Slide"), (PrintScope::Custom, "Custom Range")] { @@ -116,7 +116,7 @@ pub(super) fn print(app: &mut SlideApp, ui: &mut Ui, bs: &mut Backstage) { }); ui.add_space(4.0); let layout = LAYOUTS.iter().find(|l| l.0 == bs.print_layout).map_or("Full Page Slides", |l| l.1); - let combo = egui::ComboBox::from_id_salt("backstage_print_layout").width(240.0).selected_text(layout).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt("backstage_print_layout").width(240.0).selected_text(layout).show_ui(ui, |ui| { for (id, label) in LAYOUTS { if ui.selectable_label(bs.print_layout == id, label).clicked() { bs.print_layout = id; @@ -130,7 +130,7 @@ pub(super) fn print(app: &mut SlideApp, ui: &mut Ui, bs: &mut Backstage) { // for notes pages and handouts. ui.add_enabled_ui(bs.print_layout != "slides", |ui| { let paper = deckcraft_engine::cmd::file::PAPERS.iter().find(|p| p.0 == bs.print_paper).map_or("Letter", |p| p.1); - egui::ComboBox::from_id_salt("backstage_print_paper") + craft_ui::ComboBox::from_id_salt("backstage_print_paper") .width(240.0) .selected_text(paper) .show_ui(ui, |ui| { @@ -144,7 +144,7 @@ pub(super) fn print(app: &mut SlideApp, ui: &mut Ui, bs: &mut Backstage) { .widget_info(|| egui::WidgetInfo::labeled(egui::Role::ComboBox, true, "Paper size")); ui.add_space(4.0); let orient = if bs.print_landscape { "Landscape Orientation" } else { "Portrait Orientation" }; - egui::ComboBox::from_id_salt("backstage_print_orientation") + craft_ui::ComboBox::from_id_salt("backstage_print_orientation") .width(240.0) .selected_text(orient) .show_ui(ui, |ui| { @@ -317,7 +317,7 @@ pub(super) fn export(app: &mut SlideApp, ui: &mut Ui, bs: &mut Backstage) { ExportTask::Handouts => { ui.label(RichText::new("Create Handouts").font(theme::font(16.0)).color(t.text)); bullets(ui, &["Several slides on each page of a PDF", "Three a page leaves lines for notes", "Print them for your audience"]); - let combo = egui::ComboBox::from_id_salt("backstage_handouts") + let combo = craft_ui::ComboBox::from_id_salt("backstage_handouts") .width(240.0) .selected_text(format!("{} slides per page", bs.handouts_per_page)) .show_ui(ui, |ui| { diff --git a/crates/ui-egui/src/dialogs.rs b/crates/ui-egui/src/dialogs.rs index 00ac33c7..ed33b9cd 100644 --- a/crates/ui-egui/src/dialogs.rs +++ b/crates/ui-egui/src/dialogs.rs @@ -262,7 +262,7 @@ fn color_label(v: &Value) -> String { fn choice(ui: &mut Ui, d: &mut Dialog, salt: &str, name: &str, key: &str, choices: &[(&str, &str)]) { let cur = d.get(key, ""); let label = choices.iter().find(|(v, _)| *v == cur).map(|(_, l)| *l).unwrap_or(cur.as_str()); - let combo = egui::ComboBox::from_id_salt(salt).selected_text(label).width(140.0).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt(salt).selected_text(label).width(140.0).show_ui(ui, |ui| { for (v, l) in choices { if ui.selectable_label(cur == *v, *l).clicked() { d.fields.insert((*key).into(), (*v).into()); diff --git a/crates/ui-egui/src/dialogs/body.rs b/crates/ui-egui/src/dialogs/body.rs index 071e042a..ae19ac67 100644 --- a/crates/ui-egui/src/dialogs/body.rs +++ b/crates/ui-egui/src/dialogs/body.rs @@ -50,15 +50,16 @@ pub(super) fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool { } let label = ui.label("Slides sized for:"); let preset = d.get("preset", ""); - let combo = egui::ComboBox::from_id_salt("sizes").selected_text(if preset.is_empty() { "Custom" } else { &preset }).show_ui(ui, |ui| { - for (label, w, h) in deckcraft_model::defaults::SLIDE_SIZES { - if ui.selectable_label(preset == *label, *label).clicked() { - d.fields.insert("preset".into(), label.to_string()); - put_slide_dim(d, "w", *w, ppu); - put_slide_dim(d, "h", *h, ppu); + let combo = + craft_ui::ComboBox::from_id_salt("sizes").selected_text(if preset.is_empty() { "Custom" } else { &preset }).show_ui(ui, |ui| { + for (label, w, h) in deckcraft_model::defaults::SLIDE_SIZES { + if ui.selectable_label(preset == *label, *label).clicked() { + d.fields.insert("preset".into(), label.to_string()); + put_slide_dim(d, "w", *w, ppu); + put_slide_dim(d, "h", *h, ppu); + } } - } - }); + }); let _ = combo.response.labelled_by(label.id); let abbr = unit_abbr(len); let (w_seed, h_seed) = (field_of(d, "w"), field_of(d, "h")); @@ -98,7 +99,7 @@ pub(super) fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool { ui.add_enabled_ui(date && automatic, |ui| { ui.horizontal(|ui| { ui.label(" Format:"); - egui::ComboBox::from_id_salt("hf-date-format").selected_text(label).width(200.0).show_ui(ui, |ui| { + craft_ui::ComboBox::from_id_salt("hf-date-format").selected_text(label).width(200.0).show_ui(ui, |ui| { for (kind, sample) in &rows { if ui.selectable_label(fmt == *kind, sample).clicked() { d.fields.insert("dateFormat".into(), (*kind).to_string()); @@ -210,7 +211,7 @@ pub(super) fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool { let chosen = d.fields.entry("custom".into()).or_insert_with(|| sh.custom_show.clone().unwrap_or_default()).clone(); let field = ui.label("Slides"); let label = if chosen.is_empty() { "All slides".to_string() } else { chosen.clone() }; - let combo = egui::ComboBox::from_id_salt("setup_custom").selected_text(label).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt("setup_custom").selected_text(label).show_ui(ui, |ui| { if ui.selectable_label(chosen.is_empty(), "All slides").clicked() { d.fields.insert("custom".into(), String::new()); } @@ -369,7 +370,7 @@ pub(super) fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool { let color = d.get("color", ""); ui.horizontal(|ui| { let field = ui.add_sized(vec2(120.0, 20.0), egui::Label::new("Color:")); - let combo = egui::ComboBox::from_id_salt("bullet-color") + let combo = craft_ui::ComboBox::from_id_salt("bullet-color") .selected_text(colors.iter().find(|c| c.0 == color).map_or("Automatic", |c| c.1)) .show_ui(ui, |ui| { for (k, l) in colors { @@ -475,7 +476,7 @@ pub(super) fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool { ]; let shown = targets.iter().find(|t| t.0 == kind).map_or("Next Slide", |t| t.1); ui.add_enabled_ui(hyperlink, |ui| { - let combo = egui::ComboBox::from_id_salt("action-target").selected_text(shown).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt("action-target").selected_text(shown).show_ui(ui, |ui| { for (k, l) in targets { if ui.selectable_label(kind == k, l).clicked() { d.fields.insert("kind".into(), k.into()); @@ -667,7 +668,7 @@ pub(super) fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool { ui.add_space(4.0); ui.horizontal(|ui| { let field = ui.label("Print layout:"); - let combo = egui::ComboBox::from_id_salt("pdf_layout") + let combo = craft_ui::ComboBox::from_id_salt("pdf_layout") .selected_text(match pdf_layout.as_str() { "notes" => "Notes Pages", "h1" => "Handouts (1 slide per page)", @@ -752,7 +753,7 @@ pub(super) fn body(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bool { let mut to = d.get("to", ""); egui::Grid::new("replace_fonts").num_columns(2).spacing(vec2(10.0, 8.0)).show(ui, |ui| { let field = ui.label("Replace:"); - let combo = egui::ComboBox::from_id_salt("rf_from").width(240.0).selected_text(from.clone()).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt("rf_from").width(240.0).selected_text(from.clone()).show_ui(ui, |ui| { for f in &used { ui.selectable_value(&mut from, f.clone(), f); } diff --git a/crates/ui-egui/src/dialogs/credits.rs b/crates/ui-egui/src/dialogs/credits.rs index 0cef384b..b133efe1 100644 --- a/crates/ui-egui/src/dialogs/credits.rs +++ b/crates/ui-egui/src/dialogs/credits.rs @@ -223,7 +223,7 @@ pub fn contributors_ui(ui: &mut egui::Ui) { } ui.separator(); let field = ui.label("Sort"); - let combo = egui::ComboBox::from_id_salt("credits_sort").selected_text(v.key.label().0).show_ui(ui, |ui| { + let combo = craft_ui::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; diff --git a/crates/ui-egui/src/dialogs/date_time.rs b/crates/ui-egui/src/dialogs/date_time.rs index 2f78dbc3..89ba6a9d 100644 --- a/crates/ui-egui/src/dialogs/date_time.rs +++ b/crates/ui-egui/src/dialogs/date_time.rs @@ -49,7 +49,7 @@ pub(super) fn date_time_dialog(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) let lang_label = DATE_LANGS.iter().find(|(k, _)| *k == lang).map(|(_, l)| *l).unwrap_or("English (United States)"); ui.horizontal(|ui| { ui.label("Language:"); - let opened = egui::ComboBox::from_id_salt("date-lang").selected_text(lang_label).width(240.0).show_ui(ui, |ui| { + let opened = craft_ui::ComboBox::from_id_salt("date-lang").selected_text(lang_label).width(240.0).show_ui(ui, |ui| { for (k, l) in DATE_LANGS { if ui.selectable_label(lang == *k, *l).clicked() { d.fields.insert("language".into(), (*k).to_string()); diff --git a/crates/ui-egui/src/dialogs/export.rs b/crates/ui-egui/src/dialogs/export.rs index d69e247c..27e2e5ef 100644 --- a/crates/ui-egui/src/dialogs/export.rs +++ b/crates/ui-egui/src/dialogs/export.rs @@ -16,7 +16,7 @@ pub(super) fn gif_options(app: &SlideApp, ui: &mut Ui, d: &mut Dialog) -> Result ui.add_space(4.0); ui.horizontal(|ui| { let field = ui.add_sized(vec2(120.0, 20.0), egui::Label::new("Size:")); - let combo = egui::ComboBox::from_id_salt("gif_size").selected_text(size_label(&size)).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt("gif_size").selected_text(size_label(&size)).show_ui(ui, |ui| { for k in SIZE_PRESETS.iter().map(|(k, _)| *k).chain(["custom"]) { if ui.selectable_label(size == k, size_label(k)).clicked() { d.fields.insert("gifSize".into(), k.into()); diff --git a/crates/ui-egui/src/dialogs/font.rs b/crates/ui-egui/src/dialogs/font.rs index 7e2eabf7..f8841404 100644 --- a/crates/ui-egui/src/dialogs/font.rs +++ b/crates/ui-egui/src/dialogs/font.rs @@ -26,7 +26,7 @@ pub(super) fn font_dialog(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bo } ui.horizontal(|ui| { let field = ui.add_sized(vec2(88.0, 20.0), egui::Label::new("Font")); - let combo = egui::ComboBox::from_id_salt("font_dialog_family") + let combo = craft_ui::ComboBox::from_id_salt("font_dialog_family") .selected_text(if family.is_empty() { " " } else { family.as_str() }) .width(300.0) .show_ui(ui, |ui| { @@ -75,7 +75,7 @@ pub(super) fn font_dialog(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) -> bo let mut spacing = d.get("spacing", "0"); let edited = ui.add(egui::TextEdit::singleline(&mut spacing).desired_width(64.0).hint_text("pt")); let mut picked = None; - let combo = egui::ComboBox::from_id_salt("font_dialog_spacing") + let combo = craft_ui::ComboBox::from_id_salt("font_dialog_spacing") .selected_text(match spacing.as_str() { "-3" => "Very tight", "-1.5" => "Tight", diff --git a/crates/ui-egui/src/dialogs/paragraph.rs b/crates/ui-egui/src/dialogs/paragraph.rs index d442c825..3dcdfdec 100644 --- a/crates/ui-egui/src/dialogs/paragraph.rs +++ b/crates/ui-egui/src/dialogs/paragraph.rs @@ -103,19 +103,20 @@ pub(super) fn paragraph_dialog(app: &mut SlideApp, ui: &mut Ui, d: &mut Dialog) let field = ui.add_sized(vec2(110.0, 20.0), egui::Label::new("Line spacing")); let kind = d.get("lineKind", "multiple"); let value = d.get("lineValue", "1"); - let combo = egui::ComboBox::from_id_salt("paragraph_line").selected_text(line_preset_label(&kind, &value)).width(140.0).show_ui(ui, |ui| { - for (label, k, v) in [ - ("Single", "multiple", Some("1")), - ("1.5 lines", "multiple", Some("1.5")), - ("Double", "multiple", Some("2")), - ("Multiple", "multiple", None), - ("Exactly", "exactly", None), - ] { - if ui.selectable_label(line_preset_label(&kind, &value) == label, label).clicked() { - picked = Some((k, v)); + let combo = + craft_ui::ComboBox::from_id_salt("paragraph_line").selected_text(line_preset_label(&kind, &value)).width(140.0).show_ui(ui, |ui| { + for (label, k, v) in [ + ("Single", "multiple", Some("1")), + ("1.5 lines", "multiple", Some("1.5")), + ("Double", "multiple", Some("2")), + ("Multiple", "multiple", None), + ("Exactly", "exactly", None), + ] { + if ui.selectable_label(line_preset_label(&kind, &value) == label, label).clicked() { + picked = Some((k, v)); + } } - } - }); + }); let _ = combo.response.labelled_by(field.id); ui.add_space(8.0); let _ = labeled_text(ui, d, "At", "lineValue", 64.0); diff --git a/crates/ui-egui/src/dialogs/photo_album.rs b/crates/ui-egui/src/dialogs/photo_album.rs index 84c6f5b9..236fef33 100644 --- a/crates/ui-egui/src/dialogs/photo_album.rs +++ b/crates/ui-egui/src/dialogs/photo_album.rs @@ -69,7 +69,7 @@ fn pick_album_picture(app: &mut SlideApp) -> Option { fn album_choice(ui: &mut Ui, d: &mut Dialog, id: &str, name: &str, key: &str, default: &str, choices: &[(&str, &str)]) { let cur = d.get(key, default); let label = choices.iter().find(|(k, _)| *k == cur).map(|(_, l)| *l).unwrap_or(default); - let opened = egui::ComboBox::from_id_salt(id).selected_text(label).width(220.0).show_ui(ui, |ui| { + let opened = craft_ui::ComboBox::from_id_salt(id).selected_text(label).width(220.0).show_ui(ui, |ui| { for (k, l) in choices { if ui.selectable_label(cur == *k, *l).clicked() { d.fields.insert(key.into(), (*k).to_string()); diff --git a/crates/ui-egui/src/dialogs/theme_fonts.rs b/crates/ui-egui/src/dialogs/theme_fonts.rs index 0bf15ff0..14b88eb8 100644 --- a/crates/ui-egui/src/dialogs/theme_fonts.rs +++ b/crates/ui-egui/src/dialogs/theme_fonts.rs @@ -30,7 +30,7 @@ fn theme_font_choices(app: &SlideApp, selected: &str) -> Vec { /// Draw an accessible font combo box and update the selected family; the caller supplies the /// visible label. fn font_combo(ui: &mut Ui, label: &str, choices: &[String], selected: &mut String) { - let resp = egui::ComboBox::from_id_salt(label).selected_text(selected.as_str()).width(240.0).show_ui(ui, |ui| { + let resp = craft_ui::ComboBox::from_id_salt(label).selected_text(selected.as_str()).width(240.0).show_ui(ui, |ui| { for face in choices { if ui.selectable_label(selected == face, face).clicked() { *selected = face.clone(); diff --git a/crates/ui-egui/src/panels/background.rs b/crates/ui-egui/src/panels/background.rs index 0373616f..05bc11be 100644 --- a/crates/ui-egui/src/panels/background.rs +++ b/crates/ui-egui/src/panels/background.rs @@ -156,7 +156,7 @@ fn picture_background_options(app: &mut SlideApp, ui: &mut Ui, pf: &deckcraft_mo }; ui.horizontal(|ui| { let field = ui.add_sized(vec2(72.0, 20.0), egui::Label::new("Alignment")); - let combo = egui::ComboBox::from_id_salt("bg-align").selected_text(align_name).width(140.0).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt("bg-align").selected_text(align_name).width(140.0).show_ui(ui, |ui| { for (k, l) in [ ("tl", "Top Left"), ("t", "Top"), @@ -183,7 +183,7 @@ fn picture_background_options(app: &mut SlideApp, ui: &mut Ui, pf: &deckcraft_mo }; ui.horizontal(|ui| { let field = ui.add_sized(vec2(72.0, 20.0), egui::Label::new("Mirror")); - let combo = egui::ComboBox::from_id_salt("bg-mirror").selected_text(mirror_name).width(140.0).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt("bg-mirror").selected_text(mirror_name).width(140.0).show_ui(ui, |ui| { for (k, l) in [("none", "None"), ("x", "Horizontal"), ("y", "Vertical"), ("xy", "Both")] { if ui.selectable_label(flip == k, l).clicked() { run(app, "design.background", json!({"pictureProps": {"mirror": k}})); diff --git a/crates/ui-egui/src/panels/fillui.rs b/crates/ui-egui/src/panels/fillui.rs index 2410dc0a..5150b8f0 100644 --- a/crates/ui-egui/src/panels/fillui.rs +++ b/crates/ui-egui/src/panels/fillui.rs @@ -169,7 +169,7 @@ pub fn gradient_editor(ui: &mut Ui, id: &str, g: &Gradient, sc: &ColorScheme) -> }; ui.horizontal(|ui| { let field = ui.add_sized(vec2(70.0, 20.0), egui::Label::new("Type")); - let combo = egui::ComboBox::from_id_salt((id, "kind")).selected_text(kind).width(120.0).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt((id, "kind")).selected_text(kind).width(120.0).show_ui(ui, |ui| { for k in ["Linear", "Radial", "Rectangular", "Path"] { if ui.selectable_label(kind == k, k).clicked() && kind != k { let focus = match &g.shape { diff --git a/crates/ui-egui/src/panels/format_shape.rs b/crates/ui-egui/src/panels/format_shape.rs index 77b26bf4..cb324721 100644 --- a/crates/ui-egui/src/panels/format_shape.rs +++ b/crates/ui-egui/src/panels/format_shape.rs @@ -396,7 +396,7 @@ fn line_choice(app: &mut SlideApp, ui: &mut Ui, label: &str, key: &str, current: ui.horizontal(|ui| { let field = ui.add_sized(vec2(90.0, 20.0), egui::Label::new(label)); let shown = items.iter().find(|(_, v)| *v == current).map_or(current, |(l, _)| *l); - let combo = egui::ComboBox::from_id_salt(("fmt-line", key)).selected_text(shown).width(120.0).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt(("fmt-line", key)).selected_text(shown).width(120.0).show_ui(ui, |ui| { for (l, v) in items { if ui.selectable_label(*v == current, *l).clicked() { run(app, "shape.line", json!({key: v})); @@ -542,7 +542,7 @@ fn picture_fill_options(app: &mut SlideApp, ui: &mut Ui, id: u32, pf: &deckcraft ui.horizontal(|ui| { let field = ui.add_sized(vec2(90.0, 20.0), egui::Label::new(label)); let shown = opts.iter().find(|(k, _)| k == cur).map_or(opts[0].1, |(_, l)| *l); - let combo = egui::ComboBox::from_id_salt(("picfill", id, key)).selected_text(shown).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt(("picfill", id, key)).selected_text(shown).show_ui(ui, |ui| { for (k, l) in opts { if ui.selectable_label(*k == cur.as_str(), *l).clicked() { run(app, "shape.fill", json!({"pictureProps": {key: k}})); @@ -594,7 +594,7 @@ fn preset_label(name: &str) -> String { fn three_d_combo(app: &mut SlideApp, ui: &mut Ui, id: u32, label: &str, key: &str, cur: &str, options: &[&str]) { ui.horizontal(|ui| { let field = ui.add_sized(vec2(90.0, 20.0), egui::Label::new(label)); - let combo = egui::ComboBox::from_id_salt(("3d", id, key)).selected_text(preset_label(cur)).width(170.0).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt(("3d", id, key)).selected_text(preset_label(cur)).width(170.0).show_ui(ui, |ui| { for o in options { if ui.selectable_label(*o == cur, preset_label(o)).clicked() { run(app, "shape.effects", json!({"threeD": {key: o}})); diff --git a/crates/ui-egui/src/ribbon/transitions.rs b/crates/ui-egui/src/ribbon/transitions.rs index 3417e657..0e6ad70d 100644 --- a/crates/ui-egui/src/ribbon/transitions.rs +++ b/crates/ui-egui/src/ribbon/transitions.rs @@ -76,7 +76,7 @@ pub(super) fn transitions(app: &mut SlideApp, ui: &mut Ui) { .and_then(|t| t.sound) .and_then(|m| app.session.active().and_then(|d| d.doc.media(m).map(|i| i.name.trim_end_matches(".wav").to_string()))) .unwrap_or_else(|| if stop { "[Stop Previous Sound]".into() } else { "[No Sound]".into() }); - let combo = egui::ComboBox::from_id_salt("transition_sound").width(140.0).selected_text(name).show_ui(ui, |ui| { + let combo = craft_ui::ComboBox::from_id_salt("transition_sound").width(140.0).selected_text(name).show_ui(ui, |ui| { let none = cur.as_ref().is_none_or(|t| t.sound.is_none() && !t.stop_sound); if ui.selectable_label(none, "[No Sound]").clicked() { run(app, "transition.sound", json!({"none": true})); diff --git a/xtask/src/pdf_deps.rs b/xtask/src/pdf_deps.rs index d25bb0f4..100aa3a0 100644 --- a/xtask/src/pdf_deps.rs +++ b/xtask/src/pdf_deps.rs @@ -6,7 +6,7 @@ use std::process::Command; use serde_json::Value; -const SHARED_REV: &str = "9f75d3dc19b4b514c4f3d4847ed1ec1b0e86b4ef"; +const SHARED_REV: &str = "92d392cff132eaf53e13afff77f38b5c11b73aa0"; const REGISTRY: &str = "registry+https://github.com/rust-lang/crates.io-index"; pub fn run(root: &Path) -> Result<(), String> {