mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 23:01:02 +00:00
Merge pull request #5570 from dotCooCoo/fix/hide-others-locked-layer-and-guides
Object: Unselected Artwork keeps groups that hold a selected layer or a locked guide
This commit is contained in:
@@ -347,7 +347,7 @@ fn other_layers(s: &mut Session, lock: bool) -> Result<Value> {
|
||||
}
|
||||
|
||||
/// Returns the objects [`super::select::walk_selectable`] visits that are not among the selected objects `roots` and
|
||||
/// hold none of them. A selected layer's objects count as selected. The walk goes into a plain group, but not a Shaper
|
||||
/// hold none of them. A selected layer and its objects count as selected. The walk goes into a plain group, but not a Shaper
|
||||
/// group, that holds a selected object. With `lock`, it also goes into a clip group or compound path that holds one,
|
||||
/// and includes guide paths while `guides_locked`. Without `lock`, guide paths and the objects that hold one are left
|
||||
/// out while `guides_locked`; a clip group, Shaper group, compound path and every other object that holds a selected
|
||||
@@ -360,14 +360,32 @@ fn unselected(
|
||||
guides_locked: bool,
|
||||
lock: bool,
|
||||
) -> Vec<NodeId> {
|
||||
/// Pushes the visible guide paths in `n`, `n` included, locked ones too.
|
||||
fn shown_guides(n: &vectorcraft_doc::Node, out: &mut Vec<NodeId>) {
|
||||
if !n.visible {
|
||||
return;
|
||||
}
|
||||
if matches!(n.kind, NodeKind::Path { guide: true, .. }) {
|
||||
out.push(n.id);
|
||||
}
|
||||
for c in n.children().into_iter().flatten() {
|
||||
shown_guides(c, out);
|
||||
}
|
||||
}
|
||||
let mut roots: HashSet<NodeId> = roots.iter().copied().collect();
|
||||
roots.extend(selection.iter().filter_map(|id| d.node(*id)).filter(|n| n.is_layer()).flat_map(|l| l.layer_art(true)));
|
||||
let layers = || selection.iter().filter_map(|id| d.node(*id)).filter(|n| n.is_layer());
|
||||
roots.extend(layers().map(|l| l.id));
|
||||
roots.extend(layers().flat_map(|l| l.layer_art(true)));
|
||||
let mut kept: Vec<NodeId> = roots.iter().copied().collect();
|
||||
if guides_locked && !lock {
|
||||
super::select::walk_selectable(d, iso, |n| {
|
||||
if matches!(n.kind, NodeKind::Path { guide: true, .. }) {
|
||||
kept.push(n.id);
|
||||
}
|
||||
// The walk skips locked objects, so the guide paths in them are looked for here.
|
||||
for c in n.children().into_iter().flatten().filter(|c| c.locked) {
|
||||
shown_guides(c, &mut kept);
|
||||
}
|
||||
true
|
||||
});
|
||||
}
|
||||
|
||||
@@ -865,6 +865,51 @@ fn hide_unselected_artwork_keeps_groups_with_locked_guides_and_the_selected_laye
|
||||
assert_eq!(selected(&s), [other]);
|
||||
}
|
||||
|
||||
/// While Lock Guides is on, Hide › Unselected Artwork keeps a group visible when it holds a guide path that is locked
|
||||
/// itself, and hides the group's other members one by one.
|
||||
#[test]
|
||||
fn hide_unselected_artwork_keeps_groups_with_a_locked_guide_path() {
|
||||
let mut s = session();
|
||||
let a = rect(&mut s, 0.0, 0.0, 10.0, 10.0);
|
||||
let guide = rect(&mut s, 40.0, 0.0, 10.0, 10.0);
|
||||
let x = rect(&mut s, 60.0, 0.0, 10.0, 10.0);
|
||||
sel(&mut s, &[guide, x]);
|
||||
let g = id_of(&s.execute("object.group", &json!({})).unwrap());
|
||||
sel(&mut s, &[guide]);
|
||||
s.execute("view.guides.make", &json!({})).unwrap();
|
||||
s.execute("layer.setProps", &json!({"id": guide.0, "locked": true})).unwrap();
|
||||
s.execute("view.guides.lock", &json!({"locked": true})).unwrap();
|
||||
sel(&mut s, &[a]);
|
||||
assert_eq!(s.execute("object.hide.unselected", &json!({})).unwrap(), json!({"count": 1}));
|
||||
assert_eq!([a, g, guide, x].map(|id| node(&s, id).visible), [true, true, true, false]);
|
||||
}
|
||||
|
||||
/// Hide › Unselected Artwork keeps a group visible when it holds a selected layer whose art is all locked, and hides the
|
||||
/// group's other members one by one.
|
||||
#[test]
|
||||
fn hide_unselected_artwork_keeps_a_group_that_holds_a_selected_layer() {
|
||||
let mut s = session();
|
||||
let b = rect(&mut s, 0.0, 0.0, 10.0, 10.0);
|
||||
let y = rect(&mut s, 20.0, 0.0, 10.0, 10.0);
|
||||
let z = rect(&mut s, 40.0, 0.0, 10.0, 10.0);
|
||||
sel(&mut s, &[y]);
|
||||
let g = id_of(&s.execute("object.group", &json!({})).unwrap());
|
||||
let sub = s
|
||||
.edit("nest", |d, _| {
|
||||
let id = d.alloc_id();
|
||||
d.insert(Some(g), usize::MAX, Node::layer(id, "Sub", vectorcraft_doc::LayerColor::Preset(1)))
|
||||
.map_err(|e| EngineError::Other(e.to_string()))?;
|
||||
let art = d.remove(z).map_err(|e| EngineError::Other(e.to_string()))?;
|
||||
d.insert(Some(id), 0, (*art).clone()).map_err(|e| EngineError::Other(e.to_string()))?;
|
||||
Ok(id)
|
||||
})
|
||||
.unwrap();
|
||||
s.execute("layer.setProps", &json!({"id": z.0, "locked": true})).unwrap();
|
||||
sel(&mut s, &[sub]);
|
||||
assert_eq!(s.execute("object.hide.unselected", &json!({})).unwrap(), json!({"count": 2}));
|
||||
assert_eq!([b, g, y, sub, z].map(|id| node(&s, id).visible), [false, true, false, true, true]);
|
||||
}
|
||||
|
||||
/// Lock Unselected Artwork locks `b`, `n` in the group that holds selected `m`, `p` on another layer, and the clip
|
||||
/// group's unselected members `c1` and clipping path `c3` in one undo step labeled "Lock". The clip group container,
|
||||
/// `c2`, the selected objects, group `g`, hidden object `h` and art `q` on a locked layer stay unlocked. `k` was locked
|
||||
|
||||
Reference in New Issue
Block a user