use crate::animate_bool_eased;
use egui::{Id, Rect, Ui, UiBuilder, Vec2};
pub struct Collapse {
#[allow(dead_code)]
horizontal: bool,
visible: bool,
id: Id,
duration: Option<f32>,
}
impl Collapse {
pub fn vertical(id: impl Into<Id>, visible: bool) -> Self {
Self {
horizontal: false,
visible,
id: id.into(),
duration: None,
}
}
pub fn with_animation_time(mut self, animation_time: f32) -> Self {
self.duration = Some(animation_time);
self
}
pub fn ui(self, ui: &mut Ui, content: impl FnOnce(&mut Ui)) {
let id = self.id;
let visible = self.visible;
let x = animate_bool_eased(
ui.ctx(),
id,
visible,
simple_easing::cubic_in_out,
self.duration.unwrap_or(ui.style().animation_time),
);
let last_size = ui
.ctx()
.memory_mut(|mem| *mem.data.get_temp_mut_or(id, 0.0));
let mut child = ui.new_child(
UiBuilder::new()
.max_rect(Rect::from_min_size(
ui.next_widget_position(),
ui.available_size(),
))
.layout(*ui.layout()),
);
let current_size = last_size * x;
let clip_rect = ui.clip_rect().intersect(Rect::from_min_size(
child.next_widget_position(),
Vec2::new(child.available_size().x, current_size),
));
child.set_clip_rect(clip_rect);
content(&mut child);
let size = child.min_size().min(ui.available_size());
ui.memory_mut(|mem| {
mem.data.insert_temp(id, size.y);
});
ui.allocate_rect(
Rect::from_min_size(ui.next_widget_position(), Vec2::new(size.x, current_size)),
egui::Sense::hover(),
);
}
}