use super::box_model::BoxLengths;
use super::*;
use crate::tree::LayoutCtx;
impl Container {
pub(super) fn update_size_targets(
&mut self,
ctx: &mut LayoutCtx,
id: WidgetId,
lengths: &BoxLengths,
content: Size,
) {
let targets = [
(
lengths.width.exact_size(),
lengths.width.min(),
lengths.width.max(),
content.width + lengths.padding.horizontal_total(),
),
(
lengths.height.exact_size(),
lengths.height.min(),
lengths.height.max(),
content.height + lengths.padding.vertical_total(),
),
];
let parent = ctx.tree_ref().get_parent(id);
let frame_instant = ctx.tree_ref().frame_instant();
let Some(ref mut anims) = self.anims else {
return;
};
let mut retargeted = false;
for slot in anims.slots_mut() {
let (anim, (exact, min, max, content_extent)) = match slot {
AnimSlot::width(anim) => (anim, targets[0]),
AnimSlot::height(anim) => (anim, targets[1]),
_ => continue,
};
let target = exact.unwrap_or_else(|| {
let grown = content_extent.max(min.unwrap_or(0.0));
match max {
Some(max) => grown.min(max),
None => grown,
}
});
if anim.is_initial() {
if anim.begin_enter(ctx, target, || frame_instant) {
retargeted = true;
} else {
anim.set_immediate(ctx, target);
}
} else if (target - *anim.target()).abs() > 0.001 {
anim.animate_to(target, frame_instant);
retargeted = true;
}
}
if retargeted {
request_job(id, JobRequest::Animation(RequiredJob::Layout));
if let Some(parent_id) = parent {
request_job(parent_id, JobRequest::Layout);
}
}
}
}
pub(super) fn seed_or_enter<T: crate::animation::Animatable>(
ctx: &mut LayoutCtx,
anim: &mut AnimationState<T>,
target: T,
now: impl FnOnce() -> crate::clock::FrameInstant,
) -> bool {
let entered = anim.begin_enter(ctx, target, now);
if !entered {
anim.set_immediate(ctx, target);
}
entered || anim.owes_its_first_play()
}