1 /*
2 * Copyright (c) 2021-2023 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_indexer.h"
17
18 #include "base/geometry/dimension.h"
19 #include "base/log/ace_scoring_log.h"
20 #include "base/utils/utils.h"
21 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
22 #include "bridge/declarative_frontend/jsview/js_scroller.h"
23 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
24 #include "bridge/declarative_frontend/jsview/models/indexer_model_impl.h"
25 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_indexer_theme.h"
26 #include "core/common/resource/resource_object.h"
27 #include "core/components/common/layout/constants.h"
28 #include "core/components/common/properties/decoration.h"
29 #include "core/components/common/properties/text_style.h"
30 #include "core/components/indexer/indexer_theme.h"
31 #include "core/components_ng/pattern/indexer/indexer_model_ng.h"
32
33 namespace OHOS::Ace {
34 std::unique_ptr<IndexerModel> IndexerModel::instance_ = nullptr;
35 std::mutex IndexerModel::mutex_;
GetInstance()36 IndexerModel* IndexerModel::GetInstance()
37 {
38 if (!instance_) {
39 std::lock_guard<std::mutex> lock(mutex_);
40 if (!instance_) {
41 #ifdef NG_BUILD
42 instance_.reset(new NG::IndexerModelNG());
43 #else
44 if (Container::IsCurrentUseNewPipeline()) {
45 instance_.reset(new NG::IndexerModelNG());
46 } else {
47 instance_.reset(new Framework::IndexerModelImpl());
48 }
49 #endif
50 }
51 }
52 return instance_.get();
53 }
54 } // namespace OHOS::Ace
55
56 namespace OHOS::Ace::Framework {
57 namespace {
58 const std::vector<FontStyle> FONT_STYLES = { FontStyle::NORMAL, FontStyle::ITALIC };
59 const std::vector<V2::AlignStyle> ALIGN_STYLE = { V2::AlignStyle::LEFT, V2::AlignStyle::RIGHT, V2::AlignStyle::START,
60 V2::AlignStyle::END };
61 const std::vector<NG::AlignStyle> NG_ALIGN_STYLE = { NG::AlignStyle::LEFT, NG::AlignStyle::RIGHT, NG::AlignStyle::START,
62 NG::AlignStyle::END };
63 constexpr Dimension DEFAULT_ITEM_SIZE = 16.0_vp;
64 constexpr double ZERO_RADIUS = 0.0;
65 constexpr double POPUP_ITEM_DEFAULT_RADIUS = 24.0;
66 constexpr double ITEM_DEFAULT_RADIUS = 8.0;
67 constexpr double RADIUS_OFFSET = 4.0;
68 }; // namespace
69
ParseIndexerSelectedObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal,bool isMethodProp=false)70 void JSIndexer::ParseIndexerSelectedObject(
71 const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal, bool isMethodProp = false)
72 {
73 CHECK_NULL_VOID(changeEventVal->IsFunction());
74 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
75 auto changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](const int32_t selected) {
76 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
77 ACE_SCORING_EVENT("Indexer.SelectedChangeEvent");
78 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(selected));
79 func->ExecuteJS(1, &newJSVal);
80 };
81
82 if (isMethodProp) {
83 IndexerModel::GetInstance()->SetChangeEvent(changeEvent);
84 } else {
85 IndexerModel::GetInstance()->SetCreatChangeEvent(changeEvent);
86 }
87 }
88
CreateArc(const JSCallbackInfo & args)89 void JSIndexer::CreateArc(const JSCallbackInfo& args)
90 {
91 Create(args, true);
92 }
93
Create(const JSCallbackInfo & args)94 void JSIndexer::Create(const JSCallbackInfo& args)
95 {
96 Create(args, false);
97 }
98
Create(const JSCallbackInfo & args,bool isArc)99 void JSIndexer::Create(const JSCallbackInfo& args, bool isArc)
100 {
101 if (args.Length() < 1 || !args[0]->IsObject()) {
102 return;
103 }
104 size_t length = 0;
105 int32_t selectedVal = 0;
106 std::vector<std::string> indexerArray;
107 JSRef<JSObject> paramObj = JSRef<JSObject>::Cast(args[0]);
108 JSRef<JSVal> arrayVal = paramObj->GetProperty("arrayValue");
109 if (arrayVal->IsArray()) {
110 JSRef<JSArray> jsArray = JSRef<JSArray>::Cast(arrayVal);
111 length = jsArray->Length();
112 for (size_t i = 0; i < length; i++) {
113 auto value = jsArray->GetValueAt(i);
114 if (value->IsString()) {
115 indexerArray.emplace_back(value->ToString());
116 }
117 }
118 }
119
120 JSRef<JSVal> selectedProperty = paramObj->GetProperty("selected");
121 if (selectedProperty->IsNumber()) {
122 selectedVal = selectedProperty->ToNumber<int32_t>();
123 IndexerModel::GetInstance()->Create(indexerArray, selectedVal, isArc);
124 JSIndexerTheme::ApplyTheme();
125 JSRef<JSVal> changeEventVal = paramObj->GetProperty("$selected");
126 ParseIndexerSelectedObject(args, changeEventVal);
127 } else if (!isArc && length > 0 && selectedProperty->IsObject()) {
128 JSRef<JSObject> selectedObj = JSRef<JSObject>::Cast(selectedProperty);
129 auto selectedValueProperty = selectedObj->GetProperty("value");
130 if (selectedValueProperty->IsNumber()) {
131 selectedVal = selectedValueProperty->ToNumber<int32_t>();
132 }
133 IndexerModel::GetInstance()->Create(indexerArray, selectedVal, isArc);
134 JSIndexerTheme::ApplyTheme();
135 JSRef<JSVal> changeEventVal = selectedObj->GetProperty("changeEvent");
136 if (!changeEventVal.IsEmpty()) {
137 if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
138 ParseIndexerSelectedObject(args, changeEventVal);
139 }
140 return;
141 }
142
143 args.ReturnSelf();
144 } else {
145 IndexerModel::GetInstance()->Create(indexerArray, selectedVal, isArc);
146 JSIndexerTheme::ApplyTheme();
147 }
148 }
149
SetSelectedColor(const JSCallbackInfo & args)150 void JSIndexer::SetSelectedColor(const JSCallbackInfo& args)
151 {
152 if (args.Length() < 1) {
153 return;
154 }
155 std::optional<Color> colorOpt;
156 Color selectedColor;
157 RefPtr<ResourceObject> resObj;
158 bool setByUser = false;
159 if (ParseJsColor(args[0], selectedColor, resObj)) {
160 colorOpt = selectedColor;
161 setByUser = true;
162 }
163 IndexerModel::GetInstance()->SetSelectedColor(colorOpt);
164 if (SystemProperties::ConfigChangePerform()) {
165 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::SELECTED_COLOR, resObj);
166 IndexerModel::GetInstance()->SetSelectedColorByUser(setByUser);
167 }
168 }
169
SetColor(const JSCallbackInfo & args)170 void JSIndexer::SetColor(const JSCallbackInfo& args)
171 {
172 if (args.Length() < 1) {
173 return;
174 }
175 std::optional<Color> colorOpt;
176 Color color;
177 RefPtr<ResourceObject> resObj;
178 bool setByUser = false;
179 if (ParseJsColor(args[0], color, resObj)) {
180 colorOpt = color;
181 setByUser = true;
182 }
183 IndexerModel::GetInstance()->SetColor(colorOpt);
184 if (SystemProperties::ConfigChangePerform()) {
185 IndexerModel::GetInstance()->SetColorByUser(setByUser);
186 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::COLOR, resObj);
187 }
188 }
189
SetPopupColor(const JSCallbackInfo & args)190 void JSIndexer::SetPopupColor(const JSCallbackInfo& args)
191 {
192 if (args.Length() < 1) {
193 return;
194 }
195 std::optional<Color> colorOpt;
196 Color popupColor;
197 RefPtr<ResourceObject> resObj;
198 bool setByUser = false;
199 if (ParseJsColor(args[0], popupColor, resObj)) {
200 colorOpt = popupColor;
201 setByUser = true;
202 }
203 IndexerModel::GetInstance()->SetPopupColor(colorOpt);
204 if (SystemProperties::ConfigChangePerform()) {
205 IndexerModel::GetInstance()->SetPopupColorByUser(setByUser);
206 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::POPUP_COLOR, resObj);
207 }
208 }
209
SetSelectedBackgroundColor(const JSCallbackInfo & args)210 void JSIndexer::SetSelectedBackgroundColor(const JSCallbackInfo& args)
211 {
212 if (args.Length() < 1) {
213 return;
214 }
215 std::optional<Color> colorOpt;
216 Color selectedBackgroundColor;
217 RefPtr<ResourceObject> resObj;
218 bool setByUser = false;
219 if (ParseJsColor(args[0], selectedBackgroundColor, resObj)) {
220 colorOpt = selectedBackgroundColor;
221 setByUser = true;
222 }
223 IndexerModel::GetInstance()->SetSelectedBackgroundColor(colorOpt);
224 if (SystemProperties::ConfigChangePerform()) {
225 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::SELECTED_BACKGROUND_COLOR, resObj);
226 IndexerModel::GetInstance()->SetSelectedBGColorByUser(setByUser);
227 }
228 }
229
SetPopupBackground(const JSCallbackInfo & args)230 void JSIndexer::SetPopupBackground(const JSCallbackInfo& args)
231 {
232 if (args.Length() < 1) {
233 return;
234 }
235 std::optional<Color> colorOpt;
236 Color popupBackground;
237 RefPtr<ResourceObject> resObj;
238 bool setByUser = false;
239 if (ParseJsColor(args[0], popupBackground, resObj)) {
240 colorOpt = popupBackground;
241 setByUser = true;
242 }
243 IndexerModel::GetInstance()->SetPopupBackground(colorOpt);
244 if (SystemProperties::ConfigChangePerform()) {
245 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::POPUP_BACKGROUND, resObj);
246 IndexerModel::GetInstance()->SetPopupBackgroundColorByUser(setByUser);
247 }
248 }
249
SetUsingPopup(bool state)250 void JSIndexer::SetUsingPopup(bool state)
251 {
252 IndexerModel::GetInstance()->SetUsingPopup(state);
253 }
254
SetSelectedFont(const JSCallbackInfo & args)255 void JSIndexer::SetSelectedFont(const JSCallbackInfo& args)
256 {
257 if (args.Length() < 1) {
258 return;
259 }
260 IndexerTextStyle textStyle;
261 if (args[0]->IsObject()) {
262 GetFontContent(args, textStyle);
263 }
264 IndexerModel::GetInstance()->SetSelectedFont(
265 textStyle.fontSize, textStyle.fontWeight, textStyle.fontFamily, textStyle.fontStyle);
266 if (SystemProperties::ConfigChangePerform()) {
267 IndexerModel::GetInstance()->CreateWithResourceObj(
268 IndexerJsResourceType::SELECTED_FONT_SIZE, textStyle.fontSizeResObj);
269 IndexerModel::GetInstance()->CreateWithResourceObj(
270 IndexerJsResourceType::SELECTED_FONT_FAMILY, textStyle.fontFamilyResObj);
271 }
272 }
273
SetPopupFont(const JSCallbackInfo & args)274 void JSIndexer::SetPopupFont(const JSCallbackInfo& args)
275 {
276 if (args.Length() < 1) {
277 return;
278 }
279 IndexerTextStyle textStyle;
280 if (args[0]->IsObject()) {
281 GetFontContent(args, textStyle);
282 }
283 IndexerModel::GetInstance()->SetPopupFont(
284 textStyle.fontSize, textStyle.fontWeight, textStyle.fontFamily, textStyle.fontStyle);
285 if (SystemProperties::ConfigChangePerform()) {
286 IndexerModel::GetInstance()->CreateWithResourceObj(
287 IndexerJsResourceType::POPUP_FONT_SIZE, textStyle.fontSizeResObj);
288 IndexerModel::GetInstance()->CreateWithResourceObj(
289 IndexerJsResourceType::POPUP_FONT_FAMILY, textStyle.fontFamilyResObj);
290 }
291 }
292
SetFont(const JSCallbackInfo & args)293 void JSIndexer::SetFont(const JSCallbackInfo& args)
294 {
295 if (args.Length() < 1) {
296 return;
297 }
298 IndexerTextStyle textStyle;
299 if (args[0]->IsObject()) {
300 GetFontContent(args, textStyle);
301 }
302 IndexerModel::GetInstance()->SetFont(
303 textStyle.fontSize, textStyle.fontWeight, textStyle.fontFamily, textStyle.fontStyle);
304 if (SystemProperties::ConfigChangePerform()) {
305 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::FONT_SIZE, textStyle.fontSizeResObj);
306 IndexerModel::GetInstance()->CreateWithResourceObj(
307 IndexerJsResourceType::FONT_FAMILY, textStyle.fontFamilyResObj);
308 }
309 }
310
JsOnSelected(const JSCallbackInfo & args)311 void JSIndexer::JsOnSelected(const JSCallbackInfo& args)
312 {
313 if (args[0]->IsFunction()) {
314 auto onSelected = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
315 const int32_t selected) {
316 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
317 auto params = ConvertToJSValues(selected);
318 func->Call(JSRef<JSObject>(), params.size(), params.data());
319 };
320 IndexerModel::GetInstance()->SetOnSelected(onSelected);
321 }
322 }
323
JsOnRequestPopupData(const JSCallbackInfo & args)324 void JSIndexer::JsOnRequestPopupData(const JSCallbackInfo& args)
325 {
326 if (args[0]->IsFunction()) {
327 auto requestPopupData = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
328 const int32_t selected) {
329 std::vector<std::string> popupData;
330 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx, popupData);
331 auto params = ConvertToJSValues(selected);
332 JSRef<JSArray> result = func->Call(JSRef<JSObject>(), params.size(), params.data());
333 if (result.IsEmpty()) {
334 return popupData;
335 }
336
337 if (!result->IsArray()) {
338 return popupData;
339 }
340
341 for (size_t i = 0; i < result->Length(); i++) {
342 if (result->GetValueAt(i)->IsString()) {
343 auto item = result->GetValueAt(i);
344 popupData.emplace_back(item->ToString());
345 }
346 }
347 return popupData;
348 };
349 IndexerModel::GetInstance()->SetOnRequestPopupData(requestPopupData);
350 }
351 }
352
JsOnPopupSelected(const JSCallbackInfo & args)353 void JSIndexer::JsOnPopupSelected(const JSCallbackInfo& args)
354 {
355 if (args[0]->IsFunction()) {
356 auto onPopupSelected = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
357 const int32_t selected) {
358 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
359 auto params = ConvertToJSValues(selected);
360 func->Call(JSRef<JSObject>(), params.size(), params.data());
361 };
362 IndexerModel::GetInstance()->SetOnPopupSelected(onPopupSelected);
363 }
364 }
365
GetFontContent(const JSCallbackInfo & args,IndexerTextStyle & textStyle)366 void JSIndexer::GetFontContent(const JSCallbackInfo& args, IndexerTextStyle& textStyle)
367 {
368 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
369 JSRef<JSVal> size = obj->GetProperty("size");
370 CalcDimension fontSizeData;
371 if (ParseJsDimensionFp(size, fontSizeData, textStyle.fontSizeResObj) && !fontSizeData.IsNegative() &&
372 fontSizeData.Unit() != DimensionUnit::PERCENT) {
373 textStyle.fontSize = fontSizeData;
374 }
375
376 JSRef<JSVal> weight = obj->GetProperty("weight");
377 if (weight->IsString() || weight->IsNumber()) {
378 textStyle.fontWeight = ConvertStrToFontWeight(weight->ToString());
379 }
380
381 JSRef<JSVal> family = obj->GetProperty("family");
382 std::vector<std::string> fontFamilies;
383 if (ParseJsFontFamilies(family, fontFamilies, textStyle.fontFamilyResObj)) {
384 textStyle.fontFamily = fontFamilies;
385 }
386
387 JSRef<JSVal> style = obj->GetProperty("style");
388 if (style->IsNumber()) {
389 int32_t value = style->ToNumber<int32_t>();
390 if (value >= 0 && value < static_cast<int32_t>(FONT_STYLES.size())) {
391 textStyle.fontStyle = FONT_STYLES[value];
392 }
393 }
394 }
395
SetItemSize(const JSCallbackInfo & args)396 void JSIndexer::SetItemSize(const JSCallbackInfo& args)
397 {
398 if (args.Length() < 1) {
399 return;
400 }
401 CalcDimension itemSize;
402 if (ParseJsDimensionVp(args[0], itemSize) && GreatNotEqual(itemSize.Value(), 0.0) &&
403 itemSize.Unit() != DimensionUnit::PERCENT) {
404 IndexerModel::GetInstance()->SetItemSize(itemSize);
405 return;
406 }
407 IndexerModel::GetInstance()->SetItemSize(DEFAULT_ITEM_SIZE);
408 }
409
SetAlignStyle(const JSCallbackInfo & args)410 void JSIndexer::SetAlignStyle(const JSCallbackInfo& args)
411 {
412 if (args.Length() < 1) {
413 return;
414 }
415 int32_t value = Container::IsCurrentUseNewPipeline() ? static_cast<int32_t>(NG::AlignStyle::END)
416 : static_cast<int32_t>(V2::AlignStyle::END);
417 auto alignValue = -1;
418 if (args[0]->IsNumber()) {
419 alignValue = args[0]->ToNumber<int32_t>();
420 }
421 if (alignValue >= 0 && alignValue < static_cast<int32_t>(ALIGN_STYLE.size())) {
422 value = alignValue;
423 }
424 IndexerModel::GetInstance()->SetAlignStyle(value);
425 CalcDimension popupHorizontalSpace(-1.0);
426 RefPtr<ResourceObject> resObj;
427 if (args.Length() > 1) {
428 ParseJsDimensionVp(args[1], popupHorizontalSpace, resObj);
429 }
430 if (SystemProperties::ConfigChangePerform()) {
431 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::ALIGN_OFFSET, resObj);
432 }
433 IndexerModel::GetInstance()->SetPopupHorizontalSpace(popupHorizontalSpace);
434 }
435
SetSelected(const JSCallbackInfo & args)436 void JSIndexer::SetSelected(const JSCallbackInfo& args)
437 {
438 if (args.Length() < 1) {
439 return;
440 }
441 int32_t selected = 0;
442 auto selectedVal = args[0];
443 JSRef<JSVal> changeEventVal;
444 if (selectedVal->IsObject()) {
445 JSRef<JSObject> obj = JSRef<JSObject>::Cast(selectedVal);
446 selectedVal = obj->GetProperty("value");
447 changeEventVal = obj->GetProperty("$value");
448 } else if (args.Length() > 1) {
449 changeEventVal = args[1];
450 }
451 if (ParseJsInteger<int32_t>(selectedVal, selected)) {
452 IndexerModel::GetInstance()->SetSelected(selected);
453 }
454 ParseIndexerSelectedObject(args, changeEventVal, true);
455 }
456
SetPopupPosition(const JSCallbackInfo & args)457 void JSIndexer::SetPopupPosition(const JSCallbackInfo& args)
458 {
459 std::optional<Dimension> xOpt;
460 std::optional<Dimension> yOpt;
461 if (args[0]->IsObject()) {
462 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
463 CalcDimension x;
464 CalcDimension y;
465 RefPtr<ResourceObject> resObjX;
466 RefPtr<ResourceObject> resObjY;
467 JSRef<JSVal> xVal = obj->GetProperty("x");
468 JSRef<JSVal> yVal = obj->GetProperty("y");
469 if ((xVal->IsString() && StringUtils::StringToCalcDimensionNG(xVal->ToString(), x, false)) ||
470 (!xVal->IsString() && JSViewAbstract::ParseJsDimensionVp(xVal, x, resObjX))) {
471 xOpt = x;
472 }
473 if ((yVal->IsString() && StringUtils::StringToCalcDimensionNG(yVal->ToString(), y, false)) ||
474 (!yVal->IsString() && JSViewAbstract::ParseJsDimensionVp(yVal, y, resObjY))) {
475 yOpt = y;
476 }
477 if (SystemProperties::ConfigChangePerform()) {
478 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::POPUP_POSITION_X, resObjX);
479 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::POPUP_POSITION_Y, resObjY);
480 }
481 } else if (Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
482 return;
483 }
484 IndexerModel::GetInstance()->SetPopupPositionX(xOpt);
485 IndexerModel::GetInstance()->SetPopupPositionY(yOpt);
486 }
487
SetPopupSelectedColor(const JSCallbackInfo & args)488 void JSIndexer::SetPopupSelectedColor(const JSCallbackInfo& args)
489 {
490 if (args.Length() < 1) {
491 return;
492 }
493 std::optional<Color> colorOpt;
494 Color popupSelectedColor;
495 RefPtr<ResourceObject> resObj;
496 bool setByUser = false;
497 if (ParseJsColor(args[0], popupSelectedColor, resObj)) {
498 colorOpt = popupSelectedColor;
499 setByUser = true;
500 }
501 IndexerModel::GetInstance()->SetPopupSelectedColor(colorOpt);
502 if (SystemProperties::ConfigChangePerform()) {
503 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::POPUP_SELECTED_COLOR, resObj);
504 IndexerModel::GetInstance()->SetPopupSelectedColorByUser(setByUser);
505 }
506 }
507
SetPopupUnselectedColor(const JSCallbackInfo & args)508 void JSIndexer::SetPopupUnselectedColor(const JSCallbackInfo& args)
509 {
510 if (args.Length() < 1) {
511 return;
512 }
513 std::optional<Color> colorOpt;
514 Color popupUnselectedColor;
515 RefPtr<ResourceObject> resObj;
516 bool setByUser = false;
517 if (ParseJsColor(args[0], popupUnselectedColor, resObj)) {
518 colorOpt = popupUnselectedColor;
519 setByUser = true;
520 }
521 IndexerModel::GetInstance()->SetPopupUnselectedColor(colorOpt);
522 if (SystemProperties::ConfigChangePerform()) {
523 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::POPUP_UNSELECTED_COLOR, resObj);
524 IndexerModel::GetInstance()->SetPopupUnselectedColorByUser(setByUser);
525 }
526 }
527
SetPopupItemFont(const JSCallbackInfo & args)528 void JSIndexer::SetPopupItemFont(const JSCallbackInfo& args)
529 {
530 CalcDimension fontSize;
531 std::string weight;
532 RefPtr<ResourceObject> resObj;
533 if (args[0]->IsObject()) {
534 JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
535 JSRef<JSVal> size = obj->GetProperty("size");
536 if (!size->IsNull()) {
537 CalcDimension fontSizeData;
538 if (ParseJsDimensionFp(size, fontSizeData, resObj) && !fontSizeData.IsNegative() &&
539 fontSizeData.Unit() != DimensionUnit::PERCENT) {
540 fontSize = fontSizeData;
541 }
542 }
543
544 auto jsWeight = obj->GetProperty("weight");
545 if (!jsWeight->IsNull()) {
546 if (jsWeight->IsNumber()) {
547 weight = std::to_string(jsWeight->ToNumber<int32_t>());
548 } else {
549 ParseJsString(jsWeight, weight);
550 }
551 }
552 }
553 IndexerModel::GetInstance()->SetFontSize(fontSize);
554 IndexerModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(weight, FontWeight::MEDIUM));
555 if (SystemProperties::ConfigChangePerform()) {
556 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::POPUP_ITEM_FONT_SIZE, resObj);
557 }
558 }
559
SetPopupItemBackgroundColor(const JSCallbackInfo & args)560 void JSIndexer::SetPopupItemBackgroundColor(const JSCallbackInfo& args)
561 {
562 if (args.Length() < 1) {
563 return;
564 }
565 std::optional<Color> colorOpt;
566 Color popupItemBackgroundColor;
567 RefPtr<ResourceObject> resObj;
568 bool setByUser = false;
569 if (ParseJsColor(args[0], popupItemBackgroundColor, resObj)) {
570 colorOpt = popupItemBackgroundColor;
571 setByUser = true;
572 }
573 IndexerModel::GetInstance()->SetPopupItemBackground(colorOpt);
574 if (SystemProperties::ConfigChangePerform()) {
575 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::POPUP_ITEM_BACKGROUND_COLOR, resObj);
576 IndexerModel::GetInstance()->SetPopupItemBackgroundColorByUser(setByUser);
577 }
578 }
579
PaseColor(const JSCallbackInfo & args)580 std::optional<Color> JSIndexer::PaseColor(const JSCallbackInfo& args)
581 {
582 std::optional<Color> colorOpt;
583 Color color;
584 if (ParseJsColor(args[0], color)) {
585 colorOpt = color;
586 }
587 return colorOpt;
588 }
589
SetAutoCollapse(const JSCallbackInfo & args)590 void JSIndexer::SetAutoCollapse(const JSCallbackInfo& args)
591 {
592 bool state = true;
593 if (args[0]->IsBoolean()) {
594 state = args[0]->ToBoolean();
595 }
596 IndexerModel::GetInstance()->SetAutoCollapse(state);
597 }
598
SetPopupItemBorderRadius(const JSCallbackInfo & args)599 void JSIndexer::SetPopupItemBorderRadius(const JSCallbackInfo& args)
600 {
601 auto radius = Dimension(ZERO_RADIUS, DimensionUnit::VP);
602 auto popupRadius = Dimension(ZERO_RADIUS, DimensionUnit::VP);
603 if (args.Length() > 0 && args[0]->IsNumber()) {
604 auto radiusValue = args[0]->ToNumber<double>();
605 if (radiusValue >= 0) {
606 radius.SetValue(radiusValue);
607 radius.SetUnit(DimensionUnit::VP);
608 popupRadius.SetValue(radiusValue + RADIUS_OFFSET);
609 popupRadius.SetUnit(DimensionUnit::VP);
610 }
611 } else {
612 radius.SetValue(POPUP_ITEM_DEFAULT_RADIUS);
613 radius.SetUnit(DimensionUnit::VP);
614 popupRadius.SetValue(radius.Value() + RADIUS_OFFSET);
615 popupRadius.SetUnit(DimensionUnit::VP);
616 }
617 IndexerModel::GetInstance()->SetPopupItemBorderRadius(radius);
618 IndexerModel::GetInstance()->SetPopupBorderRadius(popupRadius);
619 }
620
SetItemBorderRadius(const JSCallbackInfo & args)621 void JSIndexer::SetItemBorderRadius(const JSCallbackInfo& args)
622 {
623 auto radius = Dimension(ZERO_RADIUS, DimensionUnit::VP);
624 auto indexerRadius = Dimension(ZERO_RADIUS, DimensionUnit::VP);
625 if (args.Length() > 0 && args[0]->IsNumber()) {
626 auto radiusValue = args[0]->ToNumber<double>();
627 if (radiusValue >= 0) {
628 radius.SetValue(radiusValue);
629 radius.SetUnit(DimensionUnit::VP);
630 indexerRadius.SetValue(radiusValue + RADIUS_OFFSET);
631 indexerRadius.SetUnit(DimensionUnit::VP);
632 }
633 } else {
634 radius.SetValue(ITEM_DEFAULT_RADIUS);
635 radius.SetUnit(DimensionUnit::VP);
636 indexerRadius.SetValue(radius.Value() + RADIUS_OFFSET);
637 indexerRadius.SetUnit(DimensionUnit::VP);
638 }
639 IndexerModel::GetInstance()->SetItemBorderRadius(radius);
640 IndexerModel::GetInstance()->SetIndexerBorderRadius(indexerRadius);
641 }
642
SetPopupBackgroundBlurStyle(const JSCallbackInfo & args)643 void JSIndexer::SetPopupBackgroundBlurStyle(const JSCallbackInfo& args)
644 {
645 if (args.Length() < 1) {
646 return;
647 }
648
649 BlurStyleOption styleOption;
650 if (args[0]->IsNumber()) {
651 auto blurStyle = args[0]->ToNumber<int32_t>();
652 if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
653 blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
654 styleOption.blurStyle = static_cast<BlurStyle>(blurStyle);
655 } else {
656 styleOption.blurStyle = BlurStyle::COMPONENT_REGULAR;
657 }
658 } else {
659 styleOption.blurStyle = BlurStyle::COMPONENT_REGULAR;
660 }
661 IndexerModel::GetInstance()->SetPopupBackgroundBlurStyle(styleOption);
662 }
663
SetPopupTitleBackground(const JSCallbackInfo & args)664 void JSIndexer::SetPopupTitleBackground(const JSCallbackInfo& args)
665 {
666 if (args.Length() < 1) {
667 return;
668 }
669 std::optional<Color> colorOpt;
670 Color popupTitleBackground;
671 RefPtr<ResourceObject> resObj;
672 bool setByUser = false;
673 if (ParseJsColor(args[0], popupTitleBackground, resObj)) {
674 colorOpt = popupTitleBackground;
675 setByUser = true;
676 }
677 IndexerModel::GetInstance()->SetPopupTitleBackground(colorOpt);
678 if (SystemProperties::ConfigChangePerform()) {
679 IndexerModel::GetInstance()->CreateWithResourceObj(IndexerJsResourceType::POPUP_TITLE_BACKGROUND, resObj);
680 IndexerModel::GetInstance()->SetPopupTitleBackgroundByUser(setByUser);
681 }
682 }
683
SetWidth(const JSCallbackInfo & args)684 void JSIndexer::SetWidth(const JSCallbackInfo& args)
685 {
686 JSViewAbstract::JsWidth(args);
687 if (args[0]->IsString() && args[0]->ToString() == "auto") {
688 IndexerModel::GetInstance()->SetAdaptiveWidth(true);
689 } else {
690 IndexerModel::GetInstance()->SetAdaptiveWidth(false);
691 }
692 }
693
SetEnableHapticFeedback(const JSCallbackInfo & args)694 void JSIndexer::SetEnableHapticFeedback(const JSCallbackInfo& args)
695 {
696 bool state = true;
697 if (args.Length() > 0 && args[0]->IsBoolean()) {
698 state = args[0]->ToBoolean();
699 }
700 IndexerModel::GetInstance()->SetEnableHapticFeedback(state);
701 }
702
JSBind(BindingTarget globalObj)703 void JSIndexer::JSBind(BindingTarget globalObj)
704 {
705 MethodOptions opt = MethodOptions::NONE;
706 JSClass<JSIndexer>::Declare("AlphabetIndexer");
707 JSClass<JSIndexer>::StaticMethod("create", &JSIndexer::Create);
708 JSClass<JSIndexer>::StaticMethod("createArc", &JSIndexer::CreateArc);
709 // API7 onSelected deprecated
710 JSClass<JSIndexer>::StaticMethod("onSelected", &JSIndexer::JsOnSelected);
711 JSClass<JSIndexer>::StaticMethod("onSelect", &JSIndexer::JsOnSelected);
712 JSClass<JSIndexer>::StaticMethod("color", &JSIndexer::SetColor, opt);
713 JSClass<JSIndexer>::StaticMethod("selectedColor", &JSIndexer::SetSelectedColor, opt);
714 JSClass<JSIndexer>::StaticMethod("popupColor", &JSIndexer::SetPopupColor, opt);
715 JSClass<JSIndexer>::StaticMethod("selectedBackgroundColor", &JSIndexer::SetSelectedBackgroundColor, opt);
716 JSClass<JSIndexer>::StaticMethod("popupBackground", &JSIndexer::SetPopupBackground, opt);
717 JSClass<JSIndexer>::StaticMethod("usingPopup", &JSIndexer::SetUsingPopup, opt);
718 JSClass<JSIndexer>::StaticMethod("selectedFont", &JSIndexer::SetSelectedFont);
719 JSClass<JSIndexer>::StaticMethod("font", &JSIndexer::SetFont);
720 JSClass<JSIndexer>::StaticMethod("popupFont", &JSIndexer::SetPopupFont);
721 JSClass<JSIndexer>::StaticMethod("itemSize", &JSIndexer::SetItemSize, opt);
722 JSClass<JSIndexer>::StaticMethod("alignStyle", &JSIndexer::SetAlignStyle, opt);
723 JSClass<JSIndexer>::StaticMethod("onRequestPopupData", &JSIndexer::JsOnRequestPopupData, opt);
724 JSClass<JSIndexer>::StaticMethod("selected", &JSIndexer::SetSelected, opt);
725 JSClass<JSIndexer>::StaticMethod("popupPosition", &JSIndexer::SetPopupPosition, opt);
726 JSClass<JSIndexer>::StaticMethod("popupSelectedColor", &JSIndexer::SetPopupSelectedColor, opt);
727 JSClass<JSIndexer>::StaticMethod("popupUnselectedColor", &JSIndexer::SetPopupUnselectedColor, opt);
728 JSClass<JSIndexer>::StaticMethod("popupItemFont", &JSIndexer::SetPopupItemFont);
729 JSClass<JSIndexer>::StaticMethod("popupItemBackgroundColor", &JSIndexer::SetPopupItemBackgroundColor, opt);
730 JSClass<JSIndexer>::StaticMethod("autoCollapse", &JSIndexer::SetAutoCollapse, opt);
731 JSClass<JSIndexer>::StaticMethod("popupItemBorderRadius", &JSIndexer::SetPopupItemBorderRadius);
732 JSClass<JSIndexer>::StaticMethod("itemBorderRadius", &JSIndexer::SetItemBorderRadius);
733 JSClass<JSIndexer>::StaticMethod("popupBackgroundBlurStyle", &JSIndexer::SetPopupBackgroundBlurStyle);
734 JSClass<JSIndexer>::StaticMethod("popupTitleBackground", &JSIndexer::SetPopupTitleBackground, opt);
735 JSClass<JSIndexer>::StaticMethod("width", &JSIndexer::SetWidth);
736 JSClass<JSIndexer>::StaticMethod("enableHapticFeedback", &JSIndexer::SetEnableHapticFeedback, opt);
737 // keep compatible, need remove after
738 JSClass<JSIndexer>::StaticMethod("onPopupSelect", &JSIndexer::JsOnPopupSelected, opt);
739 JSClass<JSIndexer>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
740 JSClass<JSIndexer>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
741 JSClass<JSIndexer>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
742 JSClass<JSIndexer>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
743 JSClass<JSIndexer>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
744 JSClass<JSIndexer>::InheritAndBind<JSViewAbstract>(globalObj);
745 }
746 } // namespace OHOS::Ace::Framework
747