Paste in Place: art copied from off the artboards goes back where it was (fixes #1924)

This commit is contained in:
Marco Arnulfo
2026-10-16 02:56:35 +07:00
committed by bflatastic
parent d35ed26b0f
commit f2f1945973
2 changed files with 24 additions and 3 deletions
+10 -3
View File
@@ -80,7 +80,8 @@ pub struct Clipboard {
pub para_styles: Vec<TextStyleDef>,
/// Brushes the objects' strokes use.
pub brushes: Vec<Brush>,
/// The artboard the objects were copied from: Paste on All Artboards keeps their offset to it.
/// The artboard the objects were copied from (none when they lie on no artboard): Paste on All
/// Artboards keeps their offset to it.
pub source_artboard: Option<Rect>,
/// Per object: the name of the layer it was copied from (Paste Remembers Layers).
pub source_layers: Vec<Option<String>>,
@@ -109,8 +110,14 @@ impl Clipboard {
source_layers.push(anc.iter().rev().skip(1).find_map(|a| d.node(*a).filter(|l| l.is_layer())).and_then(|l| l.name.clone()));
}
let bounds = nodes.iter().filter_map(Node::visual_bounds).reduce(|a, b| a.union(b));
let board = bounds.and_then(|b| d.artboard_at(b.center())).unwrap_or(0);
Self { source_artboard: d.artboards.get(board).map(|a| a.rect), source_layers, source_doc: Some(st.uid), ..Self::gather(d, nodes) }
// Art on no artboard has no source artboard: in-place pastes put it back where it was (#1924).
let board = bounds.and_then(|b| d.artboard_at(b.center()));
Self {
source_artboard: board.and_then(|i| d.artboards.get(i)).map(|a| a.rect),
source_layers,
source_doc: Some(st.uid),
..Self::gather(d, nodes)
}
}
/// Every object of `src` (each top-level layer's contents) with its resources, for Place and
+14
View File
@@ -571,6 +571,20 @@ fn in_place_pastes_go_onto_the_artboard_named() {
}
}
/// Art copied from beside the artboards goes back where it was, whichever artboard is active (#1924).
#[test]
fn in_place_pastes_of_art_off_the_artboards_stay_where_it_was() {
let mut s = Session::new();
s.execute("file.new", &json!({"width": 200, "height": 100, "artboards": 2})).unwrap();
let boards: Vec<Rect> = doc(&s).artboards.iter().map(|a| a.rect).collect();
let r = rect(&mut s, boards[0].x0 - 100.0, boards[0].y0 + 15.0, 20.0, 20.0);
copy(&mut s, &[r]);
for cmd in ["edit.pasteInPlace", "edit.pasteInFront", "edit.pasteInBack"] {
let ids = ids_of(&s.execute(cmd, &json!({"artboard": 1})).unwrap());
assert_eq!(doc(&s).bounds_of(&ids, false).unwrap().origin(), Point::new(boards[0].x0 - 100.0, boards[0].y0 + 15.0), "{cmd}");
}
}
#[test]
fn paste_remembers_layers_restores_the_source_layers() {
let mut s = session();