use std::time::Duration;
use gpui::prelude::*;
use gpui::{Animation, AnimationElement, AnimationExt, ElementId, SharedString};
use super::Clip;
pub trait Motioned: IntoElement + Styled + Sized + 'static {
fn animate(self, id: impl Into<ElementId>, clip: impl Into<Clip>) -> AnimationElement<Self> {
let clip = clip.into();
let total = clip.total_ms();
let (span, repeats) = if total.is_finite() {
(total.max(1.0), false)
} else {
let passes = if clip.alternates() { 2.0 } else { 1.0 };
((clip.iteration_ms() * passes).max(1.0), true)
};
let mut animation = Animation::new(Duration::from_secs_f32(span / 1000.0));
if repeats {
animation = animation.repeat();
}
self.with_animation(id, animation, move |el, t| clip.sample(t * span).apply(el))
}
fn animate_when(
self,
condition: bool,
id: impl Into<ElementId>,
clip: impl Into<Clip>,
) -> AnimationElement<Self> {
let id = ElementId::NamedChild(
Box::new(id.into()),
SharedString::new_static(if condition { "on" } else { "off" }),
);
let clip = if condition {
clip.into()
} else {
Clip::default()
};
self.animate(id, clip)
}
}
impl<E: IntoElement + Styled + 'static> Motioned for E {}