Isolation mode: double-clicking a single object isolates it

With Double Click To Isolate on, the Selection tool isolated groups only. A
double-click on a single path, compound path, image, mesh or placed file now
isolates it too, as the public documentation describes. Type still switches to
the Type tool; blends, envelopes, repeats and symbol instances keep their own
editing modes.

While a single object is isolated only it is hit, marqueed and taken by Select
All, new art goes beside it in its group or layer, and a double-click on the
empty canvas leaves with it selected. object.isolate accepts any object except
type.
This commit is contained in:
Ayberk A.
2026-10-12 18:56:41 +07:00
committed by bflatastic
parent 412e83c825
commit 3073f0ab03
9 changed files with 104 additions and 15 deletions
+4 -1
View File
@@ -632,7 +632,10 @@ mod tests {
let cx2 = cx(&d, &whole, &p);
let a = crate::create("selection").pointer(&cx2, &PointerEvent::new(PointerKind::DoubleClick, 190.0, 110.0));
assert_eq!(a, vec![Action::Dialog(DIALOG.into(), json!({"id": id.0, "corners": [0, 1, 2, 3]}))]);
assert!(crate::create("selection").pointer(&cx2, &PointerEvent::new(PointerKind::DoubleClick, 150.0, 150.0)).is_empty());
// Off the widgets, the Selection tool's double-click isolates the shape (Double Click To
// Isolate) instead.
let a = crate::create("selection").pointer(&cx2, &PointerEvent::new(PointerKind::DoubleClick, 150.0, 150.0));
assert_eq!(a, vec![Action::Exec("object.isolate".into(), json!({"id": id.0}))]);
}
/// Hide Corner Widget for angles greater than (#394): a rectangle's right angles hide below
+12 -5
View File
@@ -3,8 +3,8 @@
//! Guides, or with them off View › Snap to Point, snap it),
//! bounding-box scale (Shift proportional, Alt from centre) and rotate (outside corners, Shift 45°),
//! drag a live rectangle's or polygon's corner widget to round its corners (Alt-click cycles their kind,
//! double-click opens the Corners dialog), double-click to enter isolation mode (Double Click To
//! Isolate), Cmd/Ctrl-click to select the object behind (Command Click to Select Objects Behind),
//! double-click opens the Corners dialog), double-click a group or an object to enter isolation
//! mode (Double Click To Isolate), Cmd/Ctrl-click to select the object behind (Command Click to Select Objects Behind),
//! click or drag a ruler guide ([`crate::rulerguide`]), drag the brackets of type on a path
//! ([`crate::pathtype`]), double-click the type widget to convert point type to area type and back
//! ([`crate::typewidget`]).
@@ -260,12 +260,19 @@ impl Tool for SelectionTool {
}
if let Some(h) = hit_test(cx.doc, p, cx.hit_options()) {
let top = h.top_object(cx.isolation);
if cx.double_click_isolate && cx.doc.node(top).is_some_and(|n| matches!(n.kind, vectorcraft_doc::NodeKind::Group { .. })) {
return vec![Action::Exec("object.isolate".into(), json!({ "id": top.0 }))];
}
if cx.doc.node(top).is_some_and(|n| matches!(n.kind, vectorcraft_doc::NodeKind::Text(_))) {
return vec![Action::SwitchTool("type".into())];
}
// A group, a compound path or a single path, image, mesh or placed file, not
// the one already isolated. Blends, envelopes, repeats and symbol instances
// aren't: they have editing modes of their own.
use vectorcraft_doc::NodeKind as K;
let isolates = cx.doc.node(top).is_some_and(|n| {
matches!(n.kind, K::Group { .. } | K::Compound { .. } | K::Path { .. } | K::Image(_) | K::Mesh(_) | K::PlacedDocument(_))
});
if cx.double_click_isolate && isolates && cx.isolation != Some(top) {
return vec![Action::Exec("object.isolate".into(), json!({ "id": top.0 }))];
}
} else if cx.isolation.is_some() {
return vec![Action::Exec("object.exitIsolation".into(), json!({}))];
}