mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Artboards: the canvas outlines the active artboard in black
The canvas drew artboard 1's edge in black, 1 px wide, whichever artboard was active, and drew every other artboard's edge in gray, 0.6 px wide. It now draws the active artboard's edge in black and draws the other artboards' edges in gray, at the same widths. The active artboard is the artboard that the status bar's navigator shows and that Align to Artboard and Paste in Place use. With several artboards selected by the Artboard tool, it is the one the tool draws with handles and its name. Docs: docs/target-app-parity.md.
This commit is contained in:
@@ -409,7 +409,7 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
|
||||
}
|
||||
// Artboard edges and names. The Artboard tool labels its active artboard itself (following
|
||||
// a move or resize): that one isn't named twice.
|
||||
let active_ab = 0;
|
||||
let active_ab = crate::panels::artboards::selected(app, doc.artboards.len());
|
||||
let artboard_tool = app.session.tool_id() == "artboard";
|
||||
let tool_labelled = artboard_tool.then(|| app.session.tool_options()["active"].as_u64()).flatten();
|
||||
for (i, ab) in doc.artboards.iter().enumerate() {
|
||||
@@ -2574,6 +2574,56 @@ mod tests {
|
||||
assert_eq!(lefts(&app), [boards[1].x0; 2], "an artboard the caller names is kept");
|
||||
}
|
||||
|
||||
/// The canvas outlines the active artboard in black, 1 px wide, and outlines the other
|
||||
/// artboards in gray, 0.6 px wide. In the test, the active artboard is Artboard 1 at first,
|
||||
/// then the one Go to Artboard went to, and then, with several artboards selected by the
|
||||
/// Artboard tool, the tool's active one (the one Shift-clicked last).
|
||||
#[test]
|
||||
fn the_active_artboard_is_outlined_in_black() {
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
app.session.execute("file.new", &json!({"width": 200, "height": 100, "artboards": 3})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
// → each artboard's edge as drawn: (width, color).
|
||||
let edges = |app: &mut VectorcraftApp| {
|
||||
let s = shapes(app, &ctx);
|
||||
let xf = Xf::new(app.canvas_rect.unwrap(), app.view().unwrap());
|
||||
let on = |p: &[Pos2], q: &[Pos2]| p.len() == q.len() && p.iter().zip(q).all(|(a, b)| (*a - *b).length() < 0.01);
|
||||
let boards: Vec<Rect> = app.session.active().unwrap().doc.artboards.iter().map(|a| a.rect).collect();
|
||||
boards
|
||||
.iter()
|
||||
.map(|r| {
|
||||
let q = xf.quad(*r);
|
||||
s.iter()
|
||||
.find_map(|s| match s {
|
||||
Shape::Path(p) if p.closed && p.fill == Color32::TRANSPARENT && on(&p.points, &q) => {
|
||||
Some((p.stroke.width, p.stroke.color.clone()))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.expect("the artboard's edge")
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let (black, gray) = (egui::epaint::ColorMode::Solid(Color32::from_gray(0)), egui::epaint::ColorMode::Solid(Color32::from_gray(120)));
|
||||
let active = |i: usize| -> Vec<(f32, egui::epaint::ColorMode)> {
|
||||
(0..3).map(|j| if j == i { (1.0, black.clone()) } else { (0.6, gray.clone()) }).collect()
|
||||
};
|
||||
assert_eq!(edges(&mut app), active(0));
|
||||
app.run("view.goToArtboard", json!({"index": 1})).unwrap();
|
||||
assert_eq!(edges(&mut app), active(1), "Artboard 2 is active: its edge is black and Artboard 1's edge is gray");
|
||||
// The Artboard tool starts on Artboard 2; a Shift-click on Artboard 3 selects it too and
|
||||
// makes it the active one.
|
||||
app.select_tool("artboard");
|
||||
let at = app.session.active().unwrap().doc.artboards[2].rect.center();
|
||||
let view = app.view_info();
|
||||
let shift = Mods { shift: true, ..Default::default() };
|
||||
for kind in [PointerKind::Down, PointerKind::Up] {
|
||||
dispatch(&mut app, &PointerEvent { kind, pos: at, mods: shift, pressure: 1.0 }, view);
|
||||
}
|
||||
assert_eq!(app.session.tool_options()["selected"], json!([2, 1]));
|
||||
assert_eq!(edges(&mut app), active(2), "Artboard 3 is the active one of the two selected");
|
||||
}
|
||||
|
||||
/// Enable Touch Gestures (#585): a two-finger tap undoes and a three-finger one redoes, and the
|
||||
/// first finger's press (the pointer egui makes of it) draws nothing. Off, a tap does nothing.
|
||||
#[test]
|
||||
|
||||
@@ -495,6 +495,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
Align to Artboard uses the active artboard, the one the Artboards panel highlights (`object.align {artboard}`). A press with a selection tool inside an artboard makes that artboard active; with the Selection tool, a Shift-click on an empty spot inside an artboard makes it active and keeps the selection. One selected object is aligned to the active artboard too, whatever Align To says (a lone object is never the key object). When an action plays, its Align to Artboard, All on Active Artboard, Paste in Place, Paste in Front and Paste in Back steps that name no artboard use the artboard that is active then.
|
||||
With Align to Artboard chosen, the Align panel's Distribute Objects and Distribute Spacing buttons use the active artboard (`object.distribute` and `object.distributeSpacing` with `to: "artboard"` and `artboard`). The first object's left or top edge goes to the artboard's left or top edge, and the last object's right or bottom edge goes to the artboard's right or bottom edge. Distribute Objects spaces the other objects evenly by its button's line, and two objects are enough. Distribute Spacing makes the gaps between the objects equal. With anchor points selected, the buttons space the points among themselves and do not use the artboard. When an action plays, its Distribute Objects and Distribute Spacing steps with Align to Artboard use the artboard that is active then.
|
||||
Choosing the Artboard tool (Shift+O, its toolbar button, Edit Artboards in Properties or Document Setup, or the Artboards panel menu's Artboard Options…) starts it on the active artboard: the canvas outlines that artboard, and Delete, Cut, Copy, the Transform panel and Artboard Options act on it.
|
||||
The canvas draws the active artboard's edge in black, as the public [Select artboards](https://helpx.adobe.com/illustrator/desktop/create-manage-artboards/add-edit-artboards/select-artboards.html) page describes. It draws the other artboards' edges in gray. With several artboards selected by the Artboard tool, the canvas draws the black edge around the active one, which the tool shows with handles and its name. It used to draw artboard 1's edge in black whichever artboard was active.
|
||||
View › Rotate View turns the view to the status bar's preset angles (`view.rotate {angle}`, which takes any angle).
|
||||
When the view angle changes (a Rotate View drag, the status bar's angle menu, Reset Rotate View or a saved view) and the desktop app renders the frame at the new angle on the render worker, the canvas draws the last frame turned to the new angle until that frame is ready. It used to draw no art until then.
|
||||
The status bar navigator's field shows the active artboard's number and name, and its drop-down lists every artboard by number and name, as the Artboards panel does. Choosing an artboard in the list makes it the active artboard and fits it in the window (`view.goToArtboard`). The list opens on the active artboard's row and lays out only the rows in view and at most one more.
|
||||
|
||||
Reference in New Issue
Block a user