Nice foldable animations
This commit is contained in:
parent
0fdc1048c8
commit
8fd95153fe
2 changed files with 21 additions and 16 deletions
|
@ -7,6 +7,9 @@ pub(crate) struct State {
|
|||
|
||||
#[serde(skip)] // Times are relative, and we don't want to continue animations anyway
|
||||
toggle_time: f64,
|
||||
|
||||
/// Height open the region when open. Used for animations
|
||||
open_height: Option<f32>,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
|
@ -14,6 +17,7 @@ impl Default for State {
|
|||
Self {
|
||||
open: false,
|
||||
toggle_time: -f64::INFINITY,
|
||||
open_height: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +65,7 @@ impl CollapsingHeader {
|
|||
Some(id),
|
||||
);
|
||||
|
||||
let state = {
|
||||
let mut state = {
|
||||
let mut memory = region.memory();
|
||||
let mut state = memory.collapsing_headers.entry(id).or_insert(State {
|
||||
open: default_open,
|
||||
|
@ -95,23 +99,16 @@ impl CollapsingHeader {
|
|||
|
||||
let animation_time = region.style().animation_time;
|
||||
let time_since_toggle = (region.input().time - state.toggle_time) as f32;
|
||||
let time_since_toggle = time_since_toggle + region.input().dt; // Instant feedback
|
||||
let animate = time_since_toggle < animation_time;
|
||||
if animate {
|
||||
region.indent(id, |child_region| {
|
||||
let max_height = if state.open {
|
||||
remap(
|
||||
time_since_toggle,
|
||||
0.0..=animation_time,
|
||||
// Get instant feedback, and we don't expect to get bigger than this
|
||||
100.0..=1500.0,
|
||||
)
|
||||
let full_height = state.open_height.unwrap_or(1000.0);
|
||||
remap(time_since_toggle, 0.0..=animation_time, 0.0..=full_height)
|
||||
} else {
|
||||
remap_clamp(
|
||||
time_since_toggle,
|
||||
0.0..=animation_time,
|
||||
// TODO: state.open_height
|
||||
50.0..=0.0,
|
||||
)
|
||||
let full_height = state.open_height.unwrap_or_default();
|
||||
remap_clamp(time_since_toggle, 0.0..=animation_time, full_height..=0.0)
|
||||
};
|
||||
|
||||
let mut clip_rect = child_region.clip_rect();
|
||||
|
@ -121,15 +118,19 @@ impl CollapsingHeader {
|
|||
let top_left = child_region.top_left();
|
||||
add_contents(child_region);
|
||||
|
||||
state.open_height = Some(child_region.bounding_size().y);
|
||||
|
||||
// Pretend children took up less space:
|
||||
let mut child_bounds = child_region.child_bounds();
|
||||
child_bounds.max.y = child_bounds.max.y.min(top_left.y + max_height);
|
||||
child_region.force_set_child_bounds(child_bounds);
|
||||
});
|
||||
} else if state.open {
|
||||
region.indent(id, add_contents);
|
||||
let full_size = region.indent(id, add_contents).rect.size();
|
||||
state.open_height = Some(full_size.y);
|
||||
}
|
||||
|
||||
region.memory().collapsing_headers.insert(id, state);
|
||||
region.response(interact)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -513,7 +513,11 @@ impl Region {
|
|||
}
|
||||
|
||||
/// Create a child region which is indented to the right
|
||||
pub fn indent(&mut self, id_source: impl Hash, add_contents: impl FnOnce(&mut Region)) {
|
||||
pub fn indent(
|
||||
&mut self,
|
||||
id_source: impl Hash,
|
||||
add_contents: impl FnOnce(&mut Region),
|
||||
) -> InteractInfo {
|
||||
assert!(
|
||||
self.dir == Direction::Vertical,
|
||||
"You can only indent vertical layouts"
|
||||
|
@ -538,7 +542,7 @@ impl Region {
|
|||
width: self.style.line_width,
|
||||
});
|
||||
|
||||
self.reserve_space(indent + size, None);
|
||||
self.reserve_space(indent + size, None)
|
||||
}
|
||||
|
||||
pub fn left_column(&mut self, width: f32) -> Region {
|
||||
|
|
Loading…
Reference in a new issue