@@ -908,4 +908,78 @@ mod test_transform_layer {
908908 let translation_diff = ( after_cancel. translation - original_transform. translation ) . length ( ) ;
909909 assert ! ( translation_diff < 1.0 , "Translation component changed too much: {}" , translation_diff) ;
910910 }
911+
912+ #[ tokio:: test]
913+ async fn test_grab_rotate_scale_chained ( ) {
914+ let mut editor = EditorTestUtils :: create ( ) ;
915+ editor. new_document ( ) . await ;
916+ editor. drag_tool ( ToolType :: Rectangle , 0. , 0. , 100. , 100. , ModifierKeys :: empty ( ) ) . await ;
917+ let document = editor. active_document ( ) ;
918+ let layer = document. metadata ( ) . all_layers ( ) . next ( ) . unwrap ( ) ;
919+ editor. handle_message ( NodeGraphMessage :: SelectedNodesSet { nodes : vec ! [ layer. to_node( ) ] } ) . await ;
920+ let original_transform = get_layer_transform ( & mut editor, layer) . await . unwrap ( ) ;
921+
922+ editor. handle_message ( TransformLayerMessage :: BeginGrab ) . await ;
923+ editor. move_mouse ( 150.0 , 130.0 , ModifierKeys :: empty ( ) , MouseKeys :: NONE ) . await ;
924+ editor
925+ . handle_message ( TransformLayerMessage :: PointerMove {
926+ slow_key : Key :: Shift ,
927+ increments_key : Key :: Control ,
928+ } )
929+ . await ;
930+
931+ let after_grab_transform = get_layer_transform ( & mut editor, layer) . await . unwrap ( ) ;
932+ let expected_translation = DVec2 :: new ( 50.0 , 30.0 ) ;
933+ let actual_translation = after_grab_transform. translation - original_transform. translation ;
934+ assert ! (
935+ ( actual_translation - expected_translation) . length( ) < 1e-5 ,
936+ "Expected translation of {:?}, got {:?}" ,
937+ expected_translation,
938+ actual_translation
939+ ) ;
940+
941+ // 2. Chain to rotation - from current position to create ~45 degree rotation
942+ editor. handle_message ( TransformLayerMessage :: BeginRotate ) . await ;
943+ editor. move_mouse ( 190.0 , 90.0 , ModifierKeys :: empty ( ) , MouseKeys :: NONE ) . await ;
944+ editor
945+ . handle_message ( TransformLayerMessage :: PointerMove {
946+ slow_key : Key :: Shift ,
947+ increments_key : Key :: Control ,
948+ } )
949+ . await ;
950+ let after_rotate_transform = get_layer_transform ( & mut editor, layer) . await . unwrap ( ) ;
951+ // Checking for off-diagonal elements close to 0.707, which corresponds to cos(45°) and sin(45°)
952+ assert ! (
953+ !after_rotate_transform. matrix2. abs_diff_eq( after_grab_transform. matrix2, 1e-5 ) &&
954+ ( after_rotate_transform. matrix2. x_axis. y. abs( ) - 0.707 ) . abs( ) < 0.1 && // Check for off-diagonal elements close to 0.707
955+ ( after_rotate_transform. matrix2. y_axis. x. abs( ) - 0.707 ) . abs( ) < 0.1 , // that would indicate ~45° rotation
956+ "Rotation should change matrix components with approximately 45° rotation"
957+ ) ;
958+
959+ // 3. Chain to scaling - scale(area) up by 2x
960+ editor. handle_message ( TransformLayerMessage :: BeginScale ) . await ;
961+ editor. move_mouse ( 250.0 , 200.0 , ModifierKeys :: empty ( ) , MouseKeys :: NONE ) . await ;
962+ editor
963+ . handle_message ( TransformLayerMessage :: PointerMove {
964+ slow_key : Key :: Shift ,
965+ increments_key : Key :: Control ,
966+ } )
967+ . await ;
968+
969+ let after_scale_transform = get_layer_transform ( & mut editor, layer) . await . unwrap ( ) ;
970+ let before_scale_det = after_rotate_transform. matrix2 . determinant ( ) ;
971+ let after_scale_det = after_scale_transform. matrix2 . determinant ( ) ;
972+ assert ! (
973+ after_scale_det >= 2.0 * before_scale_det,
974+ "Scale should increase the determinant of the matrix (before: {}, after: {})" ,
975+ before_scale_det,
976+ after_scale_det
977+ ) ;
978+
979+ editor. handle_message ( TransformLayerMessage :: ApplyTransformOperation { final_transform : true } ) . await ;
980+ let final_transform = get_layer_transform ( & mut editor, layer) . await . unwrap ( ) ;
981+
982+ assert ! ( final_transform. abs_diff_eq( after_scale_transform, 1e-5 ) , "Final transform should match the transform before committing" ) ;
983+ assert ! ( !final_transform. abs_diff_eq( original_transform, 1e-5 ) , "Final transform should be different from original transform" ) ;
984+ }
911985}
0 commit comments