Direct Selection: a Shift-click on a segment pick's endpoint selects that anchor (#1278)
The endpoints of a selected segment are hollow, so select.anchors and select.anchorsMany now start from no anchors of that path instead of toggling the endpoint off.
This commit is contained in:
parent
1ac797685f
commit
4149a09d61
|
|
@ -377,7 +377,10 @@ fn anchors(s: &mut Session, p: &Value) -> Result<Value> {
|
|||
// A path selected as a whole has every anchor selected: toggle and add start from them all.
|
||||
let whole = sel.contains(id) && sel.partial(id).is_none();
|
||||
sel.add(id);
|
||||
sel.segments.remove(&id);
|
||||
// A segment pick's endpoints aren't selected anchors: start from none of them.
|
||||
if sel.segments.remove(&id).is_some() {
|
||||
sel.anchors.remove(&id);
|
||||
}
|
||||
let e = sel.anchors.entry(id).or_default();
|
||||
if whole && let Some(path) = d.node(id).and_then(|n| n.path_data()) {
|
||||
e.extend(path.anchors().map(|(s, i, _)| (s, i)));
|
||||
|
|
@ -416,7 +419,8 @@ fn anchors_many(s: &mut Session, p: &Value) -> Result<Value> {
|
|||
sel.clear();
|
||||
}
|
||||
for (id, refs) in items {
|
||||
sel.segments.remove(&id);
|
||||
// A segment pick's endpoints aren't selected anchors: start from none of them.
|
||||
let segment_pick = sel.segments.remove(&id).is_some();
|
||||
let all: BTreeSet<(usize, usize)> =
|
||||
d.node(id).and_then(|n| n.path_data()).map(|p| p.anchors().map(|(s, i, _)| (s, i)).collect()).unwrap_or_default();
|
||||
// Anything but a path is selected, toggled or deselected as a whole.
|
||||
|
|
@ -430,6 +434,7 @@ fn anchors_many(s: &mut Session, p: &Value) -> Result<Value> {
|
|||
}
|
||||
// From the anchors selected now (all of them for a path selected as a whole).
|
||||
let now = match sel.partial(id) {
|
||||
_ if segment_pick => BTreeSet::new(),
|
||||
Some(a) => a.clone(),
|
||||
None if sel.contains(id) => all.clone(),
|
||||
None => BTreeSet::new(),
|
||||
|
|
|
|||
|
|
@ -724,6 +724,25 @@ fn direct_segment_delete_keeps_the_other_rectangle_edges_and_one_undo() {
|
|||
}
|
||||
}
|
||||
|
||||
/// A segment pick's endpoints are hollow: Shift-clicking or Shift-marqueeing one selects that
|
||||
/// anchor, rather than toggling it off and leaving the other endpoint selected.
|
||||
#[test]
|
||||
fn selecting_an_anchor_after_a_segment_pick_starts_from_no_anchors() {
|
||||
let mut s = session();
|
||||
let id = rect(&mut s, 100.0, 100.0, 200.0, 150.0);
|
||||
let segment = json!({"id": id.0, "segments": [[0, 0]]});
|
||||
s.execute("select.segments", &segment).unwrap();
|
||||
s.execute("select.anchors", &json!({"id": id.0, "anchors": [[0, 0]], "mode": "toggle"})).unwrap();
|
||||
let sel = &s.doc().unwrap().selection;
|
||||
assert_eq!(sel.partial(id), Some(&[(0, 0)].into()));
|
||||
assert!(sel.segments.is_empty());
|
||||
s.execute("select.segments", &segment).unwrap();
|
||||
s.execute("select.anchorsMany", &json!({"items": [{"id": id.0, "anchors": [[0, 1]]}], "mode": "add"})).unwrap();
|
||||
let sel = &s.doc().unwrap().selection;
|
||||
assert_eq!(sel.partial(id), Some(&[(0, 1)].into()));
|
||||
assert!(sel.segments.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn segment_delete_preserves_curves_appearance_and_unrelated_contours() {
|
||||
let data = "M100 100C110 70 150 130 170 100C180 75 230 125 250 100C270 140 280 80 310 100C320 120 140 140 100 100Z M400 100L500 100L500 200Z";
|
||||
|
|
|
|||
Loading…
Reference in New Issue