1use bitflags::bitflags;
8use crate::Vector;
9use crate::rendering::composition::CompositionStretch;
10use crate::rendering::composition::ICompositionObjectHost;
11use crate::rendering::composition::animations::AnimationInstanceFactory;
12use crate::rendering::composition::animations::ICompositionAnimation;
13use crate::rendering::composition::expressions::ExpressionVariant;
14use crate::rendering::composition::server::CompositionProperty;
15use crate::rendering::composition::server::CompositionPropertyOf;
16use crate::rendering::composition::server::IServerAnimatedPropertyHost;
17use crate::rendering::composition::server::ServerPropertyValue;
18use crate::rendering::composition::server::ServerValueChange;
19use crate::rendering::composition::server::props_of;
20use crate::rendering::composition::transport::BatchStreamReader;
21use crate::rendering::composition::transport::BatchStreamWriter;
22use crate::rendering::composition::transport::BatchValue;
23use crate::rendering::composition::transport::BatchValueReader;
24use std::any::Any;
25use std::any::TypeId;
26use std::cell::Cell;
27use std::sync::OnceLock;
28use std::time::Duration;
29
30bitflags! {
31 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
33 pub struct CompositionViewBoxChangedFields: u16 {
34 const HORIZONTAL_ALIGNMENT_RATIO = 1;
35 const HORIZONTAL_ALIGNMENT_RATIO_ANIMATED = 2;
36 const OFFSET = 4;
37 const OFFSET_ANIMATED = 8;
38 const SIZE = 16;
39 const SIZE_ANIMATED = 32;
40 const STRETCH = 64;
41 const VERTICAL_ALIGNMENT_RATIO = 128;
42 const VERTICAL_ALIGNMENT_RATIO_ANIMATED = 256;
43 }
44}
45
46impl BatchValue for CompositionViewBoxChangedFields {
47 #[inline]
48 fn write_to(&self, out: &mut Vec<u8>) {
49 self.bits().write_to(out);
50 }
51
52 #[inline]
53 fn read_from(input: &mut BatchValueReader<'_>) -> Self {
54 CompositionViewBoxChangedFields::from_bits_retain(u16::read_from(input))
55 }
56}
57
58pub trait CompositionViewBoxHooks: ICompositionObjectHost {
61 fn initialize_defaults_extra(&self) {}
62
63 fn validate_horizontal_alignment_ratio_change(&self, _old_value: f32, _new_value: f32) {}
64 fn on_horizontal_alignment_ratio_changed(&self) {}
65 fn on_horizontal_alignment_ratio_changing(&self) {}
66
67 fn validate_offset_change(&self, _old_value: Vector, _new_value: Vector) {}
68 fn on_offset_changed(&self) {}
69 fn on_offset_changing(&self) {}
70
71 fn validate_size_change(&self, _old_value: Vector, _new_value: Vector) {}
72 fn on_size_changed(&self) {}
73 fn on_size_changing(&self) {}
74
75 fn validate_stretch_change(&self, _old_value: CompositionStretch, _new_value: CompositionStretch) {}
76 fn on_stretch_changed(&self) {}
77 fn on_stretch_changing(&self) {}
78
79 fn validate_vertical_alignment_ratio_change(&self, _old_value: f32, _new_value: f32) {}
80 fn on_vertical_alignment_ratio_changed(&self) {}
81 fn on_vertical_alignment_ratio_changing(&self) {}
82}
83
84pub struct CompositionViewBoxProps {
86 changed_fields_of_composition_view_box: Cell<CompositionViewBoxChangedFields>,
87 horizontal_alignment_ratio: Cell<f32>,
88 offset: Cell<Vector>,
89 size: Cell<Vector>,
90 stretch: Cell<CompositionStretch>,
91 vertical_alignment_ratio: Cell<f32>,
92}
93
94impl Default for CompositionViewBoxProps {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100impl CompositionViewBoxProps {
101 pub fn new() -> Self {
105 Self {
106 changed_fields_of_composition_view_box: Cell::new(CompositionViewBoxChangedFields::empty()),
107 horizontal_alignment_ratio: Cell::new(Default::default()),
108 offset: Cell::new(Default::default()),
109 size: Cell::new(Default::default()),
110 stretch: Cell::new(Default::default()),
111 vertical_alignment_ratio: Cell::new(Default::default()),
112 }
113 }
114
115 pub fn initialize_defaults(&self, host: &dyn CompositionViewBoxHooks) {
118 self.initialize_own_defaults(host);
119 }
120
121 pub fn initialize_own_defaults(&self, host: &dyn CompositionViewBoxHooks) {
123 CompositionViewBoxHooks::initialize_defaults_extra(host);
124 self.set_horizontal_alignment_ratio(host, 0.5);
125 self.set_stretch(host, CompositionStretch::Fill);
126 self.set_vertical_alignment_ratio(host, 0.5);
127 }
128
129 pub fn horizontal_alignment_ratio(&self) -> f32 {
131 self.horizontal_alignment_ratio.get()
132 }
133
134 pub fn set_horizontal_alignment_ratio(&self, host: &dyn CompositionViewBoxHooks, value: f32) {
136 let mut changed = false;
137 let old_value = self.horizontal_alignment_ratio.get();
138 if old_value.differs(&value) {
139 CompositionViewBoxHooks::validate_horizontal_alignment_ratio_change(host, old_value, value);
140 CompositionViewBoxHooks::on_horizontal_alignment_ratio_changing(host);
141 changed = true;
142 self.horizontal_alignment_ratio.set(value);
144 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::HORIZONTAL_ALIGNMENT_RATIO);
146 host.register_for_serialization();
147 host.pending_animations().remove(ServerCompositionViewBoxProps::id_of_horizontal_alignment_ratio_property().base());
149 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() & !CompositionViewBoxChangedFields::HORIZONTAL_ALIGNMENT_RATIO_ANIMATED);
150 if let Some(animation) = host.implicit_animation("HorizontalAlignmentRatio") {
152 if let Some(a) = animation.as_composition_animation() {
154 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::HORIZONTAL_ALIGNMENT_RATIO_ANIMATED);
155 host.pending_animations().set(
156 ServerCompositionViewBoxProps::id_of_horizontal_alignment_ratio_property().base(),
157 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
158 );
159 }
160 host.start_animation_group(&animation, "HorizontalAlignmentRatio", ExpressionVariant::create(value));
162 }
163 }
164 self.horizontal_alignment_ratio.set(value);
165 if changed {
166 CompositionViewBoxHooks::on_horizontal_alignment_ratio_changed(host);
167 }
168 }
169
170 pub fn offset(&self) -> Vector {
172 self.offset.get()
173 }
174
175 pub fn set_offset(&self, host: &dyn CompositionViewBoxHooks, value: Vector) {
177 let mut changed = false;
178 let old_value = self.offset.get();
179 if old_value.differs(&value) {
180 CompositionViewBoxHooks::validate_offset_change(host, old_value, value);
181 CompositionViewBoxHooks::on_offset_changing(host);
182 changed = true;
183 self.offset.set(value);
185 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::OFFSET);
187 host.register_for_serialization();
188 host.pending_animations().remove(ServerCompositionViewBoxProps::id_of_offset_property().base());
190 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() & !CompositionViewBoxChangedFields::OFFSET_ANIMATED);
191 if let Some(animation) = host.implicit_animation("Offset") {
193 if let Some(a) = animation.as_composition_animation() {
195 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::OFFSET_ANIMATED);
196 host.pending_animations().set(
197 ServerCompositionViewBoxProps::id_of_offset_property().base(),
198 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
199 );
200 }
201 host.start_animation_group(&animation, "Offset", ExpressionVariant::create(value));
203 }
204 }
205 self.offset.set(value);
206 if changed {
207 CompositionViewBoxHooks::on_offset_changed(host);
208 }
209 }
210
211 pub fn size(&self) -> Vector {
213 self.size.get()
214 }
215
216 pub fn set_size(&self, host: &dyn CompositionViewBoxHooks, value: Vector) {
218 let mut changed = false;
219 let old_value = self.size.get();
220 if old_value.differs(&value) {
221 CompositionViewBoxHooks::validate_size_change(host, old_value, value);
222 CompositionViewBoxHooks::on_size_changing(host);
223 changed = true;
224 self.size.set(value);
226 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::SIZE);
228 host.register_for_serialization();
229 host.pending_animations().remove(ServerCompositionViewBoxProps::id_of_size_property().base());
231 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() & !CompositionViewBoxChangedFields::SIZE_ANIMATED);
232 if let Some(animation) = host.implicit_animation("Size") {
234 if let Some(a) = animation.as_composition_animation() {
236 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::SIZE_ANIMATED);
237 host.pending_animations().set(
238 ServerCompositionViewBoxProps::id_of_size_property().base(),
239 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
240 );
241 }
242 host.start_animation_group(&animation, "Size", ExpressionVariant::create(value));
244 }
245 }
246 self.size.set(value);
247 if changed {
248 CompositionViewBoxHooks::on_size_changed(host);
249 }
250 }
251
252 pub fn stretch(&self) -> CompositionStretch {
254 self.stretch.get()
255 }
256
257 pub fn set_stretch(&self, host: &dyn CompositionViewBoxHooks, value: CompositionStretch) {
259 let mut changed = false;
260 let old_value = self.stretch.get();
261 if old_value.differs(&value) {
262 CompositionViewBoxHooks::validate_stretch_change(host, old_value, value);
263 CompositionViewBoxHooks::on_stretch_changing(host);
264 changed = true;
265 self.stretch.set(value);
267 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::STRETCH);
269 host.register_for_serialization();
270 }
271 self.stretch.set(value);
272 if changed {
273 CompositionViewBoxHooks::on_stretch_changed(host);
274 }
275 }
276
277 pub fn vertical_alignment_ratio(&self) -> f32 {
279 self.vertical_alignment_ratio.get()
280 }
281
282 pub fn set_vertical_alignment_ratio(&self, host: &dyn CompositionViewBoxHooks, value: f32) {
284 let mut changed = false;
285 let old_value = self.vertical_alignment_ratio.get();
286 if old_value.differs(&value) {
287 CompositionViewBoxHooks::validate_vertical_alignment_ratio_change(host, old_value, value);
288 CompositionViewBoxHooks::on_vertical_alignment_ratio_changing(host);
289 changed = true;
290 self.vertical_alignment_ratio.set(value);
292 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::VERTICAL_ALIGNMENT_RATIO);
294 host.register_for_serialization();
295 host.pending_animations().remove(ServerCompositionViewBoxProps::id_of_vertical_alignment_ratio_property().base());
297 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() & !CompositionViewBoxChangedFields::VERTICAL_ALIGNMENT_RATIO_ANIMATED);
298 if let Some(animation) = host.implicit_animation("VerticalAlignmentRatio") {
300 if let Some(a) = animation.as_composition_animation() {
302 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::VERTICAL_ALIGNMENT_RATIO_ANIMATED);
303 host.pending_animations().set(
304 ServerCompositionViewBoxProps::id_of_vertical_alignment_ratio_property().base(),
305 a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
306 );
307 }
308 host.start_animation_group(&animation, "VerticalAlignmentRatio", ExpressionVariant::create(value));
310 }
311 }
312 self.vertical_alignment_ratio.set(value);
313 if changed {
314 CompositionViewBoxHooks::on_vertical_alignment_ratio_changed(host);
315 }
316 }
317
318 pub fn start_animation(
322 &self,
323 host: &dyn CompositionViewBoxHooks,
324 property_name: &str,
325 animation: &dyn ICompositionAnimation,
326 final_value: Option<ExpressionVariant>,
327 ) -> bool {
328 if property_name == "HorizontalAlignmentRatio" {
329 let server = animation.create_instance(host.server(), final_value);
330 host.pending_animations().set(ServerCompositionViewBoxProps::id_of_horizontal_alignment_ratio_property().base(), server);
331 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::HORIZONTAL_ALIGNMENT_RATIO_ANIMATED);
332 host.register_for_serialization();
333 return true;
334 }
335 if property_name == "Offset" {
336 let server = animation.create_instance(host.server(), final_value);
337 host.pending_animations().set(ServerCompositionViewBoxProps::id_of_offset_property().base(), server);
338 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::OFFSET_ANIMATED);
339 host.register_for_serialization();
340 return true;
341 }
342 if property_name == "Size" {
343 let server = animation.create_instance(host.server(), final_value);
344 host.pending_animations().set(ServerCompositionViewBoxProps::id_of_size_property().base(), server);
345 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::SIZE_ANIMATED);
346 host.register_for_serialization();
347 return true;
348 }
349 if property_name == "VerticalAlignmentRatio" {
350 let server = animation.create_instance(host.server(), final_value);
351 host.pending_animations().set(ServerCompositionViewBoxProps::id_of_vertical_alignment_ratio_property().base(), server);
352 self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::VERTICAL_ALIGNMENT_RATIO_ANIMATED);
353 host.register_for_serialization();
354 return true;
355 }
356 false
357 }
358
359 pub fn serialize_changes_core(&self, host: &dyn CompositionViewBoxHooks, writer: &mut BatchStreamWriter<'_>) {
362 let changed = self.changed_fields_of_composition_view_box.get();
363 writer.write(changed);
364 if changed.contains(CompositionViewBoxChangedFields::HORIZONTAL_ALIGNMENT_RATIO_ANIMATED) {
365 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionViewBoxProps::id_of_horizontal_alignment_ratio_property().base()));
366 } else if changed.contains(CompositionViewBoxChangedFields::HORIZONTAL_ALIGNMENT_RATIO) {
367 writer.write(self.horizontal_alignment_ratio.get());
368 }
369 if changed.contains(CompositionViewBoxChangedFields::OFFSET_ANIMATED) {
370 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionViewBoxProps::id_of_offset_property().base()));
371 } else if changed.contains(CompositionViewBoxChangedFields::OFFSET) {
372 writer.write(self.offset.get());
373 }
374 if changed.contains(CompositionViewBoxChangedFields::SIZE_ANIMATED) {
375 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionViewBoxProps::id_of_size_property().base()));
376 } else if changed.contains(CompositionViewBoxChangedFields::SIZE) {
377 writer.write(self.size.get());
378 }
379 if changed.contains(CompositionViewBoxChangedFields::STRETCH) {
380 writer.write(self.stretch.get());
381 }
382 if changed.contains(CompositionViewBoxChangedFields::VERTICAL_ALIGNMENT_RATIO_ANIMATED) {
383 writer.write_value(host.pending_animations().get_and_remove(ServerCompositionViewBoxProps::id_of_vertical_alignment_ratio_property().base()));
384 } else if changed.contains(CompositionViewBoxChangedFields::VERTICAL_ALIGNMENT_RATIO) {
385 writer.write(self.vertical_alignment_ratio.get());
386 }
387 self.changed_fields_of_composition_view_box.set(CompositionViewBoxChangedFields::empty());
388 }
389}
390
391pub trait ServerCompositionViewBoxHooks: IServerAnimatedPropertyHost {
394 fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
395 fn on_fields_deserialized(&self, _changed: CompositionViewBoxChangedFields) {}
396
397 fn on_stretch_changed(&self) {}
398 fn on_stretch_changing(&self) {}
399}
400
401pub struct ServerCompositionViewBoxProps {
403 horizontal_alignment_ratio: Cell<f32>,
404 offset: Cell<Vector>,
405 size: Cell<Vector>,
406 stretch: Cell<CompositionStretch>,
407 vertical_alignment_ratio: Cell<f32>,
408}
409
410impl Default for ServerCompositionViewBoxProps {
411 fn default() -> Self {
412 Self::new()
413 }
414}
415
416impl ServerCompositionViewBoxProps {
417 pub fn new() -> Self {
420 Self {
421 horizontal_alignment_ratio: Cell::new(Default::default()),
422 offset: Cell::new(Default::default()),
423 size: Cell::new(Default::default()),
424 stretch: Cell::new(Default::default()),
425 vertical_alignment_ratio: Cell::new(Default::default()),
426 }
427 }
428
429 pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
432 if type_id == TypeId::of::<Self>() {
433 return Some(self);
434 }
435 None
436 }
437
438 pub fn id_of_horizontal_alignment_ratio_property() -> &'static CompositionPropertyOf<f32> {
440 static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
441 PROPERTY.get_or_init(|| {
442 CompositionProperty::register::<ServerCompositionViewBoxProps, f32>(
443 "HorizontalAlignmentRatio",
444 "ServerCompositionViewBox",
445 |obj| props_of::<ServerCompositionViewBoxProps>(obj).horizontal_alignment_ratio.get(),
446 |obj, v| props_of::<ServerCompositionViewBoxProps>(obj).horizontal_alignment_ratio.set(v),
447 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionViewBoxProps>(obj).horizontal_alignment_ratio.get())),
448 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionViewBoxProps>(obj).horizontal_alignment_ratio.set(v.cast_or_default::<f32>())),
449 )
450 })
451 }
452
453 pub fn horizontal_alignment_ratio(&self) -> f32 {
455 self.horizontal_alignment_ratio.get()
456 }
457
458 pub fn set_horizontal_alignment_ratio(&self, host: &dyn ServerCompositionViewBoxHooks, value: f32) {
459 self.horizontal_alignment_ratio.set(value);
460 host.remove_animation_for_property(Self::id_of_horizontal_alignment_ratio_property().base());
461 }
462
463 pub fn id_of_offset_property() -> &'static CompositionPropertyOf<Vector> {
465 static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
466 PROPERTY.get_or_init(|| {
467 CompositionProperty::register::<ServerCompositionViewBoxProps, Vector>(
468 "Offset",
469 "ServerCompositionViewBox",
470 |obj| props_of::<ServerCompositionViewBoxProps>(obj).offset.get(),
471 |obj, v| props_of::<ServerCompositionViewBoxProps>(obj).offset.set(v),
472 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionViewBoxProps>(obj).offset.get())),
473 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionViewBoxProps>(obj).offset.set(v.cast_or_default::<Vector>())),
474 )
475 })
476 }
477
478 pub fn offset(&self) -> Vector {
480 self.offset.get()
481 }
482
483 pub fn set_offset(&self, host: &dyn ServerCompositionViewBoxHooks, value: Vector) {
484 self.offset.set(value);
485 host.remove_animation_for_property(Self::id_of_offset_property().base());
486 }
487
488 pub fn id_of_size_property() -> &'static CompositionPropertyOf<Vector> {
490 static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
491 PROPERTY.get_or_init(|| {
492 CompositionProperty::register::<ServerCompositionViewBoxProps, Vector>(
493 "Size",
494 "ServerCompositionViewBox",
495 |obj| props_of::<ServerCompositionViewBoxProps>(obj).size.get(),
496 |obj, v| props_of::<ServerCompositionViewBoxProps>(obj).size.set(v),
497 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionViewBoxProps>(obj).size.get())),
498 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionViewBoxProps>(obj).size.set(v.cast_or_default::<Vector>())),
499 )
500 })
501 }
502
503 pub fn size(&self) -> Vector {
505 self.size.get()
506 }
507
508 pub fn set_size(&self, host: &dyn ServerCompositionViewBoxHooks, value: Vector) {
509 self.size.set(value);
510 host.remove_animation_for_property(Self::id_of_size_property().base());
511 }
512
513 pub fn id_of_stretch_property() -> &'static CompositionPropertyOf<CompositionStretch> {
515 static PROPERTY: OnceLock<CompositionPropertyOf<CompositionStretch>> = OnceLock::new();
516 PROPERTY.get_or_init(|| {
517 CompositionProperty::register::<ServerCompositionViewBoxProps, CompositionStretch>(
518 "Stretch",
519 "ServerCompositionViewBox",
520 |obj| props_of::<ServerCompositionViewBoxProps>(obj).stretch.get(),
521 |obj, v| props_of::<ServerCompositionViewBoxProps>(obj).stretch.set(v),
522 None,
523 None,
524 )
525 })
526 }
527
528 pub fn stretch(&self) -> CompositionStretch {
530 self.stretch.get()
531 }
532
533 pub fn set_stretch(&self, host: &dyn ServerCompositionViewBoxHooks, value: CompositionStretch) {
534 let old_value = self.stretch.get();
535 let mut changed = false;
536 if old_value.differs(&value) {
537 ServerCompositionViewBoxHooks::on_stretch_changing(host);
538 changed = true;
539 }
540 host.set_value(
541 Self::id_of_stretch_property().base(),
542 ServerValueChange {
543 equal: old_value.default_equals(&value),
544 old_resource: None,
545 new_resource: None,
546 assign: &mut || self.stretch.set(value),
547 },
548 );
549 if changed {
550 ServerCompositionViewBoxHooks::on_stretch_changed(host);
551 }
552 }
553
554 pub fn id_of_vertical_alignment_ratio_property() -> &'static CompositionPropertyOf<f32> {
556 static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
557 PROPERTY.get_or_init(|| {
558 CompositionProperty::register::<ServerCompositionViewBoxProps, f32>(
559 "VerticalAlignmentRatio",
560 "ServerCompositionViewBox",
561 |obj| props_of::<ServerCompositionViewBoxProps>(obj).vertical_alignment_ratio.get(),
562 |obj, v| props_of::<ServerCompositionViewBoxProps>(obj).vertical_alignment_ratio.set(v),
563 Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionViewBoxProps>(obj).vertical_alignment_ratio.get())),
564 Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionViewBoxProps>(obj).vertical_alignment_ratio.set(v.cast_or_default::<f32>())),
565 )
566 })
567 }
568
569 pub fn vertical_alignment_ratio(&self) -> f32 {
571 self.vertical_alignment_ratio.get()
572 }
573
574 pub fn set_vertical_alignment_ratio(&self, host: &dyn ServerCompositionViewBoxHooks, value: f32) {
575 self.vertical_alignment_ratio.set(value);
576 host.remove_animation_for_property(Self::id_of_vertical_alignment_ratio_property().base());
577 }
578
579 pub fn deserialize_changes_core(
582 &self,
583 host: &dyn ServerCompositionViewBoxHooks,
584 reader: &mut BatchStreamReader<'_>,
585 committed_at: Duration,
586 ) {
587 ServerCompositionViewBoxHooks::deserialize_changes_extra(host, reader);
588 let changed = reader.read::<CompositionViewBoxChangedFields>();
589 if changed.contains(CompositionViewBoxChangedFields::HORIZONTAL_ALIGNMENT_RATIO_ANIMATED) {
590 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
591 panic!("a batch starts an animation of `HorizontalAlignmentRatio` without an animation instance");
592 };
593 host.set_animated_value(
594 Self::id_of_horizontal_alignment_ratio_property().base(),
595 ExpressionVariant::create(self.horizontal_alignment_ratio.get()),
596 committed_at,
597 animation,
598 );
599 } else if changed.contains(CompositionViewBoxChangedFields::HORIZONTAL_ALIGNMENT_RATIO) {
600 let value = reader.read::<f32>();
601 self.set_horizontal_alignment_ratio(host, value);
602 }
603 if changed.contains(CompositionViewBoxChangedFields::OFFSET_ANIMATED) {
604 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
605 panic!("a batch starts an animation of `Offset` without an animation instance");
606 };
607 host.set_animated_value(
608 Self::id_of_offset_property().base(),
609 ExpressionVariant::create(self.offset.get()),
610 committed_at,
611 animation,
612 );
613 } else if changed.contains(CompositionViewBoxChangedFields::OFFSET) {
614 let value = reader.read::<Vector>();
615 self.set_offset(host, value);
616 }
617 if changed.contains(CompositionViewBoxChangedFields::SIZE_ANIMATED) {
618 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
619 panic!("a batch starts an animation of `Size` without an animation instance");
620 };
621 host.set_animated_value(
622 Self::id_of_size_property().base(),
623 ExpressionVariant::create(self.size.get()),
624 committed_at,
625 animation,
626 );
627 } else if changed.contains(CompositionViewBoxChangedFields::SIZE) {
628 let value = reader.read::<Vector>();
629 self.set_size(host, value);
630 }
631 if changed.contains(CompositionViewBoxChangedFields::STRETCH) {
632 let value = reader.read::<CompositionStretch>();
633 self.set_stretch(host, value);
634 }
635 if changed.contains(CompositionViewBoxChangedFields::VERTICAL_ALIGNMENT_RATIO_ANIMATED) {
636 let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
637 panic!("a batch starts an animation of `VerticalAlignmentRatio` without an animation instance");
638 };
639 host.set_animated_value(
640 Self::id_of_vertical_alignment_ratio_property().base(),
641 ExpressionVariant::create(self.vertical_alignment_ratio.get()),
642 committed_at,
643 animation,
644 );
645 } else if changed.contains(CompositionViewBoxChangedFields::VERTICAL_ALIGNMENT_RATIO) {
646 let value = reader.read::<f32>();
647 self.set_vertical_alignment_ratio(host, value);
648 }
649 ServerCompositionViewBoxHooks::on_fields_deserialized(host, changed);
650 }
651
652 pub fn get_composition_property(name: &str) -> Option<&'static CompositionProperty> {
655 if name == "HorizontalAlignmentRatio" {
656 return Some(Self::id_of_horizontal_alignment_ratio_property().base());
657 }
658 if name == "Offset" {
659 return Some(Self::id_of_offset_property().base());
660 }
661 if name == "Size" {
662 return Some(Self::id_of_size_property().base());
663 }
664 if name == "VerticalAlignmentRatio" {
665 return Some(Self::id_of_vertical_alignment_ratio_property().base());
666 }
667 None
668 }
669}