ferroui_base/media/effects/
i_drop_shadow_effect.rs1use crate::media::effects::{
2 DropShadowDirectionEffect, DropShadowEffect, DropShadowEffectBase, Effect, IEffect, IImmutableEffect,
3};
4use crate::media::ref_adapter::RefAdapter;
5use crate::media::Color;
6use crate::{ObjectType, Upcast};
7use std::any::Any;
8use std::f64::consts::PI;
9use std::rc::Rc;
10
11pub trait IDropShadowEffect: IEffect {
13 fn offset_x(&self) -> f64;
15
16 fn offset_y(&self) -> f64;
18
19 fn blur_radius(&self) -> f64;
21
22 fn color(&self) -> Color;
24
25 fn opacity(&self) -> f64;
27}
28
29pub trait IDirectionDropShadowEffect: IDropShadowEffect {
31 fn direction(&self) -> f64;
33
34 fn shadow_depth(&self) -> f64;
36}
37
38fn drop_shadow_equals(this: &dyn IDropShadowEffect, other: Option<&dyn IEffect>) -> bool {
39 other.and_then(|other| other.as_drop_shadow_effect()).is_some_and(|d| {
40 d.offset_x() == this.offset_x()
41 && d.offset_y() == this.offset_y()
42 && d.blur_radius() == this.blur_radius()
43 && d.color() == this.color()
44 && d.opacity() == this.opacity()
45 })
46}
47
48#[derive(Clone, Copy, Debug)]
50pub struct ImmutableDropShadowEffect {
51 offset_x: f64,
52 offset_y: f64,
53 blur_radius: f64,
54 color: Color,
55 opacity: f64,
56}
57
58impl ImmutableDropShadowEffect {
59 pub fn new(offset_x: f64, offset_y: f64, blur_radius: f64, color: Color, opacity: f64) -> Self {
60 Self { offset_x, offset_y, blur_radius, color, opacity }
61 }
62
63 #[inline]
65 pub fn offset_x(&self) -> f64 {
66 self.offset_x
67 }
68
69 #[inline]
71 pub fn offset_y(&self) -> f64 {
72 self.offset_y
73 }
74
75 #[inline]
77 pub fn blur_radius(&self) -> f64 {
78 self.blur_radius
79 }
80
81 #[inline]
83 pub fn color(&self) -> Color {
84 self.color
85 }
86
87 #[inline]
89 pub fn opacity(&self) -> f64 {
90 self.opacity
91 }
92}
93
94impl IEffect for ImmutableDropShadowEffect {
95 fn as_any(&self) -> &dyn Any {
96 self
97 }
98
99 fn as_drop_shadow_effect(&self) -> Option<&dyn IDropShadowEffect> {
100 Some(self)
101 }
102
103 fn as_immutable_effect(&self) -> Option<&dyn IImmutableEffect> {
104 Some(self)
105 }
106
107 fn into_immutable_effect(self: Rc<Self>) -> Option<std::sync::Arc<dyn IImmutableEffect>> {
108 Some(std::sync::Arc::new(*self))
109 }
110}
111
112impl IDropShadowEffect for ImmutableDropShadowEffect {
113 #[inline]
114 fn offset_x(&self) -> f64 {
115 self.offset_x
116 }
117
118 #[inline]
119 fn offset_y(&self) -> f64 {
120 self.offset_y
121 }
122
123 #[inline]
124 fn blur_radius(&self) -> f64 {
125 self.blur_radius
126 }
127
128 #[inline]
129 fn color(&self) -> Color {
130 self.color
131 }
132
133 #[inline]
134 fn opacity(&self) -> f64 {
135 self.opacity
136 }
137}
138
139impl IImmutableEffect for ImmutableDropShadowEffect {
140 fn equals(&self, other: Option<&dyn IEffect>) -> bool {
141 drop_shadow_equals(self, other)
142 }
143}
144
145#[derive(Clone, Copy, Debug)]
147pub struct ImmutableDropShadowDirectionEffect {
148 direction: f64,
149 shadow_depth: f64,
150 blur_radius: f64,
151 color: Color,
152 opacity: f64,
153}
154
155impl ImmutableDropShadowDirectionEffect {
156 pub fn new(direction: f64, shadow_depth: f64, blur_radius: f64, color: Color, opacity: f64) -> Self {
157 Self { direction, shadow_depth, blur_radius, color, opacity }
158 }
159
160 pub fn offset_x(&self) -> f64 {
162 (self.direction * PI / 180.0).cos() * self.shadow_depth
163 }
164
165 pub fn offset_y(&self) -> f64 {
167 (self.direction * PI / 180.0).sin() * self.shadow_depth
168 }
169
170 #[inline]
172 pub fn direction(&self) -> f64 {
173 self.direction
174 }
175
176 #[inline]
178 pub fn shadow_depth(&self) -> f64 {
179 self.shadow_depth
180 }
181
182 #[inline]
184 pub fn blur_radius(&self) -> f64 {
185 self.blur_radius
186 }
187
188 #[inline]
190 pub fn color(&self) -> Color {
191 self.color
192 }
193
194 #[inline]
196 pub fn opacity(&self) -> f64 {
197 self.opacity
198 }
199}
200
201impl IEffect for ImmutableDropShadowDirectionEffect {
202 fn as_any(&self) -> &dyn Any {
203 self
204 }
205
206 fn as_drop_shadow_effect(&self) -> Option<&dyn IDropShadowEffect> {
207 Some(self)
208 }
209
210 fn as_direction_drop_shadow_effect(&self) -> Option<&dyn IDirectionDropShadowEffect> {
211 Some(self)
212 }
213
214 fn as_immutable_effect(&self) -> Option<&dyn IImmutableEffect> {
215 Some(self)
216 }
217
218 fn into_immutable_effect(self: Rc<Self>) -> Option<std::sync::Arc<dyn IImmutableEffect>> {
219 Some(std::sync::Arc::new(*self))
220 }
221}
222
223impl IDropShadowEffect for ImmutableDropShadowDirectionEffect {
224 fn offset_x(&self) -> f64 {
225 ImmutableDropShadowDirectionEffect::offset_x(self)
226 }
227
228 fn offset_y(&self) -> f64 {
229 ImmutableDropShadowDirectionEffect::offset_y(self)
230 }
231
232 #[inline]
233 fn blur_radius(&self) -> f64 {
234 self.blur_radius
235 }
236
237 #[inline]
238 fn color(&self) -> Color {
239 self.color
240 }
241
242 #[inline]
243 fn opacity(&self) -> f64 {
244 self.opacity
245 }
246}
247
248impl IDirectionDropShadowEffect for ImmutableDropShadowDirectionEffect {
249 #[inline]
250 fn direction(&self) -> f64 {
251 self.direction
252 }
253
254 #[inline]
255 fn shadow_depth(&self) -> f64 {
256 self.shadow_depth
257 }
258}
259
260impl IImmutableEffect for ImmutableDropShadowDirectionEffect {
261 fn equals(&self, other: Option<&dyn IEffect>) -> bool {
262 drop_shadow_equals(self, other)
263 }
264}
265
266impl<T: ObjectType + Upcast<Effect>> IDropShadowEffect for RefAdapter<T> {
267 fn offset_x(&self) -> f64 {
268 match self.object().downcast_ref::<DropShadowEffect>() {
269 Some(shadow) => shadow.offset_x(),
270 None => self.class::<DropShadowDirectionEffect>().offset_x(),
271 }
272 }
273
274 fn offset_y(&self) -> f64 {
275 match self.object().downcast_ref::<DropShadowEffect>() {
276 Some(shadow) => shadow.offset_y(),
277 None => self.class::<DropShadowDirectionEffect>().offset_y(),
278 }
279 }
280
281 #[inline]
282 fn blur_radius(&self) -> f64 {
283 self.class::<DropShadowEffectBase>().blur_radius()
284 }
285
286 #[inline]
287 fn color(&self) -> Color {
288 self.class::<DropShadowEffectBase>().color()
289 }
290
291 #[inline]
292 fn opacity(&self) -> f64 {
293 self.class::<DropShadowEffectBase>().opacity()
294 }
295}
296
297impl<T: ObjectType + Upcast<Effect>> IDirectionDropShadowEffect for RefAdapter<T> {
298 #[inline]
299 fn direction(&self) -> f64 {
300 self.class::<DropShadowDirectionEffect>().direction()
301 }
302
303 #[inline]
304 fn shadow_depth(&self) -> f64 {
305 self.class::<DropShadowDirectionEffect>().shadow_depth()
306 }
307}