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