From 2af1566934706d1ef9fdd969b4309e81311b5720 Mon Sep 17 00:00:00 2001 From: Kaur Kuut Date: Tue, 26 May 2026 17:45:02 +0300 Subject: [PATCH] Restore transform testing and add one new transform test. --- .../screenshots/transforms_pointer_events.png | Bin 10896 -> 5420 bytes .../transforms_translation_rotation.png | Bin 2245 -> 2023 bytes masonry/src/tests/mod.rs | 15 +- masonry/src/tests/transforms.rs | 134 +++++++++++++----- 4 files changed, 113 insertions(+), 36 deletions(-) diff --git a/masonry/screenshots/transforms_pointer_events.png b/masonry/screenshots/transforms_pointer_events.png index 8c3bf2585ae20510546eb3b18089599dc681b2ee..a61b95fb12f8e6052b9de6603bc1a04d755c3105 100644 GIT binary patch literal 5420 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 E0B6#bnE(I) literal 10896 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 J@{@7ke*x?&gS7wv diff --git a/masonry/screenshots/transforms_translation_rotation.png b/masonry/screenshots/transforms_translation_rotation.png index 51690d11dbeadba59fdc18d366fb336a32db378d..d222b18cf1f1679332d957a216b7d3a0828eac26 100644 GIT binary patch literal 2023 zcmcgs`#02y1057nu@$R_MrSB9%t_OFq)fILGxCVZs6kXLF(Pah)3CK|F=85F%Oo1F zka5VXA+}w+UTLB{QmCjVM)LX0d_ME|%%|P{fbTi`)Aycp&pqef`{O+~+ux76)@ZX4 z27_7aMf0FzFgn-1(opYTr|sn5C+cgtArJ^=3teOh((D*XNTnzlB@nl!vtfg_vr}$vuC1?E zFq!JbMZnk?ZERE=JEnGaMxH(e_v}HiSgo6zhDy~OI;4q=R0)NUL;?;D%Ee+uZLMP4 zHtp)w=;6a^216~A0Thbn$rJFezvMf1AR9Mo_wCa-I3NN6^zI#Cbf9R(H*a3Q25V{* zb#)33N7>Mz*uP)%;swa%!UhItM~D33LwQ%1{NhEWpPyP+7Yz+nCnqbVQsCrCm8~r@ zI}2oI!+1PGA|X5;{Pr!tVyP@Fw3jc#Q&V7JAzW1j#l@*^+<+cDP}tZYxw&v_tAb!_ zyDC1uyLN!>Xd5dP9z~grOVFTvPElWhxquY zbvc|}yO7jWWkiI^(Ge*tgGx#uHd}e(gleO&Z&4AHpATQU1Y0{e`1-1^U4thkz~6tD zr>83`DxiS@d3U$`{CVa3_rUx-(AOuAiBZMIst5#RbQFw_SB;H<3k!g!rzR{+G z>5+$rt9pCoE-o5xZ}q{0nseurD_5fT?<>}>MJp?zSFgb7Y0$|DnVSPlOwiAt0e5%J z$B)3ORp_l-(E9c0rcK&AccAEK)$%eR5-HNsl=}Lpp&@FJn7D&PG7AjUJ%8TP%`JDp z{SpSVa*vnCfxy&B+1PQGU>zM(XT}oXSeY! z_O9bvvEnw6EOz;{HvPbKwbAliF$UcWuNCQr;~fhctw{IZMgMmwEyu|R0)pa^Wy6(B z)#%eQ8k4*^!;bFHYl#lBqtkiknB}wpvXJIQE;cVVCDc$guz*|eJYulqWt&g^#q{S% z?JR#jJ)Ov*CEc;-ngVWNJa`8irt<0UM}NsHa^Kn^q$$Y3ZP0jrXoos(S3m`T?T18q zUf3`%Ax(!oPf5XUB0H6=X_*QS`kDm?E$%u3{~FuYj@hDi6U>m8~yZs4TVi)*(m>$ayM1m;ZB zas`e7-3>v<1lCpw3uLF8!3>xdRegP~C-mVJGM&RCcAftczqS zVK!b+v$=(fZ?3GbI2d9Pw?XS~Y|uV?c}3FgoS7x7Tba{vnxyr|31*!P`>RMQi!ok1 zmgc_qibg$<6{<(KsWuh7(HxcCrpO8jSJ_cvWqX}i^v12b=Zd7Q0hp0&M-$O|>J z+Z!a}CX*)bQF}_MencvTKaxWv#(&f*e&pp)J1q$h`&Qfk{o%VA*qof6i9Bk<|6tC9 zht67v#Z0+URy`h0q7Llb&G~cIo@YiL^CWi888^ysgRF)ds+1<_Fw`@)U`lvEOKh!m z_JcNNv^u_=Pn6t#BiB$pTwQ@z;PnvCPpzH<_Vm<>G(0Y)Ro|>XU{0BRT2t2YC{hv- znXwlav@~Vj_$0Z04aGQ*Lr=?$MM~Q54JYJA;(=wQB$oxZu|vZeS(SKtcy|lvW3oie zztu7?;9@fm``YFU`>H#**!oOaunSi<$q`d4B}_Yaz94$~uDn#%SVfA>wZ_vwX0ke& z@(K1*ilk+|X}0qg3eS7?^Yc!}{5ySTs?$B`$F|N%!zsGg|web`h5tC)$V8Z>VMXLZ%d3>QB_>57benofkj*W{G7BTiI*t z%m36-yog292aiPdmW&!w)|)Z2{H+=MJuJS7nHOVjD(_2I(st04+0rx{KE8~6J8TuQ yj@)GS|B$2nRx^>i5SJclCp7r)@AN;L*G9eozdcKNoMR>b+VP_Jd58|4xcCoK1MT$y literal 2245 zcmdT`c{J1u8y-th?wCxaB4ZmBMcJj9CbwZmmRqS5)gY0vWhtXZ9Cbrz?x>^%2`3Se zr7Sa!(hV`)WXTp9rDid|G5hwLt9#D(o%5aVzy7=Dyze>B`<&-}-{-IQygB>*anO}U zDw)}|PYCYcP$$XIza9ipLvK-A0Q zQ?&HwG&I!f*Q<1Nz?CaOE!bymZFPS?mrND{04q0F@ZhBEpYqx;>-;D%NKTiJ>cafd;NOh#S7lms{#W9Fgsgt- z7l=f$jg8{K0qNKn$JSPnl_eM%;VfScPEWH>oRD0*CdkVZAP~xX_xLq6KxU?}t&LY$ zxOn~gB8$alvswQB($G+`ot>hp3YeQ?pFJzuwM$N=F2doe;bG3`DCffm?!JA}jT=?J z|1Rk3XG$y1B{s?2);<%frIN zsj0$+1(uJGltdEZ@v@c{USgu?*)v{61^?SOww0Cg{CQDxGcPSo*x9*o^X4LrwxFr0 z{`{GZ#mY{elx*3eJa$a7Y?(SRP@<;?mX`88JY+*d98XUf5~*Y|*}c8o?b{WbHYtOH zC11a?VK8vV4#nZa(#S~hxpN`{L2~h;kjG=q&axdH75VuBE|(P$APo-}8yc!suU7r? z3pg;q-LOHmA}&rRA;HStUIV;+0s>hM^~QP}B8_uC`o!lQ*qD)UQwRD%-_fEnpq5y5 z-ivw-YgtV_gpI+*a3v9j#z9+K2U7)XLne3QBj$xx5GV|?z~g# zCDYloM21>j;#q+7{)rgObWx`?n3`J%)Io(uk<|!W!<_0ji^D#)@Bqr%ZH@Rt=z9Ed z^fvf0O8$!6?xAw@SUk1rf-sI}T8~GeM-tK_o+lyiB5)b=ckFVpgUpXdVf{x++M-`4 z5{hlm)^ynrOKj{7dr@4P3K(pIcj%b3`p+B*wF;pE=m+IO{qdw-588=K#Z21l=bS#b z`w0JtVB00#WNWf4LeuSz`(06)1=s~6$uQE+5%HtT5frH%o&ot z4c?@qT$mF)^`3cE_-g;t*n0c}gdZ(!?;gH#C#yNRFL-M*jPYbyQBjQW>~(FP$2)LE zh8HZQ7C?t2fv=~!ykKfv*f$N=I)ZW4s7<_SYiH2m)CFj1CTfq4FPZv0MU%6e+8lcc77~#=j?&$p&4q8D6T2quzOi;cgj5t>Qds-lT6e z^)`@Pe-%H0@GEB*_+Z$kQ!4oyswQHr*)}k?Qv_zyP*M7^v zHk`wq;*`z3t5vyej33R$bnnHt-PRPQm^y;~O0Ykx>KSoDbmn7*tp@9GZ8aqvx?@xI zG-)F(;w=FiB*GtwTfaMzk7e?sODLqTNux_<7$#ZSO)UF~3EZ@wOYHG@;xHhsOLy}YbI(z30zHA-`+X9_ z$Wab^D$*#zlan`&x9}9s8x%swlDC2e*O9v8qQ2n`#+WGLS^!U1NxKFD91%Z^M;OPV z+RDMGC$sjcoB`w%W>ZH^@Jq|l{Qh_p*pG^=$iNl;rX-J_n!UxqD-gXnOM+btN=`tr z@|t*5GOd#@P5b^#2a)78F2Vb|AT}5HJ)hdUS=oz>5j`(_OI>-u@I4y&rdQ^=U1EmdPUd30-L?+A7J($ z@L%Sq0px!t|KA+yLkm6k;wZ#9tX;Kr zQiv9)>KveI)64R^|DqzyLXR{A{|;1Hy(};4af1EK-7P>CPpS0QoIa~R(Rx2_={ impl Widget { @@ -24,50 +22,116 @@ fn blue_box(inner: impl Widget) -> impl Widget { box_props.insert(BorderWidth::all(2.px())); WrapperWidget::new( - SizedBox::new(inner.prepare()) - .width(200.px()) - .height(100.px()) - .with_props(box_props), + NewWidget::new( + SizedBox::new(inner.prepare()) + .width(100.px()) + .height(50.px()), + ) + .with_props(box_props), ) } #[test] fn transforms_translation_rotation() { let translation = Vec2::new(100.0, 50.0); - let transformed_widget = NewWidget::new(blue_box(Label::new("Background"))).with_options( - // Currently there's no support for changing the transform-origin, which is currently at the top left. + let transformed_widget = NewWidget::new(blue_box(Label::new("Background"))).with_transform( + // Currently there's no support for changing the transform-origin, + // which is currently at the top left. // This rotates around the center of the widget - WidgetOptions { - transform: Affine::translate(-translation) - .then_rotate(PI * 0.25) - .then_translate(translation), - ..Default::default() - }, + Affine::translate(-translation) + .then_rotate(PI * 0.25) + .then_translate(translation), ); let widget = ZStack::new() - .with_fixed(transformed_widget, ChildAlignment::ParentAligned) + .with(transformed_widget, ChildAlignment::ParentAligned) .prepare(); - let mut harness = TestHarness::create(default_property_set(), widget); + let mut harness = TestHarness::create(test_property_set(), widget); + assert_render_snapshot!(harness, "transforms_translation_rotation"); } #[test] fn transforms_pointer_events() { - let transformed_widget = NewWidget::new(blue_box(ZStack::new().with_fixed( - Button::with_text("Should be pressed").prepare(), - UnitPoint::BOTTOM_RIGHT, - ))) - .with_options(WidgetOptions { - transform: Affine::rotate(PI * 0.125).then_translate(Vec2::new(100.0, 50.0)), - ..Default::default() - }); + let transformed_widget = NewWidget::new(blue_box( + ZStack::new().with(Button::with_text("OK").prepare(), UnitPoint::BOTTOM_RIGHT), + )) + .with_transform(Affine::rotate(PI * 0.125).then_translate(Vec2::new(100.0, 50.0))); let widget = ZStack::new() - .with_fixed(transformed_widget, ChildAlignment::ParentAligned) + .with(transformed_widget, ChildAlignment::ParentAligned) .prepare(); - let mut harness = TestHarness::create(default_property_set(), widget); - harness.mouse_move((335.0, 350.0)); // Should hit the last "d" of the button text + let mut harness = TestHarness::create(test_property_set(), widget); + + harness.mouse_move((300.0, 280.0)); // Should hit the "O" of the button text harness.mouse_button_press(None); + assert_render_snapshot!(harness, "transforms_pointer_events"); } + +#[test] +fn transforms_handle_content_box_space_translation() { + let tag = WidgetTag::unique(); + let child = NewWidget::new(SizedBox::empty().size(10.px(), 8.px())) + .with_tag(tag) + .with_transform(Affine::scale_non_uniform(2., 3.)) + .with_props(( + BorderWidth::all(0.5.px()), + Padding { + left: 1.px(), + right: 0.5.px(), + top: 2.px(), + bottom: 1.5.px(), + }, + )); + + let root = ModularWidget::new_parent(child) + .layout_fn(|child, ctx, _, size| { + let child_size = ctx.compute_size(child, SizeDef::fit(size), size.into()); + ctx.run_layout(child, child_size); + ctx.place_child(child, Point::new(5., 7.)); + }) + .prepare() + .with_props(Dimensions::fixed(40.px(), 40.px())); + + let harness = TestHarness::create(test_property_set(), root); + let child = harness.get_widget(tag); + let ctx = child.ctx(); + + // Border 0.5 + padding (1.0,2.0) gives top-left content inset (1.5,2.5). + assert_vec2_approx_eq( + "border_box_translation", + ctx.border_box_translation(), + Vec2::new(1.5, 2.5), + ); + // (0,0) + content inset (1.5,2.5), then scale (2,3) and add layout origin (5,7). + assert_point_approx_eq( + "to_window content origin", + ctx.to_window(Point::ORIGIN), + Point::new(8., 14.5), + ); + // (2,1) + content inset (1.5,2.5) = (3.5,3.5), then scale (2,3) and add (5,7). + assert_point_approx_eq( + "to_window local point", + ctx.to_window(Point::new(2., 1.)), + Point::new(12., 17.5), + ); + // Border box origin (-1.5,-2.5) cancels content inset, leaving the layout origin (5,7). + assert_point_approx_eq( + "to_window border origin", + ctx.to_window(ctx.border_box().origin()), + Point::new(5., 7.), + ); + // Inverse: ((12,17.5) - (5,7)) / (2,3) = (3.5,3.5), then subtract inset (1.5,2.5). + assert_point_approx_eq( + "to_local", + ctx.to_local(Point::new(12., 17.5)), + Point::new(2., 1.), + ); + // window_transform bakes in the required calculations and achieves the same result. + assert_point_approx_eq( + "window_transform", + ctx.window_transform() * Point::new(2., 1.), + Point::new(12., 17.5), + ); +}