1 /*
2  * Copyright (c) 2021-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 
16 #include "bridge/declarative_frontend/jsview/js_textpicker.h"
17 
18 #include <cstdint>
19 #include <securec.h>
20 
21 #include "base/log/ace_scoring_log.h"
22 #include "bridge/common/utils/engine_helper.h"
23 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_text_picker_theme.h"
24 #include "bridge/declarative_frontend/engine/functions/js_function.h"
25 #include "bridge/declarative_frontend/jsview/js_datepicker.h"
26 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
27 #include "bridge/declarative_frontend/jsview/js_utils.h"
28 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
29 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
30 #include "bridge/declarative_frontend/jsview/models/textpicker_model_impl.h"
31 #include "bridge/declarative_frontend/view_stack_processor.h"
32 #include "core/components/picker/picker_base_component.h"
33 #include "core/components/picker/picker_theme.h"
34 #include "core/components_ng/base/view_stack_processor.h"
35 #include "core/components_ng/pattern/text_picker/textpicker_model.h"
36 #include "core/components_ng/pattern/text_picker/textpicker_model_ng.h"
37 #include "core/components_ng/pattern/text_picker/textpicker_properties.h"
38 #include "core/pipeline_ng/pipeline_context.h"
39 
40 namespace OHOS::Ace {
41 namespace {
42 const DimensionOffset TEXT_PICKER_OFFSET_DEFAULT_TOP = DimensionOffset(0.0_vp, 40.0_vp);
43 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
44     DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
45     DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
46     DialogAlignment::BOTTOM_END };
47 const std::vector<HoverModeAreaType> HOVER_MODE_AREA_TYPE = { HoverModeAreaType::TOP_SCREEN,
48     HoverModeAreaType::BOTTOM_SCREEN };
49 const std::regex DIMENSION_REGEX(R"(^[-+]?\d+(?:\.\d+)?(?:px|vp|fp|lpx)?$)", std::regex::icase);
50 }
51 
52 std::unique_ptr<TextPickerModel> TextPickerModel::textPickerInstance_ = nullptr;
53 std::unique_ptr<TextPickerDialogModel> TextPickerDialogModel::textPickerDialogInstance_ = nullptr;
54 std::mutex TextPickerModel::mutex_;
55 std::mutex TextPickerDialogModel::mutex_;
56 
GetInstance()57 TextPickerModel* TextPickerModel::GetInstance()
58 {
59     if (!textPickerInstance_) {
60         std::lock_guard<std::mutex> lock(mutex_);
61         if (!textPickerInstance_) {
62 #ifdef NG_BUILD
63             textPickerInstance_.reset(new NG::TextPickerModelNG());
64 #else
65             if (Container::IsCurrentUseNewPipeline()) {
66                 textPickerInstance_.reset(new NG::TextPickerModelNG());
67             } else {
68                 textPickerInstance_.reset(new Framework::TextPickerModelImpl());
69             }
70 #endif
71         }
72     }
73     return textPickerInstance_.get();
74 }
75 
GetInstance()76 TextPickerDialogModel* TextPickerDialogModel::GetInstance()
77 {
78     if (!textPickerDialogInstance_) {
79         std::lock_guard<std::mutex> lock(mutex_);
80         if (!textPickerDialogInstance_) {
81 #ifdef NG_BUILD
82             textPickerDialogInstance_.reset(new NG::TextPickerDialogModelNG());
83 #else
84             if (Container::IsCurrentUseNewPipeline()) {
85                 textPickerDialogInstance_.reset(new NG::TextPickerDialogModelNG());
86             } else {
87                 textPickerDialogInstance_.reset(new Framework::TextPickerDialogModelImpl());
88             }
89 #endif
90         }
91     }
92     return textPickerDialogInstance_.get();
93 }
94 } // namespace OHOS::Ace
95 
96 namespace OHOS::Ace::Framework {
97 namespace {
ParseFontOfButtonStyle(const JSRef<JSObject> & pickerButtonParamObject,ButtonInfo & buttonInfo)98 void ParseFontOfButtonStyle(const JSRef<JSObject>& pickerButtonParamObject, ButtonInfo& buttonInfo)
99 {
100     CalcDimension fontSize;
101     JSRef<JSVal> sizeProperty = pickerButtonParamObject->GetProperty("fontSize");
102     if (JSViewAbstract::ParseJsDimensionVpNG(sizeProperty, fontSize) && fontSize.Unit() != DimensionUnit::PERCENT &&
103         GreatOrEqual(fontSize.Value(), 0.0)) {
104         if (JSViewAbstract::ParseJsDimensionFp(sizeProperty, fontSize)) {
105             buttonInfo.fontSize = fontSize;
106         }
107     }
108     Color fontColor;
109     if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("fontColor"), fontColor)) {
110         buttonInfo.fontColor = fontColor;
111     }
112     auto fontWeight = pickerButtonParamObject->GetProperty("fontWeight");
113     if (fontWeight->IsString() || fontWeight->IsNumber()) {
114         buttonInfo.fontWeight = ConvertStrToFontWeight(fontWeight->ToString(), FontWeight::MEDIUM);
115     }
116     JSRef<JSVal> style = pickerButtonParamObject->GetProperty("fontStyle");
117     if (style->IsNumber()) {
118         auto value = style->ToNumber<int32_t>();
119         if (value >= 0 && value < static_cast<int32_t>(FontStyle::NONE)) {
120             buttonInfo.fontStyle = static_cast<FontStyle>(value);
121         }
122     }
123     JSRef<JSVal> family = pickerButtonParamObject->GetProperty("fontFamily");
124     std::vector<std::string> fontFamilies;
125     if (JSViewAbstract::ParseJsFontFamilies(family, fontFamilies)) {
126         buttonInfo.fontFamily = fontFamilies;
127     }
128 }
129 
ParseButtonStyle(const JSRef<JSObject> & pickerButtonParamObject)130 ButtonInfo ParseButtonStyle(const JSRef<JSObject>& pickerButtonParamObject)
131 {
132     ButtonInfo buttonInfo;
133     if (pickerButtonParamObject->GetProperty("type")->IsNumber()) {
134         buttonInfo.type =
135             static_cast<ButtonType>(pickerButtonParamObject->GetProperty("type")->ToNumber<int32_t>());
136     }
137     if (pickerButtonParamObject->GetProperty("style")->IsNumber()) {
138         auto styleModeIntValue = pickerButtonParamObject->GetProperty("style")->ToNumber<int32_t>();
139         if (styleModeIntValue >= static_cast<int32_t>(ButtonStyleMode::NORMAL) &&
140             styleModeIntValue <= static_cast<int32_t>(ButtonStyleMode::TEXT)) {
141             buttonInfo.buttonStyle = static_cast<ButtonStyleMode>(styleModeIntValue);
142         }
143     }
144     if (pickerButtonParamObject->GetProperty("role")->IsNumber()) {
145         auto buttonRoleIntValue = pickerButtonParamObject->GetProperty("role")->ToNumber<int32_t>();
146         if (buttonRoleIntValue >= static_cast<int32_t>(ButtonRole::NORMAL) &&
147             buttonRoleIntValue <= static_cast<int32_t>(ButtonRole::ERROR)) {
148             buttonInfo.role = static_cast<ButtonRole>(buttonRoleIntValue);
149         }
150     }
151     ParseFontOfButtonStyle(pickerButtonParamObject, buttonInfo);
152     Color backgroundColor;
153     if (JSViewAbstract::ParseJsColor(pickerButtonParamObject->GetProperty("backgroundColor"), backgroundColor)) {
154         buttonInfo.backgroundColor = backgroundColor;
155     }
156     auto radius = ParseBorderRadiusAttr(pickerButtonParamObject->GetProperty("borderRadius"));
157     if (radius.has_value()) {
158         buttonInfo.borderRadius = radius.value();
159     }
160 
161     auto primaryValue = pickerButtonParamObject->GetProperty("primary");
162     if (primaryValue->IsBoolean()) {
163         buttonInfo.isPrimary = primaryValue->ToBoolean();
164     }
165 
166     return buttonInfo;
167 }
168 
ParseButtonStyles(const JSRef<JSObject> & paramObject)169 std::vector<ButtonInfo> ParseButtonStyles(const JSRef<JSObject>& paramObject)
170 {
171     std::vector<ButtonInfo> buttonInfos;
172     auto acceptButtonStyle = paramObject->GetProperty("acceptButtonStyle");
173     if (acceptButtonStyle->IsObject()) {
174         auto acceptButtonStyleParamObject = JSRef<JSObject>::Cast(acceptButtonStyle);
175         buttonInfos.emplace_back(ParseButtonStyle(acceptButtonStyleParamObject));
176         buttonInfos[0].isAcceptButton = true;
177     } else {
178         ButtonInfo buttonInfo;
179         buttonInfos.emplace_back(buttonInfo);
180     }
181     auto cancelButtonStyle = paramObject->GetProperty("cancelButtonStyle");
182     if (cancelButtonStyle->IsObject()) {
183         auto cancelButtonStyleParamObject = JSRef<JSObject>::Cast(cancelButtonStyle);
184         buttonInfos.emplace_back(ParseButtonStyle(cancelButtonStyleParamObject));
185     }
186 
187     return buttonInfos;
188 }
189 } // namespace
190 
JSBind(BindingTarget globalObj)191 void JSTextPicker::JSBind(BindingTarget globalObj)
192 {
193     JSClass<JSTextPicker>::Declare("TextPicker");
194     MethodOptions opt = MethodOptions::NONE;
195     JSClass<JSTextPicker>::StaticMethod("create", &JSTextPicker::Create, opt);
196     JSClass<JSTextPicker>::StaticMethod("defaultPickerItemHeight", &JSTextPicker::SetDefaultPickerItemHeight);
197     JSClass<JSTextPicker>::StaticMethod("canLoop", &JSTextPicker::SetCanLoop);
198     JSClass<JSTextPicker>::StaticMethod("disappearTextStyle", &JSTextPicker::SetDisappearTextStyle);
199     JSClass<JSTextPicker>::StaticMethod("textStyle", &JSTextPicker::SetTextStyle);
200     JSClass<JSTextPicker>::StaticMethod("selectedTextStyle", &JSTextPicker::SetSelectedTextStyle);
201     JSClass<JSTextPicker>::StaticMethod("selectedIndex", &JSTextPicker::SetSelectedIndex);
202     JSClass<JSTextPicker>::StaticMethod("divider", &JSTextPicker::SetDivider);
203     JSClass<JSTextPicker>::StaticMethod("opacity", &JSTextPicker::JsOpacity);
204 
205     JSClass<JSTextPicker>::StaticMethod("onAccept", &JSTextPicker::OnAccept);
206     JSClass<JSTextPicker>::StaticMethod("onCancel", &JSTextPicker::OnCancel);
207     JSClass<JSTextPicker>::StaticMethod("onChange", &JSTextPicker::OnChange);
208     JSClass<JSTextPicker>::StaticMethod("onScrollStop", &JSTextPicker::OnScrollStop);
209     JSClass<JSTextPicker>::StaticMethod("backgroundColor", &JSTextPicker::PickerBackgroundColor);
210     JSClass<JSTextPicker>::StaticMethod("gradientHeight", &JSTextPicker::SetGradientHeight);
211     JSClass<JSTextPicker>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
212     JSClass<JSTextPicker>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
213     JSClass<JSTextPicker>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
214     JSClass<JSTextPicker>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
215     JSClass<JSTextPicker>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
216     JSClass<JSTextPicker>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
217     JSClass<JSTextPicker>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
218     JSClass<JSTextPicker>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
219     JSClass<JSTextPicker>::InheritAndBind<JSViewAbstract>(globalObj);
220 }
221 
PickerBackgroundColor(const JSCallbackInfo & info)222 void JSTextPicker::PickerBackgroundColor(const JSCallbackInfo& info)
223 {
224     JSViewAbstract::JsBackgroundColor(info);
225 
226     if (info.Length() < 1) {
227         return;
228     }
229     Color backgroundColor;
230     if (!ParseJsColor(info[0], backgroundColor)) {
231         return;
232     }
233     TextPickerModel::GetInstance()->SetBackgroundColor(backgroundColor);
234 }
235 
JsOpacity(const JSCallbackInfo & info)236 void JSTextPicker::JsOpacity(const JSCallbackInfo& info)
237 {
238     JSViewAbstract::JsOpacity(info);
239     TextPickerModel::GetInstance()->HasUserDefinedOpacity();
240 }
241 
ProcessCascadeOptionDepth(const NG::TextCascadePickerOptions & option)242 size_t JSTextPicker::ProcessCascadeOptionDepth(const NG::TextCascadePickerOptions& option)
243 {
244     size_t depth = 1;
245     if (option.children.size() == 0) {
246         return depth;
247     }
248 
249     for (auto&& pos : option.children) {
250         size_t tmpDep = 1;
251         tmpDep += ProcessCascadeOptionDepth(pos);
252         if (tmpDep > depth) {
253             depth = tmpDep;
254         }
255     }
256     return depth;
257 }
258 
CreateMulti(const RefPtr<PickerTheme> & theme,const std::vector<std::string> & values,const std::vector<uint32_t> & selectedValues,const NG::TextCascadePickerOptionsAttr & attr,const std::vector<NG::TextCascadePickerOptions> & options)259 void JSTextPicker::CreateMulti(const RefPtr<PickerTheme>& theme, const std::vector<std::string>& values,
260     const std::vector<uint32_t>& selectedValues, const NG::TextCascadePickerOptionsAttr& attr,
261     const std::vector<NG::TextCascadePickerOptions>& options)
262 {
263     TextPickerModel::GetInstance()->MultiInit(theme);
264     TextPickerModel::GetInstance()->SetValues(values);
265     TextPickerModel::GetInstance()->SetSelecteds(selectedValues);
266     TextPickerModel::GetInstance()->SetIsCascade(attr.isCascade);
267     TextPickerModel::GetInstance()->SetHasSelectAttr(attr.isHasSelectAttr);
268     TextPickerModel::GetInstance()->SetColumns(options);
269 }
270 
ParseTextPickerValueObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)271 void ParseTextPickerValueObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
272 {
273     CHECK_NULL_VOID(changeEventVal->IsFunction());
274 
275     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
276     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
277     auto onValueChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
278                              const std::vector<std::string>& value) {
279         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
280         ACE_SCORING_EVENT("TextPicker.onValueChange");
281         if (value.size() == 1) {
282             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(value[0]));
283             PipelineContext::SetCallBackNode(node);
284             func->ExecuteJS(1, &newJSVal);
285         } else {
286             JSRef<JSArray> valueArray = JSRef<JSArray>::New();
287             for (uint32_t i = 0; i < value.size(); i++) {
288                 valueArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(value[i])));
289             }
290             JSRef<JSVal> newJSVal = JSRef<JSVal>::Cast(valueArray);
291             PipelineContext::SetCallBackNode(node);
292             func->ExecuteJS(1, &newJSVal);
293         }
294     };
295     TextPickerModel::GetInstance()->SetOnValueChangeEvent(std::move(onValueChange));
296 }
297 
ParseTextPickerSelectedObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)298 void ParseTextPickerSelectedObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
299 {
300     CHECK_NULL_VOID(changeEventVal->IsFunction());
301 
302     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
303     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
304     auto onSelectedChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
305                                 const std::vector<double>& index) {
306         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
307         ACE_SCORING_EVENT("TextPicker.onSelectedChange");
308         if (index.size() == 1) {
309             PipelineContext::SetCallBackNode(node);
310             JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(index[0]));
311             func->ExecuteJS(1, &newJSVal);
312         } else {
313             JSRef<JSArray> indexArray = JSRef<JSArray>::New();
314             for (uint32_t i = 0; i < index.size(); i++) {
315                 indexArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(index[i])));
316             }
317             PipelineContext::SetCallBackNode(node);
318             JSRef<JSVal> newJSVal = JSRef<JSVal>::Cast(indexArray);
319             func->ExecuteJS(1, &newJSVal);
320         }
321     };
322     TextPickerModel::GetInstance()->SetOnSelectedChangeEvent(std::move(onSelectedChange));
323 }
324 
Create(const JSCallbackInfo & info)325 void JSTextPicker::Create(const JSCallbackInfo& info)
326 {
327     if (info.Length() >= 1 && info[0]->IsObject()) {
328         auto paramObject = JSRef<JSObject>::Cast(info[0]);
329         ParseTextArrayParam param;
330         NG::TextCascadePickerOptionsAttr optionsAttr;
331         bool optionsMultiContentCheckErr = false;
332         bool optionsCascadeContentCheckErr = false;
333         auto isSingleRange = ProcessSingleRangeValue(paramObject, param);
334         TextPickerModel::GetInstance()->SetSingleRange(isSingleRange);
335         if (!isSingleRange) {
336             if (!JSTextPickerParser::ParseMultiTextArray(paramObject, param)) {
337                 param.options.clear();
338                 optionsMultiContentCheckErr = true;
339             }
340             if (optionsMultiContentCheckErr) {
341                 optionsCascadeContentCheckErr =
342                     !ProcessCascadeOptions(paramObject, param.options, param.selecteds, param.values, optionsAttr);
343             }
344         }
345         if (!isSingleRange && optionsMultiContentCheckErr && optionsCascadeContentCheckErr) {
346             param.result.clear();
347             param.options.clear();
348 
349             auto targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
350             bool firstBuild = targetNode && targetNode->IsFirstBuilding();
351             if (!firstBuild) {
352                 return;
353             }
354         }
355         auto theme = GetTheme<PickerTheme>();
356         CHECK_NULL_VOID(theme);
357         if (!param.result.empty()) {
358             TextPickerModel::GetInstance()->Create(theme, param.kind);
359             TextPickerModel::GetInstance()->SetRange(param.result);
360             TextPickerModel::GetInstance()->SetSelected(param.selected);
361             TextPickerModel::GetInstance()->SetValue(param.value);
362         } else {
363             CreateMulti(theme, param.values, param.selecteds, optionsAttr, param.options);
364         }
365         TextPickerModel::GetInstance()->SetDefaultAttributes(theme);
366         JSInteractableView::SetFocusable(true);
367         JSInteractableView::SetFocusNode(true);
368         if (param.valueChangeEventVal->IsFunction()) {
369             ParseTextPickerValueObject(info, param.valueChangeEventVal);
370         }
371         if (param.selectedChangeEventVal->IsFunction()) {
372             ParseTextPickerSelectedObject(info, param.selectedChangeEventVal);
373         }
374         JSTextPickerTheme::ApplyTheme();
375     }
376 }
377 
ProcessSingleRangeValue(const JSRef<JSObject> & paramObjec,ParseTextArrayParam & param)378 bool JSTextPicker::ProcessSingleRangeValue(const JSRef<JSObject>& paramObjec, ParseTextArrayParam& param)
379 {
380     bool ret = true;
381     auto getRange = paramObjec->GetProperty("range");
382     if (getRange->IsNull() || getRange->IsUndefined()) {
383         if (TextPickerModel::GetInstance()->GetSingleRange()) {
384             return ret;
385         }
386         return false;
387     }
388     if (!JSTextPickerParser::ParseTextArray(paramObjec, param)) {
389         if (!JSTextPickerParser::ParseIconTextArray(paramObjec, param.result, param.kind, param.selected)) {
390             param.result.clear();
391             ret = false;
392         }
393     }
394     return ret;
395 }
396 
ProcessCascadeOptions(const JSRef<JSObject> & paramObject,std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,NG::TextCascadePickerOptionsAttr & attr)397 bool JSTextPicker::ProcessCascadeOptions(const JSRef<JSObject>& paramObject,
398     std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues,
399     std::vector<std::string>& values, NG::TextCascadePickerOptionsAttr& attr)
400 {
401     auto getRange = paramObject->GetProperty("range");
402     if (getRange->IsNull() || getRange->IsUndefined()) {
403         options.clear();
404         return false;
405     }
406     if (!JSTextPickerParser::ParseCascadeTextArray(paramObject, selectedValues, values, attr)) {
407         options.clear();
408         return false;
409     } else {
410         JSTextPickerParser::GenerateCascadeOptions(getRange, options);
411         uint32_t maxCount = options.empty() ? 0 : 1;
412         for (size_t i = 0; i < options.size(); i++) {
413             size_t tmp = ProcessCascadeOptionDepth(options[i]);
414             if (tmp > maxCount) {
415                 maxCount = tmp;
416             }
417         }
418         if (selectedValues.size() < maxCount) {
419             auto differ = maxCount - selectedValues.size();
420             for (uint32_t i = 0; i < differ; i++) {
421                 selectedValues.emplace_back(0);
422             }
423         }
424         if (values.size() < maxCount) {
425             auto differ = maxCount - values.size();
426             for (uint32_t i = 0; i < differ; i++) {
427                 values.emplace_back("");
428             }
429         }
430         attr.isCascade = true;
431         TextPickerModel::GetInstance()->SetMaxCount(maxCount);
432     }
433     return true;
434 }
435 
GenerateCascadeOptionsInternal(const JSRef<JSObject> & jsObj,std::vector<NG::TextCascadePickerOptions> & options)436 bool JSTextPickerParser::GenerateCascadeOptionsInternal(
437     const JSRef<JSObject>& jsObj, std::vector<NG::TextCascadePickerOptions>& options)
438 {
439     NG::TextCascadePickerOptions option;
440     auto text = jsObj->GetProperty("text");
441     std::string textStr = "";
442     if (ParseJsString(text, textStr)) {
443         option.rangeResult.emplace_back(textStr);
444     } else {
445         return false;
446     }
447 
448     auto children = jsObj->GetProperty("children");
449     if (children->IsArray()) {
450         JSRef<JSArray> arrayChildren = JSRef<JSArray>::Cast(children);
451         if (arrayChildren->Length() > 0) {
452             if (!GenerateCascadeOptions(arrayChildren, option.children)) {
453                 return false;
454             }
455         }
456     }
457     options.emplace_back(option);
458     return true;
459 }
460 
GenerateCascadeOptions(const JSRef<JSArray> & array,std::vector<NG::TextCascadePickerOptions> & options)461 bool JSTextPickerParser::GenerateCascadeOptions(
462     const JSRef<JSArray>& array, std::vector<NG::TextCascadePickerOptions>& options)
463 {
464     for (size_t i = 0; i < array->Length(); i++) {
465         if (array->GetValueAt(i)->IsObject()) {
466             auto jsObj = JSRef<JSObject>::Cast(array->GetValueAt(i));
467             if (!GenerateCascadeOptionsInternal(jsObj, options)) {
468                 return false;
469             }
470         } else {
471             options.clear();
472             return false;
473         }
474     }
475     return true;
476 }
477 
ParseMultiTextArrayRangeInternal(const JSRef<JSVal> & value,std::vector<NG::TextCascadePickerOptions> & options)478 bool JSTextPickerParser::ParseMultiTextArrayRangeInternal(
479     const JSRef<JSVal>& value, std::vector<NG::TextCascadePickerOptions>& options)
480 {
481     if (value->IsArray()) {
482         NG::TextCascadePickerOptions option;
483         if (!ParseJsStrArray(value, option.rangeResult)) {
484             return false;
485         } else {
486             options.emplace_back(option);
487         }
488     } else {
489         return false;
490     }
491     return true;
492 }
493 
ParseMultiTextArrayRange(const JSRef<JSArray> & jsRangeValue,std::vector<NG::TextCascadePickerOptions> & options)494 bool JSTextPickerParser::ParseMultiTextArrayRange(
495     const JSRef<JSArray>& jsRangeValue, std::vector<NG::TextCascadePickerOptions>& options)
496 {
497     options.clear();
498     if (jsRangeValue->Length() > 0) {
499         for (size_t i = 0; i < jsRangeValue->Length(); i++) {
500             JSRef<JSVal> value = jsRangeValue->GetValueAt(i);
501             if (!ParseMultiTextArrayRangeInternal(value, options)) {
502                 return false;
503             }
504         }
505     } else {
506         return false;
507     }
508     return true;
509 }
510 
ParseMultiTextArraySelectInternal(const std::vector<NG::TextCascadePickerOptions> & options,const std::vector<std::string> & values,std::vector<uint32_t> & selectedValues)511 void JSTextPickerParser::ParseMultiTextArraySelectInternal(const std::vector<NG::TextCascadePickerOptions>& options,
512     const std::vector<std::string>& values, std::vector<uint32_t>& selectedValues)
513 {
514     uint32_t selectedValue = 0;
515     auto sizeOfValues = values.size();
516     for (uint32_t i = 0; i < options.size(); i++) {
517         if ((sizeOfValues >= 0 && sizeOfValues < i + 1) || values[i].empty()) {
518             selectedValues.emplace_back(0);
519             continue;
520         }
521 
522         auto valueIterator = std::find(options[i].rangeResult.begin(), options[i].rangeResult.end(), values[i]);
523         if (valueIterator != options[i].rangeResult.end()) {
524             selectedValue = static_cast<uint32_t>(std::distance(options[i].rangeResult.begin(), valueIterator));
525             selectedValues.emplace_back(selectedValue);
526         } else {
527             selectedValues.emplace_back(0);
528         }
529     }
530 }
531 
ParseMultiTextArraySelectArrayInternal(const std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues)532 void JSTextPickerParser::ParseMultiTextArraySelectArrayInternal(
533     const std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues)
534 {
535     for (uint32_t i = 0; i < options.size(); i++) {
536         if (selectedValues.size() > 0 && selectedValues.size() < i + 1) {
537             selectedValues.emplace_back(0);
538         } else {
539             if (selectedValues[i] >= options[i].rangeResult.size()) {
540                 selectedValues[i] = 0;
541             }
542         }
543     }
544 }
545 
ParseMultiTextArraySelect(const JsiRef<JsiValue> & jsSelectedValue,ParseTextArrayParam & param)546 bool JSTextPickerParser::ParseMultiTextArraySelect(const JsiRef<JsiValue>& jsSelectedValue, ParseTextArrayParam& param)
547 {
548     if (jsSelectedValue->IsArray()) {
549         if (!ParseJsIntegerArray(jsSelectedValue, param.selecteds)) {
550             return false;
551         }
552         ParseMultiTextArraySelectArrayInternal(param.options, param.selecteds);
553     } else {
554         uint32_t selectedValue = 0;
555         if (ParseJsInteger(jsSelectedValue, selectedValue)) {
556             if (param.options.size() < 1 || selectedValue >= param.options[0].rangeResult.size()) {
557                 selectedValue = 0;
558             }
559             param.selecteds.emplace_back(selectedValue);
560             for (uint32_t i = 1; i < param.options.size(); i++) {
561                 param.selecteds.emplace_back(0);
562             }
563         } else {
564             ParseMultiTextArraySelectInternal(param.options, param.values, param.selecteds);
565         }
566     }
567     return true;
568 }
569 
ParseMultiTextArrayValueInternal(const std::vector<NG::TextCascadePickerOptions> & options,std::vector<std::string> & values)570 void JSTextPickerParser::ParseMultiTextArrayValueInternal(
571     const std::vector<NG::TextCascadePickerOptions>& options, std::vector<std::string>& values)
572 {
573     for (uint32_t i = 0; i < options.size(); i++) {
574         if (values.size() > 0 && values.size() < i + 1) {
575             if (options[i].rangeResult.size() > 0) {
576                 values.emplace_back(options[i].rangeResult[0]);
577             } else {
578                 values.emplace_back("");
579             }
580         } else {
581             auto valueIterator = std::find(options[i].rangeResult.begin(), options[i].rangeResult.end(), values[i]);
582             if (valueIterator == options[i].rangeResult.end()) {
583                 values[i] = options[i].rangeResult.front();
584             }
585         }
586     }
587 }
588 
ParseMultiTextArrayValueSingleInternal(const std::vector<NG::TextCascadePickerOptions> & options,const std::string & value,std::vector<std::string> & values)589 void JSTextPickerParser::ParseMultiTextArrayValueSingleInternal(
590     const std::vector<NG::TextCascadePickerOptions>& options, const std::string& value,
591     std::vector<std::string>& values)
592 {
593     if (options.size() > 0) {
594         auto valueIterator = std::find(options[0].rangeResult.begin(), options[0].rangeResult.end(), value);
595         if (valueIterator != options[0].rangeResult.end()) {
596             values.emplace_back(value);
597         } else {
598             values.emplace_back(options[0].rangeResult.front());
599         }
600         for (uint32_t i = 1; i < options.size(); i++) {
601             values.emplace_back(options[i].rangeResult.front());
602         }
603     } else {
604         for (uint32_t i = 0; i < options.size(); i++) {
605             values.emplace_back(options[i].rangeResult.front());
606         }
607     }
608 }
609 
ParseMultiTextArrayValue(const JsiRef<JsiValue> & jsValue,ParseTextArrayParam & param)610 bool JSTextPickerParser::ParseMultiTextArrayValue(const JsiRef<JsiValue>& jsValue, ParseTextArrayParam& param)
611 {
612     if (jsValue->IsArray()) {
613         if (!ParseJsStrArray(jsValue, param.values)) {
614             return false;
615         }
616         ParseMultiTextArrayValueInternal(param.options, param.values);
617     } else {
618         std::string value;
619         if (ParseJsString(jsValue, value)) {
620             ParseMultiTextArrayValueSingleInternal(param.options, value, param.values);
621         } else {
622             for (uint32_t i = 0; i < param.options.size(); i++) {
623                 if (param.options[i].rangeResult.size() > 0) {
624                     param.values.emplace_back(param.options[i].rangeResult.front());
625                 }
626             }
627         }
628     }
629     return true;
630 }
631 
ParseMultiTextArray(const JSRef<JSObject> & paramObject,ParseTextArrayParam & param)632 bool JSTextPickerParser::ParseMultiTextArray(const JSRef<JSObject>& paramObject, ParseTextArrayParam& param)
633 {
634     auto getSelected = paramObject->GetProperty("selected");
635     auto getValue = paramObject->GetProperty("value");
636     auto getRange = paramObject->GetProperty("range");
637     if (getRange->IsNull() || getRange->IsUndefined()) {
638         return false;
639     }
640     if (!getRange->IsArray()) {
641         return false;
642     }
643     JSRef<JSArray> array = JSRef<JSArray>::Cast(getRange);
644     if (!ParseMultiTextArrayRange(array, param.options)) {
645         return false;
646     }
647     if (getValue->IsObject()) {
648         JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(getValue);
649         param.valueChangeEventVal = valueObj->GetProperty("changeEvent");
650         if (param.valueChangeEventVal->IsFunction()) {
651             getValue = valueObj->GetProperty("value");
652         }
653     }
654     if (!ParseMultiTextArrayValue(getValue, param)) {
655         return false;
656     }
657     if (getSelected->IsObject()) {
658         JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(getSelected);
659         param.selectedChangeEventVal = selectedObj->GetProperty("changeEvent");
660         if (param.selectedChangeEventVal->IsFunction()) {
661             getSelected = selectedObj->GetProperty("value");
662         }
663     }
664     if (!ParseMultiTextArraySelect(getSelected, param)) {
665         return false;
666     }
667     return true;
668 }
669 
ParseInternalArray(const JSRef<JSArray> & jsRangeValue,std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,uint32_t index,bool isHasSelectAttr)670 bool JSTextPickerParser::ParseInternalArray(const JSRef<JSArray>& jsRangeValue, std::vector<uint32_t>& selectedValues,
671     std::vector<std::string>& values, uint32_t index, bool isHasSelectAttr)
672 {
673     std::vector<std::string> resultStr;
674     for (size_t i = 0; i < jsRangeValue->Length(); i++) {
675         if (jsRangeValue->GetValueAt(i)->IsObject()) {
676             auto jsObj = JSRef<JSObject>::Cast(jsRangeValue->GetValueAt(i));
677             auto getText = jsObj->GetProperty("text");
678             std::string textStr = "";
679             if (ParseJsString(getText, textStr)) {
680                 resultStr.emplace_back(textStr);
681             } else {
682                 return false;
683             }
684         }
685     }
686     if (index + 1 > values.size()) {
687         if (resultStr.size() > 0) {
688             values.emplace_back(resultStr.front());
689         } else {
690             values.emplace_back("");
691         }
692     } else {
693         if (resultStr.size() > 0) {
694             auto valueIterator = std::find(resultStr.begin(), resultStr.end(), values[index]);
695             if (valueIterator == resultStr.end()) {
696                 values[index] = resultStr.front();
697             }
698         } else {
699             values[index] = "";
700         }
701     }
702 
703     SetSelectedValues(selectedValues, values, index, isHasSelectAttr, resultStr);
704 
705     if (!jsRangeValue->GetValueAt(selectedValues[index])->IsObject()) {
706         return true;
707     }
708     auto jsObj = JSRef<JSObject>::Cast(jsRangeValue->GetValueAt(selectedValues[index]));
709     auto getChildren = jsObj->GetProperty("children");
710     if (getChildren->IsArray()) {
711         ParseInternalArray(getChildren, selectedValues, values, index + 1, isHasSelectAttr);
712     }
713     return true;
714 }
715 
SetSelectedValues(std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,uint32_t index,bool isHasSelectAttr,std::vector<std::string> & resultStr)716 void JSTextPickerParser::SetSelectedValues(std::vector<uint32_t>& selectedValues, std::vector<std::string>& values,
717     uint32_t index, bool isHasSelectAttr, std::vector<std::string>& resultStr)
718 {
719     if (index + 1 > selectedValues.size()) {
720         selectedValues.emplace_back(0);
721     } else {
722         if (selectedValues[index] >= resultStr.size()) {
723             selectedValues[index] = 0;
724         }
725     }
726 
727     if (!isHasSelectAttr && selectedValues[index] == 0 && !values[index].empty()) {
728         auto valueIterator = std::find(resultStr.begin(), resultStr.end(), values[index]);
729         if (valueIterator != resultStr.end()) {
730             auto localDistance = std::distance(resultStr.begin(), valueIterator);
731             selectedValues[index] = localDistance > 0 ? static_cast<uint32_t>(localDistance) : 0;
732         }
733     }
734 }
735 
ParseCascadeTextArray(const JSRef<JSObject> & paramObject,std::vector<uint32_t> & selectedValues,std::vector<std::string> & values,NG::TextCascadePickerOptionsAttr & attr)736 bool JSTextPickerParser::ParseCascadeTextArray(const JSRef<JSObject>& paramObject,
737     std::vector<uint32_t>& selectedValues, std::vector<std::string>& values, NG::TextCascadePickerOptionsAttr& attr)
738 {
739     JSRef<JSArray> getRange = paramObject->GetProperty("range");
740     auto getSelected = paramObject->GetProperty("selected");
741     auto getValue = paramObject->GetProperty("value");
742     if (getValue->IsArray()) {
743         if (!ParseJsStrArray(getValue, values)) {
744             return false;
745         }
746     } else {
747         std::string value = "";
748         if (!ParseJsString(getValue, value)) {
749             value = "";
750         }
751         values.emplace_back(value);
752     }
753     if (getSelected->IsArray()) {
754         if (!ParseJsIntegerArray(getSelected, selectedValues)) {
755             attr.isHasSelectAttr = false;
756             return false;
757         } else {
758             attr.isHasSelectAttr = true;
759         }
760     } else {
761         uint32_t selectValue = 0;
762         if (!ParseJsInteger(getSelected, selectValue)) {
763             selectValue = 0;
764             attr.isHasSelectAttr = false;
765         } else {
766             attr.isHasSelectAttr = true;
767         }
768         selectedValues.emplace_back(selectValue);
769     }
770     return ParseInternalArray(getRange, selectedValues, values, 0, attr.isHasSelectAttr);
771 }
772 
ParseTextArray(const JSRef<JSObject> & paramObject,ParseTextArrayParam & param)773 bool JSTextPickerParser::ParseTextArray(const JSRef<JSObject>& paramObject, ParseTextArrayParam& param)
774 {
775     auto getSelected = paramObject->GetProperty("selected");
776     auto getValue = paramObject->GetProperty("value");
777     JSRef<JSArray> getRange = paramObject->GetProperty("range");
778     std::vector<std::string> getRangeVector;
779     if (getRange->Length() > 0) {
780         if (!ParseJsStrArray(getRange, getRangeVector)) {
781             return false;
782         }
783 
784         param.result.clear();
785         for (const auto& text : getRangeVector) {
786             NG::RangeContent content;
787             content.icon_ = "";
788             content.text_ = text;
789             param.result.emplace_back(content);
790         }
791         param.kind = NG::TEXT;
792         if (getValue->IsObject()) {
793             JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(getValue);
794             param.valueChangeEventVal = valueObj->GetProperty("changeEvent");
795             if (param.valueChangeEventVal->IsFunction()) {
796                 getValue = valueObj->GetProperty("value");
797             }
798         }
799         if (!ParseJsString(getValue, param.value)) {
800             param.value = getRangeVector.front();
801         }
802         if (getSelected->IsObject()) {
803             JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(getSelected);
804             param.selectedChangeEventVal = selectedObj->GetProperty("changeEvent");
805             if (param.selectedChangeEventVal->IsFunction()) {
806                 getSelected = selectedObj->GetProperty("value");
807             }
808         }
809         if (!ParseJsInteger(getSelected, param.selected) && !param.value.empty()) {
810             auto valueIterator = std::find(getRangeVector.begin(), getRangeVector.end(), param.value);
811             if (valueIterator != getRangeVector.end()) {
812                 param.selected = static_cast<uint32_t>(std::distance(getRangeVector.begin(), valueIterator));
813             }
814         }
815         if (param.selected >= getRangeVector.size()) {
816             param.selected = 0;
817         }
818     }
819 
820     return true;
821 }
822 
ParseIconTextArray(const JSRef<JSObject> & paramObject,std::vector<NG::RangeContent> & result,uint32_t & kind,uint32_t & selectedValue)823 bool JSTextPickerParser::ParseIconTextArray(
824     const JSRef<JSObject>& paramObject, std::vector<NG::RangeContent>& result, uint32_t& kind, uint32_t& selectedValue)
825 {
826     auto getSelected = paramObject->GetProperty("selected");
827     auto getRange = paramObject->GetProperty("range");
828     if (!getRange->IsArray()) {
829         return false;
830     }
831     JSRef<JSArray> array = JSRef<JSArray>::Cast(getRange);
832     result.clear();
833     kind = 0;
834     for (size_t i = 0; i < array->Length(); i++) {
835         if (!array->GetValueAt(i)->IsObject()) {
836             continue;
837         }
838         auto jsObj = JSRef<JSObject>::Cast(array->GetValueAt(i));
839         auto rangeIcon = jsObj->GetProperty("icon");
840         auto rangeText = jsObj->GetProperty("text");
841         NG::RangeContent content;
842         std::string icon;
843         std::string text;
844         if (ParseJsMedia(rangeIcon, icon)) {
845             content.icon_ = icon;
846             kind |= NG::ICON;
847         }
848 
849         if (ParseJsString(rangeText, text)) {
850             content.text_ = text;
851             kind |= NG::TEXT;
852         }
853         result.emplace_back(content);
854     }
855 
856     if (kind != NG::ICON && kind != (NG::ICON | NG::TEXT)) {
857         return false;
858     }
859 
860     if (!ParseJsInteger(getSelected, selectedValue)) {
861         selectedValue = 0;
862     }
863     return true;
864 }
865 
IsUserDefinedFontFamily(const std::string & pos)866 void JSTextPickerParser::IsUserDefinedFontFamily(const std::string& pos)
867 {
868     if (pos == "disappearTextStyle") {
869         TextPickerModel::GetInstance()->HasUserDefinedDisappearFontFamily(true);
870     } else if (pos == "textStyle") {
871         TextPickerModel::GetInstance()->HasUserDefinedNormalFontFamily(true);
872     } else if (pos == "selectedTextStyle") {
873         TextPickerModel::GetInstance()->HasUserDefinedSelectedFontFamily(true);
874     }
875 }
876 
ParseTextStyle(const JSRef<JSObject> & paramObj,NG::PickerTextStyle & textStyle,const std::string & pos)877 void JSTextPickerParser::ParseTextStyle(
878     const JSRef<JSObject>& paramObj, NG::PickerTextStyle& textStyle, const std::string& pos)
879 {
880     auto fontColor = paramObj->GetProperty("color");
881     auto fontOptions = paramObj->GetProperty("font");
882 
883     Color textColor;
884     if (ParseJsColor(fontColor, textColor)) {
885         textStyle.textColor = textColor;
886     }
887 
888     if (!fontOptions->IsObject()) {
889         return;
890     }
891     JSRef<JSObject> fontObj = JSRef<JSObject>::Cast(fontOptions);
892     auto fontSize = fontObj->GetProperty("size");
893     auto fontWeight = fontObj->GetProperty("weight");
894     auto fontFamily = fontObj->GetProperty("family");
895     auto fontStyle = fontObj->GetProperty("style");
896     if (fontSize->IsNull() || fontSize->IsUndefined()) {
897         textStyle.fontSize = Dimension(-1);
898     } else {
899         CalcDimension size;
900         if (!ParseJsDimensionFp(fontSize, size) || size.Unit() == DimensionUnit::PERCENT) {
901             textStyle.fontSize = Dimension(-1);
902         } else {
903             textStyle.fontSize = size;
904         }
905     }
906 
907     if (!fontWeight->IsNull() && !fontWeight->IsUndefined()) {
908         std::string weight;
909         if (fontWeight->IsNumber()) {
910             weight = std::to_string(fontWeight->ToNumber<int32_t>());
911         } else {
912             ParseJsString(fontWeight, weight);
913         }
914         textStyle.fontWeight = ConvertStrToFontWeight(weight);
915     }
916 
917     if (!fontFamily->IsNull() && !fontFamily->IsUndefined()) {
918         std::vector<std::string> families;
919         if (ParseJsFontFamilies(fontFamily, families)) {
920             textStyle.fontFamily = families;
921             IsUserDefinedFontFamily(pos);
922         }
923     }
924 
925     if (fontStyle->IsNumber()) {
926         auto style = fontStyle->ToNumber<int32_t>();
927         if (style < 0 || style > 1) {
928             return;
929         }
930         textStyle.fontStyle = static_cast<FontStyle>(style);
931     }
932 }
933 
SetDefaultPickerItemHeight(const JSCallbackInfo & info)934 void JSTextPicker::SetDefaultPickerItemHeight(const JSCallbackInfo& info)
935 {
936     if (info.Length() < 1) {
937         return;
938     }
939     CalcDimension height;
940     if (info[0]->IsNumber() || info[0]->IsString()) {
941         if (!ParseJsDimensionFp(info[0], height)) {
942             return;
943         }
944     }
945     TextPickerModel::GetInstance()->SetDefaultPickerItemHeight(height);
946 }
947 
SetGradientHeight(const JSCallbackInfo & info)948 void JSTextPicker::SetGradientHeight(const JSCallbackInfo& info)
949 {
950     CalcDimension height;
951     auto pickerTheme = GetTheme<PickerTheme>();
952     if (info[0]->IsNull() || info[0]->IsUndefined()) {
953         if (pickerTheme) {
954             height = pickerTheme->GetGradientHeight();
955         } else {
956             height = 0.0_vp;
957         }
958     }
959     if (info.Length() >= 1) {
960         if (!ConvertFromJSValueNG(info[0], height)) {
961             if (pickerTheme) {
962                 height = pickerTheme->GetGradientHeight();
963             }
964         }
965         if ((height.Unit() == DimensionUnit::PERCENT) &&
966             ((height.Value() > 1.0f) || (height.Value() < 0.0f))) {
967             if (pickerTheme) {
968                 height = pickerTheme->GetGradientHeight();
969             } else {
970                 height = 0.0_vp;
971             }
972         }
973     }
974     TextPickerModel::GetInstance()->SetGradientHeight(height);
975 }
976 
SetCanLoop(const JSCallbackInfo & info)977 void JSTextPicker::SetCanLoop(const JSCallbackInfo& info)
978 {
979     bool value = true;
980     if (info[0]->IsBoolean()) {
981         value = info[0]->ToBoolean();
982     }
983     TextPickerModel::GetInstance()->SetCanLoop(value);
984 }
985 
SetDisappearTextStyle(const JSCallbackInfo & info)986 void JSTextPicker::SetDisappearTextStyle(const JSCallbackInfo& info)
987 {
988     auto theme = GetTheme<PickerTheme>();
989     CHECK_NULL_VOID(theme);
990     NG::PickerTextStyle textStyle;
991     JSTextPickerTheme::ObtainTextStyle(textStyle);
992     if (info[0]->IsObject()) {
993         JSTextPickerParser::ParseTextStyle(info[0], textStyle, "disappearTextStyle");
994     }
995     TextPickerModel::GetInstance()->SetDisappearTextStyle(theme, textStyle);
996 }
997 
SetTextStyle(const JSCallbackInfo & info)998 void JSTextPicker::SetTextStyle(const JSCallbackInfo& info)
999 {
1000     auto theme = GetTheme<PickerTheme>();
1001     CHECK_NULL_VOID(theme);
1002     NG::PickerTextStyle textStyle;
1003     JSTextPickerTheme::ObtainTextStyle(textStyle);
1004     if (info[0]->IsObject()) {
1005         JSTextPickerParser::ParseTextStyle(info[0], textStyle, "textStyle");
1006     }
1007     TextPickerModel::GetInstance()->SetNormalTextStyle(theme, textStyle);
1008 }
1009 
SetSelectedTextStyle(const JSCallbackInfo & info)1010 void JSTextPicker::SetSelectedTextStyle(const JSCallbackInfo& info)
1011 {
1012     auto theme = GetTheme<PickerTheme>();
1013     CHECK_NULL_VOID(theme);
1014     NG::PickerTextStyle textStyle;
1015     JSTextPickerTheme::ObtainSelectedTextStyle(textStyle);
1016     if (info[0]->IsObject()) {
1017         JSTextPickerParser::ParseTextStyle(info[0], textStyle, "selectedTextStyle");
1018     }
1019     TextPickerModel::GetInstance()->SetSelectedTextStyle(theme, textStyle);
1020 }
1021 
ProcessCascadeSelected(const std::vector<NG::TextCascadePickerOptions> & options,uint32_t index,std::vector<uint32_t> & selectedValues)1022 void JSTextPicker::ProcessCascadeSelected(
1023     const std::vector<NG::TextCascadePickerOptions>& options, uint32_t index, std::vector<uint32_t>& selectedValues)
1024 {
1025     std::vector<std::string> rangeResultValue;
1026     for (size_t i = 0; i < options.size(); i++) {
1027         rangeResultValue.emplace_back(options[i].rangeResult[0]);
1028     }
1029 
1030     if (static_cast<int32_t>(index) > static_cast<int32_t>(selectedValues.size()) - 1) {
1031         selectedValues.emplace_back(0);
1032     }
1033     if (selectedValues[index] >= rangeResultValue.size()) {
1034         selectedValues[index] = 0;
1035     }
1036     if (static_cast<int32_t>(selectedValues[index]) <= static_cast<int32_t>(options.size()) - 1 &&
1037         options[selectedValues[index]].children.size() > 0) {
1038         ProcessCascadeSelected(options[selectedValues[index]].children, index + 1, selectedValues);
1039     }
1040 }
1041 
SetSelectedInternal(uint32_t count,std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues)1042 void JSTextPicker::SetSelectedInternal(
1043     uint32_t count, std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues)
1044 {
1045     for (uint32_t i = 0; i < count; i++) {
1046         if (selectedValues.size() > 0 && selectedValues.size() < i + 1) {
1047             selectedValues.emplace_back(0);
1048         } else {
1049             if (selectedValues[i] >= options[i].rangeResult.size()) {
1050                 selectedValues[i] = 0;
1051             }
1052         }
1053     }
1054 }
1055 
SetSelectedIndexMultiInternal(uint32_t count,std::vector<NG::TextCascadePickerOptions> & options,std::vector<uint32_t> & selectedValues)1056 void JSTextPicker::SetSelectedIndexMultiInternal(
1057     uint32_t count, std::vector<NG::TextCascadePickerOptions>& options, std::vector<uint32_t>& selectedValues)
1058 {
1059     if (!TextPickerModel::GetInstance()->IsCascade()) {
1060         SetSelectedInternal(count, options, selectedValues);
1061     } else {
1062         TextPickerModel::GetInstance()->SetHasSelectAttr(true);
1063         ProcessCascadeSelected(options, 0, selectedValues);
1064         uint32_t maxCount = TextPickerModel::GetInstance()->GetMaxCount();
1065         if (selectedValues.size() < maxCount) {
1066             auto differ = maxCount - selectedValues.size();
1067             for (uint32_t i = 0; i < differ; i++) {
1068                 selectedValues.emplace_back(0);
1069             }
1070         }
1071     }
1072 }
1073 
SetSelectedIndexSingleInternal(const std::vector<NG::TextCascadePickerOptions> & options,uint32_t count,uint32_t & selectedValue,std::vector<uint32_t> & selectedValues)1074 void JSTextPicker::SetSelectedIndexSingleInternal(const std::vector<NG::TextCascadePickerOptions>& options,
1075     uint32_t count, uint32_t& selectedValue, std::vector<uint32_t>& selectedValues)
1076 {
1077     if (options.size() > 0) {
1078         if (selectedValue >= options[0].rangeResult.size()) {
1079             selectedValue = 0;
1080         }
1081         selectedValues.emplace_back(selectedValue);
1082         for (uint32_t i = 1; i < count; i++) {
1083             selectedValues.emplace_back(0);
1084         }
1085     } else {
1086         for (uint32_t i = 0; i < count; i++) {
1087             selectedValues.emplace_back(0);
1088         }
1089     }
1090 }
1091 
SetSelectedIndexMulti(const JsiRef<JsiValue> & jsSelectedValue)1092 void JSTextPicker::SetSelectedIndexMulti(const JsiRef<JsiValue>& jsSelectedValue)
1093 {
1094     std::vector<uint32_t> selectedValues;
1095     std::vector<NG::TextCascadePickerOptions> options;
1096     TextPickerModel::GetInstance()->GetMultiOptions(options);
1097     auto count =
1098         TextPickerModel::GetInstance()->IsCascade() ? TextPickerModel::GetInstance()->GetMaxCount() : options.size();
1099     if (jsSelectedValue->IsArray()) {
1100         if (!ParseJsIntegerArray(jsSelectedValue, selectedValues)) {
1101             selectedValues.clear();
1102             for (uint32_t i = 0; i < count; i++) {
1103                 selectedValues.emplace_back(0);
1104             }
1105             TextPickerModel::GetInstance()->SetSelecteds(selectedValues);
1106             TextPickerModel::GetInstance()->SetHasSelectAttr(false);
1107             return;
1108         }
1109         SetSelectedIndexMultiInternal(count, options, selectedValues);
1110     } else {
1111         uint32_t selectedValue = 0;
1112         if (ParseJsInteger(jsSelectedValue, selectedValue)) {
1113             TextPickerModel::GetInstance()->SetHasSelectAttr(true);
1114             SetSelectedIndexSingleInternal(options, count, selectedValue, selectedValues);
1115         } else {
1116             selectedValues.clear();
1117             TextPickerModel::GetInstance()->SetHasSelectAttr(false);
1118             for (uint32_t i = 0; i < count; i++) {
1119                 selectedValues.emplace_back(0);
1120             }
1121         }
1122     }
1123     TextPickerModel::GetInstance()->SetSelecteds(selectedValues);
1124 }
1125 
SetSelectedIndexSingle(const JsiRef<JsiValue> & jsSelectedValue)1126 void JSTextPicker::SetSelectedIndexSingle(const JsiRef<JsiValue>& jsSelectedValue)
1127 {
1128     // Single
1129     std::vector<NG::RangeContent> rangeResult;
1130     TextPickerModel::GetInstance()->GetSingleRange(rangeResult);
1131     if (jsSelectedValue->IsArray()) {
1132         std::vector<uint32_t> selectedValues;
1133         if (!ParseJsIntegerArray(jsSelectedValue, selectedValues)) {
1134             uint32_t selectedValue = 0;
1135             TextPickerModel::GetInstance()->SetSelected(selectedValue);
1136             return;
1137         }
1138         if (selectedValues.size() > 0) {
1139             if (selectedValues[0] >= rangeResult.size()) {
1140                 selectedValues[0] = 0;
1141             }
1142         } else {
1143             selectedValues.emplace_back(0);
1144         }
1145 
1146         TextPickerModel::GetInstance()->SetSelected(selectedValues[0]);
1147     } else {
1148         uint32_t selectedValue = 0;
1149         if (ParseJsInteger(jsSelectedValue, selectedValue)) {
1150             if (selectedValue >= rangeResult.size()) {
1151                 selectedValue = 0;
1152             }
1153         }
1154         TextPickerModel::GetInstance()->SetSelected(selectedValue);
1155     }
1156 }
1157 
SetSelectedIndex(const JSCallbackInfo & info)1158 void JSTextPicker::SetSelectedIndex(const JSCallbackInfo& info)
1159 {
1160     if (info.Length() >= 1) {
1161         auto jsSelectedValue = info[0];
1162         if (jsSelectedValue->IsNull() || jsSelectedValue->IsUndefined()) {
1163             return;
1164         }
1165         if (TextPickerModel::GetInstance()->IsSingle()) {
1166             SetSelectedIndexSingle(jsSelectedValue);
1167         } else {
1168             SetSelectedIndexMulti(jsSelectedValue);
1169         }
1170     }
1171 }
1172 
CheckDividerValue(const Dimension & dimension)1173 bool JSTextPicker::CheckDividerValue(const Dimension &dimension)
1174 {
1175     if (dimension.Value() >= 0.0f && dimension.Unit() != DimensionUnit::PERCENT) {
1176         return true;
1177     }
1178     return false;
1179 }
1180 
SetDivider(const JSCallbackInfo & info)1181 void JSTextPicker::SetDivider(const JSCallbackInfo& info)
1182 {
1183     NG::ItemDivider divider;
1184     auto pickerTheme = GetTheme<PickerTheme>();
1185     Dimension defaultStrokeWidth = 0.0_vp;
1186     Dimension defaultMargin = 0.0_vp;
1187     Color defaultColor = Color::TRANSPARENT;
1188     // Set default strokeWidth and color
1189     if (pickerTheme) {
1190         defaultStrokeWidth = pickerTheme->GetDividerThickness();
1191         defaultColor = pickerTheme->GetDividerColor();
1192         divider.strokeWidth = defaultStrokeWidth;
1193         divider.color = defaultColor;
1194     }
1195 
1196     if (info.Length() >= 1 && info[0]->IsObject()) {
1197         JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
1198 
1199         Dimension strokeWidth = defaultStrokeWidth;
1200         if (ConvertFromJSValueNG(obj->GetProperty("strokeWidth"), strokeWidth) && CheckDividerValue(strokeWidth)) {
1201             divider.strokeWidth = strokeWidth;
1202         }
1203 
1204         Color color = defaultColor;
1205         if (ConvertFromJSValue(obj->GetProperty("color"), color)) {
1206             divider.color = color;
1207         }
1208 
1209         Dimension startMargin = defaultMargin;
1210         if (ConvertFromJSValueNG(obj->GetProperty("startMargin"), startMargin) && CheckDividerValue(startMargin)) {
1211             divider.startMargin = startMargin;
1212         }
1213 
1214         Dimension endMargin = defaultMargin;
1215         if (ConvertFromJSValueNG(obj->GetProperty("endMargin"), endMargin) &&  CheckDividerValue(endMargin)) {
1216             divider.endMargin = endMargin;
1217         }
1218     } else if (info.Length() >= 1 && info[0]->IsNull()) {
1219         divider.strokeWidth = 0.0_vp;
1220     }
1221     TextPickerModel::GetInstance()->SetDivider(divider);
1222 }
1223 
OnAccept(const JSCallbackInfo & info)1224 void JSTextPicker::OnAccept(const JSCallbackInfo& info) {}
1225 
OnCancel(const JSCallbackInfo & info)1226 void JSTextPicker::OnCancel(const JSCallbackInfo& info) {}
1227 
OnChange(const JSCallbackInfo & info)1228 void JSTextPicker::OnChange(const JSCallbackInfo& info)
1229 {
1230     if (!info[0]->IsFunction()) {
1231         return;
1232     }
1233     auto jsFunc = JSRef<JSFunc>::Cast(info[0]);
1234     auto onChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
1235                         const std::vector<std::string>& value, const std::vector<double>& index) {
1236         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1237         ACE_SCORING_EVENT("TextPicker.onChange");
1238         if (value.size() == 1 && index.size() == 1) {
1239             auto params = ConvertToJSValues(value[0], index[0]);
1240             func->Call(JSRef<JSObject>(), static_cast<int>(params.size()), params.data());
1241         } else {
1242             std::vector<JSRef<JSVal>> result;
1243             JSRef<JSArray> valueArray = JSRef<JSArray>::New();
1244             for (uint32_t i = 0; i < value.size(); i++) {
1245                 valueArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(value[i])));
1246             }
1247             JSRef<JSVal> valueJs = JSRef<JSVal>::Cast(valueArray);
1248             result.emplace_back(valueJs);
1249             JSRef<JSArray> selectedArray = JSRef<JSArray>::New();
1250             for (uint32_t i = 0; i < index.size(); i++) {
1251                 selectedArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(index[i])));
1252             }
1253             JSRef<JSVal> selectedJs = JSRef<JSVal>::Cast(selectedArray);
1254             result.emplace_back(selectedJs);
1255             func->Call(JSRef<JSObject>(), static_cast<int>(result.size()), result.data());
1256         }
1257     };
1258     TextPickerModel::GetInstance()->SetOnCascadeChange(std::move(onChange));
1259     info.ReturnSelf();
1260 }
1261 
OnScrollStop(const JSCallbackInfo & info)1262 void JSTextPicker::OnScrollStop(const JSCallbackInfo& info)
1263 {
1264     if (!info[0]->IsFunction()) {
1265         return;
1266     }
1267     auto jsFunc = JSRef<JSFunc>::Cast(info[0]);
1268     auto onScrollStop = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
1269                         const std::vector<std::string>& value, const std::vector<double>& index) {
1270         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1271         ACE_SCORING_EVENT("TextPicker.onScrollStop");
1272         if (value.size() == 1 && index.size() == 1) {
1273             auto params = ConvertToJSValues(value[0], index[0]);
1274             func->Call(JSRef<JSObject>(), static_cast<int>(params.size()), params.data());
1275         } else {
1276             std::vector<JSRef<JSVal>> result;
1277             JSRef<JSArray> valueArray = JSRef<JSArray>::New();
1278             for (uint32_t i = 0; i < value.size(); i++) {
1279                 valueArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(value[i])));
1280             }
1281             JSRef<JSVal> valueJs = JSRef<JSVal>::Cast(valueArray);
1282             result.emplace_back(valueJs);
1283             JSRef<JSArray> selectedArray = JSRef<JSArray>::New();
1284             for (uint32_t i = 0; i < index.size(); i++) {
1285                 selectedArray->SetValueAt(i, JSRef<JSVal>::Make(ToJSValue(index[i])));
1286             }
1287             JSRef<JSVal> selectedJs = JSRef<JSVal>::Cast(selectedArray);
1288             result.emplace_back(selectedJs);
1289             func->Call(JSRef<JSObject>(), static_cast<int>(result.size()), result.data());
1290         }
1291     };
1292     TextPickerModel::GetInstance()->SetOnScrollStop(std::move(onScrollStop));
1293     info.ReturnSelf();
1294 }
1295 
JSBind(BindingTarget globalObj)1296 void JSTextPickerDialog::JSBind(BindingTarget globalObj)
1297 {
1298     JSClass<JSTextPickerDialog>::Declare("TextPickerDialog");
1299     JSClass<JSTextPickerDialog>::StaticMethod("show", &JSTextPickerDialog::Show);
1300 
1301     JSClass<JSTextPickerDialog>::Bind<>(globalObj);
1302 }
1303 
TextPickerDialogAppearEvent(const JSCallbackInfo & info,TextPickerDialogEvent & textPickerDialogEvent)1304 void TextPickerDialogAppearEvent(const JSCallbackInfo& info, TextPickerDialogEvent& textPickerDialogEvent)
1305 {
1306     std::function<void()> didAppearEvent;
1307     std::function<void()> willAppearEvent;
1308     if (!info[0]->IsObject()) {
1309         return;
1310     }
1311     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1312     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1313     auto onDidAppear = paramObject->GetProperty("onDidAppear");
1314     if (!onDidAppear->IsUndefined() && onDidAppear->IsFunction()) {
1315         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidAppear));
1316         didAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1317             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1318             ACE_SCORING_EVENT("TextPickerDialog.onDidAppear");
1319             PipelineContext::SetCallBackNode(node);
1320             func->Execute();
1321         };
1322     }
1323     auto onWillAppear = paramObject->GetProperty("onWillAppear");
1324     if (!onWillAppear->IsUndefined() && onWillAppear->IsFunction()) {
1325         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillAppear));
1326         willAppearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1327             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1328             ACE_SCORING_EVENT("TextPickerDialog.onWillAppear");
1329             PipelineContext::SetCallBackNode(node);
1330             func->Execute();
1331         };
1332     }
1333     textPickerDialogEvent.onDidAppear = std::move(didAppearEvent);
1334     textPickerDialogEvent.onWillAppear = std::move(willAppearEvent);
1335 }
1336 
TextPickerDialogDisappearEvent(const JSCallbackInfo & info,TextPickerDialogEvent & textPickerDialogEvent)1337 void TextPickerDialogDisappearEvent(const JSCallbackInfo& info, TextPickerDialogEvent& textPickerDialogEvent)
1338 {
1339     std::function<void()> didDisappearEvent;
1340     std::function<void()> willDisappearEvent;
1341     if (!info[0]->IsObject()) {
1342         return;
1343     }
1344     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1345     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1346     auto onDidDisappear = paramObject->GetProperty("onDidDisappear");
1347     if (!onDidDisappear->IsUndefined() && onDidDisappear->IsFunction()) {
1348         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onDidDisappear));
1349         didDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1350             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1351             ACE_SCORING_EVENT("TextPickerDialog.onDidDisappear");
1352             PipelineContext::SetCallBackNode(node);
1353             func->Execute();
1354         };
1355     }
1356     auto onWillDisappear = paramObject->GetProperty("onWillDisappear");
1357     if (!onWillDisappear->IsUndefined() && onWillDisappear->IsFunction()) {
1358         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onWillDisappear));
1359         willDisappearEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1360             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1361             ACE_SCORING_EVENT("TextPickerDialog.onWillDisappear");
1362             PipelineContext::SetCallBackNode(node);
1363             func->Execute();
1364         };
1365     }
1366     textPickerDialogEvent.onDidDisappear = std::move(didDisappearEvent);
1367     textPickerDialogEvent.onWillDisappear = std::move(willDisappearEvent);
1368 }
1369 
Show(const JSCallbackInfo & info)1370 void JSTextPickerDialog::Show(const JSCallbackInfo& info)
1371 {
1372     auto scopedDelegate = EngineHelper::GetCurrentDelegateSafely();
1373     CHECK_NULL_VOID(scopedDelegate);
1374     if (!info[0]->IsObject()) {
1375         return;
1376     }
1377 
1378     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1379     std::function<void()> cancelEvent;
1380     std::function<void(const std::string&)> acceptEvent;
1381     std::function<void(const std::string&)> changeEvent;
1382     auto onCancel = paramObject->GetProperty("onCancel");
1383     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1384     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1385         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1386         cancelEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1387             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1388             ACE_SCORING_EVENT("TextPickerDialog.onCancel");
1389             PipelineContext::SetCallBackNode(node);
1390             func->Execute();
1391         };
1392     }
1393     auto onAccept = paramObject->GetProperty("onAccept");
1394     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1395         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1396         acceptEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1397                           const std::string& info) {
1398             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1399             std::vector<std::string> keys = { "value", "index" };
1400             ACE_SCORING_EVENT("TextPickerDialog.onAccept");
1401             PipelineContext::SetCallBackNode(node);
1402             func->Execute(keys, info);
1403         };
1404     }
1405     auto onChange = paramObject->GetProperty("onChange");
1406     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1407         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1408         changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1409                           const std::string& info) {
1410             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1411             std::vector<std::string> keys = { "value", "index" };
1412             ACE_SCORING_EVENT("TextPickerDialog.onChange");
1413             PipelineContext::SetCallBackNode(node);
1414             func->Execute(keys, info);
1415         };
1416     }
1417     std::function<void(const std::string&)> scrollStopEvent;
1418     auto onScrollStop = paramObject->GetProperty("onScrollStop");
1419     if (!onScrollStop->IsUndefined() && onScrollStop->IsFunction()) {
1420         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onScrollStop));
1421         scrollStopEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1422                               const std::string& info) {
1423             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1424             std::vector<std::string> keys = { "value", "index" };
1425             ACE_SCORING_EVENT("TextPickerDialog.onScrollStop");
1426             PipelineContext::SetCallBackNode(node);
1427             func->Execute(keys, info);
1428         };
1429     }
1430     NG::TextPickerSettingData settingData;
1431     TextPickerDialog textPickerDialog;
1432 
1433     auto pickerText = TextPickerDialogModel::GetInstance()->CreateObject();
1434     if (pickerText == nullptr) {
1435         // parse Multi column text
1436         if (!ParseShowData(paramObject, settingData)) {
1437             return;
1438         }
1439     } else {
1440         auto getSelected = paramObject->GetProperty("selected");
1441         auto defaultHeight = paramObject->GetProperty("defaultPickerItemHeight");
1442         auto canLoop = paramObject->GetProperty("canLoop");
1443         JSRef<JSArray> getRange = paramObject->GetProperty("range");
1444         std::vector<std::string> getRangeVector;
1445         if (!JSViewAbstract::ParseJsStrArray(getRange, getRangeVector)) {
1446             return;
1447         }
1448         std::string value = "";
1449         uint32_t selectedValue = 0;
1450         auto getValue = paramObject->GetProperty("value");
1451         if (!JSViewAbstract::ParseJsInteger(getSelected, selectedValue) &&
1452             JSViewAbstract::ParseJsString(getValue, value)) {
1453             auto valueIterator = std::find(getRangeVector.begin(), getRangeVector.end(), value);
1454             if (valueIterator != getRangeVector.end()) {
1455                 selectedValue = static_cast<uint32_t>(std::distance(getRangeVector.begin(), valueIterator));
1456             }
1457         }
1458         if (selectedValue >= getRangeVector.size()) {
1459             selectedValue = 0;
1460         }
1461         CalcDimension height;
1462         if (defaultHeight->IsNumber() || defaultHeight->IsString()) {
1463             if (!JSViewAbstract::ParseJsDimensionFp(defaultHeight, height)) {
1464                 return;
1465             }
1466         }
1467         if (!defaultHeight->IsEmpty()) {
1468             textPickerDialog.isDefaultHeight = true;
1469         }
1470         textPickerDialog.height = height;
1471         textPickerDialog.selectedValue = selectedValue;
1472         textPickerDialog.getRangeVector = getRangeVector;
1473     }
1474 
1475     // Parse alignment
1476     auto alignmentValue = paramObject->GetProperty("alignment");
1477     if (alignmentValue->IsNumber()) {
1478         auto alignment = alignmentValue->ToNumber<int32_t>();
1479         if (alignment >= 0 && alignment < static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
1480             textPickerDialog.alignment = DIALOG_ALIGNMENT[alignment];
1481         }
1482         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1483             if (alignment == static_cast<int32_t>(DialogAlignment::TOP) ||
1484                 alignment == static_cast<int32_t>(DialogAlignment::TOP_START) ||
1485                 alignment == static_cast<int32_t>(DialogAlignment::TOP_END)) {
1486                 textPickerDialog.offset = TEXT_PICKER_OFFSET_DEFAULT_TOP;
1487             }
1488         }
1489     }
1490 
1491     // Parse offset
1492     auto offsetValue = paramObject->GetProperty("offset");
1493     if (offsetValue->IsObject()) {
1494         auto offsetObj = JSRef<JSObject>::Cast(offsetValue);
1495         CalcDimension dx;
1496         auto dxValue = offsetObj->GetProperty("dx");
1497         JSAlertDialog::ParseJsDimensionVp(dxValue, dx);
1498         CalcDimension dy;
1499         auto dyValue = offsetObj->GetProperty("dy");
1500         JSAlertDialog::ParseJsDimensionVp(dyValue, dy);
1501         textPickerDialog.offset = DimensionOffset(dx, dy);
1502     }
1503 
1504     // Parse maskRect.
1505     auto maskRectValue = paramObject->GetProperty("maskRect");
1506     DimensionRect maskRect;
1507     if (JSViewAbstract::ParseJsDimensionRect(maskRectValue, maskRect)) {
1508         textPickerDialog.maskRect = maskRect;
1509     }
1510 
1511     auto backgroundColorValue = paramObject->GetProperty("backgroundColor");
1512     Color backgroundColor;
1513     if (JSViewAbstract::ParseJsColor(backgroundColorValue, backgroundColor)) {
1514         textPickerDialog.backgroundColor = backgroundColor;
1515     }
1516 
1517     auto backgroundBlurStyle = paramObject->GetProperty("backgroundBlurStyle");
1518     if (backgroundBlurStyle->IsNumber()) {
1519         auto blurStyle = backgroundBlurStyle->ToNumber<int32_t>();
1520         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
1521             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
1522             textPickerDialog.backgroundBlurStyle = blurStyle;
1523         }
1524     }
1525     auto shadowValue = paramObject->GetProperty("shadow");
1526     Shadow shadow;
1527     if ((shadowValue->IsObject() || shadowValue->IsNumber()) && JSViewAbstract::ParseShadowProps(shadowValue, shadow)) {
1528         textPickerDialog.shadow = shadow;
1529     }
1530 
1531     auto enableHoverModeValue = paramObject->GetProperty("enableHoverMode");
1532     if (enableHoverModeValue->IsBoolean()) {
1533         textPickerDialog.enableHoverMode = enableHoverModeValue->ToBoolean();
1534     }
1535 
1536     auto hoverModeAreaValue = paramObject->GetProperty("hoverModeArea");
1537     if (hoverModeAreaValue->IsNumber()) {
1538         auto hoverModeArea = hoverModeAreaValue->ToNumber<int32_t>();
1539         if (hoverModeArea >= 0 && hoverModeArea < static_cast<int32_t>(HOVER_MODE_AREA_TYPE.size())) {
1540             textPickerDialog.hoverModeArea = HOVER_MODE_AREA_TYPE[hoverModeArea];
1541         }
1542     }
1543 
1544     auto buttonInfos = ParseButtonStyles(paramObject);
1545 
1546     TextPickerDialogEvent textPickerDialogEvent { nullptr, nullptr, nullptr, nullptr };
1547     TextPickerDialogAppearEvent(info, textPickerDialogEvent);
1548     TextPickerDialogDisappearEvent(info, textPickerDialogEvent);
1549     TextPickerDialogModel::GetInstance()->SetTextPickerDialogShow(pickerText, settingData, std::move(cancelEvent),
1550         std::move(acceptEvent), std::move(changeEvent), std::move(scrollStopEvent), textPickerDialog,
1551         textPickerDialogEvent, buttonInfos);
1552 }
1553 
TextPickerDialogShow(const JSRef<JSObject> & paramObj,const std::map<std::string,NG::DialogTextEvent> & dialogEvent,const std::map<std::string,NG::DialogGestureEvent> & dialogCancelEvent)1554 void JSTextPickerDialog::TextPickerDialogShow(const JSRef<JSObject>& paramObj,
1555     const std::map<std::string, NG::DialogTextEvent>& dialogEvent,
1556     const std::map<std::string, NG::DialogGestureEvent>& dialogCancelEvent)
1557 {
1558     auto container = Container::CurrentSafely();
1559     if (!container) {
1560         return;
1561     }
1562     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
1563     if (!pipelineContext) {
1564         return;
1565     }
1566 
1567     auto executor = pipelineContext->GetTaskExecutor();
1568     if (!executor) {
1569         return;
1570     }
1571 
1572     auto theme = JSTextPicker::GetTheme<DialogTheme>();
1573     CHECK_NULL_VOID(theme);
1574 
1575     NG::TextPickerSettingData settingData;
1576     if (!ParseShowData(paramObj, settingData)) {
1577         return;
1578     }
1579 
1580     DialogProperties properties;
1581     properties.alignment = theme->GetAlignment();
1582     if (properties.alignment == DialogAlignment::BOTTOM &&
1583         Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_ELEVEN)) {
1584         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1585     }
1586 
1587     properties.customStyle = false;
1588     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
1589         properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
1590     }
1591     auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
1592     auto overlayManager = context ? context->GetOverlayManager() : nullptr;
1593     executor->PostTask(
1594         [properties, settingData, dialogEvent, dialogCancelEvent, weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
1595             auto overlayManager = weak.Upgrade();
1596             CHECK_NULL_VOID(overlayManager);
1597             overlayManager->ShowTextDialog(properties, settingData, dialogEvent, dialogCancelEvent);
1598         },
1599         TaskExecutor::TaskType::UI, "ArkUIDialogShowTextPicker");
1600 }
1601 
ParseShowDataOptions(const JSRef<JSObject> & paramObject,ParseTextArrayParam & param,NG::TextCascadePickerOptionsAttr & attr)1602 bool JSTextPickerDialog::ParseShowDataOptions(
1603     const JSRef<JSObject>& paramObject, ParseTextArrayParam& param, NG::TextCascadePickerOptionsAttr& attr)
1604 {
1605     bool optionsMultiContentCheckErr = false;
1606     bool optionsCascadeContentCheckErr = false;
1607     if (!JSTextPickerParser::ParseMultiTextArray(paramObject, param)) {
1608         param.options.clear();
1609         optionsMultiContentCheckErr = true;
1610     }
1611 
1612     if (optionsMultiContentCheckErr) {
1613         if (!JSTextPickerParser::ParseCascadeTextArray(paramObject, param.selecteds, param.values, attr)) {
1614             param.options.clear();
1615             optionsCascadeContentCheckErr = true;
1616         } else {
1617             JSRef<JSArray> getRange = paramObject->GetProperty("range");
1618             JSTextPickerParser::GenerateCascadeOptions(getRange, param.options);
1619             attr.isCascade = true;
1620         }
1621     }
1622     if (optionsMultiContentCheckErr && optionsCascadeContentCheckErr) {
1623         param.options.clear();
1624         return false;
1625     }
1626     return true;
1627 }
1628 
ParseShowDataAttribute(const JSRef<JSObject> & paramObject,NG::TextPickerSettingData & settingData)1629 bool JSTextPickerDialog::ParseShowDataAttribute(
1630     const JSRef<JSObject>& paramObject, NG::TextPickerSettingData& settingData)
1631 {
1632     CalcDimension height;
1633     auto defaultHeight = paramObject->GetProperty("defaultPickerItemHeight");
1634     if (defaultHeight->IsNumber() || defaultHeight->IsString()) {
1635         if (!JSViewAbstract::ParseJsDimensionFp(defaultHeight, height)) {
1636             return false;
1637         }
1638     }
1639     settingData.height = height;
1640     ParseTextProperties(paramObject, settingData.properties);
1641     return true;
1642 }
ParseCanLoop(const JSRef<JSObject> & paramObject,bool & canLoop)1643 bool JSTextPickerDialog::ParseCanLoop(const JSRef<JSObject>& paramObject, bool& canLoop)
1644 {
1645     bool result = false;
1646     auto prop = paramObject->GetProperty("canLoop");
1647     bool value = false;
1648     if (prop->IsBoolean() && JSViewAbstract::ParseJsBool(prop, value)) {
1649         canLoop = value;
1650         result = true;
1651     } else {
1652         canLoop = true;
1653         result = false;
1654     }
1655     return result;
1656 }
1657 
ParseShowDataMultiContent(const std::vector<NG::TextCascadePickerOptions> & options,const std::vector<uint32_t> & selectedValues,const std::vector<std::string> & values,NG::TextCascadePickerOptionsAttr & attr,NG::TextPickerSettingData & settingData)1658 void JSTextPickerDialog::ParseShowDataMultiContent(const std::vector<NG::TextCascadePickerOptions>& options,
1659     const std::vector<uint32_t>& selectedValues, const std::vector<std::string>& values,
1660     NG::TextCascadePickerOptionsAttr& attr, NG::TextPickerSettingData& settingData)
1661 {
1662     settingData.columnKind = NG::TEXT;
1663     for (auto& item : selectedValues) {
1664         settingData.selectedValues.emplace_back(item);
1665     }
1666     for (auto& item : values) {
1667         settingData.values.emplace_back(item);
1668     }
1669     for (auto& item : options) {
1670         settingData.options.emplace_back(item);
1671     }
1672     settingData.attr.isCascade = attr.isCascade;
1673     settingData.attr.isHasSelectAttr = attr.isHasSelectAttr;
1674 }
1675 
ParseShowData(const JSRef<JSObject> & paramObject,NG::TextPickerSettingData & settingData)1676 bool JSTextPickerDialog::ParseShowData(const JSRef<JSObject>& paramObject, NG::TextPickerSettingData& settingData)
1677 {
1678     ParseTextArrayParam param;
1679     bool rangeContentCheckErr = false;
1680     bool optionsCascadeContentCheckErr = false;
1681     NG::TextCascadePickerOptionsAttr attr;
1682     auto getRange = paramObject->GetProperty("range");
1683     if (getRange->IsNull() || getRange->IsUndefined()) {
1684         return false;
1685     }
1686     if (!JSTextPickerParser::ParseTextArray(paramObject, param)) {
1687         if (!JSTextPickerParser::ParseIconTextArray(paramObject, param.result, param.kind, param.selected)) {
1688             rangeContentCheckErr = true;
1689             param.result.clear();
1690         }
1691     }
1692     if (rangeContentCheckErr) {
1693         optionsCascadeContentCheckErr = !ParseShowDataOptions(paramObject, param, attr);
1694     }
1695     if (rangeContentCheckErr && optionsCascadeContentCheckErr) {
1696         return false;
1697     }
1698     if (memset_s(&settingData, sizeof(NG::TextPickerSettingData), 0, sizeof(NG::TextPickerSettingData)) != EOK) {
1699         return false;
1700     }
1701     if (!ParseShowDataAttribute(paramObject, settingData)) {
1702         return false;
1703     }
1704     ParseCanLoop(paramObject, settingData.canLoop);
1705     if (param.result.size() > 0) {
1706         settingData.selected = param.selected;
1707         settingData.columnKind = param.kind;
1708         for (const auto& item : param.result) {
1709             settingData.rangeVector.emplace_back(item);
1710         }
1711     } else {
1712         ParseShowDataMultiContent(param.options, param.selecteds, param.values, attr, settingData);
1713     }
1714     return true;
1715 }
1716 
ParseTextProperties(const JSRef<JSObject> & paramObj,NG::PickerTextProperties & result)1717 void JSTextPickerDialog::ParseTextProperties(const JSRef<JSObject>& paramObj, NG::PickerTextProperties& result)
1718 {
1719     auto disappearProperty = paramObj->GetProperty("disappearTextStyle");
1720     auto normalProperty = paramObj->GetProperty("textStyle");
1721     auto selectedProperty = paramObj->GetProperty("selectedTextStyle");
1722 
1723     if (!disappearProperty->IsNull() && disappearProperty->IsObject()) {
1724         JSRef<JSObject> disappearObj = JSRef<JSObject>::Cast(disappearProperty);
1725         JSTextPickerParser::ParseTextStyle(disappearObj, result.disappearTextStyle_, "disappearTextStyle");
1726     }
1727 
1728     if (!normalProperty->IsNull() && normalProperty->IsObject()) {
1729         JSRef<JSObject> noramlObj = JSRef<JSObject>::Cast(normalProperty);
1730         JSTextPickerParser::ParseTextStyle(noramlObj, result.normalTextStyle_, "textStyle");
1731     }
1732 
1733     if (!selectedProperty->IsNull() && selectedProperty->IsObject()) {
1734         JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(selectedProperty);
1735         JSTextPickerParser::ParseTextStyle(selectedObj, result.selectedTextStyle_, "selectedTextStyle");
1736     }
1737 }
1738 
DialogEvent(const JSCallbackInfo & info)1739 std::map<std::string, NG::DialogTextEvent> JSTextPickerDialog::DialogEvent(const JSCallbackInfo& info)
1740 {
1741     std::map<std::string, NG::DialogTextEvent> dialogEvent;
1742     if (!info[0]->IsObject()) {
1743         return dialogEvent;
1744     }
1745     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1746     auto onAccept = paramObject->GetProperty("onAccept");
1747     auto targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1748     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1749         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1750         auto acceptId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1751                             const std::string& info) {
1752             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1753             std::vector<std::string> keys = { "value", "index" };
1754             ACE_SCORING_EVENT("TextPickerDialog.onAccept");
1755             PipelineContext::SetCallBackNode(node);
1756             func->Execute(keys, info);
1757         };
1758         dialogEvent["acceptId"] = acceptId;
1759     }
1760     auto onChange = paramObject->GetProperty("onChange");
1761     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1762         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1763         auto changeId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1764                             const std::string& info) {
1765             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1766             std::vector<std::string> keys = { "value", "index" };
1767             ACE_SCORING_EVENT("TextPickerDialog.onChange");
1768             PipelineContext::SetCallBackNode(node);
1769             func->Execute(keys, info);
1770         };
1771         dialogEvent["changeId"] = changeId;
1772     }
1773     auto onScrollStop = paramObject->GetProperty("onScrollStop");
1774     if (!onScrollStop->IsUndefined() && onScrollStop->IsFunction()) {
1775         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onScrollStop));
1776         auto scrollStopId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1777                             const std::string& info) {
1778             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1779             std::vector<std::string> keys = { "value", "index" };
1780             ACE_SCORING_EVENT("TextPickerDialog.onScrollStop");
1781             PipelineContext::SetCallBackNode(node);
1782             func->Execute(keys, info);
1783         };
1784         dialogEvent["scrollStopId"] = scrollStopId;
1785     }
1786     return dialogEvent;
1787 }
1788 
DialogCancelEvent(const JSCallbackInfo & info)1789 std::map<std::string, NG::DialogGestureEvent> JSTextPickerDialog::DialogCancelEvent(const JSCallbackInfo& info)
1790 {
1791     std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
1792     if (!info[0]->IsObject()) {
1793         return dialogCancelEvent;
1794     }
1795     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1796     auto onCancel = paramObject->GetProperty("onCancel");
1797     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1798     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1799         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1800         auto cancelId = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1801                             const GestureEvent& /* info */) {
1802             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1803             ACE_SCORING_EVENT("TextPickerDialog.onCancel");
1804             PipelineContext::SetCallBackNode(node);
1805             func->Execute();
1806         };
1807         dialogCancelEvent["cancelId"] = cancelId;
1808     }
1809     return dialogCancelEvent;
1810 }
1811 
AddEvent(RefPtr<PickerTextComponent> & picker,const JSCallbackInfo & info)1812 void JSTextPickerDialog::AddEvent(RefPtr<PickerTextComponent>& picker, const JSCallbackInfo& info)
1813 {
1814     if (!info[0]->IsObject()) {
1815         return;
1816     }
1817     auto paramObject = JSRef<JSObject>::Cast(info[0]);
1818     auto onAccept = paramObject->GetProperty("onAccept");
1819     WeakPtr<NG::FrameNode> targetNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
1820     if (!onAccept->IsUndefined() && onAccept->IsFunction()) {
1821         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onAccept));
1822         auto acceptId = EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1823                                         const std::string& info) {
1824             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1825             std::vector<std::string> keys = { "value", "index" };
1826             ACE_SCORING_EVENT("TextPickerDialog.onAccept");
1827             PipelineContext::SetCallBackNode(node);
1828             func->Execute(keys, info);
1829         });
1830         picker->SetDialogAcceptEvent(acceptId);
1831     }
1832     auto onCancel = paramObject->GetProperty("onCancel");
1833     if (!onCancel->IsUndefined() && onCancel->IsFunction()) {
1834         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCancel));
1835         auto cancelId =
1836             EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode]() {
1837                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1838                 ACE_SCORING_EVENT("TextPickerDialog.onCancel");
1839                 PipelineContext::SetCallBackNode(node);
1840                 func->Execute();
1841             });
1842         picker->SetDialogCancelEvent(cancelId);
1843     }
1844     auto onChange = paramObject->GetProperty("onChange");
1845     if (!onChange->IsUndefined() && onChange->IsFunction()) {
1846         auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onChange));
1847         auto changeId = EventMarker([execCtx = info.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
1848                                         const std::string& info) {
1849             JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1850             std::vector<std::string> keys = { "value", "index" };
1851             ACE_SCORING_EVENT("TextPickerDialog.onChange");
1852             PipelineContext::SetCallBackNode(node);
1853             func->Execute(keys, info);
1854         });
1855         picker->SetDialogChangeEvent(changeId);
1856     }
1857 }
1858 
ParseText(RefPtr<PickerTextComponent> & component,const JSRef<JSObject> & paramObj)1859 void JSTextPickerDialog::ParseText(RefPtr<PickerTextComponent>& component, const JSRef<JSObject>& paramObj)
1860 {
1861     auto getSelected = paramObj->GetProperty("selected");
1862     auto defaultHeight = paramObj->GetProperty("defaultPickerItemHeight");
1863     auto canLoop = paramObj->GetProperty("canLoop");
1864     JSRef<JSArray> getRange = paramObj->GetProperty("range");
1865     std::vector<std::string> getRangeVector;
1866     if (!JSViewAbstract::ParseJsStrArray(getRange, getRangeVector)) {
1867         return;
1868     }
1869 
1870     std::string value = "";
1871     uint32_t selectedValue = 0;
1872     auto getValue = paramObj->GetProperty("value");
1873     if (!JSViewAbstract::ParseJsInteger(getSelected, selectedValue) && JSViewAbstract::ParseJsString(getValue, value)) {
1874         auto valueIterator = std::find(getRangeVector.begin(), getRangeVector.end(), value);
1875         if (valueIterator != getRangeVector.end()) {
1876             selectedValue = static_cast<uint32_t>(std::distance(getRangeVector.begin(), valueIterator));
1877         }
1878     }
1879 
1880     if (selectedValue >= getRangeVector.size()) {
1881         selectedValue = 0;
1882     }
1883 
1884     CalcDimension height;
1885     if (defaultHeight->IsNumber() || defaultHeight->IsString()) {
1886         if (!JSViewAbstract::ParseJsDimensionFp(defaultHeight, height)) {
1887             return;
1888         }
1889     }
1890 
1891     component->SetIsDialog(true);
1892     component->SetIsCreateDialogComponent(true);
1893     if (!defaultHeight->IsEmpty()) {
1894         component->SetColumnHeight(height);
1895         component->SetDefaultHeight(true);
1896     }
1897     component->SetSelected(selectedValue);
1898     component->SetRange(getRangeVector);
1899 }
1900 } // namespace OHOS::Ace::Framework
1901