use wrap_render::WrapRender;
use crate::prelude::*;
#[derive(Default)]
pub struct Padding {
pub padding: EdgeInsets,
}
impl Declare for Padding {
type Builder = FatObj<()>;
#[inline]
fn declarer() -> Self::Builder { FatObj::new(()) }
}
impl_compose_child_for_wrap_render!(Padding);
impl WrapRender for Padding {
fn measure(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut MeasureCtx) -> Size {
let thickness = self.padding.thickness();
let min = (clamp.min - thickness).max(ZERO_SIZE);
let max = (clamp.max - thickness).max(ZERO_SIZE);
let child_clamp = BoxClamp { min, max };
let size = host.measure(child_clamp, ctx);
clamp.clamp(size + thickness)
}
fn place_children(&self, size: Size, host: &dyn Render, ctx: &mut PlaceCtx) {
let thickness = self.padding.thickness();
host.place_children(size - thickness, ctx);
}
fn paint(&self, host: &dyn Render, ctx: &mut PaintingCtx) {
ctx.content_only_transform_apply(&Transform::translation(self.padding.left, self.padding.top));
host.paint(ctx);
}
fn get_transform(&self, host: &dyn Render) -> Option<Transform> {
let padding_matrix = Transform::translation(self.padding.left, self.padding.top);
let ts = host
.get_transform()
.map_or(padding_matrix, |h| padding_matrix.then(&h));
Some(ts)
}
#[inline]
fn wrapper_dirty_phase(&self) -> DirtyPhase { DirtyPhase::Layout }
#[cfg(feature = "debug")]
fn debug_type(&self) -> Option<&'static str> { Some("padding") }
#[cfg(feature = "debug")]
fn debug_properties(&self) -> Option<serde_json::Value> {
let p = self.padding;
Some(serde_json::json!({
"left": p.left,
"right": p.right,
"top": p.top,
"bottom": p.bottom
}))
}
}
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.))
.with_x(0.),
LayoutCase::new(&[0, 0]).with_size(Size::new(100., 100.))
);
#[test]
#[cfg(not(target_arch = "wasm32"))]
fn fix_padding_draw() {
crate::reset_test_env!();
assert_widget_eq_image!(
WidgetTester::new(text! {
padding: EdgeInsets::all(10.),
background: Color::GREEN,
text: "Hello, Ribir!"
})
.with_wnd_size(Size::new(128., 48.))
.with_comparison(0.000025),
"padding_draw"
);
}
}