ferroui_base/media/
i_brush.rs1use crate::media::ref_adapter::RefAdapter;
2use crate::media::{
3 Brush, Color, ConicGradientBrush, DrawingBrush, GradientBrush, GradientSpreadMethod, IConicGradientBrush, IGradientBrush,
4 IGradientStop, IImageBrush, IImmutableBrush, ILinearGradientBrush, IMutableBrush, IRadialGradientBrush,
5 ISceneBrush, ISolidColorBrush, ITileBrush, ITransform, ImageBrush, LinearGradientBrush, RadialGradientBrush,
6 SolidColorBrush, TileBrush, VisualBrush,
7};
8use crate::{FerroObject, ObjectType, Ref, RelativePoint, RelativeScalar, Upcast};
9use std::any::Any;
10use std::rc::Rc;
11
12pub trait IBrush: 'static {
20 fn opacity(&self) -> f64;
22
23 fn transform(&self) -> Option<Rc<dyn ITransform>>;
25
26 fn transform_origin(&self) -> RelativePoint;
28
29 fn relative_transform(&self) -> Option<Rc<dyn ITransform>>;
32
33 fn as_any(&self) -> &dyn Any;
36
37 fn as_object(&self) -> Option<&FerroObject> {
39 None
40 }
41
42 fn as_solid_color_brush(&self) -> Option<&dyn ISolidColorBrush> {
44 None
45 }
46
47 fn as_gradient_brush(&self) -> Option<&dyn IGradientBrush> {
49 None
50 }
51
52 fn as_linear_gradient_brush(&self) -> Option<&dyn ILinearGradientBrush> {
54 None
55 }
56
57 fn as_radial_gradient_brush(&self) -> Option<&dyn IRadialGradientBrush> {
59 None
60 }
61
62 fn as_conic_gradient_brush(&self) -> Option<&dyn IConicGradientBrush> {
64 None
65 }
66
67 fn as_tile_brush(&self) -> Option<&dyn ITileBrush> {
69 None
70 }
71
72 fn as_image_brush(&self) -> Option<&dyn IImageBrush> {
74 None
75 }
76
77 fn as_scene_brush(&self) -> Option<&dyn ISceneBrush> {
79 None
80 }
81
82 fn as_mutable_brush(&self) -> Option<&dyn IMutableBrush> {
84 None
85 }
86
87 fn as_immutable_brush(&self) -> Option<&dyn IImmutableBrush> {
90 None
91 }
92
93 fn as_composition_render_resource(
97 &self,
98 ) -> Option<&dyn crate::rendering::composition::drawing::ICompositionRenderResource> {
99 None
100 }
101
102 fn as_composition_brush(&self) -> Option<&crate::rendering::composition::CompositionBrush> {
105 None
106 }
107
108 fn into_immutable_brush(self: Rc<Self>) -> Option<Rc<dyn IImmutableBrush>> {
110 None
111 }
112
113 fn to_shared(&self) -> Option<crate::media::SharedBrush> {
117 None
118 }
119
120 #[doc(hidden)]
122 fn reference_id(&self) -> *const () {
123 self as *const Self as *const ()
124 }
125
126 fn equals(&self, other: &dyn IBrush) -> bool {
129 self.reference_id() == other.reference_id()
130 }
131}
132
133impl PartialEq for dyn IBrush {
134 #[inline]
135 fn eq(&self, other: &Self) -> bool {
136 self.equals(other)
137 }
138}
139
140impl std::fmt::Debug for dyn IBrush {
141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142 match self.as_solid_color_brush() {
143 Some(solid) => write!(f, "IBrush({})", solid.color()),
144 None => f.write_str("IBrush"),
145 }
146 }
147}
148
149impl<T: ObjectType + Upcast<Brush>> RefAdapter<T> {
150 #[inline]
151 fn brush(&self) -> &Brush {
152 (*self.0).upcast()
153 }
154}
155
156impl<T: ObjectType + Upcast<Brush>> IBrush for RefAdapter<T> {
157 #[inline]
158 fn opacity(&self) -> f64 {
159 self.brush().opacity()
160 }
161
162 #[inline]
163 fn transform(&self) -> Option<Rc<dyn ITransform>> {
164 self.brush().transform()
165 }
166
167 #[inline]
168 fn transform_origin(&self) -> RelativePoint {
169 self.brush().transform_origin()
170 }
171
172 #[inline]
173 fn relative_transform(&self) -> Option<Rc<dyn ITransform>> {
174 self.brush().relative_transform()
175 }
176
177 fn as_any(&self) -> &dyn Any {
178 self.brush()
179 }
180
181 fn as_object(&self) -> Option<&FerroObject> {
182 Some(self.object())
183 }
184
185 fn as_solid_color_brush(&self) -> Option<&dyn ISolidColorBrush> {
186 if self.object().is::<SolidColorBrush>() {
187 Some(self)
188 } else {
189 None
190 }
191 }
192
193 fn as_gradient_brush(&self) -> Option<&dyn IGradientBrush> {
194 if self.object().is::<GradientBrush>() {
195 Some(self)
196 } else {
197 None
198 }
199 }
200
201 fn as_linear_gradient_brush(&self) -> Option<&dyn ILinearGradientBrush> {
202 if self.object().is::<LinearGradientBrush>() {
203 Some(self)
204 } else {
205 None
206 }
207 }
208
209 fn as_radial_gradient_brush(&self) -> Option<&dyn IRadialGradientBrush> {
210 if self.object().is::<RadialGradientBrush>() {
211 Some(self)
212 } else {
213 None
214 }
215 }
216
217 fn as_conic_gradient_brush(&self) -> Option<&dyn IConicGradientBrush> {
218 if self.object().is::<ConicGradientBrush>() {
219 Some(self)
220 } else {
221 None
222 }
223 }
224
225 fn as_tile_brush(&self) -> Option<&dyn ITileBrush> {
226 if self.object().is::<TileBrush>() {
227 Some(self)
228 } else {
229 None
230 }
231 }
232
233 fn as_image_brush(&self) -> Option<&dyn IImageBrush> {
234 if self.object().is::<ImageBrush>() {
235 Some(self)
236 } else {
237 None
238 }
239 }
240
241 fn as_scene_brush(&self) -> Option<&dyn ISceneBrush> {
242 if self.object().is::<VisualBrush>() || self.object().is::<DrawingBrush>() {
243 Some(self)
244 } else {
245 None
246 }
247 }
248
249 fn as_mutable_brush(&self) -> Option<&dyn IMutableBrush> {
250 if self.object().is::<SolidColorBrush>()
251 || self.object().is::<GradientBrush>()
252 || self.object().is::<ImageBrush>()
253 {
254 Some(self)
255 } else {
256 None
257 }
258 }
259
260 fn as_composition_render_resource(
261 &self,
262 ) -> Option<&dyn crate::rendering::composition::drawing::ICompositionRenderResource> {
263 let brush = self.brush();
266 brush.factory().map(|_| brush as &dyn crate::rendering::composition::drawing::ICompositionRenderResource)
267 }
268
269 fn reference_id(&self) -> *const () {
270 RefAdapter::reference_id(self)
271 }
272}
273
274impl<T: ObjectType + Upcast<Brush>> ISolidColorBrush for RefAdapter<T> {
275 #[inline]
276 fn color(&self) -> Color {
277 self.class::<SolidColorBrush>().color()
278 }
279}
280
281impl<T: ObjectType + Upcast<Brush>> IGradientBrush for RefAdapter<T> {
282 fn gradient_stops(&self) -> Vec<Rc<dyn IGradientStop>> {
283 self.class::<GradientBrush>().gradient_stops().iter().map(Into::into).collect()
284 }
285
286 #[inline]
287 fn spread_method(&self) -> GradientSpreadMethod {
288 self.class::<GradientBrush>().spread_method()
289 }
290}
291
292impl<T: ObjectType + Upcast<Brush>> ILinearGradientBrush for RefAdapter<T> {
293 #[inline]
294 fn start_point(&self) -> RelativePoint {
295 self.class::<LinearGradientBrush>().start_point()
296 }
297
298 #[inline]
299 fn end_point(&self) -> RelativePoint {
300 self.class::<LinearGradientBrush>().end_point()
301 }
302}
303
304impl<T: ObjectType + Upcast<Brush>> IRadialGradientBrush for RefAdapter<T> {
305 #[inline]
306 fn center(&self) -> RelativePoint {
307 self.class::<RadialGradientBrush>().center()
308 }
309
310 #[inline]
311 fn gradient_origin(&self) -> RelativePoint {
312 self.class::<RadialGradientBrush>().gradient_origin()
313 }
314
315 #[inline]
316 fn radius_x(&self) -> RelativeScalar {
317 self.class::<RadialGradientBrush>().radius_x()
318 }
319
320 #[inline]
321 fn radius_y(&self) -> RelativeScalar {
322 self.class::<RadialGradientBrush>().radius_y()
323 }
324}
325
326impl<T: ObjectType + Upcast<Brush>> IConicGradientBrush for RefAdapter<T> {
327 #[inline]
328 fn center(&self) -> RelativePoint {
329 self.class::<ConicGradientBrush>().center()
330 }
331
332 #[inline]
333 fn angle(&self) -> f64 {
334 self.class::<ConicGradientBrush>().angle()
335 }
336}
337
338impl<T: ObjectType + Upcast<Brush>> IMutableBrush for RefAdapter<T> {
339 fn to_immutable(&self) -> Rc<dyn IImmutableBrush> {
340 let object = self.object();
341 if let Some(solid) = object.downcast_ref::<SolidColorBrush>() {
342 solid.to_immutable()
343 } else if let Some(image) = object.downcast_ref::<ImageBrush>() {
344 image.to_immutable()
345 } else {
346 self.class::<GradientBrush>().to_immutable()
347 }
348 }
349}
350
351impl<T: ObjectType + Upcast<Brush>> From<Ref<T>> for Rc<dyn IBrush> {
352 #[inline]
353 fn from(value: Ref<T>) -> Self {
354 Rc::new(RefAdapter(value))
355 }
356}
357
358impl<T: ObjectType + Upcast<Brush>> From<&Ref<T>> for Rc<dyn IBrush> {
359 #[inline]
360 fn from(value: &Ref<T>) -> Self {
361 Rc::new(RefAdapter(value.clone()))
362 }
363}