mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 00:17:42 +00:00
Fix #5502: Export As PNG exports the active artboard, not always the first
File > Export > Export As PNG... opened PNG Options with no artboard chosen, and a single-image export without one writes the first artboard, whichever was in use. With no artboard choice given, it now takes the active artboard, or each artboard the Artboard tool has selected (one file each). A choice the caller gives is kept.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -170,6 +170,19 @@ fn run_ui_part2(app: &mut VectorcraftApp, id: &str, p: &Value) -> Option<Result<
|
||||
let mut params = if p.is_object() { p.clone() } else { json!({}) };
|
||||
params["format"] = json!("png");
|
||||
params["path"] = json!(path);
|
||||
// No artboard named: the artboard in use rather than the first (#5502), or each one the
|
||||
// Artboard tool has selected, one file each.
|
||||
let named = ["useArtboards", "rect"].iter().chain(vectorcraft_engine::cmd::fileio::ARTBOARD_PARAMS.iter()).any(|k| !params[*k].is_null());
|
||||
let n = app.session.active().map_or(0, |d| d.doc.artboards.len());
|
||||
if !named && n > 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)
|
||||
}),
|
||||
|
||||
+2
-1
@@ -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. |
|
||||
|
||||
Reference in New Issue
Block a user