mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 17:56:50 -06:00
Merge pull request #2498 from vangel76/fix/2383-merge-selected-sublayer
Layers: Merge Selected with a layer and its sublayer highlighted merges into the last top-level layer (#2383)
This commit is contained in:
@@ -271,8 +271,19 @@ fn merge(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if ids.len() < 2 {
|
||||
return Err(bad(C, "highlight two or more rows to merge"));
|
||||
}
|
||||
let into =
|
||||
ids.iter().rev().copied().find(|id| d.node(*id).is_some_and(Node::is_layer)).ok_or_else(|| bad(C, "highlight a layer to merge into"))?;
|
||||
// The last highlighted layer that is not inside another highlighted row: with a layer and its
|
||||
// sublayer both highlighted (Select All in the panel), the sublayer travels with its layer
|
||||
// instead of becoming the target (#2383).
|
||||
let roots: HashSet<NodeId> = row_roots(d, &ids).into_iter().collect();
|
||||
let is_layer = |id: &NodeId| d.node(*id).is_some_and(Node::is_layer);
|
||||
let into = ids
|
||||
.iter()
|
||||
.rev()
|
||||
.copied()
|
||||
.filter(is_layer)
|
||||
.find(|id| roots.contains(id))
|
||||
.or_else(|| ids.iter().rev().copied().find(is_layer))
|
||||
.ok_or_else(|| bad(C, "highlight a layer to merge into"))?;
|
||||
let around = d.ancestry(into).unwrap_or_default();
|
||||
// (Rows inside the target layer merge too: only rows inside other listed rows go with those.)
|
||||
let rest: Vec<NodeId> = ids.iter().copied().filter(|id| *id != into).collect();
|
||||
|
||||
@@ -578,7 +578,11 @@ fn collect_merge_flatten_and_reverse() {
|
||||
run(&mut s, "layer.merge", json!({"ids": [col.0, layer.0]}));
|
||||
assert!(s.doc().unwrap().doc.node(col).is_none());
|
||||
assert_eq!(children(&s, layer), vec![c, sub, a, g]);
|
||||
assert!(s.execute("layer.merge", &json!({"ids": [layer.0, sub.0]})).is_err(), "not into its own sublayer");
|
||||
// A layer and its sublayer: the sublayer merges into its layer, never the other way round.
|
||||
run(&mut s, "layer.merge", json!({"ids": [layer.0, sub.0]}));
|
||||
assert!(s.doc().unwrap().doc.node(sub).is_none());
|
||||
assert_eq!(children(&s, layer), vec![c, a, g]);
|
||||
run(&mut s, "edit.undo", json!({}));
|
||||
assert!(s.execute("layer.merge", &json!({"ids": [layer.0]})).is_err());
|
||||
// Flatten: other visible layers merge in, hidden ones go, templates stay.
|
||||
let l2 = id(&run(&mut s, "layer.new", json!({"top": true})));
|
||||
@@ -595,6 +599,32 @@ fn collect_merge_flatten_and_reverse() {
|
||||
assert_eq!(undos(&s), before + 1);
|
||||
}
|
||||
|
||||
/// Merge Selected with every row highlighted (a layer, its sublayer and another layer, in panel
|
||||
/// order) merges the layers into the last top-level one instead of refusing a sublayer target (#2383).
|
||||
#[test]
|
||||
fn merge_selected_with_all_layer_rows_highlighted_merges_into_the_last_top_level_layer() {
|
||||
for reversed in [false, true] {
|
||||
let mut s = session();
|
||||
let (layer, sub, a, _, _, c) = tree(&mut s);
|
||||
let l2 = id(&run(&mut s, "layer.new", json!({"top": true})));
|
||||
let d = rect(&mut s, 500.0);
|
||||
// Panel order, top first: Layer 2, Layer 1, its sublayer.
|
||||
let mut rows = vec![l2.0, layer.0, sub.0];
|
||||
if reversed {
|
||||
rows.reverse();
|
||||
}
|
||||
run(&mut s, "layer.highlight", json!({"ids": rows}));
|
||||
let into = id(&run(&mut s, "layer.merge", json!({})));
|
||||
let st = s.doc().unwrap();
|
||||
assert_eq!(st.doc.layers.len(), 1, "reversed: {reversed}");
|
||||
assert_eq!(into, st.doc.layers[0].id);
|
||||
for n in [a, c, d] {
|
||||
assert!(st.doc.layer_of(n) == Some(into), "{n:?} reversed: {reversed}");
|
||||
}
|
||||
assert!(st.doc.node(sub).is_some() || st.doc.node(layer).is_some() || st.doc.node(l2).is_some());
|
||||
}
|
||||
}
|
||||
|
||||
/// Collect in New Layer puts the new layer beside the topmost row when that row is directly in a
|
||||
/// layer, and on top of the layer holding its group when it is in a group. When that row is in a
|
||||
/// hidden or locked layer, the selected art it collects from another layer is deselected, the key
|
||||
|
||||
Reference in New Issue
Block a user