6 #include "flutter/lib/ui/semantics/semantics_node.h"
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) {
83 return self.node.HasAction(flutter::SemanticsAction::kTap);
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())};
100 SkM44 transform =
self.node.transform;
107 transform = ancestor.node.transform * transform;
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
189 - (id<UICoordinateSpace>)coordinateSpace {
192 return self.scrollView;
196 return self.scrollView;
202 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(
226 self.semanticsObject.uid, flutter::SemanticsAction::kScrollToOffset,
227 fml::MallocMapping::Copy(encoded.bytes, encoded.length));
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()
instancetype typedDataWithFloat64:(NSData *data)
NSArray< SemanticsObject * > * childrenInHitTestOrder
instancetype sharedInstance()