Skip to main content

ferroui_base/rendering/composition/generated/
composition_view_box.rs

1// @generated by scripts/generate_composition.py — do not edit
2
3//! `CompositionViewBox`.
4//!
5//! Defined by the FerroUI overlay (scripts/composition-schema-winui.xml).
6
7use 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    /// The fields of `CompositionViewBox` that changed since its last serialization.
32    #[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
58/// The partial methods of `CompositionViewBox`: implemented by the class that embeds
59/// [`CompositionViewBoxProps`]. Every hook defaults to doing nothing.
60pub 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
84/// The UI-thread properties of `CompositionViewBox`.
85pub 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    /// Creates the properties with every field at the default of its type.
102    /// The defaults of the schema are applied by
103    /// [`initialize_defaults`](Self::initialize_defaults).
104    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    /// The `InitializeDefaults` calls of the constructor chain: the base
116    /// classes first, then this class.
117    pub fn initialize_defaults(&self, host: &dyn CompositionViewBoxHooks) {
118        self.initialize_own_defaults(host);
119    }
120
121    /// `InitializeDefaults` of this class alone.
122    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    /// `HorizontalAlignmentRatio` (animated, default `0.5`, FerroUI overlay).
130    pub fn horizontal_alignment_ratio(&self) -> f32 {
131        self.horizontal_alignment_ratio.get()
132    }
133
134    /// Sets `HorizontalAlignmentRatio` (animated, default `0.5`, FerroUI overlay).
135    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            // Update the backing value
143            self.horizontal_alignment_ratio.set(value);
144            // Register object for serialization in the next batch
145            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            // Reset previous animation if any
148            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            // Check for implicit animations
151            if let Some(animation) = host.implicit_animation("HorizontalAlignmentRatio") {
152                // Animation affects only current property
153                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                // Animation is triggered by the current field, but does not necessary affects it
161                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    /// `Offset` (animated, FerroUI overlay).
171    pub fn offset(&self) -> Vector {
172        self.offset.get()
173    }
174
175    /// Sets `Offset` (animated, FerroUI overlay).
176    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            // Update the backing value
184            self.offset.set(value);
185            // Register object for serialization in the next batch
186            self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::OFFSET);
187            host.register_for_serialization();
188            // Reset previous animation if any
189            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            // Check for implicit animations
192            if let Some(animation) = host.implicit_animation("Offset") {
193                // Animation affects only current property
194                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                // Animation is triggered by the current field, but does not necessary affects it
202                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    /// `Size` (animated, FerroUI overlay).
212    pub fn size(&self) -> Vector {
213        self.size.get()
214    }
215
216    /// Sets `Size` (animated, FerroUI overlay).
217    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            // Update the backing value
225            self.size.set(value);
226            // Register object for serialization in the next batch
227            self.changed_fields_of_composition_view_box.set(self.changed_fields_of_composition_view_box.get() | CompositionViewBoxChangedFields::SIZE);
228            host.register_for_serialization();
229            // Reset previous animation if any
230            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            // Check for implicit animations
233            if let Some(animation) = host.implicit_animation("Size") {
234                // Animation affects only current property
235                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                // Animation is triggered by the current field, but does not necessary affects it
243                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    /// `Stretch` (default `CompositionStretch::Fill`, FerroUI overlay).
253    pub fn stretch(&self) -> CompositionStretch {
254        self.stretch.get()
255    }
256
257    /// Sets `Stretch` (default `CompositionStretch::Fill`, FerroUI overlay).
258    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            // Update the backing value
266            self.stretch.set(value);
267            // Register object for serialization in the next batch
268            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    /// `VerticalAlignmentRatio` (animated, default `0.5`, FerroUI overlay).
278    pub fn vertical_alignment_ratio(&self) -> f32 {
279        self.vertical_alignment_ratio.get()
280    }
281
282    /// Sets `VerticalAlignmentRatio` (animated, default `0.5`, FerroUI overlay).
283    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            // Update the backing value
291            self.vertical_alignment_ratio.set(value);
292            // Register object for serialization in the next batch
293            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            // Reset previous animation if any
296            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            // Check for implicit animations
299            if let Some(animation) = host.implicit_animation("VerticalAlignmentRatio") {
300                // Animation affects only current property
301                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                // Animation is triggered by the current field, but does not necessary affects it
309                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    /// Connects an animation with the named property. Returns `false` when
319    /// neither this class nor its generated bases have an animated property
320    /// of that name: the caller continues with its hand-written base.
321    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    /// Writes the changes of the object: the base class first, then the
360    /// changed-fields mask and the changed members of this class.
361    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
391/// The partial methods of `ServerCompositionViewBox`: implemented by the class that embeds
392/// [`ServerCompositionViewBoxProps`]. Every hook defaults to doing nothing.
393pub 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
401/// The server-side properties of `ServerCompositionViewBox`.
402pub 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    /// Creates the properties with every field at the default of its type; the
418    /// values of the UI thread arrive with the first batch.
419    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    /// This block or the block of a base class, by type: what
430    /// `IServerObject::get_props` of the embedding class returns.
431    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    /// The composition property of `HorizontalAlignmentRatio`.
439    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    /// `HorizontalAlignmentRatio` (animated).
454    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    /// The composition property of `Offset`.
464    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    /// `Offset` (animated).
479    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    /// The composition property of `Size`.
489    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    /// `Size` (animated).
504    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    /// The composition property of `Stretch`.
514    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    /// `Stretch`.
529    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    /// The composition property of `VerticalAlignmentRatio`.
555    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    /// `VerticalAlignmentRatio` (animated).
570    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    /// Reads the changes of the object: the base class first, then the
580    /// changed-fields mask and the changed members of this class.
581    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    /// The composition property with the given name, among the properties
653    /// of this class and of its generated bases that have a variant form.
654    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}