Skip to main content

aura_anim_iced/timeline/
step.rs

1use super::{Hold, Parallel, Sequence, Track};
2use crate::{property::PropertySnapshot, timing::Duration};
3
4/// A timeline step that can contribute duration to a timeline.
5#[derive(Debug, Clone, PartialEq)]
6pub enum TimelineStep {
7    /// A keyframe track.
8    Track(Track),
9    /// A sequential group of steps.
10    Sequence(Sequence),
11    /// A parallel group of steps.
12    Parallel(Parallel),
13    /// A silent hold segment.
14    Hold(Hold),
15}
16
17impl TimelineStep {
18    /// Returns the finite total duration of this step, or `None` for infinite tracks.
19    #[must_use]
20    pub fn total_duration(&self) -> Option<Duration> {
21        match self {
22            Self::Track(track) => track.total_duration(),
23            Self::Sequence(sequence) => sequence.total_duration(),
24            Self::Parallel(parallel) => parallel.total_duration(),
25            Self::Hold(hold) => Some(hold.total_duration()),
26        }
27    }
28
29    /// Samples this step at local timeline `offset`.
30    #[must_use]
31    pub fn sample_at(&self, offset: impl Into<Duration>) -> Option<PropertySnapshot> {
32        match self {
33            Self::Track(track) => track.sample_at(offset),
34            Self::Sequence(sequence) => sequence.sample_at(offset),
35            Self::Parallel(parallel) => parallel.sample_at(offset),
36            Self::Hold(_) => None,
37        }
38    }
39
40    /// Samples the final visual state for this step.
41    #[must_use]
42    pub fn completion_snapshot(&self) -> Option<PropertySnapshot> {
43        match self {
44            Self::Track(track) => track.completion_snapshot(),
45            Self::Sequence(sequence) => sequence.completion_snapshot(),
46            Self::Parallel(parallel) => parallel.completion_snapshot(),
47            Self::Hold(_) => None,
48        }
49    }
50
51    pub(crate) fn sample_entry_hint(&self) -> usize {
52        match self {
53            Self::Track(track) => track.keyframes().track_count(),
54            Self::Sequence(sequence) => sequence.steps().iter().map(Self::sample_entry_hint).sum(),
55            Self::Parallel(parallel) => parallel
56                .steps()
57                .iter()
58                .map(Self::sample_entry_hint)
59                .max()
60                .unwrap_or(0),
61            Self::Hold(_) => 0,
62        }
63    }
64
65    pub(crate) fn is_hold(&self) -> bool {
66        matches!(self, Self::Hold(_))
67    }
68}
69
70impl From<Track> for TimelineStep {
71    fn from(value: Track) -> Self {
72        Self::Track(value)
73    }
74}
75
76impl From<Sequence> for TimelineStep {
77    fn from(value: Sequence) -> Self {
78        Self::Sequence(value)
79    }
80}
81
82impl From<Parallel> for TimelineStep {
83    fn from(value: Parallel) -> Self {
84        Self::Parallel(value)
85    }
86}
87
88impl From<Hold> for TimelineStep {
89    fn from(value: Hold) -> Self {
90        Self::Hold(value)
91    }
92}