diff --git a/crates/ui-egui/src/dialogs/tests_export.rs b/crates/ui-egui/src/dialogs/tests_export.rs index f658c31b0..891fb586b 100644 --- a/crates/ui-egui/src/dialogs/tests_export.rs +++ b/crates/ui-egui/src/dialogs/tests_export.rs @@ -106,6 +106,37 @@ fn export_as_png_picks_the_file_then_shows_png_options() { assert_eq!(&written.borrow()[0].1[16..20], 120u32.to_be_bytes(), "60 pt at 144 ppi"); } +/// File › Export › Export As PNG… exports the artboard in use, not the first (#5502), and each +/// artboard the Artboard tool has selected, one file each. +#[test] +fn export_as_png_exports_the_active_artboard() { + let (mut app, written) = app(2); + // The ellipse is on the first artboard; the second is empty. + let opaque = |bytes: &[u8]| image::load_from_memory(bytes).unwrap().to_rgba8().pixels().any(|p| p.0[3] > 0); + app.view_mut().unwrap().artboard = 1; + app.run("file.export.png", json!({})).unwrap(); + assert_eq!(app.ui.dialog.as_ref().unwrap().fields["artboard"], json!(1)); + frame(&mut app); + confirm(&mut app).unwrap(); + assert!(!opaque(&written.borrow()[0].1), "the second artboard, which is empty"); + app.view_mut().unwrap().artboard = 0; + app.run("file.export.png", json!({})).unwrap(); + frame(&mut app); + confirm(&mut app).unwrap(); + assert!(opaque(&written.borrow()[1].1), "the first artboard, with the ellipse"); + // A choice given is kept. + app.run("file.export.png", json!({"useArtboards": false})).unwrap(); + assert!(app.ui.dialog.as_ref().unwrap().fields.get("artboard").is_none_or(serde_json::Value::is_null)); + app.ui.dialog = None; + // Artboards the Artboard tool selected: one file each. + app.select_tool("artboard"); + app.session.set_tool_option("selected", &json!([0, 1])); + app.run("file.export.png", json!({})).unwrap(); + frame(&mut app); + confirm(&mut app).unwrap(); + assert_eq!(names(&written)[2..], ["/out/Untitled-1-Artboard-1.png", "/out/Untitled-1-Artboard-2.png"]); +} + #[test] fn export_as_with_a_range_then_png_options_writes_one_file_per_artboard() { let (mut app, written) = app(3); diff --git a/crates/ui-egui/src/menus/run.rs b/crates/ui-egui/src/menus/run.rs index 80fe0a184..2d134f76f 100644 --- a/crates/ui-egui/src/menus/run.rs +++ b/crates/ui-egui/src/menus/run.rs @@ -170,6 +170,19 @@ fn run_ui_part2(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option 0 { + match crate::panels::artboards::picked(app, n).as_slice() { + [i] => params["artboard"] = json!(i), + several => { + params["artboards"] = json!(several); + params["useArtboards"] = json!(true); + } + } + } crate::dialogs::open_raster_options(app, f, params); Ok(Value::Null) }), diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 26f56b16f..bbfcdc069 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -1,6 +1,6 @@ # UI and interaction parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-04 · **Change:** minor (New Document's units belong to the chosen preset; Recent and Saved cards keep their own units; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-04 · **Change:** minor (File › Export › Export As PNG exports the active artboard, or each one the Artboard tool selected, not always the first, #5502; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x) ## Feature submission evidence @@ -30,6 +30,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard | Date | Change | Summary | |---|---|---| +| 2026-11-04 | minor | File › Export › Export As PNG… exports the active artboard, or each artboard the Artboard tool has selected (one file each), instead of always the first (#5502); a choice the caller gives is kept; scores and estimates unchanged | | 2026-11-04 | minor | Document Tools add-on (a VectorCraft addition): Object › Plug-ins › Document Tools › Batch Trace Folder asks for a folder of images and a destination folder and traces each image into it (#4921); scores and estimates unchanged | | 2026-11-03 | minor | The Action Options row cites the public Actions panel page and describes its controls. Scores and estimates remain unchanged. | | 2026-11-03 | minor | Enclosing Lasso provides whole-object enclosure selection as an add-on with no default shortcut or Basic toolbar slot. Scores and estimates remain unchanged. |