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