Skip to main content

ferroui_base/rendering/composition/generated/
shape_visual.rs

1// @generated by scripts/generate_composition.py — do not edit
2
3//! `ShapeVisual`.
4//!
5//! Defined by the FerroUI overlay (scripts/composition-schema-winui.xml).
6
7use bitflags::bitflags;
8use crate::rendering::composition::ICompositionObject;
9use crate::rendering::composition::animations::ICompositionAnimation;
10use crate::rendering::composition::expressions::ExpressionVariant;
11use crate::rendering::composition::server::AsServerRenderResource;
12use crate::rendering::composition::server::CompositionProperty;
13use crate::rendering::composition::server::CompositionPropertyOf;
14use crate::rendering::composition::server::IServerAnimatedPropertyHost;
15use crate::rendering::composition::server::IServerObject;
16use crate::rendering::composition::server::ServerPropertyValue;
17use crate::rendering::composition::server::ServerValueChange;
18use crate::rendering::composition::server::props_of;
19use crate::rendering::composition::server::read_server_object;
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::cell::RefCell;
28use std::rc::Rc;
29use std::sync::OnceLock;
30use std::time::Duration;
31use super::CompositionContainerVisualHooks;
32use super::CompositionContainerVisualProps;
33
34bitflags! {
35    /// The fields of `ShapeVisual` that changed since its last serialization.
36    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
37    pub struct ShapeVisualChangedFields: u8 {
38        const SHAPES = 1;
39        const VIEW_BOX = 2;
40    }
41}
42
43impl BatchValue for ShapeVisualChangedFields {
44    #[inline]
45    fn write_to(&self, out: &mut Vec<u8>) {
46        self.bits().write_to(out);
47    }
48
49    #[inline]
50    fn read_from(input: &mut BatchValueReader<'_>) -> Self {
51        ShapeVisualChangedFields::from_bits_retain(u8::read_from(input))
52    }
53}
54
55/// The partial methods of `ShapeVisual`: implemented by the class that embeds
56/// [`ShapeVisualProps`]. Every hook defaults to doing nothing.
57pub trait ShapeVisualHooks: CompositionContainerVisualHooks {
58    fn initialize_defaults_extra(&self) {}
59
60    fn validate_shapes_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
61    fn on_shapes_changed(&self) {}
62    fn on_shapes_changing(&self) {}
63
64    fn validate_view_box_change(&self, _old_value: &Option<Rc<dyn ICompositionObject>>, _new_value: &Option<Rc<dyn ICompositionObject>>) {}
65    fn on_view_box_changed(&self) {}
66    fn on_view_box_changing(&self) {}
67}
68
69/// The UI-thread properties of `ShapeVisual`.
70pub struct ShapeVisualProps {
71    base: CompositionContainerVisualProps,
72    changed_fields_of_shape_visual: Cell<ShapeVisualChangedFields>,
73    shapes: RefCell<Option<Rc<dyn ICompositionObject>>>,
74    view_box: RefCell<Option<Rc<dyn ICompositionObject>>>,
75}
76
77impl Default for ShapeVisualProps {
78    fn default() -> Self {
79        Self::new()
80    }
81}
82
83impl ShapeVisualProps {
84    /// Creates the properties with every field at the default of its type.
85    /// The defaults of the schema are applied by
86    /// [`initialize_defaults`](Self::initialize_defaults).
87    pub fn new() -> Self {
88        Self {
89            base: CompositionContainerVisualProps::new(),
90            changed_fields_of_shape_visual: Cell::new(ShapeVisualChangedFields::empty()),
91            shapes: RefCell::new(None),
92            view_box: RefCell::new(None),
93        }
94    }
95
96    /// The properties of the base class.
97    pub fn base(&self) -> &CompositionContainerVisualProps {
98        &self.base
99    }
100
101    /// The `InitializeDefaults` calls of the constructor chain: the base
102    /// classes first, then this class.
103    pub fn initialize_defaults(&self, host: &dyn ShapeVisualHooks) {
104        self.base.initialize_defaults(host);
105        self.initialize_own_defaults(host);
106    }
107
108    /// `InitializeDefaults` of this class alone.
109    pub fn initialize_own_defaults(&self, host: &dyn ShapeVisualHooks) {
110        ShapeVisualHooks::initialize_defaults_extra(host);
111    }
112
113    /// `Shapes` (FerroUI overlay).
114    pub fn shapes(&self) -> Option<Rc<dyn ICompositionObject>> {
115        self.shapes.borrow().clone()
116    }
117
118    /// Sets `Shapes` (FerroUI overlay).
119    pub fn set_shapes(&self, host: &dyn ShapeVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
120        let mut changed = false;
121        let old_value = self.shapes.borrow().clone();
122        if old_value.differs(&value) {
123            ShapeVisualHooks::validate_shapes_change(host, &old_value, &value);
124            ShapeVisualHooks::on_shapes_changing(host);
125            changed = true;
126            // Update the backing value
127            *self.shapes.borrow_mut() = value.clone();
128            // Register object for serialization in the next batch
129            self.changed_fields_of_shape_visual.set(self.changed_fields_of_shape_visual.get() | ShapeVisualChangedFields::SHAPES);
130            host.register_for_serialization();
131        }
132        *self.shapes.borrow_mut() = value;
133        if changed {
134            ShapeVisualHooks::on_shapes_changed(host);
135        }
136    }
137
138    /// `ViewBox` (FerroUI overlay).
139    pub fn view_box(&self) -> Option<Rc<dyn ICompositionObject>> {
140        self.view_box.borrow().clone()
141    }
142
143    /// Sets `ViewBox` (FerroUI overlay).
144    pub fn set_view_box(&self, host: &dyn ShapeVisualHooks, value: Option<Rc<dyn ICompositionObject>>) {
145        let mut changed = false;
146        let old_value = self.view_box.borrow().clone();
147        if old_value.differs(&value) {
148            ShapeVisualHooks::validate_view_box_change(host, &old_value, &value);
149            ShapeVisualHooks::on_view_box_changing(host);
150            changed = true;
151            // Update the backing value
152            *self.view_box.borrow_mut() = value.clone();
153            // Register object for serialization in the next batch
154            self.changed_fields_of_shape_visual.set(self.changed_fields_of_shape_visual.get() | ShapeVisualChangedFields::VIEW_BOX);
155            host.register_for_serialization();
156        }
157        *self.view_box.borrow_mut() = value;
158        if changed {
159            ShapeVisualHooks::on_view_box_changed(host);
160        }
161    }
162
163    /// Connects an animation with the named property. Returns `false` when
164    /// neither this class nor its generated bases have an animated property
165    /// of that name: the caller continues with its hand-written base.
166    pub fn start_animation(
167        &self,
168        host: &dyn ShapeVisualHooks,
169        property_name: &str,
170        animation: &dyn ICompositionAnimation,
171        final_value: Option<ExpressionVariant>,
172    ) -> bool {
173        self.base.start_animation(host, property_name, animation, final_value)
174    }
175
176    /// Writes the changes of the object: the base class first, then the
177    /// changed-fields mask and the changed members of this class.
178    pub fn serialize_changes_core(&self, host: &dyn ShapeVisualHooks, writer: &mut BatchStreamWriter<'_>) {
179        self.base.serialize_changes_core(host, writer);
180        let changed = self.changed_fields_of_shape_visual.get();
181        writer.write(changed);
182        if changed.contains(ShapeVisualChangedFields::SHAPES) {
183            writer.write_server_object(self.shapes.borrow().clone().map(|o| o.server()));
184        }
185        if changed.contains(ShapeVisualChangedFields::VIEW_BOX) {
186            writer.write_server_object(self.view_box.borrow().clone().map(|o| o.server()));
187        }
188        self.changed_fields_of_shape_visual.set(ShapeVisualChangedFields::empty());
189    }
190}
191
192/// The partial methods of `ServerShapeVisual`: implemented by the class that embeds
193/// [`ServerShapeVisualProps`]. Every hook defaults to doing nothing.
194pub trait ServerShapeVisualHooks: IServerAnimatedPropertyHost {
195    /// `base.DeserializeChangesCore(reader, committedAt)`: reads the changes of
196    /// the hand-written base class `ServerSizeDependantVisual`.
197    fn base_deserialize_changes_core(&self, reader: &mut BatchStreamReader<'_>, committed_at: Duration);
198
199    fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
200    fn on_fields_deserialized(&self, _changed: ShapeVisualChangedFields) {}
201
202    fn on_shapes_changed(&self) {}
203    fn on_shapes_changing(&self) {}
204
205    fn on_view_box_changed(&self) {}
206    fn on_view_box_changing(&self) {}
207}
208
209/// The server-side properties of `ServerShapeVisual`.
210pub struct ServerShapeVisualProps {
211    shapes: RefCell<Option<Rc<dyn IServerObject>>>,
212    view_box: RefCell<Option<Rc<dyn IServerObject>>>,
213}
214
215impl Default for ServerShapeVisualProps {
216    fn default() -> Self {
217        Self::new()
218    }
219}
220
221impl ServerShapeVisualProps {
222    /// Creates the properties with every field at the default of its type; the
223    /// values of the UI thread arrive with the first batch.
224    pub fn new() -> Self {
225        Self {
226            shapes: RefCell::new(None),
227            view_box: RefCell::new(None),
228        }
229    }
230
231    /// This block or the block of a base class, by type: what
232    /// `IServerObject::get_props` of the embedding class returns.
233    pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
234        if type_id == TypeId::of::<Self>() {
235            return Some(self);
236        }
237        None
238    }
239
240    /// The composition property of `Shapes`.
241    pub fn id_of_shapes_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
242        static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
243        PROPERTY.get_or_init(|| {
244            CompositionProperty::register::<ServerShapeVisualProps, Option<Rc<dyn IServerObject>>>(
245                "Shapes",
246                "ServerShapeVisual",
247                |obj| props_of::<ServerShapeVisualProps>(obj).shapes.borrow().clone(),
248                |obj, v| *props_of::<ServerShapeVisualProps>(obj).shapes.borrow_mut() = v,
249                None,
250                None,
251            )
252        })
253    }
254
255    /// `Shapes`.
256    pub fn shapes(&self) -> Option<Rc<dyn IServerObject>> {
257        self.shapes.borrow().clone()
258    }
259
260    pub fn set_shapes(&self, host: &dyn ServerShapeVisualHooks, value: Option<Rc<dyn IServerObject>>) {
261        let old_value = self.shapes.borrow().clone();
262        let mut changed = false;
263        if old_value.differs(&value) {
264            ServerShapeVisualHooks::on_shapes_changing(host);
265            changed = true;
266        }
267        host.set_value(
268            Self::id_of_shapes_property().base(),
269            ServerValueChange {
270                equal: old_value.default_equals(&value),
271                old_resource: old_value.as_server_render_resource(),
272                new_resource: value.as_server_render_resource(),
273                assign: &mut || *self.shapes.borrow_mut() = value.clone(),
274            },
275        );
276        if changed {
277            ServerShapeVisualHooks::on_shapes_changed(host);
278        }
279    }
280
281    /// The composition property of `ViewBox`.
282    pub fn id_of_view_box_property() -> &'static CompositionPropertyOf<Option<Rc<dyn IServerObject>>> {
283        static PROPERTY: OnceLock<CompositionPropertyOf<Option<Rc<dyn IServerObject>>>> = OnceLock::new();
284        PROPERTY.get_or_init(|| {
285            CompositionProperty::register::<ServerShapeVisualProps, Option<Rc<dyn IServerObject>>>(
286                "ViewBox",
287                "ServerShapeVisual",
288                |obj| props_of::<ServerShapeVisualProps>(obj).view_box.borrow().clone(),
289                |obj, v| *props_of::<ServerShapeVisualProps>(obj).view_box.borrow_mut() = v,
290                None,
291                None,
292            )
293        })
294    }
295
296    /// `ViewBox`.
297    pub fn view_box(&self) -> Option<Rc<dyn IServerObject>> {
298        self.view_box.borrow().clone()
299    }
300
301    pub fn set_view_box(&self, host: &dyn ServerShapeVisualHooks, value: Option<Rc<dyn IServerObject>>) {
302        let old_value = self.view_box.borrow().clone();
303        let mut changed = false;
304        if old_value.differs(&value) {
305            ServerShapeVisualHooks::on_view_box_changing(host);
306            changed = true;
307        }
308        host.set_value(
309            Self::id_of_view_box_property().base(),
310            ServerValueChange {
311                equal: old_value.default_equals(&value),
312                old_resource: old_value.as_server_render_resource(),
313                new_resource: value.as_server_render_resource(),
314                assign: &mut || *self.view_box.borrow_mut() = value.clone(),
315            },
316        );
317        if changed {
318            ServerShapeVisualHooks::on_view_box_changed(host);
319        }
320    }
321
322    /// Reads the changes of the object: the base class first, then the
323    /// changed-fields mask and the changed members of this class.
324    pub fn deserialize_changes_core(
325        &self,
326        host: &dyn ServerShapeVisualHooks,
327        reader: &mut BatchStreamReader<'_>,
328        committed_at: Duration,
329    ) {
330        let compositor = host.server_compositor();
331        ServerShapeVisualHooks::base_deserialize_changes_core(host, reader, committed_at);
332        ServerShapeVisualHooks::deserialize_changes_extra(host, reader);
333        let changed = reader.read::<ShapeVisualChangedFields>();
334        if changed.contains(ShapeVisualChangedFields::SHAPES) {
335            let value = read_server_object(reader, compositor.as_ref());
336            self.set_shapes(host, value);
337        }
338        if changed.contains(ShapeVisualChangedFields::VIEW_BOX) {
339            let value = read_server_object(reader, compositor.as_ref());
340            self.set_view_box(host, value);
341        }
342        ServerShapeVisualHooks::on_fields_deserialized(host, changed);
343    }
344}