ferroui_base/rendering/composition/animations/
composition_animation.rs1use super::{PropertySetSnapshot, PropertySetSnapshotSource};
2use crate::media::Color;
3use crate::numerics::{Matrix3x2, Matrix4x4, Quaternion, Vector2, Vector3, Vector4};
4use crate::rendering::composition::expressions::{
5 Expression, ExpressionEvaluationContext, ExpressionParseException, ExpressionParser, ExpressionVariant,
6 IExpressionForeignFunctionInterface, IExpressionObject, IExpressionParameterCollection,
7};
8use crate::rendering::composition::{AsCompositionObject, CompositionObject, CompositionPropertySet, Compositor};
9use std::cell::RefCell;
10use std::collections::BTreeMap;
11use std::rc::Rc;
12
13pub struct CompositionAnimation {
29 object: CompositionObject,
30 property_set: Rc<CompositionPropertySet>,
31 target: RefCell<Option<String>>,
32 initial_value_expressions: InitialValueExpressionCollection,
33}
34
35impl CompositionAnimation {
36 pub(crate) fn new(compositor: &Rc<Compositor>) -> Self {
37 Self {
38 object: CompositionObject::new(compositor, None),
39 property_set: CompositionPropertySet::new_parameters(compositor),
40 target: RefCell::new(None),
41 initial_value_expressions: InitialValueExpressionCollection::default(),
42 }
43 }
44
45 pub fn object(&self) -> &CompositionObject {
47 &self.object
48 }
49
50 pub fn compositor(&self) -> &Rc<Compositor> {
52 self.object.compositor()
53 }
54
55 pub fn clear_all_parameters(&self) {
57 self.property_set.clear_all()
58 }
59
60 pub fn clear_parameter(&self, key: &str) {
62 self.property_set.clear(key)
63 }
64
65 fn set_variant(&self, key: &str, value: ExpressionVariant) {
66 self.property_set.set(key, value)
67 }
68
69 pub fn set_boolean_parameter(&self, key: &str, value: bool) {
72 self.set_variant(key, value.into())
73 }
74
75 pub fn set_color_parameter(&self, key: &str, value: Color) {
76 self.set_variant(key, value.into())
77 }
78
79 pub fn set_expression_reference_parameter(&self, key: &str, animation_object: Rc<dyn AsCompositionObject>) {
89 self.set_reference_parameter(key, animation_object)
90 }
91
92 pub fn set_matrix3x2_parameter(&self, key: &str, value: Matrix3x2) {
93 self.set_variant(key, value.into())
94 }
95
96 pub fn set_matrix4x4_parameter(&self, key: &str, value: Matrix4x4) {
97 self.set_variant(key, value.into())
98 }
99
100 pub fn set_quaternion_parameter(&self, key: &str, value: Quaternion) {
101 self.set_variant(key, value.into())
102 }
103
104 pub fn set_reference_parameter(&self, key: &str, composition_object: Rc<dyn AsCompositionObject>) {
105 self.property_set.set_object(key, composition_object)
106 }
107
108 pub fn set_scalar_parameter(&self, key: &str, value: f32) {
109 self.set_variant(key, value.into())
110 }
111
112 pub fn set_vector2_parameter(&self, key: &str, value: Vector2) {
113 self.set_variant(key, value.into())
114 }
115
116 pub fn set_vector3_parameter(&self, key: &str, value: Vector3) {
117 self.set_variant(key, value.into())
118 }
119
120 pub fn set_vector4_parameter(&self, key: &str, value: Vector4) {
121 self.set_variant(key, value.into())
122 }
123
124 pub fn target(&self) -> Option<String> {
126 self.target.borrow().clone()
127 }
128
129 pub fn set_target(&self, value: Option<String>) {
130 *self.target.borrow_mut() = value;
131 }
132
133 pub fn initial_value_expressions(&self) -> &InitialValueExpressionCollection {
137 &self.initial_value_expressions
138 }
139
140 pub(crate) fn create_snapshot(&self) -> Rc<PropertySetSnapshot> {
141 Rc::new(self.property_set.snapshot())
142 }
143
144 pub(crate) fn create_snapshot_source(&self) -> PropertySetSnapshotSource {
147 self.property_set.snapshot_source()
148 }
149}
150
151#[derive(Default)]
164pub struct InitialValueExpressionCollection {
165 expressions: RefCell<BTreeMap<String, String>>,
166}
167
168impl InitialValueExpressionCollection {
169 pub fn insert(&self, property_name: &str, expression: &str) -> bool {
172 self.expressions
173 .borrow_mut()
174 .insert(property_name.to_owned(), expression.to_owned())
175 .is_some()
176 }
177
178 pub fn lookup(&self, property_name: &str) -> Option<String> {
180 self.expressions.borrow().get(property_name).cloned()
181 }
182
183 pub fn has_key(&self, property_name: &str) -> bool {
185 self.expressions.borrow().contains_key(property_name)
186 }
187
188 pub fn remove(&self, property_name: &str) -> bool {
191 self.expressions.borrow_mut().remove(property_name).is_some()
192 }
193
194 pub fn clear(&self) {
196 self.expressions.borrow_mut().clear()
197 }
198
199 pub fn size(&self) -> usize {
201 self.expressions.borrow().len()
202 }
203
204 pub fn get_view(&self) -> Vec<(String, String)> {
206 self.expressions
207 .borrow()
208 .iter()
209 .map(|(k, v)| (k.clone(), v.clone()))
210 .collect()
211 }
212
213 pub fn parse_all(&self) -> Result<Vec<(String, Expression)>, ExpressionParseException> {
217 self.expressions
218 .borrow()
219 .iter()
220 .map(|(name, source)| ExpressionParser::parse(source).map(|parsed| (name.clone(), parsed)))
221 .collect()
222 }
223
224 pub fn evaluate_parsed(
236 expressions: &[(String, Expression)],
237 target: &dyn IExpressionObject,
238 parameters: Option<&dyn IExpressionParameterCollection>,
239 foreign_function_interface: &dyn IExpressionForeignFunctionInterface,
240 ) -> Vec<(String, ExpressionVariant)> {
241 let mut values = Vec::with_capacity(expressions.len());
242 for (property_name, expression) in expressions {
243 let current = target.get_property(property_name);
244 let context = ExpressionEvaluationContext {
245 starting_value: current,
246 current_value: current,
247 final_value: current,
248 target: Some(target),
249 parameters,
250 foreign_function_interface: Some(foreign_function_interface),
251 };
252 let value = expression.evaluate(&context);
253 if value != ExpressionVariant::Invalid {
254 values.push((property_name.clone(), value));
255 }
256 }
257 values
258 }
259}