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.bridge->view();
67 - (NSArray<id<UIFocusEnvironment>>*)preferredFocusEnvironments {
71 - (id<UIFocusItemContainer>)focusItemContainer {
75 #pragma mark - UIFocusItem Conformance
77 - (BOOL)canBecomeFocused {
78 if ((
self.node.flags &
static_cast<int32_t
>(flutter::SemanticsFlags::kIsHidden)) != 0) {
83 return self.node.HasAction(flutter::SemanticsAction::kTap);
92 SkPoint quad[4] = {SkPoint::Make(
self.node.rect.left(),
self.node.rect.top()),
93 SkPoint::Make(
self.node.rect.left(),
self.node.rect.bottom()),
94 SkPoint::Make(
self.node.rect.right(),
self.node.rect.top()),
95 SkPoint::Make(
self.node.rect.right(),
self.node.rect.bottom())};
97 SkM44 transform =
self.node.transform;
104 transform = ancestor.node.transform * transform;
107 for (
auto& vertex : quad) {
108 SkV4 vector = transform.map(vertex.x(), vertex.y(), 0, 1);
109 vertex = SkPoint::Make(vector.x / vector.w, vector.y / vector.w);
113 rect.setBounds(quad, 4);
121 CGRect unscaledRect =
122 CGRectMake(rect.x() + scrollView.bounds.origin.x, rect.y() + scrollView.bounds.origin.y,
123 rect.width(), rect.height());
134 CGFloat scale = (
self.bridge->view().window.screen ?: UIScreen.mainScreen).scale;
135 return CGRectMake(unscaledRect.origin.x / scale, unscaledRect.origin.y / scale,
136 unscaledRect.size.width / scale, unscaledRect.size.height / scale);
139 #pragma mark - UIFocusItemContainer Conformance
141 - (NSArray<id<UIFocusItem>>*)focusItemsInRect:(CGRect)rect {
151 NSMutableArray<id<UIFocusItem>>* reversedItems =
152 [[NSMutableArray alloc] initWithCapacity:self.childrenInHitTestOrder.count];
153 for (NSUInteger i = 0; i <
self.childrenInHitTestOrder.count; ++i) {
155 [reversedItems addObject:child.focusItem];
157 return reversedItems;
160 - (id<UICoordinateSpace>)coordinateSpace {
162 return self.parent.coordinateSpace ?:
self.bridge->view();
179 #pragma mark - Scrolling
185 - (id<UICoordinateSpace>)coordinateSpace {
188 return self.scrollView;
192 return self.scrollView;
198 UIFocusItemScrollableContainer>
203 #pragma mark - FlutterSemanticsScrollView UIFocusItemScrollableContainer Conformance
205 - (CGSize)visibleSize {
206 return self.frame.size;
209 - (void)setContentOffset:(CGPoint)contentOffset {
210 [
super setContentOffset:contentOffset];
213 if (![
self.semanticsObject isAccessibilityBridgeAlive] || !
self.isDoingSystemScrolling) {
217 double offset[2] = {contentOffset.x, contentOffset.y};
221 self.semanticsObject.bridge->DispatchSemanticsAction(
222 self.semanticsObject.uid, flutter::SemanticsAction::kScrollToOffset,
223 fml::MallocMapping::Copy(encoded.bytes, encoded.length));
226 - (BOOL)canBecomeFocused {
230 - (id<UIFocusEnvironment>)parentFocusEnvironment {
231 return self.semanticsObject.parentFocusEnvironment;
234 - (NSArray<id<UIFocusEnvironment>>*)preferredFocusEnvironments {
238 - (NSArray<id<UIFocusItem>>*)focusItemsInRect:(CGRect)rect {
239 return [
self.semanticsObject focusItemsInRect:rect];