1 /*
2 * Copyright (c) 2022 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
16 #include "bridge/declarative_frontend/jsview/js_view_measure_layout.h"
17
18 #include "jsnapi.h"
19
20 #include "base/geometry/dimension.h"
21 #include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
22 #include "frameworks/core/components_ng/base/frame_node.h"
23 #include "frameworks/core/components_ng/pattern/custom/custom_measure_layout_node.h"
24
25 namespace OHOS::Ace::Framework {
26
27 #ifdef USE_ARK_ENGINE
28
29 namespace {
30 using OHOS::Ace::NG::LayoutConstraintF;
31 using OHOS::Ace::NG::LayoutProperty;
32 using OHOS::Ace::NG::SizeF;
GenConstraint(const std::optional<NG::LayoutConstraintF> & parentConstraint)33 JSRef<JSObject> GenConstraint(const std::optional<NG::LayoutConstraintF>& parentConstraint)
34 {
35 auto minSize = parentConstraint->minSize;
36 auto maxSize = parentConstraint->maxSize;
37 JSRef<JSObject> constraint = JSRef<JSObject>::New();
38 constraint->SetProperty<double>("minWidth", minSize.Width());
39 constraint->SetProperty<double>("minHeight", minSize.Height());
40 constraint->SetProperty<double>("maxWidth", maxSize.Width());
41 constraint->SetProperty<double>("maxHeight", maxSize.Height());
42 return constraint;
43 }
44
GenConstraintNG(const NG::LayoutConstraintF & parentConstraint)45 JSRef<JSObject> GenConstraintNG(const NG::LayoutConstraintF& parentConstraint)
46 {
47 auto minSize = parentConstraint.minSize;
48 auto maxSize = parentConstraint.maxSize;
49 JSRef<JSObject> constraint = JSRef<JSObject>::New();
50 auto pipeline = PipelineBase::GetCurrentContext();
51 constraint->SetProperty<double>("minWidth", minSize.Width() / pipeline->GetDipScale());
52 constraint->SetProperty<double>("minHeight", minSize.Height() / pipeline->GetDipScale());
53 constraint->SetProperty<double>("maxWidth", maxSize.Width() / pipeline->GetDipScale());
54 constraint->SetProperty<double>("maxHeight", maxSize.Height() / pipeline->GetDipScale());
55 return constraint;
56 }
57
GenPlaceChildrenConstraintNG(const NG::SizeF & size,RefPtr<NG::LayoutProperty> layoutProperty)58 JSRef<JSObject> GenPlaceChildrenConstraintNG(const NG::SizeF& size, RefPtr<NG::LayoutProperty> layoutProperty)
59 {
60 JSRef<JSObject> constraint = JSRef<JSObject>::New();
61 auto pipeline = PipelineBase::GetCurrentContext();
62 CHECK_NULL_RETURN(pipeline, JSRef<JSObject>::New());
63 if (!layoutProperty) {
64 constraint->SetProperty<double>("minWidth", 0.0f);
65 constraint->SetProperty<double>("minHeight", 0.0f);
66 constraint->SetProperty<double>("maxWidth", 0.0f);
67 constraint->SetProperty<double>("maxHeight", 0.0f);
68 return constraint;
69 }
70 auto minSize = layoutProperty->GetLayoutConstraint().value().minSize;
71 constraint->SetProperty<double>("minWidth", minSize.Width() / pipeline->GetDipScale());
72 constraint->SetProperty<double>("minHeight", minSize.Height() / pipeline->GetDipScale());
73 auto parentNode = AceType::DynamicCast<NG::FrameNode>(layoutProperty->GetHost()->GetParent());
74 if (parentNode && parentNode->GetTag() == V2::COMMON_VIEW_ETS_TAG) {
75 layoutProperty = parentNode->GetLayoutProperty();
76 }
77 const std::unique_ptr<NG::PaddingProperty>& padding = layoutProperty->GetPaddingProperty();
78 const std::unique_ptr<NG::BorderWidthProperty>& borderWidth = layoutProperty->GetBorderWidthProperty();
79 auto topPadding = padding ? padding->top->GetDimension().ConvertToVp() : 0.0f;
80 auto bottomPadding = padding ? padding->bottom->GetDimension().ConvertToVp() : 0.0f;
81 auto leftPadding = padding ? padding->left->GetDimension().ConvertToVp() : 0.0f;
82 auto rightPadding = padding ? padding->right->GetDimension().ConvertToVp() : 0.0f;
83 auto topBorder = borderWidth ? borderWidth->topDimen->ConvertToVp() : 0.0f;
84 auto bottomBorder = borderWidth ? borderWidth->bottomDimen->ConvertToVp() : 0.0f;
85 auto leftBorder = borderWidth ? borderWidth->leftDimen->ConvertToVp() : 0.0f;
86 auto rightBorder = borderWidth ? borderWidth->rightDimen->ConvertToVp() : 0.0f;
87 constraint->SetProperty<double>("maxWidth", size.Width() / pipeline->GetDipScale() - leftPadding - rightPadding -
88 leftBorder - rightBorder);
89 constraint->SetProperty<double>("maxHeight", size.Height() / pipeline->GetDipScale() - topPadding - bottomPadding -
90 topBorder - bottomBorder);
91 return constraint;
92 }
93
GenPadding(const std::unique_ptr<NG::PaddingProperty> & paddingNative)94 JSRef<JSObject> GenPadding(const std::unique_ptr<NG::PaddingProperty>& paddingNative)
95 {
96 JSRef<JSObject> padding = JSRef<JSObject>::New();
97 padding->SetProperty("top", paddingNative->top->GetDimension().ConvertToVp());
98 padding->SetProperty("right", paddingNative->right->GetDimension().ConvertToVp());
99 padding->SetProperty("bottom", paddingNative->bottom->GetDimension().ConvertToVp());
100 padding->SetProperty("left", paddingNative->left->GetDimension().ConvertToVp());
101 return padding;
102 }
103
GenMargin(const std::unique_ptr<NG::MarginProperty> & marginNative)104 JSRef<JSObject> GenMargin(const std::unique_ptr<NG::MarginProperty>& marginNative)
105 {
106 JSRef<JSObject> margin = JSRef<JSObject>::New();
107 margin->SetProperty("top", marginNative->top->GetDimension().ConvertToVp());
108 margin->SetProperty("right", marginNative->right->GetDimension().ConvertToVp());
109 margin->SetProperty("bottom", marginNative->bottom->GetDimension().ConvertToVp());
110 margin->SetProperty("left", marginNative->left->GetDimension().ConvertToVp());
111 return margin;
112 }
113
GenEdgeWidths(const std::unique_ptr<NG::BorderWidthProperty> & edgeWidthsNative)114 JSRef<JSObject> GenEdgeWidths(const std::unique_ptr<NG::BorderWidthProperty>& edgeWidthsNative)
115 {
116 JSRef<JSObject> edgeWidths = JSRef<JSObject>::New();
117 edgeWidths->SetProperty("top", edgeWidthsNative->topDimen->ConvertToVp());
118 edgeWidths->SetProperty("right", edgeWidthsNative->rightDimen->ConvertToVp());
119 edgeWidths->SetProperty("bottom", edgeWidthsNative->bottomDimen->ConvertToVp());
120 edgeWidths->SetProperty("left", edgeWidthsNative->leftDimen->ConvertToVp());
121 return edgeWidths;
122 }
123
GenEdgesGlobalized(const NG::PaddingPropertyT<float> & edgeNative,TextDirection direction)124 JSRef<JSObject> GenEdgesGlobalized(const NG::PaddingPropertyT<float>& edgeNative, TextDirection direction)
125 {
126 JSRef<JSObject> edges = JSRef<JSObject>::New();
127 auto pipeline = PipelineBase::GetCurrentContext();
128 double px2vpScale = pipeline ? 1.0 / pipeline->GetDipScale() : 1.0;
129 edges->SetProperty("top", edgeNative.top.value_or(0) * px2vpScale);
130 edges->SetProperty("bottom", edgeNative.bottom.value_or(0) * px2vpScale);
131 if (direction != TextDirection::RTL) {
132 edges->SetProperty("start", edgeNative.left.value_or(0) * px2vpScale);
133 edges->SetProperty("end", edgeNative.right.value_or(0) * px2vpScale);
134 } else {
135 edges->SetProperty("start", edgeNative.right.value_or(0) * px2vpScale);
136 edges->SetProperty("end", edgeNative.left.value_or(0) * px2vpScale);
137 }
138 return edges;
139 }
140
GenBorderWidthGlobalized(const NG::BorderWidthPropertyT<float> & edgeNative,TextDirection direction)141 JSRef<JSObject> GenBorderWidthGlobalized(const NG::BorderWidthPropertyT<float>& edgeNative, TextDirection direction)
142 {
143 JSRef<JSObject> edges = JSRef<JSObject>::New();
144 auto pipeline = PipelineBase::GetCurrentContext();
145 double px2vpScale = pipeline ? 1.0 / pipeline->GetDipScale() : 1.0;
146 edges->SetProperty("top", edgeNative.topDimen.value_or(0) * px2vpScale);
147 edges->SetProperty("bottom", edgeNative.bottomDimen.value_or(0) * px2vpScale);
148 if (direction != TextDirection::RTL) {
149 edges->SetProperty("start", edgeNative.leftDimen.value_or(0) * px2vpScale);
150 edges->SetProperty("end", edgeNative.rightDimen.value_or(0) * px2vpScale);
151 } else {
152 edges->SetProperty("start", edgeNative.rightDimen.value_or(0) * px2vpScale);
153 edges->SetProperty("end", edgeNative.leftDimen.value_or(0) * px2vpScale);
154 }
155 return edges;
156 }
157
GenBorderInfo(const RefPtr<NG::LayoutWrapper> & layoutWrapper)158 JSRef<JSObject> GenBorderInfo(const RefPtr<NG::LayoutWrapper>& layoutWrapper)
159 {
160 JSRef<JSObject> borderInfo = JSRef<JSObject>::New();
161 auto layoutProperty = layoutWrapper->GetLayoutProperty();
162 const std::unique_ptr<NG::PaddingProperty> defaultPadding = std::make_unique<NG::PaddingProperty>();
163 const std::unique_ptr<NG::PaddingProperty> defaultMargin = std::make_unique<NG::MarginProperty>();
164 const std::unique_ptr<NG::BorderWidthProperty>& defaultEdgeWidth = std::make_unique<NG::BorderWidthProperty>();
165 if (!layoutProperty) {
166 borderInfo->SetPropertyObject("borderWidth", GenEdgeWidths(defaultEdgeWidth));
167 borderInfo->SetPropertyObject("margin", GenMargin(defaultPadding));
168 borderInfo->SetPropertyObject("padding", GenPadding(defaultPadding));
169 return borderInfo;
170 }
171
172 borderInfo->SetPropertyObject("borderWidth",
173 GenEdgeWidths(
174 layoutProperty->GetBorderWidthProperty() ? layoutProperty->GetBorderWidthProperty() : defaultEdgeWidth));
175
176 borderInfo->SetPropertyObject("margin",
177 GenMargin(layoutProperty->GetMarginProperty() ? layoutProperty->GetMarginProperty() : defaultMargin));
178 borderInfo->SetPropertyObject("padding",
179 GenPadding(layoutProperty->GetPaddingProperty() ? layoutProperty->GetPaddingProperty() : defaultPadding));
180
181 return borderInfo;
182 }
183
GenPositionInfo(const RefPtr<NG::LayoutWrapper> & layoutWrapper)184 JSRef<JSObject> GenPositionInfo(const RefPtr<NG::LayoutWrapper>& layoutWrapper)
185 {
186 auto offset = layoutWrapper->GetGeometryNode()->GetFrameOffset();
187 JSRef<JSObject> position = JSRef<JSObject>::New();
188 position->SetProperty("x", offset.GetX());
189 position->SetProperty("y", offset.GetY());
190 return position;
191 }
192
GenSelfLayoutInfo(RefPtr<NG::LayoutProperty> layoutProperty)193 JSRef<JSObject> GenSelfLayoutInfo(RefPtr<NG::LayoutProperty> layoutProperty)
194 {
195 JSRef<JSObject> selfLayoutInfo = JSRef<JSObject>::New();
196 const std::unique_ptr<NG::PaddingProperty> defaultPadding = std::make_unique<NG::PaddingProperty>();
197 const std::unique_ptr<NG::PaddingProperty> defaultMargin = std::make_unique<NG::MarginProperty>();
198 const std::unique_ptr<NG::BorderWidthProperty>& defaultEdgeWidth = std::make_unique<NG::BorderWidthProperty>();
199 if (!layoutProperty) {
200 selfLayoutInfo->SetPropertyObject("borderWidth", GenEdgeWidths(defaultEdgeWidth));
201 selfLayoutInfo->SetPropertyObject("margin", GenMargin(defaultPadding));
202 selfLayoutInfo->SetPropertyObject("padding", GenPadding(defaultPadding));
203 selfLayoutInfo->SetProperty("width", 0.0f);
204 selfLayoutInfo->SetProperty("height", 0.0f);
205 return selfLayoutInfo;
206 }
207 auto parentNode = AceType::DynamicCast<NG::FrameNode>(layoutProperty->GetHost()->GetParent());
208 auto pipeline = PipelineBase::GetCurrentContext();
209 if (parentNode && parentNode->GetTag() == V2::COMMON_VIEW_ETS_TAG) {
210 layoutProperty = parentNode->GetLayoutProperty();
211 }
212 auto host = layoutProperty->GetHost();
213 NG::RectF originGeoRect;
214 if (host) {
215 originGeoRect = host->GetGeometryNode()->GetFrameRect();
216 }
217 auto width =
218 GreatNotEqual(originGeoRect.Width(), 0.0f) ? originGeoRect.Width() / pipeline->GetDipScale()
219 : layoutProperty->GetLayoutConstraint()
220 ? layoutProperty->GetLayoutConstraint()->selfIdealSize.Width().value_or(0.0) / pipeline->GetDipScale()
221 : 0.0f;
222 auto height =
223 GreatNotEqual(originGeoRect.Height(), 0.0f) ? originGeoRect.Height() / pipeline->GetDipScale()
224 : layoutProperty->GetLayoutConstraint()
225 ? layoutProperty->GetLayoutConstraint()->selfIdealSize.Height().value_or(0.0) / pipeline->GetDipScale()
226 : 0.0f;
227
228 selfLayoutInfo->SetPropertyObject("borderWidth",
229 GenEdgeWidths(
230 layoutProperty->GetBorderWidthProperty() ? layoutProperty->GetBorderWidthProperty() : defaultEdgeWidth));
231 selfLayoutInfo->SetPropertyObject("margin",
232 GenMargin(layoutProperty->GetMarginProperty() ? layoutProperty->GetMarginProperty() : defaultPadding));
233 selfLayoutInfo->SetPropertyObject("padding",
234 GenPadding(layoutProperty->GetPaddingProperty() ? layoutProperty->GetPaddingProperty() : defaultPadding));
235 selfLayoutInfo->SetProperty(
236 "width", NearEqual(width, 0.0f)
237 ? layoutProperty->GetLayoutConstraint()->percentReference.Width() / pipeline->GetDipScale()
238 : width);
239 selfLayoutInfo->SetProperty(
240 "height", NearEqual(height, 0.0f)
241 ? layoutProperty->GetLayoutConstraint()->percentReference.Height() / pipeline->GetDipScale()
242 : height);
243 return selfLayoutInfo;
244 }
245
FillSubComponentProperty(JSRef<JSObjTemplate> & info,const RefPtr<NG::LayoutWrapper> & layoutWrapper,const size_t & index)246 void FillSubComponentProperty(
247 JSRef<JSObjTemplate>& info, const RefPtr<NG::LayoutWrapper>& layoutWrapper, const size_t& index)
248 {
249 info->SetProperty<std::string>("name", layoutWrapper->GetHostNode()->GetTag());
250 info->SetProperty<std::string>("id", std::to_string(layoutWrapper->GetHostNode()->GetId()));
251 info->SetPropertyObject("constraint", GenConstraint(layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()));
252 info->SetPropertyObject("borderInfo", GenBorderInfo(layoutWrapper));
253 info->SetPropertyObject("position", GenPositionInfo(layoutWrapper));
254 }
255
FillPlaceSizeProperty(JSRef<JSObjTemplate> & info,const NG::SizeF & size)256 void FillPlaceSizeProperty(JSRef<JSObjTemplate>& info, const NG::SizeF& size)
257 {
258 JSRef<JSObject> measureResult = JSRef<JSObject>::New();
259 Dimension measureWidth(size.Width(), DimensionUnit::PX);
260 Dimension measureHeight(size.Height(), DimensionUnit::PX);
261 measureResult->SetProperty("width", measureWidth.ConvertToVp());
262 measureResult->SetProperty("height", measureHeight.ConvertToVp());
263 info->SetPropertyObject("measureResult", measureResult);
264 }
265 } // namespace
266
JSMeasureLayoutParam(NG::LayoutWrapper * layoutWrapper)267 JSMeasureLayoutParam::JSMeasureLayoutParam(NG::LayoutWrapper* layoutWrapper) : MeasureLayoutParam(layoutWrapper)
268 {
269 Init();
270 }
271
Init()272 void JSMeasureLayoutParam::Init()
273 {
274 int32_t count = GetTotalChildCount();
275 childArray_ = JSRef<JSArray>::New(count);
276 GenChildArray(0, count);
277 }
278
GenChildArray(int32_t start,int32_t end)279 void JSMeasureLayoutParam::GenChildArray(int32_t start, int32_t end)
280 {
281 JSRef<JSFunc> measureFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSMeasure);
282 JSRef<JSFunc> layoutFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSLayout);
283 for (int32_t index = start; index < end; index++) {
284 JSRef<JSObjTemplate> info = JSRef<JSObjTemplate>::New();
285 info->SetInternalFieldCount(1);
286 FillSubComponentProperty(info, GetOrCreateChildByIndex(index), index);
287 info->Wrap<NG::MeasureLayoutChild>(&Get(index));
288 info->SetPropertyObject("measure", measureFunc);
289 info->SetPropertyObject("layout", layoutFunc);
290 childArray_->SetValueAt(index, info);
291 }
292 }
293
GetConstraint()294 JSRef<JSObject> JSMeasureLayoutParam::GetConstraint()
295 {
296 auto layoutWrapper = GetLayoutWrapper();
297 if (layoutWrapper && layoutWrapper->GetGeometryNode() &&
298 layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint()) {
299 auto parentConstraint = layoutWrapper->GetGeometryNode()->GetParentLayoutConstraint();
300 return GenConstraint(parentConstraint);
301 }
302 return GenConstraint(LayoutConstraintF());
303 }
304
Update(NG::LayoutWrapper * layoutWrapper)305 void JSMeasureLayoutParam::Update(NG::LayoutWrapper* layoutWrapper)
306 {
307 NG::MeasureLayoutChild* addr = nullptr;
308 int32_t count = GetTotalChildCount();
309 if (count > 0) {
310 addr = &Get(0);
311 }
312 MeasureLayoutParam::Update(layoutWrapper);
313 int32_t newCount = GetTotalChildCount();
314 if (count == newCount) {
315 return;
316 }
317 childArray_->SetLength(newCount);
318 if (count < newCount) {
319 GenChildArray(count, newCount);
320 }
321 if (addr != &Get(0)) {
322 for (int32_t index = 0; index < count; index++) {
323 auto info = JSRef<JSObjTemplate>::Cast(childArray_->GetValueAt(index));
324 info->Wrap<NG::MeasureLayoutChild>(&Get(index));
325 }
326 }
327 }
328
GetInstance(NG::LayoutWrapper * layoutWrapper)329 RefPtr<JSMeasureLayoutParam> JSMeasureLayoutParam::GetInstance(NG::LayoutWrapper* layoutWrapper)
330 {
331 auto host = AceType::DynamicCast<NG::CustomMeasureLayoutNode>(layoutWrapper->GetHostNode());
332 CHECK_NULL_RETURN(host, nullptr);
333 auto jsParam = AceType::DynamicCast<JSMeasureLayoutParam>(host->GetMeasureLayoutParam());
334 if (!jsParam) {
335 jsParam = AceType::MakeRefPtr<JSMeasureLayoutParam>(layoutWrapper);
336 host->SetMeasureLayoutParam(jsParam);
337 } else {
338 jsParam->Update(layoutWrapper);
339 }
340 return jsParam;
341 }
342
JSMeasureLayoutParamNG(NG::LayoutWrapper * layoutWrapper)343 JSMeasureLayoutParamNG::JSMeasureLayoutParamNG(NG::LayoutWrapper* layoutWrapper) : MeasureLayoutParam(layoutWrapper)
344 {
345 Init();
346 }
347
Init()348 void JSMeasureLayoutParamNG::Init()
349 {
350 int32_t count = GetTotalChildCount();
351 childArray_ = JSRef<JSArray>::New(count);
352 GenChildArray(0, count);
353 }
354
GenChildArray(int32_t start,int32_t end)355 void JSMeasureLayoutParamNG::GenChildArray(int32_t start, int32_t end)
356 {
357 JSRef<JSObject> size = JSRef<JSObject>::New();
358 size->SetProperty("width", 0);
359 size->SetProperty("height", 0);
360 JSRef<JSFunc> measureFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSMeasure);
361 JSRef<JSFunc> layoutFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSPlaceChildren);
362 JSRef<JSFunc> getMarginFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSGetMargin);
363 JSRef<JSFunc> getPaddingFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSGetPadding);
364 JSRef<JSFunc> getBorderWidthFunc = JSRef<JSFunc>::New<FunctionCallback>(ViewMeasureLayout::JSGetBorderWidth);
365 for (int32_t index = start; index < end; index++) {
366 JSRef<JSObjTemplate> info = JSRef<JSObjTemplate>::New();
367 info->SetInternalFieldCount(1);
368 info->SetPropertyObject("measureResult", size);
369 info->Wrap<NG::MeasureLayoutChild>(&Get(index));
370 info->SetPropertyObject("measure", measureFunc);
371 info->SetPropertyObject("layout", layoutFunc);
372 info->SetPropertyObject("getMargin", getMarginFunc);
373 info->SetPropertyObject("getPadding", getPaddingFunc);
374 info->SetPropertyObject("getBorderWidth", getBorderWidthFunc);
375 childArray_->SetValueAt(index, info);
376 }
377 }
378
GetConstraint()379 JSRef<JSObject> JSMeasureLayoutParamNG::GetConstraint()
380 {
381 auto layoutWrapper = GetLayoutWrapper();
382 if (layoutWrapper && layoutWrapper->GetLayoutProperty() &&
383 layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()) {
384 auto layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint().value();
385 return GenConstraintNG(layoutConstraint);
386 }
387 return GenConstraintNG(LayoutConstraintF());
388 }
389
GetPlaceChildrenConstraint()390 JSRef<JSObject> JSMeasureLayoutParamNG::GetPlaceChildrenConstraint()
391 {
392 auto layoutWrapper = GetLayoutWrapper();
393 if (layoutWrapper && layoutWrapper->GetLayoutProperty() && layoutWrapper->GetGeometryNode()) {
394 auto layoutFrameSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
395 return GenPlaceChildrenConstraintNG(layoutFrameSize, layoutWrapper->GetLayoutProperty());
396 }
397 return GenPlaceChildrenConstraintNG(SizeF(), MakeRefPtr<LayoutProperty>());
398 }
399
GetSelfLayoutInfo()400 JSRef<JSObject> JSMeasureLayoutParamNG::GetSelfLayoutInfo()
401 {
402 auto layoutWrapper = GetLayoutWrapper();
403 return GenSelfLayoutInfo(layoutWrapper && layoutWrapper->GetLayoutProperty() ? layoutWrapper->GetLayoutProperty()
404 : MakeRefPtr<LayoutProperty>());
405 }
406
UpdateSize(int32_t index,const NG::SizeF & size)407 void JSMeasureLayoutParamNG::UpdateSize(int32_t index, const NG::SizeF& size)
408 {
409 auto info = JSRef<JSObjTemplate>::Cast(childArray_->GetValueAt(index));
410 auto layoutWrapper = GetChildByIndex(index);
411 FillPlaceSizeProperty(info, size);
412 }
413
Update(NG::LayoutWrapper * layoutWrapper)414 void JSMeasureLayoutParamNG::Update(NG::LayoutWrapper* layoutWrapper)
415 {
416 NG::MeasureLayoutChild* addr = nullptr;
417 int32_t count = GetTotalChildCount();
418 if (count > 0) {
419 addr = &Get(0);
420 }
421 MeasureLayoutParam::Update(layoutWrapper);
422 int32_t newCount = GetTotalChildCount();
423 if (count == newCount) {
424 return;
425 }
426 childArray_->SetLength(newCount);
427 if (count < newCount) {
428 GenChildArray(count, newCount);
429 }
430 if (addr != &Get(0)) {
431 for (int32_t index = 0; index < count; index++) {
432 auto info = JSRef<JSObjTemplate>::Cast(childArray_->GetValueAt(index));
433 info->Wrap<NG::MeasureLayoutChild>(&Get(index));
434 }
435 }
436 }
437
GetInstance(NG::LayoutWrapper * layoutWrapper)438 RefPtr<JSMeasureLayoutParamNG> JSMeasureLayoutParamNG::GetInstance(NG::LayoutWrapper* layoutWrapper)
439 {
440 auto host = AceType::DynamicCast<NG::CustomMeasureLayoutNode>(layoutWrapper->GetHostNode());
441 CHECK_NULL_RETURN(host, nullptr);
442 auto jsParam = AceType::DynamicCast<JSMeasureLayoutParamNG>(host->GetMeasureLayoutParam());
443 if (!jsParam) {
444 jsParam = AceType::MakeRefPtr<JSMeasureLayoutParamNG>(layoutWrapper);
445 host->SetMeasureLayoutParam(jsParam);
446 } else {
447 jsParam->Update(layoutWrapper);
448 }
449 return jsParam;
450 }
451
JSMeasure(panda::JsiRuntimeCallInfo * runtimeCallInfo)452 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSMeasure(panda::JsiRuntimeCallInfo* runtimeCallInfo)
453 {
454 ACE_SCOPED_TRACE("ViewMeasureLayout::JSMeasure");
455 EcmaVM* vm = runtimeCallInfo->GetVM();
456 Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
457 auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
458 vm, 0));
459 CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
460 auto child = ptr->GetOrCreateChild();
461 if (!child) {
462 return panda::JSValueRef::Undefined(vm);
463 }
464
465 auto childLayoutConstraint = ptr->CreateChildConstraint();
466 auto layoutProperty = child->GetLayoutProperty();
467 auto info = runtimeCallInfo;
468 if (info->GetArgsNumber() >= 1 && info->GetCallArgRef(0)->IsObject(vm)) {
469 auto jsObject = JsiObject(info->GetCallArgRef(0)->ToObject(vm));
470 JSRef<JSObject> sizeObj = JSRef<JSObject>::Make(jsObject);
471 CalcDimension minWidth;
472 if (JSViewAbstract::ParseJsDimensionVp(sizeObj->GetProperty("minWidth"), minWidth)) {
473 if (layoutProperty) {
474 layoutProperty->UpdateCalcMinSize(NG::CalcSize(NG::CalcLength(minWidth), std::nullopt));
475 } else {
476 auto length = ConvertToPx(NG::CalcLength(minWidth), childLayoutConstraint.scaleProperty,
477 childLayoutConstraint.percentReference.Width());
478 if (length) {
479 childLayoutConstraint.minSize.SetWidth(length.value());
480 }
481 }
482 }
483
484 CalcDimension maxWidth;
485 if (JSViewAbstract::ParseJsDimensionVp(sizeObj->GetProperty("maxWidth"), maxWidth)) {
486 if (layoutProperty) {
487 layoutProperty->UpdateCalcMaxSize(NG::CalcSize(NG::CalcLength(maxWidth), std::nullopt));
488 } else {
489 auto length = ConvertToPx(NG::CalcLength(maxWidth), childLayoutConstraint.scaleProperty,
490 childLayoutConstraint.percentReference.Width());
491 if (length) {
492 childLayoutConstraint.maxSize.SetWidth(length.value());
493 }
494 }
495 }
496
497 CalcDimension minHeight;
498 if (JSViewAbstract::ParseJsDimensionVp(sizeObj->GetProperty("minHeight"), minHeight)) {
499 if (layoutProperty) {
500 layoutProperty->UpdateCalcMinSize(NG::CalcSize(std::nullopt, NG::CalcLength(minHeight)));
501 } else {
502 auto length = ConvertToPx(NG::CalcLength(minHeight), childLayoutConstraint.scaleProperty,
503 childLayoutConstraint.percentReference.Height());
504 if (length) {
505 childLayoutConstraint.minSize.SetHeight(length.value());
506 }
507 }
508 }
509
510 CalcDimension maxHeight;
511 if (JSViewAbstract::ParseJsDimensionVp(sizeObj->GetProperty("maxHeight"), maxHeight)) {
512 if (layoutProperty) {
513 layoutProperty->UpdateCalcMaxSize(NG::CalcSize(std::nullopt, NG::CalcLength(maxHeight)));
514 } else {
515 auto length = ConvertToPx(NG::CalcLength(maxHeight), childLayoutConstraint.scaleProperty,
516 childLayoutConstraint.percentReference.Height());
517 if (length) {
518 childLayoutConstraint.maxSize.SetHeight(length.value());
519 }
520 }
521 }
522 }
523 child->Measure(childLayoutConstraint);
524
525 auto size = child->GetGeometryNode()->GetFrameSize();
526 ptr->UpdateSize(size);
527 Dimension measureWidth(size.Width(), DimensionUnit::PX);
528 Dimension measureHeight(size.Height(), DimensionUnit::PX);
529 Local<ObjectRef> measureResultObject = ObjectRef::New(vm);
530 measureResultObject->Set(vm, ToJSValue("width"), ToJSValue(measureWidth.ConvertToVp()));
531 measureResultObject->Set(vm, ToJSValue("height"), ToJSValue(measureHeight.ConvertToVp()));
532 return measureResultObject;
533 }
534
JSLayout(panda::JsiRuntimeCallInfo * runtimeCallInfo)535 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSLayout(panda::JsiRuntimeCallInfo* runtimeCallInfo)
536 {
537 ACE_SCOPED_TRACE("ViewMeasureLayout::JSLayout");
538 EcmaVM* vm = runtimeCallInfo->GetVM();
539 Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
540 auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
541 vm, 0));
542 CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
543 auto child = ptr->GetChild();
544 if (!child) {
545 return panda::JSValueRef::Undefined(vm);
546 }
547
548 auto info = runtimeCallInfo;
549 if (info->GetArgsNumber() != 1 || !info->GetCallArgRef(0)->IsObject(vm)) {
550 LOGE("JSLayout arg is wrong");
551 child->Layout();
552 return panda::JSValueRef::Undefined(vm);
553 }
554
555 auto jsObject = JsiObject(info->GetCallArgRef(0)->ToObject(vm));
556 JSRef<JSObject> layoutInfo = JSRef<JSObject>::Make(jsObject);
557 JSRef<JSObject> sizeObj = layoutInfo->GetProperty("position");
558 JSRef<JSVal> xVal = sizeObj->GetProperty("x");
559 JSRef<JSVal> yVal = sizeObj->GetProperty("y");
560 CalcDimension dimenX;
561 CalcDimension dimenY;
562 auto xResult = JSViewAbstract::ParseJsDimensionVp(xVal, dimenX);
563 auto yResult = JSViewAbstract::ParseJsDimensionVp(yVal, dimenY);
564 if (!(xResult || yResult)) {
565 LOGE("the position prop is illegal");
566 } else {
567 child->GetGeometryNode()->SetMarginFrameOffset({ dimenX.ConvertToPx(), dimenY.ConvertToPx() });
568 }
569 child->Layout();
570
571 return panda::JSValueRef::Undefined(vm);
572 }
573
JSPlaceChildren(panda::JsiRuntimeCallInfo * runtimeCallInfo)574 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSPlaceChildren(panda::JsiRuntimeCallInfo* runtimeCallInfo)
575 {
576 ACE_SCOPED_TRACE("ViewMeasureLayout::JSPlaceChildren");
577 EcmaVM* vm = runtimeCallInfo->GetVM();
578 Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
579 auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
580 vm, 0));
581 CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
582 auto child = ptr->GetChild();
583 if (!child) {
584 return panda::JSValueRef::Undefined(vm);
585 }
586
587 auto info = runtimeCallInfo;
588 if (info->GetArgsNumber() != 1 || !info->GetCallArgRef(0)->IsObject(vm)) {
589 LOGE("JSPlaceChildren arg is wrong");
590 child->Layout();
591 return panda::JSValueRef::Undefined(vm);
592 }
593
594 auto jsObject = JsiObject(info->GetCallArgRef(0)->ToObject(vm));
595 JSRef<JSObject> layoutInfo = JSRef<JSObject>::Make(jsObject);
596 JSRef<JSVal> xVal = layoutInfo->GetProperty("x");
597 JSRef<JSVal> yVal = layoutInfo->GetProperty("y");
598 CalcDimension dimenX;
599 CalcDimension dimenY;
600 auto xResult = JSViewAbstract::ParseJsDimensionVp(xVal, dimenX);
601 auto yResult = JSViewAbstract::ParseJsDimensionVp(yVal, dimenY);
602 if (!(xResult || yResult)) {
603 LOGE("the position prop is illegal");
604 } else {
605 child->GetGeometryNode()->SetMarginFrameOffset({ dimenX.ConvertToPx(), dimenY.ConvertToPx() });
606 }
607 child->Layout();
608 return panda::JSValueRef::Undefined(vm);
609 }
610
JSGetMargin(panda::JsiRuntimeCallInfo * runtimeCallInfo)611 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSGetMargin(panda::JsiRuntimeCallInfo* runtimeCallInfo)
612 {
613 EcmaVM* vm = runtimeCallInfo->GetVM();
614 Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
615 auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
616 vm, 0));
617 CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
618 auto child = ptr->GetOrCreateChild();
619 if (!(child && child->GetLayoutProperty())) {
620 return GenEdgesGlobalized({}, TextDirection::LTR).Get().GetLocalHandle();
621 }
622 auto layoutProperty = child->GetLayoutProperty();
623 auto direction = layoutProperty->GetNonAutoLayoutDirection();
624 return GenEdgesGlobalized(layoutProperty->CreateMarginWithoutCache(), direction).Get().GetLocalHandle();
625 }
626
JSGetPadding(panda::JsiRuntimeCallInfo * runtimeCallInfo)627 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSGetPadding(panda::JsiRuntimeCallInfo* runtimeCallInfo)
628 {
629 EcmaVM* vm = runtimeCallInfo->GetVM();
630 Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
631 auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
632 vm, 0));
633 CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
634 auto child = ptr->GetOrCreateChild();
635 if (!(child && child->GetLayoutProperty())) {
636 return GenEdgesGlobalized({}, TextDirection::LTR).Get().GetLocalHandle();
637 }
638 auto layoutProperty = child->GetLayoutProperty();
639 auto direction = layoutProperty->GetNonAutoLayoutDirection();
640 return GenEdgesGlobalized(layoutProperty->CreatePaddingWithoutBorder(false, false), direction)
641 .Get()
642 .GetLocalHandle();
643 }
644
JSGetBorderWidth(panda::JsiRuntimeCallInfo * runtimeCallInfo)645 panda::Local<panda::JSValueRef> ViewMeasureLayout::JSGetBorderWidth(panda::JsiRuntimeCallInfo* runtimeCallInfo)
646 {
647 EcmaVM* vm = runtimeCallInfo->GetVM();
648 Local<JSValueRef> thisObj = runtimeCallInfo->GetThisRef();
649 auto ptr = static_cast<NG::MeasureLayoutChild*>(panda::Local<panda::ObjectRef>(thisObj)->GetNativePointerField(
650 vm, 0));
651 CHECK_NULL_RETURN(ptr, panda::JSValueRef::Undefined(vm));
652 auto child = ptr->GetOrCreateChild();
653 if (!(child && child->GetLayoutProperty())) {
654 return GenBorderWidthGlobalized({}, TextDirection::LTR).Get().GetLocalHandle();
655 }
656 auto layoutProperty = child->GetLayoutProperty();
657 auto direction = layoutProperty->GetNonAutoLayoutDirection();
658 return GenBorderWidthGlobalized(layoutProperty->CreateBorder(), direction).Get().GetLocalHandle();
659 }
660 #endif
661
662 } // namespace OHOS::Ace::Framework