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#include "flutter/lib/ui/semantics/semantics_update_builder.h"
6#include "flutter/lib/ui/ui_dart_state.h"
7
8#include "third_party/skia/include/core/SkScalar.h"
9#include "third_party/tonic/converter/dart_converter.h"
10#include "third_party/tonic/dart_args.h"
11#include "third_party/tonic/dart_binding_macros.h"
12#include "third_party/tonic/dart_library_natives.h"
13
14namespace flutter {
15
16static void SemanticsUpdateBuilder_constructor(Dart_NativeArguments args) {
17 UIDartState::ThrowIfUIOperationsProhibited();
18 DartCallConstructor(&SemanticsUpdateBuilder::create, args);
19}
20
21IMPLEMENT_WRAPPERTYPEINFO(ui, SemanticsUpdateBuilder);
22
23#define FOR_EACH_BINDING(V) \
24 V(SemanticsUpdateBuilder, updateNode) \
25 V(SemanticsUpdateBuilder, updateCustomAction) \
26 V(SemanticsUpdateBuilder, build)
27
28FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
29
30void SemanticsUpdateBuilder::RegisterNatives(
31 tonic::DartLibraryNatives* natives) {
32 natives->Register({{"SemanticsUpdateBuilder_constructor",
33 SemanticsUpdateBuilder_constructor, 1, true},
34 FOR_EACH_BINDING(DART_REGISTER_NATIVE)});
35}
36
37SemanticsUpdateBuilder::SemanticsUpdateBuilder() = default;
38
39SemanticsUpdateBuilder::~SemanticsUpdateBuilder() = default;
40
41void SemanticsUpdateBuilder::updateNode(
42 int id,
43 int flags,
44 int actions,
45 int maxValueLength,
46 int currentValueLength,
47 int textSelectionBase,
48 int textSelectionExtent,
49 int platformViewId,
50 int scrollChildren,
51 int scrollIndex,
52 double scrollPosition,
53 double scrollExtentMax,
54 double scrollExtentMin,
55 double left,
56 double top,
57 double right,
58 double bottom,
59 double elevation,
60 double thickness,
61 std::string label,
62 std::string hint,
63 std::string value,
64 std::string increasedValue,
65 std::string decreasedValue,
66 int textDirection,
67 const tonic::Float64List& transform,
68 const tonic::Int32List& childrenInTraversalOrder,
69 const tonic::Int32List& childrenInHitTestOrder,
70 const tonic::Int32List& localContextActions) {
71 FML_CHECK(transform.data() && SkScalarsAreFinite(*transform.data(), 9))
72 << "Semantics update transform was not set or not finite.";
73 FML_CHECK(scrollChildren == 0 ||
74 (scrollChildren > 0 && childrenInHitTestOrder.data()))
75 << "Semantics update contained scrollChildren but did not have "
76 "childrenInHitTestOrder";
77 SemanticsNode node;
78 node.id = id;
79 node.flags = flags;
80 node.actions = actions;
81 node.maxValueLength = maxValueLength;
82 node.currentValueLength = currentValueLength;
83 node.textSelectionBase = textSelectionBase;
84 node.textSelectionExtent = textSelectionExtent;
85 node.platformViewId = platformViewId;
86 node.scrollChildren = scrollChildren;
87 node.scrollIndex = scrollIndex;
88 node.scrollPosition = scrollPosition;
89 node.scrollExtentMax = scrollExtentMax;
90 node.scrollExtentMin = scrollExtentMin;
91 node.rect = SkRect::MakeLTRB(left, top, right, bottom);
92 node.elevation = elevation;
93 node.thickness = thickness;
94 node.label = label;
95 node.hint = hint;
96 node.value = value;
97 node.increasedValue = increasedValue;
98 node.decreasedValue = decreasedValue;
99 node.textDirection = textDirection;
100 SkScalar scalarTransform[16];
101 for (int i = 0; i < 16; ++i) {
102 scalarTransform[i] = transform.data()[i];
103 }
104 node.transform = SkM44::ColMajor(scalarTransform);
105 node.childrenInTraversalOrder =
106 std::vector<int32_t>(childrenInTraversalOrder.data(),
107 childrenInTraversalOrder.data() +
108 childrenInTraversalOrder.num_elements());
109 node.childrenInHitTestOrder = std::vector<int32_t>(
110 childrenInHitTestOrder.data(),
111 childrenInHitTestOrder.data() + childrenInHitTestOrder.num_elements());
112 node.customAccessibilityActions = std::vector<int32_t>(
113 localContextActions.data(),
114 localContextActions.data() + localContextActions.num_elements());
115 nodes_[id] = node;
116}
117
118void SemanticsUpdateBuilder::updateCustomAction(int id,
119 std::string label,
120 std::string hint,
121 int overrideId) {
122 CustomAccessibilityAction action;
123 action.id = id;
124 action.overrideId = overrideId;
125 action.label = label;
126 action.hint = hint;
127 actions_[id] = action;
128}
129
130void SemanticsUpdateBuilder::build(Dart_Handle semantics_update_handle) {
131 SemanticsUpdate::create(semantics_update_handle, std::move(nodes_),
132 std::move(actions_));
133}
134
135} // namespace flutter
136