32@interface SemanticsObject (UIFocusSystem) <UIFocusItem, UIFocusItemContainer>
40@implementation SemanticsObject (UIFocusSystem)
46#pragma mark - UIFocusEnvironment Conformance
48- (void)setNeedsFocusUpdate {
51- (void)updateFocusIfNeeded {
54- (
BOOL)shouldUpdateFocusInContext:(UIFocusUpdateContext*)context {
58- (void)didUpdateFocusInContext:(UIFocusUpdateContext*)context
59 withAnimationCoordinator:(UIFocusAnimationCoordinator*)coordinator {
62- (
id<UIFocusEnvironment>)parentFocusEnvironment {
64 return self.parent.focusItem ?: ([
self isAccessibilityBridgeAlive] ?
self.bridge->view() : nil);
67- (NSArray<
id<UIFocusEnvironment>>*)preferredFocusEnvironments {
71- (
id<UIFocusItemContainer>)focusItemContainer {
75#pragma mark - UIFocusItem Conformance
77- (
BOOL)canBecomeFocused {
78 if (
self.node.flags.isHidden) {
92 if (![
self isAccessibilityBridgeAlive]) {
95 SkPoint quad[4] = {SkPoint::Make(
self.node.rect.left(),
self.node.rect.top()),
96 SkPoint::Make(
self.node.rect.left(),
self.node.rect.bottom()),
97 SkPoint::Make(
self.node.rect.right(),
self.node.rect.top()),
98 SkPoint::Make(
self.node.rect.right(),
self.node.rect.bottom())};
110 for (
auto& vertex : quad) {
111 SkV4 vector =
transform.map(vertex.x(), vertex.y(), 0, 1);
112 vertex = SkPoint::Make(vector.x / vector.w, vector.y / vector.w);
116 rect.setBounds({quad, 4});
124 CGRect unscaledRect =
125 CGRectMake(rect.x() + scrollView.bounds.origin.x, rect.y() + scrollView.bounds.origin.y,
126 rect.width(), rect.height());
137 CGFloat scale = (
self.bridge->view().window.screen ?: UIScreen.mainScreen).scale;
138 return CGRectMake(unscaledRect.origin.x / scale, unscaledRect.origin.y / scale,
139 unscaledRect.size.width / scale, unscaledRect.size.height / scale);
142#pragma mark - UIFocusItemContainer Conformance
144- (NSArray<
id<UIFocusItem>>*)focusItemsInRect:(CGRect)rect {
154 NSMutableArray<id<UIFocusItem>>* reversedItems =
155 [[NSMutableArray alloc] initWithCapacity:self.childrenInHitTestOrder.count];
156 for (NSUInteger
i = 0;
i <
self.childrenInHitTestOrder.count; ++
i) {
158 [reversedItems addObject:child.focusItem];
160 return reversedItems;
163- (
id<UICoordinateSpace>)coordinateSpace {
165 return self.parent.coordinateSpace
166 ?: ([
self isAccessibilityBridgeAlive] ?
self.bridge->view() : nil);
183#pragma mark - Scrolling
185@interface FlutterScrollableSemanticsObject (CoordinateSpace)
188@implementation FlutterScrollableSemanticsObject (CoordinateSpace)
189- (
id<UICoordinateSpace>)coordinateSpace {
192 return self.scrollView;
195- (
id<UIFocusItem>)focusItem {
196 return self.scrollView;
201@interface FlutterSemanticsScrollView (UIFocusItemScrollableContainer) <
202 UIFocusItemScrollableContainer>
205@implementation FlutterSemanticsScrollView (UIFocusItemScrollableContainer)
207#pragma mark - FlutterSemanticsScrollView UIFocusItemScrollableContainer Conformance
209- (CGSize)visibleSize {
210 return self.frame.size;
213- (void)setContentOffset:(CGPoint)contentOffset {
214 [
super setContentOffset:contentOffset];
217 if (![
self.semanticsObject isAccessibilityBridgeAlive] || !
self.isDoingSystemScrolling) {
221 double offset[2] = {contentOffset.x, contentOffset.y};
225 self.semanticsObject.bridge->DispatchSemanticsAction(
230- (
BOOL)canBecomeFocused {
234- (
id<UIFocusEnvironment>)parentFocusEnvironment {
235 return self.semanticsObject.parentFocusEnvironment;
238- (NSArray<
id<UIFocusEnvironment>>*)preferredFocusEnvironments {
242- (NSArray<
id<UIFocusItem>>*)focusItemsInRect:(CGRect)rect {
243 return [
self.semanticsObject focusItemsInRect:rect];
id< UIFocusItem > focusItem()
static MallocMapping Copy(const T *begin, const T *end)
instancetype typedDataWithFloat64:(NSData *data)
NSArray< SemanticsObject * > * childrenInHitTestOrder
instancetype sharedInstance()