use super::{inspector_metadata, GraphicsLayer, Modifier};
use crate::modifier_nodes::{GraphicsLayerElement, LazyGraphicsLayerElement};
use cranpose_ui_graphics::{
gradient_cut_mask_effect, gradient_fade_dst_out_effect, rounded_alpha_mask_effect, BlendMode,
Color, ColorFilter, CompositingStrategy, GradientCutMaskSpec, GradientFadeMaskSpec, LayerShape,
RenderEffect, RuntimeShader, TransformOrigin,
};
use std::rc::Rc;
impl Modifier {
pub fn graphics_layer(self, layer: impl Fn() -> GraphicsLayer + 'static) -> Self {
let modifier = Self::with_element(LazyGraphicsLayerElement::new(Rc::new(layer)))
.with_inspector_metadata(inspector_metadata("graphicsLayer", |info| {
info.add_property("lazy", "true");
}));
self.then(modifier)
}
pub fn graphics_layer_value(self, layer: GraphicsLayer) -> Self {
let inspector_values = layer.clone();
let modifier = Self::with_element(GraphicsLayerElement::new(layer))
.with_inspector_metadata(inspector_metadata("graphicsLayer", move |info| {
info.add_property("alpha", inspector_values.alpha.to_string());
info.add_property("scale", inspector_values.scale.to_string());
info.add_property("scaleX", inspector_values.scale_x.to_string());
info.add_property("scaleY", inspector_values.scale_y.to_string());
info.add_property("rotationX", inspector_values.rotation_x.to_string());
info.add_property("rotationY", inspector_values.rotation_y.to_string());
info.add_property("rotationZ", inspector_values.rotation_z.to_string());
info.add_property(
"cameraDistance",
inspector_values.camera_distance.to_string(),
);
info.add_property(
"transformOrigin",
format!(
"{},{}",
inspector_values.transform_origin.pivot_fraction_x,
inspector_values.transform_origin.pivot_fraction_y
),
);
info.add_property("translationX", inspector_values.translation_x.to_string());
info.add_property("translationY", inspector_values.translation_y.to_string());
info.add_property(
"shadowElevation",
inspector_values.shadow_elevation.to_string(),
);
info.add_property("shape", format!("{:?}", inspector_values.shape));
info.add_property("clip", inspector_values.clip.to_string());
info.add_property(
"ambientShadowColor",
format!("{:?}", inspector_values.ambient_shadow_color),
);
info.add_property(
"spotShadowColor",
format!("{:?}", inspector_values.spot_shadow_color),
);
info.add_property(
"compositingStrategy",
format!("{:?}", inspector_values.compositing_strategy),
);
info.add_property("blendMode", format!("{:?}", inspector_values.blend_mode));
if let Some(filter) = inspector_values.color_filter {
info.add_property("colorFilter", format!("{filter:?}"));
}
}));
self.then(modifier)
}
#[allow(clippy::too_many_arguments)]
pub fn graphics_layer_params(
self,
scale_x: f32,
scale_y: f32,
alpha: f32,
translation_x: f32,
translation_y: f32,
shadow_elevation: f32,
rotation_x: f32,
rotation_y: f32,
rotation_z: f32,
camera_distance: f32,
transform_origin: TransformOrigin,
shape: LayerShape,
clip: bool,
render_effect: Option<RenderEffect>,
ambient_shadow_color: Color,
spot_shadow_color: Color,
compositing_strategy: CompositingStrategy,
blend_mode: BlendMode,
color_filter: Option<ColorFilter>,
) -> Self {
self.graphics_layer_value(GraphicsLayer {
alpha,
scale: 1.0,
scale_x,
scale_y,
rotation_x,
rotation_y,
rotation_z,
camera_distance,
transform_origin,
translation_x,
translation_y,
shadow_elevation,
ambient_shadow_color,
spot_shadow_color,
shape,
clip,
compositing_strategy,
blend_mode,
color_filter,
render_effect,
backdrop_effect: None,
})
}
pub fn graphics_layer_block(self, configure: impl Fn(&mut GraphicsLayer) + 'static) -> Self {
self.graphics_layer(move || {
let mut layer = GraphicsLayer::default();
configure(&mut layer);
layer
})
}
pub fn shadow(self, elevation: f32) -> Self {
self.shadow_with(
elevation,
LayerShape::Rectangle,
elevation > 0.0,
Color::BLACK,
Color::BLACK,
)
}
pub fn shadow_with(
self,
elevation: f32,
shape: LayerShape,
clip: bool,
ambient_color: Color,
spot_color: Color,
) -> Self {
let clamped_elevation = elevation.max(0.0);
if clamped_elevation == 0.0 && !clip {
return self;
}
self.graphics_layer_value(GraphicsLayer {
shadow_elevation: clamped_elevation,
ambient_shadow_color: ambient_color,
spot_shadow_color: spot_color,
shape,
clip,
..Default::default()
})
}
pub fn backdrop_effect(self, effect: RenderEffect) -> Self {
let layer = GraphicsLayer {
backdrop_effect: Some(effect),
..Default::default()
};
let modifier = Self::with_element(GraphicsLayerElement::new(layer))
.with_inspector_metadata(inspector_metadata("backdropEffect", |info| {
info.add_property("enabled", "true");
}));
self.then(modifier)
}
pub fn shader_background(self, shader: RuntimeShader) -> Self {
self.backdrop_effect(RenderEffect::runtime_shader(shader))
}
pub fn color_filter(self, filter: ColorFilter) -> Self {
let layer = GraphicsLayer {
color_filter: Some(filter),
..Default::default()
};
let modifier = Self::with_element(GraphicsLayerElement::new(layer))
.with_inspector_metadata(inspector_metadata("colorFilter", |info| {
info.add_property("enabled", "true");
}));
self.then(modifier)
}
pub fn tint(self, tint: Color) -> Self {
self.color_filter(ColorFilter::tint(tint))
}
pub fn compositing_strategy(self, strategy: CompositingStrategy) -> Self {
self.graphics_layer_value(GraphicsLayer {
compositing_strategy: strategy,
..Default::default()
})
}
pub fn layer_blend_mode(self, blend_mode: BlendMode) -> Self {
self.graphics_layer_value(GraphicsLayer {
blend_mode,
..Default::default()
})
}
pub fn gradient_cut_mask(
self,
area_width: f32,
area_height: f32,
spec: GradientCutMaskSpec,
) -> Self {
let layer = GraphicsLayer {
render_effect: Some(gradient_cut_mask_effect(&spec, area_width, area_height)),
..Default::default()
};
self.graphics_layer_value(layer)
}
pub fn rounded_alpha_mask(
self,
area_width: f32,
area_height: f32,
corner_radius: f32,
edge_feather: f32,
) -> Self {
let layer = GraphicsLayer {
render_effect: Some(rounded_alpha_mask_effect(
area_width,
area_height,
corner_radius,
edge_feather,
)),
..Default::default()
};
self.graphics_layer_value(layer)
}
pub fn gradient_fade_dst_out(
self,
area_width: f32,
area_height: f32,
spec: GradientFadeMaskSpec,
) -> Self {
let layer = GraphicsLayer {
render_effect: Some(gradient_fade_dst_out_effect(&spec, area_width, area_height)),
..Default::default()
};
self.graphics_layer_value(layer)
}
}