• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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_linear_indicator.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "core/common/container.h"
20 #include "core/components_ng/base/view_abstract_model.h"
21 #include "core/components_ng/pattern/linear_indicator/linear_indicator_model.h"
22 #include "core/components_ng/pattern/linear_indicator/linear_indicator_model_ng.h"
23 #include "core/components_ng/pattern/linear_indicator/linear_indicator_theme.h"
24 #include "frameworks/bridge/declarative_frontend/jsview/js_linear_indicator_controller.h"
25 
26 namespace OHOS::Ace {
27 
28 std::unique_ptr<LinearIndicatorModel> LinearIndicatorModel::instance_ = nullptr;
29 
GetInstance()30 LinearIndicatorModel* LinearIndicatorModel::GetInstance()
31 {
32     if (!instance_) {
33         instance_.reset(new NG::LinearIndicatorModelNG());
34     }
35     return instance_.get();
36 }
37 
38 } // namespace OHOS::Ace
39 
40 namespace OHOS::Ace::Framework {
41 
Create(const JSCallbackInfo & info)42 void JSLinearIndicator::Create(const JSCallbackInfo& info)
43 {
44     const int32_t length = info.Length();
45     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
46     CHECK_NULL_VOID(pipeline);
47     auto theme = pipeline->GetThemeManager()->GetTheme<NG::LinearIndicatorTheme>();
48     CHECK_NULL_VOID(theme);
49     int32_t progressCount = theme->GetDefaultProgressCount();
50     int32_t defaultProgressMin = theme->GetDefaultProgressMin();
51 
52     if (length > 0) {
53         auto arg0 = info[0];
54         if (arg0->IsNumber()) {
55             progressCount = arg0->ToNumber<int32_t>();
56             if (progressCount < defaultProgressMin) {
57                 progressCount = defaultProgressMin;
58             }
59         }
60     }
61     RefPtr<NG::LinearIndicatorController> controller = LinearIndicatorModel::GetInstance()->Create(progressCount);
62     if (length > 1) {
63         auto arg1 = info[1];
64         if (arg1->IsObject()) {
65             auto* jsController = JSRef<JSObject>::Cast(arg1)->Unwrap<JSLinearIndicatorController>();
66             if (jsController) {
67                 jsController->SetController(controller);
68             }
69         }
70     }
71 }
72 
SetStyle(const JSCallbackInfo & info)73 void JSLinearIndicator::SetStyle(const JSCallbackInfo& info)
74 {
75     if (info.Length() == 0) {
76         return;
77     }
78     auto arg0 = info[0];
79     if (!arg0->IsObject()) {
80         return;
81     }
82     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
83     CHECK_NULL_VOID(pipeline);
84     auto theme = pipeline->GetThemeManager()->GetTheme<NG::LinearIndicatorTheme>();
85     CHECK_NULL_VOID(theme);
86     auto paramObject = JSRef<JSObject>::Cast(arg0);
87     SetSpace(paramObject, theme);
88     SetStrokeWidth(paramObject, theme);
89     SetStrokeRadius(paramObject, theme);
90     SetTrackBackgroundColor(paramObject, theme);
91     SetTrackColor(paramObject, theme);
92 }
93 
Loop(const JSCallbackInfo & info)94 void JSLinearIndicator::Loop(const JSCallbackInfo& info)
95 {
96     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
97     CHECK_NULL_VOID(pipeline);
98     auto theme = pipeline->GetThemeManager()->GetTheme<NG::LinearIndicatorTheme>();
99     CHECK_NULL_VOID(theme);
100     bool value = theme->GetDefaultLoop();
101     if (info.Length() > 0) {
102         auto arg0 = info[0];
103         if (arg0->IsBoolean()) {
104             value = arg0->ToBoolean();
105         }
106     }
107     LinearIndicatorModel::GetInstance()->Loop(value);
108 }
109 
OnChange(const JSCallbackInfo & info)110 void JSLinearIndicator::OnChange(const JSCallbackInfo& info)
111 {
112     if ((info.Length() == 0)) {
113         return;
114     }
115     auto arg0 = info[0];
116     if (!arg0->IsFunction()) {
117         return;
118     }
119 
120     auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(arg0));
121     auto onChangeCallback = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
122                                 int32_t index, float progress) {
123         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
124         ACE_SCORING_EVENT("LinearIndicator::onChange");
125         JSRef<JSVal> params[2] = { JSRef<JSVal>::Make(ToJSValue(index)), JSRef<JSVal>::Make(ToJSValue(progress)) };
126         func->ExecuteJS(2, params);
127     };
128     LinearIndicatorModel::GetInstance()->OnChange(std::move(onChangeCallback));
129 }
130 
JSBind(BindingTarget globalObj)131 void JSLinearIndicator::JSBind(BindingTarget globalObj)
132 {
133     JSClass<JSLinearIndicator>::Declare("LinearIndicator");
134     MethodOptions opt = MethodOptions::NONE;
135     JSClass<JSLinearIndicator>::StaticMethod("create", &JSLinearIndicator::Create, opt);
136     JSClass<JSLinearIndicator>::StaticMethod("indicatorStyle", &JSLinearIndicator::SetStyle, opt);
137     JSClass<JSLinearIndicator>::StaticMethod("indicatorLoop", &JSLinearIndicator::Loop, opt);
138     JSClass<JSLinearIndicator>::StaticMethod("onChange", &JSLinearIndicator::OnChange, opt);
139     JSClass<JSLinearIndicator>::StaticMethod("height", &JSLinearIndicator::JsHeight, opt);
140     JSClass<JSLinearIndicator>::StaticMethod("padding", &JSLinearIndicator::JsPadding, opt);
141     JSClass<JSLinearIndicator>::StaticMethod("paddingLeft", &JSLinearIndicator::SetPaddingLeft, opt);
142     JSClass<JSLinearIndicator>::StaticMethod("paddingRight", &JSLinearIndicator::SetPaddingRight, opt);
143     JSClass<JSViewAbstract>::StaticMethod("paddingTop", &JSLinearIndicator::JsIgnore, opt);
144     JSClass<JSViewAbstract>::StaticMethod("paddingBottom", &JSLinearIndicator::JsIgnore, opt);
145     JSClass<JSLinearIndicator>::Inherit<JSViewAbstract>();
146     JSClass<JSLinearIndicator>::Inherit<JSInteractableView>();
147     JSClass<JSLinearIndicator>::Bind<>(globalObj);
148 }
149 
SetSpace(const JSRef<JSObject> & paramObject,const RefPtr<NG::LinearIndicatorTheme> & theme)150 void JSLinearIndicator::SetSpace(const JSRef<JSObject>& paramObject, const RefPtr<NG::LinearIndicatorTheme>& theme)
151 {
152     CalcDimension spaceDimension;
153     CalcDimension defaultSpace = theme->GetDefaultSpace();
154     auto space = paramObject->GetProperty("space");
155     if (space->IsUndefined() || space->IsNull() || !ParseLengthMetricsToDimension(space, spaceDimension)) {
156         spaceDimension = defaultSpace;
157     }
158     if (LessNotEqual(spaceDimension.Value(), 0.0f) || spaceDimension.Unit() == DimensionUnit::PERCENT) {
159         spaceDimension = defaultSpace;
160     }
161     LinearIndicatorModel::GetInstance()->SetSpace(spaceDimension);
162 }
163 
SetStrokeWidth(const JSRef<JSObject> & paramObject,const RefPtr<NG::LinearIndicatorTheme> & theme)164 void JSLinearIndicator::SetStrokeWidth(
165     const JSRef<JSObject>& paramObject, const RefPtr<NG::LinearIndicatorTheme>& theme)
166 {
167     CalcDimension strokeWidthDimension;
168     CalcDimension defaultStrokeWidth = theme->GetDefaultStrokeWidth();
169     CalcDimension defaultStrokeWidthMin = theme->GetDefaultStrokeWidthMin();
170     auto strokeWidth = paramObject->GetProperty("strokeWidth");
171     if (strokeWidth->IsUndefined() || strokeWidth->IsNull() ||
172         !ParseLengthMetricsToDimension(strokeWidth, strokeWidthDimension)) {
173         strokeWidthDimension = defaultStrokeWidth;
174     }
175     if (LessNotEqual(strokeWidthDimension.Value(), 0.0f) || strokeWidthDimension.Unit() == DimensionUnit::PERCENT) {
176         strokeWidthDimension = defaultStrokeWidth;
177     }
178     if (strokeWidthDimension.ConvertToVp() < defaultStrokeWidthMin.ConvertToVp()) {
179         strokeWidthDimension = defaultStrokeWidthMin;
180     }
181     LinearIndicatorModel::GetInstance()->SetStrokeWidth(strokeWidthDimension);
182 }
183 
SetStrokeRadius(const JSRef<JSObject> & paramObject,const RefPtr<NG::LinearIndicatorTheme> & theme)184 void JSLinearIndicator::SetStrokeRadius(
185     const JSRef<JSObject>& paramObject, const RefPtr<NG::LinearIndicatorTheme>& theme)
186 {
187     CalcDimension strokeRadiusDimension;
188     CalcDimension defaultStrokeRadius = theme->GetDefaultStrokeRadius();
189     auto strokeRadius = paramObject->GetProperty("strokeRadius");
190     if (strokeRadius->IsUndefined() || strokeRadius->IsNull() ||
191         !ParseLengthMetricsToDimension(strokeRadius, strokeRadiusDimension)) {
192         strokeRadiusDimension = defaultStrokeRadius;
193     }
194     if (LessNotEqual(strokeRadiusDimension.Value(), 0.0f) || strokeRadiusDimension.Unit() == DimensionUnit::PERCENT) {
195         strokeRadiusDimension = defaultStrokeRadius;
196     }
197     LinearIndicatorModel::GetInstance()->SetStrokeRadius(strokeRadiusDimension);
198 }
199 
SetTrackBackgroundColor(const JSRef<JSObject> & paramObject,const RefPtr<NG::LinearIndicatorTheme> & theme)200 void JSLinearIndicator::SetTrackBackgroundColor(
201     const JSRef<JSObject>& paramObject, const RefPtr<NG::LinearIndicatorTheme>& theme)
202 {
203     Color trackBackgroundColorValue;
204     auto trackBackgroundColor = paramObject->GetProperty("trackBackgroundColor");
205     if (trackBackgroundColor->IsUndefined() || trackBackgroundColor->IsNull() ||
206         !ParseColorMetricsToColor(trackBackgroundColor, trackBackgroundColorValue)) {
207         trackBackgroundColorValue = theme->GetTrackBackgroundColor();
208     }
209     LinearIndicatorModel::GetInstance()->SetTrackBackgroundColor(trackBackgroundColorValue);
210 }
211 
SetTrackColor(const JSRef<JSObject> & paramObject,const RefPtr<NG::LinearIndicatorTheme> & theme)212 void JSLinearIndicator::SetTrackColor(const JSRef<JSObject>& paramObject, const RefPtr<NG::LinearIndicatorTheme>& theme)
213 {
214     Color trackColorValue;
215     auto trackColor = paramObject->GetProperty("trackColor");
216     if (trackColor->IsUndefined() || trackColor->IsNull() || !ParseColorMetricsToColor(trackColor, trackColorValue)) {
217         trackColorValue = theme->GetTrackColor();
218     }
219     LinearIndicatorModel::GetInstance()->SetTrackColor(trackColorValue);
220 }
221 
JsHeight(const JSCallbackInfo & info)222 void JSLinearIndicator::JsHeight(const JSCallbackInfo& info)
223 {
224     if (info.Length() == 0) {
225         return;
226     }
227     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
228     CHECK_NULL_VOID(pipeline);
229     auto theme = pipeline->GetThemeManager()->GetTheme<NG::LinearIndicatorTheme>();
230     CHECK_NULL_VOID(theme);
231     Dimension defaultHeight = theme->GetDefaultHeight();
232 
233     CalcDimension value = defaultHeight;
234     auto jsValue = info[0];
235     if (jsValue->IsUndefined()) {
236         value = defaultHeight;
237     } else if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
238         if (!ParseJsDimensionVpNG(jsValue, value)) {
239             value = defaultHeight;
240         }
241     } else if (!ParseJsDimensionVp(jsValue, value)) {
242         value = defaultHeight;
243     }
244     if (LessNotEqual(value.Value(), 0.0)) {
245         value = defaultHeight;
246     }
247     ViewAbstractModel::GetInstance()->SetHeight(value);
248 }
249 
JsPadding(const JSCallbackInfo & info)250 void JSLinearIndicator::JsPadding(const JSCallbackInfo& info)
251 {
252     if (info.Length() == 0) {
253         return;
254     }
255     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
256     CHECK_NULL_VOID(pipeline);
257     auto theme = pipeline->GetThemeManager()->GetTheme<NG::LinearIndicatorTheme>();
258     CHECK_NULL_VOID(theme);
259     Dimension defaultLeft = theme->GetPaddingLeft();
260     Dimension defaultRight = theme->GetPaddingRight();
261 
262     auto jsVal = info[0];
263     if ((!jsVal->IsObject()) && (!jsVal->IsString()) && (!jsVal->IsNumber())) {
264         ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, defaultLeft, defaultRight);
265         return;
266     }
267     if (jsVal->IsObject()) {
268         CommonCalcDimension commonCalcDimension;
269         JSRef<JSObject> paddingObj = JSRef<JSObject>::Cast(jsVal);
270         ParseCommonMarginOrPaddingCorner(paddingObj, commonCalcDimension);
271         if (!commonCalcDimension.left.has_value() || LessNotEqual(commonCalcDimension.left.value().Value(), 0.0)) {
272             commonCalcDimension.left = defaultLeft;
273         }
274         if (!commonCalcDimension.right.has_value() || LessNotEqual(commonCalcDimension.right.value().Value(), 0.0)) {
275             commonCalcDimension.right = defaultRight;
276         }
277         ViewAbstractModel::GetInstance()->SetPaddings(
278             std::nullopt, std::nullopt, commonCalcDimension.left, commonCalcDimension.right);
279         return;
280     }
281     CalcDimension length;
282     if (ParseJsDimensionVp(jsVal, length) && (!LessNotEqual(length.Value(), 0.0))) {
283         ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, length, length);
284     } else {
285         ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, defaultLeft, defaultRight);
286     }
287 }
288 
SetPaddingLeft(const JSCallbackInfo & info)289 void JSLinearIndicator::SetPaddingLeft(const JSCallbackInfo& info)
290 {
291     if (info.Length() == 0) {
292         return;
293     }
294     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
295     CHECK_NULL_VOID(pipeline);
296     auto theme = pipeline->GetThemeManager()->GetTheme<NG::LinearIndicatorTheme>();
297     CHECK_NULL_VOID(theme);
298     Dimension defaultLeft = theme->GetPaddingLeft();
299     CalcDimension value;
300     if (!ParseJsDimensionVp(info[0], value)) {
301         value = defaultLeft;
302     }
303     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, value, std::nullopt);
304 }
305 
SetPaddingRight(const JSCallbackInfo & info)306 void JSLinearIndicator::SetPaddingRight(const JSCallbackInfo& info)
307 {
308     if (info.Length() == 0) {
309         return;
310     }
311     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
312     CHECK_NULL_VOID(pipeline);
313     auto theme = pipeline->GetThemeManager()->GetTheme<NG::LinearIndicatorTheme>();
314     CHECK_NULL_VOID(theme);
315     Dimension defaultRight = theme->GetPaddingRight();
316     CalcDimension value;
317     if (!ParseJsDimensionVp(info[0], value)) {
318         value = defaultRight;
319     }
320     ViewAbstractModel::GetInstance()->SetPaddings(std::nullopt, std::nullopt, std::nullopt, value);
321 }
322 
JsIgnore(const JSCallbackInfo & info)323 void JSLinearIndicator::JsIgnore(const JSCallbackInfo& info) {}
324 
325 } // namespace OHOS::Ace::Framework
326