mirror of
https://github.com/storytold/figcraft.git
synced 2026-10-25 19:06:47 -06:00
* fix(ui): SVG and PDF export rows offer no size (#256) The size picker (1x, 2x, 512w…) showed on every export row, but SVG and PDF are vector and their export ignores it (export_bytes_with). It now shows for PNG, JPG and WebP only, and the suffix field takes its width. Refs #256 ("exporting to SVG is offered in different resolutions, although this should not be the case"). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * fix(ui): export size field as an Option; test WebP too (#256) From review: the size field's width is an Option instead of a negative width, and the test checks WebP as well as JPG. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3f5f673ebc
commit
c846f157dc
@@ -60,20 +60,23 @@ pub fn section(app: &mut FigApp, ui: &mut Ui, doc: &Document, sel: &[NodeId]) {
|
||||
}
|
||||
}
|
||||
|
||||
/// One export setting: size (typed or picked), suffix, format, advanced options and remove; a
|
||||
/// PDF's print settings under it.
|
||||
/// One export setting: size (typed or picked; images only, SVG and PDF are vector), suffix,
|
||||
/// format, advanced options and remove; a PDF's print settings under it.
|
||||
fn setting_row(app: &mut FigApp, ui: &mut Ui, ids: &[NodeId], i: usize, e: &ExportSetting) {
|
||||
row(ui, 32.0, |ui| {
|
||||
// Tighter spacing so the advanced options and remove buttons fit beside the fields.
|
||||
ui.spacing_mut().item_spacing.x = 4.0;
|
||||
let (size_w, format_w, button, gap) = (52.0, 54.0, 22.0, ui.spacing().item_spacing.x);
|
||||
let suffix_w = (ui.available_width() - size_w - format_w - button * 2.0 - gap * 4.0).max(32.0);
|
||||
let presets: Vec<String> =
|
||||
ExportSize::SCALES.iter().map(|value| ExportSize::Scale { value: *value }.label()).chain(["512w".into(), "512h".into()]).collect();
|
||||
if let Some(s) = widgets::combo_field(ui, Id::new(("export_size", i)), &e.size.label(), size_w, &presets)
|
||||
&& ExportSize::parse(&s) != Some(e.size)
|
||||
{
|
||||
app.run("export.update", json!({"ids": ids, "index": i, "size": s}));
|
||||
let (format_w, button, gap) = (54.0, 22.0, ui.spacing().item_spacing.x);
|
||||
let size_w = e.format.is_raster().then_some(52.0);
|
||||
let suffix_w = (ui.available_width() - size_w.map_or(0.0, |w| w + gap) - format_w - button * 2.0 - gap * 3.0).max(32.0);
|
||||
if let Some(size_w) = size_w {
|
||||
let presets: Vec<String> =
|
||||
ExportSize::SCALES.iter().map(|value| ExportSize::Scale { value: *value }.label()).chain(["512w".into(), "512h".into()]).collect();
|
||||
if let Some(s) = widgets::combo_field(ui, Id::new(("export_size", i)), &e.size.label(), size_w, &presets)
|
||||
&& ExportSize::parse(&s) != Some(e.size)
|
||||
{
|
||||
app.run("export.update", json!({"ids": ids, "index": i, "size": s}));
|
||||
}
|
||||
}
|
||||
if let Some(sfx) = widgets::text_field(ui, Id::new(("export_suffix", i)), &e.suffix, suffix_w, tr("Suffix"))
|
||||
&& sfx != e.suffix
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! The Export section's Preview row: a slice paints nothing itself, so its preview must show the
|
||||
//! page content under it — the same thing exporting the slice writes — and not a blank
|
||||
//! transparency checkerboard next to a correct export.
|
||||
//! transparency checkerboard next to a correct export. And its setting rows: a size only for
|
||||
//! images.
|
||||
|
||||
use figcraft_doc::{Document, NodeId};
|
||||
use figcraft_engine::Session;
|
||||
@@ -50,3 +51,28 @@ fn other_layers_preview_themselves() {
|
||||
assert_eq!([pix.width(), pix.height()], [200, 100], "the layer's own area");
|
||||
assert!(paints(&pix));
|
||||
}
|
||||
|
||||
/// SVG and PDF are vector: their export rows offer no size, which their export ignores (#256).
|
||||
#[test]
|
||||
fn export_rows_offer_a_size_for_images_only() {
|
||||
let mut s = Session::new();
|
||||
let r = crate::present_tests::id(&s.execute("shape.rectangle", &json!({"x": 0, "y": 0, "width": 100, "height": 80})).unwrap());
|
||||
s.execute("select.set", &json!({"ids": [r]})).unwrap();
|
||||
s.execute("export.add", &json!({"ids": [r]})).unwrap();
|
||||
let mut u = crate::layers_drag_tests::Ui::new(s);
|
||||
let size_menu = |u: &crate::layers_drag_tests::Ui| u.ctx.read_response(egui::Id::new(("export_size", 0)).with("menu")).is_some();
|
||||
u.frame(vec![]);
|
||||
assert!(size_menu(&u), "PNG has sizes");
|
||||
for format in ["svg", "pdf"] {
|
||||
u.app.run("export.update", json!({"ids": [r], "index": 0, "format": format}));
|
||||
u.frame(vec![]);
|
||||
u.frame(vec![]);
|
||||
assert!(!size_menu(&u), "{format} is vector: no size");
|
||||
}
|
||||
for format in ["jpg", "webp"] {
|
||||
u.app.run("export.update", json!({"ids": [r], "index": 0, "format": format}));
|
||||
u.frame(vec![]);
|
||||
u.frame(vec![]);
|
||||
assert!(size_menu(&u), "{format} has sizes again");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user