| Flutter iOS Embedder |

FlutterPlatformViews_Internal.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_
6 #define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_
7
8 #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h"
9
10 #include <Metal/Metal.h>
11
12 #include "flutter/flow/surface.h"
13 #include "flutter/fml/memory/weak_ptr.h"
14 #include "flutter/fml/task_runner.h"
15 #include "flutter/fml/trace_event.h"
16 #include "flutter/impeller/base/thread_safety.h"
17 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h"
18 #import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h"
19 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsController.h"
20 #import "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewResponder.h"
21 #include "flutter/shell/platform/darwin/ios/ios_context.h"
22 #include "third_party/skia/include/core/SkRect.h"
23
24 // A UIView that acts as a clipping mask for the |ChildClippingView|.
25 //
26 // On the [UIView drawRect:] method, this view performs a series of clipping operations and sets the
27 // alpha channel to the final resulting area to be 1; it also sets the "clipped out" area's alpha
28 // channel to be 0.
29 //
30 // When a UIView sets a |FlutterClippingMaskView| as its `maskView`, the alpha channel of the UIView
31 // is replaced with the alpha channel of the |FlutterClippingMaskView|.
32 @interface FlutterClippingMaskView : UIView
33
34 - (instancetype)initWithFrame:(CGRect)frame screenScale:(CGFloat)screenScale;
35
36 - (void)reset;
37
38 // Adds a clip rect operation to the queue.
39 //
40 // The `clipSkRect` is transformed with the `matrix` before adding to the queue.
41 - (void)clipRect:(const SkRect&)clipSkRect matrix:(const SkMatrix&)matrix;
42
43 // Adds a clip rrect operation to the queue.
44 //
45 // The `clipSkRRect` is transformed with the `matrix` before adding to the queue.
46 - (void)clipRRect:(const SkRRect&)clipSkRRect matrix:(const SkMatrix&)matrix;
47
48 // Adds a clip path operation to the queue.
49 //
50 // The `path` is transformed with the `matrix` before adding to the queue.
51 - (void)clipPath:(const SkPath&)path matrix:(const SkMatrix&)matrix;
52
53 @end
54
55 // A pool that provides |FlutterClippingMaskView|s.
56 //
57 // The pool has a capacity that can be set in the initializer.
58 // When requesting a FlutterClippingMaskView, the pool will first try to reuse an available maskView
59 // in the pool. If there are none available, a new FlutterClippingMaskView is constructed. If the
60 // capacity is reached, the newly constructed FlutterClippingMaskView is not added to the pool.
61 //
62 // Call |insertViewToPoolIfNeeded:| to return a maskView to the pool.
63 @interface FlutterClippingMaskViewPool : NSObject
64
65 // Initialize the pool with `capacity`. When the `capacity` is reached, a FlutterClippingMaskView is
66 // constructed when requested, and it is not added to the pool.
67 - (instancetype)initWithCapacity:(NSInteger)capacity;
68
69 // Reuse a maskView from the pool, or allocate a new one.
70 - (FlutterClippingMaskView*)getMaskViewWithFrame:(CGRect)frame;
71
72 // Insert the `maskView` into the pool.
73 - (void)insertViewToPoolIfNeeded:(FlutterClippingMaskView*)maskView;
74
75 @end
76
77 // An object represents a blur filter.
78 //
79 // This object produces a `backdropFilterView`.
80 // To blur a View, add `backdropFilterView` as a subView of the View.
81 @interface PlatformViewFilter : NSObject
82
83 // Determines the rect of the blur effect in the coordinate system of `backdropFilterView`'s
84 // parentView.
85 @property(nonatomic, readonly) CGRect frame;
86
87 // Determines the blur intensity.
88 //
89 // It is set as the value of `inputRadius` of the `gaussianFilter` that is internally used.
90 @property(nonatomic, readonly) CGFloat blurRadius;
91
92 // This is the view to use to blur the PlatformView.
93 //
94 // It is a modified version of UIKit's `UIVisualEffectView`.
95 // The inputRadius can be customized and it doesn't add any color saturation to the blurred view.
96 @property(nonatomic, readonly) UIVisualEffectView* backdropFilterView;
97
98 // For testing only.
99 + (void)resetPreparation;
100
101 - (instancetype)init NS_UNAVAILABLE;
102
103 // Initialize the filter object.
104 //
105 // The `frame` determines the rect of the blur effect in the coordinate system of
106 // `backdropFilterView`'s parentView. The `blurRadius` determines the blur intensity. It is set as
107 // the value of `inputRadius` of the `gaussianFilter` that is internally used. The
108 // `UIVisualEffectView` is the view that is used to add the blur effects. It is modified to become
109 // `backdropFilterView`, which better supports the need of Flutter.
110 //
111 // Note: if the implementation of UIVisualEffectView changes in a way that affects the
112 // implementation in `PlatformViewFilter`, this method will return nil.
113 - (instancetype)initWithFrame:(CGRect)frame
114 blurRadius:(CGFloat)blurRadius
115 visualEffectView:(UIVisualEffectView*)visualEffectView NS_DESIGNATED_INITIALIZER;
116
117 @end
118
119 // The parent view handles clipping to its subViews.
120 @interface ChildClippingView : UIView
121
122 // Applies blur backdrop filters to the ChildClippingView with blur values from
123 // filters.
124 - (void)applyBlurBackdropFilters:(NSArray<PlatformViewFilter*>*)filters;
125
126 // For testing only.
127 - (NSMutableArray*)backdropFilterSubviews;
128 @end
129
130 // A UIView that is used as the parent for embedded UIViews.
131 //
132 // This view has 2 roles:
133 // 1. Delay or prevent touch events from arriving the embedded view.
134 // 2. Dispatching all events that are hittested to the embedded view to the FlutterView.
135 @interface FlutterTouchInterceptingView : UIView
136 - (instancetype)initWithEmbeddedView:(UIView*)embeddedView
137 platformViewsController:(FlutterPlatformViewsController*)platformViewsController
138 gestureRecognizersBlockingPolicy:
139 (FlutterPlatformViewGestureRecognizersBlockingPolicy)blockingPolicy;
140
141 // Stop delaying any active touch sequence (and let it arrive the embedded view).
142 - (void)releaseGesture;
143
144 // Prevent the touch sequence from ever arriving to the embedded view.
145 - (void)blockGesture;
146
147 // Get embedded view
148 - (UIView*)embeddedView;
149
150 // Sets flutterAccessibilityContainer as this view's accessibilityContainer.
151 @property(nonatomic, retain) id flutterAccessibilityContainer;
152 @end
153
154 @interface UIView (FirstResponder)
155 // Returns YES if a view or any of its descendant view is the first responder. Returns NO otherwise.
156 @property(nonatomic, readonly) BOOL flt_hasFirstResponderInViewHierarchySubtree;
157 @end
158
159 // This recognizer delays touch events from being dispatched to the responder chain until it failed
160 // recognizing a gesture.
161 //
162 // We only fail this recognizer when asked to do so by the Flutter framework (which does so by
163 // invoking an acceptGesture method on the platform_views channel). And this is how we allow the
164 // Flutter framework to delay or prevent the embedded view from getting a touch sequence.
165 @interface FlutterDelayingGestureRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate>
166
167 // Indicates that if the `FlutterDelayingGestureRecognizer`'s state should be set to
168 // `UIGestureRecognizerStateEnded` during next `touchesEnded` call.
169 @property(nonatomic) BOOL shouldEndInNextTouchesEnded;
170
171 // Indicates that the `FlutterDelayingGestureRecognizer`'s `touchesEnded` has been invoked without
172 // setting the state to `UIGestureRecognizerStateEnded`.
173 @property(nonatomic) BOOL touchedEndedWithoutBlocking;
174
175 @property(nonatomic) UIGestureRecognizer* forwardingRecognizer;
176
177 - (instancetype)initWithTarget:(id)target
178 action:(SEL)action
179 forwardingRecognizer:(UIGestureRecognizer*)forwardingRecognizer;
180 @end
181
182 // While the FlutterDelayingGestureRecognizer is preventing touches from hitting the responder chain
183 // the touch events are not arriving to the FlutterView (and thus not arriving to the Flutter
184 // framework). We use this gesture recognizer to dispatch the events directly to the FlutterView
185 // while during this phase.
186 //
187 // If the Flutter framework decides to dispatch events to the embedded view, we fail the
188 // FlutterDelayingGestureRecognizer which sends the events up the responder chain. But since the
189 // events are handled by the embedded view they are not delivered to the Flutter framework in this
190 // phase as well. So during this phase as well the ForwardingGestureRecognizer dispatched the events
191 // directly to the FlutterView.
192 @interface ForwardingGestureRecognizer : UIGestureRecognizer <UIGestureRecognizerDelegate>
193 - (instancetype)initWithTarget:(id)target
194 platformViewsController:(FlutterPlatformViewsController*)platformViewsController;
195 - (ForwardingGestureRecognizer*)recreateRecognizerWithTarget:(id)target;
196 @end
197
198 #endif // FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_
UIView(FirstResponder)::flt_hasFirstResponderInViewHierarchySubtree
BOOL flt_hasFirstResponderInViewHierarchySubtree
Definition: FlutterPlatformViews_Internal.h:156
FlutterPlatformViews.h
PlatformViewFilter::backdropFilterView
UIVisualEffectView * backdropFilterView
Definition: FlutterPlatformViews_Internal.h:96
FlutterPlatformViewsController.h
ChildClippingView
Definition: FlutterPlatformViews.mm:143
-[FlutterTouchInterceptingView blockGesture]
void blockGesture()
Definition: FlutterPlatformViews.mm:584
-[FlutterClippingMaskView reset]
void reset()
Definition: FlutterPlatformViews.mm:234
-[FlutterTouchInterceptingView releaseGesture]
void releaseGesture()
Definition: FlutterPlatformViews.mm:565
FlutterClippingMaskView
Definition: FlutterPlatformViews.mm:206
-[PlatformViewFilter NS_UNAVAILABLE]
instancetype NS_UNAVAILABLE()
PlatformViewFilter
Definition: FlutterPlatformViews.mm:51
FlutterChannels.h
initWithFrame
instancetype initWithFrame
Definition: FlutterTextInputPlugin.h:172
+[PlatformViewFilter resetPreparation]
void resetPreparation()
Definition: FlutterPlatformViews.mm:78
PlatformViewFilter::frame
CGRect frame
Definition: FlutterPlatformViews_Internal.h:85
FlutterPlugin.h
FlutterClippingMaskViewPool
Definition: FlutterPlatformViews.mm:464
FlutterTouchInterceptingView::flutterAccessibilityContainer
id flutterAccessibilityContainer
Definition: FlutterPlatformViews_Internal.h:151
-[ChildClippingView backdropFilterSubviews]
NSMutableArray * backdropFilterSubviews()
Definition: FlutterPlatformViews.mm:181
FlutterViewResponder.h
ForwardingGestureRecognizer
Definition: FlutterPlatformViews.mm:700
FlutterDelayingGestureRecognizer
Definition: FlutterPlatformViews.mm:651
FlutterPlatformViewGestureRecognizersBlockingPolicy
FlutterPlatformViewGestureRecognizersBlockingPolicy
Definition: FlutterPlugin.h:252
PlatformViewFilter::blurRadius
CGFloat blurRadius
Definition: FlutterPlatformViews_Internal.h:90
UIView(FirstResponder)
Definition: FlutterPlatformViews.mm:501
FlutterPlatformViewsController
Definition: FlutterPlatformViewsController.h:31
FlutterTouchInterceptingView
Definition: FlutterPlatformViews.mm:521
-[FlutterTouchInterceptingView embeddedView]
UIView * embeddedView()
ios_context.h