use crate::{prelude::*, wrap_render::*};
#[derive(Clone, Default)]
pub struct TransformWidget {
pub transform: Transform,
}
impl Declare for TransformWidget {
type Builder = FatObj<()>;
#[inline]
fn declarer() -> Self::Builder { FatObj::new(()) }
}
impl_compose_child_for_wrap_render!(TransformWidget);
impl WrapRender for TransformWidget {
#[inline]
fn measure(&self, clamp: BoxClamp, host: &dyn Render, ctx: &mut MeasureCtx) -> Size {
host.measure(clamp, ctx)
}
fn paint(&self, host: &dyn Render, ctx: &mut PaintingCtx) {
ctx.painter().apply_transform(&self.transform);
host.paint(ctx)
}
fn hit_test(&self, host: &dyn Render, ctx: &mut HitTestCtx, pos: Point) -> HitTest {
if let Some(t) = self.transform.inverse() {
let lt = ctx.box_pos().unwrap();
let pos = (pos - lt).to_point();
let pos = t.transform_point(pos) + lt.to_vector();
host.hit_test(ctx, pos)
} else {
HitTest { hit: false, can_hit_child: false }
}
}
fn get_transform(&self, host: &dyn Render) -> Option<Transform> {
if let Some(t) = host.get_transform() {
Some(self.transform.then(&t))
} else {
Some(self.transform)
}
}
#[inline]
fn wrapper_dirty_phase(&self) -> DirtyPhase { DirtyPhase::Paint }
#[cfg(feature = "debug")]
fn debug_type(&self) -> Option<&'static str> { Some("transform") }
#[cfg(feature = "debug")]
fn debug_properties(&self) -> Option<serde_json::Value> {
let t = self.transform;
Some(serde_json::json!({
"m11": t.m11,
"m12": t.m12,
"m21": t.m21,
"m22": t.m22,
"m31": t.m31,
"m32": t.m32
}))
}
}
impl TransformWidget {
#[inline]
pub fn new(transform: Transform) -> Self { Self { transform } }
}
#[cfg(test)]
mod tests {
use ribir_dev_helper::*;
use super::*;
use crate::test_helper::*;
widget_layout_test!(
smoke,
WidgetTester::new(fn_widget! {
@TransformWidget {
transform: Transform::new(2., 0., 0., 2., 0., 0.),
@MockBox {
size: Size::new(100., 100.)
}
}
}),
LayoutCase::default().with_size((100., 100.).into())
);
}