mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Keep Layers panel selection inside the isolated group
Fixes #2286 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Haiku 5.5
parent
ee6cd6de55
commit
e510190867
@@ -412,6 +412,9 @@ fn target(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if !st.doc.is_editable(id) {
|
||||
return Err(bad(C, "the object is hidden or locked"));
|
||||
}
|
||||
if !in_isolation(&st.doc, st.isolation, id) {
|
||||
return Err(bad(C, "the object is outside the isolated group"));
|
||||
}
|
||||
let layer = n.is_layer();
|
||||
let rows = st.layer_rows.clone();
|
||||
if p.get("add").and_then(Value::as_bool).unwrap_or(false) {
|
||||
@@ -645,6 +648,11 @@ fn collect(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
Ok(json!({ "id": lid.0 }))
|
||||
}
|
||||
|
||||
/// Whether `id` lies inside the isolated group or layer (always, outside isolation mode).
|
||||
fn in_isolation(doc: &Document, isolation: Option<NodeId>, id: NodeId) -> bool {
|
||||
isolation.is_none_or(|iso| iso != id && doc.ancestry(id).is_some_and(|a| a.contains(&iso)))
|
||||
}
|
||||
|
||||
/// The selection column: select a row's art.
|
||||
fn select_art(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
const C: &str = "layer.selectAll";
|
||||
@@ -652,7 +660,7 @@ fn select_art(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let add = bool_or(p, "add", false);
|
||||
let st = s.doc()?;
|
||||
let n = st.doc.node(id).ok_or(EngineError::NoNode(id))?;
|
||||
let ids: Vec<NodeId> = if !st.doc.is_editable(id) {
|
||||
let ids: Vec<NodeId> = if !st.doc.is_editable(id) || !in_isolation(&st.doc, st.isolation, id) {
|
||||
vec![]
|
||||
} else if n.is_layer() {
|
||||
n.layer_art(true)
|
||||
|
||||
@@ -1014,6 +1014,35 @@ fn select_menu_commands_stay_inside_the_isolated_group() {
|
||||
assert_eq!(selected(&s), vec![a, b, text_inside]);
|
||||
}
|
||||
|
||||
/// In isolation mode the Layers panel's target circle and selection column can't select an object
|
||||
/// outside the isolated group, so it can't be moved either (#2286).
|
||||
#[test]
|
||||
fn layers_panel_selects_nothing_outside_the_isolated_group() {
|
||||
let mut s = session();
|
||||
let a = rect(&mut s, 0.0, 0.0, 50.0, 50.0);
|
||||
let b = rect(&mut s, 100.0, 0.0, 50.0, 50.0);
|
||||
let outside = rect(&mut s, 300.0, 0.0, 50.0, 50.0);
|
||||
sel(&mut s, &[a, b]);
|
||||
let g = id_of(&s.execute("object.group", &json!({})).unwrap());
|
||||
s.execute("object.isolate", &json!({"id": g.0})).unwrap();
|
||||
let before = bounds(&s, outside);
|
||||
let _ = s.execute("layer.target", &json!({"id": outside.0}));
|
||||
assert!(!selected(&s).contains(&outside));
|
||||
let _ = s.execute("layer.target", &json!({"id": outside.0, "add": true}));
|
||||
assert!(!selected(&s).contains(&outside));
|
||||
let _ = s.execute("layer.selectAll", &json!({"id": outside.0}));
|
||||
assert!(!selected(&s).contains(&outside));
|
||||
let _ = s.execute("layer.selectAll", &json!({"id": outside.0, "add": true}));
|
||||
assert!(!selected(&s).contains(&outside));
|
||||
let _ = s.execute("object.move", &json!({"dx": 10, "dy": 0}));
|
||||
assert_eq!(bounds(&s, outside), before);
|
||||
// Objects inside the group can still be targeted and selected.
|
||||
s.execute("layer.target", &json!({"id": a.0})).unwrap();
|
||||
assert_eq!(selected(&s), vec![a]);
|
||||
s.execute("layer.selectAll", &json!({"id": b.0})).unwrap();
|
||||
assert_eq!(selected(&s), vec![b]);
|
||||
}
|
||||
|
||||
/// In isolation mode a recalled selection leaves out the objects outside the isolated group, and
|
||||
/// Next Object Above selects nothing outside it.
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user