-
Notifications
You must be signed in to change notification settings - Fork 6k
Use a single mask view to clip platform view #20050
Changes from 15 commits
db33eae
31db69b
0158df3
9785f97
eab8257
c0627b6
31d44e8
087b769
7c2ae3a
3a703fd
1ad2449
cab73d9
9b59753
ae69e2b
fa983ab
a1cd71a
4c102ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |||
| FLUTTER_ASSERT_NOT_ARC | ||||
| @class FlutterPlatformViewsTestMockPlatformView; | ||||
| static FlutterPlatformViewsTestMockPlatformView* gMockPlatformView = nil; | ||||
| const float kFloatCompareEpsilon = 0.001; | ||||
|
|
||||
| @interface FlutterPlatformViewsTestMockPlatformView : UIView | ||||
| @end | ||||
|
|
@@ -143,4 +144,128 @@ - (void)testCanCreatePlatformViewWithoutFlutterView { | |||
| flutterPlatformViewsController->Reset(); | ||||
| } | ||||
|
|
||||
| - (void)testChildClippingViewHitTests { | ||||
| ChildClippingView *childCilppingView = [[[ChildClippingView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)] autorelease]; | ||||
| UIView *childView = [[[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)] autorelease]; | ||||
| [childCilppingView addSubview:childView]; | ||||
|
|
||||
| XCTAssertFalse([childCilppingView pointInside:CGPointMake(50, 50) withEvent:nil]); | ||||
| XCTAssertTrue([childCilppingView pointInside:CGPointMake(150, 150) withEvent:nil]); | ||||
|
||||
| } | ||||
|
|
||||
| - (void)testCompositePlatformView { | ||||
| flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; | ||||
| auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest"); | ||||
| flutter::TaskRunners runners(/*label=*/self.name.UTF8String, | ||||
| /*platform=*/thread_task_runner, | ||||
| /*raster=*/thread_task_runner, | ||||
| /*ui=*/thread_task_runner, | ||||
| /*io=*/thread_task_runner); | ||||
| auto platform_view = std::make_unique<flutter::PlatformViewIOS>( | ||||
| /*delegate=*/mock_delegate, | ||||
| /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, | ||||
| /*task_runners=*/runners); | ||||
|
|
||||
| auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>(); | ||||
|
|
||||
| FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = | ||||
| [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; | ||||
| flutterPlatformViewsController->RegisterViewFactory( | ||||
| factory, @"MockFlutterPlatformView", | ||||
| FlutterPlatformViewGestureRecognizersBlockingPolicyEager); | ||||
| FlutterResult result = ^(id result) { | ||||
| }; | ||||
| flutterPlatformViewsController->OnMethodCall( | ||||
| [FlutterMethodCall | ||||
| methodCallWithMethodName:@"create" | ||||
| arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], | ||||
| result); | ||||
|
|
||||
| XCTAssertNotNil(gMockPlatformView); | ||||
|
|
||||
| UIView *mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)] autorelease]; | ||||
| flutterPlatformViewsController->SetFlutterView(mockFlutterView); | ||||
| // Create embedded view params | ||||
| flutter::MutatorsStack stack; | ||||
| // Layer tree always pushes a screen scale factor to the stack | ||||
| SkMatrix screenScaleMatrix = SkMatrix::MakeScale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale); | ||||
|
||||
| stack.PushTransform(screenScaleMatrix); | ||||
| // Push a translate matrix | ||||
| SkMatrix translateMatrix = SkMatrix::MakeTrans(100, 100); | ||||
| stack.PushTransform(translateMatrix); | ||||
| SkMatrix finalMatrix; | ||||
| finalMatrix.setConcat(screenScaleMatrix, translateMatrix); | ||||
|
|
||||
| auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack); | ||||
|
|
||||
| flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); | ||||
| flutterPlatformViewsController->CompositeEmbeddedView(2); | ||||
| CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds | ||||
| toView:mockFlutterView]; | ||||
| XCTAssertTrue(CGRectEqualToRect(platformViewRectInFlutterView, CGRectMake(100, 100, 300, 300))); | ||||
| flutterPlatformViewsController->Reset(); | ||||
| } | ||||
|
|
||||
| - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView { | ||||
| flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate; | ||||
| auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest"); | ||||
| flutter::TaskRunners runners(/*label=*/self.name.UTF8String, | ||||
| /*platform=*/thread_task_runner, | ||||
| /*raster=*/thread_task_runner, | ||||
| /*ui=*/thread_task_runner, | ||||
| /*io=*/thread_task_runner); | ||||
| auto platform_view = std::make_unique<flutter::PlatformViewIOS>( | ||||
| /*delegate=*/mock_delegate, | ||||
| /*rendering_api=*/flutter::IOSRenderingAPI::kSoftware, | ||||
| /*task_runners=*/runners); | ||||
|
|
||||
| auto flutterPlatformViewsController = std::make_unique<flutter::FlutterPlatformViewsController>(); | ||||
|
|
||||
| FlutterPlatformViewsTestMockFlutterPlatformFactory* factory = | ||||
| [[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease]; | ||||
| flutterPlatformViewsController->RegisterViewFactory( | ||||
| factory, @"MockFlutterPlatformView", | ||||
| FlutterPlatformViewGestureRecognizersBlockingPolicyEager); | ||||
| FlutterResult result = ^(id result) { | ||||
| }; | ||||
| flutterPlatformViewsController->OnMethodCall( | ||||
| [FlutterMethodCall | ||||
| methodCallWithMethodName:@"create" | ||||
| arguments:@{@"id" : @2, @"viewType" : @"MockFlutterPlatformView"}], | ||||
| result); | ||||
|
|
||||
| XCTAssertNotNil(gMockPlatformView); | ||||
|
|
||||
| UIView *mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)] autorelease]; | ||||
| flutterPlatformViewsController->SetFlutterView(mockFlutterView); | ||||
| // Create embedded view params | ||||
| flutter::MutatorsStack stack; | ||||
| // Layer tree always pushes a screen scale factor to the stack | ||||
| SkMatrix screenScaleMatrix = SkMatrix::MakeScale([UIScreen mainScreen].scale, [UIScreen mainScreen].scale); | ||||
|
||||
| stack.PushTransform(screenScaleMatrix); | ||||
| // Push a rotate matrix | ||||
| SkMatrix rotateMatrix; | ||||
| rotateMatrix.setRotate(10); | ||||
| stack.PushTransform(rotateMatrix); | ||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is fine, but what about Line 133 in c57aff1
Should that be in a separate unit test?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To test the clipping, we will probably have to render the view into an image, then check the pixels (sort like a screenshot). I think the scenario tests already covered all the clippings, it is kind of redundant. |
||||
| SkMatrix finalMatrix; | ||||
| finalMatrix.setConcat(screenScaleMatrix, rotateMatrix); | ||||
|
|
||||
| auto embeddedViewParams = std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack); | ||||
|
|
||||
| flutterPlatformViewsController->PrerollCompositeEmbeddedView(2, std::move(embeddedViewParams)); | ||||
| flutterPlatformViewsController->CompositeEmbeddedView(2); | ||||
| CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds | ||||
| toView:mockFlutterView]; | ||||
| XCTAssertTrue([gMockPlatformView.superview.superview isKindOfClass: ChildClippingView.class]); | ||||
| ChildClippingView *childClippingView = (ChildClippingView *)gMockPlatformView.superview.superview; | ||||
| // The childclippingview's frame is set based on flow, but the platform view's frame is set based on quartz. | ||||
| // Although they should be the same, but we should tolerate small floating point errors. | ||||
| XCTAssertTrue(fabs(platformViewRectInFlutterView.origin.x - childClippingView.frame.origin.x) < kFloatCompareEpsilon); | ||||
| XCTAssertTrue(fabs(platformViewRectInFlutterView.origin.y - childClippingView.frame.origin.y) < kFloatCompareEpsilon); | ||||
| XCTAssertTrue(fabs(platformViewRectInFlutterView.size.width - childClippingView.frame.size.width) < kFloatCompareEpsilon); | ||||
| XCTAssertTrue(fabs(platformViewRectInFlutterView.size.height - childClippingView.frame.size.height) < kFloatCompareEpsilon); | ||||
|
||||
|
|
||||
| flutterPlatformViewsController->Reset(); | ||||
| } | ||||
|
|
||||
| @end | ||||
Uh oh!
There was an error while loading. Please reload this page.