Fix #4893: New Document saves a preset after More Settings

This commit is contained in:
bflatastic
2026-10-31 22:22:30 +07:00
parent cd2b5f77a4
commit 06043139e6
3 changed files with 70 additions and 11 deletions
+66 -9
View File
@@ -330,15 +330,7 @@ fn details(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, b: &mut
ui.add_space(8.0);
ui.horizontal(|ui| {
form::text(ui, d, "name", DETAILS - 50.0);
if widgets::icon_button(ui, "save", tl!("Save Preset"), d.bool(SAVING), 26.0).clicked() {
let saving = !d.bool(SAVING);
d.fields.insert(SAVING.into(), json!(saving));
if saving && d.str("presetName").is_empty() {
let template = "Preset {number}";
let name = crate::i18n::fmt(tl!(template), &[("number", &(app.session.prefs.new_doc_presets.len() + 1).to_string())]);
d.fields.insert("presetName".into(), json!(name));
}
}
save_button(app, ui, d);
});
if d.bool(SAVING) {
save_row(app, ui, d);
@@ -388,6 +380,19 @@ fn details(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog, b: &mut
});
}
/// The Save Preset button beside the name: it shows or hides [`save_row`].
fn save_button(app: &VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) {
if widgets::icon_button(ui, "save", tl!("Save Preset"), d.bool(SAVING), 26.0).clicked() {
let saving = !d.bool(SAVING);
d.fields.insert(SAVING.into(), json!(saving));
if saving && d.str("presetName").is_empty() {
let template = "Preset {number}";
let name = crate::i18n::fmt(tl!(template), &[("number", &(app.session.prefs.new_doc_presets.len() + 1).to_string())]);
d.fields.insert("presetName".into(), json!(name));
}
}
}
/// Save Preset: the preset's name, Save and Cancel.
fn save_row(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) {
ui.add_space(4.0);
@@ -520,7 +525,14 @@ fn show_more(app: &mut VectorcraftApp, ctx: &egui::Context) {
ui.add_space(12.0);
widgets::label_row(ui, tl!("Name:"), L, |ui| {
form::text(ui, &mut d, "name", 300.0);
save_button(app, ui, &mut d);
});
if d.bool(SAVING) {
// Under the name, in the fields' column.
widgets::label_row(ui, "", L, |ui| {
ui.vertical(|ui| save_row(app, ui, &mut d));
});
}
// Profile: the preset categories (the tabs); Size: the profile's presets.
let profiles: Vec<&str> = newdoc::CATEGORIES.iter().map(|c| c.0).collect();
let profile = profiles.iter().find(|p| p.eq_ignore_ascii_case(&d.str("category"))).copied().unwrap_or("[Custom]");
@@ -894,4 +906,49 @@ mod tests {
crate::dialogs::confirm(&mut app).unwrap();
assert_eq!(app.session.prefs.recent_new_docs[0].name, "Zine");
}
/// Save Preset works in More Settings too (#4893), saving its settings: the artboard layout
/// only More Settings shows among them.
#[test]
fn more_settings_saves_a_preset_of_its_settings() {
let mut app = VectorcraftApp::new(Session::new(), Default::default());
app.run("file.newDialog", json!({})).unwrap();
app.ui.dialog.as_mut().unwrap().kind = super::MORE.into();
set(&mut app, "artboards", json!(4));
set(&mut app, "artboardLayout", json!({"layout": "column", "spacing": 30}));
set(&mut app, super::SAVING, json!(true));
set(&mut app, "presetName", json!("Strip"));
let ctx = egui::Context::default();
crate::theme::install_fonts(&ctx);
let mut time = 0.0;
let mut run = |app: &mut VectorcraftApp, events| {
time += 0.5;
let screen_rect = Some(egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1400.0, 1000.0)));
let raw = egui::RawInput { screen_rect, events, time: Some(time), ..Default::default() };
let mut out = ctx.run_ui(raw, |ui| crate::dialogs::show(app, ui.ctx()));
out.textures_delta.clear();
out
};
run(&mut app, vec![]);
let out = run(&mut app, vec![]);
fn walk(s: &egui::Shape, out: &mut Vec<(String, egui::Pos2)>) {
match s {
egui::Shape::Text(t) => out.push((t.galley.text().to_string(), t.visual_bounding_rect().center())),
egui::Shape::Vec(v) => v.iter().for_each(|s| walk(s, out)),
_ => {}
}
}
let mut texts = vec![];
out.shapes.iter().for_each(|c| walk(&c.shape, &mut texts));
assert!(texts.iter().any(|(t, _)| t == "Preset Name"), "the preset's name field shows");
let at = texts.iter().find(|(t, _)| t == "Save").map(|(_, p)| *p).expect("a Save button");
let press = |pressed| egui::Event::PointerButton { pos: at, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() };
run(&mut app, vec![egui::Event::PointerMoved(at), press(true)]);
run(&mut app, vec![press(false)]);
let saved = app.session.prefs.new_doc_presets.iter().find(|p| p.name == "Strip").expect("saved");
assert_eq!(saved.artboards, 4);
assert_eq!((saved.layout, saved.spacing), (super::ArtboardLayout::Column, 30.0));
assert_eq!((field(&app, "category"), field(&app, "preset"), field(&app, super::SAVING)), (json!("Saved"), json!("Strip"), json!(false)));
assert_eq!(app.ui.dialog.as_ref().unwrap().kind, super::MORE, "More Settings stays open");
}
}
+2 -1
View File
@@ -1,6 +1,6 @@
# Parity with Adobe Illustrator
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-31 · **Change:** minor (Object › Rasterize with the CMYK colour model makes a CMYK image, #4882; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-31 · **Change:** minor (New Document: Save Preset in More Settings, #4893; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
## Feature submission evidence
@@ -19,6 +19,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
| Date | Change | Summary |
|---|---|---|
| 2026-10-31 | minor | New Document: More Settings has the Save Preset button beside the name too, saving its settings (artboard layout included) as a preset (#4893); scores unchanged. |
| 2026-10-31 | minor | Object › Rasterize in a CMYK document with its CMYK colour model makes a CMYK image of the art's ink amounts (as CMYK exports draw them), so the Properties panel says CMYK and CMYK exports keep its inks; a transparent background becomes the image's opacity mask (#4882); scores unchanged. |
| 2026-10-31 | minor | Export for Screens is laid out as Illustrator's: Artboards and Assets tabs with a grid or list of thumbnails, Clear Selection and Prefix under them, Create Sub-folders by Scale or Format (on by default), Export PDFs As Single File or Multiple Files (`pdfs`), iOS and Android rows, the format presets in a ☰ menu, and a Selected / files-to-export count; the naming pattern, Layers and Selection pages and folders list stay in `document.exportForScreens` for scripts and MCP; scores unchanged. |
| 2026-10-31 | minor | Export for Screens is laid out as the reference app's: Artboards and Assets tabs with a grid or list of thumbnails, Clear Selection and Prefix under them, Create Sub-folders by Scale or Format (on by default), Export PDFs As Single File or Multiple Files (`pdfs`), iOS and Android rows, the format presets in a ☰ menu, and a Selected / files-to-export count; the naming pattern, Layers and Selection pages and folders list stay in `document.exportForScreens` for scripts and MCP; scores unchanged. |
+2 -1
View File
@@ -1,6 +1,6 @@
# UI and interaction parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-31 · **Change:** minor (Export for Screens laid out as the reference app's) · **Target:** Adobe Illustrator 2026 (30.x)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-31 · **Change:** minor (New Document: Save Preset in More Settings, #4893; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
## Feature submission evidence
@@ -379,6 +379,7 @@ separate. Scores and hours unchanged. [Behavior and command details](development
| Date | Change | Summary |
|---|---|---|
| 2026-10-31 | minor | New Document: More Settings has Save Preset beside the name, as Preset Details does, and saves its settings (#4893); scores and estimates unchanged |
| 2026-10-31 | minor | Export for Screens is laid out as the reference app's: Artboards and Assets tabs with a grid or list of thumbnails, Clear Selection and Prefix under them, Create Sub-folders by Scale or Format (on by default), Export PDFs As Single File or Multiple Files (`pdfs`), iOS and Android rows, the format presets in a ☰ menu, and a Selected / files-to-export count; the naming pattern, Layers and Selection pages and folders list stay in `document.exportForScreens` for scripts and MCP; scores unchanged |
| 2026-10-31 | minor | Direct Selection: with Alt held at the press, a marquee selects every path it touches whole and keeps the Group Selection pointer while dragging (#4890); a click on a selected object's centre point (Show Center) selects the object whole, and a drag from it moves the object (#4891); scores unchanged |
| 2026-10-31 | minor | Arrange Tools add-on (a VectorCraft addition): Object › Plug-ins › Arrange Tools; scores and estimates unchanged |