use wrap_render::WrapRender;
use crate::prelude::*;
#[derive(Default, Clone)]
pub struct ClipBoundary {
pub clip_boundary: bool,
}
impl Declare for ClipBoundary {
type Builder = FatObj<()>;
#[inline]
fn declarer() -> Self::Builder { FatObj::new(()) }
}
impl_compose_child_for_wrap_render!(ClipBoundary);
impl WrapRender for ClipBoundary {
fn measure(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut MeasureCtx) -> Size {
host.measure(clamp, ctx)
}
fn size_affected_by_child(&self, host: &dyn Render) -> bool { host.size_affected_by_child() }
fn paint(&self, host: &dyn Render, ctx: &mut PaintingCtx) {
if self.clip_boundary {
let rect = Rect::from_size(
ctx
.box_size()
.expect("impossible without size in painting stage"),
);
let path = if let Some(radius) = Provider::of::<Radius>(ctx) {
Path::rect_round(&rect, &radius)
} else {
Path::rect(&rect)
};
ctx.box_painter().clip(path.into());
}
host.paint(ctx)
}
fn hit_test(&self, host: &dyn Render, ctx: &mut HitTestCtx, pos: Point) -> HitTest {
let mut hit = host.hit_test(ctx, pos);
hit.can_hit_child &= ctx.box_hit_test(pos);
hit
}
#[inline]
fn wrapper_dirty_phase(&self) -> DirtyPhase { DirtyPhase::Layout }
#[cfg(feature = "debug")]
fn debug_type(&self) -> Option<&'static str> { Some("clipBoundary") }
#[cfg(feature = "debug")]
fn debug_properties(&self) -> Option<serde_json::Value> {
Some(serde_json::json!({ "enabled": self.clip_boundary }))
}
}
#[cfg(test)]
mod tests {
use ribir_dev_helper::*;
use super::*;
use crate::{reset_test_env, test_helper::*};
#[test]
#[cfg(not(target_arch = "wasm32"))]
fn clip_boundary() {
reset_test_env!();
let size = Size::new(40., 40.);
assert_widget_eq_image!(
WidgetTester::new(fn_widget! {
@MockBox {
clip_boundary: true,
radius: Radius::all(20.),
size: size,
@MockBox {
background: Color::GRAY,
size: size,
}
}
})
.with_wnd_size(size)
.with_comparison(0.00015),
"clip_boundary"
);
}
}