Smart Guides: a moved selection reaches ruler guides within the Snapping Tolerance

With Smart Guides on, a selection moved with the Selection tool, Direct
Selection or a shape tool reached a ruler guide only within the Snap to
Point distance (2 px), while drawn points and bounding-box handles reach
it within the Snapping Tolerance (4 px). The move now uses the Snapping
Tolerance for the grabbed point and the edges, with and without Shift.
With Smart Guides off, Snap to Point keeps its own distance.
This commit is contained in:
dotCooCoo
2026-11-12 19:59:19 -08:00
parent e899f3fdb4
commit b89ddeccd0
2 changed files with 39 additions and 5 deletions
+5 -4
View File
@@ -239,7 +239,8 @@ pub(crate) struct MoveSnap {
copy_targets: Option<Targets>,
copy_points: Option<Targets>,
/// With Smart Guides on, the ruler guides View › Snap to Point still pulls the grabbed point
/// onto (#1534), and lines the bounds up with (#5746); `points` holds them with Smart Guides off.
/// onto (#1534), and lines the bounds up with (#5746), within the Snapping Tolerance as drawing
/// does; `points` holds them with Smart Guides off.
rulers: Option<Targets>,
}
@@ -303,7 +304,7 @@ impl MoveSnap {
// axis without one that Smart Guides left free, the bounds line up with the ruler guides
// (#5746), alongside the Smart Guides.
if let Some(t) = &self.rulers {
let (adj, ov, held) = t.snap_moved_to_rulers(start + d, self.bounds.map(|b| b + d), cx.tol(cx.snap_tolerance), taken);
let (adj, ov, held) = t.snap_moved_to_rulers(start + d, self.bounds.map(|b| b + d), cx.snap_tol(), taken);
if adj != Vec2::ZERO {
d += adj;
if held {
@@ -373,7 +374,7 @@ impl MoveSnap {
}
}
if let Some(t) = &self.rulers {
let (q, ov) = t.snap_point_along(start + d, u, cx.tol(cx.snap_tolerance));
let (q, ov) = t.snap_point_along(start + d, u, cx.snap_tol());
if q != start + d {
d = q - start;
guides = ov;
@@ -382,7 +383,7 @@ impl MoveSnap {
{
// Nothing else lined up: the bounds slide along the line onto a ruler guide, as
// they do without Shift (#4312).
let (adj, ov) = t.snap_moved_along_to_rulers(start + d, b + d, u, cx.tol(cx.snap_tolerance));
let (adj, ov) = t.snap_moved_along_to_rulers(start + d, b + d, u, cx.snap_tol());
d += adj;
guides = ov;
}
+34 -1
View File
@@ -751,7 +751,7 @@ fn escape_cancels_a_move_or_an_alt_drag_copy() {
}
/// #1534: with Smart Guides on (the default), the point a selection is dragged by still snaps
/// to a ruler guide within the Snap to Point distance; not with Snap to Point off.
/// to a ruler guide within the Snapping Tolerance; not with Snap to Point off.
#[test]
fn a_move_snaps_the_grabbed_point_to_a_ruler_guide_with_smart_guides_on() {
let (mut d, id) = doc_with_rect();
@@ -797,6 +797,39 @@ fn a_shift_move_lands_the_edges_on_a_ruler_guide() {
assert!(moved_by(m, (231.0, 0.0)), "{m:?}");
}
/// With Smart Guides on, a moved selection reaches a ruler guide within the Snapping Tolerance
/// (4 px), as drawing and handle drags do; with Smart Guides off, Snap to Point reaches it within
/// its own distance (2 px).
#[test]
fn a_move_reaches_ruler_guides_within_the_snapping_tolerance() {
let (mut d, id) = doc_with_rect();
d.add_ruler_guide(&vectorcraft_doc::Guide::new(true, 340.0));
let mut s = Selection::default();
s.add(id);
let p = paint();
let dx = |c: &ToolContext, to: f64| {
let mut t = SelectionTool::default();
t.pointer(c, &ev(PointerKind::Down, 150.0, 150.0));
let a = t.pointer(c, &ev(PointerKind::Drag, to, 150.0));
let Some(Action::Preview(_, v)) = a.last() else { panic!("{a:?}") };
v["matrix"][4].as_f64().unwrap()
};
let c = cx(&d, &s, &p);
assert!(c.smart_guides && c.snap_to_point && c.guides);
// The right edge, 3 px short of the guide, lands on it, with or without Shift.
assert_eq!(dx(&c, 150.0 + 137.0), 140.0);
let (m, _) = shift_moved(&c, (150.0 + 137.0, 150.0));
assert!(moved_by(m, (140.0, 0.0)), "{m:?}");
// The grabbed point, 3 px from the guide, lands on it.
assert_eq!(dx(&c, 337.0), 190.0);
// 5 px away is out of reach.
assert_eq!(dx(&c, 150.0 + 135.0), 135.0);
// Smart Guides off: the grabbed point lands on the guide from 1.5 px, not from 3 px.
let off = ToolContext { smart_guides: false, ..cx(&d, &s, &p) };
assert_eq!(dx(&off, 338.5), 190.0);
assert_eq!(dx(&off, 337.0), 187.0);
}
/// Alt pressed during a move makes a copy, which snaps to the original it leaves behind (as
/// gathered before the previews moved it); released, the move doesn't.
#[test]