ferroui_base/rendering/composition/
composition_gradient_stop.rs1use super::animations::{ICompositionAnimation, ICompositionAnimationBase, ImplicitAnimationCollection};
2use super::expressions::ExpressionVariant;
3use super::generated::{
4 CompositionGradientStopHooks, CompositionGradientStopProps, ServerCompositionGradientStopProps,
5};
6use super::server::{CompositionProperty, ServerCompositionGradientStop, ServerObjectId};
7use super::transport::{BatchStreamWriter, IRegisterForSerialization};
8use super::{
9 AsCompositionObject, CompositionObject, Compositor, ICompositionObject, ICompositionObjectAnimations,
10 ICompositionObjectHost, ICompositorSerializable, PendingAnimations,
11};
12use crate::media::{Color, IGradientStop};
13use crate::utilities::MathUtilities;
14use std::any::Any;
15use std::rc::{Rc, Weak};
16
17pub struct CompositionGradientStop {
20 this: Weak<CompositionGradientStop>,
21 object: CompositionObject,
22 props: CompositionGradientStopProps,
23}
24
25impl CompositionGradientStop {
26 fn create(compositor: &Rc<Compositor>) -> Rc<CompositionGradientStop> {
27 let server = compositor.create_server_object(|compositor, _| ServerCompositionGradientStop::new(compositor));
28 Rc::new_cyclic(|this: &Weak<CompositionGradientStop>| CompositionGradientStop {
29 this: this.clone(),
30 object: CompositionObject::new(compositor, Some(server)),
31 props: CompositionGradientStopProps::new(),
32 })
33 }
34
35 pub(crate) fn new(compositor: &Rc<Compositor>) -> Rc<CompositionGradientStop> {
36 let stop = Self::create(compositor);
37 stop.props.initialize_defaults(&*stop);
38 stop
39 }
40
41 pub(crate) fn with_offset_and_color(compositor: &Rc<Compositor>, offset: f64, color: Color) -> Rc<CompositionGradientStop> {
42 let stop = Self::create(compositor);
43 let mut offset = offset;
44 if MathUtilities::is_zero(offset) {
45 offset = 0.0;
46 }
47 stop.set_offset(if offset < 0.0 {
48 0.0
49 } else if offset > 1.0 {
50 1.0
51 } else {
52 offset
53 });
54 stop.set_color(color);
55 stop.props.initialize_defaults(&*stop);
56 stop
57 }
58
59 pub fn compositor(&self) -> &Rc<Compositor> {
60 self.object.compositor()
61 }
62
63 pub fn object(&self) -> &CompositionObject {
65 &self.object
66 }
67
68 pub fn server(&self) -> ServerObjectId {
70 self.object.required_server()
71 }
72
73 pub fn color(&self) -> Color {
74 self.props.color()
75 }
76
77 pub fn set_color(&self, value: Color) {
78 self.props.set_color(self, value)
79 }
80
81 pub fn offset(&self) -> f64 {
82 self.props.offset()
83 }
84
85 pub fn set_offset(&self, value: f64) {
86 self.props.set_offset(self, value)
87 }
88
89 pub fn implicit_animations(&self) -> Option<Rc<ImplicitAnimationCollection>> {
91 self.object.implicit_animations()
92 }
93
94 pub fn set_implicit_animations(&self, value: Option<Rc<ImplicitAnimationCollection>>) {
95 self.object.set_implicit_animations(value)
96 }
97}
98
99impl CompositionGradientStopHooks for CompositionGradientStop {}
102
103impl IGradientStop for CompositionGradientStop {
104 fn color(&self) -> Color {
105 self.props.color()
106 }
107
108 fn offset(&self) -> f64 {
109 self.props.offset()
110 }
111
112 fn as_composition_gradient_stop(&self) -> Option<&CompositionGradientStop> {
113 Some(self)
114 }
115}
116
117impl IRegisterForSerialization for CompositionGradientStop {
118 fn register_for_serialization(&self) {
119 self.object
120 .register_for_serialization(|| self.this.upgrade().map(|this| this as Rc<dyn ICompositorSerializable>));
121 }
122}
123
124impl ICompositionObjectHost for CompositionGradientStop {
125 fn server(&self) -> ServerObjectId {
126 self.object.required_server()
127 }
128
129 fn pending_animations(&self) -> &PendingAnimations {
130 self.object.pending_animations()
131 }
132
133 fn implicit_animation(&self, property_name: &str) -> Option<Rc<dyn ICompositionAnimationBase>> {
134 self.object.implicit_animation(property_name)
135 }
136
137 fn start_animation_group(
138 &self,
139 grp: &Rc<dyn ICompositionAnimationBase>,
140 target: &str,
141 final_value: ExpressionVariant,
142 ) -> bool {
143 self.start_animation_group_for(&**grp, target, final_value)
144 }
145}
146
147impl ICompositionObjectAnimations for CompositionGradientStop {
148 fn try_start_animation(
149 &self,
150 property_name: &str,
151 animation: &dyn ICompositionAnimation,
152 final_value: Option<ExpressionVariant>,
153 ) -> bool {
154 self.props.start_animation(self, property_name, animation, final_value)
155 }
156
157 fn get_composition_property(&self, property_name: &str) -> Option<&'static CompositionProperty> {
158 ServerCompositionGradientStopProps::get_composition_property(property_name)
159 }
160
161 fn composition_object(&self) -> &CompositionObject {
162 &self.object
163 }
164}
165
166impl AsCompositionObject for CompositionGradientStop {
167 fn as_composition_object(&self) -> &CompositionObject {
168 &self.object
169 }
170
171 fn composition_type_name(&self) -> &'static str {
172 "CompositionGradientStop"
173 }
174}
175
176impl ICompositionObject for CompositionGradientStop {
177 fn server(&self) -> ServerObjectId {
178 self.object.required_server()
179 }
180
181 fn as_any(&self) -> &dyn Any {
182 self
183 }
184
185 fn into_any_rc(self: Rc<Self>) -> Rc<dyn Any> {
186 self
187 }
188}
189
190impl ICompositorSerializable for CompositionGradientStop {
191 fn try_get_server(&self, c: &Compositor) -> Option<ServerObjectId> {
192 self.object.try_get_server(c)
193 }
194
195 fn serialize_changes(&self, c: &Compositor, writer: &mut BatchStreamWriter<'_>) {
196 self.object.begin_serialize_changes(c);
197 self.props.serialize_changes_core(self, writer);
198 }
199}