use bevy::prelude::*;
use crate::animations::build_ui_transform;
use crate::filters::{BackdropInput, FilterChain, FilterInput, MorphInput, MorphState};
use crate::layer::LayerGroupAlpha;
use crate::layer::transform3d::LayerTransform3d;
use crate::protocol::animatable::AnimatableField;
use crate::protocol::units::Angle;
use crate::style::Style;
use crate::style::props::*;
use crate::style::{Writer, WriterCtx, owns};
use crate::transition::{
ScrollTransitionInput, ScrollTransitionState, TransitionInput, TransitionState,
};
use crate::ui_map::set_if_neq_or_insert;
use crate::ui_map::{length_to_val, remove_unless_fresh};
pub static GROUP_ALPHA_WRITER: Writer = Writer {
reads: &[&OPACITY],
attrs: &[],
writes: &[owns::<LayerGroupAlpha>],
apply: |ctx, s, ec| {
if !ctx.promoted {
return;
}
let alpha = s.get(&OPACITY).static_val().unwrap_or(1.0);
ec.queue(set_if_neq_or_insert(LayerGroupAlpha(alpha)));
},
};
pub static TRANSFORM_WRITER: Writer = Writer {
reads: &[&TRANSFORM],
attrs: &[],
writes: &[owns::<UiTransform>],
apply: |_, s, ec| {
if let Some(t) = s.get(&TRANSFORM) {
ec.insert(build_ui_transform(
t.translate_x.static_val().map(length_to_val),
t.translate_y.static_val().map(length_to_val),
t.scale.static_val(),
t.scale_x.static_val(),
t.scale_y.static_val(),
t.rotate.static_val().map(Angle::radians),
));
}
},
};
pub static TRANSFORM3D_WRITER: Writer = Writer {
reads: &[&TRANSFORM3D],
attrs: &[],
writes: &[owns::<LayerTransform3d>],
apply: |_, s, ec| {
if let Some(t) = s.get(&TRANSFORM3D).cloned() {
ec.queue(set_if_neq_or_insert(LayerTransform3d(t)));
}
},
};
pub static FILTER_WRITER: Writer = Writer {
reads: &[&FILTER],
attrs: &[],
writes: &[owns::<FilterInput>],
apply: |ctx, s, ec| match s.get(&FILTER).filter(|c| !c.0.is_empty()) {
Some(chain) => {
ec.insert(FilterInput(chain.clone()));
}
None => remove_unless_fresh::<FilterInput>(ec, ctx.fresh),
},
};
pub static BACKDROP_FILTER_WRITER: Writer = Writer {
reads: &[&BACKDROP_FILTER],
attrs: &[],
writes: &[owns::<BackdropInput>],
apply: |ctx, s, ec| match s.get(&BACKDROP_FILTER).filter(|c| !c.0.is_empty()) {
Some(chain) => {
ec.insert(BackdropInput(chain.clone()));
}
None => remove_unless_fresh::<BackdropInput>(ec, ctx.fresh),
},
};
pub static MORPH_FILTER_WRITER: Writer = Writer {
reads: &[&MORPH_FILTER],
attrs: &[],
writes: &[owns::<MorphInput>],
apply: |ctx, s, ec| match s.get(&MORPH_FILTER) {
Some(morph) => {
ec.insert(MorphInput {
chain: FilterChain(vec![morph.filter.clone()]),
key: morph.key.clone(),
});
}
None => remove_unless_fresh::<(MorphInput, MorphState)>(ec, ctx.fresh),
},
};
pub static TRANSITION_WRITER: Writer = Writer {
reads: &[
&TRANSITION,
&MORPH_FILTER,
&TRANSFORM,
&OPACITY,
&BACKGROUND_COLOR,
&WIDTH,
&HEIGHT,
&MAX_WIDTH,
&MAX_HEIGHT,
&BORDER_RADIUS,
&TRANSFORM3D,
],
attrs: &[],
writes: &[owns::<TransitionInput>, owns::<TransitionState>],
apply: |ctx, s, ec| crate::transition::apply_transition(ec, Some(s), ctx.fresh),
};
pub static SCROLL_TRANSITION_WRITER: Writer = Writer {
reads: &[&TRANSITION],
attrs: &[],
writes: &[owns::<ScrollTransitionInput>, owns::<ScrollTransitionState>],
apply: apply_scroll_transition,
};
fn apply_scroll_transition(ctx: &WriterCtx, s: &Style, ec: &mut EntityCommands) {
match s.get(&TRANSITION).and_then(|t| t.scroll.as_ref()) {
Some(spec) if ctx.fresh => {
ec.insert((
ScrollTransitionInput(spec.clone()),
ScrollTransitionState::default(),
));
}
Some(spec) => {
ec.insert(ScrollTransitionInput(spec.clone()));
ec.insert_if_new(ScrollTransitionState::default());
}
None if ctx.fresh => {}
None => {
ec.remove::<ScrollTransitionInput>();
ec.remove::<ScrollTransitionState>();
}
}
}