use std::time::Duration;
use crate::animation::Easing;
use crate::style::Color;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ExitAnimation {
pub(crate) duration: Duration,
pub(crate) easing: Option<Easing>,
pub(crate) opacity: Option<f32>,
pub(crate) fg: Option<Color>,
pub(crate) bg: Option<Color>,
pub(crate) offset: Option<(i16, i16)>,
pub(crate) collapse: bool,
}
impl ExitAnimation {
pub const fn new(duration_ms: u64) -> Self {
Self {
duration: Duration::from_millis(duration_ms),
easing: None,
opacity: Some(0.0),
fg: None,
bg: None,
offset: None,
collapse: false,
}
}
pub const fn slide(duration_ms: u64, dx: i16, dy: i16) -> Self {
let mut exit = Self::new(duration_ms);
exit.offset = Some((dx, dy));
exit
}
pub const fn collapse(duration_ms: u64) -> Self {
let mut exit = Self::new(duration_ms);
exit.collapse = true;
exit
}
pub const fn opacity(mut self, opacity: f32) -> Self {
self.opacity = Some(opacity);
self
}
pub const fn keep_opacity(mut self) -> Self {
self.opacity = None;
self
}
pub const fn fg(mut self, color: Color) -> Self {
self.fg = Some(color);
self
}
pub const fn bg(mut self, color: Color) -> Self {
self.bg = Some(color);
self
}
pub const fn offset(mut self, dx: i16, dy: i16) -> Self {
self.offset = Some((dx, dy));
self
}
pub const fn easing(mut self, easing: Easing) -> Self {
self.easing = Some(easing);
self
}
pub const fn with_collapse(mut self, collapse: bool) -> Self {
self.collapse = collapse;
self
}
pub const fn duration(&self) -> Duration {
self.duration
}
}
impl From<u64> for ExitAnimation {
fn from(duration_ms: u64) -> Self {
Self::new(duration_ms)
}
}
impl From<Duration> for ExitAnimation {
fn from(duration: Duration) -> Self {
Self {
duration,
..Self::new(0)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_bare_duration_shorthand_is_a_fade() {
assert_eq!(ExitAnimation::from(200), ExitAnimation::new(200));
assert_eq!(ExitAnimation::new(200).opacity, Some(0.0));
assert_eq!(
ExitAnimation::new(200).duration(),
Duration::from_millis(200)
);
}
#[test]
fn an_exit_can_drop_the_fade_and_move_instead() {
let exit = ExitAnimation::slide(180, 0, -1).keep_opacity();
assert_eq!(exit.opacity, None);
assert_eq!(exit.offset, Some((0, -1)));
}
#[test]
fn collapse_is_independent_of_every_other_property() {
let exit = ExitAnimation::slide(120, 2, 0).with_collapse(true);
assert!(exit.collapse);
assert_eq!(exit.offset, Some((2, 0)));
assert_eq!(exit.opacity, Some(0.0));
assert!(!ExitAnimation::new(120).collapse);
}
}