From 7a2acbc178602956b48d2799473900ac6d623be1 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Sat, 31 Oct 2026 21:16:28 +0700 Subject: [PATCH] Export for Screens: the dialog is laid out as Illustrator's --- .../ui-egui/src/dialogs/export_for_screens.rs | 740 +++++++++--------- .../src/dialogs/tests_accessibility.rs | 6 +- .../src/dialogs/tests_screen_assets.rs | 11 +- crates/ui-egui/src/dialogs/tests_screens.rs | 257 +++--- crates/ui-egui/src/i18n/bg.tsv | 8 + crates/ui-egui/src/i18n/bs.tsv | 8 + crates/ui-egui/src/i18n/ca.tsv | 8 + crates/ui-egui/src/i18n/cs.tsv | 8 + crates/ui-egui/src/i18n/da.tsv | 8 + crates/ui-egui/src/i18n/de.tsv | 8 + crates/ui-egui/src/i18n/el.tsv | 8 + crates/ui-egui/src/i18n/es.tsv | 8 + crates/ui-egui/src/i18n/fi.tsv | 8 + crates/ui-egui/src/i18n/fr.tsv | 8 + crates/ui-egui/src/i18n/hu.tsv | 8 + crates/ui-egui/src/i18n/id.tsv | 8 + crates/ui-egui/src/i18n/it.tsv | 8 + crates/ui-egui/src/i18n/ja.tsv | 8 + crates/ui-egui/src/i18n/ka.tsv | 8 + crates/ui-egui/src/i18n/ko.tsv | 8 + crates/ui-egui/src/i18n/nl.tsv | 8 + crates/ui-egui/src/i18n/pl.tsv | 8 + crates/ui-egui/src/i18n/pt-br.tsv | 8 + crates/ui-egui/src/i18n/ru.tsv | 8 + crates/ui-egui/src/i18n/sv.tsv | 8 + crates/ui-egui/src/i18n/tr.tsv | 8 + crates/ui-egui/src/i18n/uk.tsv | 8 + crates/ui-egui/src/i18n/vi.tsv | 8 + crates/ui-egui/src/i18n/zh-hans.tsv | 8 + crates/ui-egui/src/i18n/zh-hant.tsv | 8 + crates/ui-egui/src/io/export.rs | 2 + crates/ui-egui/src/panels/asset_export.rs | 2 +- .../ui-egui/src/panels/tests_asset_export.rs | 2 +- 33 files changed, 673 insertions(+), 555 deletions(-) diff --git a/crates/ui-egui/src/dialogs/export_for_screens.rs b/crates/ui-egui/src/dialogs/export_for_screens.rs index 7bc4ca8b7..fdb48a753 100644 --- a/crates/ui-egui/src/dialogs/export_for_screens.rs +++ b/crates/ui-egui/src/dialogs/export_for_screens.rs @@ -1,34 +1,31 @@ -//! File → Export → Export for Screens: the Artboards tab (All, a range or Full Document, Include -//! Bleed, thumbnails with checkboxes) and the Assets tab (the Asset Export panel's assets, with -//! checkboxes), the destination (folder picker, Open Location after Export, Create Sub-folders; -//! the web downloads instead), the format rows (scale as `2x`, `100w`, `100h` or `72ppi`, suffix, -//! format), the presets, Format Settings (the gear) and the prefix. It opens on the settings the -//! document last exported with, except that while the Artboard tool is in use the artboards it has -//! selected are the ones chosen; the format rows are the Asset Export panel's too ([`formats`]). +//! File → Export → Export for Screens, laid out as Illustrator's: on the left the Artboards and +//! Assets tabs (thumbnails with checkboxes, in a grid or a list), Clear Selection and the prefix; +//! on the right Select (All, a range or Full Document, Include Bleed), the destination (folder +//! picker, Open Location after Export, Create Sub-folders by scale or by format; the web downloads +//! instead), Export PDFs As (one file of every artboard or a file each), and the format rows (scale +//! as `2x`, `100w`, `100h` or `72ppi`, suffix, format) with the iOS and Android rows, the format +//! presets (the ☰ menu) and Format Settings (the gear); below, how many items are selected and +//! how many files the export writes. It opens on the settings the document last exported with, +//! except that while the Artboard tool is in use the artboards it has selected are the ones chosen; +//! the format rows are the Asset Export panel's too ([`formats`]). On the desktop with Background +//! Export on, the files are encoded and written on the background thread +//! ([`crate::background`]) after the dialog closes. //! -//! The Layers tab exports each checked layer's art alone, and the Selection tab the selected art as -//! one file or a file per object. A file name pattern (`name`: ``, ``, `####`, -//! `YYYYMMDD`…, see `document.exportForScreens`) names every file alike, with a live example, and -//! the files go into one folder, or a folder per row, format, item, or item and format -//! (`folders`). Export presets (built-in and saved) set the formats, naming and folders at once. -//! On the desktop with Background Export on, the files are encoded and written on the background -//! thread ([`crate::background`]) after the dialog closes. +//! `document.exportForScreens` does more than the dialog shows (layers, the selection, file name +//! patterns, a folder per item): those are for scripts and MCP. //! -//! Fields (`ui.dialog.set`): `tab` (artboards|assets|layers|selection), `select` (all|range|full), `range`, +//! Fields (`ui.dialog.set`): `tab` (artboards|assets), `select` (all|range|full), `range`, //! `boards` ([bool] per artboard), `assets` ([asset id] checked on the Assets tab), `includeBleed`, -//! `folder`, `openLocation`, `subfolders`, `prefix`, `preset` (""|mobile|density: where the rows -//! came from), `formats` (rows of `document.exportForScreens`, `scale` as text), `settings` -//! ({png|png8|jpg|webp|gif|tiff|svg|pdf: {…}}), `layers` ([layer id] checked on the Layers tab), -//! `selectionMode` (one|each), `name` (the pattern), `counterStart`, `folders` -//! (none|rows|format|item|itemFormat), `exportPreset` (the preset applied last, "" for none); +//! `folder`, `openLocation`, `subfolders`, `subfolderBy` (scale|format), `pdfs` (single|multiple), +//! `prefix`, `preset` (""|mobile|density: where the rows came from), `formats` (rows of +//! `document.exportForScreens`, `scale` as text), `settings` ({png|png8|jpg|webp|gif|tiff|svg|pdf: +//! {…}}), `view` (grid|list), `exportPreset` (the format preset applied last, "" for none); //! `__settings` names the format whose Format Settings show ("" when closed), `__savePreset` is the //! name being typed to save a preset (absent when not saving). use serde::Deserialize; use serde_json::{Map, Value, json}; -use vectorcraft_engine::cmd::fileio::{self, ArtboardPick, SCREEN_PRESETS, ScreenSize, pdf}; - -use vectorcraft_doc::{ExportAsset, NodeId}; +use vectorcraft_engine::cmd::fileio::{self, ArtboardPick, ScreenSize, pdf}; use super::{DialogSpec, form, png_options, svg_options}; use crate::state::Dialog; @@ -43,11 +40,9 @@ pub(super) const SPEC: DialogSpec = DialogSpec { ok_label: Some(|app| match (io::is_web(app), app.ui.dialog.as_ref().map(|d| d.str("tab")).as_deref()) { (true, _) => "Download", (false, Some("assets")) => "Export Asset", - (false, Some("layers")) => "Export Layer", - (false, Some("selection")) => "Export Selection", (false, _) => "Export Artboard", }), - min_width: 660.0, + min_width: 720.0, ..DialogSpec::FORM }; @@ -80,32 +75,13 @@ fn print_marks() -> Value { json!({"trim": true, "registration": true, "colorBars": true, "pageInfo": true}) } -/// Where the files go: (`folders` value, label). -const FOLDERS: [(&str, &str); 5] = [ - ("none", "All in One Folder"), - ("rows", "By Size or Row"), - ("format", "By Format"), - ("item", "By Artboard or Item"), - ("itemFormat", "By Item, Then Format"), -]; -const FOLDER_LABELS: [&str; 5] = ["All in One Folder", "By Size or Row", "By Format", "By Artboard or Item", "By Item, Then Format"]; - -/// The tokens Insert adds to the file name pattern: (label, token). -const TOKENS: [(&str, &str); 8] = [ - ("Document Name", ""), - ("Artboard or Item Name", ""), - ("Number (####)", "####"), - ("Date (YYYYMMDD)", "YYYYMMDD"), - ("Date (YYYY-MM-DD)", "YYYY-MM-DD"), - ("Time (hhmmss)", "