mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 18:54:57 +00:00
Plug-ins: hit tests re-evaluate live art when a swatch or color group changes
A painted live effect's pieces name swatches, so a kept evaluation could outlive a swatch that was renamed or removed and answer a click with art the document no longer draws. The kept evaluation now holds the document's swatches and color groups and is stale when they change.
This commit is contained in:
+18
-4
@@ -128,11 +128,14 @@ fn live_inputs() -> u64 {
|
||||
}
|
||||
|
||||
/// A live object evaluated by [`live_art`] on this thread: the object, its document's symbols (by
|
||||
/// name and art) and patterns and the [`LiveInputs`] as they were, the art and its [`art_size`].
|
||||
/// name and art), patterns, swatches and color groups and the [`LiveInputs`] as they were, the art
|
||||
/// and its [`art_size`].
|
||||
struct EvaluatedLive {
|
||||
node: Node,
|
||||
symbols: Vec<(String, Arc<Node>)>,
|
||||
patterns: Vec<crate::PatternDef>,
|
||||
swatches: crate::Shared<Vec<vectorcraft_color::Swatch>>,
|
||||
swatch_groups: crate::Shared<Vec<vectorcraft_color::SwatchGroup>>,
|
||||
inputs: u64,
|
||||
art: Rc<Vec<Node>>,
|
||||
size: usize,
|
||||
@@ -146,6 +149,8 @@ impl EvaluatedLive {
|
||||
&& self.symbols.iter().zip(&doc.symbols).all(|((name, art), s)| *name == s.name && Arc::ptr_eq(art, &s.art))
|
||||
&& self.node == *n
|
||||
&& self.patterns == doc.patterns
|
||||
&& self.swatches == doc.swatches
|
||||
&& self.swatch_groups == doc.swatch_groups
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,8 +189,8 @@ thread_local! {
|
||||
|
||||
/// The art live object `n` of `doc` draws ([`set_live_art`]); [`crate::live::expand_live`] while
|
||||
/// nothing is registered. The art is evaluated again when `n`, a symbol of `doc`, a pattern of
|
||||
/// `doc` or the [`LiveInputs`] have changed since, and on every click while it or the document's
|
||||
/// symbols or patterns hold a placed document ([`holds_placed`]).
|
||||
/// `doc`, its swatches or color groups, or the [`LiveInputs`] have changed since, and on every
|
||||
/// click while it or the document's symbols or patterns hold a placed document ([`holds_placed`]).
|
||||
fn live_art(doc: &Document, n: &Node) -> Rc<Vec<Node>> {
|
||||
let inputs = live_inputs();
|
||||
let kept = EVALUATED.with_borrow_mut(|kept| {
|
||||
@@ -206,7 +211,16 @@ fn live_art(doc: &Document, n: &Node) -> Rc<Vec<Node>> {
|
||||
return art;
|
||||
}
|
||||
let symbols = doc.symbols.iter().map(|s| (s.name.clone(), s.art.clone())).collect();
|
||||
let e = EvaluatedLive { node: n.clone(), symbols, patterns: doc.patterns.clone(), inputs, art: art.clone(), size };
|
||||
let e = EvaluatedLive {
|
||||
node: n.clone(),
|
||||
symbols,
|
||||
patterns: doc.patterns.clone(),
|
||||
swatches: doc.swatches.clone(),
|
||||
swatch_groups: doc.swatch_groups.clone(),
|
||||
inputs,
|
||||
art: art.clone(),
|
||||
size,
|
||||
};
|
||||
EVALUATED.with_borrow_mut(|kept| {
|
||||
kept.insert(0, e);
|
||||
kept.truncate(LIVE_KEPT);
|
||||
|
||||
@@ -605,11 +605,41 @@ fn evaluated_art_is_not_kept_while_a_placed_document_may_show_in_it() {
|
||||
fn a_kept_evaluation_is_stale_after_the_live_inputs_change() {
|
||||
let d = Document::new(100.0, 100.0);
|
||||
let n = Node::path(NodeId(3), shapes::rectangle(Rect::new(0.0, 0.0, 10.0, 10.0)), Appearance::default_art());
|
||||
let e = EvaluatedLive { node: n.clone(), symbols: vec![], patterns: vec![], inputs: 7, art: std::rc::Rc::new(vec![]), size: 0 };
|
||||
let e = kept_evaluation(&d, &n);
|
||||
assert!(e.is_of(&d, &n, 7));
|
||||
assert!(!e.is_of(&d, &n, 8));
|
||||
}
|
||||
|
||||
/// An evaluation of `n` in `d`, with inputs 7, holding no symbols, patterns or art.
|
||||
fn kept_evaluation(d: &Document, n: &Node) -> EvaluatedLive {
|
||||
EvaluatedLive {
|
||||
node: n.clone(),
|
||||
symbols: vec![],
|
||||
patterns: vec![],
|
||||
swatches: d.swatches.clone(),
|
||||
swatch_groups: d.swatch_groups.clone(),
|
||||
inputs: 7,
|
||||
art: std::rc::Rc::new(vec![]),
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// A kept evaluation is stale once a swatch changes, in a color group too: a painted live effect's
|
||||
/// pieces name swatches.
|
||||
#[test]
|
||||
fn a_kept_evaluation_is_stale_after_a_swatch_changes() {
|
||||
let mut d = Document::new(100.0, 100.0);
|
||||
let n = Node::path(NodeId(3), shapes::rectangle(Rect::new(0.0, 0.0, 10.0, 10.0)), Appearance::default_art());
|
||||
let e = kept_evaluation(&d, &n);
|
||||
assert!(e.is_of(&d, &n, 7));
|
||||
d.swatches.first_mut().unwrap().name = "Renamed".into();
|
||||
assert!(!e.is_of(&d, &n, 7));
|
||||
let mut d = Document::new(100.0, 100.0);
|
||||
let e = kept_evaluation(&d, &n);
|
||||
d.swatch_groups.push(vectorcraft_color::SwatchGroup { name: "Added".into(), swatches: vec![] });
|
||||
assert!(!e.is_of(&d, &n, 7));
|
||||
}
|
||||
|
||||
/// A rectangle (40, 40)–(140, 140) clipping a filled 200 × 200 square drawn over its edges, in a
|
||||
/// clip group (or, `layer`, as the first layer's clipping mask): the group (or the layer), the
|
||||
/// clipping path and the art.
|
||||
|
||||
Reference in New Issue
Block a user