use gpui::prelude::*;
use gpui::{div, AnyElement, App, ElementId, Entity, IntoElement, Window};
use super::{Animator, Clip, Motion, Motioned, Sequence};
use crate::devtools::{Probed, ProbedAny};
use crate::transition::TransitionKind;
#[derive(IntoElement)]
pub struct Animated {
id: ElementId,
clip: Clip,
animator: Option<Entity<Animator>>,
child: Option<AnyElement>,
}
impl Animated {
pub fn new(id: impl Into<ElementId>) -> Self {
Animated {
id: id.into(),
clip: Clip::default(),
animator: None,
child: None,
}
}
pub fn motion(mut self, motion: Motion) -> Self {
self.clip = Clip::Motion(motion);
self
}
pub fn sequence(mut self, sequence: Sequence) -> Self {
self.clip = Clip::Sequence(sequence);
self
}
pub fn clip(mut self, clip: impl Into<Clip>) -> Self {
self.clip = clip.into();
self
}
pub fn enter(self, kind: TransitionKind) -> Self {
self.motion(Motion::enter(kind))
}
pub fn animator(mut self, animator: &Entity<Animator>) -> Self {
self.animator = Some(animator.clone());
self
}
pub fn child(mut self, child: impl IntoElement) -> Self {
self.child = Some(child.into_any_element());
self
}
}
impl RenderOnce for Animated {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
let child = self.child.unwrap_or_else(|| div().into_any_element());
if let Some(animator) = self.animator {
let frame = animator.read(cx).frame(window);
let progress = frame.progress;
return frame
.apply(div())
.child(child)
.probe("Animated")
.attr_with("progress", || format!("{progress:.2}"))
.into_any_element();
}
div()
.child(child)
.animate(self.id, self.clip)
.probe_any("Animated")
.into_any_element()
}
}