use std::{hash::Hash, time::Duration};
use ggez::graphics::Rect;
use crate::ui::{UiContent, UiElement};
use super::{Layout, Visuals};
pub struct Transition<T: Copy + Eq + Hash> {
pub(crate) new_layout: Option<Layout>,
pub(crate) new_visuals: Option<Visuals>,
pub(crate) new_hover_visuals: Option<Option<Visuals>>,
pub(crate) new_content: Option<Box<dyn UiContent<T>>>,
pub(crate) new_tooltip: Option<Option<Box<UiElement<T>>>>,
total_duration: Duration,
progressed_duration: Duration,
}
impl<T: Copy + Eq + Hash> std::fmt::Debug for Transition<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Transition")
.field("new_layout", &self.new_layout)
.field("new_visuals", &self.new_visuals)
.field("new_hover_visuals", &self.new_hover_visuals)
.field("new_tooltip", &self.new_tooltip)
.field("total_duration", &self.total_duration)
.field("progressed_duration", &self.progressed_duration)
.finish()
}
}
impl<T: Copy + Eq + Hash> Transition<T> {
pub fn new(duration: Duration) -> Self {
Self {
new_layout: None,
new_visuals: None,
new_hover_visuals: None,
new_content: None,
new_tooltip: None,
total_duration: duration,
progressed_duration: Duration::ZERO,
}
}
pub fn with_new_layout(mut self, new_layout: Layout) -> Self {
self.new_layout = Some(new_layout);
self
}
pub fn with_new_visuals(mut self, new_visuals: Visuals) -> Self {
self.new_visuals = Some(new_visuals);
self
}
pub fn with_new_hover_visuals(mut self, new_hover_visuals: Option<Visuals>) -> Self {
self.new_hover_visuals = Some(new_hover_visuals);
self
}
pub fn with_new_content<E>(mut self, new_content: E) -> Self
where
E: UiContent<T> + 'static,
{
self.new_content = Some(Box::new(new_content));
self
}
pub fn with_new_tooltip(mut self, new_tooltip: Option<UiElement<T>>) -> Self {
self.new_tooltip = new_tooltip.map(|element| Some(Box::new(element)));
self
}
pub(crate) fn progress(&mut self, delta: Duration) -> bool {
self.progressed_duration += delta;
self.progressed_duration >= self.total_duration
}
pub(crate) fn get_progress_ratio(&self) -> f32 {
self.progressed_duration.as_secs_f32() / self.total_duration.as_secs_f32()
}
}
pub(crate) fn average_rect(rect1: &Rect, rect2: &Rect, ratio: f32) -> Rect {
Rect {
x: rect1.x * (1. - ratio) + rect2.x * ratio,
y: rect1.y * (1. - ratio) + rect2.y * ratio,
w: rect1.w * (1. - ratio) + rect2.w * ratio,
h: rect1.h * (1. - ratio) + rect2.h * ratio,
}
}