From ed96b2ff6575cf2266ced902459972965050715b Mon Sep 17 00:00:00 2001 From: bflatastic Date: Wed, 14 Oct 2026 06:22:03 +0700 Subject: [PATCH] Marquee guide selection: one shared helper for both selection tools --- crates/tools/src/direct.rs | 18 ++---------------- crates/tools/src/rulerguide.rs | 13 +++++++++++-- crates/tools/src/select.rs | 18 ++---------------- 3 files changed, 15 insertions(+), 34 deletions(-) diff --git a/crates/tools/src/direct.rs b/crates/tools/src/direct.rs index 56c68f0e..f6ed7124 100644 --- a/crates/tools/src/direct.rs +++ b/crates/tools/src/direct.rs @@ -730,22 +730,8 @@ impl Tool for DirectSelectionTool { } sel.retain(|(id, _)| cx.doc.is_editable(*id)); let items: Vec = sel.iter().map(|(id, v)| json!({"id": id.0, "anchors": anchors_json(v)})).collect(); - let guides = crate::rulerguide::guides_in_rect(cx, r); - let mut out = vec![]; - if toggle { - if !items.is_empty() { - out.push(Action::Exec("select.anchorsMany".into(), json!({"items": items, "mode": "toggle"}))); - } - if !guides.is_empty() { - out.push(Action::Exec("guide.select".into(), json!({ "indexes": guides, "toggle": true }))); - } - } else { - out.push(Action::Exec("select.anchorsMany".into(), json!({"items": items, "mode": "set"}))); - if !guides.is_empty() { - out.push(Action::Exec("guide.select".into(), json!({ "indexes": guides, "toggle": true }))); - } - } - out + let art = Action::Exec("select.anchorsMany".into(), json!({"items": items, "mode": if toggle { "toggle" } else { "set" }})); + std::iter::once(art).chain(crate::rulerguide::marquee_select(cx, r)).collect() } _ => vec![], } diff --git a/crates/tools/src/rulerguide.rs b/crates/tools/src/rulerguide.rs index 53f98bc6..1683ac51 100644 --- a/crates/tools/src/rulerguide.rs +++ b/crates/tools/src/rulerguide.rs @@ -2,7 +2,8 @@ //! made where it is released over the canvas: with the Artboard tool, an artboard guide of the //! active artboard. For the selection tools ([`GuideEdit`]), a press on a guide selects it (Shift //! adds it to the selected guides or, released without a drag, takes it out); dragging moves the -//! selected guides (Alt copies them). A dragged guide snaps ([`GuideSnap`]): with Shift to the +//! selected guides (Alt copies them), and a marquee selects the guides it crosses along with the +//! art ([`marquee_select`]). A dragged guide snaps ([`GuideSnap`]): with Shift to the //! ruler's ticks, else to whole pixels, the grid, with Smart Guides the art's and the artboards' //! edges, centres and anchors, or with Snap to Point the anchors. Dropped off the canvas onto its //! ruler, a moved guide is deleted. Hidden or locked guides (View › Guides), and guides on a hidden @@ -32,8 +33,16 @@ pub fn guide_at(cx: &ToolContext, p: Point) -> Option { .map(|(i, _)| i) } +/// What a selection tool's marquee `r` does to the ruler guides, after its action selecting the +/// art: the guides it crosses join the selection (with a Shift marquee, the selected ones leave +/// it, as with a Shift-click on a guide). +pub fn marquee_select(cx: &ToolContext, r: Rect) -> Option { + let guides = guides_in_rect(cx, r); + (!guides.is_empty()).then(|| Action::Exec("guide.select".into(), json!({ "indexes": guides, "toggle": true }))) +} + /// The editable ruler guides intersecting marquee rectangle `r`. -pub fn guides_in_rect(cx: &ToolContext, r: Rect) -> Vec { +fn guides_in_rect(cx: &ToolContext, r: Rect) -> Vec { if !cx.guides { return vec![]; } diff --git a/crates/tools/src/select.rs b/crates/tools/src/select.rs index 262bf536..92826893 100644 --- a/crates/tools/src/select.rs +++ b/crates/tools/src/select.rs @@ -459,22 +459,8 @@ impl Tool for SelectionTool { return if toggle { vec![] } else { vec![Action::Exec("select.none".into(), json!({}))] }; } let ids: Vec = marquee(cx.doc, r, cx.isolation, false); - let guides = crate::rulerguide::guides_in_rect(cx, r); - let mut out = vec![]; - if toggle { - if !ids.is_empty() { - out.push(Action::Exec("select.toggle".into(), json!({ "ids": json_ids(&ids) }))); - } - if !guides.is_empty() { - out.push(Action::Exec("guide.select".into(), json!({ "indexes": guides, "toggle": true }))); - } - } else { - out.push(Action::Exec("select.set".into(), json!({ "ids": json_ids(&ids) }))); - if !guides.is_empty() { - out.push(Action::Exec("guide.select".into(), json!({ "indexes": guides, "toggle": true }))); - } - } - out + let art = Action::Exec(if toggle { "select.toggle" } else { "select.set" }.into(), json!({ "ids": json_ids(&ids) })); + std::iter::once(art).chain(crate::rulerguide::marquee_select(cx, r)).collect() } _ => vec![], }