mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 09:59:47 -06:00
Isolation mode: Lock, Unlock All, Hide and Show All work on the isolated art
Squashed from #4849 onto main.
This commit is contained in:
@@ -566,17 +566,29 @@ pub(crate) fn selected_roots(s: &Session) -> Result<Vec<NodeId>> {
|
||||
/// rest still go to the compound path, which holds the paint.
|
||||
pub(crate) fn selected_roots_to_transform(s: &Session) -> Result<Vec<NodeId>> {
|
||||
let st = s.doc()?;
|
||||
Ok(roots_within(&st.doc, st.selection.in_paint_order(&st.doc), true))
|
||||
Ok(roots_within(&st.doc, st.selection.in_paint_order(&st.doc), |_| true))
|
||||
}
|
||||
|
||||
/// [`selected_roots`] for the selected objects inside the isolated object `root`
|
||||
/// ([`super::inside_isolation`]): `root` itself and objects outside it are left out before the
|
||||
/// objects held by another selected object are dropped. A selected path of a compound path stands
|
||||
/// for its compound unless the compound is `root` or `members` is set (as in
|
||||
/// [`selected_roots_to_transform`]).
|
||||
pub(crate) fn selected_roots_inside(s: &Session, root: NodeId, members: bool) -> Result<Vec<NodeId>> {
|
||||
let st = s.doc()?;
|
||||
let ids = st.selection.in_paint_order(&st.doc).into_iter().filter(|id| super::inside_isolation(&st.doc, root, *id)).collect();
|
||||
Ok(roots_within(&st.doc, ids, |compound| members || compound == root))
|
||||
}
|
||||
|
||||
/// The top-level objects among `ids` (in paint order): compound-path members stand for their
|
||||
/// compound, and ids whose ancestor is also listed, and layers, are dropped.
|
||||
pub(crate) fn roots_of(doc: &Document, ids: Vec<NodeId>) -> Vec<NodeId> {
|
||||
roots_within(doc, ids, false)
|
||||
roots_within(doc, ids, |_| false)
|
||||
}
|
||||
|
||||
/// [`roots_of`]; with `members`, a compound path's member listed stays itself.
|
||||
fn roots_within(doc: &Document, ids: Vec<NodeId>, members: bool) -> Vec<NodeId> {
|
||||
/// [`roots_of`]; a compound path's member listed stays itself when `members` holds for the
|
||||
/// compound's id.
|
||||
fn roots_within(doc: &Document, ids: Vec<NodeId>, members: impl Fn(NodeId) -> bool) -> Vec<NodeId> {
|
||||
// Every id's place in the tree, found in one walk (a lookup per id is a walk per id).
|
||||
let paths = doc.index_paths(ids.iter().copied());
|
||||
// A compound-path member acts as its compound (compounds are one object).
|
||||
@@ -586,7 +598,7 @@ fn roots_within(doc: &Document, ids: Vec<NodeId>, members: bool) -> Vec<NodeId>
|
||||
let path = paths.get(&id);
|
||||
let parent = path.and_then(|p| p.split_last()).map(|(_, up)| up).filter(|up| !up.is_empty());
|
||||
match parent.and_then(|up| doc.node_at(up).map(|n| (up, n))) {
|
||||
Some((up, n)) if matches!(n.kind, vectorcraft_doc::NodeKind::Compound { .. }) && !members => (n.id, Some(up.to_vec())),
|
||||
Some((up, n)) if matches!(n.kind, vectorcraft_doc::NodeKind::Compound { .. }) && !members(n.id) => (n.id, Some(up.to_vec())),
|
||||
_ => (id, path.cloned()),
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user