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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_linear_indicator.h"
16
17 #include <string>
18
19 #include "base/geometry/dimension.h"
20 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_button_bridge.h"
21 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_common_bridge.h"
22 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
23 #include "core/components/common/properties/text_style.h"
24 #include "core/components_ng/base/frame_node.h"
25 #include "core/components_ng/pattern/button/button_model_ng.h"
26 #include "core/components_ng/pattern/button/button_request_data.h"
27 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
28
29 namespace OHOS::Ace::NG {
30
31 constexpr int NUM_0 = 0;
32 constexpr int NUM_1 = 1;
33 constexpr int NUM_2 = 2;
34
SetIndicatorStyleSize(EcmaVM * vm,ArkUINodeHandle nativeNode,const Local<panda::ObjectRef> & obj)35 void LinearIndicatorBridge::SetIndicatorStyleSize(
36 EcmaVM* vm, ArkUINodeHandle nativeNode, const Local<panda::ObjectRef>& obj)
37 {
38 auto jsSpace = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "space"));
39 auto jsStrokeWidth = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "strokeWidth"));
40 auto jsStrokeRadius = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "strokeRadius"));
41
42 CalcDimension space;
43 if (ArkTSUtils::ParseJsLengthMetrics(vm, jsSpace, space) && GreatOrEqual(space.Value(), 0.0f) &&
44 space.Unit() != DimensionUnit::PERCENT) {
45 GetArkUINodeModifiers()->getLinearIndicatorModifier()->setLinearIndicatorIndicatorStyleSpace(
46 nativeNode, space.Value(), static_cast<int>(space.Unit()));
47 } else {
48 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleSpace(nativeNode);
49 }
50
51 CalcDimension strokeWidth;
52 if (ArkTSUtils::ParseJsLengthMetrics(vm, jsStrokeWidth, strokeWidth) && GreatOrEqual(strokeWidth.Value(), 0.0f) &&
53 strokeWidth.Unit() != DimensionUnit::PERCENT) {
54 GetArkUINodeModifiers()->getLinearIndicatorModifier()->setLinearIndicatorIndicatorStyleStrokeWidth(
55 nativeNode, strokeWidth.Value(), static_cast<int>(strokeWidth.Unit()));
56 } else {
57 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleStrokeWidth(
58 nativeNode);
59 }
60
61 CalcDimension strokeRadius;
62 if (ArkTSUtils::ParseJsLengthMetrics(vm, jsStrokeRadius, strokeRadius) &&
63 GreatOrEqual(strokeRadius.Value(), 0.0f) && strokeRadius.Unit() != DimensionUnit::PERCENT) {
64 GetArkUINodeModifiers()->getLinearIndicatorModifier()->setLinearIndicatorIndicatorStyleStrokeRadius(
65 nativeNode, strokeRadius.Value(), static_cast<int>(strokeRadius.Unit()));
66 } else {
67 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleStrokeRadius(
68 nativeNode);
69 }
70 }
71
SetIndicatorStyleColor(EcmaVM * vm,ArkUINodeHandle nativeNode,const Local<panda::ObjectRef> & obj)72 void LinearIndicatorBridge::SetIndicatorStyleColor(
73 EcmaVM* vm, ArkUINodeHandle nativeNode, const Local<panda::ObjectRef>& obj)
74 {
75 auto jsTrackBackgroundColor = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "trackBackgroundColor"));
76 auto jsTrackColor = obj->Get(vm, panda::StringRef::NewFromUtf8(vm, "trackColor"));
77
78 Color trackBackgroundColor;
79 if (ParseColorMetricsToColor(vm, jsTrackBackgroundColor, trackBackgroundColor)) {
80 GetArkUINodeModifiers()->getLinearIndicatorModifier()->setLinearIndicatorIndicatorStyleTrackBackgroundColor(
81 nativeNode, trackBackgroundColor.GetValue());
82 } else {
83 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleTrackBackgroundColor(
84 nativeNode);
85 }
86
87 Color trackColor;
88 if (ParseColorMetricsToColor(vm, jsTrackColor, trackColor)) {
89 GetArkUINodeModifiers()->getLinearIndicatorModifier()->setLinearIndicatorIndicatorStyleTrackColor(
90 nativeNode, trackColor.GetValue());
91 } else {
92 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleTrackColor(nativeNode);
93 }
94 }
95
SetIndicatorStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)96 ArkUINativeModuleValue LinearIndicatorBridge::SetIndicatorStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
97 {
98 EcmaVM* vm = runtimeCallInfo->GetVM();
99 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
100 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
101 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
102 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
103 if (secondArg->IsObject(vm)) {
104 Local<panda::ObjectRef> obj = secondArg->ToObject(vm);
105 SetIndicatorStyleSize(vm, nativeNode, obj);
106 SetIndicatorStyleColor(vm, nativeNode, obj);
107 } else {
108 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleSpace(nativeNode);
109 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleStrokeWidth(
110 nativeNode);
111 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleStrokeRadius(
112 nativeNode);
113 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleTrackBackgroundColor(
114 nativeNode);
115 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleTrackColor(nativeNode);
116 }
117 return panda::JSValueRef::Undefined(vm);
118 }
119
ResetIndicatorStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)120 ArkUINativeModuleValue LinearIndicatorBridge::ResetIndicatorStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
121 {
122 EcmaVM* vm = runtimeCallInfo->GetVM();
123 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
124 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
125 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
126 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleSpace(nativeNode);
127 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleStrokeWidth(nativeNode);
128 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleStrokeRadius(nativeNode);
129 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleTrackBackgroundColor(
130 nativeNode);
131 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorStyleTrackColor(nativeNode);
132 return panda::JSValueRef::Undefined(vm);
133 }
134
SetIndicatorLoop(ArkUIRuntimeCallInfo * runtimeCallInfo)135 ArkUINativeModuleValue LinearIndicatorBridge::SetIndicatorLoop(ArkUIRuntimeCallInfo* runtimeCallInfo)
136 {
137 EcmaVM* vm = runtimeCallInfo->GetVM();
138 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
139 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
140 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
141 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
142 bool SetIndicatorLoop = true;
143 if (secondArg->IsBoolean()) {
144 SetIndicatorLoop = secondArg->ToBoolean(vm)->Value();
145 GetArkUINodeModifiers()->getLinearIndicatorModifier()->setLinearIndicatorIndicatorLoop(
146 nativeNode, SetIndicatorLoop);
147 } else {
148 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorLoop(nativeNode);
149 }
150 return panda::JSValueRef::Undefined(vm);
151 }
152
ResetIndicatorLoop(ArkUIRuntimeCallInfo * runtimeCallInfo)153 ArkUINativeModuleValue LinearIndicatorBridge::ResetIndicatorLoop(ArkUIRuntimeCallInfo* runtimeCallInfo)
154 {
155 EcmaVM* vm = runtimeCallInfo->GetVM();
156 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
157 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
158 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
159 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorIndicatorLoop(nativeNode);
160 return panda::JSValueRef::Undefined(vm);
161 }
162
SetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)163 ArkUINativeModuleValue LinearIndicatorBridge::SetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
164 {
165 EcmaVM* vm = runtimeCallInfo->GetVM();
166 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
167 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
168 Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
169 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
170 auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
171 CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
172 if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
173 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorOnChange(nativeNode);
174 return panda::JSValueRef::Undefined(vm);
175 }
176 panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
177 std::function<void(int index, float progress)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
178 int index, float progress) {
179 panda::LocalScope pandaScope(vm);
180 panda::TryCatch trycatch(vm);
181 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
182 panda::Local<panda::JSValueRef> params[NUM_2] = { panda::NumberRef::New(vm, index),
183 panda::NumberRef::New(vm, progress) };
184 func->Call(vm, func.ToLocal(), params, NUM_2);
185 };
186 GetArkUINodeModifiers()->getLinearIndicatorModifier()->setLinearIndicatorOnChange(
187 nativeNode, reinterpret_cast<void*>(&callback));
188 return panda::JSValueRef::Undefined(vm);
189 }
190
ResetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)191 ArkUINativeModuleValue LinearIndicatorBridge::ResetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
192 {
193 EcmaVM* vm = runtimeCallInfo->GetVM();
194 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
195 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
196 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
197 GetArkUINodeModifiers()->getLinearIndicatorModifier()->resetLinearIndicatorOnChange(nativeNode);
198 return panda::JSValueRef::Undefined(vm);
199 }
200
ParseColorMetricsToColor(const EcmaVM * vm,const Local<JSValueRef> & jsValue,Color & result)201 bool LinearIndicatorBridge::ParseColorMetricsToColor(const EcmaVM* vm, const Local<JSValueRef>& jsValue, Color& result)
202 {
203 if (!jsValue->IsObject(vm)) {
204 return false;
205 }
206 auto obj = jsValue->ToObject(vm);
207 auto toNumericProp = obj->Get(vm, "toNumeric");
208 if (toNumericProp->IsFunction(vm)) {
209 panda::Local<panda::FunctionRef> func = toNumericProp;
210 auto colorVal = func->Call(vm, obj, nullptr, 0);
211 result.SetValue(colorVal->Uint32Value(vm));
212 return true;
213 }
214 return false;
215 }
216
217 } // namespace OHOS::Ace::NG
218