• 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 "arc_swiper_napi.h"
17 
18 #include "arc_swiper_controller.h"
19 #include "arc_swiper_indicator.h"
20 #include "ext_napi_utils.h"
21 
22 #include "bridge/declarative_frontend/engine/js_converter.h"
23 #include "bridge/declarative_frontend/jsview/js_linear_gradient.h"
24 #include "core/components/swiper/swiper_component.h"
25 #include "core/components/swiper/swiper_indicator_theme.h"
26 #include "core/components_ng/pattern/swiper/swiper_model_ng.h"
27 
28 extern const char _binary_arkui_arcswiper_abc_start[];
29 extern const char _binary_arkui_arcswiper_abc_end[];
30 
31 namespace OHOS::Ace {
32 namespace {
33 static constexpr const size_t MAX_ARG_NUM = 10;
34 static constexpr const int32_t DEFAULT_DURATION = 400;
35 static constexpr const int32_t THREE_CLOCK_DIRECTION = 0;
36 static constexpr const int32_t SIX_CLOCK_DIRECTION = 1;
37 static constexpr const int32_t NINE_CLOCK_DIRECTION = 2;
38 } // namespace
39 
40 std::unique_ptr<SwiperModel> SwiperModel::instance_ = nullptr;
41 std::mutex SwiperModel::mutex_;
42 
GetInstance()43 SwiperModel* SwiperModel::GetInstance()
44 {
45     if (!instance_) {
46         std::lock_guard<std::mutex> lock(mutex_);
47         if (!instance_) {
48             instance_.reset(new NG::SwiperModelNG());
49         }
50     }
51     return instance_.get();
52 }
53 
JsCreate(napi_env env,napi_callback_info info)54 napi_value JsCreate(napi_env env, napi_callback_info info)
55 {
56     auto controller = SwiperModel::GetInstance()->Create(true);
57     SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::ARC_DOT);
58 
59     size_t argc = MAX_ARG_NUM;
60     napi_value argv[MAX_ARG_NUM] = { nullptr };
61     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
62     if (argc > 0 && ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_object)) {
63         NG::JsArcSwiperController* jsController = nullptr;
64         napi_unwrap(env, argv[0], (void**)&jsController);
65         if (jsController) {
66             jsController->SetController(controller);
67         }
68     }
69 
70     return ExtNapiUtils::CreateNull(env);
71 }
72 
JsIndex(napi_env env,napi_callback_info info)73 napi_value JsIndex(napi_env env, napi_callback_info info)
74 {
75     size_t argc = MAX_ARG_NUM;
76     napi_value argv[MAX_ARG_NUM] = { nullptr };
77     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
78     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
79 
80     int32_t index = 0;
81     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_number)) {
82         index = ExtNapiUtils::GetCInt32(env, argv[0]);
83     }
84     index = index < 0 ? 0 : index;
85     SwiperModel::GetInstance()->SetIndex(index);
86 
87     return ExtNapiUtils::CreateNull(env);
88 }
89 
GetArcDotIndicatorInfo(napi_env env,napi_value value)90 SwiperArcDotParameters GetArcDotIndicatorInfo(napi_env env, napi_value value)
91 {
92     SwiperArcDotParameters swiperParameters;
93     auto pipelineContext = PipelineBase::GetCurrentContext();
94     CHECK_NULL_RETURN(pipelineContext, swiperParameters);
95     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
96     CHECK_NULL_RETURN(swiperIndicatorTheme, swiperParameters);
97     NG::JsArcSwiperIndicator* indicator = nullptr;
98     napi_unwrap(env, value, (void**)&indicator);
99 
100     // parse arcDirection
101     swiperParameters.arcDirection = SwiperArcDirection::SIX_CLOCK_DIRECTION;
102     if (indicator && indicator->HasArcDirection()) {
103         swiperParameters.arcDirection = indicator->GetArcDirection();
104     }
105     // parse itemColor
106     swiperParameters.itemColor =
107         (indicator && indicator->HasItemColor()) ? indicator->GetItemColor() : swiperIndicatorTheme->GetArcItemColor();
108     // parse selectedItemColor
109     swiperParameters.selectedItemColor = (indicator && indicator->HasSelectedItemColor())
110                                              ? indicator->GetSelectedItemColor()
111                                              : swiperIndicatorTheme->GetArcSelectedItemColor();
112     // parse containerColor
113     swiperParameters.containerColor = (indicator && indicator->HasContainerColor())
114                                           ? indicator->GetContainerColor()
115                                           : swiperIndicatorTheme->GetArcContainerColor();
116     // parse maskColor
117     swiperParameters.maskColor =
118         (indicator && indicator->HasMaskColor()) ? indicator->GetMaskColor() : swiperIndicatorTheme->GetArcMaskColor();
119 
120     return swiperParameters;
121 }
122 
JsIndicator(napi_env env,napi_callback_info info)123 napi_value JsIndicator(napi_env env, napi_callback_info info)
124 {
125     size_t argc = MAX_ARG_NUM;
126     napi_value argv[MAX_ARG_NUM] = { nullptr };
127     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
128     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
129 
130     bool showIndicator = true;
131     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_boolean)) {
132         showIndicator = ExtNapiUtils::GetBool(env, argv[0]);
133     } else {
134         SwiperModel::GetInstance()->SetIndicatorIsBoolean(false);
135         SwiperArcDotParameters swiperParameters = GetArcDotIndicatorInfo(env, argv[0]);
136         SwiperModel::GetInstance()->SetArcDotIndicatorStyle(swiperParameters);
137     }
138 
139     SwiperModel::GetInstance()->SetShowIndicator(showIndicator);
140 
141     return ExtNapiUtils::CreateNull(env);
142 }
143 
JsDuration(napi_env env,napi_callback_info info)144 napi_value JsDuration(napi_env env, napi_callback_info info)
145 {
146     size_t argc = MAX_ARG_NUM;
147     napi_value argv[MAX_ARG_NUM] = { nullptr };
148     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
149     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
150 
151     int32_t duration = DEFAULT_DURATION;
152     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_number)) {
153         duration = ExtNapiUtils::GetCInt32(env, argv[0]);
154     }
155     duration = duration < 0 ? DEFAULT_DURATION : duration;
156     SwiperModel::GetInstance()->SetDuration(duration);
157 
158     return ExtNapiUtils::CreateNull(env);
159 }
160 
JsVertical(napi_env env,napi_callback_info info)161 napi_value JsVertical(napi_env env, napi_callback_info info)
162 {
163     size_t argc = MAX_ARG_NUM;
164     napi_value argv[MAX_ARG_NUM] = { nullptr };
165     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
166     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
167 
168     bool isVertical = false;
169     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_boolean)) {
170         isVertical = ExtNapiUtils::GetBool(env, argv[0]);
171     }
172     SwiperModel::GetInstance()->SetDirection(isVertical ? Axis::VERTICAL : Axis::HORIZONTAL);
173 
174     return ExtNapiUtils::CreateNull(env);
175 }
176 
JsDisableSwipe(napi_env env,napi_callback_info info)177 napi_value JsDisableSwipe(napi_env env, napi_callback_info info)
178 {
179     size_t argc = MAX_ARG_NUM;
180     napi_value argv[MAX_ARG_NUM] = { nullptr };
181     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
182     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
183 
184     bool isDisable = false;
185     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_boolean)) {
186         isDisable = ExtNapiUtils::GetBool(env, argv[0]);
187     }
188     SwiperModel::GetInstance()->SetDisableSwipe(isDisable);
189 
190     return ExtNapiUtils::CreateNull(env);
191 }
192 
JsOnChange(napi_env env,napi_callback_info info)193 napi_value JsOnChange(napi_env env, napi_callback_info info)
194 {
195     size_t argc = MAX_ARG_NUM;
196     napi_value thisVal = nullptr;
197     napi_value argv[MAX_ARG_NUM] = { nullptr };
198     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
199     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
200     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
201         return ExtNapiUtils::CreateNull(env);
202     }
203     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
204     auto onChange = [asyncEvent](const BaseEventInfo* info) {
205         napi_handle_scope scope = nullptr;
206         napi_open_handle_scope(asyncEvent->GetEnv(), &scope);
207         CHECK_NULL_VOID(scope);
208 
209         const auto* eventInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
210         if (!eventInfo) {
211             napi_close_handle_scope(asyncEvent->GetEnv(), scope);
212             return;
213         }
214         napi_value arrayValue = ExtNapiUtils::CreateInt32(asyncEvent->GetEnv(), eventInfo->GetIndex());
215         napi_value argv[1] = { arrayValue };
216         asyncEvent->Call(1, argv);
217 
218         napi_close_handle_scope(asyncEvent->GetEnv(), scope);
219     };
220     SwiperModel::GetInstance()->SetOnChange(std::move(onChange));
221     return ExtNapiUtils::CreateNull(env);
222 }
223 
GetAnimationInfoJsObject(napi_env env,const AnimationCallbackInfo & info)224 napi_value GetAnimationInfoJsObject(napi_env env, const AnimationCallbackInfo& info)
225 {
226     napi_value jsObject = ExtNapiUtils::CreateObject(env);
227 
228     napi_value currentOffsetValue = ExtNapiUtils::CreateDouble(env, info.currentOffset.value_or(0.0f));
229     ExtNapiUtils::SetNamedProperty(env, jsObject, "currentOffset", currentOffsetValue);
230     napi_value targetOffsetValue = ExtNapiUtils::CreateDouble(env, info.targetOffset.value_or(0.0f));
231     ExtNapiUtils::SetNamedProperty(env, jsObject, "targetOffset", targetOffsetValue);
232     napi_value velocityValue = ExtNapiUtils::CreateDouble(env, info.velocity.value_or(0.0f));
233     ExtNapiUtils::SetNamedProperty(env, jsObject, "velocity", velocityValue);
234 
235     return jsObject;
236 }
237 
238 static  RefPtr<SwiperContentTransitionProxy> g_proxy = nullptr;
239 
FinishTransition(napi_env env,napi_callback_info info)240 static napi_value FinishTransition(napi_env env, napi_callback_info info)
241 {
242     void *data = nullptr;
243     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data));
244     auto proxy = AceType::Claim(reinterpret_cast<SwiperContentTransitionProxy *>(data));
245     if (proxy) {
246         proxy->FinishTransition();
247     }
248     data = nullptr;
249     g_proxy = nullptr;
250     return nullptr;
251 }
252 
GetSwiperContentTransitionProxyJsObject(napi_env env,const RefPtr<SwiperContentTransitionProxy> & proxy)253 static napi_value GetSwiperContentTransitionProxyJsObject(napi_env env,
254                                                           const RefPtr<SwiperContentTransitionProxy>& proxy)
255 {
256     napi_value jsObject = ExtNapiUtils::CreateObject(env);
257 
258     napi_value selectedIndex = ExtNapiUtils::CreateInt32(env, proxy->GetSelectedIndex());
259     ExtNapiUtils::SetNamedProperty(env, jsObject, "selectedIndex", selectedIndex);
260     napi_value index = ExtNapiUtils::CreateInt32(env, proxy->GetIndex());
261     ExtNapiUtils::SetNamedProperty(env, jsObject, "index", index);
262     napi_value position = ExtNapiUtils::CreateDouble(env, proxy->GetPosition());
263     ExtNapiUtils::SetNamedProperty(env, jsObject, "position", position);
264     napi_value mainAxisLength = ExtNapiUtils::CreateDouble(env, proxy->GetMainAxisLength());
265     ExtNapiUtils::SetNamedProperty(env, jsObject, "mainAxisLength", mainAxisLength);
266     const char* funName = "finishTransition";
267     napi_value funcValue = nullptr;
268     g_proxy = proxy;
269     funcValue = ExtNapiUtils::CreateFunction(env, funName, strlen(funName),
270                                              FinishTransition, (void*)Referenced::RawPtr(g_proxy));
271     ExtNapiUtils::SetNamedProperty(env, jsObject, funName, funcValue);
272 
273     return jsObject;
274 }
275 
JsOnAnimationStart(napi_env env,napi_callback_info info)276 napi_value JsOnAnimationStart(napi_env env, napi_callback_info info)
277 {
278     size_t argc = MAX_ARG_NUM;
279     napi_value thisVal = nullptr;
280     napi_value argv[MAX_ARG_NUM] = { nullptr };
281     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
282     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
283     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
284         return ExtNapiUtils::CreateNull(env);
285     }
286     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
287     auto onAnimationStart = [asyncEvent](int32_t index, int32_t targetIndex, const AnimationCallbackInfo& info) {
288         napi_env env = asyncEvent->GetEnv();
289         napi_handle_scope scope = nullptr;
290         napi_open_handle_scope(env, &scope);
291         CHECK_NULL_VOID(scope);
292 
293         napi_value arrayValueOne = ExtNapiUtils::CreateInt32(env, index);
294         napi_value arrayValueTwo = ExtNapiUtils::CreateInt32(env, targetIndex);
295         napi_value arrayValueThree = GetAnimationInfoJsObject(env, info);
296 
297         napi_value argv[3] = { arrayValueOne, arrayValueTwo, arrayValueThree };
298         asyncEvent->Call(3, argv);
299 
300         napi_close_handle_scope(env, scope);
301     };
302     SwiperModel::GetInstance()->SetOnAnimationStart(std::move(onAnimationStart));
303     return ExtNapiUtils::CreateNull(env);
304 }
305 
JsOnAnimationEnd(napi_env env,napi_callback_info info)306 napi_value JsOnAnimationEnd(napi_env env, napi_callback_info info)
307 {
308     size_t argc = MAX_ARG_NUM;
309     napi_value thisVal = nullptr;
310     napi_value argv[MAX_ARG_NUM] = { nullptr };
311     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
312     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
313     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
314         return ExtNapiUtils::CreateNull(env);
315     }
316     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
317     auto onAnimationEnd = [asyncEvent](int32_t index, const AnimationCallbackInfo& info) {
318         napi_env env = asyncEvent->GetEnv();
319         napi_handle_scope scope = nullptr;
320         napi_open_handle_scope(env, &scope);
321         CHECK_NULL_VOID(scope);
322 
323         napi_value arrayValueOne = ExtNapiUtils::CreateInt32(env, index);
324         napi_value arrayValueTwo = GetAnimationInfoJsObject(env, info);
325 
326         napi_value argv[2] = { arrayValueOne, arrayValueTwo };
327         asyncEvent->Call(2, argv);
328 
329         napi_close_handle_scope(env, scope);
330     };
331     SwiperModel::GetInstance()->SetOnAnimationEnd(std::move(onAnimationEnd));
332     return ExtNapiUtils::CreateNull(env);
333 }
334 
JsOnGestureSwipe(napi_env env,napi_callback_info info)335 napi_value JsOnGestureSwipe(napi_env env, napi_callback_info info)
336 {
337     size_t argc = MAX_ARG_NUM;
338     napi_value thisVal = nullptr;
339     napi_value argv[MAX_ARG_NUM] = { nullptr };
340     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
341     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
342     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
343         return ExtNapiUtils::CreateNull(env);
344     }
345     auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
346     auto onGestureSwipe = [asyncEvent](int32_t index, const AnimationCallbackInfo& info) {
347         napi_env env = asyncEvent->GetEnv();
348         napi_handle_scope scope = nullptr;
349         napi_open_handle_scope(env, &scope);
350         CHECK_NULL_VOID(scope);
351 
352         napi_value arrayValueOne = ExtNapiUtils::CreateInt32(env, index);
353         napi_value arrayValueTwo = GetAnimationInfoJsObject(env, info);
354 
355         napi_value argv[2] = { arrayValueOne, arrayValueTwo };
356         asyncEvent->Call(2, argv);
357 
358         napi_close_handle_scope(env, scope);
359     };
360     SwiperModel::GetInstance()->SetOnGestureSwipe(std::move(onGestureSwipe));
361     return ExtNapiUtils::CreateNull(env);
362 }
363 
JsSetDigitalCrownSensitivity(napi_env env,napi_callback_info info)364 napi_value JsSetDigitalCrownSensitivity(napi_env env, napi_callback_info info)
365 {
366     size_t argc = MAX_ARG_NUM;
367     napi_value thisVal = nullptr;
368     napi_value argv[MAX_ARG_NUM] = { nullptr };
369     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
370     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
371     int32_t sensitivity = 1;
372     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_number)) {
373         sensitivity = static_cast<int32_t>(ExtNapiUtils::GetCInt32(env, argv[0]));
374     }
375 
376     SwiperModel::GetInstance()->SetDigitalCrownSensitivity(sensitivity);
377     return ExtNapiUtils::CreateNull(env);
378 }
379 
JsSetEffectMode(napi_env env,napi_callback_info info)380 napi_value JsSetEffectMode(napi_env env, napi_callback_info info)
381 {
382     size_t argc = MAX_ARG_NUM;
383     napi_value thisVal = nullptr;
384     napi_value argv[MAX_ARG_NUM] = { nullptr };
385     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
386     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
387     EdgeEffect edgeEffect = EdgeEffect::SPRING;
388     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_number)) {
389         edgeEffect = static_cast<EdgeEffect>(ExtNapiUtils::GetCInt32(env, argv[0]));
390     }
391     if (static_cast<int>(edgeEffect) < static_cast<int>(EdgeEffect::SPRING) ||
392         static_cast<int>(edgeEffect) > static_cast<int>(EdgeEffect::NONE)) {
393             edgeEffect = EdgeEffect::SPRING;
394         }
395 
396     SwiperModel::GetInstance()->SetEdgeEffect(edgeEffect);
397     return ExtNapiUtils::CreateNull(env);
398 }
399 
JsSetCustomContentTransition(napi_env env,napi_callback_info info)400 napi_value JsSetCustomContentTransition(napi_env env, napi_callback_info info)
401 {
402     size_t argc = MAX_ARG_NUM;
403     napi_value thisVal = nullptr;
404     napi_value argv[MAX_ARG_NUM] = { nullptr };
405     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
406     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
407     if (!ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_object)) {
408         return ExtNapiUtils::CreateNull(env);
409     }
410 
411     SwiperContentAnimatedTransition transitionInfo;
412     napi_value jsTimeout = ExtNapiUtils::GetNamedProperty(env, argv[0], "timeout");
413     if (ExtNapiUtils::CheckTypeForNapiValue(env, jsTimeout, napi_number)) {
414         int32_t timeOut = static_cast<int32_t>(ExtNapiUtils::GetCInt32(env, jsTimeout));
415         transitionInfo.timeout = timeOut < 0 ? 0 : timeOut;
416     } else {
417         transitionInfo.timeout = 0;
418     }
419 
420     napi_value jsTransition = ExtNapiUtils::GetNamedProperty(env, argv[0], "transition");
421     if (ExtNapiUtils::CheckTypeForNapiValue(env, jsTransition, napi_function)) {
422         auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, jsTransition);
423         auto onTransition = [asyncEvent](const RefPtr<SwiperContentTransitionProxy>& proxy) {
424             napi_env env = asyncEvent->GetEnv();
425             napi_handle_scope scope = nullptr;
426             napi_open_handle_scope(env, &scope);
427             CHECK_NULL_VOID(scope);
428 
429             napi_value arrayValueOne = GetSwiperContentTransitionProxyJsObject(env, proxy);
430             napi_value argv[1] = { arrayValueOne };
431             asyncEvent->Call(1, argv);
432             napi_close_handle_scope(env, scope);
433         };
434         transitionInfo.transition = std::move(onTransition);
435     }
436     SwiperModel::GetInstance()->SetCustomContentTransition(transitionInfo);
437     return ExtNapiUtils::CreateNull(env);
438 }
439 
JsSetDisableTransitionAnimation(napi_env env,napi_callback_info info)440 napi_value JsSetDisableTransitionAnimation(napi_env env, napi_callback_info info)
441 {
442     size_t argc = MAX_ARG_NUM;
443     napi_value argv[MAX_ARG_NUM] = { nullptr };
444     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
445     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
446 
447     bool isDisable = false;
448     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_boolean)) {
449         isDisable = ExtNapiUtils::GetBool(env, argv[0]);
450     }
451     SwiperModel::GetInstance()->SetDisableTransitionAnimation(isDisable);
452 
453     return ExtNapiUtils::CreateNull(env);
454 }
455 
ShowNext(napi_env env,napi_callback_info info)456 napi_value ShowNext(napi_env env, napi_callback_info info)
457 {
458     napi_value thisVar = nullptr;
459     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, NULL));
460     NG::JsArcSwiperController* controller = nullptr;
461     napi_unwrap(env, thisVar, (void**)&controller);
462     napi_value objectValue = ExtNapiUtils::CreateNull(env);
463     CHECK_NULL_RETURN(controller, objectValue);
464     controller->ShowNext();
465     return objectValue;
466 }
467 
ShowPrevious(napi_env env,napi_callback_info info)468 napi_value ShowPrevious(napi_env env, napi_callback_info info)
469 {
470     napi_value thisVar = nullptr;
471     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, NULL));
472     NG::JsArcSwiperController* controller = nullptr;
473     napi_unwrap(env, thisVar, (void**)&controller);
474     napi_value objectValue = ExtNapiUtils::CreateNull(env);
475     CHECK_NULL_RETURN(controller, objectValue);
476     controller->ShowPrevious();
477     return objectValue;
478 }
479 
FinishAnimation(napi_env env,napi_callback_info info)480 napi_value FinishAnimation(napi_env env, napi_callback_info info)
481 {
482     size_t argc = MAX_ARG_NUM;
483     napi_value thisVal = nullptr;
484     napi_value argv[MAX_ARG_NUM] = { nullptr };
485     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
486     NG::JsArcSwiperController* controller = nullptr;
487     napi_unwrap(env, thisVal, (void**)&controller);
488     napi_value objectValue = ExtNapiUtils::CreateNull(env);
489     CHECK_NULL_RETURN(controller, objectValue);
490 
491     CommonFunc onFinish = nullptr;
492     if (argc > 0 && ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_function)) {
493         auto asyncEvent = std::make_shared<NapiAsyncEvent>(env, argv[0]);
494         onFinish = [asyncEvent]() {
495             napi_handle_scope scope = nullptr;
496             napi_open_handle_scope(asyncEvent->GetEnv(), &scope);
497             CHECK_NULL_VOID(scope);
498             asyncEvent->Call(0, nullptr);
499             napi_close_handle_scope(asyncEvent->GetEnv(), scope);
500         };
501     }
502     controller->FinishAnimation(onFinish);
503 
504     return objectValue;
505 }
506 
ArcSwiperControllerConstructor(napi_env env,napi_callback_info info)507 napi_value ArcSwiperControllerConstructor(napi_env env, napi_callback_info info)
508 {
509     napi_value thisVar = nullptr;
510     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
511     auto controller = AceType::MakeRefPtr<NG::JsArcSwiperController>();
512     CHECK_NULL_RETURN(controller, ExtNapiUtils::CreateNull(env));
513     controller->IncRefCount();
514     napi_wrap(
515         env, thisVar, AceType::RawPtr(controller),
516         [](napi_env env, void* data, void* hint) {
517             auto* controller = reinterpret_cast<NG::JsArcSwiperController*>(data);
518             controller->DecRefCount();
519         },
520         nullptr, nullptr);
521     return thisVar;
522 }
523 
ArcDotIndicatorConstructor(napi_env env,napi_callback_info info)524 napi_value ArcDotIndicatorConstructor(napi_env env, napi_callback_info info)
525 {
526     napi_value thisVar = nullptr;
527     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
528     auto indicator = AceType::MakeRefPtr<NG::JsArcSwiperIndicator>();
529     CHECK_NULL_RETURN(indicator, ExtNapiUtils::CreateNull(env));
530     indicator->IncRefCount();
531     napi_wrap(
532         env, thisVar, AceType::RawPtr(indicator),
533         [](napi_env env, void* data, void* hint) {
534             auto* indicator = reinterpret_cast<NG::JsArcSwiperIndicator*>(data);
535             indicator->DecRefCount();
536         },
537         nullptr, nullptr);
538     return thisVar;
539 }
540 
SetArcDirection(napi_env env,napi_callback_info info)541 napi_value SetArcDirection(napi_env env, napi_callback_info info)
542 {
543     napi_value thisVar = nullptr;
544     size_t argc = MAX_ARG_NUM;
545     napi_value argv[MAX_ARG_NUM] = { nullptr };
546     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
547     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
548     NG::JsArcSwiperIndicator* indicator = nullptr;
549     napi_unwrap(env, thisVar, (void**)&indicator);
550     CHECK_NULL_RETURN(indicator, thisVar);
551     SwiperArcDirection arcDirection = SwiperArcDirection::SIX_CLOCK_DIRECTION;
552     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_number)) {
553         arcDirection = static_cast<SwiperArcDirection>(ExtNapiUtils::GetCInt32(env, argv[0]));
554     }
555 
556     if (static_cast<int>(arcDirection) < static_cast<int>(SwiperArcDirection::THREE_CLOCK_DIRECTION) ||
557         static_cast<int>(arcDirection) > static_cast<int>(SwiperArcDirection::NINE_CLOCK_DIRECTION)) {
558             arcDirection = SwiperArcDirection::SIX_CLOCK_DIRECTION;
559         }
560     indicator->SetArcDirection(arcDirection);
561     return thisVar;
562 }
563 
SetItemColor(napi_env env,napi_callback_info info)564 napi_value SetItemColor(napi_env env, napi_callback_info info)
565 {
566     napi_value thisVar = nullptr;
567     size_t argc = MAX_ARG_NUM;
568     napi_value argv[MAX_ARG_NUM] = { nullptr };
569     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
570     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
571     NG::JsArcSwiperIndicator* indicator = nullptr;
572     napi_unwrap(env, thisVar, (void**)&indicator);
573     CHECK_NULL_RETURN(indicator, thisVar);
574 
575     Color colorVal;
576     if (ExtNapiUtils::ParseColor(env, argv[0], colorVal)) {
577         indicator->SetItemColor(colorVal);
578     } else {
579         indicator->ResetItemColor();
580     }
581     return thisVar;
582 }
583 
SetSelectedItemColor(napi_env env,napi_callback_info info)584 napi_value SetSelectedItemColor(napi_env env, napi_callback_info info)
585 {
586     napi_value thisVar = nullptr;
587     size_t argc = MAX_ARG_NUM;
588     napi_value argv[MAX_ARG_NUM] = { nullptr };
589     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
590     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
591     NG::JsArcSwiperIndicator* indicator = nullptr;
592     napi_unwrap(env, thisVar, (void**)&indicator);
593     CHECK_NULL_RETURN(indicator, thisVar);
594 
595     Color colorVal;
596     if (ExtNapiUtils::ParseColor(env, argv[0], colorVal)) {
597         indicator->SetSelectedItemColor(colorVal);
598     } else {
599         indicator->ResetSelectedItemColor();
600     }
601     return thisVar;
602 }
603 
SetBackgroundColor(napi_env env,napi_callback_info info)604 napi_value SetBackgroundColor(napi_env env, napi_callback_info info)
605 {
606     napi_value thisVar = nullptr;
607     size_t argc = MAX_ARG_NUM;
608     napi_value argv[MAX_ARG_NUM] = { nullptr };
609     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
610     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
611     NG::JsArcSwiperIndicator* indicator = nullptr;
612     napi_unwrap(env, thisVar, (void**)&indicator);
613     CHECK_NULL_RETURN(indicator, thisVar);
614 
615     Color colorVal;
616     if (ExtNapiUtils::ParseColor(env, argv[0], colorVal)) {
617         indicator->SetContainerColor(colorVal);
618     } else {
619         indicator->ResetContainerColor();
620     }
621     return thisVar;
622 }
623 
ConvertGradientColor(napi_env env,napi_value value,NG::Gradient & gradient)624 bool ConvertGradientColor(napi_env env, napi_value value, NG::Gradient& gradient)
625 {
626     auto jsValue = Framework::JsConverter::ConvertNapiValueToJsVal(value);
627     Framework::JSLinearGradient* jsLinearGradient =
628         Framework::JSRef<Framework::JSObject>::Cast(jsValue)->Unwrap<Framework::JSLinearGradient>();
629 
630     if (!jsLinearGradient || jsLinearGradient->GetGradient().empty()) {
631         return false;
632     }
633 
634     size_t size = jsLinearGradient->GetGradient().size();
635     if (size == 1) {
636         // If there is only one color, then this color is used for both the begin and end side.
637         NG::GradientColor gradientColor;
638         gradientColor.SetLinearColor(LinearColor(jsLinearGradient->GetGradient().front().first));
639         gradientColor.SetDimension(jsLinearGradient->GetGradient().front().second);
640         gradient.AddColor(gradientColor);
641         gradient.AddColor(gradientColor);
642         return true;
643     }
644 
645     for (size_t colorIndex = 0; colorIndex < size; colorIndex++) {
646         NG::GradientColor gradientColor;
647         gradientColor.SetLinearColor(LinearColor(jsLinearGradient->GetGradient().at(colorIndex).first));
648         gradientColor.SetDimension(jsLinearGradient->GetGradient().at(colorIndex).second);
649         gradient.AddColor(gradientColor);
650     }
651     return true;
652 }
653 
SetMaskColor(napi_env env,napi_callback_info info)654 napi_value SetMaskColor(napi_env env, napi_callback_info info)
655 {
656     napi_value thisVar = nullptr;
657     size_t argc = MAX_ARG_NUM;
658     napi_value argv[MAX_ARG_NUM] = { nullptr };
659     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
660     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
661     NG::JsArcSwiperIndicator* indicator = nullptr;
662     napi_unwrap(env, thisVar, (void**)&indicator);
663     CHECK_NULL_RETURN(indicator, thisVar);
664 
665     NG::Gradient gradient;
666     if (ExtNapiUtils::CheckTypeForNapiValue(env, argv[0], napi_object) &&
667         ConvertGradientColor(env, argv[0], gradient)) {
668         indicator->SetMaskColor(gradient);
669     } else {
670         indicator->ResetMaskColor();
671     }
672 
673     return thisVar;
674 }
675 
InitArcSwiper(napi_env env,napi_value exports)676 napi_value InitArcSwiper(napi_env env, napi_value exports)
677 {
678     napi_property_descriptor desc[] = {
679         DECLARE_NAPI_FUNCTION("create", JsCreate),
680         DECLARE_NAPI_FUNCTION("index", JsIndex),
681         DECLARE_NAPI_FUNCTION("indicator", JsIndicator),
682         DECLARE_NAPI_FUNCTION("duration", JsDuration),
683         DECLARE_NAPI_FUNCTION("vertical", JsVertical),
684         DECLARE_NAPI_FUNCTION("disableSwipe", JsDisableSwipe),
685         DECLARE_NAPI_FUNCTION("onChange", JsOnChange),
686         DECLARE_NAPI_FUNCTION("onAnimationStart", JsOnAnimationStart),
687         DECLARE_NAPI_FUNCTION("onAnimationEnd", JsOnAnimationEnd),
688         DECLARE_NAPI_FUNCTION("onGestureSwipe", JsOnGestureSwipe),
689         DECLARE_NAPI_FUNCTION("digitalCrownSensitivity", JsSetDigitalCrownSensitivity),
690         DECLARE_NAPI_FUNCTION("effectMode", JsSetEffectMode),
691         DECLARE_NAPI_FUNCTION("customContentTransition", JsSetCustomContentTransition),
692         DECLARE_NAPI_FUNCTION("disableTransitionAnimation", JsSetDisableTransitionAnimation),
693     };
694     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
695     return exports;
696 }
697 
InitArcDotIndicator(napi_env env,napi_value exports)698 napi_value InitArcDotIndicator(napi_env env, napi_value exports)
699 {
700     napi_value arcDotIndicatorClass = nullptr;
701     napi_property_descriptor desc[] = {
702         DECLARE_NAPI_FUNCTION("arcDirection", SetArcDirection),
703         DECLARE_NAPI_FUNCTION("itemColor", SetItemColor),
704         DECLARE_NAPI_FUNCTION("selectedItemColor", SetSelectedItemColor),
705         DECLARE_NAPI_FUNCTION("backgroundColor", SetBackgroundColor),
706         DECLARE_NAPI_FUNCTION("maskColor", SetMaskColor),
707     };
708 
709     NAPI_CALL(env, napi_define_class(env, "ArcDotIndicator", NAPI_AUTO_LENGTH, ArcDotIndicatorConstructor, nullptr,
710                        sizeof(desc) / sizeof(desc[0]), desc, &arcDotIndicatorClass));
711     NAPI_CALL(env, napi_set_named_property(env, exports, "ArcDotIndicator", arcDotIndicatorClass));
712     return exports;
713 }
714 
InitArcDirection(napi_env env,napi_value exports)715 napi_value InitArcDirection(napi_env env, napi_value exports)
716 {
717     napi_value arcDirection = nullptr;
718     napi_create_object(env, &arcDirection);
719     napi_value prop = ExtNapiUtils::CreateInt32(env, THREE_CLOCK_DIRECTION);
720     napi_set_named_property(env, arcDirection, "THREE_CLOCK_DIRECTION", prop);
721     prop = ExtNapiUtils::CreateInt32(env, SIX_CLOCK_DIRECTION);
722     napi_set_named_property(env, arcDirection, "SIX_CLOCK_DIRECTION", prop);
723     prop = ExtNapiUtils::CreateInt32(env, NINE_CLOCK_DIRECTION);
724     napi_set_named_property(env, arcDirection, "NINE_CLOCK_DIRECTION", prop);
725 
726     NAPI_CALL(env, napi_set_named_property(env, exports, "ArcDirection", arcDirection));
727     return exports;
728 }
729 
InitController(napi_env env,napi_value exports)730 napi_value InitController(napi_env env, napi_value exports)
731 {
732     napi_value arcSwiperControllerClass = nullptr;
733     napi_property_descriptor desc[] = {
734         DECLARE_NAPI_FUNCTION("showNext", ShowNext),
735         DECLARE_NAPI_FUNCTION("showPrevious", ShowPrevious),
736         DECLARE_NAPI_FUNCTION("finishAnimation", FinishAnimation),
737     };
738 
739     NAPI_CALL(env, napi_define_class(env, "ArcSwiperController", NAPI_AUTO_LENGTH, ArcSwiperControllerConstructor,
740                        nullptr, sizeof(desc) / sizeof(desc[0]), desc, &arcSwiperControllerClass));
741     NAPI_CALL(env, napi_set_named_property(env, exports, "ArcSwiperController", arcSwiperControllerClass));
742     return exports;
743 }
744 
ExportArcSwiper(napi_env env,napi_value exports)745 napi_value ExportArcSwiper(napi_env env, napi_value exports)
746 {
747     InitArcSwiper(env, exports);
748     InitController(env, exports);
749     InitArcDotIndicator(env, exports);
750     InitArcDirection(env, exports);
751 
752     return exports;
753 }
754 
755 } // namespace OHOS::Ace
756 
NAPI_arkui_ArcSwiper_GetABCCode(const char ** buf,int * buflen)757 extern "C" ACE_FORCE_EXPORT void NAPI_arkui_ArcSwiper_GetABCCode(const char** buf, int* buflen)
758 {
759     if (buf != nullptr) {
760         *buf = _binary_arkui_arcswiper_abc_start;
761     }
762     if (buflen != nullptr) {
763         *buflen = _binary_arkui_arcswiper_abc_end - _binary_arkui_arcswiper_abc_start;
764     }
765 }
766 
767 static napi_module arcSwiperModule = {
768     .nm_version = 1,
769     .nm_flags = 0,
770     .nm_filename = nullptr,
771     .nm_register_func = OHOS::Ace::ExportArcSwiper,
772     .nm_modname = "arkui.ArcSwiper",
773     .nm_priv = ((void*)0),
774     .reserved = { 0 },
775 };
776 
RegisterArcSwiperModule()777 extern "C" __attribute__((constructor)) void RegisterArcSwiperModule()
778 {
779     napi_module_register(&arcSwiperModule);
780 }
781