1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_relative_container_bridge.h"
16
17 #include "base/geometry/calc_dimension.h"
18 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
19 #include "core/components_ng/pattern/relative_container/relative_container_model_ng.h"
20 #include "core/interfaces/arkoala/arkoala_api.h"
21
22 namespace OHOS::Ace::NG {
23 namespace {
24 constexpr int NUM_0 = 0;
25 constexpr int NUM_1 = 1;
26 constexpr int NUM_2 = 2;
27 constexpr int NUM_3 = 3;
28 constexpr int POSITION_DIMENSION = 2;
29 constexpr char END_CHAR = '\0';
30
ParseStringToCharPtr(std::string str)31 ArkUI_CharPtr ParseStringToCharPtr(std::string str)
32 {
33 char* id = static_cast<char*>(malloc((str.length() + 1) * sizeof(char)));
34 CHECK_NULL_RETURN(id, nullptr);
35 str.copy(id, str.length());
36 id[str.length()] = END_CHAR;
37 return id;
38 }
39
FreeGuideLineCharPtr(ArkUIGuidelineStyle * values,ArkUI_Int32 size)40 void FreeGuideLineCharPtr(ArkUIGuidelineStyle* values, ArkUI_Int32 size)
41 {
42 for (int32_t i = 0; i < size; ++i) {
43 free(const_cast<char*>(values[i].id));
44 values[i].id = nullptr;
45 }
46 }
47
FreeBarrierCharPtr(ArkUIBarrierStyle * values,ArkUI_Int32 size)48 void FreeBarrierCharPtr(ArkUIBarrierStyle* values, ArkUI_Int32 size)
49 {
50 for (int32_t i = 0; i < size; ++i) {
51 free(const_cast<char*>(values[i].id));
52 values[i].id = nullptr;
53 auto referencedIdChar = values[i].referencedId;
54 auto referencedIdSize = values[i].referencedIdSize;
55 for (int32_t j = 0; j < referencedIdSize; ++j) {
56 free(const_cast<char*>(referencedIdChar[j]));
57 referencedIdChar[j] = nullptr;
58 }
59 }
60 }
61
ParseReferencedId(EcmaVM * vm,int32_t referenceSize,const panda::Local<panda::ArrayRef> & array,std::vector<ArkUI_CharPtr> & referencedIds)62 void ParseReferencedId(EcmaVM* vm, int32_t referenceSize,
63 const panda::Local<panda::ArrayRef>& array, std::vector<ArkUI_CharPtr>& referencedIds)
64 {
65 for (int32_t i = 0; i < referenceSize; i++) {
66 Local<JSValueRef> referencedId = panda::ArrayRef::GetValueAt(vm, array, i);
67 if (referencedId->IsString(vm)) {
68 std::string str = referencedId->ToString(vm)->ToString(vm);
69 referencedIds.push_back(ParseStringToCharPtr(str));
70 }
71 }
72 }
73 } // namespace
74
SetGuideLine(ArkUIRuntimeCallInfo * runtimeCallInfo)75 ArkUINativeModuleValue RelativeContainerBridge::SetGuideLine(ArkUIRuntimeCallInfo* runtimeCallInfo)
76 {
77 EcmaVM* vm = runtimeCallInfo->GetVM();
78 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
79 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
80 Local<JSValueRef> idsArg = runtimeCallInfo->GetCallArgRef(NUM_1);
81 Local<JSValueRef> directionsArg = runtimeCallInfo->GetCallArgRef(NUM_2);
82 Local<JSValueRef> positionsArg = runtimeCallInfo->GetCallArgRef(NUM_3);
83 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
84 if (!idsArg->IsArray(vm) || !directionsArg->IsArray(vm) || !positionsArg->IsArray(vm)) {
85 GetArkUINodeModifiers()->getRelativeContainerModifier()->resetGuideline(nativeNode);
86 return panda::JSValueRef::Undefined(vm);
87 }
88 std::vector<ArkUIGuidelineStyle> guidelineInfos;
89 auto idsArr = panda::Local<panda::ArrayRef>(idsArg);
90 auto directionsArr = panda::Local<panda::ArrayRef>(directionsArg);
91 auto positionsArr = panda::Local<panda::ArrayRef>(positionsArg);
92 int32_t size = static_cast<int32_t>(idsArr->Length(vm));
93 for (int32_t i = 0; i < size; i++) {
94 ArkUIGuidelineStyle info;
95 Local<JSValueRef> idVal = panda::ArrayRef::GetValueAt(vm, idsArr, i);
96 if (idVal->IsString(vm)) {
97 std::string str = idVal->ToString(vm)->ToString(vm);
98 info.id = ParseStringToCharPtr(str);
99 }
100 Local<JSValueRef> directionVal = panda::ArrayRef::GetValueAt(vm, directionsArr, i);
101 if (directionVal->IsNumber()) {
102 info.direction = directionVal->Int32Value(vm);
103 }
104 Local<JSValueRef> posStartVal = panda::ArrayRef::GetValueAt(vm,
105 positionsArr, i * POSITION_DIMENSION);
106 CalcDimension startPos;
107 if (ArkTSUtils::ParseJsDimensionVpNG(vm, posStartVal, startPos)) {
108 info.start = startPos.Value();
109 info.hasStart = true;
110 }
111 Local<JSValueRef> posEndVal = panda::ArrayRef::GetValueAt(vm,
112 positionsArr, i * POSITION_DIMENSION + 1);
113 CalcDimension endPos;
114 if (ArkTSUtils::ParseJsDimensionVpNG(vm, posEndVal, endPos)) {
115 info.end = endPos.Value();
116 info.hasEnd = true;
117 }
118 guidelineInfos.push_back(info);
119 }
120 ArkUIGuidelineStyle* values = guidelineInfos.data();
121 GetArkUINodeModifiers()->getRelativeContainerModifier()->setGuideLine(nativeNode, values, size);
122 FreeGuideLineCharPtr(values, size);
123 return panda::JSValueRef::Undefined(vm);
124 }
125
ResetGuideLine(ArkUIRuntimeCallInfo * runtimeCallInfo)126 ArkUINativeModuleValue RelativeContainerBridge::ResetGuideLine(ArkUIRuntimeCallInfo* runtimeCallInfo)
127 {
128 EcmaVM* vm = runtimeCallInfo->GetVM();
129 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
130 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
131 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
132 GetArkUINodeModifiers()->getRelativeContainerModifier()->resetGuideline(nativeNode);
133 return panda::JSValueRef::Undefined(vm);
134 }
135
SetBarrier(ArkUIRuntimeCallInfo * runtimeCallInfo)136 ArkUINativeModuleValue RelativeContainerBridge::SetBarrier(ArkUIRuntimeCallInfo* runtimeCallInfo)
137 {
138 EcmaVM* vm = runtimeCallInfo->GetVM();
139 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
140 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
141 Local<JSValueRef> idsArg = runtimeCallInfo->GetCallArgRef(NUM_1);
142 Local<JSValueRef> directionsArg = runtimeCallInfo->GetCallArgRef(NUM_2);
143 Local<JSValueRef> referenceIdsArg = runtimeCallInfo->GetCallArgRef(NUM_3);
144 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
145 if (!idsArg->IsArray(vm) || !directionsArg->IsArray(vm) || !referenceIdsArg->IsArray(vm)) {
146 GetArkUINodeModifiers()->getRelativeContainerModifier()->resetBarrier(nativeNode);
147 return panda::JSValueRef::Undefined(vm);
148 }
149 std::vector<ArkUIBarrierStyle> barrierInfos;
150 auto idsArr = panda::Local<panda::ArrayRef>(idsArg);
151 auto directionsArr = panda::Local<panda::ArrayRef>(directionsArg);
152 auto referenceIdsArr = panda::Local<panda::ArrayRef>(referenceIdsArg);
153 int32_t size = static_cast<int32_t>(idsArr->Length(vm));
154 std::vector<ArkUI_CharPtr> referencedIds;
155 for (int32_t i = 0; i < size; i++) {
156 ArkUIBarrierStyle info;
157 Local<JSValueRef> idVal = panda::ArrayRef::GetValueAt(vm, idsArr, i);
158 Local<JSValueRef> directionVal = panda::ArrayRef::GetValueAt(vm, directionsArr, i);
159 Local<JSValueRef> referencedIdVal = panda::ArrayRef::GetValueAt(vm, referenceIdsArr, i);
160 if (idVal->IsString(vm)) {
161 std::string str = idVal->ToString(vm)->ToString(vm);
162 info.id = ParseStringToCharPtr(str);
163 }
164 if (directionVal->IsNumber()) {
165 info.direction = directionVal->Int32Value(vm);
166 }
167 if (referencedIdVal->IsArray(vm)) {
168 auto array = panda::Local<panda::ArrayRef>(referencedIdVal);
169 uint32_t referenceSize = array->Length(vm);
170 ParseReferencedId(vm, static_cast<int32_t>(referenceSize), array, referencedIds);
171 info.referencedId = referencedIds.data();
172 info.referencedIdSize = static_cast<int32_t>(referencedIds.size());
173 referencedIds.clear();
174 } else {
175 info.referencedIdSize = 0;
176 }
177 barrierInfos.push_back(info);
178 }
179 ArkUIBarrierStyle* values = barrierInfos.data();
180 GetArkUINodeModifiers()->getRelativeContainerModifier()->setBarrier(nativeNode, values, size);
181 FreeBarrierCharPtr(values, size);
182 return panda::JSValueRef::Undefined(vm);
183 }
184
ResetBarrier(ArkUIRuntimeCallInfo * runtimeCallInfo)185 ArkUINativeModuleValue RelativeContainerBridge::ResetBarrier(ArkUIRuntimeCallInfo* runtimeCallInfo)
186 {
187 EcmaVM* vm = runtimeCallInfo->GetVM();
188 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
189 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
190 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
191 GetArkUINodeModifiers()->getRelativeContainerModifier()->resetBarrier(nativeNode);
192 return panda::JSValueRef::Undefined(vm);
193 }
194 } // namespace OHOS::Ace::NG
195