use crate::{prelude::*, wrap_render::WrapRender};
#[derive(Default)]
pub struct Padding {
pub padding: EdgeInsets,
}
impl Declare for Padding {
type Builder = FatObj<()>;
#[inline]
fn declarer() -> Self::Builder { FatObj::new(()) }
}
impl<'c> ComposeChild<'c> for Padding {
type Child = Widget<'c>;
fn compose_child(this: impl StateWriter<Value = Self>, child: Self::Child) -> Widget<'c> {
WrapRender::combine_child(this, child)
}
}
impl WrapRender for Padding {
fn perform_layout(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut LayoutCtx) -> Size {
let thickness = self.padding.thickness();
let zero = Size::zero();
let (ctx, children) = ctx.split_children();
for c in children {
ctx.update_position(c, Point::zero());
}
let min = (clamp.min - thickness).max(zero);
let max = (clamp.max - thickness).max(zero);
let child_clamp = BoxClamp { min, max };
let mut size = host.perform_layout(child_clamp, ctx);
size = clamp.clamp(size + thickness);
let (ctx, children) = ctx.split_children();
for c in children {
if let Some(pos) = ctx.widget_box_pos(c) {
let pos = pos + Vector::new(self.padding.left, self.padding.top);
ctx.update_position(c, pos);
}
}
size
}
}
impl Padding {
#[inline]
pub fn new(padding: EdgeInsets) -> Self { Self { padding } }
}
#[cfg(test)]
mod tests {
use ribir_dev_helper::*;
use super::*;
use crate::test_helper::*;
widget_layout_test!(
smoke,
WidgetTester::new(fn_widget! {
@MockMulti {
padding: EdgeInsets::only_left(1.),
@MockBox {
size: Size::new(100., 100.),
}
}
}),
LayoutCase::default().with_size(Size::new(101., 100.)),
LayoutCase::new(&[0, 0])
.with_size(Size::new(100., 100.))
.with_x(1.)
);
}