Selection: a marquee selects an Intertwine group or a repeat only where it meets their art

A marquee measured an Intertwine group and a repeat by their bounding
box. A marquee in the gap between two members of an Intertwine group,
or between two copies of a repeat, selected the object, although a
click there misses and a plain group needs a marquee to meet one of its
members. Direct and Group Selection's marquees also selected the
Intertwine group whole beside the anchor points of its members.

The marquee now touches an Intertwine group by its members, as it
touches a plain group, and it touches a repeat by the copies the repeat
draws, as clicks hit them. Direct and Group Selection's marquees select
the anchor points of an Intertwine group's members, and Group
Selection's E marquee selects the members inside it. Blends, and
envelopes outside Edit Contents, keep their box, as clicks on them do.

Docs: docs/target-app-parity.md.
This commit is contained in:
dotCooCoo
2026-10-18 12:34:38 +07:00
committed by bflatastic
parent 7d56260b47
commit 438d27ffbe
3 changed files with 122 additions and 3 deletions
+29
View File
@@ -1450,6 +1450,35 @@ mod tests {
assert_eq!(a, vec![Action::Exec("select.anchorsMany".into(), json!({"items": [{"id": rect.0, "anchors": [[0, 1]]}], "mode": "set"}))]);
}
/// A marquee across a member of an Intertwine group selects the member's anchors, as in a
/// plain group, and not the Intertwine group whole.
#[test]
fn marquee_selects_the_anchors_of_intertwine_members() {
let mut d = vectorcraft_doc::Document::new(500.0, 500.0);
let l = d.layers[0].id;
let (a, b, g) = (d.alloc_id(), d.alloc_id(), d.alloc_id());
let path = |id, x| {
std::sync::Arc::new(vectorcraft_doc::Node::path(
id,
vectorcraft_geom::shapes::rectangle(Rect::new(x, 100.0, x + 100.0, 200.0)),
vectorcraft_doc::Appearance::default_art(),
))
};
let intertwine = vectorcraft_doc::Node::new(g, vectorcraft_doc::NodeKind::Intertwine { children: vec![path(a, 100.0), path(b, 300.0)] });
d.insert(Some(l), 0, intertwine).unwrap();
let s = Selection::default();
let p = paint();
let cx = cx(&d, &s, &p);
for group in [false, true] {
let mut t = DirectSelectionTool::new(group);
// Around the first member's top-right corner.
t.pointer(&cx, &PointerEvent::new(PointerKind::Down, 150.0, 50.0));
let actions = t.pointer(&cx, &PointerEvent::new(PointerKind::Up, 250.0, 150.0));
let items = json!([{"id": a.0, "anchors": [[0, 1]]}]);
assert_eq!(actions, vec![Action::Exec("select.anchorsMany".into(), json!({"items": items, "mode": "set"}))], "group: {group}");
}
}
/// Shift-drag a marquee: the anchors inside toggle (#483), with Group Selection too.
#[test]
fn shift_marquee_toggles_anchors() {