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