macro_rules! with_animatable_props {
($cb:ident) => {
$cb! {
((P::TranslateX), (transform translate_x), (none), Transform, Transform),
((P::TranslateY), (transform translate_y), (none), Transform, Transform),
((P::Scale), (transform scale), (none), Transform, Transform),
((P::ScaleX), (transform scale_x), (none), Transform, Transform),
((P::ScaleY), (transform scale_y), (none), Transform, Transform),
((P::Rotate), (transform rotate), (none), Transform, Transform),
((P::Opacity), (prop OPACITY), (none), Opacity, Opacity),
((P::BackgroundColor), (prop BACKGROUND_COLOR), (color bg), Color, Background),
((P::BorderColor), (prop BORDER_COLOR), (color border), Color, None),
((P::Color), (prop COLOR), (color text), Color, None),
((P::BackgroundImageTint), (bg_tint), (color image_tint), Color, None),
((P::Width), (prop WIDTH), (node width), Node, None),
((P::Height), (prop HEIGHT), (node height), Node, None),
((P::MinWidth), (prop MIN_WIDTH), (node min_width), Node, None),
((P::MinHeight), (prop MIN_HEIGHT), (node min_height), Node, None),
((P::MaxWidth), (prop MAX_WIDTH), (node max_width), Node, None),
((P::MaxHeight), (prop MAX_HEIGHT), (node max_height), Node, None),
((P::Left), (prop LEFT), (node left), Node, None),
((P::Right), (prop RIGHT), (node right), Node, None),
((P::Top), (prop TOP), (node top), Node, None),
((P::Bottom), (prop BOTTOM), (node bottom), Node, None),
((P::FlexBasis), (prop FLEX_BASIS), (node flex_basis), Node, None),
((P::Gap), (prop GAP), (node_gap_both), Node, None),
((P::RowGap), (prop ROW_GAP), (node row_gap), Node, None),
((P::ColumnGap), (prop COLUMN_GAP), (node column_gap), Node, None),
((P::AspectRatio), (prop ASPECT_RATIO), (node_aspect), Node, None),
((P::BorderRadius), (prop BORDER_RADIUS), (node_radius_all), Node, BorderRadius),
((P::Transform3d(F::Perspective)), (t3d perspective num 0.0), (none), Transform3d, Transform3d),
((P::Transform3d(F::TranslateX)), (t3d translate_x num 0.0), (none), Transform3d, Transform3d),
((P::Transform3d(F::TranslateY)), (t3d translate_y num 0.0), (none), Transform3d, Transform3d),
((P::Transform3d(F::TranslateZ)), (t3d translate_z num 0.0), (none), Transform3d, Transform3d),
((P::Transform3d(F::RotateX)), (t3d rotate_x angle), (none), Transform3d, Transform3d),
((P::Transform3d(F::RotateY)), (t3d rotate_y angle), (none), Transform3d, Transform3d),
((P::Transform3d(F::RotateZ)), (t3d rotate_z angle), (none), Transform3d, Transform3d),
((P::Transform3d(F::Scale)), (t3d scale num 1.0), (none), Transform3d, Transform3d),
((P::Transform3d(F::ScaleX)), (t3d scale_x num 1.0), (none), Transform3d, Transform3d),
((P::Transform3d(F::ScaleY)), (t3d scale_y num 1.0), (none), Transform3d, Transform3d),
((P::Transform3d(F::OriginX)), (t3d_origin x), (none), Transform3d, Transform3d),
((P::Transform3d(F::OriginY)), (t3d_origin y), (none), Transform3d, Transform3d),
}
};
}
pub(crate) use with_animatable_props;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum PropStage {
Transform,
Transform3d,
Opacity,
Node,
Color,
Filter,
Backdrop,
Morph,
Ext,
Gradient,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ChannelId {
Transform,
Opacity,
Background,
BorderRadius,
Filter,
Backdrop,
Transform3d,
BackgroundGradient,
BorderGradient,
}
impl super::protocol::AnimatableProperty {
#[allow(unused_parens)]
pub(crate) fn park(&self) -> Option<ChannelId> {
use super::protocol::{AnimatableProperty as P, Transform3dField as F};
macro_rules! park_of {
(None) => {
Option::<ChannelId>::None
};
($id:ident) => {
Some(ChannelId::$id)
};
}
macro_rules! park_arms {
($(($prop:tt, $acc:tt, $write:tt, $stage:ident, $park:ident),)*) => {
match self {
$($prop => park_of!($park),)*
P::FilterParam { .. } => Some(ChannelId::Filter),
P::BackdropParam { .. } => Some(ChannelId::Backdrop),
P::MorphParam { .. } => None,
P::BackgroundGradientParam { .. } => Some(ChannelId::BackgroundGradient),
P::BorderGradientParam { .. } => Some(ChannelId::BorderGradient),
P::Ext { .. } => None,
}
};
}
with_animatable_props!(park_arms)
}
#[allow(unused_parens)]
pub(crate) fn stage(&self) -> PropStage {
use super::protocol::{AnimatableProperty as P, Transform3dField as F};
macro_rules! stage_arms {
($(($prop:tt, $acc:tt, $write:tt, $stage:ident, $park:ident),)*) => {
match self {
$($prop => PropStage::$stage,)*
P::FilterParam { .. } => PropStage::Filter,
P::BackdropParam { .. } => PropStage::Backdrop,
P::MorphParam { .. } => PropStage::Morph,
P::BackgroundGradientParam { .. } | P::BorderGradientParam { .. } => {
PropStage::Gradient
}
P::Ext { .. } => PropStage::Ext,
}
};
}
with_animatable_props!(stage_arms)
}
}
impl super::protocol::AnimatedBindings {
pub(crate) fn parked(&self, channel: ChannelId) -> bool {
self.0.keys().any(|p| p.park() == Some(channel))
}
}
#[cfg(test)]
mod tests {
use super::super::protocol::{AnimatableProperty as P, Transform3dField as F};
#[test]
fn table_rows_are_in_enum_order() {
macro_rules! rows {
($(($prop:tt, $acc:tt, $write:tt, $stage:ident, $park:ident),)*) => {
vec![$($prop),*]
};
}
let rows: Vec<P> = with_animatable_props!(rows);
assert_eq!(rows.len(), 39, "static row count");
for w in rows.windows(2) {
assert!(
w[0] < w[1],
"table rows out of enum order: {:?} listed before {:?}",
w[0],
w[1]
);
}
}
}