• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 POSITION_DIMENSION = 2;
25 constexpr char END_CHAR = '\0';
26 
ParseStringToCharPtr(std::string str)27 ArkUI_CharPtr ParseStringToCharPtr(std::string str)
28 {
29     char* id = static_cast<char*>(malloc((str.length() + 1) * sizeof(char)));
30     CHECK_NULL_RETURN(id, nullptr);
31     str.copy(id, str.length());
32     id[str.length()] = END_CHAR;
33     return id;
34 }
35 
FreeGuideLineCharPtr(ArkUIGuidelineStyle * values,ArkUI_Int32 size)36 void FreeGuideLineCharPtr(ArkUIGuidelineStyle* values, ArkUI_Int32 size)
37 {
38     for (int32_t i = 0; i < size; ++i) {
39         free(const_cast<char*>(values[i].id));
40         values[i].id = nullptr;
41     }
42 }
43 
FreeBarrierCharPtr(ArkUIBarrierStyle * values,ArkUI_Int32 size)44 void FreeBarrierCharPtr(ArkUIBarrierStyle* values, ArkUI_Int32 size)
45 {
46     for (int32_t i = 0; i < size; ++i) {
47         free(const_cast<char*>(values[i].id));
48         values[i].id = nullptr;
49         auto referencedIdChar = values[i].referencedId;
50         auto referencedIdSize = values[i].referencedIdSize;
51         for (int32_t j = 0; j < referencedIdSize; ++j) {
52             free(const_cast<char*>(referencedIdChar[j]));
53             referencedIdChar[j] = nullptr;
54         }
55     }
56 }
57 
ParseReferencedId(EcmaVM * vm,int32_t referenceSize,const panda::Local<panda::ArrayRef> & array,std::vector<ArkUI_CharPtr> & referencedIds)58 void ParseReferencedId(EcmaVM* vm, int32_t referenceSize,
59     const panda::Local<panda::ArrayRef>& array, std::vector<ArkUI_CharPtr>& referencedIds)
60 {
61     for (int32_t i = 0; i < referenceSize; i++) {
62         Local<JSValueRef> referencedId = panda::ArrayRef::GetValueAt(vm, array, i);
63         if (referencedId->IsString(vm)) {
64             std::string str = referencedId->ToString(vm)->ToString(vm);
65             auto idChar = ParseStringToCharPtr(str);
66             if (idChar) {
67                 referencedIds.push_back(idChar);
68             }
69         }
70     }
71 }
72 
ParseGuideLine(const EcmaVM * vm,panda::Local<panda::ArrayRef> & positionsArr,const int32_t & i,ArkUIGuidelineStyle & info,std::vector<RefPtr<ResourceObject>> & resObjs)73 void ParseGuideLine(const EcmaVM *vm, panda::Local<panda::ArrayRef>& positionsArr, const int32_t& i,
74     ArkUIGuidelineStyle& info, std::vector<RefPtr<ResourceObject>>& resObjs)
75 {
76     Local<JSValueRef> posStartVal = panda::ArrayRef::GetValueAt(vm, positionsArr, i * POSITION_DIMENSION);
77     CalcDimension startPos;
78     RefPtr<ResourceObject> startPosResObj;
79     if (ArkTSUtils::ParseJsDimensionVpNG(vm, posStartVal, startPos, startPosResObj)) {
80         info.start = startPos.Value();
81         info.hasStart = true;
82     }
83     if (SystemProperties::ConfigChangePerform()) {
84         if (startPosResObj) {
85             resObjs.push_back(startPosResObj);
86         } else {
87             resObjs.push_back(nullptr);
88         }
89     }
90     Local<JSValueRef> posEndVal = panda::ArrayRef::GetValueAt(vm, positionsArr, i * POSITION_DIMENSION + 1);
91     CalcDimension endPos;
92     RefPtr<ResourceObject> endPosResObj;
93     if (ArkTSUtils::ParseJsDimensionVpNG(vm, posEndVal, endPos, endPosResObj)) {
94         info.end = endPos.Value();
95         info.hasEnd = true;
96     }
97     if (SystemProperties::ConfigChangePerform()) {
98         if (endPosResObj) {
99             resObjs.push_back(endPosResObj);
100         } else {
101             resObjs.push_back(nullptr);
102         }
103     }
104 }
105 } // namespace
106 
SetGuideLine(ArkUIRuntimeCallInfo * runtimeCallInfo)107 ArkUINativeModuleValue RelativeContainerBridge::SetGuideLine(ArkUIRuntimeCallInfo* runtimeCallInfo)
108 {
109     EcmaVM* vm = runtimeCallInfo->GetVM();
110     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
111     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
112     Local<JSValueRef> idsArg = runtimeCallInfo->GetCallArgRef(1);
113     Local<JSValueRef> directionsArg = runtimeCallInfo->GetCallArgRef(2);
114     Local<JSValueRef> positionsArg = runtimeCallInfo->GetCallArgRef(3);
115     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
116     if (!idsArg->IsArray(vm) || !directionsArg->IsArray(vm) || !positionsArg->IsArray(vm)) {
117         GetArkUINodeModifiers()->getRelativeContainerModifier()->resetGuideline(nativeNode);
118         return panda::JSValueRef::Undefined(vm);
119     }
120     std::vector<ArkUIGuidelineStyle> guidelineInfos;
121     auto idsArr = panda::Local<panda::ArrayRef>(idsArg);
122     auto directionsArr = panda::Local<panda::ArrayRef>(directionsArg);
123     auto positionsArr = panda::Local<panda::ArrayRef>(positionsArg);
124     int32_t size = static_cast<int32_t>(idsArr->Length(vm));
125     std::vector<RefPtr<ResourceObject>> resObjs;
126     for (int32_t i = 0; i < size; i++) {
127         ArkUIGuidelineStyle info;
128         Local<JSValueRef> idVal = panda::ArrayRef::GetValueAt(vm, idsArr, i);
129         if (idVal->IsString(vm)) {
130             std::string str = idVal->ToString(vm)->ToString(vm);
131             info.id = ParseStringToCharPtr(str);
132         }
133         Local<JSValueRef> directionVal = panda::ArrayRef::GetValueAt(vm, directionsArr, i);
134         if (directionVal->IsNumber()) {
135             info.direction = directionVal->Int32Value(vm);
136         }
137         ParseGuideLine(vm, positionsArr, i, info, resObjs);
138         guidelineInfos.push_back(info);
139     }
140     ArkUIGuidelineStyle* values = guidelineInfos.data();
141     auto rawPtr = static_cast<void*>(&resObjs);
142     GetArkUINodeModifiers()->getRelativeContainerModifier()->setGuideLine(nativeNode, values, size, rawPtr);
143     FreeGuideLineCharPtr(values, size);
144     return panda::JSValueRef::Undefined(vm);
145 }
146 
ResetGuideLine(ArkUIRuntimeCallInfo * runtimeCallInfo)147 ArkUINativeModuleValue RelativeContainerBridge::ResetGuideLine(ArkUIRuntimeCallInfo* runtimeCallInfo)
148 {
149     EcmaVM* vm = runtimeCallInfo->GetVM();
150     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
151     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
152     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
153     GetArkUINodeModifiers()->getRelativeContainerModifier()->resetGuideline(nativeNode);
154     return panda::JSValueRef::Undefined(vm);
155 }
156 
SetBarrier(ArkUIRuntimeCallInfo * runtimeCallInfo)157 ArkUINativeModuleValue RelativeContainerBridge::SetBarrier(ArkUIRuntimeCallInfo* runtimeCallInfo)
158 {
159     EcmaVM* vm = runtimeCallInfo->GetVM();
160     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
161     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
162     Local<JSValueRef> idsArg = runtimeCallInfo->GetCallArgRef(1);
163     Local<JSValueRef> directionsArg = runtimeCallInfo->GetCallArgRef(2);
164     Local<JSValueRef> referenceIdsArg = runtimeCallInfo->GetCallArgRef(3);
165     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
166     if (!idsArg->IsArray(vm) || !directionsArg->IsArray(vm) || !referenceIdsArg->IsArray(vm)) {
167         GetArkUINodeModifiers()->getRelativeContainerModifier()->resetBarrier(nativeNode);
168         return panda::JSValueRef::Undefined(vm);
169     }
170     std::vector<ArkUIBarrierStyle> barrierInfos;
171     auto idsArr = panda::Local<panda::ArrayRef>(idsArg);
172     auto directionsArr = panda::Local<panda::ArrayRef>(directionsArg);
173     auto referenceIdsArr = panda::Local<panda::ArrayRef>(referenceIdsArg);
174     int32_t size = static_cast<int32_t>(idsArr->Length(vm));
175     std::vector<ArkUI_CharPtr> referencedIds;
176     for (int32_t i = 0; i < size; i++) {
177         ArkUIBarrierStyle info;
178         Local<JSValueRef> idVal = panda::ArrayRef::GetValueAt(vm, idsArr, i);
179         Local<JSValueRef> directionVal = panda::ArrayRef::GetValueAt(vm, directionsArr, i);
180         Local<JSValueRef> referencedIdVal = panda::ArrayRef::GetValueAt(vm, referenceIdsArr, i);
181         if (idVal->IsString(vm)) {
182             std::string str = idVal->ToString(vm)->ToString(vm);
183             info.id = ParseStringToCharPtr(str);
184         }
185         if (directionVal->IsNumber()) {
186             info.direction = directionVal->Int32Value(vm);
187         }
188         if (referencedIdVal->IsArray(vm)) {
189             auto array = panda::Local<panda::ArrayRef>(referencedIdVal);
190             uint32_t referenceSize = array->Length(vm);
191             ParseReferencedId(vm, static_cast<int32_t>(referenceSize), array, referencedIds);
192             info.referencedId = referencedIds.data();
193             info.referencedIdSize = static_cast<int32_t>(referencedIds.size());
194             referencedIds.clear();
195         } else {
196             info.referencedIdSize = 0;
197         }
198         barrierInfos.push_back(info);
199     }
200     ArkUIBarrierStyle* values = barrierInfos.data();
201     GetArkUINodeModifiers()->getRelativeContainerModifier()->setBarrier(nativeNode, values, size);
202     FreeBarrierCharPtr(values, size);
203     return panda::JSValueRef::Undefined(vm);
204 }
205 
ResetBarrier(ArkUIRuntimeCallInfo * runtimeCallInfo)206 ArkUINativeModuleValue RelativeContainerBridge::ResetBarrier(ArkUIRuntimeCallInfo* runtimeCallInfo)
207 {
208     EcmaVM* vm = runtimeCallInfo->GetVM();
209     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
210     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
211     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
212     GetArkUINodeModifiers()->getRelativeContainerModifier()->resetBarrier(nativeNode);
213     return panda::JSValueRef::Undefined(vm);
214 }
215 } // namespace OHOS::Ace::NG
216