1use crate::{Color32, CornerRadius, Marginf, Rect, RectShape, Vec2};
2
3#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
9#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
10pub struct Shadow {
11 pub offset: [i8; 2],
16
17 pub blur: u8,
21
22 pub spread: u8,
24
25 pub color: Color32,
27}
28
29#[test]
30fn shadow_size() {
31 assert_eq!(
32 std::mem::size_of::<Shadow>(), 8,
33 "Shadow changed size! If it shrank - good! Update this test. If it grew - bad! Try to find a way to avoid it."
34 );
35}
36
37impl Shadow {
38 pub const NONE: Self = Self {
40 offset: [0, 0],
41 blur: 0,
42 spread: 0,
43 color: Color32::TRANSPARENT,
44 };
45
46 pub fn as_shape(&self, rect: Rect, corner_radius: impl Into<CornerRadius>) -> RectShape {
48 let Self {
51 offset,
52 blur,
53 spread,
54 color,
55 } = *self;
56 let [offset_x, offset_y] = offset;
57
58 let rect = rect
59 .translate(Vec2::new(offset_x as _, offset_y as _))
60 .expand(spread as _);
61 let corner_radius = corner_radius.into() + CornerRadius::from(spread);
62
63 RectShape::filled(rect, corner_radius, color).with_blur_width(blur as _)
64 }
65
66 pub fn margin(&self) -> Marginf {
68 let Self {
69 offset,
70 blur,
71 spread,
72 color: _,
73 } = *self;
74 let spread = spread as f32;
75 let blur = blur as f32;
76 let [offset_x, offset_y] = offset;
77 Marginf {
78 left: spread + 0.5 * blur - offset_x as f32,
79 right: spread + 0.5 * blur + offset_x as f32,
80 top: spread + 0.5 * blur - offset_y as f32,
81 bottom: spread + 0.5 * blur + offset_y as f32,
82 }
83 }
84}