1use super::{inspector_metadata, GraphicsLayer, Modifier};
2use crate::modifier_nodes::{GraphicsLayerElement, LazyGraphicsLayerElement};
3use cranpose_ui_graphics::{
4 gradient_cut_mask_effect, gradient_fade_dst_out_effect, rounded_alpha_mask_effect, BlendMode,
5 Color, ColorFilter, CompositingStrategy, GradientCutMaskSpec, GradientFadeMaskSpec, LayerShape,
6 RenderEffect, RuntimeShader, TransformOrigin,
7};
8use std::rc::Rc;
9
10impl Modifier {
11 pub fn graphics_layer(self, layer: impl Fn() -> GraphicsLayer + 'static) -> Self {
19 let modifier = Self::with_element(LazyGraphicsLayerElement::new(Rc::new(layer)))
20 .with_inspector_metadata(inspector_metadata("graphicsLayer", |info| {
21 info.add_property("lazy", "true");
22 }));
23 self.then(modifier)
24 }
25
26 pub fn graphics_layer_value(self, layer: GraphicsLayer) -> Self {
31 let inspector_values = layer.clone();
32 let modifier = Self::with_element(GraphicsLayerElement::new(layer))
33 .with_inspector_metadata(inspector_metadata("graphicsLayer", move |info| {
34 info.add_property("alpha", inspector_values.alpha.to_string());
35 info.add_property("scale", inspector_values.scale.to_string());
36 info.add_property("scaleX", inspector_values.scale_x.to_string());
37 info.add_property("scaleY", inspector_values.scale_y.to_string());
38 info.add_property("rotationX", inspector_values.rotation_x.to_string());
39 info.add_property("rotationY", inspector_values.rotation_y.to_string());
40 info.add_property("rotationZ", inspector_values.rotation_z.to_string());
41 info.add_property(
42 "cameraDistance",
43 inspector_values.camera_distance.to_string(),
44 );
45 info.add_property(
46 "transformOrigin",
47 format!(
48 "{},{}",
49 inspector_values.transform_origin.pivot_fraction_x,
50 inspector_values.transform_origin.pivot_fraction_y
51 ),
52 );
53 info.add_property("translationX", inspector_values.translation_x.to_string());
54 info.add_property("translationY", inspector_values.translation_y.to_string());
55 info.add_property(
56 "shadowElevation",
57 inspector_values.shadow_elevation.to_string(),
58 );
59 info.add_property("shape", format!("{:?}", inspector_values.shape));
60 info.add_property("clip", inspector_values.clip.to_string());
61 info.add_property(
62 "ambientShadowColor",
63 format!("{:?}", inspector_values.ambient_shadow_color),
64 );
65 info.add_property(
66 "spotShadowColor",
67 format!("{:?}", inspector_values.spot_shadow_color),
68 );
69 info.add_property(
70 "compositingStrategy",
71 format!("{:?}", inspector_values.compositing_strategy),
72 );
73 info.add_property("blendMode", format!("{:?}", inspector_values.blend_mode));
74 if let Some(filter) = inspector_values.color_filter {
75 info.add_property("colorFilter", format!("{filter:?}"));
76 }
77 }));
78 self.then(modifier)
79 }
80
81 #[allow(clippy::too_many_arguments)]
86 pub fn graphics_layer_params(
87 self,
88 scale_x: f32,
89 scale_y: f32,
90 alpha: f32,
91 translation_x: f32,
92 translation_y: f32,
93 shadow_elevation: f32,
94 rotation_x: f32,
95 rotation_y: f32,
96 rotation_z: f32,
97 camera_distance: f32,
98 transform_origin: TransformOrigin,
99 shape: LayerShape,
100 clip: bool,
101 render_effect: Option<RenderEffect>,
102 ambient_shadow_color: Color,
103 spot_shadow_color: Color,
104 compositing_strategy: CompositingStrategy,
105 blend_mode: BlendMode,
106 color_filter: Option<ColorFilter>,
107 ) -> Self {
108 self.graphics_layer_value(GraphicsLayer {
109 alpha,
110 scale: 1.0,
111 scale_x,
112 scale_y,
113 rotation_x,
114 rotation_y,
115 rotation_z,
116 camera_distance,
117 transform_origin,
118 translation_x,
119 translation_y,
120 shadow_elevation,
121 ambient_shadow_color,
122 spot_shadow_color,
123 shape,
124 clip,
125 compositing_strategy,
126 blend_mode,
127 color_filter,
128 render_effect,
129 backdrop_effect: None,
130 })
131 }
132
133 pub fn graphics_layer_block(self, configure: impl Fn(&mut GraphicsLayer) + 'static) -> Self {
138 self.graphics_layer(move || {
139 let mut layer = GraphicsLayer::default();
140 configure(&mut layer);
141 layer
142 })
143 }
144
145 pub fn shadow(self, elevation: f32) -> Self {
151 self.shadow_with(
152 elevation,
153 LayerShape::Rectangle,
154 elevation > 0.0,
155 Color::BLACK,
156 Color::BLACK,
157 )
158 }
159
160 pub fn shadow_with(
162 self,
163 elevation: f32,
164 shape: LayerShape,
165 clip: bool,
166 ambient_color: Color,
167 spot_color: Color,
168 ) -> Self {
169 let clamped_elevation = elevation.max(0.0);
170 if clamped_elevation == 0.0 && !clip {
171 return self;
172 }
173
174 self.graphics_layer_value(GraphicsLayer {
175 shadow_elevation: clamped_elevation,
176 ambient_shadow_color: ambient_color,
177 spot_shadow_color: spot_color,
178 shape,
179 clip,
180 ..Default::default()
181 })
182 }
183
184 pub fn backdrop_effect(self, effect: RenderEffect) -> Self {
186 let layer = GraphicsLayer {
187 backdrop_effect: Some(effect),
188 ..Default::default()
189 };
190 let modifier = Self::with_element(GraphicsLayerElement::new(layer))
191 .with_inspector_metadata(inspector_metadata("backdropEffect", |info| {
192 info.add_property("enabled", "true");
193 }));
194 self.then(modifier)
195 }
196
197 pub fn shader_background(self, shader: RuntimeShader) -> Self {
199 self.backdrop_effect(RenderEffect::runtime_shader(shader))
200 }
201
202 pub fn color_filter(self, filter: ColorFilter) -> Self {
206 let layer = GraphicsLayer {
207 color_filter: Some(filter),
208 ..Default::default()
209 };
210 let modifier = Self::with_element(GraphicsLayerElement::new(layer))
211 .with_inspector_metadata(inspector_metadata("colorFilter", |info| {
212 info.add_property("enabled", "true");
213 }));
214 self.then(modifier)
215 }
216
217 pub fn tint(self, tint: Color) -> Self {
219 self.color_filter(ColorFilter::tint(tint))
220 }
221
222 pub fn compositing_strategy(self, strategy: CompositingStrategy) -> Self {
224 self.graphics_layer_value(GraphicsLayer {
225 compositing_strategy: strategy,
226 ..Default::default()
227 })
228 }
229
230 pub fn layer_blend_mode(self, blend_mode: BlendMode) -> Self {
235 self.graphics_layer_value(GraphicsLayer {
236 blend_mode,
237 ..Default::default()
238 })
239 }
240
241 pub fn gradient_cut_mask(
245 self,
246 area_width: f32,
247 area_height: f32,
248 spec: GradientCutMaskSpec,
249 ) -> Self {
250 let layer = GraphicsLayer {
251 render_effect: Some(gradient_cut_mask_effect(&spec, area_width, area_height)),
252 ..Default::default()
253 };
254 self.graphics_layer_value(layer)
255 }
256
257 pub fn rounded_alpha_mask(
262 self,
263 area_width: f32,
264 area_height: f32,
265 corner_radius: f32,
266 edge_feather: f32,
267 ) -> Self {
268 let layer = GraphicsLayer {
269 render_effect: Some(rounded_alpha_mask_effect(
270 area_width,
271 area_height,
272 corner_radius,
273 edge_feather,
274 )),
275 ..Default::default()
276 };
277 self.graphics_layer_value(layer)
278 }
279
280 pub fn gradient_fade_dst_out(
285 self,
286 area_width: f32,
287 area_height: f32,
288 spec: GradientFadeMaskSpec,
289 ) -> Self {
290 let layer = GraphicsLayer {
291 render_effect: Some(gradient_fade_dst_out_effect(&spec, area_width, area_height)),
292 ..Default::default()
293 };
294 self.graphics_layer_value(layer)
295 }
296}