1 /*
2 * Copyright (c) 2021 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/view_stack_processor.h"
20 #include "core/components/slider/render_slider.h"
21 #include "core/components/slider/slider_component.h"
22 #include "core/components/slider/slider_element.h"
23 #include "core/components/slider/slider_theme.h"
24 #include "frameworks/bridge/declarative_frontend/engine/functions/js_function.h"
25
26 namespace OHOS::Ace::Framework {
27
JSBind(BindingTarget globalObj)28 void JSSlider::JSBind(BindingTarget globalObj)
29 {
30 JSClass<JSSlider>::Declare("Slider");
31 MethodOptions opt = MethodOptions::NONE;
32 JSClass<JSSlider>::StaticMethod("create", &JSSlider::Create, opt);
33 JSClass<JSSlider>::StaticMethod("blockColor", &JSSlider::SetBlockColor);
34 JSClass<JSSlider>::StaticMethod("trackColor", &JSSlider::SetTrackColor);
35 JSClass<JSSlider>::StaticMethod("trackThickness", &JSSlider::SetThickness);
36 JSClass<JSSlider>::StaticMethod("selectedColor", &JSSlider::SetSelectedColor);
37 JSClass<JSSlider>::StaticMethod("minLabel", &JSSlider::SetMinLabel);
38 JSClass<JSSlider>::StaticMethod("maxLabel", &JSSlider::SetMaxLabel);
39 JSClass<JSSlider>::StaticMethod("showSteps", &JSSlider::SetShowSteps);
40 JSClass<JSSlider>::StaticMethod("showTips", &JSSlider::SetShowTips);
41 JSClass<JSSlider>::StaticMethod("onChange", &JSSlider::OnChange);
42 JSClass<JSSlider>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
43 JSClass<JSSlider>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
44 JSClass<JSSlider>::Inherit<JSViewAbstract>();
45 JSClass<JSSlider>::Bind(globalObj);
46 }
47
GetStep(double step,double max)48 double GetStep(double step, double max)
49 {
50 if (step < 1 || step > max) {
51 step = 1;
52 }
53 return step;
54 }
55
GetValue(double value,double max,double min)56 double GetValue(double value, double max, double min)
57 {
58 if (value < min) {
59 value = min;
60 }
61
62 if (value > max) {
63 value = max;
64 }
65 return value;
66 }
67
Create(const JSCallbackInfo & info)68 void JSSlider::Create(const JSCallbackInfo& info)
69 {
70 double value = 0; // value:Current progress value. The default value is 0.
71 double min = 0; // min:Set the minimum value. The default value is 0.
72 double max = 100; // max:Set the maximum value. The default value is 100.
73 double step = 1; // step:Sets the sliding jump value of the slider. The default value is 1.
74 bool reverse = false;
75
76 if (!info[0]->IsObject()) {
77 LOGE("slider create error, info is non-valid");
78 return;
79 }
80
81 auto paramObject = JSRef<JSObject>::Cast(info[0]);
82 auto getValue = paramObject->GetProperty("value");
83 auto getMin = paramObject->GetProperty("min");
84 auto getMax = paramObject->GetProperty("max");
85 auto getStep = paramObject->GetProperty("step");
86 auto getStyle = paramObject->GetProperty("style");
87 auto direction = paramObject->GetProperty("direction");
88 auto isReverse = paramObject->GetProperty("reverse");
89
90 if (!getValue->IsNull() && getValue->IsNumber()) {
91 value = getValue->ToNumber<double>();
92 }
93
94 if (!getMin->IsNull() && getMin->IsNumber()) {
95 min = getMin->ToNumber<double>();
96 }
97
98 if (!getMax->IsNull() && getMax->IsNumber()) {
99 max = getMax->ToNumber<double>();
100 }
101
102 if (!getStep->IsNull() && getStep->IsNumber()) {
103 step = getStep->ToNumber<double>();
104 }
105
106 if (!isReverse->IsNull() && isReverse->IsBoolean()) {
107 reverse = isReverse->ToBoolean();
108 }
109
110 if (GreatOrEqual(min, max)) {
111 min = 0;
112 max = 100;
113 }
114
115 step = GetStep(step, max - min);
116
117 value = GetValue(value, max, min);
118
119 auto sliderComponent = AceType::MakeRefPtr<OHOS::Ace::SliderComponent>(value, step, min, max);
120 auto sliderMode = SliderStyle::OUTSET;
121 if (!getStyle->IsNull() && getStyle->IsNumber()) {
122 sliderMode = static_cast<SliderStyle>(getStyle->ToNumber<int32_t>());
123 }
124
125 if (sliderMode == SliderStyle::INSET) {
126 sliderComponent->SetSliderMode(SliderMode::INSET);
127 } else if (sliderMode == SliderStyle::CAPSULE) {
128 sliderComponent->SetSliderMode(SliderMode::CAPSULE);
129 } else {
130 sliderComponent->SetSliderMode(SliderMode::OUTSET);
131 }
132
133 auto sliderDirection = Axis::HORIZONTAL;
134 if (!direction->IsNull() && direction->IsNumber()) {
135 sliderDirection = static_cast<Axis>(direction->ToNumber<int32_t>());
136 }
137 sliderComponent->SetDirection(sliderDirection);
138 if (sliderDirection == Axis::VERTICAL) {
139 sliderComponent->SetDirection(Axis::VERTICAL);
140 } else {
141 sliderComponent->SetDirection(Axis::HORIZONTAL);
142 }
143
144 auto theme = GetTheme<SliderTheme>();
145 if (!theme) {
146 LOGE("Slider Theme is null");
147 return;
148 }
149 sliderComponent->SetThemeStyle(theme);
150 sliderComponent->SetReverse(reverse);
151
152 ViewStackProcessor::GetInstance()->Push(sliderComponent);
153 }
154
SetThickness(const JSCallbackInfo & info)155 void JSSlider::SetThickness(const JSCallbackInfo& info)
156 {
157 if (info.Length() < 1) {
158 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
159 return;
160 }
161 Dimension value;
162 if (!ParseJsDimensionVp(info[0], value)) {
163 return;
164 }
165 if (LessNotEqual(value.Value(), 0.0)) {
166 value.SetValue(0.0);
167 }
168 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
169 auto slider = AceType::DynamicCast<SliderComponent>(component);
170 if (!slider) {
171 LOGE("Slider Component is null");
172 return;
173 }
174 slider->SetThickness(value);
175 }
176
SetBlockColor(const JSCallbackInfo & info)177 void JSSlider::SetBlockColor(const JSCallbackInfo& info)
178 {
179 if (info.Length() < 1) {
180 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
181 return;
182 }
183
184 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
185 auto slider = AceType::DynamicCast<SliderComponent>(component);
186 if (!slider) {
187 LOGE("Slider Component is null");
188 return;
189 }
190 auto block = slider->GetBlock();
191 if (!block) {
192 LOGE("backColor Component is null");
193 return;
194 }
195
196 Color colorVal;
197 if (ParseJsColor(info[0], colorVal)) {
198 block->SetBlockColor(colorVal);
199 }
200 }
201
SetTrackColor(const JSCallbackInfo & info)202 void JSSlider::SetTrackColor(const JSCallbackInfo& info)
203 {
204 if (info.Length() < 1) {
205 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
206 return;
207 }
208
209 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
210 auto slider = AceType::DynamicCast<SliderComponent>(component);
211 if (!slider) {
212 LOGE("Slider Component is null");
213 return;
214 }
215 auto track = slider->GetTrack();
216 if (!track) {
217 LOGE("track Component is null");
218 return;
219 }
220
221 Color colorVal;
222 if (ParseJsColor(info[0], colorVal)) {
223 track->SetBackgroundColor(colorVal);
224 }
225 }
226
SetSelectedColor(const JSCallbackInfo & info)227 void JSSlider::SetSelectedColor(const JSCallbackInfo& info)
228 {
229 if (info.Length() < 1) {
230 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
231 return;
232 }
233
234 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
235 auto slider = AceType::DynamicCast<SliderComponent>(component);
236 if (!slider) {
237 LOGE("Slider Component is null");
238 return;
239 }
240 auto track = slider->GetTrack();
241 if (!track) {
242 LOGE("track Component is null");
243 return;
244 }
245
246 Color colorVal;
247 if (ParseJsColor(info[0], colorVal)) {
248 track->SetSelectColor(colorVal);
249 }
250 }
251
SetMinLabel(const JSCallbackInfo & info)252 void JSSlider::SetMinLabel(const JSCallbackInfo& info)
253 {
254 if (info.Length() < 1) {
255 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
256 return;
257 }
258
259 if (!info[0]->IsNumber()) {
260 LOGE("arg is not number.");
261 return;
262 }
263
264 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
265 auto Slider = AceType::DynamicCast<SliderComponent>(component);
266 if (!Slider) {
267 LOGE("Slider Component is null");
268 return;
269 }
270 Slider->SetMinValue(info[0]->ToNumber<double>());
271 }
272
SetMaxLabel(const JSCallbackInfo & info)273 void JSSlider::SetMaxLabel(const JSCallbackInfo& info)
274 {
275 if (info.Length() < 1) {
276 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
277 return;
278 }
279
280 if (!info[0]->IsNumber()) {
281 LOGE("arg is not number.");
282 return;
283 }
284
285 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
286 auto Slider = AceType::DynamicCast<SliderComponent>(component);
287 if (!Slider) {
288 LOGE("Slider Component is null");
289 return;
290 }
291 Slider->SetMaxValue(info[0]->ToNumber<double>());
292 }
293
SetShowSteps(const JSCallbackInfo & info)294 void JSSlider::SetShowSteps(const JSCallbackInfo& info)
295 {
296 if (info.Length() < 1) {
297 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
298 return;
299 }
300
301 if (!info[0]->IsBoolean()) {
302 LOGE("arg is not bool.");
303 return;
304 }
305
306 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
307 auto Slider = AceType::DynamicCast<SliderComponent>(component);
308 if (!Slider) {
309 LOGE("Slider Component is null");
310 return;
311 }
312 Slider->SetShowSteps(info[0]->ToBoolean());
313 }
314
SetShowTips(const JSCallbackInfo & info)315 void JSSlider::SetShowTips(const JSCallbackInfo& info)
316 {
317 if (info.Length() < 1) {
318 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
319 return;
320 }
321
322 if (!info[0]->IsBoolean()) {
323 LOGE("arg is not bool.");
324 return;
325 }
326
327 auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
328 auto Slider = AceType::DynamicCast<SliderComponent>(component);
329 if (!Slider) {
330 LOGE("Slider Component is null");
331 return;
332 }
333 Slider->SetShowTips(info[0]->ToBoolean());
334 }
335
OnChange(const JSCallbackInfo & info)336 void JSSlider::OnChange(const JSCallbackInfo& info)
337 {
338 if (!JSViewBindEvent(&SliderComponent::SetOnChange, info)) {
339 LOGW("Failed to bind event");
340 }
341 info.ReturnSelf();
342 }
343
344 } // namespace OHOS::Ace::Framework
345