use iced_core::{theme::palette, Theme};
use std::sync::Arc;
pub trait Animate: Clone + PartialEq {
fn components() -> usize;
fn update(&mut self, components: &mut impl Iterator<Item = f32>);
fn distance_to(&self, end: &Self) -> Vec<f32>;
fn lerp(&mut self, start: &Self, end: &Self, progress: f32);
}
impl Animate for f32 {
fn components() -> usize {
1
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
*self += components.next().unwrap();
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
vec![self - end]
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
*self = start + (end - start) * progress
}
}
impl Animate for iced_core::Point<f32> {
fn components() -> usize {
2
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.x += components.next().unwrap();
self.y += components.next().unwrap();
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[self.x.distance_to(&end.x), self.y.distance_to(&end.y)].concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.x.lerp(&start.x, &end.x, progress);
self.y.lerp(&start.y, &end.y, progress);
}
}
impl Animate for iced_core::Color {
fn components() -> usize {
4
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.r = (self.r + components.next().unwrap()).clamp(0.0, 1.0);
self.g = (self.g + components.next().unwrap()).clamp(0.0, 1.0);
self.b = (self.b + components.next().unwrap()).clamp(0.0, 1.0);
self.a = (self.a + components.next().unwrap()).clamp(0.0, 1.0);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.r.distance_to(&end.r),
self.g.distance_to(&end.g),
self.b.distance_to(&end.b),
self.a.distance_to(&end.a),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.r.lerp(&start.r, &end.r, progress);
self.g.lerp(&start.g, &end.g, progress);
self.b.lerp(&start.b, &end.b, progress);
self.a.lerp(&start.a, &end.a, progress);
}
}
impl Animate for iced_core::theme::Palette {
fn components() -> usize {
6 * iced_core::Color::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.background.update(components);
self.text.update(components);
self.primary.update(components);
self.success.update(components);
self.warning.update(components);
self.danger.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.background.distance_to(&end.background),
self.text.distance_to(&end.text),
self.primary.distance_to(&end.primary),
self.success.distance_to(&end.success),
self.warning.distance_to(&end.warning),
self.danger.distance_to(&end.danger),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.background
.lerp(&start.background, &end.background, progress);
self.text.lerp(&start.text, &end.text, progress);
self.primary.lerp(&start.primary, &end.primary, progress);
self.success.lerp(&start.success, &end.success, progress);
self.warning.lerp(&start.warning, &end.warning, progress);
self.danger.lerp(&start.danger, &end.danger, progress);
}
}
impl Animate for Theme {
fn components() -> usize {
iced_core::theme::Palette::components() + iced_core::theme::palette::Extended::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
let mut palette = self.palette();
palette.update(components);
let mut extended = *self.extended_palette();
extended.update(components);
*self = Theme::Custom(Arc::new(iced_core::theme::Custom::with_fn(
"Animating Theme".to_owned(),
palette,
move |_| extended,
)))
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.palette().distance_to(&end.palette()),
self.extended_palette().distance_to(end.extended_palette()),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
let mut palette = start.palette();
palette.lerp(&start.palette(), &end.palette(), progress);
let mut extended = *start.extended_palette();
extended.lerp(start.extended_palette(), end.extended_palette(), progress);
*self = Theme::Custom(Arc::new(iced_core::theme::Custom::with_fn(
"Animating Theme".to_owned(),
palette,
move |_| extended,
)));
}
}
impl Animate for palette::Pair {
fn components() -> usize {
2 * iced_core::Color::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.color.update(components);
self.text.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.color.distance_to(&end.color),
self.text.distance_to(&end.text),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.color.lerp(&start.color, &end.color, progress);
self.text.lerp(&start.text, &end.text, progress);
}
}
impl Animate for palette::Primary {
fn components() -> usize {
3 * palette::Pair::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.strong.update(components);
self.base.update(components);
self.weak.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.strong.distance_to(&end.strong),
self.base.distance_to(&end.base),
self.weak.distance_to(&end.weak),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.strong.lerp(&start.strong, &end.strong, progress);
self.base.lerp(&start.base, &end.base, progress);
self.weak.lerp(&start.weak, &end.weak, progress);
}
}
impl Animate for palette::Secondary {
fn components() -> usize {
3 * palette::Pair::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.strong.update(components);
self.base.update(components);
self.weak.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.strong.distance_to(&end.strong),
self.base.distance_to(&end.base),
self.weak.distance_to(&end.weak),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.strong.lerp(&start.strong, &end.strong, progress);
self.base.lerp(&start.base, &end.base, progress);
self.weak.lerp(&start.weak, &end.weak, progress);
}
}
impl Animate for palette::Success {
fn components() -> usize {
3 * palette::Pair::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.strong.update(components);
self.base.update(components);
self.weak.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.strong.distance_to(&end.strong),
self.base.distance_to(&end.base),
self.weak.distance_to(&end.weak),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.strong.lerp(&start.strong, &end.strong, progress);
self.base.lerp(&start.base, &end.base, progress);
self.weak.lerp(&start.weak, &end.weak, progress);
}
}
impl Animate for palette::Warning {
fn components() -> usize {
3 * palette::Pair::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.strong.update(components);
self.base.update(components);
self.weak.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.strong.distance_to(&end.strong),
self.base.distance_to(&end.base),
self.weak.distance_to(&end.weak),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.strong.lerp(&start.strong, &end.strong, progress);
self.base.lerp(&start.base, &end.base, progress);
self.weak.lerp(&start.weak, &end.weak, progress);
}
}
impl Animate for palette::Danger {
fn components() -> usize {
3 * palette::Pair::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.strong.update(components);
self.base.update(components);
self.weak.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.strong.distance_to(&end.strong),
self.base.distance_to(&end.base),
self.weak.distance_to(&end.weak),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.strong.lerp(&start.strong, &end.strong, progress);
self.base.lerp(&start.base, &end.base, progress);
self.weak.lerp(&start.weak, &end.weak, progress);
}
}
impl Animate for palette::Background {
fn components() -> usize {
8 * palette::Pair::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.strongest.update(components);
self.stronger.update(components);
self.strong.update(components);
self.base.update(components);
self.neutral.update(components);
self.weak.update(components);
self.weaker.update(components);
self.weakest.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.strongest.distance_to(&end.strongest),
self.stronger.distance_to(&end.stronger),
self.strong.distance_to(&end.strong),
self.base.distance_to(&end.base),
self.neutral.distance_to(&end.neutral),
self.weak.distance_to(&end.weak),
self.weaker.distance_to(&end.weaker),
self.weakest.distance_to(&end.weakest),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.strongest
.lerp(&start.strongest, &end.strongest, progress);
self.stronger.lerp(&start.stronger, &end.stronger, progress);
self.strong.lerp(&start.strong, &end.strong, progress);
self.base.lerp(&start.base, &end.base, progress);
self.neutral.lerp(&start.neutral, &end.neutral, progress);
self.weak.lerp(&start.weak, &end.weak, progress);
self.weaker.lerp(&start.weaker, &end.weaker, progress);
self.weakest.lerp(&start.weakest, &end.weakest, progress);
}
}
impl Animate for palette::Extended {
fn components() -> usize {
palette::Background::components()
+ palette::Primary::components()
+ palette::Secondary::components()
+ palette::Success::components()
+ palette::Warning::components()
+ palette::Danger::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.primary.update(components);
self.secondary.update(components);
self.success.update(components);
self.warning.update(components);
self.danger.update(components);
self.background.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.primary.distance_to(&end.primary),
self.secondary.distance_to(&end.secondary),
self.success.distance_to(&end.success),
self.warning.distance_to(&end.warning),
self.danger.distance_to(&end.danger),
self.background.distance_to(&end.background),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.is_dark = if progress >= 0.5 {
end.is_dark
} else {
start.is_dark
};
self.primary.lerp(&start.primary, &end.primary, progress);
self.secondary
.lerp(&start.secondary, &end.secondary, progress);
self.success.lerp(&start.success, &end.success, progress);
self.warning.lerp(&start.warning, &end.warning, progress);
self.danger.lerp(&start.danger, &end.danger, progress);
self.background
.lerp(&start.background, &end.background, progress);
}
}
impl<T> Animate for Option<T>
where
T: Animate,
{
fn components() -> usize {
T::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
if let Some(inner) = self {
inner.update(components);
} else {
components.nth(T::components() - 1);
}
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
match (self, end) {
(Some(current), Some(end)) => current.distance_to(end),
_ => vec![0.0; T::components()],
}
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
if let (Some(start), Some(end)) = (start, end) {
if let Some(value) = self.as_mut() {
value.lerp(start, end, progress);
}
}
}
}
impl Animate for iced_core::border::Radius {
fn components() -> usize {
4
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.top_left.distance_to(&end.top_left),
self.top_right.distance_to(&end.top_right),
self.bottom_left.distance_to(&end.bottom_left),
self.bottom_right.distance_to(&end.bottom_right),
]
.concat()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.top_left.update(components);
self.top_right.update(components);
self.bottom_left.update(components);
self.bottom_right.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.top_left.lerp(&start.top_left, &end.top_left, progress);
self.top_right
.lerp(&start.top_right, &end.top_right, progress);
self.bottom_left
.lerp(&start.bottom_left, &end.bottom_left, progress);
self.bottom_right
.lerp(&start.bottom_right, &end.bottom_right, progress);
}
}
impl Animate for iced_core::Border {
fn components() -> usize {
f32::components() + iced_core::Color::components() + iced_core::border::Radius::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.width.distance_to(&end.width),
self.color.distance_to(&end.color),
self.radius.distance_to(&end.radius),
]
.concat()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.width.update(components);
self.color.update(components);
self.radius.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.width.lerp(&start.width, &end.width, progress);
self.color.lerp(&start.color, &end.color, progress);
self.radius.lerp(&start.radius, &end.radius, progress);
}
}
impl<T> Animate for iced_core::Vector<T>
where
T: Animate,
{
fn components() -> usize {
2 * T::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[self.x.distance_to(&end.x), self.y.distance_to(&end.y)].concat()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.x.update(components);
self.y.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.x.lerp(&start.x, &end.x, progress);
self.y.lerp(&start.y, &end.y, progress);
}
}
impl<T> Animate for iced_core::Size<T>
where
T: Animate,
{
fn components() -> usize {
2 * T::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.width.distance_to(&end.width),
self.height.distance_to(&end.height),
]
.concat()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.width.update(components);
self.height.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.width.lerp(&start.width, &end.width, progress);
self.height.lerp(&start.height, &end.height, progress);
}
}
impl<T> Animate for iced_core::Rectangle<T>
where
T: Animate,
{
fn components() -> usize {
4 * T::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.x.distance_to(&end.x),
self.y.distance_to(&end.y),
self.width.distance_to(&end.width),
self.height.distance_to(&end.height),
]
.concat()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.x.update(components);
self.y.update(components);
self.width.update(components);
self.height.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.x.lerp(&start.x, &end.x, progress);
self.y.lerp(&start.y, &end.y, progress);
self.width.lerp(&start.width, &end.width, progress);
self.height.lerp(&start.height, &end.height, progress);
}
}
impl Animate for iced_core::Shadow {
fn components() -> usize {
iced_core::Color::components() + iced_core::Vector::<f32>::components() + f32::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.color.distance_to(&end.color),
self.offset.distance_to(&end.offset),
self.blur_radius.distance_to(&end.blur_radius),
]
.concat()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.color.update(components);
self.offset.update(components);
self.blur_radius.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.color.lerp(&start.color, &end.color, progress);
self.offset.lerp(&start.offset, &end.offset, progress);
self.blur_radius
.lerp(&start.blur_radius, &end.blur_radius, progress);
}
}
impl Animate for iced_core::Radians {
fn components() -> usize {
f32::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
self.0.distance_to(&end.0)
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.0.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.0.lerp(&start.0, &end.0, progress);
}
}
impl Animate for iced_core::gradient::ColorStop {
fn components() -> usize {
f32::components() + iced_core::Color::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.offset.distance_to(&end.offset),
self.color.distance_to(&end.color),
]
.concat()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.offset.update(components);
self.color.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.offset.lerp(&start.offset, &end.offset, progress);
self.color.lerp(&start.color, &end.color, progress);
}
}
impl<T, const N: usize> Animate for [T; N]
where
T: Animate,
{
fn components() -> usize {
N * T::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
self.iter()
.zip(end.iter())
.flat_map(|(start, end)| start.distance_to(end))
.collect()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
for item in self.iter_mut() {
item.update(components);
}
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
for (item, (start, end)) in self.iter_mut().zip(start.iter().zip(end.iter())) {
item.lerp(start, end, progress);
}
}
}
impl Animate for iced_core::gradient::Linear {
fn components() -> usize {
iced_core::Radians::components() + 8 * iced_core::gradient::ColorStop::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.angle.distance_to(&end.angle),
self.stops.distance_to(&end.stops),
]
.concat()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.angle.update(components);
for stop in &mut self.stops {
stop.update(components);
}
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.angle.lerp(&start.angle, &end.angle, progress);
for (stop, (start, end)) in self
.stops
.iter_mut()
.zip(start.stops.iter().zip(end.stops.iter()))
{
stop.lerp(start, end, progress);
}
}
}
impl Animate for iced_core::Gradient {
fn components() -> usize {
iced_core::gradient::Linear::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
match (self, end) {
(iced_core::Gradient::Linear(start), iced_core::Gradient::Linear(end)) => {
start.distance_to(end)
}
}
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
match self {
iced_core::Gradient::Linear(start) => start.update(components),
}
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
match (self, start, end) {
(
iced_core::Gradient::Linear(value),
iced_core::Gradient::Linear(start),
iced_core::Gradient::Linear(end),
) => {
value.lerp(start, end, progress);
}
}
}
}
impl Animate for iced_core::Background {
fn components() -> usize {
iced_core::gradient::Gradient::components().max(iced_core::Color::components())
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
match (self, end) {
(iced_core::Background::Color(start), iced_core::Background::Color(end)) => {
let mut distance = start.distance_to(end);
distance.resize(Self::components(), 0.0);
distance
}
(iced_core::Background::Color(_), iced_core::Background::Gradient(_)) => {
vec![0.0; Self::components()]
}
(iced_core::Background::Gradient(start), iced_core::Background::Gradient(end)) => {
let mut distance = start.distance_to(end);
distance.resize(Self::components(), 0.0);
distance
}
(iced_core::Background::Gradient(_), iced_core::Background::Color(_)) => {
vec![0.0; Self::components()]
}
}
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
match self {
iced_core::Background::Color(color) => {
color.update(components);
let extra = Self::components() - iced_core::Color::components() - 1;
components.nth(extra);
}
iced_core::Background::Gradient(gradient) => gradient.update(components),
}
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
match (self, start, end) {
(
iced_core::Background::Color(value),
iced_core::Background::Color(start),
iced_core::Background::Color(end),
) => {
value.lerp(start, end, progress);
}
(
iced_core::Background::Gradient(value),
iced_core::Background::Gradient(start),
iced_core::Background::Gradient(end),
) => {
value.lerp(start, end, progress);
}
_ => {}
}
}
}
#[cfg(feature = "widgets")]
impl Animate for iced_widget::button::Style {
fn components() -> usize {
Option::<iced_core::Background>::components()
+ iced_core::Color::components()
+ iced_core::Border::components()
+ iced_core::Shadow::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.background.distance_to(&end.background),
self.text_color.distance_to(&end.text_color),
self.border.distance_to(&end.border),
self.shadow.distance_to(&end.shadow),
]
.concat()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.background.update(components);
self.text_color.update(components);
self.border.update(components);
self.shadow.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.background
.lerp(&start.background, &end.background, progress);
self.text_color
.lerp(&start.text_color, &end.text_color, progress);
self.border.lerp(&start.border, &end.border, progress);
self.shadow.lerp(&start.shadow, &end.shadow, progress);
}
}
#[cfg(feature = "widgets")]
impl Animate for iced_widget::svg::Style {
fn components() -> usize {
Option::<iced_core::Color>::components()
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
self.color.distance_to(&end.color)
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.color.update(components);
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.color.lerp(&start.color, &end.color, progress);
}
}
impl<T1, T2> Animate for (T1, T2)
where
T1: Animate,
T2: Animate,
{
fn components() -> usize {
T1::components() + T2::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.0.update(components);
self.1.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[self.0.distance_to(&end.0), self.1.distance_to(&end.1)].concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.0.lerp(&start.0, &end.0, progress);
self.1.lerp(&start.1, &end.1, progress);
}
}
impl<T1, T2, T3> Animate for (T1, T2, T3)
where
T1: Animate,
T2: Animate,
T3: Animate,
{
fn components() -> usize {
T1::components() + T2::components() + T3::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.0.update(components);
self.1.update(components);
self.2.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.0.distance_to(&end.0),
self.1.distance_to(&end.1),
self.2.distance_to(&end.2),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.0.lerp(&start.0, &end.0, progress);
self.1.lerp(&start.1, &end.1, progress);
self.2.lerp(&start.2, &end.2, progress);
}
}
impl<T1, T2, T3, T4> Animate for (T1, T2, T3, T4)
where
T1: Animate,
T2: Animate,
T3: Animate,
T4: Animate,
{
fn components() -> usize {
T1::components() + T2::components() + T3::components() + T4::components()
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
self.0.update(components);
self.1.update(components);
self.2.update(components);
self.3.update(components);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
[
self.0.distance_to(&end.0),
self.1.distance_to(&end.1),
self.2.distance_to(&end.2),
self.3.distance_to(&end.3),
]
.concat()
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
self.0.lerp(&start.0, &end.0, progress);
self.1.lerp(&start.1, &end.1, progress);
self.2.lerp(&start.2, &end.2, progress);
self.3.lerp(&start.3, &end.3, progress);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn f32_components() {
assert_eq!(f32::components(), 1);
}
#[test]
fn f32_point_components() {
assert_eq!(iced_core::Point::<f32>::components(), 2);
}
#[test]
fn f32_color_components() {
assert_eq!(iced_core::Color::components(), 4);
}
#[test]
fn color_pair_components() {
assert_eq!(
iced_core::theme::palette::Pair::components(),
2 * iced_core::Color::components()
);
}
#[test]
fn primary_components() {
assert_eq!(
iced_core::theme::palette::Primary::components(),
3 * iced_core::theme::palette::Pair::components()
);
}
#[test]
fn secondary_components() {
assert_eq!(
iced_core::theme::palette::Secondary::components(),
3 * iced_core::theme::palette::Pair::components()
);
}
#[test]
fn success_components() {
assert_eq!(
iced_core::theme::palette::Success::components(),
3 * iced_core::theme::palette::Pair::components()
);
}
#[test]
fn danger_components() {
assert_eq!(
iced_core::theme::palette::Danger::components(),
3 * iced_core::theme::palette::Pair::components()
);
}
#[test]
fn background_components() {
assert_eq!(
iced_core::theme::palette::Background::components(),
8 * iced_core::theme::palette::Pair::components()
);
}
#[test]
fn extended_palette_components() {
assert_eq!(
iced_core::theme::palette::Extended::components(),
iced_core::theme::palette::Background::components()
+ iced_core::theme::palette::Primary::components()
+ iced_core::theme::palette::Secondary::components()
+ iced_core::theme::palette::Success::components()
+ iced_core::theme::palette::Warning::components()
+ iced_core::theme::palette::Danger::components()
);
}
#[test]
fn theme_components() {
assert_eq!(
Theme::components(),
iced_core::theme::Palette::components()
+ iced_core::theme::palette::Extended::components()
);
}
#[test]
fn option_components() {
assert_eq!(Option::<f32>::components(), 1);
}
#[test]
fn option_update_some() {
let mut option = Some(1.0);
option.update(&mut [2.0].iter().copied());
assert_eq!(option, Some(3.0));
}
#[test]
fn option_update_none() {
let mut option: Option<f32> = None;
let mut iter = [2.0, 4.0].iter().copied();
option.update(&mut iter);
assert_eq!(option, None);
assert_eq!(iter.next(), Some(4.0));
assert_eq!(iter.next(), None);
}
#[test]
fn update_background() {
let mut background = iced_core::Background::Color(iced_core::Color::BLACK);
let components = vec![0.1_f32; iced_core::Background::components()];
let mut components = components.iter().copied();
background.update(&mut components);
assert_ne!(
background,
iced_core::Background::Color(iced_core::Color::BLACK)
);
assert_eq!(components.len(), 0);
}
#[test]
fn update_button_style() {
let style = iced_widget::button::Style {
background: Some(iced_core::Background::Color(iced_core::Color::BLACK)),
text_color: iced_core::Color::BLACK,
border: iced_core::Border::default(),
shadow: iced_core::Shadow::default(),
snap: true,
};
let target = iced_widget::button::Style {
background: Some(iced_core::Background::Color(iced_core::Color::WHITE)),
text_color: iced_core::Color::WHITE,
border: iced_core::Border::default().width(1.0),
shadow: iced_core::Shadow::default(),
snap: true,
};
let mut spring = crate::Spring::new(style);
spring.set_target(target);
spring.tick(std::time::Instant::now());
assert_ne!(*spring.value(), style);
}
}