Fix #311: Pen: Auto Add/Delete on a selected path

Between paths, the Pen now adds an anchor where a click lands on a
segment of a selected path and deletes the anchor a click lands on,
with the add and delete cursors while hovering, as in the reference
app. The ends of a selected open path still continue it. Shift held,
or General > Disable Auto Add/Delete (a stored preference nothing read
until now, passed to tools as ToolContext::auto_add_delete), starts a
new path instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
theironchef
2026-10-08 03:22:31 +07:00
committed by bflatastic
co-authored by Claude Opus 5.5
parent 0830ad68c3
commit 133390ef7a
4 changed files with 128 additions and 4 deletions
+27
View File
@@ -252,6 +252,33 @@ fn pen_tool_draws_closed_path() {
assert!(p.is_closed());
}
/// Auto Add/Delete: a Pen click on a selected path's segment adds an anchor, unless General →
/// Disable Auto Add/Delete is on.
#[test]
fn pen_click_on_a_selected_path_adds_an_anchor_unless_disabled() {
let mut s = session();
let v = ViewInfo::default();
let r = s.execute("path.create", &json!({"anchors": [{"x": 10, "y": 100}, {"x": 110, "y": 100}, {"x": 210, "y": 100}]})).unwrap();
let id = NodeId(r["id"].as_u64().unwrap());
s.execute("select.all", &json!({})).unwrap();
s.select_tool("pen", v).unwrap();
let click = |s: &mut Session| {
s.pointer(&PointerEvent::new(PointerKind::Down, 60.0, 101.0), v).unwrap();
s.pointer(&PointerEvent::new(PointerKind::Up, 60.0, 101.0), v).unwrap();
};
click(&mut s);
let d = &s.doc().unwrap().doc;
assert_eq!(d.layers[0].children().unwrap().len(), 1);
assert_eq!(d.node(id).unwrap().path_data().unwrap().anchor_count(), 4);
s.execute("edit.undo", &json!({})).unwrap();
s.execute("prefs.set", &json!({"key": "disableAutoAddDelete", "value": true})).unwrap();
s.execute("select.all", &json!({})).unwrap();
click(&mut s);
let d = &s.doc().unwrap().doc;
assert_eq!(d.layers[0].children().unwrap().len(), 2, "a new path starts");
assert_eq!(d.node(id).unwrap().path_data().unwrap().anchor_count(), 3);
}
#[test]
fn direct_selection_moves_one_anchor() {
let mut s = session();
+1
View File
@@ -138,6 +138,7 @@ impl Session {
paste_plain_text: self.prefs.paste_text_formatting == "plain",
slices_hidden: self.menu.slices_hidden,
slices_locked: self.menu.slices_locked,
auto_add_delete: !self.prefs.disable_auto_add_delete,
screen: view.screen,
plane_widget: self.prefs.perspective_widget.show.then_some(self.prefs.perspective_widget.position),
};