Object: Hide Unselected Artwork keeps a selected layer's art and groups that hold locked guides

With a layer selected, Object > Hide > Unselected Artwork hid every object
on that layer, since the selected layer was dropped from the objects to
keep. The objects of a selected layer now count as selected.

While Lock Guides is on, a group that held a guide path was hidden whole,
which hid the guide with it. Guide paths now count as selected, so the
command keeps such a group visible and hides its other members one by one.
This commit is contained in:
dotCooCoo
2026-10-29 18:46:47 +07:00
committed by bflatastic
parent 9c01829cbb
commit d93657c631
3 changed files with 49 additions and 12 deletions
+19 -10
View File
@@ -79,7 +79,7 @@ pub fn specs() -> Vec<CommandSpec> {
"Unselected Artwork",
["Object", "Hide"],
Some("Cmd+Alt+Shift+3"),
"{} hide, in one undo step, every object select.all takes that is not selected and holds no selected object; in a group that holds one it hides the other members one by one, and a clip group, compound path or other object that holds one stays as it is; guide paths stay as they are while Lock Guides is on; object.showAll shows them again; disabled in isolation mode → {count}",
"{} hide, in one undo step, every object select.all takes that is not selected and holds no selected object; in a group that holds one it hides the other members one by one, and a clip group, compound path or other object that holds one stays as it is; the objects of a selected layer count as selected; while Lock Guides is on, guide paths count as selected and stay as they are; object.showAll shows them again; disabled in isolation mode → {count}",
has_selection_outside_isolation,
hide_unselected
),
@@ -322,17 +322,26 @@ fn other_layers(s: &mut Session, lock: bool) -> Result<Value> {
}
/// The objects [`super::select::walk_selectable`] visits that are not among the selected objects `roots` and hold none of
/// them. The walk goes into a plain group that holds one of `roots`; a clip group, a Shaper group, a compound path and
/// every other object that holds one is left out with its members. Guide paths are left out while `guides_locked`.
fn unselected(d: &vectorcraft_doc::Document, iso: Option<NodeId>, roots: &[NodeId], guides_locked: bool) -> Vec<NodeId> {
let holds: HashSet<NodeId> = d.index_paths(roots.iter().copied()).values().filter_map(|p| d.ancestry_at(p)).flatten().collect();
let roots: HashSet<NodeId> = roots.iter().copied().collect();
/// them. The objects of a selected layer count as selected. Guide paths are left out while `guides_locked`, and so are
/// the objects that hold one. The walk goes into a plain group that holds a selected object or such a guide path; a
/// clip group, a Shaper group, a compound path and every other object that holds one is left out with its members.
fn unselected(d: &vectorcraft_doc::Document, iso: Option<NodeId>, selection: &[NodeId], roots: &[NodeId], guides_locked: bool) -> Vec<NodeId> {
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 mut kept: Vec<NodeId> = roots.iter().copied().collect();
if guides_locked {
super::select::walk_selectable(d, iso, |n| {
if matches!(n.kind, NodeKind::Path { guide: true, .. }) {
kept.push(n.id);
}
true
});
}
let holds: HashSet<NodeId> = d.index_paths(kept).values().filter_map(|p| d.ancestry_at(p)).flatten().collect();
let mut out = vec![];
super::select::walk_selectable(d, iso, |n| {
if !holds.contains(&n.id) {
if !(guides_locked && matches!(n.kind, NodeKind::Path { guide: true, .. })) {
out.push(n.id);
}
out.push(n.id);
return false;
}
!roots.contains(&n.id) && matches!(n.kind, NodeKind::Group { clip: false, .. }) && n.extras().shaper.is_none()
@@ -344,7 +353,7 @@ fn hide_unselected(s: &mut Session, _: &Value) -> Result<Value> {
let roots = selected_roots_to_transform(s)?;
let guides_locked = s.menu.guides_locked;
let st = s.doc()?;
let ids = unselected(&st.doc, st.isolation, &roots, guides_locked);
let ids = unselected(&st.doc, st.isolation, &st.selection.objects, &roots, guides_locked);
// With nothing to hide, the document and its undo history stay as they are.
if !ids.is_empty() {
s.edit("Hide", |d, _| {