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         int32_t num = info[0]->ToNumber<int32_t>();
395         int32_t lowRange = static_cast<int32_t>(SliderModel::SliderInteraction::SLIDE_AND_CLICK);
396         int32_t upRange = static_cast<int32_t>(SliderModel::SliderInteraction::SLIDE_AND_CLICK_UP);
397         if (lowRange <= num && num <= upRange) {
398             auto mode = static_cast<SliderModel::SliderInteraction>(num);
399             SliderModel::GetInstance()->SetSliderInteractionMode(mode);
400         } else {
401             SliderModel::GetInstance()->ResetSliderInteractionMode();
402         }
403     } else {
404         SliderModel::GetInstance()->ResetSliderInteractionMode();
405     }
406 }
407 
SetShowTips(const JSCallbackInfo& info)408 void JSSlider::SetShowTips(const JSCallbackInfo& info)
409 {
410     if (info.Length() < 1) {
411         return;
412     }
413     bool showTips = false;
414     if (info[0]->IsBoolean()) {
415         showTips = info[0]->ToBoolean();
416     }
417 
418     std::optional<std::string> content;
419     if (info.Length() == SLIDER_SHOW_TIPS_MAX_PARAMS) {
420         std::string str;
421         if (ParseJsString(info[1], str)) {
422             content = str;
423         }
424     }
425 
426     SliderModel::GetInstance()->SetShowTips(showTips, content);
427 }
428 
SetBlockBorderColor(const JSCallbackInfo& info)429 void JSSlider::SetBlockBorderColor(const JSCallbackInfo& info)
430 {
431     if (info.Length() < 1) {
432         return;
433     }
434 
435     Color colorVal;
436     if (!ParseJsColor(info[0], colorVal)) {
437         SliderModel::GetInstance()->ResetBlockBorderColor();
438         return;
439     }
440     SliderModel::GetInstance()->SetBlockBorderColor(colorVal);
441 }
442 
SetBlockBorderWidth(const JSCallbackInfo& info)443 void JSSlider::SetBlockBorderWidth(const JSCallbackInfo& info)
444 {
445     if (info.Length() < 1) {
446         return;
447     }
448 
449     CalcDimension blockBorderWidth;
450     if (!ParseJsDimensionVp(info[0], blockBorderWidth)) {
451         SliderModel::GetInstance()->ResetBlockBorderWidth();
452         return;
453     }
454     if (LessNotEqual(blockBorderWidth.Value(), 0.0)) {
455         SliderModel::GetInstance()->ResetBlockBorderWidth();
456         return;
457     }
458     SliderModel::GetInstance()->SetBlockBorderWidth(blockBorderWidth);
459 }
460 
SetStepColor(const JSCallbackInfo& info)461 void JSSlider::SetStepColor(const JSCallbackInfo& info)
462 {
463     if (info.Length() < 1) {
464         return;
465     }
466 
467     Color colorVal;
468     if (!ParseJsColor(info[0], colorVal)) {
469         SliderModel::GetInstance()->ResetStepColor();
470         return;
471     }
472     SliderModel::GetInstance()->SetStepColor(colorVal);
473 }
474 
SetTrackBorderRadius(const JSCallbackInfo& info)475 void JSSlider::SetTrackBorderRadius(const JSCallbackInfo& info)
476 {
477     if (info.Length() < 1) {
478         return;
479     }
480 
481     CalcDimension trackBorderRadius;
482     if (!ParseJsDimensionVpNG(info[0], trackBorderRadius, true)) {
483         SliderModel::GetInstance()->ResetTrackBorderRadius();
484         return;
485     }
486     if (LessNotEqual(trackBorderRadius.Value(), 0.0)) {
487         SliderModel::GetInstance()->ResetTrackBorderRadius();
488         return;
489     }
490     SliderModel::GetInstance()->SetTrackBorderRadius(trackBorderRadius);
491 }
492 
SetSelectedBorderRadius(const JSCallbackInfo& info)493 void JSSlider::SetSelectedBorderRadius(const JSCallbackInfo& info)
494 {
495     if (info.Length() < 1) {
496         return;
497     }
498 
499     CalcDimension selectedBorderRadius;
500     if (!ParseJsDimensionVpNG(info[0], selectedBorderRadius, false)) {
501         SliderModel::GetInstance()->ResetSelectedBorderRadius();
502         return;
503     }
504     if (LessNotEqual(selectedBorderRadius.Value(), 0.0)) {
505         SliderModel::GetInstance()->ResetSelectedBorderRadius();
506         return;
507     }
508     SliderModel::GetInstance()->SetSelectedBorderRadius(selectedBorderRadius);
509 }
510 
SetBlockSize(const JSCallbackInfo& info)511 void JSSlider::SetBlockSize(const JSCallbackInfo& info)
512 {
513     if (info.Length() < 1) {
514         return;
515     }
516     if (!info[0]->IsObject()) {
517         SliderModel::GetInstance()->ResetBlockSize();
518         return;
519     }
520     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
521 
522     CalcDimension width;
523     JSRef<JSVal> jsWidth = sizeObj->GetProperty("width");
524     if (!ParseJsDimensionVp(jsWidth, width)) {
525         width.SetValue(0.0);
526     }
527     if (LessNotEqual(width.Value(), 0.0)) {
528         width.SetValue(0.0);
529     }
530 
531     CalcDimension height;
532     JSRef<JSVal> jsHeight = sizeObj->GetProperty("height");
533     if (!ParseJsDimensionVp(jsHeight, height)) {
534         height.SetValue(0.0);
535     }
536     if (LessNotEqual(height.Value(), 0.0)) {
537         height.SetValue(0.0);
538     }
539 
540     SliderModel::GetInstance()->SetBlockSize(width, height);
541 }
542 
SetBlockStyle(const JSCallbackInfo& info)543 void JSSlider::SetBlockStyle(const JSCallbackInfo& info)
544 {
545     if (!info[0]->IsObject()) {
546         ResetBlockStyle();
547         return;
548     }
549     auto jsObj = JSRef<JSObject>::Cast(info[0]);
550     auto getType = jsObj->GetProperty("type");
551     if (getType->IsNull() || !getType->IsNumber()) {
552         ResetBlockStyle();
553         return;
554     }
555     auto type = static_cast<SliderModel::BlockStyleType>(getType->ToNumber<int32_t>());
556     if (type == SliderModel::BlockStyleType::IMAGE) {
557         std::string src;
558         auto image = jsObj->GetProperty("image");
559         if (!ParseJsMedia(image, src)) {
560             ResetBlockStyle();
561             return;
562         }
563         std::string bundleName;
564         std::string moduleName;
565         GetJsMediaBundleInfo(image, bundleName, moduleName);
566         SliderModel::GetInstance()->SetBlockImage(src, bundleName, moduleName);
567     } else if (type == SliderModel::BlockStyleType::SHAPE) {
568         auto shape = jsObj->GetProperty("shape");
569         if (!shape->IsObject()) {
570             ResetBlockStyle();
571             return;
572         }
573         JSShapeAbstract* shapeAbstract = JSRef<JSObject>::Cast(shape)->Unwrap<JSShapeAbstract>();
574         if (shapeAbstract == nullptr) {
575             ResetBlockStyle();
576             return;
577         }
578         SliderModel::GetInstance()->SetBlockShape(shapeAbstract->GetBasicShape());
579     }
580     SliderModel::GetInstance()->SetBlockType(type);
581 }
582 
SetStepSize(const JSCallbackInfo& info)583 void JSSlider::SetStepSize(const JSCallbackInfo& info)
584 {
585     if (info.Length() < 1) {
586         return;
587     }
588 
589     CalcDimension stepSize;
590     if (!ParseJsDimensionVp(info[0], stepSize)) {
591         SliderModel::GetInstance()->ResetStepSize();
592         return;
593     }
594     if (LessNotEqual(stepSize.Value(), 0.0)) {
595         auto theme = GetTheme<SliderTheme>();
596         CHECK_NULL_VOID(theme);
597         stepSize = theme->GetMarkerSize();
598     }
599     SliderModel::GetInstance()->SetStepSize(stepSize);
600 }
601 
OnChange(const JSCallbackInfo& info)602 void JSSlider::OnChange(const JSCallbackInfo& info)
603 {
604     if (!info[0]->IsFunction()) {
605         return;
606     }
607     SliderModel::GetInstance()->SetOnChange(
608         JsEventCallback<void(float, int32_t)>(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0])));
609     info.ReturnSelf();
610 }
611 
ResetBlockStyle()612 void JSSlider::ResetBlockStyle()
613 {
614     SliderModel::GetInstance()->ResetBlockType();
615     SliderModel::GetInstance()->ResetBlockImage();
616     SliderModel::GetInstance()->ResetBlockShape();
617 }
618 } // namespace OHOS::Ace::Framework
619