lgui_core/core/scene/
shadow.rs1use super::{Color, UiRect, UiScale};
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
7pub struct ShadowStyle {
8 pub color: Color,
9 pub alpha: u8,
10 offset_x_millis: i32,
11 offset_y_millis: i32,
12 blur_millis: i32,
13 spread_millis: i32,
14}
15
16impl ShadowStyle {
17 pub const fn new(color: Color) -> Self {
18 Self {
19 color,
20 alpha: 64,
21 offset_x_millis: 0,
22 offset_y_millis: 4000,
23 blur_millis: 6000,
24 spread_millis: 0,
25 }
26 }
27
28 pub const fn alpha(mut self, alpha: u8) -> Self {
29 self.alpha = alpha;
30 self
31 }
32
33 pub fn offset(mut self, x: f32, y: f32) -> Self {
34 self.offset_x_millis = distance(x);
35 self.offset_y_millis = distance(y);
36 self
37 }
38
39 pub fn blur(mut self, sigma: f32) -> Self {
40 self.blur_millis = distance(sigma).max(0);
41 self
42 }
43
44 pub fn spread(mut self, spread: f32) -> Self {
45 self.spread_millis = distance(spread);
46 self
47 }
48
49 pub fn offset_x(self) -> f32 {
50 self.offset_x_millis as f32 / 1000.0
51 }
52 pub fn offset_y(self) -> f32 {
53 self.offset_y_millis as f32 / 1000.0
54 }
55 pub fn blur_sigma(self) -> f32 {
56 self.blur_millis as f32 / 1000.0
57 }
58 pub fn spread_radius(self) -> f32 {
59 self.spread_millis as f32 / 1000.0
60 }
61
62 pub fn paint_bounds(self, content: UiRect) -> UiRect {
63 if self.alpha == 0 {
64 return content;
65 }
66 let outset = (self.blur_sigma() * 4.0).ceil() + self.spread_radius().max(0.0).ceil() + 1.0;
68 let padded = content.inflate(outset, outset);
69 padded.union(padded.translate(self.offset_x(), self.offset_y()))
70 }
71
72 pub(crate) fn project_to_physical(self, scale: UiScale) -> Self {
73 self.offset(
74 scale.physical_ui_value(self.offset_x()),
75 scale.physical_ui_value(self.offset_y()),
76 )
77 .blur(scale.physical_ui_value(self.blur_sigma()))
78 .spread(scale.physical_ui_value(self.spread_radius()))
79 }
80}
81
82impl Default for ShadowStyle {
83 fn default() -> Self {
84 Self::new(Color::BLACK)
85 }
86}
87
88fn distance(value: f32) -> i32 {
89 if value.is_finite() {
90 (value.clamp(-4096.0, 4096.0) * 1000.0).round() as i32
91 } else {
92 0
93 }
94}