Skip to main content

ferroui_base/rendering/composition/generated/
composition_radial_gradient_brush.rs

1// @generated by scripts/generate_composition.py — do not edit
2
3//! `CompositionRadialGradientBrush`.
4//!
5//! Properties added by the FerroUI overlay (scripts/composition-schema-winui.xml): `AnchorPoint`, `CenterPoint`, `Offset`, `RotationAngle`, `Scale`, `TransformMatrix`.
6
7use bitflags::bitflags;
8use crate::Matrix;
9use crate::RelativePoint;
10use crate::RelativeScalar;
11use crate::Vector;
12use crate::rendering::composition::ICompositionObjectHost;
13use crate::rendering::composition::animations::AnimationInstanceFactory;
14use crate::rendering::composition::animations::ICompositionAnimation;
15use crate::rendering::composition::expressions::ExpressionVariant;
16use crate::rendering::composition::server::CompositionProperty;
17use crate::rendering::composition::server::CompositionPropertyOf;
18use crate::rendering::composition::server::IServerAnimatedPropertyHost;
19use crate::rendering::composition::server::ServerPropertyValue;
20use crate::rendering::composition::server::props_of;
21use crate::rendering::composition::transport::BatchStreamReader;
22use crate::rendering::composition::transport::BatchStreamWriter;
23use crate::rendering::composition::transport::BatchValue;
24use crate::rendering::composition::transport::BatchValueReader;
25use std::any::Any;
26use std::any::TypeId;
27use std::cell::Cell;
28use std::sync::OnceLock;
29use std::time::Duration;
30
31bitflags! {
32    /// The fields of `CompositionRadialGradientBrush` that changed since its last serialization.
33    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
34    pub struct CompositionRadialGradientBrushChangedFields: u32 {
35        const CENTER = 1;
36        const CENTER_ANIMATED = 2;
37        const GRADIENT_ORIGIN = 4;
38        const GRADIENT_ORIGIN_ANIMATED = 8;
39        const RADIUS_X = 16;
40        const RADIUS_X_ANIMATED = 32;
41        const RADIUS_Y = 64;
42        const RADIUS_Y_ANIMATED = 128;
43        const ANCHOR_POINT = 256;
44        const ANCHOR_POINT_ANIMATED = 512;
45        const CENTER_POINT = 1024;
46        const CENTER_POINT_ANIMATED = 2048;
47        const OFFSET = 4096;
48        const OFFSET_ANIMATED = 8192;
49        const ROTATION_ANGLE = 16384;
50        const ROTATION_ANGLE_ANIMATED = 32768;
51        const SCALE = 65536;
52        const SCALE_ANIMATED = 131072;
53        const TRANSFORM_MATRIX = 262144;
54        const TRANSFORM_MATRIX_ANIMATED = 524288;
55    }
56}
57
58impl BatchValue for CompositionRadialGradientBrushChangedFields {
59    #[inline]
60    fn write_to(&self, out: &mut Vec<u8>) {
61        self.bits().write_to(out);
62    }
63
64    #[inline]
65    fn read_from(input: &mut BatchValueReader<'_>) -> Self {
66        CompositionRadialGradientBrushChangedFields::from_bits_retain(u32::read_from(input))
67    }
68}
69
70/// The partial methods of `CompositionRadialGradientBrush`: implemented by the class that embeds
71/// [`CompositionRadialGradientBrushProps`]. Every hook defaults to doing nothing.
72pub trait CompositionRadialGradientBrushHooks: ICompositionObjectHost {
73    /// `base.SerializeChangesCore(writer)`: serializes the changes of the
74    /// hand-written base class `CompositionGradientBrush`.
75    fn base_serialize_changes_core(&self, writer: &mut BatchStreamWriter<'_>);
76
77    fn initialize_defaults_extra(&self) {}
78
79    fn validate_center_change(&self, _old_value: RelativePoint, _new_value: RelativePoint) {}
80    fn on_center_changed(&self) {}
81    fn on_center_changing(&self) {}
82
83    fn validate_gradient_origin_change(&self, _old_value: RelativePoint, _new_value: RelativePoint) {}
84    fn on_gradient_origin_changed(&self) {}
85    fn on_gradient_origin_changing(&self) {}
86
87    fn validate_radius_x_change(&self, _old_value: RelativeScalar, _new_value: RelativeScalar) {}
88    fn on_radius_x_changed(&self) {}
89    fn on_radius_x_changing(&self) {}
90
91    fn validate_radius_y_change(&self, _old_value: RelativeScalar, _new_value: RelativeScalar) {}
92    fn on_radius_y_changed(&self) {}
93    fn on_radius_y_changing(&self) {}
94
95    fn validate_anchor_point_change(&self, _old_value: Vector, _new_value: Vector) {}
96    fn on_anchor_point_changed(&self) {}
97    fn on_anchor_point_changing(&self) {}
98
99    fn validate_center_point_change(&self, _old_value: Vector, _new_value: Vector) {}
100    fn on_center_point_changed(&self) {}
101    fn on_center_point_changing(&self) {}
102
103    fn validate_offset_change(&self, _old_value: Vector, _new_value: Vector) {}
104    fn on_offset_changed(&self) {}
105    fn on_offset_changing(&self) {}
106
107    fn validate_rotation_angle_change(&self, _old_value: f32, _new_value: f32) {}
108    fn on_rotation_angle_changed(&self) {}
109    fn on_rotation_angle_changing(&self) {}
110
111    fn validate_scale_change(&self, _old_value: Vector, _new_value: Vector) {}
112    fn on_scale_changed(&self) {}
113    fn on_scale_changing(&self) {}
114
115    fn validate_transform_matrix_change(&self, _old_value: Matrix, _new_value: Matrix) {}
116    fn on_transform_matrix_changed(&self) {}
117    fn on_transform_matrix_changing(&self) {}
118}
119
120/// The UI-thread properties of `CompositionRadialGradientBrush`.
121pub struct CompositionRadialGradientBrushProps {
122    changed_fields_of_composition_radial_gradient_brush: Cell<CompositionRadialGradientBrushChangedFields>,
123    center: Cell<RelativePoint>,
124    gradient_origin: Cell<RelativePoint>,
125    radius_x: Cell<RelativeScalar>,
126    radius_y: Cell<RelativeScalar>,
127    anchor_point: Cell<Vector>,
128    center_point: Cell<Vector>,
129    offset: Cell<Vector>,
130    rotation_angle: Cell<f32>,
131    scale: Cell<Vector>,
132    transform_matrix: Cell<Matrix>,
133}
134
135impl Default for CompositionRadialGradientBrushProps {
136    fn default() -> Self {
137        Self::new()
138    }
139}
140
141impl CompositionRadialGradientBrushProps {
142    /// Creates the properties with every field at the default of its type.
143    /// The defaults of the schema are applied by
144    /// [`initialize_defaults`](Self::initialize_defaults).
145    pub fn new() -> Self {
146        Self {
147            changed_fields_of_composition_radial_gradient_brush: Cell::new(CompositionRadialGradientBrushChangedFields::empty()),
148            center: Cell::new(Default::default()),
149            gradient_origin: Cell::new(Default::default()),
150            radius_x: Cell::new(Default::default()),
151            radius_y: Cell::new(Default::default()),
152            anchor_point: Cell::new(Default::default()),
153            center_point: Cell::new(Default::default()),
154            offset: Cell::new(Default::default()),
155            rotation_angle: Cell::new(Default::default()),
156            scale: Cell::new(Default::default()),
157            transform_matrix: Cell::new(Default::default()),
158        }
159    }
160
161    /// The `InitializeDefaults` calls of the constructor chain: the base
162    /// classes first, then this class.
163    pub fn initialize_defaults(&self, host: &dyn CompositionRadialGradientBrushHooks) {
164        self.initialize_own_defaults(host);
165    }
166
167    /// `InitializeDefaults` of this class alone.
168    pub fn initialize_own_defaults(&self, host: &dyn CompositionRadialGradientBrushHooks) {
169        CompositionRadialGradientBrushHooks::initialize_defaults_extra(host);
170        self.set_radius_x(host, RelativeScalar::MIDDLE);
171        self.set_radius_y(host, RelativeScalar::MIDDLE);
172        self.set_scale(host, Vector::new(1.0, 1.0));
173        self.set_transform_matrix(host, Matrix::IDENTITY);
174    }
175
176    /// `Center` (animated).
177    pub fn center(&self) -> RelativePoint {
178        self.center.get()
179    }
180
181    /// Sets `Center` (animated).
182    pub fn set_center(&self, host: &dyn CompositionRadialGradientBrushHooks, value: RelativePoint) {
183        let mut changed = false;
184        let old_value = self.center.get();
185        if old_value.differs(&value) {
186            CompositionRadialGradientBrushHooks::validate_center_change(host, old_value, value);
187            CompositionRadialGradientBrushHooks::on_center_changing(host);
188            changed = true;
189            // Update the backing value
190            self.center.set(value);
191            // Register object for serialization in the next batch
192            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::CENTER);
193            host.register_for_serialization();
194            // Reset previous animation if any
195            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_center_property().base());
196            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::CENTER_ANIMATED);
197            // Check for implicit animations
198            if let Some(animation) = host.implicit_animation("Center") {
199                // Animation affects only current property
200                if let Some(a) = animation.as_composition_animation() {
201                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::CENTER_ANIMATED);
202                    host.pending_animations().set(
203                        ServerCompositionRadialGradientBrushProps::id_of_center_property().base(),
204                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
205                    );
206                }
207                // Animation is triggered by the current field, but does not necessary affects it
208                host.start_animation_group(&animation, "Center", ExpressionVariant::create(value));
209            }
210        }
211        self.center.set(value);
212        if changed {
213            CompositionRadialGradientBrushHooks::on_center_changed(host);
214        }
215    }
216
217    /// `GradientOrigin` (animated).
218    pub fn gradient_origin(&self) -> RelativePoint {
219        self.gradient_origin.get()
220    }
221
222    /// Sets `GradientOrigin` (animated).
223    pub fn set_gradient_origin(&self, host: &dyn CompositionRadialGradientBrushHooks, value: RelativePoint) {
224        let mut changed = false;
225        let old_value = self.gradient_origin.get();
226        if old_value.differs(&value) {
227            CompositionRadialGradientBrushHooks::validate_gradient_origin_change(host, old_value, value);
228            CompositionRadialGradientBrushHooks::on_gradient_origin_changing(host);
229            changed = true;
230            // Update the backing value
231            self.gradient_origin.set(value);
232            // Register object for serialization in the next batch
233            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::GRADIENT_ORIGIN);
234            host.register_for_serialization();
235            // Reset previous animation if any
236            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_gradient_origin_property().base());
237            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::GRADIENT_ORIGIN_ANIMATED);
238            // Check for implicit animations
239            if let Some(animation) = host.implicit_animation("GradientOrigin") {
240                // Animation affects only current property
241                if let Some(a) = animation.as_composition_animation() {
242                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::GRADIENT_ORIGIN_ANIMATED);
243                    host.pending_animations().set(
244                        ServerCompositionRadialGradientBrushProps::id_of_gradient_origin_property().base(),
245                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
246                    );
247                }
248                // Animation is triggered by the current field, but does not necessary affects it
249                host.start_animation_group(&animation, "GradientOrigin", ExpressionVariant::create(value));
250            }
251        }
252        self.gradient_origin.set(value);
253        if changed {
254            CompositionRadialGradientBrushHooks::on_gradient_origin_changed(host);
255        }
256    }
257
258    /// `RadiusX` (animated, default `RelativeScalar::MIDDLE`).
259    pub fn radius_x(&self) -> RelativeScalar {
260        self.radius_x.get()
261    }
262
263    /// Sets `RadiusX` (animated, default `RelativeScalar::MIDDLE`).
264    pub fn set_radius_x(&self, host: &dyn CompositionRadialGradientBrushHooks, value: RelativeScalar) {
265        let mut changed = false;
266        let old_value = self.radius_x.get();
267        if old_value.differs(&value) {
268            CompositionRadialGradientBrushHooks::validate_radius_x_change(host, old_value, value);
269            CompositionRadialGradientBrushHooks::on_radius_x_changing(host);
270            changed = true;
271            // Update the backing value
272            self.radius_x.set(value);
273            // Register object for serialization in the next batch
274            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::RADIUS_X);
275            host.register_for_serialization();
276            // Reset previous animation if any
277            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_radius_x_property().base());
278            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::RADIUS_X_ANIMATED);
279            // Check for implicit animations
280            if let Some(animation) = host.implicit_animation("RadiusX") {
281                // Animation affects only current property
282                if let Some(a) = animation.as_composition_animation() {
283                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::RADIUS_X_ANIMATED);
284                    host.pending_animations().set(
285                        ServerCompositionRadialGradientBrushProps::id_of_radius_x_property().base(),
286                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
287                    );
288                }
289                // Animation is triggered by the current field, but does not necessary affects it
290                host.start_animation_group(&animation, "RadiusX", ExpressionVariant::create(value));
291            }
292        }
293        self.radius_x.set(value);
294        if changed {
295            CompositionRadialGradientBrushHooks::on_radius_x_changed(host);
296        }
297    }
298
299    /// `RadiusY` (animated, default `RelativeScalar::MIDDLE`).
300    pub fn radius_y(&self) -> RelativeScalar {
301        self.radius_y.get()
302    }
303
304    /// Sets `RadiusY` (animated, default `RelativeScalar::MIDDLE`).
305    pub fn set_radius_y(&self, host: &dyn CompositionRadialGradientBrushHooks, value: RelativeScalar) {
306        let mut changed = false;
307        let old_value = self.radius_y.get();
308        if old_value.differs(&value) {
309            CompositionRadialGradientBrushHooks::validate_radius_y_change(host, old_value, value);
310            CompositionRadialGradientBrushHooks::on_radius_y_changing(host);
311            changed = true;
312            // Update the backing value
313            self.radius_y.set(value);
314            // Register object for serialization in the next batch
315            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::RADIUS_Y);
316            host.register_for_serialization();
317            // Reset previous animation if any
318            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_radius_y_property().base());
319            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::RADIUS_Y_ANIMATED);
320            // Check for implicit animations
321            if let Some(animation) = host.implicit_animation("RadiusY") {
322                // Animation affects only current property
323                if let Some(a) = animation.as_composition_animation() {
324                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::RADIUS_Y_ANIMATED);
325                    host.pending_animations().set(
326                        ServerCompositionRadialGradientBrushProps::id_of_radius_y_property().base(),
327                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
328                    );
329                }
330                // Animation is triggered by the current field, but does not necessary affects it
331                host.start_animation_group(&animation, "RadiusY", ExpressionVariant::create(value));
332            }
333        }
334        self.radius_y.set(value);
335        if changed {
336            CompositionRadialGradientBrushHooks::on_radius_y_changed(host);
337        }
338    }
339
340    /// `AnchorPoint` (animated, FerroUI overlay).
341    pub fn anchor_point(&self) -> Vector {
342        self.anchor_point.get()
343    }
344
345    /// Sets `AnchorPoint` (animated, FerroUI overlay).
346    pub fn set_anchor_point(&self, host: &dyn CompositionRadialGradientBrushHooks, value: Vector) {
347        let mut changed = false;
348        let old_value = self.anchor_point.get();
349        if old_value.differs(&value) {
350            CompositionRadialGradientBrushHooks::validate_anchor_point_change(host, old_value, value);
351            CompositionRadialGradientBrushHooks::on_anchor_point_changing(host);
352            changed = true;
353            // Update the backing value
354            self.anchor_point.set(value);
355            // Register object for serialization in the next batch
356            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::ANCHOR_POINT);
357            host.register_for_serialization();
358            // Reset previous animation if any
359            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_anchor_point_property().base());
360            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::ANCHOR_POINT_ANIMATED);
361            // Check for implicit animations
362            if let Some(animation) = host.implicit_animation("AnchorPoint") {
363                // Animation affects only current property
364                if let Some(a) = animation.as_composition_animation() {
365                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::ANCHOR_POINT_ANIMATED);
366                    host.pending_animations().set(
367                        ServerCompositionRadialGradientBrushProps::id_of_anchor_point_property().base(),
368                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
369                    );
370                }
371                // Animation is triggered by the current field, but does not necessary affects it
372                host.start_animation_group(&animation, "AnchorPoint", ExpressionVariant::create(value));
373            }
374        }
375        self.anchor_point.set(value);
376        if changed {
377            CompositionRadialGradientBrushHooks::on_anchor_point_changed(host);
378        }
379    }
380
381    /// `CenterPoint` (animated, FerroUI overlay).
382    pub fn center_point(&self) -> Vector {
383        self.center_point.get()
384    }
385
386    /// Sets `CenterPoint` (animated, FerroUI overlay).
387    pub fn set_center_point(&self, host: &dyn CompositionRadialGradientBrushHooks, value: Vector) {
388        let mut changed = false;
389        let old_value = self.center_point.get();
390        if old_value.differs(&value) {
391            CompositionRadialGradientBrushHooks::validate_center_point_change(host, old_value, value);
392            CompositionRadialGradientBrushHooks::on_center_point_changing(host);
393            changed = true;
394            // Update the backing value
395            self.center_point.set(value);
396            // Register object for serialization in the next batch
397            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::CENTER_POINT);
398            host.register_for_serialization();
399            // Reset previous animation if any
400            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_center_point_property().base());
401            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::CENTER_POINT_ANIMATED);
402            // Check for implicit animations
403            if let Some(animation) = host.implicit_animation("CenterPoint") {
404                // Animation affects only current property
405                if let Some(a) = animation.as_composition_animation() {
406                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::CENTER_POINT_ANIMATED);
407                    host.pending_animations().set(
408                        ServerCompositionRadialGradientBrushProps::id_of_center_point_property().base(),
409                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
410                    );
411                }
412                // Animation is triggered by the current field, but does not necessary affects it
413                host.start_animation_group(&animation, "CenterPoint", ExpressionVariant::create(value));
414            }
415        }
416        self.center_point.set(value);
417        if changed {
418            CompositionRadialGradientBrushHooks::on_center_point_changed(host);
419        }
420    }
421
422    /// `Offset` (animated, FerroUI overlay).
423    pub fn offset(&self) -> Vector {
424        self.offset.get()
425    }
426
427    /// Sets `Offset` (animated, FerroUI overlay).
428    pub fn set_offset(&self, host: &dyn CompositionRadialGradientBrushHooks, value: Vector) {
429        let mut changed = false;
430        let old_value = self.offset.get();
431        if old_value.differs(&value) {
432            CompositionRadialGradientBrushHooks::validate_offset_change(host, old_value, value);
433            CompositionRadialGradientBrushHooks::on_offset_changing(host);
434            changed = true;
435            // Update the backing value
436            self.offset.set(value);
437            // Register object for serialization in the next batch
438            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::OFFSET);
439            host.register_for_serialization();
440            // Reset previous animation if any
441            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_offset_property().base());
442            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::OFFSET_ANIMATED);
443            // Check for implicit animations
444            if let Some(animation) = host.implicit_animation("Offset") {
445                // Animation affects only current property
446                if let Some(a) = animation.as_composition_animation() {
447                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::OFFSET_ANIMATED);
448                    host.pending_animations().set(
449                        ServerCompositionRadialGradientBrushProps::id_of_offset_property().base(),
450                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
451                    );
452                }
453                // Animation is triggered by the current field, but does not necessary affects it
454                host.start_animation_group(&animation, "Offset", ExpressionVariant::create(value));
455            }
456        }
457        self.offset.set(value);
458        if changed {
459            CompositionRadialGradientBrushHooks::on_offset_changed(host);
460        }
461    }
462
463    /// `RotationAngle` (animated, FerroUI overlay).
464    pub fn rotation_angle(&self) -> f32 {
465        self.rotation_angle.get()
466    }
467
468    /// Sets `RotationAngle` (animated, FerroUI overlay).
469    pub fn set_rotation_angle(&self, host: &dyn CompositionRadialGradientBrushHooks, value: f32) {
470        let mut changed = false;
471        let old_value = self.rotation_angle.get();
472        if old_value.differs(&value) {
473            CompositionRadialGradientBrushHooks::validate_rotation_angle_change(host, old_value, value);
474            CompositionRadialGradientBrushHooks::on_rotation_angle_changing(host);
475            changed = true;
476            // Update the backing value
477            self.rotation_angle.set(value);
478            // Register object for serialization in the next batch
479            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::ROTATION_ANGLE);
480            host.register_for_serialization();
481            // Reset previous animation if any
482            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_rotation_angle_property().base());
483            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED);
484            // Check for implicit animations
485            if let Some(animation) = host.implicit_animation("RotationAngle") {
486                // Animation affects only current property
487                if let Some(a) = animation.as_composition_animation() {
488                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED);
489                    host.pending_animations().set(
490                        ServerCompositionRadialGradientBrushProps::id_of_rotation_angle_property().base(),
491                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
492                    );
493                }
494                // Animation is triggered by the current field, but does not necessary affects it
495                host.start_animation_group(&animation, "RotationAngle", ExpressionVariant::create(value));
496            }
497        }
498        self.rotation_angle.set(value);
499        if changed {
500            CompositionRadialGradientBrushHooks::on_rotation_angle_changed(host);
501        }
502    }
503
504    /// `Scale` (animated, default `Vector::new(1.0, 1.0)`, FerroUI overlay).
505    pub fn scale(&self) -> Vector {
506        self.scale.get()
507    }
508
509    /// Sets `Scale` (animated, default `Vector::new(1.0, 1.0)`, FerroUI overlay).
510    pub fn set_scale(&self, host: &dyn CompositionRadialGradientBrushHooks, value: Vector) {
511        let mut changed = false;
512        let old_value = self.scale.get();
513        if old_value.differs(&value) {
514            CompositionRadialGradientBrushHooks::validate_scale_change(host, old_value, value);
515            CompositionRadialGradientBrushHooks::on_scale_changing(host);
516            changed = true;
517            // Update the backing value
518            self.scale.set(value);
519            // Register object for serialization in the next batch
520            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::SCALE);
521            host.register_for_serialization();
522            // Reset previous animation if any
523            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_scale_property().base());
524            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::SCALE_ANIMATED);
525            // Check for implicit animations
526            if let Some(animation) = host.implicit_animation("Scale") {
527                // Animation affects only current property
528                if let Some(a) = animation.as_composition_animation() {
529                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::SCALE_ANIMATED);
530                    host.pending_animations().set(
531                        ServerCompositionRadialGradientBrushProps::id_of_scale_property().base(),
532                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
533                    );
534                }
535                // Animation is triggered by the current field, but does not necessary affects it
536                host.start_animation_group(&animation, "Scale", ExpressionVariant::create(value));
537            }
538        }
539        self.scale.set(value);
540        if changed {
541            CompositionRadialGradientBrushHooks::on_scale_changed(host);
542        }
543    }
544
545    /// `TransformMatrix` (animated, default `Matrix::IDENTITY`, FerroUI overlay).
546    pub fn transform_matrix(&self) -> Matrix {
547        self.transform_matrix.get()
548    }
549
550    /// Sets `TransformMatrix` (animated, default `Matrix::IDENTITY`, FerroUI overlay).
551    pub fn set_transform_matrix(&self, host: &dyn CompositionRadialGradientBrushHooks, value: Matrix) {
552        let mut changed = false;
553        let old_value = self.transform_matrix.get();
554        if old_value.differs(&value) {
555            CompositionRadialGradientBrushHooks::validate_transform_matrix_change(host, old_value, value);
556            CompositionRadialGradientBrushHooks::on_transform_matrix_changing(host);
557            changed = true;
558            // Update the backing value
559            self.transform_matrix.set(value);
560            // Register object for serialization in the next batch
561            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::TRANSFORM_MATRIX);
562            host.register_for_serialization();
563            // Reset previous animation if any
564            host.pending_animations().remove(ServerCompositionRadialGradientBrushProps::id_of_transform_matrix_property().base());
565            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() & !CompositionRadialGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED);
566            // Check for implicit animations
567            if let Some(animation) = host.implicit_animation("TransformMatrix") {
568                // Animation affects only current property
569                if let Some(a) = animation.as_composition_animation() {
570                    self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED);
571                    host.pending_animations().set(
572                        ServerCompositionRadialGradientBrushProps::id_of_transform_matrix_property().base(),
573                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
574                    );
575                }
576                // Animation is triggered by the current field, but does not necessary affects it
577                host.start_animation_group(&animation, "TransformMatrix", ExpressionVariant::create(value));
578            }
579        }
580        self.transform_matrix.set(value);
581        if changed {
582            CompositionRadialGradientBrushHooks::on_transform_matrix_changed(host);
583        }
584    }
585
586    /// Connects an animation with the named property. Returns `false` when
587    /// neither this class nor its generated bases have an animated property
588    /// of that name: the caller continues with its hand-written base.
589    pub fn start_animation(
590        &self,
591        host: &dyn CompositionRadialGradientBrushHooks,
592        property_name: &str,
593        animation: &dyn ICompositionAnimation,
594        final_value: Option<ExpressionVariant>,
595    ) -> bool {
596        if property_name == "Center" {
597            let server = animation.create_instance(host.server(), final_value);
598            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_center_property().base(), server);
599            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::CENTER_ANIMATED);
600            host.register_for_serialization();
601            return true;
602        }
603        if property_name == "GradientOrigin" {
604            let server = animation.create_instance(host.server(), final_value);
605            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_gradient_origin_property().base(), server);
606            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::GRADIENT_ORIGIN_ANIMATED);
607            host.register_for_serialization();
608            return true;
609        }
610        if property_name == "RadiusX" {
611            let server = animation.create_instance(host.server(), final_value);
612            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_radius_x_property().base(), server);
613            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::RADIUS_X_ANIMATED);
614            host.register_for_serialization();
615            return true;
616        }
617        if property_name == "RadiusY" {
618            let server = animation.create_instance(host.server(), final_value);
619            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_radius_y_property().base(), server);
620            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::RADIUS_Y_ANIMATED);
621            host.register_for_serialization();
622            return true;
623        }
624        if property_name == "AnchorPoint" {
625            let server = animation.create_instance(host.server(), final_value);
626            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_anchor_point_property().base(), server);
627            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::ANCHOR_POINT_ANIMATED);
628            host.register_for_serialization();
629            return true;
630        }
631        if property_name == "CenterPoint" {
632            let server = animation.create_instance(host.server(), final_value);
633            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_center_point_property().base(), server);
634            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::CENTER_POINT_ANIMATED);
635            host.register_for_serialization();
636            return true;
637        }
638        if property_name == "Offset" {
639            let server = animation.create_instance(host.server(), final_value);
640            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_offset_property().base(), server);
641            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::OFFSET_ANIMATED);
642            host.register_for_serialization();
643            return true;
644        }
645        if property_name == "RotationAngle" {
646            let server = animation.create_instance(host.server(), final_value);
647            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_rotation_angle_property().base(), server);
648            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED);
649            host.register_for_serialization();
650            return true;
651        }
652        if property_name == "Scale" {
653            let server = animation.create_instance(host.server(), final_value);
654            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_scale_property().base(), server);
655            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::SCALE_ANIMATED);
656            host.register_for_serialization();
657            return true;
658        }
659        if property_name == "TransformMatrix" {
660            let server = animation.create_instance(host.server(), final_value);
661            host.pending_animations().set(ServerCompositionRadialGradientBrushProps::id_of_transform_matrix_property().base(), server);
662            self.changed_fields_of_composition_radial_gradient_brush.set(self.changed_fields_of_composition_radial_gradient_brush.get() | CompositionRadialGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED);
663            host.register_for_serialization();
664            return true;
665        }
666        false
667    }
668
669    /// Writes the changes of the object: the base class first, then the
670    /// changed-fields mask and the changed members of this class.
671    pub fn serialize_changes_core(&self, host: &dyn CompositionRadialGradientBrushHooks, writer: &mut BatchStreamWriter<'_>) {
672        CompositionRadialGradientBrushHooks::base_serialize_changes_core(host, writer);
673        let changed = self.changed_fields_of_composition_radial_gradient_brush.get();
674        writer.write(changed);
675        if changed.contains(CompositionRadialGradientBrushChangedFields::CENTER_ANIMATED) {
676            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_center_property().base()));
677        } else if changed.contains(CompositionRadialGradientBrushChangedFields::CENTER) {
678            writer.write(self.center.get());
679        }
680        if changed.contains(CompositionRadialGradientBrushChangedFields::GRADIENT_ORIGIN_ANIMATED) {
681            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_gradient_origin_property().base()));
682        } else if changed.contains(CompositionRadialGradientBrushChangedFields::GRADIENT_ORIGIN) {
683            writer.write(self.gradient_origin.get());
684        }
685        if changed.contains(CompositionRadialGradientBrushChangedFields::RADIUS_X_ANIMATED) {
686            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_radius_x_property().base()));
687        } else if changed.contains(CompositionRadialGradientBrushChangedFields::RADIUS_X) {
688            writer.write(self.radius_x.get());
689        }
690        if changed.contains(CompositionRadialGradientBrushChangedFields::RADIUS_Y_ANIMATED) {
691            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_radius_y_property().base()));
692        } else if changed.contains(CompositionRadialGradientBrushChangedFields::RADIUS_Y) {
693            writer.write(self.radius_y.get());
694        }
695        if changed.contains(CompositionRadialGradientBrushChangedFields::ANCHOR_POINT_ANIMATED) {
696            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_anchor_point_property().base()));
697        } else if changed.contains(CompositionRadialGradientBrushChangedFields::ANCHOR_POINT) {
698            writer.write(self.anchor_point.get());
699        }
700        if changed.contains(CompositionRadialGradientBrushChangedFields::CENTER_POINT_ANIMATED) {
701            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_center_point_property().base()));
702        } else if changed.contains(CompositionRadialGradientBrushChangedFields::CENTER_POINT) {
703            writer.write(self.center_point.get());
704        }
705        if changed.contains(CompositionRadialGradientBrushChangedFields::OFFSET_ANIMATED) {
706            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_offset_property().base()));
707        } else if changed.contains(CompositionRadialGradientBrushChangedFields::OFFSET) {
708            writer.write(self.offset.get());
709        }
710        if changed.contains(CompositionRadialGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED) {
711            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_rotation_angle_property().base()));
712        } else if changed.contains(CompositionRadialGradientBrushChangedFields::ROTATION_ANGLE) {
713            writer.write(self.rotation_angle.get());
714        }
715        if changed.contains(CompositionRadialGradientBrushChangedFields::SCALE_ANIMATED) {
716            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_scale_property().base()));
717        } else if changed.contains(CompositionRadialGradientBrushChangedFields::SCALE) {
718            writer.write(self.scale.get());
719        }
720        if changed.contains(CompositionRadialGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED) {
721            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionRadialGradientBrushProps::id_of_transform_matrix_property().base()));
722        } else if changed.contains(CompositionRadialGradientBrushChangedFields::TRANSFORM_MATRIX) {
723            writer.write(self.transform_matrix.get());
724        }
725        self.changed_fields_of_composition_radial_gradient_brush.set(CompositionRadialGradientBrushChangedFields::empty());
726    }
727}
728
729/// The partial methods of `ServerCompositionRadialGradientBrush`: implemented by the class that embeds
730/// [`ServerCompositionRadialGradientBrushProps`]. Every hook defaults to doing nothing.
731pub trait ServerCompositionRadialGradientBrushHooks: IServerAnimatedPropertyHost {
732    /// `base.DeserializeChangesCore(reader, committedAt)`: reads the changes of
733    /// the hand-written base class `ServerCompositionGradientBrush`.
734    fn base_deserialize_changes_core(&self, reader: &mut BatchStreamReader<'_>, committed_at: Duration);
735
736    fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
737    fn on_fields_deserialized(&self, _changed: CompositionRadialGradientBrushChangedFields) {}
738}
739
740/// The server-side properties of `ServerCompositionRadialGradientBrush`.
741pub struct ServerCompositionRadialGradientBrushProps {
742    center: Cell<RelativePoint>,
743    gradient_origin: Cell<RelativePoint>,
744    radius_x: Cell<RelativeScalar>,
745    radius_y: Cell<RelativeScalar>,
746    anchor_point: Cell<Vector>,
747    center_point: Cell<Vector>,
748    offset: Cell<Vector>,
749    rotation_angle: Cell<f32>,
750    scale: Cell<Vector>,
751    transform_matrix: Cell<Matrix>,
752}
753
754impl Default for ServerCompositionRadialGradientBrushProps {
755    fn default() -> Self {
756        Self::new()
757    }
758}
759
760impl ServerCompositionRadialGradientBrushProps {
761    /// Creates the properties with every field at the default of its type; the
762    /// values of the UI thread arrive with the first batch.
763    pub fn new() -> Self {
764        Self {
765            center: Cell::new(Default::default()),
766            gradient_origin: Cell::new(Default::default()),
767            radius_x: Cell::new(Default::default()),
768            radius_y: Cell::new(Default::default()),
769            anchor_point: Cell::new(Default::default()),
770            center_point: Cell::new(Default::default()),
771            offset: Cell::new(Default::default()),
772            rotation_angle: Cell::new(Default::default()),
773            scale: Cell::new(Default::default()),
774            transform_matrix: Cell::new(Default::default()),
775        }
776    }
777
778    /// This block or the block of a base class, by type: what
779    /// `IServerObject::get_props` of the embedding class returns.
780    pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
781        if type_id == TypeId::of::<Self>() {
782            return Some(self);
783        }
784        None
785    }
786
787    /// The composition property of `Center`.
788    pub fn id_of_center_property() -> &'static CompositionPropertyOf<RelativePoint> {
789        static PROPERTY: OnceLock<CompositionPropertyOf<RelativePoint>> = OnceLock::new();
790        PROPERTY.get_or_init(|| {
791            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, RelativePoint>(
792                "Center",
793                "ServerCompositionRadialGradientBrush",
794                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).center.get(),
795                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).center.set(v),
796                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).center.get())),
797                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).center.set(v.cast_or_default::<RelativePoint>())),
798            )
799        })
800    }
801
802    /// `Center` (animated).
803    pub fn center(&self) -> RelativePoint {
804        self.center.get()
805    }
806
807    pub fn set_center(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: RelativePoint) {
808        self.center.set(value);
809        host.remove_animation_for_property(Self::id_of_center_property().base());
810    }
811
812    /// The composition property of `GradientOrigin`.
813    pub fn id_of_gradient_origin_property() -> &'static CompositionPropertyOf<RelativePoint> {
814        static PROPERTY: OnceLock<CompositionPropertyOf<RelativePoint>> = OnceLock::new();
815        PROPERTY.get_or_init(|| {
816            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, RelativePoint>(
817                "GradientOrigin",
818                "ServerCompositionRadialGradientBrush",
819                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).gradient_origin.get(),
820                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).gradient_origin.set(v),
821                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).gradient_origin.get())),
822                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).gradient_origin.set(v.cast_or_default::<RelativePoint>())),
823            )
824        })
825    }
826
827    /// `GradientOrigin` (animated).
828    pub fn gradient_origin(&self) -> RelativePoint {
829        self.gradient_origin.get()
830    }
831
832    pub fn set_gradient_origin(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: RelativePoint) {
833        self.gradient_origin.set(value);
834        host.remove_animation_for_property(Self::id_of_gradient_origin_property().base());
835    }
836
837    /// The composition property of `RadiusX`.
838    pub fn id_of_radius_x_property() -> &'static CompositionPropertyOf<RelativeScalar> {
839        static PROPERTY: OnceLock<CompositionPropertyOf<RelativeScalar>> = OnceLock::new();
840        PROPERTY.get_or_init(|| {
841            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, RelativeScalar>(
842                "RadiusX",
843                "ServerCompositionRadialGradientBrush",
844                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).radius_x.get(),
845                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).radius_x.set(v),
846                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).radius_x.get())),
847                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).radius_x.set(v.cast_or_default::<RelativeScalar>())),
848            )
849        })
850    }
851
852    /// `RadiusX` (animated).
853    pub fn radius_x(&self) -> RelativeScalar {
854        self.radius_x.get()
855    }
856
857    pub fn set_radius_x(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: RelativeScalar) {
858        self.radius_x.set(value);
859        host.remove_animation_for_property(Self::id_of_radius_x_property().base());
860    }
861
862    /// The composition property of `RadiusY`.
863    pub fn id_of_radius_y_property() -> &'static CompositionPropertyOf<RelativeScalar> {
864        static PROPERTY: OnceLock<CompositionPropertyOf<RelativeScalar>> = OnceLock::new();
865        PROPERTY.get_or_init(|| {
866            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, RelativeScalar>(
867                "RadiusY",
868                "ServerCompositionRadialGradientBrush",
869                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).radius_y.get(),
870                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).radius_y.set(v),
871                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).radius_y.get())),
872                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).radius_y.set(v.cast_or_default::<RelativeScalar>())),
873            )
874        })
875    }
876
877    /// `RadiusY` (animated).
878    pub fn radius_y(&self) -> RelativeScalar {
879        self.radius_y.get()
880    }
881
882    pub fn set_radius_y(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: RelativeScalar) {
883        self.radius_y.set(value);
884        host.remove_animation_for_property(Self::id_of_radius_y_property().base());
885    }
886
887    /// The composition property of `AnchorPoint`.
888    pub fn id_of_anchor_point_property() -> &'static CompositionPropertyOf<Vector> {
889        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
890        PROPERTY.get_or_init(|| {
891            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, Vector>(
892                "AnchorPoint",
893                "ServerCompositionRadialGradientBrush",
894                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).anchor_point.get(),
895                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).anchor_point.set(v),
896                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).anchor_point.get())),
897                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).anchor_point.set(v.cast_or_default::<Vector>())),
898            )
899        })
900    }
901
902    /// `AnchorPoint` (animated).
903    pub fn anchor_point(&self) -> Vector {
904        self.anchor_point.get()
905    }
906
907    pub fn set_anchor_point(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: Vector) {
908        self.anchor_point.set(value);
909        host.remove_animation_for_property(Self::id_of_anchor_point_property().base());
910    }
911
912    /// The composition property of `CenterPoint`.
913    pub fn id_of_center_point_property() -> &'static CompositionPropertyOf<Vector> {
914        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
915        PROPERTY.get_or_init(|| {
916            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, Vector>(
917                "CenterPoint",
918                "ServerCompositionRadialGradientBrush",
919                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).center_point.get(),
920                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).center_point.set(v),
921                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).center_point.get())),
922                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).center_point.set(v.cast_or_default::<Vector>())),
923            )
924        })
925    }
926
927    /// `CenterPoint` (animated).
928    pub fn center_point(&self) -> Vector {
929        self.center_point.get()
930    }
931
932    pub fn set_center_point(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: Vector) {
933        self.center_point.set(value);
934        host.remove_animation_for_property(Self::id_of_center_point_property().base());
935    }
936
937    /// The composition property of `Offset`.
938    pub fn id_of_offset_property() -> &'static CompositionPropertyOf<Vector> {
939        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
940        PROPERTY.get_or_init(|| {
941            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, Vector>(
942                "Offset",
943                "ServerCompositionRadialGradientBrush",
944                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).offset.get(),
945                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).offset.set(v),
946                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).offset.get())),
947                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).offset.set(v.cast_or_default::<Vector>())),
948            )
949        })
950    }
951
952    /// `Offset` (animated).
953    pub fn offset(&self) -> Vector {
954        self.offset.get()
955    }
956
957    pub fn set_offset(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: Vector) {
958        self.offset.set(value);
959        host.remove_animation_for_property(Self::id_of_offset_property().base());
960    }
961
962    /// The composition property of `RotationAngle`.
963    pub fn id_of_rotation_angle_property() -> &'static CompositionPropertyOf<f32> {
964        static PROPERTY: OnceLock<CompositionPropertyOf<f32>> = OnceLock::new();
965        PROPERTY.get_or_init(|| {
966            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, f32>(
967                "RotationAngle",
968                "ServerCompositionRadialGradientBrush",
969                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).rotation_angle.get(),
970                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).rotation_angle.set(v),
971                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).rotation_angle.get())),
972                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).rotation_angle.set(v.cast_or_default::<f32>())),
973            )
974        })
975    }
976
977    /// `RotationAngle` (animated).
978    pub fn rotation_angle(&self) -> f32 {
979        self.rotation_angle.get()
980    }
981
982    pub fn set_rotation_angle(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: f32) {
983        self.rotation_angle.set(value);
984        host.remove_animation_for_property(Self::id_of_rotation_angle_property().base());
985    }
986
987    /// The composition property of `Scale`.
988    pub fn id_of_scale_property() -> &'static CompositionPropertyOf<Vector> {
989        static PROPERTY: OnceLock<CompositionPropertyOf<Vector>> = OnceLock::new();
990        PROPERTY.get_or_init(|| {
991            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, Vector>(
992                "Scale",
993                "ServerCompositionRadialGradientBrush",
994                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).scale.get(),
995                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).scale.set(v),
996                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).scale.get())),
997                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).scale.set(v.cast_or_default::<Vector>())),
998            )
999        })
1000    }
1001
1002    /// `Scale` (animated).
1003    pub fn scale(&self) -> Vector {
1004        self.scale.get()
1005    }
1006
1007    pub fn set_scale(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: Vector) {
1008        self.scale.set(value);
1009        host.remove_animation_for_property(Self::id_of_scale_property().base());
1010    }
1011
1012    /// The composition property of `TransformMatrix`.
1013    pub fn id_of_transform_matrix_property() -> &'static CompositionPropertyOf<Matrix> {
1014        static PROPERTY: OnceLock<CompositionPropertyOf<Matrix>> = OnceLock::new();
1015        PROPERTY.get_or_init(|| {
1016            CompositionProperty::register::<ServerCompositionRadialGradientBrushProps, Matrix>(
1017                "TransformMatrix",
1018                "ServerCompositionRadialGradientBrush",
1019                |obj| props_of::<ServerCompositionRadialGradientBrushProps>(obj).transform_matrix.get(),
1020                |obj, v| props_of::<ServerCompositionRadialGradientBrushProps>(obj).transform_matrix.set(v),
1021                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionRadialGradientBrushProps>(obj).transform_matrix.get())),
1022                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionRadialGradientBrushProps>(obj).transform_matrix.set(v.cast_or_default::<Matrix>())),
1023            )
1024        })
1025    }
1026
1027    /// `TransformMatrix` (animated).
1028    pub fn transform_matrix(&self) -> Matrix {
1029        self.transform_matrix.get()
1030    }
1031
1032    pub fn set_transform_matrix(&self, host: &dyn ServerCompositionRadialGradientBrushHooks, value: Matrix) {
1033        self.transform_matrix.set(value);
1034        host.remove_animation_for_property(Self::id_of_transform_matrix_property().base());
1035    }
1036
1037    /// Reads the changes of the object: the base class first, then the
1038    /// changed-fields mask and the changed members of this class.
1039    pub fn deserialize_changes_core(
1040        &self,
1041        host: &dyn ServerCompositionRadialGradientBrushHooks,
1042        reader: &mut BatchStreamReader<'_>,
1043        committed_at: Duration,
1044    ) {
1045        ServerCompositionRadialGradientBrushHooks::base_deserialize_changes_core(host, reader, committed_at);
1046        ServerCompositionRadialGradientBrushHooks::deserialize_changes_extra(host, reader);
1047        let changed = reader.read::<CompositionRadialGradientBrushChangedFields>();
1048        if changed.contains(CompositionRadialGradientBrushChangedFields::CENTER_ANIMATED) {
1049            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1050                panic!("a batch starts an animation of `Center` without an animation instance");
1051            };
1052            host.set_animated_value(
1053                Self::id_of_center_property().base(),
1054                ExpressionVariant::create(self.center.get()),
1055                committed_at,
1056                animation,
1057            );
1058        } else if changed.contains(CompositionRadialGradientBrushChangedFields::CENTER) {
1059            let value = reader.read::<RelativePoint>();
1060            self.set_center(host, value);
1061        }
1062        if changed.contains(CompositionRadialGradientBrushChangedFields::GRADIENT_ORIGIN_ANIMATED) {
1063            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1064                panic!("a batch starts an animation of `GradientOrigin` without an animation instance");
1065            };
1066            host.set_animated_value(
1067                Self::id_of_gradient_origin_property().base(),
1068                ExpressionVariant::create(self.gradient_origin.get()),
1069                committed_at,
1070                animation,
1071            );
1072        } else if changed.contains(CompositionRadialGradientBrushChangedFields::GRADIENT_ORIGIN) {
1073            let value = reader.read::<RelativePoint>();
1074            self.set_gradient_origin(host, value);
1075        }
1076        if changed.contains(CompositionRadialGradientBrushChangedFields::RADIUS_X_ANIMATED) {
1077            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1078                panic!("a batch starts an animation of `RadiusX` without an animation instance");
1079            };
1080            host.set_animated_value(
1081                Self::id_of_radius_x_property().base(),
1082                ExpressionVariant::create(self.radius_x.get()),
1083                committed_at,
1084                animation,
1085            );
1086        } else if changed.contains(CompositionRadialGradientBrushChangedFields::RADIUS_X) {
1087            let value = reader.read::<RelativeScalar>();
1088            self.set_radius_x(host, value);
1089        }
1090        if changed.contains(CompositionRadialGradientBrushChangedFields::RADIUS_Y_ANIMATED) {
1091            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1092                panic!("a batch starts an animation of `RadiusY` without an animation instance");
1093            };
1094            host.set_animated_value(
1095                Self::id_of_radius_y_property().base(),
1096                ExpressionVariant::create(self.radius_y.get()),
1097                committed_at,
1098                animation,
1099            );
1100        } else if changed.contains(CompositionRadialGradientBrushChangedFields::RADIUS_Y) {
1101            let value = reader.read::<RelativeScalar>();
1102            self.set_radius_y(host, value);
1103        }
1104        if changed.contains(CompositionRadialGradientBrushChangedFields::ANCHOR_POINT_ANIMATED) {
1105            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1106                panic!("a batch starts an animation of `AnchorPoint` without an animation instance");
1107            };
1108            host.set_animated_value(
1109                Self::id_of_anchor_point_property().base(),
1110                ExpressionVariant::create(self.anchor_point.get()),
1111                committed_at,
1112                animation,
1113            );
1114        } else if changed.contains(CompositionRadialGradientBrushChangedFields::ANCHOR_POINT) {
1115            let value = reader.read::<Vector>();
1116            self.set_anchor_point(host, value);
1117        }
1118        if changed.contains(CompositionRadialGradientBrushChangedFields::CENTER_POINT_ANIMATED) {
1119            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1120                panic!("a batch starts an animation of `CenterPoint` without an animation instance");
1121            };
1122            host.set_animated_value(
1123                Self::id_of_center_point_property().base(),
1124                ExpressionVariant::create(self.center_point.get()),
1125                committed_at,
1126                animation,
1127            );
1128        } else if changed.contains(CompositionRadialGradientBrushChangedFields::CENTER_POINT) {
1129            let value = reader.read::<Vector>();
1130            self.set_center_point(host, value);
1131        }
1132        if changed.contains(CompositionRadialGradientBrushChangedFields::OFFSET_ANIMATED) {
1133            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1134                panic!("a batch starts an animation of `Offset` without an animation instance");
1135            };
1136            host.set_animated_value(
1137                Self::id_of_offset_property().base(),
1138                ExpressionVariant::create(self.offset.get()),
1139                committed_at,
1140                animation,
1141            );
1142        } else if changed.contains(CompositionRadialGradientBrushChangedFields::OFFSET) {
1143            let value = reader.read::<Vector>();
1144            self.set_offset(host, value);
1145        }
1146        if changed.contains(CompositionRadialGradientBrushChangedFields::ROTATION_ANGLE_ANIMATED) {
1147            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1148                panic!("a batch starts an animation of `RotationAngle` without an animation instance");
1149            };
1150            host.set_animated_value(
1151                Self::id_of_rotation_angle_property().base(),
1152                ExpressionVariant::create(self.rotation_angle.get()),
1153                committed_at,
1154                animation,
1155            );
1156        } else if changed.contains(CompositionRadialGradientBrushChangedFields::ROTATION_ANGLE) {
1157            let value = reader.read::<f32>();
1158            self.set_rotation_angle(host, value);
1159        }
1160        if changed.contains(CompositionRadialGradientBrushChangedFields::SCALE_ANIMATED) {
1161            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1162                panic!("a batch starts an animation of `Scale` without an animation instance");
1163            };
1164            host.set_animated_value(
1165                Self::id_of_scale_property().base(),
1166                ExpressionVariant::create(self.scale.get()),
1167                committed_at,
1168                animation,
1169            );
1170        } else if changed.contains(CompositionRadialGradientBrushChangedFields::SCALE) {
1171            let value = reader.read::<Vector>();
1172            self.set_scale(host, value);
1173        }
1174        if changed.contains(CompositionRadialGradientBrushChangedFields::TRANSFORM_MATRIX_ANIMATED) {
1175            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
1176                panic!("a batch starts an animation of `TransformMatrix` without an animation instance");
1177            };
1178            host.set_animated_value(
1179                Self::id_of_transform_matrix_property().base(),
1180                ExpressionVariant::create(self.transform_matrix.get()),
1181                committed_at,
1182                animation,
1183            );
1184        } else if changed.contains(CompositionRadialGradientBrushChangedFields::TRANSFORM_MATRIX) {
1185            let value = reader.read::<Matrix>();
1186            self.set_transform_matrix(host, value);
1187        }
1188        ServerCompositionRadialGradientBrushHooks::on_fields_deserialized(host, changed);
1189    }
1190
1191    /// The composition property with the given name, among the properties
1192    /// of this class and of its generated bases that have a variant form.
1193    pub fn get_composition_property(name: &str) -> Option<&'static CompositionProperty> {
1194        if name == "Center" {
1195            return Some(Self::id_of_center_property().base());
1196        }
1197        if name == "GradientOrigin" {
1198            return Some(Self::id_of_gradient_origin_property().base());
1199        }
1200        if name == "RadiusX" {
1201            return Some(Self::id_of_radius_x_property().base());
1202        }
1203        if name == "RadiusY" {
1204            return Some(Self::id_of_radius_y_property().base());
1205        }
1206        if name == "AnchorPoint" {
1207            return Some(Self::id_of_anchor_point_property().base());
1208        }
1209        if name == "CenterPoint" {
1210            return Some(Self::id_of_center_point_property().base());
1211        }
1212        if name == "Offset" {
1213            return Some(Self::id_of_offset_property().base());
1214        }
1215        if name == "RotationAngle" {
1216            return Some(Self::id_of_rotation_angle_property().base());
1217        }
1218        if name == "Scale" {
1219            return Some(Self::id_of_scale_property().base());
1220        }
1221        if name == "TransformMatrix" {
1222            return Some(Self::id_of_transform_matrix_property().base());
1223        }
1224        None
1225    }
1226}