1 /*
2 * Copyright (c) 2021-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
16 #include "frameworks/bridge/declarative_frontend/jsview/js_swiper.h"
17
18 #include <algorithm>
19 #include <cstdint>
20 #include <iterator>
21
22 #include "base/log/ace_scoring_log.h"
23 #include "base/utils/utils.h"
24 #include "bridge/common/utils/utils.h"
25 #include "bridge/declarative_frontend/engine/functions/js_click_function.h"
26 #include "bridge/declarative_frontend/engine/functions/js_swiper_function.h"
27 #include "bridge/declarative_frontend/jsview/models/swiper_model_impl.h"
28 #include "bridge/declarative_frontend/view_stack_processor.h"
29 #include "bridge/js_frontend/engine/jsi/js_value.h"
30 #include "core/animation/curve.h"
31 #include "core/components/common/layout/constants.h"
32 #include "core/components/common/properties/scroll_bar.h"
33 #include "core/components/swiper/swiper_component.h"
34 #include "core/components/swiper/swiper_indicator_theme.h"
35 #include "core/components_ng/pattern/swiper/swiper_model.h"
36 #include "core/components_ng/pattern/swiper/swiper_model_ng.h"
37
38 namespace OHOS::Ace {
39 namespace {
40 constexpr float ARROW_SIZE_COEFFICIENT = 0.75f;
41 } // namespace
42 std::unique_ptr<SwiperModel> SwiperModel::instance_ = nullptr;
43 std::mutex SwiperModel::mutex_;
44
GetInstance()45 SwiperModel* SwiperModel::GetInstance()
46 {
47 if (!instance_) {
48 std::lock_guard<std::mutex> lock(mutex_);
49 if (!instance_) {
50 #ifdef NG_BUILD
51 instance_.reset(new NG::SwiperModelNG());
52 #else
53 if (Container::IsCurrentUseNewPipeline()) {
54 instance_.reset(new NG::SwiperModelNG());
55 } else {
56 instance_.reset(new Framework::SwiperModelImpl());
57 }
58 #endif
59 }
60 }
61 return instance_.get();
62 }
63
64 } // namespace OHOS::Ace
65 namespace OHOS::Ace::Framework {
66 namespace {
67
68 const std::vector<EdgeEffect> EDGE_EFFECT = { EdgeEffect::SPRING, EdgeEffect::FADE, EdgeEffect::NONE };
69 const std::vector<SwiperDisplayMode> DISPLAY_MODE = { SwiperDisplayMode::STRETCH, SwiperDisplayMode::AUTO_LINEAR };
70 const std::vector<SwiperIndicatorType> INDICATOR_TYPE = { SwiperIndicatorType::DOT, SwiperIndicatorType::DIGIT };
71 const static int32_t DEFAULT_INTERVAL = 3000;
72 const static int32_t DEFAULT_DURATION = 400;
73 const static int32_t DEFAULT_DISPLAY_COUNT = 1;
74 const static int32_t PLATFORM_VERSION_TEN = 10;
75
SwiperChangeEventToJSValue(const SwiperChangeEvent & eventInfo)76 JSRef<JSVal> SwiperChangeEventToJSValue(const SwiperChangeEvent& eventInfo)
77 {
78 return JSRef<JSVal>::Make(ToJSValue(eventInfo.GetIndex()));
79 }
80
81 } // namespace
82
Create(const JSCallbackInfo & info)83 void JSSwiper::Create(const JSCallbackInfo& info)
84 {
85 auto controller = SwiperModel::GetInstance()->Create();
86
87 if (info.Length() > 0 && info[0]->IsObject()) {
88 auto* jsController = JSRef<JSObject>::Cast(info[0])->Unwrap<JSSwiperController>();
89 if (jsController) {
90 jsController->SetController(controller);
91 }
92 }
93 }
94
JsRemoteMessage(const JSCallbackInfo & info)95 void JSSwiper::JsRemoteMessage(const JSCallbackInfo& info)
96 {
97 RemoteCallback remoteCallback;
98 JSInteractableView::JsRemoteMessage(info, remoteCallback);
99
100 SwiperModel::GetInstance()->SetRemoteMessageEventId(std::move(remoteCallback));
101 }
102
JSBind(BindingTarget globalObj)103 void JSSwiper::JSBind(BindingTarget globalObj)
104 {
105 JSClass<JSSwiper>::Declare("Swiper");
106 MethodOptions opt = MethodOptions::NONE;
107 JSClass<JSSwiper>::StaticMethod("create", &JSSwiper::Create, opt);
108 JSClass<JSSwiper>::StaticMethod("autoPlay", &JSSwiper::SetAutoPlay, opt);
109 JSClass<JSSwiper>::StaticMethod("duration", &JSSwiper::SetDuration, opt);
110 JSClass<JSSwiper>::StaticMethod("index", &JSSwiper::SetIndex, opt);
111 JSClass<JSSwiper>::StaticMethod("interval", &JSSwiper::SetInterval, opt);
112 JSClass<JSSwiper>::StaticMethod("loop", &JSSwiper::SetLoop, opt);
113 JSClass<JSSwiper>::StaticMethod("vertical", &JSSwiper::SetVertical, opt);
114 JSClass<JSSwiper>::StaticMethod("indicator", &JSSwiper::SetIndicator, opt);
115 JSClass<JSSwiper>::StaticMethod("displayMode", &JSSwiper::SetDisplayMode);
116 JSClass<JSSwiper>::StaticMethod("effectMode", &JSSwiper::SetEffectMode);
117 JSClass<JSSwiper>::StaticMethod("displayCount", &JSSwiper::SetDisplayCount);
118 JSClass<JSSwiper>::StaticMethod("itemSpace", &JSSwiper::SetItemSpace);
119 JSClass<JSSwiper>::StaticMethod("prevMargin", &JSSwiper::SetPreviousMargin);
120 JSClass<JSSwiper>::StaticMethod("nextMargin", &JSSwiper::SetNextMargin);
121 JSClass<JSSwiper>::StaticMethod("cachedCount", &JSSwiper::SetCachedCount);
122 JSClass<JSSwiper>::StaticMethod("curve", &JSSwiper::SetCurve);
123 JSClass<JSSwiper>::StaticMethod("onChange", &JSSwiper::SetOnChange);
124 JSClass<JSSwiper>::StaticMethod("onAnimationStart", &JSSwiper::SetOnAnimationStart);
125 JSClass<JSSwiper>::StaticMethod("onAnimationEnd", &JSSwiper::SetOnAnimationEnd);
126 JSClass<JSSwiper>::StaticMethod("onGestureSwipe", &JSSwiper::SetOnGestureSwipe);
127 JSClass<JSSwiper>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
128 JSClass<JSSwiper>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
129 JSClass<JSSwiper>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
130 JSClass<JSSwiper>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
131 JSClass<JSSwiper>::StaticMethod("remoteMessage", &JSSwiper::JsRemoteMessage);
132 JSClass<JSSwiper>::StaticMethod("onClick", &JSSwiper::SetOnClick);
133 JSClass<JSSwiper>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
134 JSClass<JSSwiper>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
135 JSClass<JSSwiper>::StaticMethod("indicatorStyle", &JSSwiper::SetIndicatorStyle);
136 JSClass<JSSwiper>::StaticMethod("enabled", &JSSwiper::SetEnabled);
137 JSClass<JSSwiper>::StaticMethod("disableSwipe", &JSSwiper::SetDisableSwipe);
138 JSClass<JSSwiper>::StaticMethod("height", &JSSwiper::SetHeight);
139 JSClass<JSSwiper>::StaticMethod("width", &JSSwiper::SetWidth);
140 JSClass<JSSwiper>::StaticMethod("size", &JSSwiper::SetSize);
141 JSClass<JSSwiper>::StaticMethod("displayArrow", &JSSwiper::SetDisplayArrow);
142 JSClass<JSSwiper>::InheritAndBind<JSContainerBase>(globalObj);
143 }
144
SetAutoPlay(bool autoPlay)145 void JSSwiper::SetAutoPlay(bool autoPlay)
146 {
147 SwiperModel::GetInstance()->SetAutoPlay(autoPlay);
148 }
149
SetEnabled(const JSCallbackInfo & info)150 void JSSwiper::SetEnabled(const JSCallbackInfo& info)
151 {
152 JSViewAbstract::JsEnabled(info);
153 if (info.Length() < 1) {
154 LOGE("The info is wrong, it is supposed to have at least 1 arguments");
155 return;
156 }
157
158 if (!info[0]->IsBoolean()) {
159 LOGE("info is not bool.");
160 return;
161 }
162
163 SwiperModel::GetInstance()->SetEnabled(info[0]->ToBoolean());
164 }
165
SetDisableSwipe(bool disableSwipe)166 void JSSwiper::SetDisableSwipe(bool disableSwipe)
167 {
168 SwiperModel::GetInstance()->SetDisableSwipe(disableSwipe);
169 }
170
SetEffectMode(const JSCallbackInfo & info)171 void JSSwiper::SetEffectMode(const JSCallbackInfo& info)
172 {
173 if (info.Length() < 1) {
174 LOGE("The info is wrong, it is supposed to have atleast 1 arguments");
175 return;
176 }
177
178 if (!info[0]->IsNumber()) {
179 LOGE("info is not a number ");
180 return;
181 }
182
183 auto edgeEffect = info[0]->ToNumber<int32_t>();
184 if (edgeEffect < 0 || edgeEffect >= static_cast<int32_t>(EDGE_EFFECT.size())) {
185 LOGE("Edge effect: %{public}d illegal value", edgeEffect);
186 return;
187 }
188
189 SwiperModel::GetInstance()->SetEdgeEffect(EDGE_EFFECT[edgeEffect]);
190 }
191
SetDisplayCount(const JSCallbackInfo & info)192 void JSSwiper::SetDisplayCount(const JSCallbackInfo& info)
193 {
194 if (info.Length() < 1) {
195 LOGE("The info is wrong, it is supposed to have atleast 1 arguments");
196 return;
197 }
198
199 auto pipeline = PipelineBase::GetCurrentContext();
200 CHECK_NULL_VOID(pipeline);
201 if (pipeline->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
202 if (info[0]->IsString() && info[0]->ToString() == "auto") {
203 SwiperModel::GetInstance()->SetDisplayMode(SwiperDisplayMode::AUTO_LINEAR);
204 SwiperModel::GetInstance()->ResetDisplayCount();
205 } else if (info[0]->IsNumber() && info[0]->ToNumber<int32_t>() > 0) {
206 SwiperModel::GetInstance()->SetDisplayCount(info[0]->ToNumber<int32_t>());
207 } else if (info[0]->IsObject()) {
208 JSRef<JSObject> jsObj = JSRef<JSObject>::Cast(info[0]);
209 auto minSizeParam = jsObj->GetProperty("minSize");
210 if (minSizeParam->IsNull()) {
211 LOGW("minSize param is invalid");
212 return;
213 }
214 CalcDimension minSizeValue;
215 if (!ParseJsDimensionVp(minSizeParam, minSizeValue)) {
216 SwiperModel::GetInstance()->SetMinSize(0.0_vp);
217 return;
218 }
219 SwiperModel::GetInstance()->SetMinSize(minSizeValue);
220 } else {
221 SwiperModel::GetInstance()->SetDisplayCount(DEFAULT_DISPLAY_COUNT);
222 }
223
224 return;
225 }
226
227 if (info[0]->IsString() && info[0]->ToString() == "auto") {
228 SwiperModel::GetInstance()->SetDisplayMode(SwiperDisplayMode::AUTO_LINEAR);
229 SwiperModel::GetInstance()->ResetDisplayCount();
230 } else if (info[0]->IsNumber()) {
231 SwiperModel::GetInstance()->SetDisplayCount(info[0]->ToNumber<int32_t>());
232 }
233 }
234
SetDuration(const JSCallbackInfo & info)235 void JSSwiper::SetDuration(const JSCallbackInfo& info)
236 {
237 int32_t duration = DEFAULT_DURATION;
238
239 if (info.Length() < 1) { // user do not set any value
240 LOGE("The info is wrong, it is supposed to have atleast 1 arguments");
241 return;
242 }
243
244 // undefined value turn to default 400
245 if (!info[0]->IsUndefined()) {
246 if (!info[0]->IsNumber()) { // user set value type not Number
247 LOGE("info is not a number, set to default 400.");
248 } else { // Number type
249 duration = info[0]->ToNumber<int32_t>();
250 if (duration < 0) {
251 LOGE("duration is not valid: %{public}d, set to default 400.", duration);
252 duration = DEFAULT_DURATION;
253 }
254 }
255 }
256
257 SwiperModel::GetInstance()->SetDuration(duration);
258 }
259
ParseSwiperIndexObject(const JSCallbackInfo & args,const JSRef<JSVal> & changeEventVal)260 void ParseSwiperIndexObject(const JSCallbackInfo& args, const JSRef<JSVal>& changeEventVal)
261 {
262 CHECK_NULL_VOID(changeEventVal->IsFunction());
263
264 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(changeEventVal));
265 auto onIndex = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const BaseEventInfo* info) {
266 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
267 ACE_SCORING_EVENT("Swiper.onChangeEvent");
268 const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
269 if (!swiperInfo) {
270 LOGE("ParseSwiperIndexObject swiperInfo is nullptr");
271 return;
272 }
273 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(swiperInfo->GetIndex()));
274 func->ExecuteJS(1, &newJSVal);
275 };
276 SwiperModel::GetInstance()->SetOnChangeEvent(std::move(onIndex));
277 }
278
SetIndex(const JSCallbackInfo & info)279 void JSSwiper::SetIndex(const JSCallbackInfo& info)
280 {
281 if (info.Length() < 1 || info.Length() > 2) {
282 LOGE("The arg is wrong, it is supposed to have 1 or 2 arguments");
283 return;
284 }
285
286 int32_t index = 0;
287 if (info.Length() > 0 && info[0]->IsNumber()) {
288 index = info[0]->ToNumber<int32_t>();
289 }
290
291 auto pipeline = PipelineBase::GetCurrentContext();
292 CHECK_NULL_VOID(pipeline);
293 if (pipeline->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
294 index = index < 0 ? 0 : index;
295 }
296
297 if (index < 0) {
298 LOGE("index is not valid: %{public}d", index);
299 return;
300 }
301 SwiperModel::GetInstance()->SetIndex(index);
302
303 if (info.Length() > 1 && info[1]->IsFunction()) {
304 ParseSwiperIndexObject(info, info[1]);
305 }
306 }
307
SetInterval(const JSCallbackInfo & info)308 void JSSwiper::SetInterval(const JSCallbackInfo& info)
309 {
310 int32_t interval = DEFAULT_INTERVAL;
311
312 if (info.Length() < 1) { // user do not set any value
313 LOGE("The info is wrong, it is supposed to have atleast 1 arguments");
314 return;
315 }
316
317 // undefined value turn to default 3000
318 if (!info[0]->IsUndefined()) {
319 if (!info[0]->IsNumber()) { // user set value type not Number
320 LOGE("info is not a number, set to default 3000.");
321 } else { // Number type
322 interval = info[0]->ToNumber<int32_t>();
323 if (interval < 0) {
324 LOGE("interval is not valid: %{public}d, set to default 3000.", interval);
325 interval = DEFAULT_INTERVAL;
326 }
327 }
328 }
329
330 SwiperModel::GetInstance()->SetAutoPlayInterval(interval);
331 }
332
SetLoop(const JSCallbackInfo & info)333 void JSSwiper::SetLoop(const JSCallbackInfo& info)
334 {
335 if (info.Length() < 1) {
336 return;
337 }
338
339 auto pipeline = PipelineBase::GetCurrentContext();
340 CHECK_NULL_VOID(pipeline);
341 if (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN) {
342 SwiperModel::GetInstance()->SetLoop(info[0]->ToBoolean());
343 return;
344 }
345
346 if (info[0]->IsBoolean()) {
347 SwiperModel::GetInstance()->SetLoop(info[0]->ToBoolean());
348 } else {
349 SwiperModel::GetInstance()->SetLoop(true);
350 }
351 }
352
SetVertical(bool isVertical)353 void JSSwiper::SetVertical(bool isVertical)
354 {
355 SwiperModel::GetInstance()->SetDirection(isVertical ? Axis::VERTICAL : Axis::HORIZONTAL);
356 }
357
GetFontContent(const JSRef<JSVal> & font,bool isSelected,SwiperDigitalParameters & digitalParameters)358 void JSSwiper::GetFontContent(const JSRef<JSVal>& font, bool isSelected, SwiperDigitalParameters& digitalParameters)
359 {
360 JSRef<JSObject> obj = JSRef<JSObject>::Cast(font);
361 JSRef<JSVal> size = obj->GetProperty("size");
362 auto pipelineContext = PipelineBase::GetCurrentContext();
363 CHECK_NULL_VOID(pipelineContext);
364 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
365 CHECK_NULL_VOID(swiperIndicatorTheme);
366 // set font size, unit FP
367 CalcDimension fontSize;
368 if (!size->IsUndefined() && !size->IsNull() && ParseJsDimensionFp(size, fontSize)) {
369 if (LessOrEqual(fontSize.Value(), 0.0) || LessOrEqual(size->ToNumber<double>(), 0.0) ||
370 fontSize.Unit() == DimensionUnit::PERCENT) {
371 fontSize = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize();
372 }
373 } else {
374 fontSize = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize();
375 }
376 if (isSelected) {
377 digitalParameters.selectedFontSize = fontSize;
378 } else {
379 digitalParameters.fontSize = fontSize;
380 }
381 JSRef<JSVal> weight = obj->GetProperty("weight");
382 if (!weight->IsNull()) {
383 std::string weightValue;
384 if (weight->IsNumber()) {
385 weightValue = std::to_string(weight->ToNumber<int32_t>());
386 } else {
387 ParseJsString(weight, weightValue);
388 }
389 if (isSelected) {
390 digitalParameters.selectedFontWeight = ConvertStrToFontWeight(weightValue);
391 } else {
392 digitalParameters.fontWeight = ConvertStrToFontWeight(weightValue);
393 }
394 } else {
395 if (isSelected) {
396 digitalParameters.selectedFontWeight = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
397 } else {
398 digitalParameters.fontWeight = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
399 }
400 }
401 }
402
SetIsIndicatorCustomSize(const Dimension & dimPosition,bool parseOk)403 void JSSwiper::SetIsIndicatorCustomSize(const Dimension& dimPosition, bool parseOk)
404 {
405 if (parseOk && dimPosition > 0.0_vp) {
406 SwiperModel::GetInstance()->SetIsIndicatorCustomSize(true);
407 } else {
408 SwiperModel::GetInstance()->SetIsIndicatorCustomSize(false);
409 }
410 }
411
GetDotIndicatorInfo(const JSRef<JSObject> & obj)412 SwiperParameters JSSwiper::GetDotIndicatorInfo(const JSRef<JSObject>& obj)
413 {
414 JSRef<JSVal> leftValue = obj->GetProperty("leftValue");
415 JSRef<JSVal> topValue = obj->GetProperty("topValue");
416 JSRef<JSVal> rightValue = obj->GetProperty("rightValue");
417 JSRef<JSVal> bottomValue = obj->GetProperty("bottomValue");
418 JSRef<JSVal> itemWidthValue = obj->GetProperty("itemWidthValue");
419 JSRef<JSVal> itemHeightValue = obj->GetProperty("itemHeightValue");
420 JSRef<JSVal> selectedItemWidthValue = obj->GetProperty("selectedItemWidthValue");
421 JSRef<JSVal> selectedItemHeightValue = obj->GetProperty("selectedItemHeightValue");
422 JSRef<JSVal> maskValue = obj->GetProperty("maskValue");
423 JSRef<JSVal> colorValue = obj->GetProperty("colorValue");
424 JSRef<JSVal> selectedColorValue = obj->GetProperty("selectedColorValue");
425 auto pipelineContext = PipelineBase::GetCurrentContext();
426 CHECK_NULL_RETURN(pipelineContext, SwiperParameters());
427 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
428 CHECK_NULL_RETURN(swiperIndicatorTheme, SwiperParameters());
429 bool parseOk = false;
430 SwiperParameters swiperParameters;
431 CalcDimension dimPosition;
432 parseOk = ParseJsDimensionVp(leftValue, dimPosition);
433 if (parseOk) {
434 if (dimPosition.ConvertToPx() < 0.0f) {
435 dimPosition = 0.0_vp;
436 }
437 } else {
438 dimPosition = 0.0_vp;
439 }
440 swiperParameters.dimLeft = dimPosition;
441 parseOk = ParseJsDimensionVp(topValue, dimPosition);
442 swiperParameters.dimTop = parseOk ? dimPosition : 0.0_vp;
443 parseOk = ParseJsDimensionVp(rightValue, dimPosition);
444 swiperParameters.dimRight = parseOk ? dimPosition : 0.0_vp;
445 parseOk = ParseJsDimensionVp(bottomValue, dimPosition);
446 swiperParameters.dimBottom = parseOk ? dimPosition : 0.0_vp;
447 bool parseItemWOk =
448 ParseJsDimensionVp(itemWidthValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
449 auto defaultSize = swiperIndicatorTheme->GetSize();
450 swiperParameters.itemWidth = parseItemWOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
451 bool parseItemHOk =
452 ParseJsDimensionVp(itemHeightValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
453 swiperParameters.itemHeight = parseItemHOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
454 bool parseSeleItemWOk =
455 ParseJsDimensionVp(selectedItemWidthValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
456 swiperParameters.selectedItemWidth = parseSeleItemWOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
457 bool parseSeleItemHOk =
458 ParseJsDimensionVp(selectedItemHeightValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
459 swiperParameters.selectedItemHeight = parseSeleItemHOk && dimPosition > 0.0_vp ? dimPosition : defaultSize;
460 if (parseSeleItemWOk == false && parseSeleItemHOk == false && parseItemWOk == false && parseItemHOk == false) {
461 SwiperModel::GetInstance()->SetIsIndicatorCustomSize(false);
462 } else {
463 SwiperModel::GetInstance()->SetIsIndicatorCustomSize(true);
464 }
465 if (maskValue->IsBoolean()) {
466 auto mask = maskValue->ToBoolean();
467 swiperParameters.maskValue = mask;
468 }
469 Color colorVal;
470 parseOk = ParseJsColor(colorValue, colorVal);
471 swiperParameters.colorVal = parseOk ? colorVal : swiperIndicatorTheme->GetColor();
472 parseOk = ParseJsColor(selectedColorValue, colorVal);
473 swiperParameters.selectedColorVal = parseOk ? colorVal : swiperIndicatorTheme->GetSelectedColor();
474 return swiperParameters;
475 }
476
GetDigitIndicatorInfo(const JSRef<JSObject> & obj)477 SwiperDigitalParameters JSSwiper::GetDigitIndicatorInfo(const JSRef<JSObject>& obj)
478 {
479 JSRef<JSVal> dotLeftValue = obj->GetProperty("leftValue");
480 JSRef<JSVal> dotTopValue = obj->GetProperty("topValue");
481 JSRef<JSVal> dotRightValue = obj->GetProperty("rightValue");
482 JSRef<JSVal> dotBottomValue = obj->GetProperty("bottomValue");
483 JSRef<JSVal> fontColorValue = obj->GetProperty("fontColorValue");
484 JSRef<JSVal> selectedFontColorValue = obj->GetProperty("selectedFontColorValue");
485 JSRef<JSVal> digitFontValue = obj->GetProperty("digitFontValue");
486 JSRef<JSVal> selectedDigitFontValue = obj->GetProperty("selectedDigitFontValue");
487 auto pipelineContext = PipelineBase::GetCurrentContext();
488 CHECK_NULL_RETURN(pipelineContext, SwiperDigitalParameters());
489 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
490 CHECK_NULL_RETURN(swiperIndicatorTheme, SwiperDigitalParameters());
491 bool parseOk = false;
492 SwiperDigitalParameters digitalParameters;
493 CalcDimension dimPosition;
494 parseOk = ParseJsDimensionVp(dotLeftValue, dimPosition);
495 if (parseOk) {
496 if (dimPosition.ConvertToPx() < 0.0f) {
497 dimPosition = 0.0_vp;
498 }
499 } else {
500 dimPosition = 0.0_vp;
501 }
502 digitalParameters.dimLeft = dimPosition;
503 parseOk = ParseJsDimensionVp(dotTopValue, dimPosition);
504 digitalParameters.dimTop = parseOk ? dimPosition : 0.0_vp;
505 parseOk = ParseJsDimensionVp(dotRightValue, dimPosition);
506 digitalParameters.dimRight = parseOk ? dimPosition : 0.0_vp;
507 parseOk = ParseJsDimensionVp(dotBottomValue, dimPosition);
508 digitalParameters.dimBottom = parseOk ? dimPosition : 0.0_vp;
509 Color fontColor;
510 parseOk = JSViewAbstract::ParseJsColor(fontColorValue, fontColor);
511 digitalParameters.fontColor =
512 parseOk ? fontColor : swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
513 parseOk = JSViewAbstract::ParseJsColor(selectedFontColorValue, fontColor);
514 digitalParameters.selectedFontColor =
515 parseOk ? fontColor : swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
516 if (!digitFontValue->IsNull() && digitFontValue->IsObject()) {
517 GetFontContent(digitFontValue, false, digitalParameters);
518 }
519 if (!selectedDigitFontValue->IsNull() && selectedDigitFontValue->IsObject()) {
520 GetFontContent(selectedDigitFontValue, true, digitalParameters);
521 }
522 return digitalParameters;
523 }
524
GetArrowInfo(const JSRef<JSObject> & obj,SwiperArrowParameters & swiperArrowParameters)525 bool JSSwiper::GetArrowInfo(const JSRef<JSObject>& obj, SwiperArrowParameters& swiperArrowParameters)
526 {
527 auto isShowBackgroundValue = obj->GetProperty("showBackground");
528 auto isSidebarMiddleValue = obj->GetProperty("isSidebarMiddle");
529 auto backgroundSizeValue = obj->GetProperty("backgroundSize");
530 auto backgroundColorValue = obj->GetProperty("backgroundColor");
531 auto arrowSizeValue = obj->GetProperty("arrowSize");
532 auto arrowColorValue = obj->GetProperty("arrowColor");
533 auto pipelineContext = PipelineBase::GetCurrentContext();
534 CHECK_NULL_RETURN(pipelineContext, false);
535 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
536 CHECK_NULL_RETURN(swiperIndicatorTheme, false);
537 swiperArrowParameters.isShowBackground = isShowBackgroundValue->IsBoolean()
538 ? isShowBackgroundValue->ToBoolean()
539 : swiperIndicatorTheme->GetIsShowArrowBackground();
540 swiperArrowParameters.isSidebarMiddle = isSidebarMiddleValue->IsBoolean()
541 ? isSidebarMiddleValue->ToBoolean()
542 : swiperIndicatorTheme->GetIsSidebarMiddle();
543 bool parseOk = false;
544 CalcDimension dimension;
545 Color color;
546 if (swiperArrowParameters.isSidebarMiddle.value()) {
547 parseOk = ParseJsDimensionVp(backgroundSizeValue, dimension);
548 swiperArrowParameters.backgroundSize =
549 parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
550 ? dimension
551 : swiperIndicatorTheme->GetBigArrowBackgroundSize();
552 parseOk = ParseJsColor(backgroundColorValue, color);
553 swiperArrowParameters.backgroundColor = parseOk ? color : swiperIndicatorTheme->GetBigArrowBackgroundColor();
554 if (swiperArrowParameters.isShowBackground.value()) {
555 swiperArrowParameters.arrowSize = swiperArrowParameters.backgroundSize.value() * ARROW_SIZE_COEFFICIENT;
556 } else {
557 parseOk = ParseJsDimensionVp(arrowSizeValue, dimension);
558 swiperArrowParameters.arrowSize =
559 parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
560 ? dimension
561 : swiperIndicatorTheme->GetBigArrowSize();
562 swiperArrowParameters.backgroundSize = swiperArrowParameters.arrowSize;
563 }
564 parseOk = ParseJsColor(arrowColorValue, color);
565 swiperArrowParameters.arrowColor = parseOk ? color : swiperIndicatorTheme->GetBigArrowColor();
566 } else {
567 parseOk = ParseJsDimensionVp(backgroundSizeValue, dimension);
568 swiperArrowParameters.backgroundSize =
569 parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
570 ? dimension
571 : swiperIndicatorTheme->GetSmallArrowBackgroundSize();
572 parseOk = ParseJsColor(backgroundColorValue, color);
573 swiperArrowParameters.backgroundColor = parseOk ? color : swiperIndicatorTheme->GetSmallArrowBackgroundColor();
574 if (swiperArrowParameters.isShowBackground.value()) {
575 swiperArrowParameters.arrowSize = swiperArrowParameters.backgroundSize.value() * ARROW_SIZE_COEFFICIENT;
576 } else {
577 parseOk = ParseJsDimensionVp(arrowSizeValue, dimension);
578 swiperArrowParameters.arrowSize =
579 parseOk && GreatNotEqual(dimension.ConvertToVp(), 0.0) && !(dimension.Unit() == DimensionUnit::PERCENT)
580 ? dimension
581 : swiperIndicatorTheme->GetSmallArrowSize();
582 swiperArrowParameters.backgroundSize = swiperArrowParameters.arrowSize;
583 }
584 parseOk = ParseJsColor(arrowColorValue, color);
585 swiperArrowParameters.arrowColor = parseOk ? color : swiperIndicatorTheme->GetSmallArrowColor();
586 }
587 return true;
588 }
589
SetDisplayArrow(const JSCallbackInfo & info)590 void JSSwiper::SetDisplayArrow(const JSCallbackInfo& info)
591 {
592 if (info[0]->IsEmpty() || info[0]->IsUndefined()) {
593 SwiperModel::GetInstance()->SetDisplayArrow(false);
594 return;
595 }
596 if (info.Length() > 0 && info[0]->IsObject()) {
597 auto obj = JSRef<JSObject>::Cast(info[0]);
598 SwiperArrowParameters swiperArrowParameters;
599 if (!GetArrowInfo(obj, swiperArrowParameters)) {
600 SwiperModel::GetInstance()->SetDisplayArrow(false);
601 return;
602 }
603 SwiperModel::GetInstance()->SetArrowStyle(swiperArrowParameters);
604 SwiperModel::GetInstance()->SetDisplayArrow(true);
605 } else if (info[0]->IsBoolean()) {
606 if (info[0]->ToBoolean()) {
607 auto pipelineContext = PipelineBase::GetCurrentContext();
608 CHECK_NULL_VOID(pipelineContext);
609 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
610 CHECK_NULL_VOID(swiperIndicatorTheme);
611 SwiperArrowParameters swiperArrowParameters;
612 swiperArrowParameters.isShowBackground = swiperIndicatorTheme->GetIsShowArrowBackground();
613 swiperArrowParameters.isSidebarMiddle = swiperIndicatorTheme->GetIsSidebarMiddle();
614 swiperArrowParameters.backgroundSize = swiperIndicatorTheme->GetSmallArrowBackgroundSize();
615 swiperArrowParameters.backgroundColor = swiperIndicatorTheme->GetSmallArrowBackgroundColor();
616 swiperArrowParameters.arrowSize = swiperIndicatorTheme->GetSmallArrowSize();
617 swiperArrowParameters.arrowColor = swiperIndicatorTheme->GetSmallArrowColor();
618 SwiperModel::GetInstance()->SetArrowStyle(swiperArrowParameters);
619 SwiperModel::GetInstance()->SetDisplayArrow(true);
620 } else {
621 SwiperModel::GetInstance()->SetDisplayArrow(false);
622 return;
623 }
624 } else {
625 SwiperModel::GetInstance()->SetDisplayArrow(false);
626 return;
627 }
628 if (info.Length() > 1 && info[1]->IsBoolean()) {
629 SwiperModel::GetInstance()->SetHoverShow(info[1]->ToBoolean());
630 } else {
631 SwiperModel::GetInstance()->SetHoverShow(false);
632 }
633 }
SetIndicator(const JSCallbackInfo & info)634 void JSSwiper::SetIndicator(const JSCallbackInfo& info)
635 {
636 if (info.Length() < 1) {
637 return;
638 }
639
640 if (info[0]->IsUndefined()) {
641 SwiperModel::GetInstance()->SetShowIndicator(true);
642 return;
643 }
644 auto obj = JSRef<JSObject>::Cast(info[0]);
645 if (info[0]->IsObject()) {
646 SwiperModel::GetInstance()->SetIndicatorIsBoolean(false);
647
648 JSRef<JSVal> typeParam = obj->GetProperty("type");
649 if (typeParam->IsString()) {
650 auto type = typeParam->ToString();
651 if (type == "DigitIndicator") {
652 SwiperDigitalParameters digitalParameters = GetDigitIndicatorInfo(obj);
653 SwiperModel::GetInstance()->SetDigitIndicatorStyle(digitalParameters);
654 SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DIGIT);
655 } else {
656 SwiperParameters swiperParameters = GetDotIndicatorInfo(obj);
657 SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
658 SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DOT);
659 }
660 } else {
661 SwiperParameters swiperParameters = GetDotIndicatorInfo(obj);
662 SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
663 SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DOT);
664 }
665 } else {
666 SwiperParameters swiperParameters = GetDotIndicatorInfo(obj);
667 SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
668 SwiperModel::GetInstance()->SetIndicatorType(SwiperIndicatorType::DOT);
669 }
670 if (info[0]->IsBoolean()) {
671 bool showIndicator = false;
672 ParseJsBool(obj, showIndicator);
673 SwiperModel::GetInstance()->SetShowIndicator(showIndicator);
674 } else {
675 SwiperModel::GetInstance()->SetShowIndicator(true);
676 }
677 }
678
SetIndicatorStyle(const JSCallbackInfo & info)679 void JSSwiper::SetIndicatorStyle(const JSCallbackInfo& info)
680 {
681 SwiperParameters swiperParameters;
682 if (info[0]->IsObject()) {
683 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
684 JSRef<JSVal> leftValue = obj->GetProperty("left");
685 JSRef<JSVal> topValue = obj->GetProperty("top");
686 JSRef<JSVal> rightValue = obj->GetProperty("right");
687 JSRef<JSVal> bottomValue = obj->GetProperty("bottom");
688 JSRef<JSVal> sizeValue = obj->GetProperty("size");
689 JSRef<JSVal> maskValue = obj->GetProperty("mask");
690 JSRef<JSVal> colorValue = obj->GetProperty("color");
691 JSRef<JSVal> selectedColorValue = obj->GetProperty("selectedColor");
692 auto pipelineContext = PipelineBase::GetCurrentContext();
693 CHECK_NULL_VOID(pipelineContext);
694 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
695 CHECK_NULL_VOID(swiperIndicatorTheme);
696 CalcDimension dimPosition;
697 bool parseOk = ParseJsDimensionVp(leftValue, dimPosition);
698 swiperParameters.dimLeft = parseOk ? dimPosition : 0.0_vp;
699 parseOk = ParseJsDimensionVp(topValue, dimPosition);
700 swiperParameters.dimTop = parseOk ? dimPosition : 0.0_vp;
701 parseOk = ParseJsDimensionVp(rightValue, dimPosition);
702 swiperParameters.dimRight = parseOk ? dimPosition : 0.0_vp;
703 parseOk = ParseJsDimensionVp(bottomValue, dimPosition);
704 swiperParameters.dimBottom = parseOk ? dimPosition : 0.0_vp;
705 parseOk = ParseJsDimensionVp(sizeValue, dimPosition) && (dimPosition.Unit() != DimensionUnit::PERCENT);
706 SetIsIndicatorCustomSize(dimPosition, parseOk);
707 swiperParameters.itemWidth = parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
708 swiperParameters.itemHeight = parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
709 swiperParameters.selectedItemWidth =
710 parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
711 swiperParameters.selectedItemHeight =
712 parseOk && dimPosition > 0.0_vp ? dimPosition : swiperIndicatorTheme->GetSize();
713 if (maskValue->IsBoolean()) {
714 auto mask = maskValue->ToBoolean();
715 swiperParameters.maskValue = mask;
716 }
717 Color colorVal;
718 parseOk = ParseJsColor(colorValue, colorVal);
719 swiperParameters.colorVal = parseOk ? colorVal : swiperIndicatorTheme->GetColor();
720 parseOk = ParseJsColor(selectedColorValue, colorVal);
721 swiperParameters.selectedColorVal = parseOk ? colorVal : swiperIndicatorTheme->GetSelectedColor();
722 }
723 SwiperModel::GetInstance()->SetDotIndicatorStyle(swiperParameters);
724 info.ReturnSelf();
725 }
726
SetItemSpace(const JSCallbackInfo & info)727 void JSSwiper::SetItemSpace(const JSCallbackInfo& info)
728 {
729 if (info.Length() < 1) {
730 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
731 return;
732 }
733
734 CalcDimension value;
735 if (!ParseJsDimensionVp(info[0], value)) {
736 return;
737 }
738
739 if (LessNotEqual(value.Value(), 0.0)) {
740 value.SetValue(0.0);
741 }
742
743 SwiperModel::GetInstance()->SetItemSpace(value);
744 }
745
SetPreviousMargin(const JSCallbackInfo & info)746 void JSSwiper::SetPreviousMargin(const JSCallbackInfo& info)
747 {
748 if (info.Length() < 1) {
749 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
750 return;
751 }
752
753 CalcDimension value;
754 if (!ParseJsDimensionVp(info[0], value) || info[0]->IsNull() || info[0]->IsUndefined() ||
755 LessNotEqual(value.Value(), 0.0)) {
756 value.SetValue(0.0);
757 }
758 SwiperModel::GetInstance()->SetPreviousMargin(value);
759 }
760
SetNextMargin(const JSCallbackInfo & info)761 void JSSwiper::SetNextMargin(const JSCallbackInfo& info)
762 {
763 if (info.Length() < 1) {
764 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
765 return;
766 }
767
768 CalcDimension value;
769 if (!ParseJsDimensionVp(info[0], value) || info[0]->IsNull() || info[0]->IsUndefined() ||
770 LessNotEqual(value.Value(), 0.0)) {
771 value.SetValue(0.0);
772 }
773 SwiperModel::GetInstance()->SetNextMargin(value);
774 }
775
SetDisplayMode(int32_t index)776 void JSSwiper::SetDisplayMode(int32_t index)
777 {
778 if (index < 0 || index >= static_cast<int32_t>(DISPLAY_MODE.size())) {
779 LOGE("display mode is not valid: %{public}d", index);
780 return;
781 }
782
783 SwiperModel::GetInstance()->SetDisplayMode(DISPLAY_MODE[index]);
784 }
785
SetCachedCount(const JSCallbackInfo & info)786 void JSSwiper::SetCachedCount(const JSCallbackInfo& info)
787 {
788 if (info.Length() < 1) {
789 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
790 return;
791 }
792
793 int32_t cachedCount = 1;
794 if (info[0]->IsNumber()) {
795 cachedCount = info[0]->ToNumber<int32_t>();
796 }
797 SwiperModel::GetInstance()->SetCachedCount(cachedCount);
798 }
799
SetCurve(const JSCallbackInfo & info)800 void JSSwiper::SetCurve(const JSCallbackInfo& info)
801 {
802 RefPtr<Curve> curve = Curves::LINEAR;
803 if (info[0]->IsString()) {
804 curve = CreateCurve(info[0]->ToString());
805 } else if (info[0]->IsObject()) {
806 auto object = JSRef<JSObject>::Cast(info[0]);
807 std::function<float(float)> customCallBack = nullptr;
808 JSRef<JSVal> onCallBack = object->GetProperty("__curveCustomFunc");
809 if (onCallBack->IsFunction()) {
810 RefPtr<JsFunction> jsFuncCallBack =
811 AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(onCallBack));
812 customCallBack = [func = std::move(jsFuncCallBack), id = Container::CurrentId()](float time) -> float {
813 ContainerScope scope(id);
814 JSRef<JSVal> params[1];
815 params[0] = JSRef<JSVal>::Make(ToJSValue(time));
816 auto result = func->ExecuteJS(1, params);
817 auto resultValue = result->IsNumber() ? result->ToNumber<float>() : 1.0f;
818 if (resultValue < 0 || resultValue > 1) {
819 LOGI("The interpolate return value error = %{public}f ", resultValue);
820 }
821 return resultValue;
822 };
823 }
824 auto jsCurveString = object->GetProperty("__curveString");
825 if (jsCurveString->IsString()) {
826 auto aniTimFunc = jsCurveString->ToString();
827 if (aniTimFunc == DOM_ANIMATION_TIMING_FUNCTION_CUSTOM && customCallBack) {
828 curve = CreateCurve(customCallBack);
829 } else if (aniTimFunc != DOM_ANIMATION_TIMING_FUNCTION_CUSTOM) {
830 curve = CreateCurve(aniTimFunc);
831 }
832 }
833 }
834 SwiperModel::GetInstance()->SetCurve(curve);
835 }
836
SetOnChange(const JSCallbackInfo & info)837 void JSSwiper::SetOnChange(const JSCallbackInfo& info)
838 {
839 if (!info[0]->IsFunction()) {
840 return;
841 }
842
843 auto changeHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
844 JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
845 auto onChange = [executionContext = info.GetExecutionContext(), func = std::move(changeHandler)](
846 const BaseEventInfo* info) {
847 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
848 const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
849 if (!swiperInfo) {
850 LOGE("HandleChangeEvent swiperInfo == nullptr");
851 return;
852 }
853 ACE_SCORING_EVENT("Swiper.OnChange");
854 func->Execute(*swiperInfo);
855 };
856
857 SwiperModel::GetInstance()->SetOnChange(std::move(onChange));
858 }
859
SetOnAnimationStart(const JSCallbackInfo & info)860 void JSSwiper::SetOnAnimationStart(const JSCallbackInfo& info)
861 {
862 if (!info[0]->IsFunction()) {
863 return;
864 }
865
866 if (Container::IsCurrentUseNewPipeline()) {
867 auto animationStartHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
868 auto onAnimationStart = [executionContext = info.GetExecutionContext(),
869 func = std::move(animationStartHandler)](
870 int32_t index, int32_t targetIndex, const AnimationCallbackInfo& info) {
871 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
872 ACE_SCORING_EVENT("Swiper.onAnimationStart");
873 func->Execute(index, targetIndex, info);
874 };
875
876 SwiperModel::GetInstance()->SetOnAnimationStart(std::move(onAnimationStart));
877 return;
878 }
879
880 auto animationStartHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
881 JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
882 auto onAnimationStart = [executionContext = info.GetExecutionContext(), func = std::move(animationStartHandler)](
883 const BaseEventInfo* info) {
884 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
885 const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
886 if (!swiperInfo) {
887 LOGE("onAnimationStart swiperInfo is nullptr");
888 return;
889 }
890 ACE_SCORING_EVENT("Swiper.onAnimationStart");
891 func->Execute(*swiperInfo);
892 };
893
894 SwiperModel::GetInstance()->SetOnAnimationStart(std::move(onAnimationStart));
895 }
896
SetOnAnimationEnd(const JSCallbackInfo & info)897 void JSSwiper::SetOnAnimationEnd(const JSCallbackInfo& info)
898 {
899 if (!info[0]->IsFunction()) {
900 return;
901 }
902
903 if (Container::IsCurrentUseNewPipeline()) {
904 auto animationEndHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
905 auto onAnimationEnd = [executionContext = info.GetExecutionContext(), func = std::move(animationEndHandler)](
906 int32_t index, const AnimationCallbackInfo& info) {
907 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
908 ACE_SCORING_EVENT("Swiper.onAnimationEnd");
909 func->Execute(index, info);
910 };
911
912 SwiperModel::GetInstance()->SetOnAnimationEnd(std::move(onAnimationEnd));
913 return;
914 }
915
916 auto animationEndHandler = AceType::MakeRefPtr<JsEventFunction<SwiperChangeEvent, 1>>(
917 JSRef<JSFunc>::Cast(info[0]), SwiperChangeEventToJSValue);
918 auto onAnimationEnd = [executionContext = info.GetExecutionContext(), func = std::move(animationEndHandler)](
919 const BaseEventInfo* info) {
920 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
921 const auto* swiperInfo = TypeInfoHelper::DynamicCast<SwiperChangeEvent>(info);
922 if (!swiperInfo) {
923 LOGE("onAnimationEnd swiperInfo is nullptr");
924 return;
925 }
926 ACE_SCORING_EVENT("Swiper.onAnimationEnd");
927 func->Execute(*swiperInfo);
928 };
929
930 SwiperModel::GetInstance()->SetOnAnimationEnd(std::move(onAnimationEnd));
931 }
932
SetOnGestureSwipe(const JSCallbackInfo & info)933 void JSSwiper::SetOnGestureSwipe(const JSCallbackInfo& info)
934 {
935 if (!info[0]->IsFunction()) {
936 return;
937 }
938
939 auto gestureSwipeHandler = AceType::MakeRefPtr<JsSwiperFunction>(JSRef<JSFunc>::Cast(info[0]));
940 auto onGestureSwipe = [executionContext = info.GetExecutionContext(), func = std::move(gestureSwipeHandler)](
941 int32_t index, const AnimationCallbackInfo& info) {
942 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(executionContext);
943 ACE_SCORING_EVENT("Swiper.onGestureSwipe");
944 func->Execute(index, info);
945 };
946
947 SwiperModel::GetInstance()->SetOnGestureSwipe(std::move(onGestureSwipe));
948 }
949
SetOnClick(const JSCallbackInfo & info)950 void JSSwiper::SetOnClick(const JSCallbackInfo& info)
951 {
952 if (Container::IsCurrentUseNewPipeline()) {
953 JSInteractableView::JsOnClick(info);
954 return;
955 }
956
957 if (!info[0]->IsFunction()) {
958 LOGW("JSSwiper::SetOnClick the info is not click function");
959 return;
960 }
961
962 RefPtr<JsClickFunction> jsOnClickFunc = AceType::MakeRefPtr<JsClickFunction>(JSRef<JSFunc>::Cast(info[0]));
963 auto onClick = [execCtx = info.GetExecutionContext(), func = std::move(jsOnClickFunc)](
964 const BaseEventInfo* info, const RefPtr<V2::InspectorFunctionImpl>& impl) {
965 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
966 const auto* clickInfo = TypeInfoHelper::DynamicCast<ClickInfo>(info);
967 auto newInfo = *clickInfo;
968 if (impl) {
969 impl->UpdateEventInfo(newInfo);
970 }
971 ACE_SCORING_EVENT("onClick");
972 func->Execute(newInfo);
973 };
974
975 SwiperModel::GetInstance()->SetOnClick(onClick);
976 }
977
SetWidth(const JSCallbackInfo & info)978 void JSSwiper::SetWidth(const JSCallbackInfo& info)
979 {
980 if (info.Length() < 1) {
981 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
982 return;
983 }
984
985 SetWidth(info[0]);
986 }
987
SetWidth(const JSRef<JSVal> & jsValue)988 void JSSwiper::SetWidth(const JSRef<JSVal>& jsValue)
989 {
990 if (Container::IsCurrentUseNewPipeline()) {
991 JSViewAbstract::JsWidth(jsValue);
992 return;
993 }
994
995 JSViewAbstract::JsWidth(jsValue);
996 SwiperModel::GetInstance()->SetMainSwiperSizeWidth();
997 }
998
SetHeight(const JSRef<JSVal> & jsValue)999 void JSSwiper::SetHeight(const JSRef<JSVal>& jsValue)
1000 {
1001 if (Container::IsCurrentUseNewPipeline()) {
1002 JSViewAbstract::JsHeight(jsValue);
1003 return;
1004 }
1005
1006 JSViewAbstract::JsHeight(jsValue);
1007 SwiperModel::GetInstance()->SetMainSwiperSizeHeight();
1008 }
1009
SetHeight(const JSCallbackInfo & info)1010 void JSSwiper::SetHeight(const JSCallbackInfo& info)
1011 {
1012 if (info.Length() < 1) {
1013 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1014 return;
1015 }
1016
1017 SetHeight(info[0]);
1018 }
1019
SetSize(const JSCallbackInfo & info)1020 void JSSwiper::SetSize(const JSCallbackInfo& info)
1021 {
1022 if (info.Length() < 1) {
1023 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
1024 return;
1025 }
1026
1027 if (!info[0]->IsObject()) {
1028 LOGE("arg is not Object or String.");
1029 return;
1030 }
1031
1032 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
1033 SetWidth(sizeObj->GetProperty("width"));
1034 SetHeight(sizeObj->GetProperty("height"));
1035 }
1036
JSBind(BindingTarget globalObj)1037 void JSSwiperController::JSBind(BindingTarget globalObj)
1038 {
1039 JSClass<JSSwiperController>::Declare("SwiperController");
1040 JSClass<JSSwiperController>::CustomMethod("swipeTo", &JSSwiperController::SwipeTo);
1041 JSClass<JSSwiperController>::CustomMethod("showNext", &JSSwiperController::ShowNext);
1042 JSClass<JSSwiperController>::CustomMethod("showPrevious", &JSSwiperController::ShowPrevious);
1043 JSClass<JSSwiperController>::CustomMethod("finishAnimation", &JSSwiperController::FinishAnimation);
1044 JSClass<JSSwiperController>::Bind(globalObj, JSSwiperController::Constructor, JSSwiperController::Destructor);
1045 }
1046
Constructor(const JSCallbackInfo & args)1047 void JSSwiperController::Constructor(const JSCallbackInfo& args)
1048 {
1049 auto scroller = Referenced::MakeRefPtr<JSSwiperController>();
1050 scroller->IncRefCount();
1051 args.SetReturnValue(Referenced::RawPtr(scroller));
1052 }
1053
Destructor(JSSwiperController * scroller)1054 void JSSwiperController::Destructor(JSSwiperController* scroller)
1055 {
1056 if (scroller != nullptr) {
1057 scroller->DecRefCount();
1058 }
1059 }
1060
FinishAnimation(const JSCallbackInfo & args)1061 void JSSwiperController::FinishAnimation(const JSCallbackInfo& args)
1062 {
1063 if (!controller_) {
1064 return;
1065 }
1066
1067 if (args.Length() > 0 && args[0]->IsFunction()) {
1068 RefPtr<JsFunction> jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
1069 auto onFinish = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)]() {
1070 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
1071 ACE_SCORING_EVENT("Swiper.finishAnimation");
1072 LOGI("Swiper finish callback execute.");
1073 func->Execute();
1074 };
1075
1076 controller_->SetFinishCallback(onFinish);
1077 controller_->FinishAnimation();
1078 return;
1079 }
1080
1081 controller_->FinishAnimation();
1082 }
1083
1084 } // namespace OHOS::Ace::Framework
1085