Join the selected end points of two paths with Ctrl+J

Fixes #4163

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-26 08:18:33 +07:00
committed by bflatastic
co-authored by Claude Haiku 5.5
parent 6259448c39
commit b089b7e948
2 changed files with 35 additions and 2 deletions
+21 -2
View File
@@ -467,6 +467,9 @@ fn join(s: &mut Session, p: &Value) -> Result<Value> {
if a == b {
return Err(bad(C, "join two different paths"));
}
let st = s.doc()?;
let picked_a = st.selection.anchors.get(&a).cloned().unwrap_or_default();
let picked_b = st.selection.anchors.get(&b).cloned().unwrap_or_default();
s.edit("Join", |d, sel| {
let pb = d.node(b).and_then(|n| n.path_data()).cloned().ok_or(EngineError::NoNode(b))?;
let pa = path_mut(d, a)?;
@@ -481,8 +484,24 @@ fn join(s: &mut Session, p: &Value) -> Result<Value> {
// The ends asked for, else the closest pair.
let cands =
[(xl.distance(yf), false, false), (xl.distance(yl), false, true), (xf.distance(yf), true, false), (xf.distance(yl), true, true)];
let (rx, ry) =
ends.unwrap_or_else(|| cands.into_iter().min_by(|p, q| p.0.total_cmp(&q.0)).map_or((false, false), |(_, rx, ry)| (rx, ry)));
// Direct-selected end points decide which ends meet, before the closest pair does.
let end_of = |picked: &std::collections::BTreeSet<(usize, usize)>, si: usize, len: usize| {
let last_ix = len.checked_sub(1)?;
let first = picked.contains(&(si, 0));
let last = picked.contains(&(si, last_ix));
match (first, last) {
(true, false) => Some(true),
(false, true) => Some(false),
_ => None,
}
};
let by_selection = match (end_of(&picked_a, sa, x.anchors.len()), end_of(&picked_b, sb, y.anchors.len())) {
(Some(fa), Some(fb)) => Some((fa, !fb)),
_ => None,
};
let (rx, ry) = ends
.or(by_selection)
.unwrap_or_else(|| cands.into_iter().min_by(|p, q| p.0.total_cmp(&q.0)).map_or((false, false), |(_, rx, ry)| (rx, ry)));
if rx {
x.reverse();
}