mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 18:10:01 -06:00
ui.dialog.set stored any field name it was given, so a misspelled field (`discrad` for `discard`) was kept without effect and the dialog then ran with its old value. It now answers such a field with an error that lists the dialog's fields, and leaves the dialog unchanged. A dialog accepts the fields it holds, `__` fields, `discard` with a discard button, `preview` with a live preview, the fields it reads before a control adds them (each spec's `inputs`, for example Copy and the object options of the Transform dialogs, Move's `distance` and `angle`, the reference point, `path` of the export options dialogs, `searchFolder`, Brush Options' `tips`, the Justification and Hyphenation values that open blank, the Corners `kind` and `radius` of corners that differ, the Gradient Stop popover's `color`, `opacity`, `location` and `spread`, and a new artboard's `color` and display marks), and the fields it passes to the command it runs: every parameter of the generic `command` dialog's command, and the `textureImage` that Load Texture… sets in the Glass and Texturizer effects. Edit Selection now opens holding `deleted<i>` for each of its rows, so setting a row number it does not have returns an error, and Transparency Flattener Presets opens holding the selected preset's name and options instead of adding them on its first frame.
138 lines
6.2 KiB
Rust
138 lines
6.2 KiB
Rust
//! EPS Options (Export As → EPS): the preview (none, TIFF black and white or colour, transparent
|
|
//! or opaque), overprints and the flattener preset transparency is flattened with, fonts, the
|
|
//! options (linked files, thumbnails, CMYK PostScript, compatible gradients) and the PostScript
|
|
//! language level.
|
|
//!
|
|
//! Fields: `document.export` params (`format: eps`, `path?`, the artboard choice) and the EPS
|
|
//! options of `document.exportEps`. OK remembers the options for next time and writes the file
|
|
//! (asking where when there is no path); bad options keep the dialog open.
|
|
|
|
use serde_json::{Map, Value, json};
|
|
use vectorcraft_engine::cmd::{FlattenOptions, fileio};
|
|
use vectorcraft_eps::{Level, Overprint, Preview};
|
|
|
|
use super::DialogSpec;
|
|
use super::document_setup::{LABEL, check, choice};
|
|
use crate::state::Dialog;
|
|
use crate::{VectorcraftApp, io, widgets};
|
|
|
|
pub(super) const KIND: &str = "epsOptions";
|
|
|
|
pub(super) const SPEC: DialogSpec = DialogSpec {
|
|
heading: |_| tl!("EPS Options").into(),
|
|
body,
|
|
confirm,
|
|
ok: Some("Export"),
|
|
min_width: 420.0,
|
|
max_width: Some(460.0),
|
|
inputs: |_| &["path"],
|
|
..DialogSpec::FORM
|
|
};
|
|
|
|
/// Fields that are not remembered between exports (they belong to one export).
|
|
const PER_EXPORT: [&str; 7] = ["format", "path", "useArtboards", "range", "artboard", "artboards", "selectedOnly"];
|
|
|
|
/// The options a first EPS Options dialog starts from (the export's defaults).
|
|
fn defaults() -> Map<String, Value> {
|
|
let medium = FlattenOptions::preset_label(FlattenOptions::PRESETS[1]).unwrap_or_default();
|
|
let mut m = Map::new();
|
|
for (k, v) in [
|
|
("previewFormat", json!(Preview::default().id())),
|
|
("transparentPreview", json!(true)),
|
|
("overprints", json!(Overprint::default().id())),
|
|
("flattenerPreset", json!(medium)),
|
|
("includeLinkedFiles", json!(false)),
|
|
("thumbnails", json!(true)),
|
|
("cmykPostScript", json!(true)),
|
|
("compatibleGradients", json!(false)),
|
|
("level", json!(Level::default().id())),
|
|
] {
|
|
m.insert(k.into(), v);
|
|
}
|
|
m
|
|
}
|
|
|
|
/// Open EPS Options for an export whose params (path, artboard choice, any EPS option) are
|
|
/// `params`, over the options used last.
|
|
pub fn open(app: &mut VectorcraftApp, params: &Value) {
|
|
let mut fields = defaults();
|
|
for given in [&app.ui.eps_options, params] {
|
|
if let Some(o) = given.as_object() {
|
|
fields.extend(o.iter().map(|(k, v)| (k.clone(), v.clone())));
|
|
}
|
|
}
|
|
fields.insert("format".into(), json!("eps"));
|
|
// A built-in preset named by id (`medium`) shows as its name.
|
|
if let Some(label) = fields.get("flattenerPreset").and_then(Value::as_str).and_then(|p| FlattenOptions::preset_label(&p.to_ascii_lowercase())) {
|
|
fields.insert("flattenerPreset".into(), json!(label));
|
|
}
|
|
app.ui.dialog = Some(Dialog::new(KIND, Value::Object(fields)));
|
|
}
|
|
|
|
fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
|
widgets::subheader(ui, tl!("Preview"));
|
|
let previews: Vec<(&str, &str)> = Preview::ALL.iter().map(|p| (p.id(), p.label())).collect();
|
|
choice(ui, d, "previewFormat", tl!("Format:"), &previews);
|
|
// Only the colour preview can keep transparency.
|
|
let color = Preview::from_id(&d.str("previewFormat")) == Some(Preview::TiffColor);
|
|
let transparent = d.bool("transparentPreview");
|
|
ui.horizontal(|ui| {
|
|
ui.add_space(LABEL + 8.0);
|
|
for (label, on) in [(tl!("Transparent"), true), (tl!("Opaque"), false)] {
|
|
if widgets::radio(ui, label, color && transparent == on, color) {
|
|
d.fields.insert("transparentPreview".into(), json!(on));
|
|
}
|
|
ui.add_space(12.0);
|
|
}
|
|
});
|
|
ui.add_space(8.0);
|
|
widgets::subheader(ui, tl!("Transparency"));
|
|
let overprints: Vec<(&str, &str)> = Overprint::ALL.iter().map(|o| (o.id(), o.label())).collect();
|
|
choice(ui, d, "overprints", tl!("Overprints:"), &overprints);
|
|
let presets = app.session.flattener_presets();
|
|
let names: Vec<(&str, &str)> = presets.iter().map(|p| (p.name.as_str(), p.name.as_str())).collect();
|
|
choice(ui, d, "flattenerPreset", tl!("Preset:"), &names);
|
|
ui.add_space(8.0);
|
|
widgets::subheader(ui, tl!("Fonts"));
|
|
// Type is written as glyph outlines, which need no fonts.
|
|
widgets::check(ui, tl!("Embed Fonts (for other applications)"), true, false);
|
|
ui.add_space(8.0);
|
|
widgets::subheader(ui, tl!("Options"));
|
|
check(ui, d, "includeLinkedFiles", tl!("Include Linked Files"));
|
|
check(ui, d, "thumbnails", tl!("Include Document Thumbnails"));
|
|
check(ui, d, "cmykPostScript", tl!("Include CMYK PostScript in RGB Files"));
|
|
check(ui, d, "compatibleGradients", tl!("Compatible Gradient and Gradient Mesh Printing"));
|
|
ui.add_space(4.0);
|
|
let levels: Vec<(&str, &str)> = Level::ALL.iter().map(|l| (l.id(), l.label())).collect();
|
|
// A level set as a number (`level: 2`) reads as its id.
|
|
if let Some(Value::Number(n)) = d.fields.get("level") {
|
|
let id = n.to_string();
|
|
d.fields.insert("level".into(), json!(id));
|
|
}
|
|
choice(ui, d, "level", tl!("PostScript:"), &levels);
|
|
ui.add_space(8.0);
|
|
super::form::caption(
|
|
ui,
|
|
if Level::from_id(&d.str("level")) == Some(Level::Two) || d.bool("compatibleGradients") {
|
|
tl!("Transparency is flattened with the preset. Type is written as outlines; gradients as bands of colour.")
|
|
} else {
|
|
tl!("Transparency is flattened with the preset. Type is written as outlines; gradients stay smooth.")
|
|
},
|
|
);
|
|
false
|
|
}
|
|
|
|
/// Check the options, remember them, and write the file(s).
|
|
fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
|
let params = fileio::eps::resolve(&super::form::params(d), &app.session.prefs.flattener_presets)?;
|
|
// Nothing selected keeps the dialog open too.
|
|
if let Some(st) = app.session.active() {
|
|
fileio::export_source(st, ¶ms).map_err(|e| e.to_string())?;
|
|
}
|
|
app.ui.eps_options =
|
|
Value::Object(d.fields.iter().filter(|(k, _)| !PER_EXPORT.contains(&k.as_str())).map(|(k, v)| (k.clone(), v.clone())).collect());
|
|
app.ui.dialog = None;
|
|
let path = d.fields.get("path").and_then(Value::as_str).map(str::to_string);
|
|
io::export(app, Some("eps"), path, ¶ms)
|
|
}
|