mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 18:10:01 -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:
@@ -143,7 +143,7 @@ pub(super) fn ungroup(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
}
|
||||
|
||||
pub(super) fn lock(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
let ids = selected_roots(s)?;
|
||||
let ids = selected_lock_hide_roots(s)?;
|
||||
// With every selected object already locked, the document and its undo history stay as they
|
||||
// are, and the objects are deselected.
|
||||
let d = &s.doc()?.doc;
|
||||
@@ -163,6 +163,16 @@ pub(super) fn lock(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
ok()
|
||||
}
|
||||
|
||||
/// The selected objects ([`selected_roots`]) that Lock › Selection and Hide › Selection change: in
|
||||
/// isolation mode, only those inside the isolated object, where a path of the isolated compound
|
||||
/// path is an object of its own.
|
||||
fn selected_lock_hide_roots(s: &Session) -> Result<Vec<NodeId>> {
|
||||
match crate::cmd::ordinary_isolation(s.doc()?) {
|
||||
Some(root) => crate::cmd::edit::selected_roots_inside(s, root, false),
|
||||
None => selected_roots(s),
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_flag(d: &Document, f: impl Fn(&Node) -> bool) -> Vec<NodeId> {
|
||||
let mut v = vec![];
|
||||
d.walk(|n| {
|
||||
@@ -174,14 +184,28 @@ fn collect_flag(d: &Document, f: impl Fn(&Node) -> bool) -> Vec<NodeId> {
|
||||
}
|
||||
|
||||
/// The objects that `f` picks for `object.unlockAll` and `object.showAll` (`cmd`): in the whole
|
||||
/// document, or with `scope: "group"` inside the groups that hold the selected objects. A selected
|
||||
/// group is the group that holds its own members, and the objects of a group inside another such
|
||||
/// group are taken once. With `scope: "group"` and no selected object in a group, it returns an
|
||||
/// error.
|
||||
/// document, inside the isolated object in isolation mode, or with `scope: "group"` inside the
|
||||
/// groups that hold the selected objects (in isolation mode, only the objects of those groups
|
||||
/// that are inside the isolated object). A selected group is the group that holds its own
|
||||
/// members, and the objects of a group inside another such group are taken once. With
|
||||
/// `scope: "group"` and no selected object in a group, it returns an error.
|
||||
fn collect_flag_in_scope(s: &Session, cmd: &str, p: &Value, f: impl Fn(&Node) -> bool) -> Result<Vec<NodeId>> {
|
||||
let st = s.doc()?;
|
||||
let d = &st.doc;
|
||||
if choice(p, cmd, "scope", &["document", "group"])? != Some("group") {
|
||||
if let Some(root) = crate::cmd::ordinary_isolation(st) {
|
||||
let mut ids = vec![];
|
||||
if let Some(node) = d.node(root) {
|
||||
for child in node.children().into_iter().flatten() {
|
||||
child.walk(&mut |n| {
|
||||
if !n.is_layer() && f(n) {
|
||||
ids.push(n.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return Ok(ids);
|
||||
}
|
||||
return Ok(collect_flag(d, f));
|
||||
}
|
||||
let is_group = |id: &NodeId| d.node(*id).is_some_and(|n| matches!(n.kind, NodeKind::Group { .. }));
|
||||
@@ -204,6 +228,10 @@ fn collect_flag_in_scope(s: &Session, cmd: &str, p: &Value, f: impl Fn(&Node) ->
|
||||
});
|
||||
}
|
||||
}
|
||||
// In isolation mode only the objects inside the isolated object are taken.
|
||||
if let Some(root) = crate::cmd::ordinary_isolation(st) {
|
||||
v.retain(|id| crate::cmd::inside_isolation(d, root, *id));
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
@@ -226,7 +254,7 @@ pub(super) fn unlock_all(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
|
||||
pub(super) fn hide(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
let ids = selected_roots(s)?;
|
||||
let ids = selected_lock_hide_roots(s)?;
|
||||
// With every selected object already hidden, the document and its undo history stay as they
|
||||
// are, and the objects are deselected.
|
||||
let d = &s.doc()?.doc;
|
||||
|
||||
@@ -6,7 +6,7 @@ use super::props::set_props;
|
||||
use super::shape::{expand_shape, set_live_shape};
|
||||
use super::transform::{move_cmd, nudge, reflect, rotate, scale, shear, transform, transform_again};
|
||||
use super::{CommandSpec, cmd, has_doc, has_multi, has_selection, has_selection_or_guides};
|
||||
use crate::cmd::{has_selection_outside_isolation, outside_isolation};
|
||||
use crate::cmd::has_selected_member;
|
||||
|
||||
pub fn specs() -> Vec<CommandSpec> {
|
||||
vec![
|
||||
@@ -150,8 +150,8 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Selection",
|
||||
["Object", "Lock"],
|
||||
Some("Cmd+2"),
|
||||
"{ids?: [id…] (selected first; default: the selection)}",
|
||||
has_selection_outside_isolation,
|
||||
"{ids?: [id…] (selected first; default: the selection; in isolation mode, only those inside the isolated object)}",
|
||||
has_selected_member,
|
||||
lock
|
||||
),
|
||||
cmd!(
|
||||
@@ -159,8 +159,8 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Unlock All",
|
||||
["Object"],
|
||||
Some("Cmd+Alt+2"),
|
||||
"{scope?: \"document\"|\"group\" (default document; group: only the objects inside the groups that hold the selected objects, a selected group holding its own; the in-window menu item chosen with Shift+Alt)} unlock the locked objects and select them → {count}",
|
||||
outside_isolation,
|
||||
"{scope?: \"document\"|\"group\" (default document, which in isolation mode is the isolated object; group: only the objects inside the groups that hold the selected objects, a selected group holding its own; the in-window menu item chosen with Shift+Alt)} unlock the locked objects and select them → {count}",
|
||||
has_doc,
|
||||
unlock_all
|
||||
),
|
||||
cmd!(
|
||||
@@ -168,8 +168,8 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Selection",
|
||||
["Object", "Hide"],
|
||||
Some("Cmd+3"),
|
||||
"{ids?: [id…] (selected first; default: the selection)}",
|
||||
has_selection_outside_isolation,
|
||||
"{ids?: [id…] (selected first; default: the selection; in isolation mode, only those inside the isolated object)}",
|
||||
has_selected_member,
|
||||
hide
|
||||
),
|
||||
cmd!(
|
||||
@@ -177,8 +177,8 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Show All",
|
||||
["Object"],
|
||||
Some("Cmd+Alt+3"),
|
||||
"{scope?: \"document\"|\"group\" (default document; group: only the objects inside the groups that hold the selected objects, a selected group holding its own; the in-window menu item chosen with Shift+Alt)} show the hidden objects and select them → {count}",
|
||||
outside_isolation,
|
||||
"{scope?: \"document\"|\"group\" (default document, which in isolation mode is the isolated object; group: only the objects inside the groups that hold the selected objects, a selected group holding its own; the in-window menu item chosen with Shift+Alt)} show the hidden objects and select them → {count}",
|
||||
has_doc,
|
||||
show_all
|
||||
),
|
||||
cmd!(
|
||||
|
||||
Reference in New Issue
Block a user