mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 10:47:11 -06:00
G11: Preserve gaps when deleting open-path anchors
Keep surviving drawable runs separate when Delete or Backspace removes an open-path anchor. Preserve appearance, selection and one-step Undo. Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Codex
parent
a1b3c4804f
commit
67f9d134ed
@@ -565,8 +565,8 @@ pub(crate) fn delete_anchors(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
})
|
||||
.collect();
|
||||
} else {
|
||||
// Remove every selected anchor against the original indexes. A closed path opens
|
||||
// across each deleted run and keeps the surviving stretches in their old order.
|
||||
// Remove every selected anchor against the original indexes, keeping surviving
|
||||
// stretches separate rather than joining across deleted anchors.
|
||||
path.subpaths = std::mem::take(&mut path.subpaths)
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
@@ -593,9 +593,8 @@ pub(crate) fn delete_anchors(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
ok()
|
||||
}
|
||||
|
||||
/// Remove anchors `removed`. An open path stays one path and joins across the gap. A closed path
|
||||
/// opens there: each stretch of anchors that were not deleted becomes its own open path, in the
|
||||
/// original order, including a stretch that wraps past the last anchor.
|
||||
/// Remove anchors and their incident segments, keeping each surviving stretch as an open path.
|
||||
/// Only a closed path can have a surviving stretch that wraps past the last anchor.
|
||||
fn without_anchors(sp: SubPath, removed: &BTreeSet<usize>) -> Vec<SubPath> {
|
||||
let n = sp.anchors.len();
|
||||
let gone: BTreeSet<usize> = removed.iter().copied().filter(|&i| i < n).collect();
|
||||
@@ -603,9 +602,6 @@ fn without_anchors(sp: SubPath, removed: &BTreeSet<usize>) -> Vec<SubPath> {
|
||||
return vec![sp];
|
||||
}
|
||||
let keep = |anchors: Vec<Anchor>| (anchors.len() >= 2).then(|| SubPath::new(anchors, false));
|
||||
if !sp.closed {
|
||||
return keep(sp.anchors.into_iter().enumerate().filter(|(i, _)| !gone.contains(i)).map(|(_, a)| a).collect()).into_iter().collect();
|
||||
}
|
||||
let mut runs: Vec<Vec<Anchor>> = vec![];
|
||||
let mut run = vec![];
|
||||
for (i, anchor) in sp.anchors.into_iter().enumerate() {
|
||||
@@ -617,7 +613,11 @@ fn without_anchors(sp: SubPath, removed: &BTreeSet<usize>) -> Vec<SubPath> {
|
||||
run.push(anchor);
|
||||
}
|
||||
}
|
||||
// The anchors before the first deletion and after the last are one stretch.
|
||||
if !sp.closed {
|
||||
runs.push(run);
|
||||
return runs.into_iter().filter_map(open_run).collect();
|
||||
}
|
||||
// The anchors before the first deletion and after the last are one closed-path stretch.
|
||||
if gone.contains(&0) {
|
||||
if !run.is_empty() {
|
||||
runs.push(run);
|
||||
|
||||
Reference in New Issue
Block a user