mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 05:37:23 -06:00
Appearance: effect.apply reports the active row's object, and an empty aligned target list is an error
effect.apply now reports the item of the first selected object, whose row the active item is. With nothing selected, an explicit aligned item returns the command's error instead of an internal error.
This commit is contained in:
@@ -262,7 +262,7 @@ impl ItemTarget {
|
||||
/// targets don't share, and any other target, stands for itself in every target.
|
||||
pub(crate) fn per_target(self, s: &Session, ids: &[NodeId]) -> Vec<Option<ItemTarget>> {
|
||||
let ItemTarget::Item { index, explicit, aligned: true } = self else { return vec![Some(self); ids.len()] };
|
||||
let Some(st) = s.active() else { return vec![Some(self); ids.len()] };
|
||||
let Some(st) = s.active().filter(|_| ids.len() >= 2) else { return vec![Some(self); ids.len()] };
|
||||
let k = self.anchor(s, ids);
|
||||
let mut order = ids.to_vec();
|
||||
order.swap(0, k);
|
||||
|
||||
@@ -219,8 +219,9 @@ pub(crate) fn apply(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
index = fx.len() - 1;
|
||||
true
|
||||
})?;
|
||||
// The item the effect landed on in the first object (the active item applies where it fits).
|
||||
let first = ids.first().and_then(|id| s.doc().ok()?.doc.node(*id));
|
||||
// The item the effect landed on in the object whose row the item is (the first selected object
|
||||
// for the active item, which applies where it fits).
|
||||
let first = ids.get(item.anchor(s, &ids)).and_then(|id| s.doc().ok()?.doc.node(*id));
|
||||
let landed = first.and_then(|n| item.effects_item(&n.appearance, C).ok().flatten());
|
||||
Ok(json!({ "ids": ids_json(&ids), "index": index, "item": landed }))
|
||||
}
|
||||
|
||||
@@ -501,6 +501,16 @@ fn edits_change_the_active_row_of_the_first_selected_object() {
|
||||
assert!(matches!(fill_paint(&na, 0), Paint::Gradient(_)), "so does a's equal fill");
|
||||
assert_eq!(fill_paint(&nb, 0).color().unwrap().to_hex(), "#ff0000");
|
||||
assert!(!matches!(stroke(&nb, 2).paint, Paint::Gradient(_)) && !matches!(stroke(&na, 1).paint, Paint::Gradient(_)));
|
||||
// The effect goes on the equal rows, and the reply names the active row of b.
|
||||
run(&mut s, "appearance.setActiveItem", json!({"index": 2})); // b's stroke, a's row 1
|
||||
let r = run(&mut s, "effect.apply", json!({"effect": "distort.twist"}));
|
||||
assert_eq!(r["item"], 2);
|
||||
let (na, nb) = (node(&s, a), node(&s, b));
|
||||
assert_eq!((stroke(&nb, 2).effects.len(), stroke(&na, 1).effects.len()), (1, 1));
|
||||
// With nothing selected an aligned item is an error, not a crash.
|
||||
run(&mut s, "select.set", json!({"ids": []}));
|
||||
let e = s.execute("effect.remove", &json!({"index": 0, "item": 0, "aligned": true})).unwrap_err().to_string();
|
||||
assert!(!e.contains("internal error"), "{e}");
|
||||
}
|
||||
|
||||
/// How many steps there are to undo and to redo, and whether the document has unsaved changes.
|
||||
|
||||
Reference in New Issue
Block a user