use inset_animation::Animatable;
use inset_foundation::App;
use inset_painting::{Alignment, AlignmentGeometry, FractionalOffset};
#[derive(Clone, Debug)]
pub struct FractionalOffsetTween {
pub begin: Option<FractionalOffset>,
pub end: Option<FractionalOffset>,
}
impl FractionalOffsetTween {
pub fn new(
begin: Option<FractionalOffset>,
end: Option<FractionalOffset>,
) -> FractionalOffsetTween {
FractionalOffsetTween { begin, end }
}
pub fn lerp(&self, t: f64) -> Option<FractionalOffset> {
FractionalOffset::lerp(self.begin, self.end, t)
}
}
impl Animatable<Option<FractionalOffset>> for FractionalOffsetTween {
fn transform(&self, _app: &App, t: f64) -> Option<FractionalOffset> {
if t == 0.0 {
return self.begin;
}
if t == 1.0 {
return self.end;
}
self.lerp(t)
}
}
#[derive(Clone, Debug)]
pub struct AlignmentTween {
pub begin: Option<Alignment>,
pub end: Option<Alignment>,
}
impl AlignmentTween {
pub fn new(begin: Option<Alignment>, end: Option<Alignment>) -> AlignmentTween {
AlignmentTween { begin, end }
}
pub fn lerp(&self, t: f64) -> Alignment {
Alignment::lerp(self.begin, self.end, t)
.expect("AlignmentTween.begin or end must be set before use")
}
}
impl Animatable<Alignment> for AlignmentTween {
fn transform(&self, _app: &App, t: f64) -> Alignment {
if t == 0.0 {
return self.begin.expect("Tween.begin must be set before use");
}
if t == 1.0 {
return self.end.expect("Tween.end must be set before use");
}
self.lerp(t)
}
}
#[derive(Clone, Debug)]
pub struct AlignmentGeometryTween {
pub begin: Option<AlignmentGeometry>,
pub end: Option<AlignmentGeometry>,
}
impl AlignmentGeometryTween {
pub fn new(
begin: Option<AlignmentGeometry>,
end: Option<AlignmentGeometry>,
) -> AlignmentGeometryTween {
AlignmentGeometryTween { begin, end }
}
pub fn lerp(&self, t: f64) -> Option<AlignmentGeometry> {
AlignmentGeometry::lerp(self.begin, self.end, t)
}
}
impl Animatable<Option<AlignmentGeometry>> for AlignmentGeometryTween {
fn transform(&self, _app: &App, t: f64) -> Option<AlignmentGeometry> {
if t == 0.0 {
return self.begin;
}
if t == 1.0 {
return self.end;
}
self.lerp(t)
}
}
#[cfg(test)]
mod tests {
use inset_foundation::AppCell;
use inset_painting::{AlignmentDirectional, TextDirection};
use super::*;
#[test]
fn an_alignment_tween_walks_between_the_corners() {
let cell = AppCell::new();
let app = cell.borrow();
let tween = AlignmentTween::new(Some(Alignment::TOP_LEFT), Some(Alignment::BOTTOM_LEFT));
assert_eq!(tween.transform(&app, 0.0), Alignment::TOP_LEFT);
assert_eq!(tween.transform(&app, 0.5), Alignment::CENTER_LEFT);
assert_eq!(tween.transform(&app, 1.0), Alignment::BOTTOM_LEFT);
}
#[test]
fn an_alignment_geometry_tween_crosses_the_two_kinds() {
let cell = AppCell::new();
let app = cell.borrow();
let tween = AlignmentGeometryTween::new(
Some(Alignment::CENTER_RIGHT.into()),
Some(AlignmentDirectional::CENTER_END.into()),
);
let halfway = tween.transform(&app, 0.5).expect("both ends are set");
assert_eq!(
halfway.resolve(Some(TextDirection::Ltr)),
Alignment::CENTER_RIGHT
);
assert_eq!(halfway.resolve(Some(TextDirection::Rtl)), Alignment::CENTER);
}
#[test]
fn a_fractional_offset_tween_walks_between_the_corners() {
let cell = AppCell::new();
let app = cell.borrow();
let tween = FractionalOffsetTween::new(
Some(FractionalOffset::new(0.0, 0.0)),
Some(FractionalOffset::new(1.0, 1.0)),
);
assert_eq!(
tween.transform(&app, 0.25),
Some(FractionalOffset::new(0.25, 0.25))
);
}
}