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 "frameworks/bridge/declarative_frontend/jsview/js_slider.h"
17 
18 #include "bridge/declarative_frontend/jsview/js_linear_gradient.h"
19 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
20 #include "bridge/declarative_frontend/jsview/models/slider_model_impl.h"
21 #include "bridge/declarative_frontend/ark_theme/theme_apply/js_slider_theme.h"
22 #include "core/components/slider/render_slider.h"
23 #include "core/components/slider/slider_element.h"
24 #include "core/components_ng/pattern/slider/slider_model_ng.h"
25 #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
26 #include "frameworks/bridge/declarative_frontend/jsview/js_shape_abstract.h"
27 
28 namespace OHOS::Ace {
29 namespace {
30 constexpr int SLIDER_SHOW_TIPS_MAX_PARAMS = 2;
31 } // namespace
32 
33 std::unique_ptr<SliderModel> SliderModel::instance_ = nullptr;
34 std::mutex SliderModel::mutex_;
35 
GetInstance()36 SliderModel* SliderModel::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::SliderModelNG());
43 #else
44             if (Container::IsCurrentUseNewPipeline()) {
45                 instance_.reset(new NG::SliderModelNG());
46             } else {
47                 instance_.reset(new Framework::SliderModelImpl());
48             }
49 #endif
50         }
51     }
52     return instance_.get();
53 }
54 
55 } // namespace OHOS::Ace
56 
57 namespace OHOS::Ace::Framework {
58 
JSBind(BindingTarget globalObj)59 void JSSlider::JSBind(BindingTarget globalObj)
60 {
61     JSClass<JSSlider>::Declare("Slider");
62     MethodOptions opt = MethodOptions::NONE;
63     JSClass<JSSlider>::StaticMethod("create", &JSSlider::Create, opt);
64     JSClass<JSSlider>::StaticMethod("blockColor", &JSSlider::SetBlockColor);
65     JSClass<JSSlider>::StaticMethod("trackColor", &JSSlider::SetTrackColor);
66     JSClass<JSSlider>::StaticMethod("trackThickness", &JSSlider::SetThickness);
67     JSClass<JSSlider>::StaticMethod("selectedColor", &JSSlider::SetSelectedColor);
68     JSClass<JSSlider>::StaticMethod("minLabel", &JSSlider::SetMinLabel);
69     JSClass<JSSlider>::StaticMethod("maxLabel", &JSSlider::SetMaxLabel);
70     JSClass<JSSlider>::StaticMethod("minResponsiveDistance", &JSSlider::SetMinResponsiveDistance);
71     JSClass<JSSlider>::StaticMethod("showSteps", &JSSlider::SetShowSteps);
72     JSClass<JSSlider>::StaticMethod("showTips", &JSSlider::SetShowTips);
73     JSClass<JSSlider>::StaticMethod("blockBorderColor", &JSSlider::SetBlockBorderColor);
74     JSClass<JSSlider>::StaticMethod("blockBorderWidth", &JSSlider::SetBlockBorderWidth);
75     JSClass<JSSlider>::StaticMethod("stepColor", &JSSlider::SetStepColor);
76     JSClass<JSSlider>::StaticMethod("trackBorderRadius", &JSSlider::SetTrackBorderRadius);
77     JSClass<JSSlider>::StaticMethod("selectedBorderRadius", &JSSlider::SetSelectedBorderRadius);
78     JSClass<JSSlider>::StaticMethod("blockSize", &JSSlider::SetBlockSize);
79     JSClass<JSSlider>::StaticMethod("blockStyle", &JSSlider::SetBlockStyle);
80     JSClass<JSSlider>::StaticMethod("stepSize", &JSSlider::SetStepSize);
81     JSClass<JSSlider>::StaticMethod("sliderInteractionMode", &JSSlider::SetSliderInteractionMode);
82     JSClass<JSSlider>::StaticMethod("slideRange", &JSSlider::SetValidSlideRange);
83     JSClass<JSSlider>::StaticMethod("onChange", &JSSlider::OnChange);
84     JSClass<JSSlider>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
85     JSClass<JSSlider>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
86     JSClass<JSSlider>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
87     JSClass<JSSlider>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
88     JSClass<JSSlider>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
89     JSClass<JSSlider>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
90     JSClass<JSSlider>::InheritAndBind<JSViewAbstract>(globalObj);
91 }
92 
GetStep(double step,double max,double min)93 double GetStep(double step, double max, double min)
94 {
95     if (LessOrEqual(step, 0.0) || step > max - min) {
96         step = 1;
97     }
98     return step;
99 }
100 
GetValue(double value,double max,double min)101 double GetValue(double value, double max, double min)
102 {
103     if (value < min) {
104         value = min;
105     }
106 
107     if (value > max) {
108         value = max;
109     }
110     return value;
111 }
112 
ParseSliderValueObject(const JSCallbackInfo & info,const JSRef<JSVal> & changeEventVal)113 void ParseSliderValueObject(const JSCallbackInfo& info, const JSRef<JSVal>& changeEventVal)
114 {
115     CHECK_NULL_VOID(changeEventVal->IsFunction());
116 
117     JsEventCallback<void(float)> onChangeEvent(info.GetExecutionContext(), JSRef<JSFunc>::Cast(changeEventVal));
118     SliderModel::GetInstance()->SetOnChangeEvent(std::move(onChangeEvent));
119 }
120 
Create(const JSCallbackInfo & info)121 void JSSlider::Create(const JSCallbackInfo& info)
122 {
123     static const double valueMin = -1000000.0f;
124     double value = valueMin; // value:Current progress value. The default value is min.
125     double min = 0;   // min:Set the minimum value. The default value is 0.
126     double max = 100; // max:Set the maximum value. The default value is 100.
127     double step = 1;  // step:Sets the sliding jump value of the slider. The default value is 1.
128     bool reverse = false;
129 
130     if (!info[0]->IsObject()) {
131         SliderModel::GetInstance()->Create(
132             static_cast<float>(value), static_cast<float>(step), static_cast<float>(min), static_cast<float>(max));
133         JSSliderTheme::ApplyTheme();
134         return;
135     }
136 
137     auto paramObject = JSRef<JSObject>::Cast(info[0]);
138     auto getValue = paramObject->GetProperty("value");
139     auto getMin = paramObject->GetProperty("min");
140     auto getMax = paramObject->GetProperty("max");
141     auto getStep = paramObject->GetProperty("step");
142     auto getStyle = paramObject->GetProperty("style");
143     auto direction = paramObject->GetProperty("direction");
144     auto isReverse = paramObject->GetProperty("reverse");
145     JSRef<JSVal> changeEventVal;
146 
147     if (!getValue->IsNull() && getValue->IsNumber()) {
148         value = getValue->ToNumber<double>();
149     } else if (!getValue->IsNull() && getValue->IsObject()) {
150         JSRef<JSObject> valueObj = JSRef<JSObject>::Cast(getValue);
151         changeEventVal = valueObj->GetProperty("changeEvent");
152         auto valueProperty = valueObj->GetProperty("value");
153         value = valueProperty->ToNumber<double>();
154     }
155 
156     if (!getMin->IsNull() && getMin->IsNumber()) {
157         min = getMin->ToNumber<double>();
158     }
159 
160     if (!getMax->IsNull() && getMax->IsNumber()) {
161         max = getMax->ToNumber<double>();
162     }
163 
164     if (!getStep->IsNull() && getStep->IsNumber()) {
165         step = getStep->ToNumber<double>();
166     }
167 
168     if (!isReverse->IsNull() && isReverse->IsBoolean()) {
169         reverse = isReverse->ToBoolean();
170     }
171 
172     if (GreatOrEqual(min, max)) {
173         min = 0;
174         max = 100;
175     }
176 
177     step = GetStep(step, max, min);
178 
179     if (!Container::IsCurrentUseNewPipeline()) {
180         value = GetValue(value, max, min);
181     }
182 
183     auto sliderStyle = SliderStyle::OUTSET;
184     auto sliderMode = SliderModel::SliderMode::OUTSET;
185     if (!getStyle->IsNull() && getStyle->IsNumber()) {
186         sliderStyle = static_cast<SliderStyle>(getStyle->ToNumber<int32_t>());
187     }
188     if (sliderStyle == SliderStyle::INSET) {
189         sliderMode = SliderModel::SliderMode::INSET;
190     } else if (sliderStyle == SliderStyle::CAPSULE) {
191         sliderMode = SliderModel::SliderMode::CAPSULE;
192     } else if (sliderStyle == SliderStyle::NONE) {
193         sliderMode = SliderModel::SliderMode::NONE;
194     } else {
195         sliderMode = SliderModel::SliderMode::OUTSET;
196     }
197 
198     auto sliderDirection = Axis::HORIZONTAL;
199     if (!direction->IsNull() && direction->IsNumber()) {
200         sliderDirection = static_cast<Axis>(direction->ToNumber<int32_t>());
201     }
202     if (sliderDirection != Axis::VERTICAL) {
203         sliderDirection = Axis::HORIZONTAL;
204     }
205 
206     SliderModel::GetInstance()->Create(
207         static_cast<float>(value), static_cast<float>(step), static_cast<float>(min), static_cast<float>(max));
208     SliderModel::GetInstance()->SetSliderMode(sliderMode);
209     SliderModel::GetInstance()->SetDirection(sliderDirection);
210     SliderModel::GetInstance()->SetReverse(reverse);
211     if (!changeEventVal->IsUndefined() && changeEventVal->IsFunction()) {
212         ParseSliderValueObject(info, changeEventVal);
213     }
214     JSSliderTheme::ApplyTheme();
215 }
216 
SetThickness(const JSCallbackInfo & info)217 void JSSlider::SetThickness(const JSCallbackInfo& info)
218 {
219     if (info.Length() < 1) {
220         return;
221     }
222     CalcDimension value;
223     if (!ParseJsDimensionVp(info[0], value)) {
224         value = CalcDimension(0.0);
225     }
226     SliderModel::GetInstance()->SetThickness(value);
227 }
228 
SetBlockColor(const JSCallbackInfo & info)229 void JSSlider::SetBlockColor(const JSCallbackInfo& info)
230 {
231     if (info.Length() < 1) {
232         return;
233     }
234     Color colorVal;
235     if (!ParseJsColor(info[0], colorVal)) {
236         auto theme = GetTheme<SliderTheme>();
237         CHECK_NULL_VOID(theme);
238         colorVal = theme->GetBlockColor();
239     }
240     SliderModel::GetInstance()->SetBlockColor(colorVal);
241 }
242 
SetTrackColor(const JSCallbackInfo & info)243 void JSSlider::SetTrackColor(const JSCallbackInfo& info)
244 {
245     if (info.Length() < 1) {
246         return;
247     }
248     NG::Gradient gradient;
249     bool isResourceColor = false;
250     if (!ConvertGradientColor(info[0], gradient)) {
251         Color colorVal;
252         if (info[0]->IsNull() || info[0]->IsUndefined() || !ParseJsColor(info[0], colorVal)) {
253             auto theme = GetTheme<SliderTheme>();
254             CHECK_NULL_VOID(theme);
255             colorVal = theme->GetTrackBgColor();
256         }
257         isResourceColor = true;
258         gradient = NG::SliderModelNG::CreateSolidGradient(colorVal);
259         // Set track color to Framework::SliderModelImpl. Need to backward compatibility with old pipeline.
260         SliderModel::GetInstance()->SetTrackBackgroundColor(colorVal);
261     }
262     // Set track gradient color to NG::SliderModelNG
263     SliderModel::GetInstance()->SetTrackBackgroundColor(gradient, isResourceColor);
264 }
265 
ConvertGradientColor(const JsiRef<JsiValue> & param,NG::Gradient & gradient)266 bool JSSlider::ConvertGradientColor(const JsiRef<JsiValue>& param, NG::Gradient& gradient)
267 {
268     if (param->IsNull() || param->IsUndefined() || !param->IsObject()) {
269         return false;
270     }
271 
272     JSLinearGradient* jsLinearGradient = JSRef<JSObject>::Cast(param)->Unwrap<JSLinearGradient>();
273     if (!jsLinearGradient || jsLinearGradient->GetGradient().empty()) {
274         return false;
275     }
276 
277     size_t size = jsLinearGradient->GetGradient().size();
278     if (size == 1) {
279         // If there is only one color, then this color is used for both the begin and end side.
280         NG::GradientColor gradientColor;
281         gradientColor.SetLinearColor(LinearColor(jsLinearGradient->GetGradient().front().first));
282         gradientColor.SetDimension(jsLinearGradient->GetGradient().front().second);
283         gradient.AddColor(gradientColor);
284         gradient.AddColor(gradientColor);
285         return true;
286     }
287 
288     for (size_t colorIndex = 0; colorIndex < size; colorIndex++) {
289         NG::GradientColor gradientColor;
290         gradientColor.SetLinearColor(LinearColor(jsLinearGradient->GetGradient().at(colorIndex).first));
291         gradientColor.SetDimension(jsLinearGradient->GetGradient().at(colorIndex).second);
292         gradient.AddColor(gradientColor);
293     }
294     return true;
295 }
296 
SetSelectedColor(const JSCallbackInfo & info)297 void JSSlider::SetSelectedColor(const JSCallbackInfo& info)
298 {
299     if (info.Length() < 1) {
300         return;
301     }
302     Color colorVal;
303     if (!ParseJsColor(info[0], colorVal)) {
304         auto theme = GetTheme<SliderTheme>();
305         CHECK_NULL_VOID(theme);
306         colorVal = theme->GetTrackSelectedColor();
307     }
308     SliderModel::GetInstance()->SetSelectColor(colorVal);
309 }
310 
SetMinLabel(const JSCallbackInfo & info)311 void JSSlider::SetMinLabel(const JSCallbackInfo& info)
312 {
313     if (!info[0]->IsString() && !info[0]->IsNumber()) {
314         return;
315     }
316     SliderModel::GetInstance()->SetMinLabel(info[0]->ToNumber<float>());
317 }
318 
SetMaxLabel(const JSCallbackInfo & info)319 void JSSlider::SetMaxLabel(const JSCallbackInfo& info)
320 {
321     if (!info[0]->IsString() && !info[0]->IsNumber()) {
322         return;
323     }
324     SliderModel::GetInstance()->SetMaxLabel(info[0]->ToNumber<float>());
325 }
326 
SetValidSlideRange(const JSCallbackInfo & info)327 void JSSlider::SetValidSlideRange(const JSCallbackInfo& info)
328 {
329     if (!info[0]->IsObject()) {
330         SliderModel::GetInstance()->ResetValidSlideRange();
331         return;
332     }
333 
334     auto paramObject = JSRef<JSObject>::Cast(info[0]);
335     auto getValueRangeFrom = paramObject->GetProperty("from");
336     auto getValueRangeTo = paramObject->GetProperty("to");
337     float rangeFromValue = std::numeric_limits<float>::quiet_NaN();
338     float rangeToValue = std::numeric_limits<float>::quiet_NaN();
339     if (getValueRangeFrom->IsEmpty()) {
340         rangeFromValue = std::numeric_limits<float>::infinity();
341     } else if (getValueRangeFrom->IsNumber()) {
342         rangeFromValue = getValueRangeFrom->ToNumber<double>();
343     }
344     if (getValueRangeTo->IsEmpty()) {
345         rangeToValue = std::numeric_limits<float>::infinity();
346     } else if (getValueRangeTo->IsNumber()) {
347         rangeToValue = getValueRangeTo->ToNumber<double>();
348     }
349 
350     if (std::isnan(rangeFromValue) || std::isnan(rangeToValue) ||
351         (std::isinf(rangeFromValue) && std::isinf(rangeToValue))) {
352         SliderModel::GetInstance()->ResetValidSlideRange();
353         return;
354     }
355     SliderModel::GetInstance()->SetValidSlideRange(rangeFromValue, rangeToValue);
356 }
357 
SetMinResponsiveDistance(const JSCallbackInfo & info)358 void JSSlider::SetMinResponsiveDistance(const JSCallbackInfo& info)
359 {
360     if (info.Length() < 1) {
361         SliderModel::GetInstance()->ResetMinResponsiveDistance();
362         return;
363     }
364     float value = 0.0f;
365     if (info[0]->IsString() || info[0]->IsNumber()) {
366         value = info[0]->ToNumber<float>();
367         value = std::isfinite(value) ? value : 0.0f;
368         SliderModel::GetInstance()->SetMinResponsiveDistance(value);
369     } else {
370         SliderModel::GetInstance()->ResetMinResponsiveDistance();
371     }
372 }
373 
SetShowSteps(const JSCallbackInfo & info)374 void JSSlider::SetShowSteps(const JSCallbackInfo& info)
375 {
376     if (info.Length() < 1) {
377         return;
378     }
379     bool showSteps = false;
380     if (info[0]->IsBoolean()) {
381         showSteps = info[0]->ToBoolean();
382     }
383     SliderModel::GetInstance()->SetShowSteps(showSteps);
384 }
385 
SetSliderInteractionMode(const JSCallbackInfo & info)386 void JSSlider::SetSliderInteractionMode(const JSCallbackInfo& info)
387 {
388     if (info.Length() < 1) {
389         SliderModel::GetInstance()->ResetSliderInteractionMode();
390         return;
391     }
392 
393     if (!info[0]->IsNull() && info[0]->IsNumber()) {
394         auto mode = static_cast<SliderModel::SliderInteraction>(info[0]->ToNumber<int32_t>());
395         SliderModel::GetInstance()->SetSliderInteractionMode(mode);
396     } else {
397         SliderModel::GetInstance()->ResetSliderInteractionMode();
398     }
399 }
400 
SetShowTips(const JSCallbackInfo & info)401 void JSSlider::SetShowTips(const JSCallbackInfo& info)
402 {
403     if (info.Length() < 1) {
404         return;
405     }
406     bool showTips = false;
407     if (info[0]->IsBoolean()) {
408         showTips = info[0]->ToBoolean();
409     }
410 
411     std::optional<std::string> content;
412     if (info.Length() == SLIDER_SHOW_TIPS_MAX_PARAMS) {
413         std::string str;
414         if (ParseJsString(info[1], str)) {
415             content = str;
416         }
417     }
418 
419     SliderModel::GetInstance()->SetShowTips(showTips, content);
420 }
421 
SetBlockBorderColor(const JSCallbackInfo & info)422 void JSSlider::SetBlockBorderColor(const JSCallbackInfo& info)
423 {
424     if (info.Length() < 1) {
425         return;
426     }
427 
428     Color colorVal;
429     if (!ParseJsColor(info[0], colorVal)) {
430         SliderModel::GetInstance()->ResetBlockBorderColor();
431         return;
432     }
433     SliderModel::GetInstance()->SetBlockBorderColor(colorVal);
434 }
435 
SetBlockBorderWidth(const JSCallbackInfo & info)436 void JSSlider::SetBlockBorderWidth(const JSCallbackInfo& info)
437 {
438     if (info.Length() < 1) {
439         return;
440     }
441 
442     CalcDimension blockBorderWidth;
443     if (!ParseJsDimensionVp(info[0], blockBorderWidth)) {
444         SliderModel::GetInstance()->ResetBlockBorderWidth();
445         return;
446     }
447     if (LessNotEqual(blockBorderWidth.Value(), 0.0)) {
448         SliderModel::GetInstance()->ResetBlockBorderWidth();
449         return;
450     }
451     SliderModel::GetInstance()->SetBlockBorderWidth(blockBorderWidth);
452 }
453 
SetStepColor(const JSCallbackInfo & info)454 void JSSlider::SetStepColor(const JSCallbackInfo& info)
455 {
456     if (info.Length() < 1) {
457         return;
458     }
459 
460     Color colorVal;
461     if (!ParseJsColor(info[0], colorVal)) {
462         SliderModel::GetInstance()->ResetStepColor();
463         return;
464     }
465     SliderModel::GetInstance()->SetStepColor(colorVal);
466 }
467 
SetTrackBorderRadius(const JSCallbackInfo & info)468 void JSSlider::SetTrackBorderRadius(const JSCallbackInfo& info)
469 {
470     if (info.Length() < 1) {
471         return;
472     }
473 
474     CalcDimension trackBorderRadius;
475     if (!ParseJsDimensionVpNG(info[0], trackBorderRadius, true)) {
476         SliderModel::GetInstance()->ResetTrackBorderRadius();
477         return;
478     }
479     if (LessNotEqual(trackBorderRadius.Value(), 0.0)) {
480         SliderModel::GetInstance()->ResetTrackBorderRadius();
481         return;
482     }
483     SliderModel::GetInstance()->SetTrackBorderRadius(trackBorderRadius);
484 }
485 
SetSelectedBorderRadius(const JSCallbackInfo & info)486 void JSSlider::SetSelectedBorderRadius(const JSCallbackInfo& info)
487 {
488     if (info.Length() < 1) {
489         return;
490     }
491 
492     CalcDimension selectedBorderRadius;
493     if (!ParseJsDimensionVpNG(info[0], selectedBorderRadius, false)) {
494         SliderModel::GetInstance()->ResetSelectedBorderRadius();
495         return;
496     }
497     if (LessNotEqual(selectedBorderRadius.Value(), 0.0)) {
498         SliderModel::GetInstance()->ResetSelectedBorderRadius();
499         return;
500     }
501     SliderModel::GetInstance()->SetSelectedBorderRadius(selectedBorderRadius);
502 }
503 
SetBlockSize(const JSCallbackInfo & info)504 void JSSlider::SetBlockSize(const JSCallbackInfo& info)
505 {
506     if (info.Length() < 1) {
507         return;
508     }
509     if (!info[0]->IsObject()) {
510         SliderModel::GetInstance()->ResetBlockSize();
511         return;
512     }
513     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
514 
515     CalcDimension width;
516     JSRef<JSVal> jsWidth = sizeObj->GetProperty("width");
517     if (!ParseJsDimensionVp(jsWidth, width)) {
518         width.SetValue(0.0);
519     }
520     if (LessNotEqual(width.Value(), 0.0)) {
521         width.SetValue(0.0);
522     }
523 
524     CalcDimension height;
525     JSRef<JSVal> jsHeight = sizeObj->GetProperty("height");
526     if (!ParseJsDimensionVp(jsHeight, height)) {
527         height.SetValue(0.0);
528     }
529     if (LessNotEqual(height.Value(), 0.0)) {
530         height.SetValue(0.0);
531     }
532 
533     SliderModel::GetInstance()->SetBlockSize(width, height);
534 }
535 
SetBlockStyle(const JSCallbackInfo & info)536 void JSSlider::SetBlockStyle(const JSCallbackInfo& info)
537 {
538     if (!info[0]->IsObject()) {
539         ResetBlockStyle();
540         return;
541     }
542     auto jsObj = JSRef<JSObject>::Cast(info[0]);
543     auto getType = jsObj->GetProperty("type");
544     if (getType->IsNull() || !getType->IsNumber()) {
545         ResetBlockStyle();
546         return;
547     }
548     auto type = static_cast<SliderModel::BlockStyleType>(getType->ToNumber<int32_t>());
549     if (type == SliderModel::BlockStyleType::IMAGE) {
550         std::string src;
551         auto image = jsObj->GetProperty("image");
552         if (!ParseJsMedia(image, src)) {
553             ResetBlockStyle();
554             return;
555         }
556         std::string bundleName;
557         std::string moduleName;
558         GetJsMediaBundleInfo(image, bundleName, moduleName);
559         SliderModel::GetInstance()->SetBlockImage(src, bundleName, moduleName);
560     } else if (type == SliderModel::BlockStyleType::SHAPE) {
561         auto shape = jsObj->GetProperty("shape");
562         if (!shape->IsObject()) {
563             ResetBlockStyle();
564             return;
565         }
566         JSShapeAbstract* shapeAbstract = JSRef<JSObject>::Cast(shape)->Unwrap<JSShapeAbstract>();
567         if (shapeAbstract == nullptr) {
568             ResetBlockStyle();
569             return;
570         }
571         SliderModel::GetInstance()->SetBlockShape(shapeAbstract->GetBasicShape());
572     }
573     SliderModel::GetInstance()->SetBlockType(type);
574 }
575 
SetStepSize(const JSCallbackInfo & info)576 void JSSlider::SetStepSize(const JSCallbackInfo& info)
577 {
578     if (info.Length() < 1) {
579         return;
580     }
581 
582     CalcDimension stepSize;
583     if (!ParseJsDimensionVp(info[0], stepSize)) {
584         SliderModel::GetInstance()->ResetStepSize();
585         return;
586     }
587     if (LessNotEqual(stepSize.Value(), 0.0)) {
588         auto theme = GetTheme<SliderTheme>();
589         CHECK_NULL_VOID(theme);
590         stepSize = theme->GetMarkerSize();
591     }
592     SliderModel::GetInstance()->SetStepSize(stepSize);
593 }
594 
OnChange(const JSCallbackInfo & info)595 void JSSlider::OnChange(const JSCallbackInfo& info)
596 {
597     if (!info[0]->IsFunction()) {
598         return;
599     }
600     SliderModel::GetInstance()->SetOnChange(
601         JsEventCallback<void(float, int32_t)>(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0])));
602     info.ReturnSelf();
603 }
604 
ResetBlockStyle()605 void JSSlider::ResetBlockStyle()
606 {
607     SliderModel::GetInstance()->ResetBlockType();
608     SliderModel::GetInstance()->ResetBlockImage();
609     SliderModel::GetInstance()->ResetBlockShape();
610 }
611 } // namespace OHOS::Ace::Framework
612