• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_rating_bridge.h"
16 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
17 #include "core/components_ng/base/frame_node.h"
18 #include "core/components_ng/pattern/rating/rating_model_ng.h"
19 
20 namespace OHOS::Ace::NG {
21 constexpr double STEPS_DEFAULT = 0.5;
22 constexpr double STEPS_MIN_SIZE = 0.1;
23 constexpr int32_t STARS_DEFAULT = 5;
24 constexpr int NUM_0 = 0;
25 constexpr int NUM_1 = 1;
26 constexpr int NUM_2 = 2;
27 constexpr int NUM_3 = 3;
28 constexpr int PARAM_ARR_LENGTH_1 = 1;
29 const char* NODEPTR_OF_UINODE = "nodePtr_";
JsRatingChangeCallback(panda::JsiRuntimeCallInfo * runtimeCallInfo)30 panda::Local<panda::JSValueRef> JsRatingChangeCallback(panda::JsiRuntimeCallInfo* runtimeCallInfo)
31 {
32     auto vm = runtimeCallInfo->GetVM();
33     int32_t argc = static_cast<int32_t>(runtimeCallInfo->GetArgsNumber());
34     if (argc != 1) {
35         return panda::JSValueRef::Undefined(vm);
36     }
37     auto firstArg = runtimeCallInfo->GetCallArgRef(0);
38     if (!firstArg->IsNumber()) {
39         return panda::JSValueRef::Undefined(vm);
40     }
41     double value = firstArg->ToNumber(vm)->Value();
42     auto ref = runtimeCallInfo->GetThisRef();
43     auto obj = ref->ToObject(vm);
44     if (obj->GetNativePointerFieldCount(vm) < 1) {
45         return panda::JSValueRef::Undefined(vm);
46     }
47     auto frameNode = static_cast<FrameNode*>(obj->GetNativePointerField(vm, 0));
48     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
49     RatingModelNG::SetChangeValue(frameNode, value);
50     return panda::JSValueRef::Undefined(vm);
51 }
52 
SetStars(ArkUIRuntimeCallInfo * runtimeCallInfo)53 ArkUINativeModuleValue RatingBridge::SetStars(ArkUIRuntimeCallInfo* runtimeCallInfo)
54 {
55     EcmaVM* vm = runtimeCallInfo->GetVM();
56     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
57     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
58     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
59     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
60     int32_t stars = secondArg->Int32Value(vm);
61     if (stars <= 0) {
62         stars = STARS_DEFAULT;
63     }
64     GetArkUINodeModifiers()->getRatingModifier()->setStars(nativeNode, stars);
65     return panda::JSValueRef::Undefined(vm);
66 }
67 
ResetStars(ArkUIRuntimeCallInfo * runtimeCallInfo)68 ArkUINativeModuleValue RatingBridge::ResetStars(ArkUIRuntimeCallInfo* runtimeCallInfo)
69 {
70     EcmaVM* vm = runtimeCallInfo->GetVM();
71     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
72     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
73     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
74     GetArkUINodeModifiers()->getRatingModifier()->resetStars(nativeNode);
75     return panda::JSValueRef::Undefined(vm);
76 }
SetRatingStepSize(ArkUIRuntimeCallInfo * runtimeCallInfo)77 ArkUINativeModuleValue RatingBridge::SetRatingStepSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
78 {
79     EcmaVM* vm = runtimeCallInfo->GetVM();
80     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
81     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
82     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
83     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
84 
85     if (secondArg->IsNull() || !secondArg->IsNumber()) {
86         GetArkUINodeModifiers()->getRatingModifier()->resetRatingStepSize(nativeNode);
87         return panda::JSValueRef::Undefined(vm);
88     }
89     auto steps = secondArg->ToNumber(vm)->Value();
90     if (LessNotEqual(steps, STEPS_MIN_SIZE)) {
91         steps = STEPS_DEFAULT;
92     }
93     GetArkUINodeModifiers()->getRatingModifier()->setRatingStepSize(nativeNode, steps);
94     return panda::JSValueRef::Undefined(vm);
95 }
96 
ResetRatingStepSize(ArkUIRuntimeCallInfo * runtimeCallInfo)97 ArkUINativeModuleValue RatingBridge::ResetRatingStepSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
98 {
99     EcmaVM* vm = runtimeCallInfo->GetVM();
100     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
101     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
102     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
103     GetArkUINodeModifiers()->getRatingModifier()->resetRatingStepSize(nativeNode);
104     return panda::JSValueRef::Undefined(vm);
105 }
106 
SetStarStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)107 ArkUINativeModuleValue RatingBridge::SetStarStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
108 {
109     EcmaVM* vm = runtimeCallInfo->GetVM();
110     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
111     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
112     Local<JSValueRef> backgroundUriArg = runtimeCallInfo->GetCallArgRef(NUM_1);
113     Local<JSValueRef> foregroundUriArg = runtimeCallInfo->GetCallArgRef(NUM_2);
114     Local<JSValueRef> secondaryUriArg = runtimeCallInfo->GetCallArgRef(NUM_3);
115     auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
116 
117     std::string backgroundUri;
118     if (backgroundUriArg->IsString(vm)) {
119         backgroundUri = backgroundUriArg->ToString(vm)->ToString(vm);
120     }
121 
122     std::string foregroundUri;
123     if (foregroundUriArg->IsString(vm)) {
124         foregroundUri = foregroundUriArg->ToString(vm)->ToString(vm);
125     }
126 
127     std::string secondaryUri;
128     if (secondaryUriArg->IsString(vm)) {
129         secondaryUri = secondaryUriArg->ToString(vm)->ToString(vm);
130     }
131 
132     if (secondaryUri.empty() && !backgroundUri.empty()) {
133         secondaryUri = backgroundUri;
134     }
135 
136     GetArkUINodeModifiers()->getRatingModifier()->setStarStyle(
137         nativeNode, backgroundUri.c_str(), foregroundUri.c_str(), secondaryUri.c_str());
138     return panda::JSValueRef::Undefined(vm);
139 }
140 
ResetStarStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)141 ArkUINativeModuleValue RatingBridge::ResetStarStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
142 {
143     EcmaVM* vm = runtimeCallInfo->GetVM();
144     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
145     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
146     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
147     GetArkUINodeModifiers()->getRatingModifier()->resetStarStyle(nativeNode);
148     return panda::JSValueRef::Undefined(vm);
149 }
150 
SetContentModifierBuilder(ArkUIRuntimeCallInfo * runtimeCallInfo)151 ArkUINativeModuleValue RatingBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo)
152 {
153     EcmaVM* vm = runtimeCallInfo->GetVM();
154     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
155     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
156     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
157     auto* frameNode = reinterpret_cast<FrameNode*>(firstArg->ToNativePointer(vm)->Value());
158     if (!secondArg->IsObject(vm)) {
159         RatingModelNG::SetBuilderFunc(frameNode, nullptr);
160         return panda::JSValueRef::Undefined(vm);
161     }
162     panda::CopyableGlobal<panda::ObjectRef> obj(vm, secondArg);
163     auto containerId = Container::CurrentId();
164     RatingModelNG::SetBuilderFunc(frameNode,
165         [vm, frameNode, obj = std::move(obj), containerId](
166             RatingConfiguration config) -> RefPtr<FrameNode> {
167             ContainerScope scope(containerId);
168             auto context = ArkTSUtils::GetContext(vm);
169             CHECK_EQUAL_RETURN(context->IsUndefined(), true, nullptr);
170             const char* keys[] = { "stars", "indicator", "rating", "stepSize", "enabled", "triggerChange" };
171             Local<JSValueRef> values[] = { panda::NumberRef::New(vm, config.starNum_),
172                 panda::BooleanRef::New(vm, config.isIndicator_),
173                 panda::NumberRef::New(vm, config.rating_),
174                 panda::NumberRef::New(vm, config.stepSize_),
175                 panda::BooleanRef::New(vm, config.enabled_),
176                 panda::FunctionRef::New(vm, JsRatingChangeCallback) };
177             auto rating = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
178             rating->SetNativePointerFieldCount(vm, 1);
179             rating->SetNativePointerField(vm, 0, static_cast<void*>(frameNode));
180             panda::Local<panda::JSValueRef> params[NUM_2] = { context, rating };
181             LocalScope pandaScope(vm);
182             panda::TryCatch trycatch(vm);
183             auto makeFunc = obj.ToLocal()->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode"));
184             CHECK_EQUAL_RETURN(makeFunc->IsFunction(vm), false, nullptr);
185             panda::Local<panda::FunctionRef> func = makeFunc;
186             auto result = func->Call(vm, obj.ToLocal(), params, 2);
187             JSNApi::ExecutePendingJob(vm);
188             CHECK_EQUAL_RETURN(result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm), true, nullptr);
189             panda::Local<panda::JSValueRef> nodeptr =
190                 result->ToObject(vm)->Get(vm, panda::StringRef::NewFromUtf8(vm, NODEPTR_OF_UINODE));
191             CHECK_EQUAL_RETURN(nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull(), true, nullptr);
192             auto* frameNode = reinterpret_cast<FrameNode*>(nodeptr->ToNativePointer(vm)->Value());
193             CHECK_NULL_RETURN(frameNode, nullptr);
194             return AceType::Claim(frameNode);
195         });
196     return panda::JSValueRef::Undefined(vm);
197 }
198 
SetRatingOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)199 ArkUINativeModuleValue RatingBridge::SetRatingOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
200 {
201     EcmaVM* vm = runtimeCallInfo->GetVM();
202     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
203     CHECK_EQUAL_RETURN(runtimeCallInfo->GetArgsNumber() != NUM_3, true, panda::JSValueRef::Undefined(vm));
204     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
205     Local<JSValueRef> ratingArg = runtimeCallInfo->GetCallArgRef(NUM_1);
206     Local<JSValueRef> indicatorArg = runtimeCallInfo->GetCallArgRef(NUM_2);
207     auto pointer = nodeArg->ToNativePointer(vm);
208     CHECK_EQUAL_RETURN(pointer.IsEmpty(), true, panda::JSValueRef::Undefined(vm));
209     auto nativeNode = nodePtr(pointer->Value());
210     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
211 
212     double rating = 0.0;
213     if (!ratingArg->IsNull() && ratingArg->IsNumber()) {
214         rating = ratingArg->ToNumber(vm)->Value();
215     }
216     if (LessNotEqual(rating, 0.0)) {
217         rating = 0.0;
218     }
219 
220     int32_t indicator = 0;
221     if (!indicatorArg->IsNull() && indicatorArg->IsBoolean()) {
222         indicator = indicatorArg->ToBoolean(vm)->Value();
223     }
224     GetArkUINodeModifiers()->getRatingModifier()->setRatingOptions(
225         nativeNode, rating, indicator);
226     return panda::JSValueRef::Undefined(vm);
227 }
228 
SetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)229 ArkUINativeModuleValue RatingBridge::SetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
230 {
231     EcmaVM* vm = runtimeCallInfo->GetVM();
232     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
233     int32_t argsNumber = runtimeCallInfo->GetArgsNumber();
234     if (argsNumber != NUM_2) {
235         return panda::JSValueRef::Undefined(vm);
236     }
237     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
238     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
239     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
240     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
241     CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
242     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
243         GetArkUINodeModifiers()->getRatingModifier()->resetOnChange(nativeNode);
244         return panda::JSValueRef::Undefined(vm);
245     }
246     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
247     std::function<void(const std::string&)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
248                                                            const std::string& star) {
249         panda::LocalScope pandaScope(vm);
250         panda::TryCatch trycatch(vm);
251         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
252         panda::Local<panda::NumberRef> starParam = panda::NumberRef::New(vm, std::stod(star));
253         panda::Local<panda::JSValueRef> params[PARAM_ARR_LENGTH_1] = { starParam };
254         func->Call(vm, func.ToLocal(), params, PARAM_ARR_LENGTH_1);
255     };
256     GetArkUINodeModifiers()->getRatingModifier()->setOnChange(nativeNode, reinterpret_cast<void*>(&callback));
257     return panda::JSValueRef::Undefined(vm);
258 }
259 
ResetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)260 ArkUINativeModuleValue RatingBridge::ResetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
261 {
262     EcmaVM* vm = runtimeCallInfo->GetVM();
263     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
264     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
265     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
266     GetArkUINodeModifiers()->getRatingModifier()->resetOnChange(nativeNode);
267     return panda::JSValueRef::Undefined(vm);
268 }
269 
270 } // namespace OHOS::Ace::NG