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_view_common_def.h"
19 #include "bridge/declarative_frontend/jsview/models/slider_model_impl.h"
20 #include "core/components/slider/render_slider.h"
21 #include "core/components/slider/slider_element.h"
22 #include "core/components_ng/pattern/slider/slider_model_ng.h"
23 #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
24
25 namespace OHOS::Ace {
26
27 std::unique_ptr<SliderModel> SliderModel::instance_ = nullptr;
28
GetInstance()29 SliderModel* SliderModel::GetInstance()
30 {
31 if (!instance_) {
32 #ifdef NG_BUILD
33 instance_.reset(new NG::SliderModelNG());
34 #else
35 if (Container::IsCurrentUseNewPipeline()) {
36 instance_.reset(new NG::SliderModelNG());
37 } else {
38 instance_.reset(new Framework::SliderModelImpl());
39 }
40 #endif
41 }
42 return instance_.get();
43 }
44
45 } // namespace OHOS::Ace
46
47 namespace OHOS::Ace::Framework {
48
JSBind(BindingTarget globalObj)49 void JSSlider::JSBind(BindingTarget globalObj)
50 {
51 JSClass<JSSlider>::Declare("Slider");
52 MethodOptions opt = MethodOptions::NONE;
53 JSClass<JSSlider>::StaticMethod("create", &JSSlider::Create, opt);
54 JSClass<JSSlider>::StaticMethod("blockColor", &JSSlider::SetBlockColor);
55 JSClass<JSSlider>::StaticMethod("trackColor", &JSSlider::SetTrackColor);
56 JSClass<JSSlider>::StaticMethod("trackThickness", &JSSlider::SetThickness);
57 JSClass<JSSlider>::StaticMethod("selectedColor", &JSSlider::SetSelectedColor);
58 JSClass<JSSlider>::StaticMethod("minLabel", &JSSlider::SetMinLabel);
59 JSClass<JSSlider>::StaticMethod("maxLabel", &JSSlider::SetMaxLabel);
60 JSClass<JSSlider>::StaticMethod("showSteps", &JSSlider::SetShowSteps);
61 JSClass<JSSlider>::StaticMethod("showTips", &JSSlider::SetShowTips);
62 JSClass<JSSlider>::StaticMethod("onChange", &JSSlider::OnChange);
63 JSClass<JSSlider>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
64 JSClass<JSSlider>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
65 JSClass<JSSlider>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
66 JSClass<JSSlider>::Inherit<JSViewAbstract>();
67 JSClass<JSSlider>::Bind(globalObj);
68 }
69
GetStep(double step,double max,double min)70 double GetStep(double step, double max, double min)
71 {
72 if (LessOrEqual(step, 0.0) || step > max - min) {
73 step = 1;
74 }
75 return step;
76 }
77
GetValue(double value,double max,double min)78 double GetValue(double value, double max, double min)
79 {
80 if (value < min) {
81 value = min;
82 }
83
84 if (value > max) {
85 value = max;
86 }
87 return value;
88 }
89
Create(const JSCallbackInfo & info)90 void JSSlider::Create(const JSCallbackInfo& info)
91 {
92 double value = 0; // value:Current progress value. The default value is 0.
93 double min = 0; // min:Set the minimum value. The default value is 0.
94 double max = 100; // max:Set the maximum value. The default value is 100.
95 double step = 1; // step:Sets the sliding jump value of the slider. The default value is 1.
96 bool reverse = false;
97
98 if (!info[0]->IsObject()) {
99 LOGE("slider create error, info is non-valid");
100 SliderModel::GetInstance()->Create(
101 static_cast<float>(value), static_cast<float>(step), static_cast<float>(min), static_cast<float>(max));
102 return;
103 }
104
105 auto paramObject = JSRef<JSObject>::Cast(info[0]);
106 auto getValue = paramObject->GetProperty("value");
107 auto getMin = paramObject->GetProperty("min");
108 auto getMax = paramObject->GetProperty("max");
109 auto getStep = paramObject->GetProperty("step");
110 auto getStyle = paramObject->GetProperty("style");
111 auto direction = paramObject->GetProperty("direction");
112 auto isReverse = paramObject->GetProperty("reverse");
113
114 if (!getValue->IsNull() && getValue->IsNumber()) {
115 value = getValue->ToNumber<double>();
116 }
117
118 if (!getMin->IsNull() && getMin->IsNumber()) {
119 min = getMin->ToNumber<double>();
120 }
121
122 if (!getMax->IsNull() && getMax->IsNumber()) {
123 max = getMax->ToNumber<double>();
124 }
125
126 if (!getStep->IsNull() && getStep->IsNumber()) {
127 step = getStep->ToNumber<double>();
128 }
129
130 if (!isReverse->IsNull() && isReverse->IsBoolean()) {
131 reverse = isReverse->ToBoolean();
132 }
133
134 if (GreatOrEqual(min, max)) {
135 min = 0;
136 max = 100;
137 }
138
139 step = GetStep(step, max, min);
140
141 if (!Container::IsCurrentUseNewPipeline()) {
142 value = GetValue(value, max, min);
143 }
144
145 auto sliderStyle = SliderStyle::OUTSET;
146 auto sliderMode = SliderModel::SliderMode::OUTSET;
147 if (!getStyle->IsNull() && getStyle->IsNumber()) {
148 sliderStyle = static_cast<SliderStyle>(getStyle->ToNumber<int32_t>());
149 }
150 if (sliderStyle == SliderStyle::INSET) {
151 sliderMode = SliderModel::SliderMode::INSET;
152 } else if (sliderStyle == SliderStyle::CAPSULE) {
153 sliderMode = SliderModel::SliderMode::CAPSULE;
154 } else {
155 sliderMode = SliderModel::SliderMode::OUTSET;
156 }
157
158 auto sliderDirection = Axis::HORIZONTAL;
159 if (!direction->IsNull() && direction->IsNumber()) {
160 sliderDirection = static_cast<Axis>(direction->ToNumber<int32_t>());
161 }
162 if (sliderDirection != Axis::VERTICAL) {
163 sliderDirection = Axis::HORIZONTAL;
164 }
165
166 SliderModel::GetInstance()->Create(
167 static_cast<float>(value), static_cast<float>(step), static_cast<float>(min), static_cast<float>(max));
168 SliderModel::GetInstance()->SetSliderMode(sliderMode);
169 SliderModel::GetInstance()->SetDirection(sliderDirection);
170 SliderModel::GetInstance()->SetReverse(reverse);
171 }
172
SetThickness(const JSCallbackInfo & info)173 void JSSlider::SetThickness(const JSCallbackInfo& info)
174 {
175 if (info.Length() < 1) {
176 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
177 return;
178 }
179 Dimension value;
180 if (!ParseJsDimensionVp(info[0], value)) {
181 return;
182 }
183 SliderModel::GetInstance()->SetThickness(value);
184 }
185
SetBlockColor(const JSCallbackInfo & info)186 void JSSlider::SetBlockColor(const JSCallbackInfo& info)
187 {
188 if (info.Length() < 1) {
189 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
190 return;
191 }
192 Color colorVal;
193 if (!ParseJsColor(info[0], colorVal)) {
194 return;
195 }
196 SliderModel::GetInstance()->SetBlockColor(colorVal);
197 }
198
SetTrackColor(const JSCallbackInfo & info)199 void JSSlider::SetTrackColor(const JSCallbackInfo& info)
200 {
201 if (info.Length() < 1) {
202 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
203 return;
204 }
205 Color colorVal;
206 if (!ParseJsColor(info[0], colorVal)) {
207 return;
208 }
209 SliderModel::GetInstance()->SetTrackBackgroundColor(colorVal);
210 }
211
SetSelectedColor(const JSCallbackInfo & info)212 void JSSlider::SetSelectedColor(const JSCallbackInfo& info)
213 {
214 if (info.Length() < 1) {
215 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
216 return;
217 }
218 Color colorVal;
219 if (!ParseJsColor(info[0], colorVal)) {
220 return;
221 }
222 SliderModel::GetInstance()->SetSelectColor(colorVal);
223 }
224
SetMinLabel(const JSCallbackInfo & info)225 void JSSlider::SetMinLabel(const JSCallbackInfo& info)
226 {
227 if (info.Length() < 1) {
228 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
229 return;
230 }
231
232 if (!info[0]->IsString()) {
233 LOGE("arg is not string.");
234 return;
235 }
236 SliderModel::GetInstance()->SetMinLabel(info[0]->ToNumber<float>());
237 }
238
SetMaxLabel(const JSCallbackInfo & info)239 void JSSlider::SetMaxLabel(const JSCallbackInfo& info)
240 {
241 if (info.Length() < 1) {
242 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
243 return;
244 }
245
246 if (!info[0]->IsString()) {
247 LOGE("arg is not string.");
248 return;
249 }
250 SliderModel::GetInstance()->SetMaxLabel(info[0]->ToNumber<float>());
251 }
252
SetShowSteps(const JSCallbackInfo & info)253 void JSSlider::SetShowSteps(const JSCallbackInfo& info)
254 {
255 if (info.Length() < 1) {
256 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
257 return;
258 }
259
260 if (!info[0]->IsBoolean()) {
261 LOGE("arg is not bool.");
262 return;
263 }
264 SliderModel::GetInstance()->SetShowSteps(info[0]->ToBoolean());
265 }
266
SetShowTips(const JSCallbackInfo & info)267 void JSSlider::SetShowTips(const JSCallbackInfo& info)
268 {
269 if (info.Length() < 1) {
270 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
271 return;
272 }
273
274 if (!info[0]->IsBoolean()) {
275 LOGE("arg is not bool.");
276 return;
277 }
278 SliderModel::GetInstance()->SetShowTips(info[0]->ToBoolean());
279 }
280
OnChange(const JSCallbackInfo & info)281 void JSSlider::OnChange(const JSCallbackInfo& info)
282 {
283 if (info.Length() < 1) {
284 LOGW("Must contain at least 1 argument");
285 return;
286 }
287 if (!info[0]->IsFunction()) {
288 LOGW("Argument is not a function object");
289 return;
290 }
291 SliderModel::GetInstance()->SetOnChange(
292 JsEventCallback<void(float, int32_t)>(info.GetExecutionContext(), JSRef<JSFunc>::Cast(info[0])));
293 info.ReturnSelf();
294 }
295
296 } // namespace OHOS::Ace::Framework
297