mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 18:10:01 -06:00
Artboards: Artboard Options' Show Center Mark and Show Cross Hairs draw on the canvas
The Artboard Options help pages describe two display options (https://helpx.adobe.com/illustrator/desktop/create-manage-artboards/organize-manage-artboards/modify-display-settings-of-artboards.html, .../set-video-display-options-for-artboards.html): a mark at the artboard's center, and lines from the middle of each side through the center. The document already had show_center_mark and show_cross_hairs on Artboard, but nothing set or drew them. artboard.setProps (each `artboards` entry too) and artboard.new take showCenterMark and showCrossHairs as true/false, in the same single undo step as the other fields; a locked artboard can still change them. Artboard Options has both checkboxes, filled in from the artboard whether it opens from the panel or a double-click with the Artboard tool, and its New Artboard form passes them to artboard.new. The canvas draws them in the new theme token artboard_mark, 1 point wide on screen at any zoom: a cross 12 points across at the center whose arms follow the artboard's sides, and the two cross hairs. They are screen-only like the edges; exports and print never read the fields. inspect_document reports them when on. Saved files are unchanged: the two keys were already always written, so a document that never shows them saves byte for byte as before, and a file without the keys opens with both off. Video safe areas, video rulers and the pixel aspect ratio are not part of this change. Verification: artboard_display_marks_are_set_and_cleared_in_one_undo_step, artboard_display_marks_round_trip_through_the_native_format, artboard_display_marks_stay_out_of_exports (SVG and PDF identical with the marks on and off), an_artboard_shows_its_center_mark_and_cross_hairs (positions, screen-constant size under zoom, rotated view) and artboard_options_show_center_mark_and_cross_hairs. cargo xtask ci: all 10 steps passed.
This commit is contained in:
committed by
bflatastic
parent
08cfb45561
commit
64f6d2db50
@@ -1,8 +1,11 @@
|
||||
//! Artboard Options (double-click with the Artboard tool, double-click the tool, or the Artboards
|
||||
//! panel's options icon or menu): the artboard's fields, sizes parsed with units, its position
|
||||
//! from a reference point, and its background color (`color`: a color as the paint commands take
|
||||
//! it, or null for none). Sizing choices also go to the other selected artboards; fitting
|
||||
//! changes only the active artboard around stationary artwork.
|
||||
//! from a reference point, its background color (`color`: a color as the paint commands take
|
||||
//! it, or null for none), and Show Center Mark and Show Cross Hairs (`showCenterMark`,
|
||||
//! `showCrossHairs`), the display marks the canvas draws on the artboard
|
||||
//! (https://helpx.adobe.com/illustrator/desktop/create-manage-artboards/organize-manage-artboards/modify-display-settings-of-artboards.html).
|
||||
//! Sizing choices also go to the other selected artboards; fitting changes only the active
|
||||
//! artboard around stationary artwork.
|
||||
|
||||
use serde_json::{Value, json};
|
||||
use vectorcraft_color::Color;
|
||||
@@ -32,7 +35,7 @@ fn placed(d: &Dialog) -> Rect {
|
||||
/// as the Transform panel and the Control bar show an artboard's. A new Width or Height keeps the
|
||||
/// reference point where it was, as their sizes do.
|
||||
/// Then Background Color: the Fill list (None, White, Black; Custom for another color) and a swatch
|
||||
/// that picks a color of its own.
|
||||
/// that picks a color of its own, and the Show Center Mark and Show Cross Hairs checkboxes.
|
||||
fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
let (unit, origin, refi) = (app.session.general_unit(), app.ruler_origin(), reference_index(ui));
|
||||
let (was, w0, h0) = (placed(d), d.f64("width", 0.0), d.f64("height", 0.0));
|
||||
@@ -92,6 +95,9 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
if let Some(c) = set {
|
||||
d.fields.insert("color".into(), c.as_ref().map_or(Value::Null, crate::panels::color_json));
|
||||
}
|
||||
ui.add_space(8.0);
|
||||
form::check(ui, d, "showCenterMark", tl!("Show Center Mark"));
|
||||
form::check(ui, d, "showCrossHairs", tl!("Show Cross Hairs"));
|
||||
false
|
||||
}
|
||||
|
||||
@@ -194,7 +200,10 @@ pub fn open(app: &mut VectorcraftApp) -> Result<Value, String> {
|
||||
let a = st.doc.artboards.get(index).ok_or("no artboard")?;
|
||||
let r = a.rect;
|
||||
let color = a.color.as_ref().map(crate::panels::color_json);
|
||||
let fields = json!({"index": index, "name": a.name, "x": r.x0, "y": r.y0, "width": r.width(), "height": r.height(), "color": color});
|
||||
let fields = json!({
|
||||
"index": index, "name": a.name, "x": r.x0, "y": r.y0, "width": r.width(), "height": r.height(), "color": color,
|
||||
"showCenterMark": a.show_center_mark, "showCrossHairs": a.show_cross_hairs,
|
||||
});
|
||||
app.ui.dialog = Some(Dialog::new(KIND, fields));
|
||||
Ok(json!({ "dialog": KIND }))
|
||||
}
|
||||
@@ -265,8 +274,9 @@ pub fn open_new(app: &mut VectorcraftApp) -> Result<Value, String> {
|
||||
Ok(json!({ "dialog": KIND }))
|
||||
}
|
||||
|
||||
/// OK for a new artboard: `artboard.new` with the fields (an empty name gives the default one) and
|
||||
/// the background color picked, and the new artboard becomes the active one.
|
||||
/// OK for a new artboard: `artboard.new` with the fields (an empty name gives the default one),
|
||||
/// the background color picked and the display marks ticked, and the new artboard becomes the
|
||||
/// active one.
|
||||
fn confirm_new(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
||||
let mut p = json!({});
|
||||
for k in ["x", "y", "width", "height"] {
|
||||
@@ -279,6 +289,11 @@ fn confirm_new(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
||||
if let Some(c) = d.fields.get("color") {
|
||||
p["color"] = c.clone();
|
||||
}
|
||||
for k in ["showCenterMark", "showCrossHairs"] {
|
||||
if d.bool(k) {
|
||||
p[k] = json!(true);
|
||||
}
|
||||
}
|
||||
let r = run_and_close(app, "artboard.new", p)?;
|
||||
if let Some(i) = r["index"].as_u64().and_then(|i| usize::try_from(i).ok()) {
|
||||
crate::panels::artboards::select(app, i);
|
||||
|
||||
@@ -1102,6 +1102,56 @@ fn new_artboard_options_give_the_new_artboard_its_background_color() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Artboard Options shows Show Center Mark and Show Cross Hairs, ticked as the artboard has them
|
||||
/// whether it opens from the Artboards panel or from a double-click with the Artboard tool. OK
|
||||
/// sets them in one undo step, and a new artboard's Artboard Options gives it the ones ticked.
|
||||
#[test]
|
||||
fn artboard_options_show_center_mark_and_cross_hairs() {
|
||||
use vectorcraft_tools::{PointerEvent, PointerKind};
|
||||
let mut app = app();
|
||||
let marks = |app: &VectorcraftApp, i: usize| {
|
||||
let a = &app.session.doc().unwrap().doc.artboards[i];
|
||||
(a.show_center_mark, a.show_cross_hairs)
|
||||
};
|
||||
crate::dialogs::artboard_options::open(&mut app).unwrap();
|
||||
let text = crate::tests_labels::painted_text(&mut app, |app, ui| show(app, ui.ctx()));
|
||||
assert!(text.contains("Show Center Mark") && text.contains("Show Cross Hairs"), "{text}");
|
||||
let d = app.ui.dialog.as_mut().unwrap();
|
||||
assert!(!d.bool("showCenterMark") && !d.bool("showCrossHairs"));
|
||||
d.fields.insert("showCenterMark".into(), json!(true));
|
||||
let undo = app.session.doc().unwrap().history.undo.len();
|
||||
super::confirm(&mut app).unwrap();
|
||||
assert_eq!(marks(&app, 0), (true, false));
|
||||
assert_eq!(app.session.doc().unwrap().history.undo.len(), undo + 1);
|
||||
// Opened again, it shows them; unticking one clears it.
|
||||
crate::dialogs::artboard_options::open(&mut app).unwrap();
|
||||
let d = app.ui.dialog.as_mut().unwrap();
|
||||
assert!(d.bool("showCenterMark"));
|
||||
d.fields.insert("showCenterMark".into(), json!(false));
|
||||
d.fields.insert("showCrossHairs".into(), json!(true));
|
||||
super::confirm(&mut app).unwrap();
|
||||
assert_eq!(marks(&app, 0), (false, true));
|
||||
// A double-click with the Artboard tool on the artboard's empty space.
|
||||
app.select_tool("artboard");
|
||||
let view = app.view_info();
|
||||
for kind in [PointerKind::Down, PointerKind::Up, PointerKind::Down, PointerKind::Up, PointerKind::DoubleClick] {
|
||||
crate::canvas::dispatch(&mut app, &PointerEvent::new(kind, 100.0, 100.0), view);
|
||||
}
|
||||
let d = app.ui.dialog.clone().expect("Artboard Options opened");
|
||||
assert_eq!((d.kind.as_str(), d.bool("showCenterMark"), d.bool("showCrossHairs")), ("artboardOptions", false, true));
|
||||
cancel(&mut app);
|
||||
// A new artboard takes the ones ticked, and none when none is.
|
||||
for (ticked, want) in [(Some("showCenterMark"), (true, false)), (None, (false, false))] {
|
||||
app.run("ui.newArtboard", json!({})).unwrap();
|
||||
if let Some(k) = ticked {
|
||||
app.ui.dialog.as_mut().unwrap().fields.insert(k.into(), json!(true));
|
||||
}
|
||||
super::confirm(&mut app).unwrap();
|
||||
let last = app.session.doc().unwrap().doc.artboards.len() - 1;
|
||||
assert_eq!(marks(&app, last), want);
|
||||
}
|
||||
}
|
||||
|
||||
/// #1482: with Artboards 1 and 3 selected with the Artboard tool, a new Width in Artboard Options
|
||||
/// goes to both, each keeping its top-left corner and its height, in one undo step. The new name
|
||||
/// goes only to the artboard the dialog shows, and Artboard 2 keeps its size. A name alone resizes
|
||||
|
||||
Reference in New Issue
Block a user