1use bitflags::bitflags;
8use crate::Matrix;
9use crate::Vector;
10use crate::Vector3D;
11use crate::media::IBrush;
12use crate::media::IImmutableEffect;
13use crate::media::RenderOptions;
14use crate::media::TextOptions;
15use crate::numerics::Quaternion;
16use crate::platform::IGeometryImpl;
17use crate::rendering::composition::ICompositionObject;
18use crate::rendering::composition::ICompositionObjectHost;
19use crate::rendering::composition::animations::AnimationInstanceFactory;
20use crate::rendering::composition::animations::ICompositionAnimation;
21use crate::rendering::composition::expressions::ExpressionVariant;
22use crate::rendering::composition::server::AsServerRenderResource;
23use crate::rendering::composition::server::CompositionProperty;
24use crate::rendering::composition::server::CompositionPropertyOf;
25use crate::rendering::composition::server::IServerAnimatedPropertyHost;
26use crate::rendering::composition::server::IServerObject;
27use crate::rendering::composition::server::ServerPropertyValue;
28use crate::rendering::composition::server::ServerResourceRef;
29use crate::rendering::composition::server::ServerValueChange;
30use crate::rendering::composition::server::props_of;
31use crate::rendering::composition::server::read_resource;
32use crate::rendering::composition::server::read_server_object;
33use crate::rendering::composition::transport::BatchResource;
34use crate::rendering::composition::transport::BatchStreamReader;
35use crate::rendering::composition::transport::BatchStreamWriter;
36use crate::rendering::composition::transport::BatchValue;
37use crate::rendering::composition::transport::BatchValueReader;
38use std::any::Any;
39use std::any::TypeId;
40use std::cell::Cell;
41use std::cell::RefCell;
42use std::rc::Rc;
43use std::sync::Arc;
44use std::sync::OnceLock;
45use std::time::Duration;
46
47bitflags! {
48 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
50 pub struct CompositionVisualChangedFields: u64 {
51 const ROOT = 1;
52 const PARENT = 2;
53 const VISIBLE = 4;
54 const VISIBLE_ANIMATED = 8;
55 const OPACITY = 16;
56 const OPACITY_ANIMATED = 32;
57 const CLIP = 64;
58 const CLIP_TO_BOUNDS = 128;
59 const CLIP_TO_BOUNDS_ANIMATED = 256;
60 const OFFSET = 512;
61 const OFFSET_ANIMATED = 1024;
62 const TRANSLATION = 2048;
63 const TRANSLATION_ANIMATED = 4096;
64 const SIZE = 8192;
65 const SIZE_ANIMATED = 16384;
66 const ANCHOR_POINT = 32768;
67 const ANCHOR_POINT_ANIMATED = 65536;
68 const CENTER_POINT = 131072;
69 const CENTER_POINT_ANIMATED = 262144;
70 const ROTATION_ANGLE = 524288;
71 const ROTATION_ANGLE_ANIMATED = 1048576;
72 const ORIENTATION = 2097152;
73 const ORIENTATION_ANIMATED = 4194304;
74 const SCALE = 8388608;
75 const SCALE_ANIMATED = 16777216;
76 const TRANSFORM_MATRIX = 33554432;
77 const TRANSFORM_MATRIX_ANIMATED = 67108864;
78 const ADORNED_VISUAL = 134217728;
79 const ADORNER_IS_CLIPPED = 268435456;
80 const OPACITY_MASK_BRUSH = 536870912;
81 const EFFECT = 1073741824;
82 const RENDER_OPTIONS = 2147483648;
83 const TEXT_OPTIONS = 4294967296;
84 const CACHE_MODE = 8589934592;
85 }
86}
87
88impl BatchValue for CompositionVisualChangedFields {
89 #[inline]
90 fn write_to(&self, out: &mut Vec<u8>) {
91 self.bits().write_to(out);
92 }
93
94 #[inline]
95 fn read_from(input: &mut BatchValueReader<'_>) -> Self {
96 CompositionVisualChangedFields::from_bits_retain(u64::read_from(input))
97 }
98}
99
100pub trait CompositionVisualHooks: ICompositionObjectHost {
103 fn initialize_defaults_extra(&self) {}
104
105 fn validate_root_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
106 fn on_root_changed(&self) {}
107 fn on_root_changing(&self) {}
108
109 fn validate_parent_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
110 fn on_parent_changed(&self) {}
111 fn on_parent_changing(&self) {}
112
113 fn validate_visible_change(&self, _old_value: bool, _new_value: bool) {}
114 fn on_visible_changed(&self) {}
115 fn on_visible_changing(&self) {}
116
117 fn validate_opacity_change(&self, _old_value: f32, _new_value: f32) {}
118 fn on_opacity_changed(&self) {}
119 fn on_opacity_changing(&self) {}
120
121 fn validate_clip_change(&self, _old_value: &Option<Arc<dyn IGeometryImpl>>, _new_value: &Option<Arc<dyn IGeometryImpl>>) {}
122 fn on_clip_changed(&self) {}
123 fn on_clip_changing(&self) {}
124
125 fn validate_clip_to_bounds_change(&self, _old_value: bool, _new_value: bool) {}
126 fn on_clip_to_bounds_changed(&self) {}
127 fn on_clip_to_bounds_changing(&self) {}
128
129 fn validate_offset_change(&self, _old_value: Vector3D, _new_value: Vector3D) {}
130 fn on_offset_changed(&self) {}
131 fn on_offset_changing(&self) {}
132
133 fn validate_translation_change(&self, _old_value: Vector3D, _new_value: Vector3D) {}
134 fn on_translation_changed(&self) {}
135 fn on_translation_changing(&self) {}
136
137 fn validate_size_change(&self, _old_value: Vector, _new_value: Vector) {}
138 fn on_size_changed(&self) {}
139 fn on_size_changing(&self) {}
140
141 fn validate_anchor_point_change(&self, _old_value: Vector, _new_value: Vector) {}
142 fn on_anchor_point_changed(&self) {}
143 fn on_anchor_point_changing(&self) {}
144
145 fn validate_center_point_change(&self, _old_value: Vector3D, _new_value: Vector3D) {}
146 fn on_center_point_changed(&self) {}
147 fn on_center_point_changing(&self) {}
148
149 fn validate_rotation_angle_change(&self, _old_value: f32, _new_value: f32) {}
150 fn on_rotation_angle_changed(&self) {}
151 fn on_rotation_angle_changing(&self) {}
152
153 fn validate_orientation_change(&self, _old_value: Quaternion, _new_value: Quaternion) {}
154 fn on_orientation_changed(&self) {}
155 fn on_orientation_changing(&self) {}
156
157 fn validate_scale_change(&self, _old_value: Vector3D, _new_value: Vector3D) {}
158 fn on_scale_changed(&self) {}
159 fn on_scale_changing(&self) {}
160
161 fn validate_transform_matrix_change(&self, _old_value: Matrix, _new_value: Matrix) {}
162 fn on_transform_matrix_changed(&self) {}
163 fn on_transform_matrix_changing(&self) {}
164
165 fn validate_adorned_visual_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
166 fn on_adorned_visual_changed(&self) {}
167 fn on_adorned_visual_changing(&self) {}
168
169 fn validate_adorner_is_clipped_change(&self, _old_value: bool, _new_value: bool) {}
170 fn on_adorner_is_clipped_changed(&self) {}
171 fn on_adorner_is_clipped_changing(&self) {}
172
173 fn validate_opacity_mask_brush_change(&self, _old_value: &Option<BatchResource<dyn IBrush>>, _new_value: &Option<BatchResource<dyn IBrush>>) {}
174 fn on_opacity_mask_brush_changed(&self) {}
175 fn on_opacity_mask_brush_changing(&self) {}
176
177 fn validate_effect_change(&self, _old_value: &Option<Arc<dyn IImmutableEffect>>, _new_value: &Option<Arc<dyn IImmutableEffect>>) {}
178 fn on_effect_changed(&self) {}
179 fn on_effect_changing(&self) {}
180
181 fn validate_render_options_change(&self, _old_value: RenderOptions, _new_value: RenderOptions) {}
182 fn on_render_options_changed(&self) {}
183 fn on_render_options_changing(&self) {}
184
185 fn validate_text_options_change(&self, _old_value: TextOptions, _new_value: TextOptions) {}
186 fn on_text_options_changed(&self) {}
187 fn on_text_options_changing(&self) {}
188
189 fn validate_cache_mode_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
190 fn on_cache_mode_changed(&self) {}
191 fn on_cache_mode_changing(&self) {}
192}
193
194pub struct CompositionVisualProps {
196 changed_fields_of_composition_visual: Cell<CompositionVisualChangedFields>,
197 root: RefCell<Option<Rc<dyn ICompositionObject>>>,
198 parent: RefCell<Option<Rc<dyn ICompositionObject>>>,
199 visible: Cell<bool>,
200 opacity: Cell<f32>,
201 clip: RefCell<Option<Arc<dyn IGeometryImpl>>>,
202 clip_to_bounds: Cell<bool>,
203 offset: Cell<Vector3D>,
204 translation: Cell<Vector3D>,
205 size: Cell<Vector>,
206 anchor_point: Cell<Vector>,
207 center_point: Cell<Vector3D>,
208 rotation_angle: Cell<f32>,
209 orientation: Cell<Quaternion>,
210 scale: Cell<Vector3D>,
211 transform_matrix: Cell<Matrix>,
212 adorned_visual: RefCell<Option<Rc<dyn ICompositionObject>>>,
213 adorner_is_clipped: Cell<bool>,
214 opacity_mask_brush: RefCell<Option<BatchResource<dyn IBrush>>>,
215 effect: RefCell<Option<Arc<dyn IImmutableEffect>>>,
216 render_options: Cell<RenderOptions>,
217 text_options: Cell<TextOptions>,
218 cache_mode: RefCell<Option<Rc<dyn ICompositionObject>>>,
219}
220
221impl Default for CompositionVisualProps {
222 fn default() -> Self {
223 Self::new()
224 }
225}
226
227impl CompositionVisualProps {
228 pub fn new() -> Self {
232 Self {
233 changed_fields_of_composition_visual: Cell::new(CompositionVisualChangedFields::empty()),
234 root: RefCell::new(None),
235 parent: RefCell::new(None),
236 visible: Cell::new(Default::default()),
237 opacity: Cell::new(Default::default()),
238 clip: RefCell::new(None),
239 clip_to_bounds: Cell::new(Default::default()),
240 offset: Cell::new(Default::default()),
241 translation: Cell::new(Default::default()),
242 size: Cell::new(Default::default()),
243 anchor_point: Cell::new(Default::default()),
244 center_point: Cell::new(Default::default()),
245 rotation_angle: Cell::new(Default::default()),
246 orientation: Cell::new(Default::default()),
247 scale: Cell::new(Default::default()),
248 transform_matrix: Cell::new(Default::default()),
249 adorned_visual: RefCell::new(None),
250 adorner_is_clipped: Cell::new(Default::default()),
251 opacity_mask_brush: RefCell::new(None),
252 effect: RefCell::new(None),
253 render_options: Cell::new(Default::default()),
254 text_options: Cell::new(Default::default()),
255 cache_mode: RefCell::new(None),
256 }
257 }
258
259 pub fn initialize_defaults(&self, host: &dyn CompositionVisualHooks) {
262 self.initialize_own_defaults(host);
263 }
264
265 pub fn initialize_own_defaults(&self, host: &dyn CompositionVisualHooks) {
267 CompositionVisualHooks::initialize_defaults_extra(host);
268 self.set_visible(host, true);
269 self.set_opacity(host, 1.0);
270 self.set_clip_to_bounds(host, true);
271 self.set_orientation(host, Quaternion::IDENTITY);
272 self.set_scale(host, Vector3D::new(1.0, 1.0, 1.0));
273 self.set_transform_matrix(host, Matrix::IDENTITY);
274 }
275
276 pub fn root(&self) -> Option<Rc<dyn ICompositionObject>> {
278 self.root.borrow().clone()
279 }
280
281 pub fn set_root(&self, host: &dyn CompositionVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
283 let mut changed = false;
284 let old_value = self.root.borrow().clone();
285 if old_value.differs(&value) {
286 CompositionVisualHooks::validate_root_change(host, &old_value, &value);
287 CompositionVisualHooks::on_root_changing(host);
288 changed = true;
289 *self.root.borrow_mut() = value.clone();
291 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ROOT);
293 host.register_for_serialization();
294 }
295 *self.root.borrow_mut() = value;
296 if changed {
297 CompositionVisualHooks::on_root_changed(host);
298 }
299 }
300
301 pub fn parent(&self) -> Option<Rc<dyn ICompositionObject>> {
303 self.parent.borrow().clone()
304 }
305
306 pub fn set_parent(&self, host: &dyn CompositionVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
308 let mut changed = false;
309 let old_value = self.parent.borrow().clone();
310 if old_value.differs(&value) {
311 CompositionVisualHooks::validate_parent_change(host, &old_value, &value);
312 CompositionVisualHooks::on_parent_changing(host);
313 changed = true;
314 *self.parent.borrow_mut() = value.clone();
316 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::PARENT);
318 host.register_for_serialization();
319 }
320 *self.parent.borrow_mut() = value;
321 if changed {
322 CompositionVisualHooks::on_parent_changed(host);
323 }
324 }
325
326 pub fn visible(&self) -> bool {
328 self.visible.get()
329 }
330
331 pub fn set_visible(&self, host: &dyn CompositionVisualHooks, value: bool) {
333 let mut changed = false;
334 let old_value = self.visible.get();
335 if old_value.differs(&value) {
336 CompositionVisualHooks::validate_visible_change(host, old_value, value);
337 CompositionVisualHooks::on_visible_changing(host);
338 changed = true;
339 self.visible.set(value);
341 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::VISIBLE);
343 host.register_for_serialization();
344 host.pending_animations().remove(ServerCompositionVisualProps::id_of_visible_property().base());
346 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::VISIBLE_ANIMATED);
347 if let Some(animation) = host.implicit_animation("Visible") {
349 if let Some(a) = animation.as_composition_animation() {
351 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::VISIBLE_ANIMATED);
352 host.pending_animations().set(
353 ServerCompositionVisualProps::id_of_visible_property().base(),
354 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
355 );
356 }
357 host.start_animation_group(&animation, "Visible", ExpressionVariant::create(value));
359 }
360 }
361 self.visible.set(value);
362 if changed {
363 CompositionVisualHooks::on_visible_changed(host);
364 }
365 }
366
367 pub fn opacity(&self) -> f32 {
369 self.opacity.get()
370 }
371
372 pub fn set_opacity(&self, host: &dyn CompositionVisualHooks, value: f32) {
374 let mut changed = false;
375 let old_value = self.opacity.get();
376 if old_value.differs(&value) {
377 CompositionVisualHooks::validate_opacity_change(host, old_value, value);
378 CompositionVisualHooks::on_opacity_changing(host);
379 changed = true;
380 self.opacity.set(value);
382 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OPACITY);
384 host.register_for_serialization();
385 host.pending_animations().remove(ServerCompositionVisualProps::id_of_opacity_property().base());
387 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::OPACITY_ANIMATED);
388 if let Some(animation) = host.implicit_animation("Opacity") {
390 if let Some(a) = animation.as_composition_animation() {
392 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OPACITY_ANIMATED);
393 host.pending_animations().set(
394 ServerCompositionVisualProps::id_of_opacity_property().base(),
395 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
396 );
397 }
398 host.start_animation_group(&animation, "Opacity", ExpressionVariant::create(value));
400 }
401 }
402 self.opacity.set(value);
403 if changed {
404 CompositionVisualHooks::on_opacity_changed(host);
405 }
406 }
407
408 pub fn clip(&self) -> Option<Arc<dyn IGeometryImpl>> {
410 self.clip.borrow().clone()
411 }
412
413 pub fn set_clip(&self, host: &dyn CompositionVisualHooks, value: Option<Arc<dyn IGeometryImpl>>) {
415 let mut changed = false;
416 let old_value = self.clip.borrow().clone();
417 if old_value.differs(&value) {
418 CompositionVisualHooks::validate_clip_change(host, &old_value, &value);
419 CompositionVisualHooks::on_clip_changing(host);
420 changed = true;
421 *self.clip.borrow_mut() = value.clone();
423 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CLIP);
425 host.register_for_serialization();
426 }
427 *self.clip.borrow_mut() = value;
428 if changed {
429 CompositionVisualHooks::on_clip_changed(host);
430 }
431 }
432
433 pub fn clip_to_bounds(&self) -> bool {
435 self.clip_to_bounds.get()
436 }
437
438 pub fn set_clip_to_bounds(&self, host: &dyn CompositionVisualHooks, value: bool) {
440 let mut changed = false;
441 let old_value = self.clip_to_bounds.get();
442 if old_value.differs(&value) {
443 CompositionVisualHooks::validate_clip_to_bounds_change(host, old_value, value);
444 CompositionVisualHooks::on_clip_to_bounds_changing(host);
445 changed = true;
446 self.clip_to_bounds.set(value);
448 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CLIP_TO_BOUNDS);
450 host.register_for_serialization();
451 host.pending_animations().remove(ServerCompositionVisualProps::id_of_clip_to_bounds_property().base());
453 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED);
454 if let Some(animation) = host.implicit_animation("ClipToBounds") {
456 if let Some(a) = animation.as_composition_animation() {
458 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED);
459 host.pending_animations().set(
460 ServerCompositionVisualProps::id_of_clip_to_bounds_property().base(),
461 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
462 );
463 }
464 host.start_animation_group(&animation, "ClipToBounds", ExpressionVariant::create(value));
466 }
467 }
468 self.clip_to_bounds.set(value);
469 if changed {
470 CompositionVisualHooks::on_clip_to_bounds_changed(host);
471 }
472 }
473
474 pub fn offset(&self) -> Vector3D {
476 self.offset.get()
477 }
478
479 pub fn set_offset(&self, host: &dyn CompositionVisualHooks, value: Vector3D) {
481 let mut changed = false;
482 let old_value = self.offset.get();
483 if old_value.differs(&value) {
484 CompositionVisualHooks::validate_offset_change(host, old_value, value);
485 CompositionVisualHooks::on_offset_changing(host);
486 changed = true;
487 self.offset.set(value);
489 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OFFSET);
491 host.register_for_serialization();
492 host.pending_animations().remove(ServerCompositionVisualProps::id_of_offset_property().base());
494 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::OFFSET_ANIMATED);
495 if let Some(animation) = host.implicit_animation("Offset") {
497 if let Some(a) = animation.as_composition_animation() {
499 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OFFSET_ANIMATED);
500 host.pending_animations().set(
501 ServerCompositionVisualProps::id_of_offset_property().base(),
502 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
503 );
504 }
505 host.start_animation_group(&animation, "Offset", ExpressionVariant::create(value));
507 }
508 }
509 self.offset.set(value);
510 if changed {
511 CompositionVisualHooks::on_offset_changed(host);
512 }
513 }
514
515 pub fn translation(&self) -> Vector3D {
517 self.translation.get()
518 }
519
520 pub fn set_translation(&self, host: &dyn CompositionVisualHooks, value: Vector3D) {
522 let mut changed = false;
523 let old_value = self.translation.get();
524 if old_value.differs(&value) {
525 CompositionVisualHooks::validate_translation_change(host, old_value, value);
526 CompositionVisualHooks::on_translation_changing(host);
527 changed = true;
528 self.translation.set(value);
530 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSLATION);
532 host.register_for_serialization();
533 host.pending_animations().remove(ServerCompositionVisualProps::id_of_translation_property().base());
535 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::TRANSLATION_ANIMATED);
536 if let Some(animation) = host.implicit_animation("Translation") {
538 if let Some(a) = animation.as_composition_animation() {
540 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSLATION_ANIMATED);
541 host.pending_animations().set(
542 ServerCompositionVisualProps::id_of_translation_property().base(),
543 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
544 );
545 }
546 host.start_animation_group(&animation, "Translation", ExpressionVariant::create(value));
548 }
549 }
550 self.translation.set(value);
551 if changed {
552 CompositionVisualHooks::on_translation_changed(host);
553 }
554 }
555
556 pub fn size(&self) -> Vector {
558 self.size.get()
559 }
560
561 pub fn set_size(&self, host: &dyn CompositionVisualHooks, value: Vector) {
563 let mut changed = false;
564 let old_value = self.size.get();
565 if old_value.differs(&value) {
566 CompositionVisualHooks::validate_size_change(host, old_value, value);
567 CompositionVisualHooks::on_size_changing(host);
568 changed = true;
569 self.size.set(value);
571 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SIZE);
573 host.register_for_serialization();
574 host.pending_animations().remove(ServerCompositionVisualProps::id_of_size_property().base());
576 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::SIZE_ANIMATED);
577 if let Some(animation) = host.implicit_animation("Size") {
579 if let Some(a) = animation.as_composition_animation() {
581 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SIZE_ANIMATED);
582 host.pending_animations().set(
583 ServerCompositionVisualProps::id_of_size_property().base(),
584 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
585 );
586 }
587 host.start_animation_group(&animation, "Size", ExpressionVariant::create(value));
589 }
590 }
591 self.size.set(value);
592 if changed {
593 CompositionVisualHooks::on_size_changed(host);
594 }
595 }
596
597 pub fn anchor_point(&self) -> Vector {
599 self.anchor_point.get()
600 }
601
602 pub fn set_anchor_point(&self, host: &dyn CompositionVisualHooks, value: Vector) {
604 let mut changed = false;
605 let old_value = self.anchor_point.get();
606 if old_value.differs(&value) {
607 CompositionVisualHooks::validate_anchor_point_change(host, old_value, value);
608 CompositionVisualHooks::on_anchor_point_changing(host);
609 changed = true;
610 self.anchor_point.set(value);
612 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ANCHOR_POINT);
614 host.register_for_serialization();
615 host.pending_animations().remove(ServerCompositionVisualProps::id_of_anchor_point_property().base());
617 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED);
618 if let Some(animation) = host.implicit_animation("AnchorPoint") {
620 if let Some(a) = animation.as_composition_animation() {
622 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED);
623 host.pending_animations().set(
624 ServerCompositionVisualProps::id_of_anchor_point_property().base(),
625 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
626 );
627 }
628 host.start_animation_group(&animation, "AnchorPoint", ExpressionVariant::create(value));
630 }
631 }
632 self.anchor_point.set(value);
633 if changed {
634 CompositionVisualHooks::on_anchor_point_changed(host);
635 }
636 }
637
638 pub fn center_point(&self) -> Vector3D {
640 self.center_point.get()
641 }
642
643 pub fn set_center_point(&self, host: &dyn CompositionVisualHooks, value: Vector3D) {
645 let mut changed = false;
646 let old_value = self.center_point.get();
647 if old_value.differs(&value) {
648 CompositionVisualHooks::validate_center_point_change(host, old_value, value);
649 CompositionVisualHooks::on_center_point_changing(host);
650 changed = true;
651 self.center_point.set(value);
653 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CENTER_POINT);
655 host.register_for_serialization();
656 host.pending_animations().remove(ServerCompositionVisualProps::id_of_center_point_property().base());
658 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::CENTER_POINT_ANIMATED);
659 if let Some(animation) = host.implicit_animation("CenterPoint") {
661 if let Some(a) = animation.as_composition_animation() {
663 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CENTER_POINT_ANIMATED);
664 host.pending_animations().set(
665 ServerCompositionVisualProps::id_of_center_point_property().base(),
666 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
667 );
668 }
669 host.start_animation_group(&animation, "CenterPoint", ExpressionVariant::create(value));
671 }
672 }
673 self.center_point.set(value);
674 if changed {
675 CompositionVisualHooks::on_center_point_changed(host);
676 }
677 }
678
679 pub fn rotation_angle(&self) -> f32 {
681 self.rotation_angle.get()
682 }
683
684 pub fn set_rotation_angle(&self, host: &dyn CompositionVisualHooks, value: f32) {
686 let mut changed = false;
687 let old_value = self.rotation_angle.get();
688 if old_value.differs(&value) {
689 CompositionVisualHooks::validate_rotation_angle_change(host, old_value, value);
690 CompositionVisualHooks::on_rotation_angle_changing(host);
691 changed = true;
692 self.rotation_angle.set(value);
694 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ROTATION_ANGLE);
696 host.register_for_serialization();
697 host.pending_animations().remove(ServerCompositionVisualProps::id_of_rotation_angle_property().base());
699 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED);
700 if let Some(animation) = host.implicit_animation("RotationAngle") {
702 if let Some(a) = animation.as_composition_animation() {
704 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED);
705 host.pending_animations().set(
706 ServerCompositionVisualProps::id_of_rotation_angle_property().base(),
707 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
708 );
709 }
710 host.start_animation_group(&animation, "RotationAngle", ExpressionVariant::create(value));
712 }
713 }
714 self.rotation_angle.set(value);
715 if changed {
716 CompositionVisualHooks::on_rotation_angle_changed(host);
717 }
718 }
719
720 pub fn orientation(&self) -> Quaternion {
722 self.orientation.get()
723 }
724
725 pub fn set_orientation(&self, host: &dyn CompositionVisualHooks, value: Quaternion) {
727 let mut changed = false;
728 let old_value = self.orientation.get();
729 if old_value.differs(&value) {
730 CompositionVisualHooks::validate_orientation_change(host, old_value, value);
731 CompositionVisualHooks::on_orientation_changing(host);
732 changed = true;
733 self.orientation.set(value);
735 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ORIENTATION);
737 host.register_for_serialization();
738 host.pending_animations().remove(ServerCompositionVisualProps::id_of_orientation_property().base());
740 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::ORIENTATION_ANIMATED);
741 if let Some(animation) = host.implicit_animation("Orientation") {
743 if let Some(a) = animation.as_composition_animation() {
745 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ORIENTATION_ANIMATED);
746 host.pending_animations().set(
747 ServerCompositionVisualProps::id_of_orientation_property().base(),
748 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
749 );
750 }
751 host.start_animation_group(&animation, "Orientation", ExpressionVariant::create(value));
753 }
754 }
755 self.orientation.set(value);
756 if changed {
757 CompositionVisualHooks::on_orientation_changed(host);
758 }
759 }
760
761 pub fn scale(&self) -> Vector3D {
763 self.scale.get()
764 }
765
766 pub fn set_scale(&self, host: &dyn CompositionVisualHooks, value: Vector3D) {
768 let mut changed = false;
769 let old_value = self.scale.get();
770 if old_value.differs(&value) {
771 CompositionVisualHooks::validate_scale_change(host, old_value, value);
772 CompositionVisualHooks::on_scale_changing(host);
773 changed = true;
774 self.scale.set(value);
776 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SCALE);
778 host.register_for_serialization();
779 host.pending_animations().remove(ServerCompositionVisualProps::id_of_scale_property().base());
781 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::SCALE_ANIMATED);
782 if let Some(animation) = host.implicit_animation("Scale") {
784 if let Some(a) = animation.as_composition_animation() {
786 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SCALE_ANIMATED);
787 host.pending_animations().set(
788 ServerCompositionVisualProps::id_of_scale_property().base(),
789 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
790 );
791 }
792 host.start_animation_group(&animation, "Scale", ExpressionVariant::create(value));
794 }
795 }
796 self.scale.set(value);
797 if changed {
798 CompositionVisualHooks::on_scale_changed(host);
799 }
800 }
801
802 pub fn transform_matrix(&self) -> Matrix {
804 self.transform_matrix.get()
805 }
806
807 pub fn set_transform_matrix(&self, host: &dyn CompositionVisualHooks, value: Matrix) {
809 let mut changed = false;
810 let old_value = self.transform_matrix.get();
811 if old_value.differs(&value) {
812 CompositionVisualHooks::validate_transform_matrix_change(host, old_value, value);
813 CompositionVisualHooks::on_transform_matrix_changing(host);
814 changed = true;
815 self.transform_matrix.set(value);
817 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSFORM_MATRIX);
819 host.register_for_serialization();
820 host.pending_animations().remove(ServerCompositionVisualProps::id_of_transform_matrix_property().base());
822 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() & !CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED);
823 if let Some(animation) = host.implicit_animation("TransformMatrix") {
825 if let Some(a) = animation.as_composition_animation() {
827 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED);
828 host.pending_animations().set(
829 ServerCompositionVisualProps::id_of_transform_matrix_property().base(),
830 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
831 );
832 }
833 host.start_animation_group(&animation, "TransformMatrix", ExpressionVariant::create(value));
835 }
836 }
837 self.transform_matrix.set(value);
838 if changed {
839 CompositionVisualHooks::on_transform_matrix_changed(host);
840 }
841 }
842
843 pub fn adorned_visual(&self) -> Option<Rc<dyn ICompositionObject>> {
845 self.adorned_visual.borrow().clone()
846 }
847
848 pub fn set_adorned_visual(&self, host: &dyn CompositionVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
850 let mut changed = false;
851 let old_value = self.adorned_visual.borrow().clone();
852 if old_value.differs(&value) {
853 CompositionVisualHooks::validate_adorned_visual_change(host, &old_value, &value);
854 CompositionVisualHooks::on_adorned_visual_changing(host);
855 changed = true;
856 *self.adorned_visual.borrow_mut() = value.clone();
858 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ADORNED_VISUAL);
860 host.register_for_serialization();
861 }
862 *self.adorned_visual.borrow_mut() = value;
863 if changed {
864 CompositionVisualHooks::on_adorned_visual_changed(host);
865 }
866 }
867
868 pub fn adorner_is_clipped(&self) -> bool {
870 self.adorner_is_clipped.get()
871 }
872
873 pub fn set_adorner_is_clipped(&self, host: &dyn CompositionVisualHooks, value: bool) {
875 let mut changed = false;
876 let old_value = self.adorner_is_clipped.get();
877 if old_value.differs(&value) {
878 CompositionVisualHooks::validate_adorner_is_clipped_change(host, old_value, value);
879 CompositionVisualHooks::on_adorner_is_clipped_changing(host);
880 changed = true;
881 self.adorner_is_clipped.set(value);
883 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ADORNER_IS_CLIPPED);
885 host.register_for_serialization();
886 }
887 self.adorner_is_clipped.set(value);
888 if changed {
889 CompositionVisualHooks::on_adorner_is_clipped_changed(host);
890 }
891 }
892
893 pub fn opacity_mask_brush_transport_field(&self) -> Option<BatchResource<dyn IBrush>> {
895 self.opacity_mask_brush.borrow().clone()
896 }
897
898 pub fn set_opacity_mask_brush_transport_field(&self, host: &dyn CompositionVisualHooks, value: Option<BatchResource<dyn IBrush>>) {
900 let mut changed = false;
901 let old_value = self.opacity_mask_brush.borrow().clone();
902 if old_value.differs(&value) {
903 CompositionVisualHooks::validate_opacity_mask_brush_change(host, &old_value, &value);
904 CompositionVisualHooks::on_opacity_mask_brush_changing(host);
905 changed = true;
906 *self.opacity_mask_brush.borrow_mut() = value.clone();
908 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OPACITY_MASK_BRUSH);
910 host.register_for_serialization();
911 }
912 *self.opacity_mask_brush.borrow_mut() = value;
913 if changed {
914 CompositionVisualHooks::on_opacity_mask_brush_changed(host);
915 }
916 }
917
918 pub fn effect(&self) -> Option<Arc<dyn IImmutableEffect>> {
920 self.effect.borrow().clone()
921 }
922
923 pub fn set_effect(&self, host: &dyn CompositionVisualHooks, value: Option<Arc<dyn IImmutableEffect>>) {
925 let mut changed = false;
926 let old_value = self.effect.borrow().clone();
927 if old_value.differs(&value) {
928 CompositionVisualHooks::validate_effect_change(host, &old_value, &value);
929 CompositionVisualHooks::on_effect_changing(host);
930 changed = true;
931 *self.effect.borrow_mut() = value.clone();
933 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::EFFECT);
935 host.register_for_serialization();
936 }
937 *self.effect.borrow_mut() = value;
938 if changed {
939 CompositionVisualHooks::on_effect_changed(host);
940 }
941 }
942
943 pub fn render_options(&self) -> RenderOptions {
945 self.render_options.get()
946 }
947
948 pub fn set_render_options(&self, host: &dyn CompositionVisualHooks, value: RenderOptions) {
950 let mut changed = false;
951 let old_value = self.render_options.get();
952 if old_value.differs(&value) {
953 CompositionVisualHooks::validate_render_options_change(host, old_value, value);
954 CompositionVisualHooks::on_render_options_changing(host);
955 changed = true;
956 self.render_options.set(value);
958 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::RENDER_OPTIONS);
960 host.register_for_serialization();
961 }
962 self.render_options.set(value);
963 if changed {
964 CompositionVisualHooks::on_render_options_changed(host);
965 }
966 }
967
968 pub fn text_options(&self) -> TextOptions {
970 self.text_options.get()
971 }
972
973 pub fn set_text_options(&self, host: &dyn CompositionVisualHooks, value: TextOptions) {
975 let mut changed = false;
976 let old_value = self.text_options.get();
977 if old_value.differs(&value) {
978 CompositionVisualHooks::validate_text_options_change(host, old_value, value);
979 CompositionVisualHooks::on_text_options_changing(host);
980 changed = true;
981 self.text_options.set(value);
983 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TEXT_OPTIONS);
985 host.register_for_serialization();
986 }
987 self.text_options.set(value);
988 if changed {
989 CompositionVisualHooks::on_text_options_changed(host);
990 }
991 }
992
993 pub fn cache_mode(&self) -> Option<Rc<dyn ICompositionObject>> {
995 self.cache_mode.borrow().clone()
996 }
997
998 pub fn set_cache_mode(&self, host: &dyn CompositionVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
1000 let mut changed = false;
1001 let old_value = self.cache_mode.borrow().clone();
1002 if old_value.differs(&value) {
1003 CompositionVisualHooks::validate_cache_mode_change(host, &old_value, &value);
1004 CompositionVisualHooks::on_cache_mode_changing(host);
1005 changed = true;
1006 *self.cache_mode.borrow_mut() = value.clone();
1008 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CACHE_MODE);
1010 host.register_for_serialization();
1011 }
1012 *self.cache_mode.borrow_mut() = value;
1013 if changed {
1014 CompositionVisualHooks::on_cache_mode_changed(host);
1015 }
1016 }
1017
1018 pub fn start_animation(
1022 &self,
1023 host: &dyn CompositionVisualHooks,
1024 property_name: &str,
1025 animation: &dyn ICompositionAnimation,
1026 final_value: Option<ExpressionVariant>,
1027 ) -> bool {
1028 if property_name == "Visible" {
1029 let server = animation.create_instance(host.server(), final_value);
1030 host.pending_animations().set(ServerCompositionVisualProps::id_of_visible_property().base(), server);
1031 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::VISIBLE_ANIMATED);
1032 host.register_for_serialization();
1033 return true;
1034 }
1035 if property_name == "Opacity" {
1036 let server = animation.create_instance(host.server(), final_value);
1037 host.pending_animations().set(ServerCompositionVisualProps::id_of_opacity_property().base(), server);
1038 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OPACITY_ANIMATED);
1039 host.register_for_serialization();
1040 return true;
1041 }
1042 if property_name == "ClipToBounds" {
1043 let server = animation.create_instance(host.server(), final_value);
1044 host.pending_animations().set(ServerCompositionVisualProps::id_of_clip_to_bounds_property().base(), server);
1045 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED);
1046 host.register_for_serialization();
1047 return true;
1048 }
1049 if property_name == "Offset" {
1050 let server = animation.create_instance(host.server(), final_value);
1051 host.pending_animations().set(ServerCompositionVisualProps::id_of_offset_property().base(), server);
1052 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::OFFSET_ANIMATED);
1053 host.register_for_serialization();
1054 return true;
1055 }
1056 if property_name == "Translation" {
1057 let server = animation.create_instance(host.server(), final_value);
1058 host.pending_animations().set(ServerCompositionVisualProps::id_of_translation_property().base(), server);
1059 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSLATION_ANIMATED);
1060 host.register_for_serialization();
1061 return true;
1062 }
1063 if property_name == "Size" {
1064 let server = animation.create_instance(host.server(), final_value);
1065 host.pending_animations().set(ServerCompositionVisualProps::id_of_size_property().base(), server);
1066 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SIZE_ANIMATED);
1067 host.register_for_serialization();
1068 return true;
1069 }
1070 if property_name == "AnchorPoint" {
1071 let server = animation.create_instance(host.server(), final_value);
1072 host.pending_animations().set(ServerCompositionVisualProps::id_of_anchor_point_property().base(), server);
1073 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED);
1074 host.register_for_serialization();
1075 return true;
1076 }
1077 if property_name == "CenterPoint" {
1078 let server = animation.create_instance(host.server(), final_value);
1079 host.pending_animations().set(ServerCompositionVisualProps::id_of_center_point_property().base(), server);
1080 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::CENTER_POINT_ANIMATED);
1081 host.register_for_serialization();
1082 return true;
1083 }
1084 if property_name == "RotationAngle" {
1085 let server = animation.create_instance(host.server(), final_value);
1086 host.pending_animations().set(ServerCompositionVisualProps::id_of_rotation_angle_property().base(), server);
1087 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED);
1088 host.register_for_serialization();
1089 return true;
1090 }
1091 if property_name == "Orientation" {
1092 let server = animation.create_instance(host.server(), final_value);
1093 host.pending_animations().set(ServerCompositionVisualProps::id_of_orientation_property().base(), server);
1094 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::ORIENTATION_ANIMATED);
1095 host.register_for_serialization();
1096 return true;
1097 }
1098 if property_name == "Scale" {
1099 let server = animation.create_instance(host.server(), final_value);
1100 host.pending_animations().set(ServerCompositionVisualProps::id_of_scale_property().base(), server);
1101 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::SCALE_ANIMATED);
1102 host.register_for_serialization();
1103 return true;
1104 }
1105 if property_name == "TransformMatrix" {
1106 let server = animation.create_instance(host.server(), final_value);
1107 host.pending_animations().set(ServerCompositionVisualProps::id_of_transform_matrix_property().base(), server);
1108 self.changed_fields_of_composition_visual.set(self.changed_fields_of_composition_visual.get() | CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED);
1109 host.register_for_serialization();
1110 return true;
1111 }
1112 false
1113 }
1114
1115 pub fn serialize_changes_core(&self, host: &dyn CompositionVisualHooks, writer: &mut BatchStreamWriter<'_>) {
1118 let changed = self.changed_fields_of_composition_visual.get();
1119 writer.write(changed);
1120 if changed.contains(CompositionVisualChangedFields::ROOT) {
1121 writer.write_server_object(self.root.borrow().clone().map(|o| o.server()));
1122 }
1123 if changed.contains(CompositionVisualChangedFields::PARENT) {
1124 writer.write_server_object(self.parent.borrow().clone().map(|o| o.server()));
1125 }
1126 if changed.contains(CompositionVisualChangedFields::VISIBLE_ANIMATED) {
1127 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_visible_property().base()));
1128 } else if changed.contains(CompositionVisualChangedFields::VISIBLE) {
1129 writer.write(self.visible.get());
1130 }
1131 if changed.contains(CompositionVisualChangedFields::OPACITY_ANIMATED) {
1132 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_opacity_property().base()));
1133 } else if changed.contains(CompositionVisualChangedFields::OPACITY) {
1134 writer.write(self.opacity.get());
1135 }
1136 if changed.contains(CompositionVisualChangedFields::CLIP) {
1137 writer.write_value(self.clip.borrow().clone());
1138 }
1139 if changed.contains(CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED) {
1140 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_clip_to_bounds_property().base()));
1141 } else if changed.contains(CompositionVisualChangedFields::CLIP_TO_BOUNDS) {
1142 writer.write(self.clip_to_bounds.get());
1143 }
1144 if changed.contains(CompositionVisualChangedFields::OFFSET_ANIMATED) {
1145 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_offset_property().base()));
1146 } else if changed.contains(CompositionVisualChangedFields::OFFSET) {
1147 writer.write(self.offset.get());
1148 }
1149 if changed.contains(CompositionVisualChangedFields::TRANSLATION_ANIMATED) {
1150 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_translation_property().base()));
1151 } else if changed.contains(CompositionVisualChangedFields::TRANSLATION) {
1152 writer.write(self.translation.get());
1153 }
1154 if changed.contains(CompositionVisualChangedFields::SIZE_ANIMATED) {
1155 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_size_property().base()));
1156 } else if changed.contains(CompositionVisualChangedFields::SIZE) {
1157 writer.write(self.size.get());
1158 }
1159 if changed.contains(CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED) {
1160 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_anchor_point_property().base()));
1161 } else if changed.contains(CompositionVisualChangedFields::ANCHOR_POINT) {
1162 writer.write(self.anchor_point.get());
1163 }
1164 if changed.contains(CompositionVisualChangedFields::CENTER_POINT_ANIMATED) {
1165 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_center_point_property().base()));
1166 } else if changed.contains(CompositionVisualChangedFields::CENTER_POINT) {
1167 writer.write(self.center_point.get());
1168 }
1169 if changed.contains(CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED) {
1170 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_rotation_angle_property().base()));
1171 } else if changed.contains(CompositionVisualChangedFields::ROTATION_ANGLE) {
1172 writer.write(self.rotation_angle.get());
1173 }
1174 if changed.contains(CompositionVisualChangedFields::ORIENTATION_ANIMATED) {
1175 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_orientation_property().base()));
1176 } else if changed.contains(CompositionVisualChangedFields::ORIENTATION) {
1177 writer.write(self.orientation.get());
1178 }
1179 if changed.contains(CompositionVisualChangedFields::SCALE_ANIMATED) {
1180 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_scale_property().base()));
1181 } else if changed.contains(CompositionVisualChangedFields::SCALE) {
1182 writer.write(self.scale.get());
1183 }
1184 if changed.contains(CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED) {
1185 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionVisualProps::id_of_transform_matrix_property().base()));
1186 } else if changed.contains(CompositionVisualChangedFields::TRANSFORM_MATRIX) {
1187 writer.write(self.transform_matrix.get());
1188 }
1189 if changed.contains(CompositionVisualChangedFields::ADORNED_VISUAL) {
1190 writer.write_server_object(self.adorned_visual.borrow().clone().map(|o| o.server()));
1191 }
1192 if changed.contains(CompositionVisualChangedFields::ADORNER_IS_CLIPPED) {
1193 writer.write(self.adorner_is_clipped.get());
1194 }
1195 if changed.contains(CompositionVisualChangedFields::OPACITY_MASK_BRUSH) {
1196 writer.write_resource(self.opacity_mask_brush.borrow().clone());
1197 }
1198 if changed.contains(CompositionVisualChangedFields::EFFECT) {
1199 writer.write_value(self.effect.borrow().clone());
1200 }
1201 if changed.contains(CompositionVisualChangedFields::RENDER_OPTIONS) {
1202 writer.write(self.render_options.get());
1203 }
1204 if changed.contains(CompositionVisualChangedFields::TEXT_OPTIONS) {
1205 writer.write(self.text_options.get());
1206 }
1207 if changed.contains(CompositionVisualChangedFields::CACHE_MODE) {
1208 writer.write_server_object(self.cache_mode.borrow().clone().map(|o| o.server()));
1209 }
1210 self.changed_fields_of_composition_visual.set(CompositionVisualChangedFields::empty());
1211 }
1212}
1213
1214pub trait ServerCompositionVisualHooks: IServerAnimatedPropertyHost {
1217 fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
1218 fn on_fields_deserialized(&self, _changed: CompositionVisualChangedFields) {}
1219
1220 fn on_root_changed(&self) {}
1221 fn on_root_changing(&self) {}
1222
1223 fn on_parent_changed(&self) {}
1224 fn on_parent_changing(&self) {}
1225
1226 fn on_clip_changed(&self) {}
1227 fn on_clip_changing(&self) {}
1228
1229 fn on_adorned_visual_changed(&self) {}
1230 fn on_adorned_visual_changing(&self) {}
1231
1232 fn on_adorner_is_clipped_changed(&self) {}
1233 fn on_adorner_is_clipped_changing(&self) {}
1234
1235 fn on_opacity_mask_brush_changed(&self) {}
1236 fn on_opacity_mask_brush_changing(&self) {}
1237
1238 fn on_effect_changed(&self) {}
1239 fn on_effect_changing(&self) {}
1240
1241 fn on_render_options_changed(&self) {}
1242 fn on_render_options_changing(&self) {}
1243
1244 fn on_text_options_changed(&self) {}
1245 fn on_text_options_changing(&self) {}
1246
1247 fn on_cache_mode_changed(&self) {}
1248 fn on_cache_mode_changing(&self) {}
1249}
1250
1251pub struct ServerCompositionVisualProps {
1253 root: RefCell<Option<Rc<dyn IServerObject>>>,
1254 parent: RefCell<Option<Rc<dyn IServerObject>>>,
1255 visible: Cell<bool>,
1256 opacity: Cell<f32>,
1257 clip: RefCell<Option<Arc<dyn IGeometryImpl>>>,
1258 clip_to_bounds: Cell<bool>,
1259 offset: Cell<Vector3D>,
1260 translation: Cell<Vector3D>,
1261 size: Cell<Vector>,
1262 anchor_point: Cell<Vector>,
1263 center_point: Cell<Vector3D>,
1264 rotation_angle: Cell<f32>,
1265 orientation: Cell<Quaternion>,
1266 scale: Cell<Vector3D>,
1267 transform_matrix: Cell<Matrix>,
1268 adorned_visual: RefCell<Option<Rc<dyn IServerObject>>>,
1269 adorner_is_clipped: Cell<bool>,
1270 opacity_mask_brush: RefCell<Option<ServerResourceRef<dyn IBrush>>>,
1271 effect: RefCell<Option<Arc<dyn IImmutableEffect>>>,
1272 render_options: Cell<RenderOptions>,
1273 text_options: Cell<TextOptions>,
1274 cache_mode: RefCell<Option<Rc<dyn IServerObject>>>,
1275}
1276
1277impl Default for ServerCompositionVisualProps {
1278 fn default() -> Self {
1279 Self::new()
1280 }
1281}
1282
1283impl ServerCompositionVisualProps {
1284 pub fn new() -> Self {
1287 Self {
1288 root: RefCell::new(None),
1289 parent: RefCell::new(None),
1290 visible: Cell::new(Default::default()),
1291 opacity: Cell::new(Default::default()),
1292 clip: RefCell::new(None),
1293 clip_to_bounds: Cell::new(Default::default()),
1294 offset: Cell::new(Default::default()),
1295 translation: Cell::new(Default::default()),
1296 size: Cell::new(Default::default()),
1297 anchor_point: Cell::new(Default::default()),
1298 center_point: Cell::new(Default::default()),
1299 rotation_angle: Cell::new(Default::default()),
1300 orientation: Cell::new(Default::default()),
1301 scale: Cell::new(Default::default()),
1302 transform_matrix: Cell::new(Default::default()),
1303 adorned_visual: RefCell::new(None),
1304 adorner_is_clipped: Cell::new(Default::default()),
1305 opacity_mask_brush: RefCell::new(None),
1306 effect: RefCell::new(None),
1307 render_options: Cell::new(Default::default()),
1308 text_options: Cell::new(Default::default()),
1309 cache_mode: RefCell::new(None),
1310 }
1311 }
1312
1313 pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
1316 if type_id == TypeId::of::<Self>() {
1317 return Some(self);
1318 }
1319 None
1320 }
1321
1322 pub fn id_of_root_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
1324 static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
1325 PROPERTY.get_or_init(|| {
1326 CompositionProperty::register::<ServerCompositionVisualProps, Option<Rc<dyn IServerObject>>>(
1327 "Root",
1328 "ServerCompositionVisual",
1329 |obj| props_of::<ServerCompositionVisualProps>(obj).root.borrow().clone(),
1330 |obj, v| *props_of::<ServerCompositionVisualProps>(obj).root.borrow_mut() = v,
1331 None,
1332 None,
1333 )
1334 })
1335 }
1336
1337 pub fn root(&self) -> Option<Rc<dyn IServerObject>> {
1339 self.root.borrow().clone()
1340 }
1341
1342 pub fn set_root(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Rc<dyn IServerObject>>) {
1343 let old_value = self.root.borrow().clone();
1344 let mut changed = false;
1345 if old_value.differs(&value) {
1346 ServerCompositionVisualHooks::on_root_changing(host);
1347 changed = true;
1348 }
1349 host.set_value(
1350 Self::id_of_root_property().base(),
1351 ServerValueChange {
1352 equal: old_value.default_equals(&value),
1353 old_resource: old_value.as_server_render_resource(),
1354 new_resource: value.as_server_render_resource(),
1355 assign: &mut || *self.root.borrow_mut() = value.clone(),
1356 },
1357 );
1358 if changed {
1359 ServerCompositionVisualHooks::on_root_changed(host);
1360 }
1361 }
1362
1363 pub fn id_of_parent_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
1365 static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
1366 PROPERTY.get_or_init(|| {
1367 CompositionProperty::register::<ServerCompositionVisualProps, Option<Rc<dyn IServerObject>>>(
1368 "Parent",
1369 "ServerCompositionVisual",
1370 |obj| props_of::<ServerCompositionVisualProps>(obj).parent.borrow().clone(),
1371 |obj, v| *props_of::<ServerCompositionVisualProps>(obj).parent.borrow_mut() = v,
1372 None,
1373 None,
1374 )
1375 })
1376 }
1377
1378 pub fn parent(&self) -> Option<Rc<dyn IServerObject>> {
1380 self.parent.borrow().clone()
1381 }
1382
1383 pub fn set_parent(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Rc<dyn IServerObject>>) {
1384 let old_value = self.parent.borrow().clone();
1385 let mut changed = false;
1386 if old_value.differs(&value) {
1387 ServerCompositionVisualHooks::on_parent_changing(host);
1388 changed = true;
1389 }
1390 host.set_value(
1391 Self::id_of_parent_property().base(),
1392 ServerValueChange {
1393 equal: old_value.default_equals(&value),
1394 old_resource: old_value.as_server_render_resource(),
1395 new_resource: value.as_server_render_resource(),
1396 assign: &mut || *self.parent.borrow_mut() = value.clone(),
1397 },
1398 );
1399 if changed {
1400 ServerCompositionVisualHooks::on_parent_changed(host);
1401 }
1402 }
1403
1404 pub fn id_of_visible_property() -> &'static CompositionPropertyOf<bool> {
1406 static PROPERTY: OnceLock<CompositionPropertyOf<bool>> = OnceLock::new();
1407 PROPERTY.get_or_init(|| {
1408 CompositionProperty::register::<ServerCompositionVisualProps, bool>(
1409 "Visible",
1410 "ServerCompositionVisual",
1411 |obj| props_of::<ServerCompositionVisualProps>(obj).visible.get(),
1412 |obj, v| props_of::<ServerCompositionVisualProps>(obj).visible.set(v),
1413 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).visible.get())),
1414 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).visible.set(v.cast_or_default::<bool>())),
1415 )
1416 })
1417 }
1418
1419 pub fn visible(&self) -> bool {
1421 self.visible.get()
1422 }
1423
1424 pub fn set_visible(&self, host: &dyn ServerCompositionVisualHooks, value: bool) {
1425 self.visible.set(value);
1426 host.remove_animation_for_property(Self::id_of_visible_property().base());
1427 }
1428
1429 pub fn id_of_opacity_property() -> &'static CompositionPropertyOf<f32> {
1431 static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
1432 PROPERTY.get_or_init(|| {
1433 CompositionProperty::register::<ServerCompositionVisualProps, f32>(
1434 "Opacity",
1435 "ServerCompositionVisual",
1436 |obj| props_of::<ServerCompositionVisualProps>(obj).opacity.get(),
1437 |obj, v| props_of::<ServerCompositionVisualProps>(obj).opacity.set(v),
1438 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).opacity.get())),
1439 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).opacity.set(v.cast_or_default::<f32>())),
1440 )
1441 })
1442 }
1443
1444 pub fn opacity(&self) -> f32 {
1446 self.opacity.get()
1447 }
1448
1449 pub fn set_opacity(&self, host: &dyn ServerCompositionVisualHooks, value: f32) {
1450 self.opacity.set(value);
1451 host.remove_animation_for_property(Self::id_of_opacity_property().base());
1452 }
1453
1454 pub fn id_of_clip_property() -> &'static CompositionPropertyOf<Option<Arc<dyn IGeometryImpl>>> {
1456 static PROPERTY: OnceLock<CompositionPropertyOf<Option<Arc<dyn IGeometryImpl>>>> = OnceLock::new();
1457 PROPERTY.get_or_init(|| {
1458 CompositionProperty::register::<ServerCompositionVisualProps, Option<Arc<dyn IGeometryImpl>>>(
1459 "Clip",
1460 "ServerCompositionVisual",
1461 |obj| props_of::<ServerCompositionVisualProps>(obj).clip.borrow().clone(),
1462 |obj, v| *props_of::<ServerCompositionVisualProps>(obj).clip.borrow_mut() = v,
1463 None,
1464 None,
1465 )
1466 })
1467 }
1468
1469 pub fn clip(&self) -> Option<Arc<dyn IGeometryImpl>> {
1471 self.clip.borrow().clone()
1472 }
1473
1474 pub fn set_clip(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Arc<dyn IGeometryImpl>>) {
1475 let old_value = self.clip.borrow().clone();
1476 let mut changed = false;
1477 if old_value.differs(&value) {
1478 ServerCompositionVisualHooks::on_clip_changing(host);
1479 changed = true;
1480 }
1481 host.set_value(
1482 Self::id_of_clip_property().base(),
1483 ServerValueChange {
1484 equal: old_value.default_equals(&value),
1485 old_resource: None,
1486 new_resource: None,
1487 assign: &mut || *self.clip.borrow_mut() = value.clone(),
1488 },
1489 );
1490 if changed {
1491 ServerCompositionVisualHooks::on_clip_changed(host);
1492 }
1493 }
1494
1495 pub fn id_of_clip_to_bounds_property() -> &'static CompositionPropertyOf<bool> {
1497 static PROPERTY: OnceLock<CompositionPropertyOf<bool>> = OnceLock::new();
1498 PROPERTY.get_or_init(|| {
1499 CompositionProperty::register::<ServerCompositionVisualProps, bool>(
1500 "ClipToBounds",
1501 "ServerCompositionVisual",
1502 |obj| props_of::<ServerCompositionVisualProps>(obj).clip_to_bounds.get(),
1503 |obj, v| props_of::<ServerCompositionVisualProps>(obj).clip_to_bounds.set(v),
1504 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).clip_to_bounds.get())),
1505 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).clip_to_bounds.set(v.cast_or_default::<bool>())),
1506 )
1507 })
1508 }
1509
1510 pub fn clip_to_bounds(&self) -> bool {
1512 self.clip_to_bounds.get()
1513 }
1514
1515 pub fn set_clip_to_bounds(&self, host: &dyn ServerCompositionVisualHooks, value: bool) {
1516 self.clip_to_bounds.set(value);
1517 host.remove_animation_for_property(Self::id_of_clip_to_bounds_property().base());
1518 }
1519
1520 pub fn id_of_offset_property() -> &'static CompositionPropertyOf<Vector3D> {
1522 static PROPERTY: OnceLock<CompositionPropertyOf<Vector3D>> = OnceLock::new();
1523 PROPERTY.get_or_init(|| {
1524 CompositionProperty::register::<ServerCompositionVisualProps, Vector3D>(
1525 "Offset",
1526 "ServerCompositionVisual",
1527 |obj| props_of::<ServerCompositionVisualProps>(obj).offset.get(),
1528 |obj, v| props_of::<ServerCompositionVisualProps>(obj).offset.set(v),
1529 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).offset.get())),
1530 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).offset.set(v.cast_or_default::<Vector3D>())),
1531 )
1532 })
1533 }
1534
1535 pub fn offset(&self) -> Vector3D {
1537 self.offset.get()
1538 }
1539
1540 pub fn set_offset(&self, host: &dyn ServerCompositionVisualHooks, value: Vector3D) {
1541 self.offset.set(value);
1542 host.remove_animation_for_property(Self::id_of_offset_property().base());
1543 }
1544
1545 pub fn id_of_translation_property() -> &'static CompositionPropertyOf<Vector3D> {
1547 static PROPERTY: OnceLock<CompositionPropertyOf<Vector3D>> = OnceLock::new();
1548 PROPERTY.get_or_init(|| {
1549 CompositionProperty::register::<ServerCompositionVisualProps, Vector3D>(
1550 "Translation",
1551 "ServerCompositionVisual",
1552 |obj| props_of::<ServerCompositionVisualProps>(obj).translation.get(),
1553 |obj, v| props_of::<ServerCompositionVisualProps>(obj).translation.set(v),
1554 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).translation.get())),
1555 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).translation.set(v.cast_or_default::<Vector3D>())),
1556 )
1557 })
1558 }
1559
1560 pub fn translation(&self) -> Vector3D {
1562 self.translation.get()
1563 }
1564
1565 pub fn set_translation(&self, host: &dyn ServerCompositionVisualHooks, value: Vector3D) {
1566 self.translation.set(value);
1567 host.remove_animation_for_property(Self::id_of_translation_property().base());
1568 }
1569
1570 pub fn id_of_size_property() -> &'static CompositionPropertyOf<Vector> {
1572 static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
1573 PROPERTY.get_or_init(|| {
1574 CompositionProperty::register::<ServerCompositionVisualProps, Vector>(
1575 "Size",
1576 "ServerCompositionVisual",
1577 |obj| props_of::<ServerCompositionVisualProps>(obj).size.get(),
1578 |obj, v| props_of::<ServerCompositionVisualProps>(obj).size.set(v),
1579 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).size.get())),
1580 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).size.set(v.cast_or_default::<Vector>())),
1581 )
1582 })
1583 }
1584
1585 pub fn size(&self) -> Vector {
1587 self.size.get()
1588 }
1589
1590 pub fn set_size(&self, host: &dyn ServerCompositionVisualHooks, value: Vector) {
1591 self.size.set(value);
1592 host.remove_animation_for_property(Self::id_of_size_property().base());
1593 }
1594
1595 pub fn id_of_anchor_point_property() -> &'static CompositionPropertyOf<Vector> {
1597 static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
1598 PROPERTY.get_or_init(|| {
1599 CompositionProperty::register::<ServerCompositionVisualProps, Vector>(
1600 "AnchorPoint",
1601 "ServerCompositionVisual",
1602 |obj| props_of::<ServerCompositionVisualProps>(obj).anchor_point.get(),
1603 |obj, v| props_of::<ServerCompositionVisualProps>(obj).anchor_point.set(v),
1604 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).anchor_point.get())),
1605 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).anchor_point.set(v.cast_or_default::<Vector>())),
1606 )
1607 })
1608 }
1609
1610 pub fn anchor_point(&self) -> Vector {
1612 self.anchor_point.get()
1613 }
1614
1615 pub fn set_anchor_point(&self, host: &dyn ServerCompositionVisualHooks, value: Vector) {
1616 self.anchor_point.set(value);
1617 host.remove_animation_for_property(Self::id_of_anchor_point_property().base());
1618 }
1619
1620 pub fn id_of_center_point_property() -> &'static CompositionPropertyOf<Vector3D> {
1622 static PROPERTY: OnceLock<CompositionPropertyOf<Vector3D>> = OnceLock::new();
1623 PROPERTY.get_or_init(|| {
1624 CompositionProperty::register::<ServerCompositionVisualProps, Vector3D>(
1625 "CenterPoint",
1626 "ServerCompositionVisual",
1627 |obj| props_of::<ServerCompositionVisualProps>(obj).center_point.get(),
1628 |obj, v| props_of::<ServerCompositionVisualProps>(obj).center_point.set(v),
1629 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).center_point.get())),
1630 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).center_point.set(v.cast_or_default::<Vector3D>())),
1631 )
1632 })
1633 }
1634
1635 pub fn center_point(&self) -> Vector3D {
1637 self.center_point.get()
1638 }
1639
1640 pub fn set_center_point(&self, host: &dyn ServerCompositionVisualHooks, value: Vector3D) {
1641 self.center_point.set(value);
1642 host.remove_animation_for_property(Self::id_of_center_point_property().base());
1643 }
1644
1645 pub fn id_of_rotation_angle_property() -> &'static CompositionPropertyOf<f32> {
1647 static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
1648 PROPERTY.get_or_init(|| {
1649 CompositionProperty::register::<ServerCompositionVisualProps, f32>(
1650 "RotationAngle",
1651 "ServerCompositionVisual",
1652 |obj| props_of::<ServerCompositionVisualProps>(obj).rotation_angle.get(),
1653 |obj, v| props_of::<ServerCompositionVisualProps>(obj).rotation_angle.set(v),
1654 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).rotation_angle.get())),
1655 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).rotation_angle.set(v.cast_or_default::<f32>())),
1656 )
1657 })
1658 }
1659
1660 pub fn rotation_angle(&self) -> f32 {
1662 self.rotation_angle.get()
1663 }
1664
1665 pub fn set_rotation_angle(&self, host: &dyn ServerCompositionVisualHooks, value: f32) {
1666 self.rotation_angle.set(value);
1667 host.remove_animation_for_property(Self::id_of_rotation_angle_property().base());
1668 }
1669
1670 pub fn id_of_orientation_property() -> &'static CompositionPropertyOf<Quaternion> {
1672 static PROPERTY: OnceLock<CompositionPropertyOf<Quaternion>> = OnceLock::new();
1673 PROPERTY.get_or_init(|| {
1674 CompositionProperty::register::<ServerCompositionVisualProps, Quaternion>(
1675 "Orientation",
1676 "ServerCompositionVisual",
1677 |obj| props_of::<ServerCompositionVisualProps>(obj).orientation.get(),
1678 |obj, v| props_of::<ServerCompositionVisualProps>(obj).orientation.set(v),
1679 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).orientation.get())),
1680 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).orientation.set(v.cast_or_default::<Quaternion>())),
1681 )
1682 })
1683 }
1684
1685 pub fn orientation(&self) -> Quaternion {
1687 self.orientation.get()
1688 }
1689
1690 pub fn set_orientation(&self, host: &dyn ServerCompositionVisualHooks, value: Quaternion) {
1691 self.orientation.set(value);
1692 host.remove_animation_for_property(Self::id_of_orientation_property().base());
1693 }
1694
1695 pub fn id_of_scale_property() -> &'static CompositionPropertyOf<Vector3D> {
1697 static PROPERTY: OnceLock<CompositionPropertyOf<Vector3D>> = OnceLock::new();
1698 PROPERTY.get_or_init(|| {
1699 CompositionProperty::register::<ServerCompositionVisualProps, Vector3D>(
1700 "Scale",
1701 "ServerCompositionVisual",
1702 |obj| props_of::<ServerCompositionVisualProps>(obj).scale.get(),
1703 |obj, v| props_of::<ServerCompositionVisualProps>(obj).scale.set(v),
1704 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).scale.get())),
1705 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).scale.set(v.cast_or_default::<Vector3D>())),
1706 )
1707 })
1708 }
1709
1710 pub fn scale(&self) -> Vector3D {
1712 self.scale.get()
1713 }
1714
1715 pub fn set_scale(&self, host: &dyn ServerCompositionVisualHooks, value: Vector3D) {
1716 self.scale.set(value);
1717 host.remove_animation_for_property(Self::id_of_scale_property().base());
1718 }
1719
1720 pub fn id_of_transform_matrix_property() -> &'static CompositionPropertyOf<Matrix> {
1722 static PROPERTY: OnceLock<CompositionPropertyOf<Matrix>> = OnceLock::new();
1723 PROPERTY.get_or_init(|| {
1724 CompositionProperty::register::<ServerCompositionVisualProps, Matrix>(
1725 "TransformMatrix",
1726 "ServerCompositionVisual",
1727 |obj| props_of::<ServerCompositionVisualProps>(obj).transform_matrix.get(),
1728 |obj, v| props_of::<ServerCompositionVisualProps>(obj).transform_matrix.set(v),
1729 None,
1730 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionVisualProps>(obj).transform_matrix.set(v.cast_or_default::<Matrix>())),
1731 )
1732 })
1733 }
1734
1735 pub fn transform_matrix(&self) -> Matrix {
1737 self.transform_matrix.get()
1738 }
1739
1740 pub fn set_transform_matrix(&self, host: &dyn ServerCompositionVisualHooks, value: Matrix) {
1741 self.transform_matrix.set(value);
1742 host.remove_animation_for_property(Self::id_of_transform_matrix_property().base());
1743 }
1744
1745 pub fn id_of_adorned_visual_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
1747 static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
1748 PROPERTY.get_or_init(|| {
1749 CompositionProperty::register::<ServerCompositionVisualProps, Option<Rc<dyn IServerObject>>>(
1750 "AdornedVisual",
1751 "ServerCompositionVisual",
1752 |obj| props_of::<ServerCompositionVisualProps>(obj).adorned_visual.borrow().clone(),
1753 |obj, v| *props_of::<ServerCompositionVisualProps>(obj).adorned_visual.borrow_mut() = v,
1754 None,
1755 None,
1756 )
1757 })
1758 }
1759
1760 pub fn adorned_visual(&self) -> Option<Rc<dyn IServerObject>> {
1762 self.adorned_visual.borrow().clone()
1763 }
1764
1765 pub fn set_adorned_visual(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Rc<dyn IServerObject>>) {
1766 let old_value = self.adorned_visual.borrow().clone();
1767 let mut changed = false;
1768 if old_value.differs(&value) {
1769 ServerCompositionVisualHooks::on_adorned_visual_changing(host);
1770 changed = true;
1771 }
1772 host.set_value(
1773 Self::id_of_adorned_visual_property().base(),
1774 ServerValueChange {
1775 equal: old_value.default_equals(&value),
1776 old_resource: old_value.as_server_render_resource(),
1777 new_resource: value.as_server_render_resource(),
1778 assign: &mut || *self.adorned_visual.borrow_mut() = value.clone(),
1779 },
1780 );
1781 if changed {
1782 ServerCompositionVisualHooks::on_adorned_visual_changed(host);
1783 }
1784 }
1785
1786 pub fn id_of_adorner_is_clipped_property() -> &'static CompositionPropertyOf<bool> {
1788 static PROPERTY: OnceLock<CompositionPropertyOf<bool>> = OnceLock::new();
1789 PROPERTY.get_or_init(|| {
1790 CompositionProperty::register::<ServerCompositionVisualProps, bool>(
1791 "AdornerIsClipped",
1792 "ServerCompositionVisual",
1793 |obj| props_of::<ServerCompositionVisualProps>(obj).adorner_is_clipped.get(),
1794 |obj, v| props_of::<ServerCompositionVisualProps>(obj).adorner_is_clipped.set(v),
1795 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionVisualProps>(obj).adorner_is_clipped.get())),
1796 None,
1797 )
1798 })
1799 }
1800
1801 pub fn adorner_is_clipped(&self) -> bool {
1803 self.adorner_is_clipped.get()
1804 }
1805
1806 pub fn set_adorner_is_clipped(&self, host: &dyn ServerCompositionVisualHooks, value: bool) {
1807 let old_value = self.adorner_is_clipped.get();
1808 let mut changed = false;
1809 if old_value.differs(&value) {
1810 ServerCompositionVisualHooks::on_adorner_is_clipped_changing(host);
1811 changed = true;
1812 }
1813 host.set_value(
1814 Self::id_of_adorner_is_clipped_property().base(),
1815 ServerValueChange {
1816 equal: old_value.default_equals(&value),
1817 old_resource: None,
1818 new_resource: None,
1819 assign: &mut || self.adorner_is_clipped.set(value),
1820 },
1821 );
1822 if changed {
1823 ServerCompositionVisualHooks::on_adorner_is_clipped_changed(host);
1824 }
1825 }
1826
1827 pub fn id_of_opacity_mask_brush_property() -> &'static CompositionPropertyOf<Option<ServerResourceRef<dyn IBrush>>> {
1829 static PROPERTY: OnceLock<CompositionPropertyOf<Option<ServerResourceRef<dyn IBrush>>>> = OnceLock::new();
1830 PROPERTY.get_or_init(|| {
1831 CompositionProperty::register::<ServerCompositionVisualProps, Option<ServerResourceRef<dyn IBrush>>>(
1832 "OpacityMaskBrush",
1833 "ServerCompositionVisual",
1834 |obj| props_of::<ServerCompositionVisualProps>(obj).opacity_mask_brush.borrow().clone(),
1835 |obj, v| *props_of::<ServerCompositionVisualProps>(obj).opacity_mask_brush.borrow_mut() = v,
1836 None,
1837 None,
1838 )
1839 })
1840 }
1841
1842 pub fn opacity_mask_brush(&self) -> Option<ServerResourceRef<dyn IBrush>> {
1844 self.opacity_mask_brush.borrow().clone()
1845 }
1846
1847 pub fn set_opacity_mask_brush(&self, host: &dyn ServerCompositionVisualHooks, value: Option<ServerResourceRef<dyn IBrush>>) {
1848 let old_value = self.opacity_mask_brush.borrow().clone();
1849 let mut changed = false;
1850 if old_value.differs(&value) {
1851 ServerCompositionVisualHooks::on_opacity_mask_brush_changing(host);
1852 changed = true;
1853 }
1854 host.set_value(
1855 Self::id_of_opacity_mask_brush_property().base(),
1856 ServerValueChange {
1857 equal: old_value.default_equals(&value),
1858 old_resource: old_value.as_server_render_resource(),
1859 new_resource: value.as_server_render_resource(),
1860 assign: &mut || *self.opacity_mask_brush.borrow_mut() = value.clone(),
1861 },
1862 );
1863 if changed {
1864 ServerCompositionVisualHooks::on_opacity_mask_brush_changed(host);
1865 }
1866 }
1867
1868 pub fn id_of_effect_property() -> &'static CompositionPropertyOf<Option<Arc<dyn IImmutableEffect>>> {
1870 static PROPERTY: OnceLock<CompositionPropertyOf<Option<Arc<dyn IImmutableEffect>>>> = OnceLock::new();
1871 PROPERTY.get_or_init(|| {
1872 CompositionProperty::register::<ServerCompositionVisualProps, Option<Arc<dyn IImmutableEffect>>>(
1873 "Effect",
1874 "ServerCompositionVisual",
1875 |obj| props_of::<ServerCompositionVisualProps>(obj).effect.borrow().clone(),
1876 |obj, v| *props_of::<ServerCompositionVisualProps>(obj).effect.borrow_mut() = v,
1877 None,
1878 None,
1879 )
1880 })
1881 }
1882
1883 pub fn effect(&self) -> Option<Arc<dyn IImmutableEffect>> {
1885 self.effect.borrow().clone()
1886 }
1887
1888 pub fn set_effect(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Arc<dyn IImmutableEffect>>) {
1889 let old_value = self.effect.borrow().clone();
1890 let mut changed = false;
1891 if old_value.differs(&value) {
1892 ServerCompositionVisualHooks::on_effect_changing(host);
1893 changed = true;
1894 }
1895 host.set_value(
1896 Self::id_of_effect_property().base(),
1897 ServerValueChange {
1898 equal: old_value.default_equals(&value),
1899 old_resource: None,
1900 new_resource: None,
1901 assign: &mut || *self.effect.borrow_mut() = value.clone(),
1902 },
1903 );
1904 if changed {
1905 ServerCompositionVisualHooks::on_effect_changed(host);
1906 }
1907 }
1908
1909 pub fn id_of_render_options_property() -> &'static CompositionPropertyOf<RenderOptions> {
1911 static PROPERTY: OnceLock<CompositionPropertyOf<RenderOptions>> = OnceLock::new();
1912 PROPERTY.get_or_init(|| {
1913 CompositionProperty::register::<ServerCompositionVisualProps, RenderOptions>(
1914 "RenderOptions",
1915 "ServerCompositionVisual",
1916 |obj| props_of::<ServerCompositionVisualProps>(obj).render_options.get(),
1917 |obj, v| props_of::<ServerCompositionVisualProps>(obj).render_options.set(v),
1918 None,
1919 None,
1920 )
1921 })
1922 }
1923
1924 pub fn render_options(&self) -> RenderOptions {
1926 self.render_options.get()
1927 }
1928
1929 pub fn set_render_options(&self, host: &dyn ServerCompositionVisualHooks, value: RenderOptions) {
1930 let old_value = self.render_options.get();
1931 let mut changed = false;
1932 if old_value.differs(&value) {
1933 ServerCompositionVisualHooks::on_render_options_changing(host);
1934 changed = true;
1935 }
1936 host.set_value(
1937 Self::id_of_render_options_property().base(),
1938 ServerValueChange {
1939 equal: old_value.default_equals(&value),
1940 old_resource: None,
1941 new_resource: None,
1942 assign: &mut || self.render_options.set(value),
1943 },
1944 );
1945 if changed {
1946 ServerCompositionVisualHooks::on_render_options_changed(host);
1947 }
1948 }
1949
1950 pub fn id_of_text_options_property() -> &'static CompositionPropertyOf<TextOptions> {
1952 static PROPERTY: OnceLock<CompositionPropertyOf<TextOptions>> = OnceLock::new();
1953 PROPERTY.get_or_init(|| {
1954 CompositionProperty::register::<ServerCompositionVisualProps, TextOptions>(
1955 "TextOptions",
1956 "ServerCompositionVisual",
1957 |obj| props_of::<ServerCompositionVisualProps>(obj).text_options.get(),
1958 |obj, v| props_of::<ServerCompositionVisualProps>(obj).text_options.set(v),
1959 None,
1960 None,
1961 )
1962 })
1963 }
1964
1965 pub fn text_options(&self) -> TextOptions {
1967 self.text_options.get()
1968 }
1969
1970 pub fn set_text_options(&self, host: &dyn ServerCompositionVisualHooks, value: TextOptions) {
1971 let old_value = self.text_options.get();
1972 let mut changed = false;
1973 if old_value.differs(&value) {
1974 ServerCompositionVisualHooks::on_text_options_changing(host);
1975 changed = true;
1976 }
1977 host.set_value(
1978 Self::id_of_text_options_property().base(),
1979 ServerValueChange {
1980 equal: old_value.default_equals(&value),
1981 old_resource: None,
1982 new_resource: None,
1983 assign: &mut || self.text_options.set(value),
1984 },
1985 );
1986 if changed {
1987 ServerCompositionVisualHooks::on_text_options_changed(host);
1988 }
1989 }
1990
1991 pub fn id_of_cache_mode_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
1993 static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
1994 PROPERTY.get_or_init(|| {
1995 CompositionProperty::register::<ServerCompositionVisualProps, Option<Rc<dyn IServerObject>>>(
1996 "CacheMode",
1997 "ServerCompositionVisual",
1998 |obj| props_of::<ServerCompositionVisualProps>(obj).cache_mode.borrow().clone(),
1999 |obj, v| *props_of::<ServerCompositionVisualProps>(obj).cache_mode.borrow_mut() = v,
2000 None,
2001 None,
2002 )
2003 })
2004 }
2005
2006 pub fn cache_mode(&self) -> Option<Rc<dyn IServerObject>> {
2008 self.cache_mode.borrow().clone()
2009 }
2010
2011 pub fn set_cache_mode(&self, host: &dyn ServerCompositionVisualHooks, value: Option<Rc<dyn IServerObject>>) {
2012 let old_value = self.cache_mode.borrow().clone();
2013 let mut changed = false;
2014 if old_value.differs(&value) {
2015 ServerCompositionVisualHooks::on_cache_mode_changing(host);
2016 changed = true;
2017 }
2018 host.set_value(
2019 Self::id_of_cache_mode_property().base(),
2020 ServerValueChange {
2021 equal: old_value.default_equals(&value),
2022 old_resource: old_value.as_server_render_resource(),
2023 new_resource: value.as_server_render_resource(),
2024 assign: &mut || *self.cache_mode.borrow_mut() = value.clone(),
2025 },
2026 );
2027 if changed {
2028 ServerCompositionVisualHooks::on_cache_mode_changed(host);
2029 }
2030 }
2031
2032 pub fn deserialize_changes_core(
2035 &self,
2036 host: &dyn ServerCompositionVisualHooks,
2037 reader: &mut BatchStreamReader<'_>,
2038 committed_at: Duration,
2039 ) {
2040 let compositor = host.server_compositor();
2041 ServerCompositionVisualHooks::deserialize_changes_extra(host, reader);
2042 let changed = reader.read::<CompositionVisualChangedFields>();
2043 if changed.contains(CompositionVisualChangedFields::ROOT) {
2044 let value = read_server_object(reader, compositor.as_ref());
2045 self.set_root(host, value);
2046 }
2047 if changed.contains(CompositionVisualChangedFields::PARENT) {
2048 let value = read_server_object(reader, compositor.as_ref());
2049 self.set_parent(host, value);
2050 }
2051 if changed.contains(CompositionVisualChangedFields::VISIBLE_ANIMATED) {
2052 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2053 panic!("a batch starts an animation of `Visible` without an animation instance");
2054 };
2055 host.set_animated_value(
2056 Self::id_of_visible_property().base(),
2057 ExpressionVariant::create(self.visible.get()),
2058 committed_at,
2059 animation,
2060 );
2061 } else if changed.contains(CompositionVisualChangedFields::VISIBLE) {
2062 let value = reader.read::<bool>();
2063 self.set_visible(host, value);
2064 }
2065 if changed.contains(CompositionVisualChangedFields::OPACITY_ANIMATED) {
2066 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2067 panic!("a batch starts an animation of `Opacity` without an animation instance");
2068 };
2069 host.set_animated_value(
2070 Self::id_of_opacity_property().base(),
2071 ExpressionVariant::create(self.opacity.get()),
2072 committed_at,
2073 animation,
2074 );
2075 } else if changed.contains(CompositionVisualChangedFields::OPACITY) {
2076 let value = reader.read::<f32>();
2077 self.set_opacity(host, value);
2078 }
2079 if changed.contains(CompositionVisualChangedFields::CLIP) {
2080 let value = reader.read_value::<Arc<dyn IGeometryImpl>>();
2081 self.set_clip(host, value);
2082 }
2083 if changed.contains(CompositionVisualChangedFields::CLIP_TO_BOUNDS_ANIMATED) {
2084 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2085 panic!("a batch starts an animation of `ClipToBounds` without an animation instance");
2086 };
2087 host.set_animated_value(
2088 Self::id_of_clip_to_bounds_property().base(),
2089 ExpressionVariant::create(self.clip_to_bounds.get()),
2090 committed_at,
2091 animation,
2092 );
2093 } else if changed.contains(CompositionVisualChangedFields::CLIP_TO_BOUNDS) {
2094 let value = reader.read::<bool>();
2095 self.set_clip_to_bounds(host, value);
2096 }
2097 if changed.contains(CompositionVisualChangedFields::OFFSET_ANIMATED) {
2098 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2099 panic!("a batch starts an animation of `Offset` without an animation instance");
2100 };
2101 host.set_animated_value(
2102 Self::id_of_offset_property().base(),
2103 ExpressionVariant::create(self.offset.get()),
2104 committed_at,
2105 animation,
2106 );
2107 } else if changed.contains(CompositionVisualChangedFields::OFFSET) {
2108 let value = reader.read::<Vector3D>();
2109 self.set_offset(host, value);
2110 }
2111 if changed.contains(CompositionVisualChangedFields::TRANSLATION_ANIMATED) {
2112 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2113 panic!("a batch starts an animation of `Translation` without an animation instance");
2114 };
2115 host.set_animated_value(
2116 Self::id_of_translation_property().base(),
2117 ExpressionVariant::create(self.translation.get()),
2118 committed_at,
2119 animation,
2120 );
2121 } else if changed.contains(CompositionVisualChangedFields::TRANSLATION) {
2122 let value = reader.read::<Vector3D>();
2123 self.set_translation(host, value);
2124 }
2125 if changed.contains(CompositionVisualChangedFields::SIZE_ANIMATED) {
2126 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2127 panic!("a batch starts an animation of `Size` without an animation instance");
2128 };
2129 host.set_animated_value(
2130 Self::id_of_size_property().base(),
2131 ExpressionVariant::create(self.size.get()),
2132 committed_at,
2133 animation,
2134 );
2135 } else if changed.contains(CompositionVisualChangedFields::SIZE) {
2136 let value = reader.read::<Vector>();
2137 self.set_size(host, value);
2138 }
2139 if changed.contains(CompositionVisualChangedFields::ANCHOR_POINT_ANIMATED) {
2140 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2141 panic!("a batch starts an animation of `AnchorPoint` without an animation instance");
2142 };
2143 host.set_animated_value(
2144 Self::id_of_anchor_point_property().base(),
2145 ExpressionVariant::create(self.anchor_point.get()),
2146 committed_at,
2147 animation,
2148 );
2149 } else if changed.contains(CompositionVisualChangedFields::ANCHOR_POINT) {
2150 let value = reader.read::<Vector>();
2151 self.set_anchor_point(host, value);
2152 }
2153 if changed.contains(CompositionVisualChangedFields::CENTER_POINT_ANIMATED) {
2154 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2155 panic!("a batch starts an animation of `CenterPoint` without an animation instance");
2156 };
2157 host.set_animated_value(
2158 Self::id_of_center_point_property().base(),
2159 ExpressionVariant::create(self.center_point.get()),
2160 committed_at,
2161 animation,
2162 );
2163 } else if changed.contains(CompositionVisualChangedFields::CENTER_POINT) {
2164 let value = reader.read::<Vector3D>();
2165 self.set_center_point(host, value);
2166 }
2167 if changed.contains(CompositionVisualChangedFields::ROTATION_ANGLE_ANIMATED) {
2168 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2169 panic!("a batch starts an animation of `RotationAngle` without an animation instance");
2170 };
2171 host.set_animated_value(
2172 Self::id_of_rotation_angle_property().base(),
2173 ExpressionVariant::create(self.rotation_angle.get()),
2174 committed_at,
2175 animation,
2176 );
2177 } else if changed.contains(CompositionVisualChangedFields::ROTATION_ANGLE) {
2178 let value = reader.read::<f32>();
2179 self.set_rotation_angle(host, value);
2180 }
2181 if changed.contains(CompositionVisualChangedFields::ORIENTATION_ANIMATED) {
2182 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2183 panic!("a batch starts an animation of `Orientation` without an animation instance");
2184 };
2185 host.set_animated_value(
2186 Self::id_of_orientation_property().base(),
2187 ExpressionVariant::create(self.orientation.get()),
2188 committed_at,
2189 animation,
2190 );
2191 } else if changed.contains(CompositionVisualChangedFields::ORIENTATION) {
2192 let value = reader.read::<Quaternion>();
2193 self.set_orientation(host, value);
2194 }
2195 if changed.contains(CompositionVisualChangedFields::SCALE_ANIMATED) {
2196 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2197 panic!("a batch starts an animation of `Scale` without an animation instance");
2198 };
2199 host.set_animated_value(
2200 Self::id_of_scale_property().base(),
2201 ExpressionVariant::create(self.scale.get()),
2202 committed_at,
2203 animation,
2204 );
2205 } else if changed.contains(CompositionVisualChangedFields::SCALE) {
2206 let value = reader.read::<Vector3D>();
2207 self.set_scale(host, value);
2208 }
2209 if changed.contains(CompositionVisualChangedFields::TRANSFORM_MATRIX_ANIMATED) {
2210 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
2211 panic!("a batch starts an animation of `TransformMatrix` without an animation instance");
2212 };
2213 host.set_animated_value(
2214 Self::id_of_transform_matrix_property().base(),
2215 ExpressionVariant::create(self.transform_matrix.get()),
2216 committed_at,
2217 animation,
2218 );
2219 } else if changed.contains(CompositionVisualChangedFields::TRANSFORM_MATRIX) {
2220 let value = reader.read::<Matrix>();
2221 self.set_transform_matrix(host, value);
2222 }
2223 if changed.contains(CompositionVisualChangedFields::ADORNED_VISUAL) {
2224 let value = read_server_object(reader, compositor.as_ref());
2225 self.set_adorned_visual(host, value);
2226 }
2227 if changed.contains(CompositionVisualChangedFields::ADORNER_IS_CLIPPED) {
2228 let value = reader.read::<bool>();
2229 self.set_adorner_is_clipped(host, value);
2230 }
2231 if changed.contains(CompositionVisualChangedFields::OPACITY_MASK_BRUSH) {
2232 let value = read_resource(reader, compositor.as_ref(), |o| o.as_brush());
2233 self.set_opacity_mask_brush(host, value);
2234 }
2235 if changed.contains(CompositionVisualChangedFields::EFFECT) {
2236 let value = reader.read_value::<Arc<dyn IImmutableEffect>>();
2237 self.set_effect(host, value);
2238 }
2239 if changed.contains(CompositionVisualChangedFields::RENDER_OPTIONS) {
2240 let value = reader.read::<RenderOptions>();
2241 self.set_render_options(host, value);
2242 }
2243 if changed.contains(CompositionVisualChangedFields::TEXT_OPTIONS) {
2244 let value = reader.read::<TextOptions>();
2245 self.set_text_options(host, value);
2246 }
2247 if changed.contains(CompositionVisualChangedFields::CACHE_MODE) {
2248 let value = read_server_object(reader, compositor.as_ref());
2249 self.set_cache_mode(host, value);
2250 }
2251 ServerCompositionVisualHooks::on_fields_deserialized(host, changed);
2252 }
2253
2254 pub fn get_composition_property(name: &str) -> Option<&'static CompositionProperty> {
2257 if name == "Visible" {
2258 return Some(Self::id_of_visible_property().base());
2259 }
2260 if name == "Opacity" {
2261 return Some(Self::id_of_opacity_property().base());
2262 }
2263 if name == "ClipToBounds" {
2264 return Some(Self::id_of_clip_to_bounds_property().base());
2265 }
2266 if name == "Offset" {
2267 return Some(Self::id_of_offset_property().base());
2268 }
2269 if name == "Translation" {
2270 return Some(Self::id_of_translation_property().base());
2271 }
2272 if name == "Size" {
2273 return Some(Self::id_of_size_property().base());
2274 }
2275 if name == "AnchorPoint" {
2276 return Some(Self::id_of_anchor_point_property().base());
2277 }
2278 if name == "CenterPoint" {
2279 return Some(Self::id_of_center_point_property().base());
2280 }
2281 if name == "RotationAngle" {
2282 return Some(Self::id_of_rotation_angle_property().base());
2283 }
2284 if name == "Orientation" {
2285 return Some(Self::id_of_orientation_property().base());
2286 }
2287 if name == "Scale" {
2288 return Some(Self::id_of_scale_property().base());
2289 }
2290 if name == "AdornerIsClipped" {
2291 return Some(Self::id_of_adorner_is_clipped_property().base());
2292 }
2293 None
2294 }
2295}