Puppet Warp pins go where they are dragged, without snapping (#8217)

A pin drag took the active tool's snapping. With the Move tool that was a
layer move's Smart Guides, which View > Snap doesn't turn off, so pins jumped
to other layers' edges with snapping off. Puppet Warp and Perspective Warp
drags no longer snap, as in Photoshop.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
paulou-jpg
2026-10-23 17:40:39 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 4bda8d7388
commit 0bd37f81af
+27 -1
View File
@@ -204,7 +204,9 @@ pub(crate) fn retarget_move(app: &mut PhotocraftApp, p: [f64; 2], mods: egui::Mo
fn begin(app: &mut PhotocraftApp, p: [f64; 2], mods: egui::Modifiers) {
app.prefs_rt.snap = None;
app.prefs_rt.snap_lines.clear();
if app.session.active().is_none() {
// Puppet Warp's pins and Perspective Warp's quads go where they are dragged, as in Photoshop:
// the press is theirs, not the tool's (with the Move tool it took a layer move's Smart Guides).
if app.session.active().is_none() || app.distort.active() {
return;
}
// The tool the press acts as: ⌘ makes a painting tool the Move tool, and a selection tool
@@ -711,6 +713,30 @@ mod tests {
assert!(app.prefs_rt.snap.is_none());
}
/// Puppet Warp's pins go where they are dragged: they don't snap, with View › Snap on or
/// off, whatever tool was active when it started. With the Move tool a pin drag took the
/// layer move's Smart Guides and jumped to the other layer's edges.
#[test]
fn puppet_warp_pins_never_snap() {
for (tool, snap) in [(Tool::Move, false), (Tool::Move, true), (Tool::RectMarquee, true), (Tool::Brush, false)] {
let mut app = app_with_box();
app.ui.tool = tool;
app.ui.extras.snap = snap;
app.ui.view.show.smart_guides = true;
app.run("view.newGuide", json!({"orientation": "vertical", "position": 321})).unwrap();
let ctx = egui::Context::default();
crate::distort_ui::menu(&mut app, &ctx, "edit.puppetWarp", &json!({})).unwrap().unwrap();
let m = egui::Modifiers::NONE;
crate::canvas::tool_event(&mut app, ToolEvent::Down { x: 60.0, y: 60.0, pressure: 1.0 }, m);
// The mover's left edge 3 px right of the target's, the pin 2 px from the guide.
crate::canvas::tool_event(&mut app, ToolEvent::Move { x: 323.0, y: 100.0, pressure: 1.0 }, m);
assert!(app.prefs_rt.snap_lines.is_empty(), "{tool:?}, snap {snap}: {:?}", app.prefs_rt.snap_lines);
crate::canvas::tool_event(&mut app, ToolEvent::Up { x: 323.0, y: 100.0 }, m);
let pins = &app.distort.puppet.as_ref().unwrap().warp.pins;
assert_eq!(pins.iter().map(|p| p.dst).collect::<Vec<_>>(), vec![[323.0, 100.0]], "{tool:?}, snap {snap}");
}
}
/// ⌘ turns a painting tool, or a marquee outside the selection, into the Move tool for the
/// drag: it gets the Move tool's box and smart-guide snapping, not the selected tool's.
#[test]