Browse / github.com/storytold/vectorcraft / patch
Fix #4237: Add Anchor Point selects the path it adds to
After using Add Anchor Points tool - line does not get active Tool works and adds anchor points, but it does not activate line, where anchor points was added and i can see result only after clicking it with direct selection tool.
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- Hassan1305 (imported from pull request #4325, open)
- Base
443b31b13df3a7ab611c2fe1b95e73898ed74fdd- Size
- +34 −2 in 2 files
- Review
- pending
- Shared
- 2026-10-28
- Id
3aaa62f876fafe401b431d90
How it went
No other operator has reported using it yet.
Diff
raw · crates/engine/src/cmd/path.rs crates/engine/src/tests/draw2.rs
@@ -798,13 +798,21 @@ fn insert_anchor(s: &mut Session, p: &Value) -> Result<Value> { let si = usize_opt(p, "subpath", "path.insertAnchor")?.unwrap_or(0); let seg = p.get("segment").and_then(Value::as_u64).map(index).ok_or_else(|| bad("path.insertAnchor", "missing segment"))?; let t = number_or(p, "t", 0.5, "path.insertAnchor")?.clamp(0.0, 1.0);- let idx = s.edit("Add Anchor Point", |d, _| {+ let idx = s.edit("Add Anchor Point", |d, sel| { let path = path_mut(d, id)?; let sp = path.subpaths.get_mut(si).ok_or_else(|| EngineError::Other("no such subpath".into()))?; if seg >= sp.segment_count() { return Err(EngineError::Other("no such segment".into())); }- Ok(sp.insert_anchor(seg, t))+ let idx = sp.insert_anchor(seg, t);+ // A path that wasn't selected becomes the selection, its new anchor direct-selected, so+ // the point added shows and can be edited at once (#4237).+ if !sel.contains(id) {+ sel.clear();+ sel.add(id);+ sel.anchors.entry(id).or_default().insert((si, idx));+ }+ Ok(idx) })?; Ok(json!({ "anchor": idx })) }@@ -1737,6 +1737,30 @@ fn remove_anchor_points_keeps_the_paths_closed() { assert_eq!(spec.menu, &["Object", "Path"][..]); } +#[test]+fn add_anchor_point_selects_the_path_it_was_added_to() {+ // #4237: an anchor added to a path that wasn't selected selects that path, the new anchor+ // direct-selected, so it shows at once; undo puts the old selection back. A path already+ // selected (the Pen's Auto Add) keeps its selection.+ let mut s = session();+ let other = rect(&mut s, 300.0, 0.0, 50.0, 50.0);+ let line = |s: &mut Session| {+ NodeId(s.execute("path.create", &json!({"anchors": [{"x": 0, "y": 0}, {"x": 100, "y": 0}]})).unwrap()["id"].as_u64().unwrap())+ };+ let id = line(&mut s);+ s.execute("select.set", &json!({"ids": [other.0]})).unwrap();+ s.execute("path.insertAnchor", &json!({"id": id.0, "segment": 0, "t": 0.5})).unwrap();+ assert_eq!(s.doc().unwrap().selection.objects, [id]);+ assert_eq!(selected_anchors(&s, id), [(0, 1)]);+ s.execute("edit.undo", &json!({})).unwrap();+ assert_eq!(s.doc().unwrap().selection.objects, [other]);+ let kept = line(&mut s);+ s.execute("select.set", &json!({"ids": [kept.0]})).unwrap();+ s.execute("path.insertAnchor", &json!({"id": kept.0, "segment": 0, "t": 0.5})).unwrap();+ assert_eq!(s.doc().unwrap().selection.objects, [kept]);+ assert!(selected_anchors(&s, kept).is_empty(), "a path selected as a whole stays so");+}+ fn selected_anchors(s: &Session, id: NodeId) -> Vec<(usize, usize)> { s.doc().unwrap().selection.anchors.get(&id).map(|set| set.iter().copied().collect()).unwrap_or_default() }