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