• 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     ArkUIRatingStyleStruct resObj;
117     std::string backgroundUri;
118     RefPtr<ResourceObject> backgroundResObj;
119     if (!ArkTSUtils::ParseJsMedia(vm, backgroundUriArg, backgroundUri, backgroundResObj)) {
120         ArkTSUtils::ParseJsString(vm, backgroundUriArg, backgroundUri, backgroundResObj);
121     }
122     resObj.backgroundResObj = AceType::RawPtr(backgroundResObj);
123 
124     std::string foregroundUri;
125     RefPtr<ResourceObject> foregroundResObj;
126     if (!ArkTSUtils::ParseJsMedia(vm, foregroundUriArg, foregroundUri, foregroundResObj)) {
127         ArkTSUtils::ParseJsString(vm, foregroundUriArg, foregroundUri, foregroundResObj);
128     }
129     resObj.foregroundResObj = AceType::RawPtr(foregroundResObj);
130 
131     std::string secondaryUri;
132     RefPtr<ResourceObject> secondaryResObj;
133     if (!ArkTSUtils::ParseJsMedia(vm, secondaryUriArg, secondaryUri, secondaryResObj)) {
134         ArkTSUtils::ParseJsString(vm, secondaryUriArg, secondaryUri, secondaryResObj);
135     }
136     resObj.secondaryResObj = AceType::RawPtr(secondaryResObj);
137 
138     if (secondaryUri.empty() && !backgroundUri.empty()) {
139         secondaryUri = backgroundUri;
140         resObj.secondaryResObj = AceType::RawPtr(backgroundResObj);
141     }
142 
143     GetArkUINodeModifiers()->getRatingModifier()->setStarStylePtr(
144         nativeNode, backgroundUri.c_str(), foregroundUri.c_str(), secondaryUri.c_str(), resObj);
145     return panda::JSValueRef::Undefined(vm);
146 }
147 
ResetStarStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)148 ArkUINativeModuleValue RatingBridge::ResetStarStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
149 {
150     EcmaVM* vm = runtimeCallInfo->GetVM();
151     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
152     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
153     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
154     GetArkUINodeModifiers()->getRatingModifier()->resetStarStyle(nativeNode);
155     return panda::JSValueRef::Undefined(vm);
156 }
157 
SetContentModifierBuilder(ArkUIRuntimeCallInfo * runtimeCallInfo)158 ArkUINativeModuleValue RatingBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo)
159 {
160     EcmaVM* vm = runtimeCallInfo->GetVM();
161     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
162     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
163     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
164     auto* frameNode = reinterpret_cast<FrameNode*>(firstArg->ToNativePointer(vm)->Value());
165     if (!secondArg->IsObject(vm)) {
166         RatingModelNG::SetBuilderFunc(frameNode, nullptr);
167         return panda::JSValueRef::Undefined(vm);
168     }
169     panda::CopyableGlobal<panda::ObjectRef> obj(vm, secondArg);
170     auto containerId = Container::CurrentId();
171     RatingModelNG::SetBuilderFunc(frameNode,
172         [vm, frameNode, obj = std::move(obj), containerId](
173             RatingConfiguration config) -> RefPtr<FrameNode> {
174             ContainerScope scope(containerId);
175             auto context = ArkTSUtils::GetContext(vm);
176             CHECK_EQUAL_RETURN(context->IsUndefined(), true, nullptr);
177             const char* keys[] = { "stars", "indicator", "rating", "stepSize", "enabled", "triggerChange" };
178             Local<JSValueRef> values[] = { panda::NumberRef::New(vm, config.starNum_),
179                 panda::BooleanRef::New(vm, config.isIndicator_),
180                 panda::NumberRef::New(vm, config.rating_),
181                 panda::NumberRef::New(vm, config.stepSize_),
182                 panda::BooleanRef::New(vm, config.enabled_),
183                 panda::FunctionRef::New(vm, JsRatingChangeCallback) };
184             auto rating = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
185             rating->SetNativePointerFieldCount(vm, 1);
186             rating->SetNativePointerField(vm, 0, static_cast<void*>(frameNode));
187             panda::Local<panda::JSValueRef> params[NUM_2] = { context, rating };
188             LocalScope pandaScope(vm);
189             panda::TryCatch trycatch(vm);
190             auto makeFunc = obj.ToLocal()->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode"));
191             CHECK_EQUAL_RETURN(makeFunc->IsFunction(vm), false, nullptr);
192             panda::Local<panda::FunctionRef> func = makeFunc;
193             auto result = func->Call(vm, obj.ToLocal(), params, 2);
194             JSNApi::ExecutePendingJob(vm);
195             CHECK_EQUAL_RETURN(result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm), true, nullptr);
196             panda::Local<panda::JSValueRef> nodeptr =
197                 result->ToObject(vm)->Get(vm, panda::StringRef::NewFromUtf8(vm, NODEPTR_OF_UINODE));
198             CHECK_EQUAL_RETURN(nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull(), true, nullptr);
199             auto* frameNode = reinterpret_cast<FrameNode*>(nodeptr->ToNativePointer(vm)->Value());
200             CHECK_NULL_RETURN(frameNode, nullptr);
201             return AceType::Claim(frameNode);
202         });
203     return panda::JSValueRef::Undefined(vm);
204 }
205 
SetRatingOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)206 ArkUINativeModuleValue RatingBridge::SetRatingOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
207 {
208     EcmaVM* vm = runtimeCallInfo->GetVM();
209     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
210     CHECK_EQUAL_RETURN(runtimeCallInfo->GetArgsNumber() != NUM_3, true, panda::JSValueRef::Undefined(vm));
211     Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
212     Local<JSValueRef> ratingArg = runtimeCallInfo->GetCallArgRef(NUM_1);
213     Local<JSValueRef> indicatorArg = runtimeCallInfo->GetCallArgRef(NUM_2);
214     auto pointer = nodeArg->ToNativePointer(vm);
215     CHECK_EQUAL_RETURN(pointer.IsEmpty(), true, panda::JSValueRef::Undefined(vm));
216     auto nativeNode = nodePtr(pointer->Value());
217     CHECK_NULL_RETURN(nativeNode, panda::JSValueRef::Undefined(vm));
218 
219     double rating = 0.0;
220     if (!ratingArg->IsNull() && ratingArg->IsNumber()) {
221         rating = ratingArg->ToNumber(vm)->Value();
222     }
223     if (LessNotEqual(rating, 0.0)) {
224         rating = 0.0;
225     }
226 
227     int32_t indicator = 0;
228     if (!indicatorArg->IsNull() && indicatorArg->IsBoolean()) {
229         indicator = indicatorArg->ToBoolean(vm)->Value();
230     }
231     GetArkUINodeModifiers()->getRatingModifier()->setRatingOptions(
232         nativeNode, rating, indicator);
233     return panda::JSValueRef::Undefined(vm);
234 }
235 
SetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)236 ArkUINativeModuleValue RatingBridge::SetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
237 {
238     EcmaVM* vm = runtimeCallInfo->GetVM();
239     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
240     uint32_t argsNumber = runtimeCallInfo->GetArgsNumber();
241     if (argsNumber != NUM_2) {
242         return panda::JSValueRef::Undefined(vm);
243     }
244     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
245     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
246     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
247     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
248     CHECK_NULL_RETURN(frameNode, panda::NativePointerRef::New(vm, nullptr));
249     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
250         GetArkUINodeModifiers()->getRatingModifier()->resetOnChange(nativeNode);
251         return panda::JSValueRef::Undefined(vm);
252     }
253     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
254     std::function<void(const std::string&)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
255                                                            const std::string& star) {
256         panda::LocalScope pandaScope(vm);
257         panda::TryCatch trycatch(vm);
258         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
259         panda::Local<panda::NumberRef> starParam = panda::NumberRef::New(vm, StringUtils::StringToDouble(star));
260         panda::Local<panda::JSValueRef> params[PARAM_ARR_LENGTH_1] = { starParam };
261         func->Call(vm, func.ToLocal(), params, PARAM_ARR_LENGTH_1);
262     };
263     GetArkUINodeModifiers()->getRatingModifier()->setOnChange(nativeNode, reinterpret_cast<void*>(&callback));
264     return panda::JSValueRef::Undefined(vm);
265 }
266 
ResetOnChange(ArkUIRuntimeCallInfo * runtimeCallInfo)267 ArkUINativeModuleValue RatingBridge::ResetOnChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
268 {
269     EcmaVM* vm = runtimeCallInfo->GetVM();
270     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
271     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
272     auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
273     GetArkUINodeModifiers()->getRatingModifier()->resetOnChange(nativeNode);
274     return panda::JSValueRef::Undefined(vm);
275 }
276 
277 } // namespace OHOS::Ace::NG