mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 15:48:33 +00:00
Fix #2091 clear stale key and vertex selections around mask copy/paste
Selecting a mask group now clears the previous key selection, so Copy/Cut act on the mask. Pasting masks clears the source mask's vertex selection, so Clear removes the pasted mask rather than points of the source. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
685448a0b2
commit
73af2379d0
3 files changed
+33
-3
No files matched your search
@@ -794,6 +794,8 @@ fn select_prop(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if !add {
|
||||
s.state.selected_props.clear();
|
||||
s.state.selected_vertices.clear();
|
||||
// Groups (masks, effects) have no keys of their own: don't leave the old selection's behind.
|
||||
s.state.selected_keys.clear();
|
||||
}
|
||||
if !s.state.selected_layers.contains(&lid) {
|
||||
s.state.selected_layers = vec![lid];
|
||||
@@ -811,9 +813,6 @@ fn select_prop(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
&& let Some(pr) = s.active_comp().and_then(|c| c.layer(lid)).and_then(|l| l.props.find(uid))
|
||||
{
|
||||
let keys: Vec<KeyRef> = pr.keys.iter().map(|k| KeyRef { layer: lid, prop: uid, time: k.time }).collect();
|
||||
if !add {
|
||||
s.state.selected_keys.clear();
|
||||
}
|
||||
s.state.selected_keys.extend(keys);
|
||||
}
|
||||
Ok(Value::Null)
|
||||
|
||||
@@ -183,6 +183,8 @@ pub(crate) fn paste_masks(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
}
|
||||
proj.next_id = next + 1;
|
||||
st.selected_props = out.clone();
|
||||
// The source mask's points (selected with it) must not outlive its selection.
|
||||
st.selected_vertices.clear();
|
||||
Ok(out)
|
||||
})?;
|
||||
Ok(json!({"masks": pasted.iter().map(|(_, u)| *u).collect::<Vec<_>>()}))
|
||||
|
||||
@@ -2006,3 +2006,32 @@ fn copy_with_an_explicit_layer_ignores_the_selected_mask() {
|
||||
assert_eq!(s.state.clipboard.len(), 1, "the named layer is copied");
|
||||
assert!(s.state.mask_clipboard.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selecting_a_mask_drops_stale_key_selection_so_copy_copies_the_mask() {
|
||||
let mut s = comp();
|
||||
let a = solid(&mut s, "#ff0000");
|
||||
s.execute("layer.select", json!({"layers": [a]})).unwrap();
|
||||
s.execute("layer.addMask", json!({})).unwrap();
|
||||
let mask = layer(&s, a).masks().unwrap().groups().next().unwrap().uid;
|
||||
s.state.selected_keys = vec![crate::KeyRef { layer: effectcraft_project::LayerId(a), prop: 1, time: Default::default() }];
|
||||
s.execute("prop.select", json!({"layer": a, "prop": mask})).unwrap();
|
||||
assert!(s.state.selected_keys.is_empty());
|
||||
assert_eq!(s.execute("edit.copy", json!({})).unwrap()["masks"], json!(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pasting_a_mask_onto_its_own_layer_drops_the_source_vertex_selection() {
|
||||
let mut s = comp();
|
||||
let a = solid(&mut s, "#ff0000");
|
||||
s.execute("layer.select", json!({"layers": [a]})).unwrap();
|
||||
s.execute("layer.addMask", json!({})).unwrap();
|
||||
let mask = layer(&s, a).masks().unwrap().groups().next().unwrap().uid;
|
||||
s.execute("prop.select", json!({"layer": a, "prop": mask})).unwrap();
|
||||
assert!(!s.state.selected_vertices.is_empty());
|
||||
s.execute("edit.copy", json!({})).unwrap();
|
||||
s.execute("edit.paste", json!({})).unwrap();
|
||||
assert!(s.state.selected_vertices.is_empty());
|
||||
s.execute("edit.clear", json!({})).unwrap();
|
||||
assert_eq!(layer(&s, a).masks().unwrap().groups().count(), 1, "the pasted mask goes, the source stays");
|
||||
}
|
||||
Reference in new issue
Block a user