#[derive(Default, Clone, Copy)]
pub struct Animation {
pub out_seg: AnimationSegment,
pub in_seg: AnimationSegment,
}
impl Animation {
pub const EMPTY: Animation =
Animation::from_segments(AnimationSegment::EMPTY, AnimationSegment::EMPTY);
pub const fn new(
duration: f32,
out_fn: fn(&mut egui::Ui, f32),
in_fn: fn(&mut egui::Ui, f32),
) -> Self {
let segment_duration = duration / 2.0;
let out_seg = AnimationSegment::new(segment_duration, out_fn);
let in_seg = AnimationSegment::new(segment_duration, in_fn);
Self { out_seg, in_seg }
}
pub const fn new_out(duration: f32, out_fn: fn(&mut egui::Ui, f32)) -> Self {
let out_seg = AnimationSegment::new(duration, out_fn);
let in_seg = AnimationSegment::EMPTY;
Self { out_seg, in_seg }
}
pub const fn new_in(duration: f32, out_fn: fn(&mut egui::Ui, f32)) -> Self {
let out_seg = AnimationSegment::EMPTY;
let in_seg = AnimationSegment::new(duration, out_fn);
Self { out_seg, in_seg }
}
pub const fn from_segments(out_seg: AnimationSegment, in_seg: AnimationSegment) -> Self {
Self { out_seg, in_seg }
}
pub const fn duration(&self) -> f32 {
self.out_seg.duration + self.in_seg.duration
}
}
#[derive(Clone, Copy)]
pub struct AnimationSegment {
pub duration: f32,
pub anim_fn: fn(&mut egui::Ui, f32),
}
impl Default for AnimationSegment {
fn default() -> Self {
AnimationSegment::EMPTY
}
}
impl AnimationSegment {
const EMPTY: AnimationSegment = AnimationSegment {
duration: 0.0,
anim_fn: |_, _| {},
};
pub const fn new(duration: f32, animation: fn(&mut egui::Ui, f32)) -> Self {
Self {
duration,
anim_fn: animation,
}
}
pub fn duration(&self) -> f32 {
self.duration
}
pub fn duration_mut(&mut self) -> f32 {
self.duration
}
pub fn anim_fn(&self) -> fn(&mut egui::Ui, f32) {
self.anim_fn
}
pub fn anim_fn_mut(&mut self) -> &mut fn(&mut egui::Ui, f32) {
&mut self.anim_fn
}
pub(super) fn animate<R>(
&self,
ui: &mut egui::Ui,
id: egui::Id,
normal: f32,
add_contents: impl FnOnce(&mut egui::Ui) -> R,
) -> R {
Self::scope_animation(ui, id, |ui| (self.anim_fn)(ui, normal), add_contents)
}
fn scope_animation<R>(
ui: &mut egui::Ui,
id: egui::Id,
anim_fn: impl FnOnce(&mut egui::Ui),
add_contents: impl FnOnce(&mut egui::Ui) -> R,
) -> R {
let layer_id = Self::animation_layer(ui, id);
ui.scope_builder(
egui::UiBuilder::new()
.id_salt("animation_scope")
.layer_id(layer_id),
|ui| {
anim_fn(ui);
add_contents(ui)
},
)
.inner
}
pub(crate) fn animation_layer(ui: &mut egui::Ui, id: egui::Id) -> egui::LayerId {
egui::LayerId::new(ui.layer_id().order, id)
}
}