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 "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_scrollable_bridge.h"
17 
18 #include "bridge/declarative_frontend/jsview/js_shape_abstract.h"
19 #include "core/components_ng/pattern/scrollable/scrollable_model_ng.h"
20 
21 namespace OHOS::Ace::NG {
SetContentClip(ArkUIRuntimeCallInfo * runtimeCallInfo)22 ArkUINativeModuleValue ScrollableBridge::SetContentClip(ArkUIRuntimeCallInfo* runtimeCallInfo)
23 {
24     EcmaVM* vm = runtimeCallInfo->GetVM();
25     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
26     auto* node = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
27 
28     Framework::JsiCallbackInfo info = Framework::JsiCallbackInfo(runtimeCallInfo);
29     if (info[1]->IsObject()) {
30         auto* clipShape = Framework::JSRef<Framework::JSObject>::Cast(info[1])->Unwrap<Framework::JSShapeAbstract>();
31         if (clipShape) {
32             ScrollableModelNG::SetContentClip(reinterpret_cast<FrameNode*>(node), ContentClipMode::CUSTOM,
33                 AceType::DynamicCast<ShapeRect>(clipShape->GetBasicShape()));
34             return panda::JSValueRef::Undefined(vm);
35         }
36     } else if (info[1]->IsNumber()) {
37         GetArkUINodeModifiers()->getScrollableModifier()->setContentClip(node, info[1]->ToNumber<int32_t>());
38         return panda::JSValueRef::Undefined(vm);
39     }
40 
41     GetArkUINodeModifiers()->getScrollableModifier()->resetContentClip(node);
42     return panda::JSValueRef::Undefined(vm);
43 }
44 
ResetContentClip(ArkUIRuntimeCallInfo * runtimeCallInfo)45 ArkUINativeModuleValue ScrollableBridge::ResetContentClip(ArkUIRuntimeCallInfo* runtimeCallInfo)
46 {
47     EcmaVM* vm = runtimeCallInfo->GetVM();
48     Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(0);
49     auto* node = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
50     GetArkUINodeModifiers()->getScrollableModifier()->resetContentClip(node);
51     return panda::JSValueRef::Undefined(vm);
52 }
53 
SetOnReachStart(ArkUIRuntimeCallInfo * runtimeCallInfo)54 ArkUINativeModuleValue ScrollableBridge::SetOnReachStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
55 {
56     EcmaVM* vm = runtimeCallInfo->GetVM();
57     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
58     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
59     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
60     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
61     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
62         GetArkUINodeModifiers()->getScrollableModifier()->resetOnReachStartCallBack(nativeNode);
63         return panda::JSValueRef::Undefined(vm);
64     }
65     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
66     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
67     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
68     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
69         panda::LocalScope pandaScope(vm);
70         panda::TryCatch trycatch(vm);
71         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
72         func->Call(vm, func.ToLocal(), nullptr, 0);
73     };
74 
75     GetArkUINodeModifiers()->getScrollableModifier()->setOnReachStartCallBack(
76         nativeNode, reinterpret_cast<void*>(&callback));
77     return panda::JSValueRef::Undefined(vm);
78 }
79 
ResetOnReachStart(ArkUIRuntimeCallInfo * runtimeCallInfo)80 ArkUINativeModuleValue ScrollableBridge::ResetOnReachStart(ArkUIRuntimeCallInfo* runtimeCallInfo)
81 {
82     EcmaVM* vm = runtimeCallInfo->GetVM();
83     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
84     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
85     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
86     GetArkUINodeModifiers()->getScrollableModifier()->resetOnReachStartCallBack(nativeNode);
87     return panda::JSValueRef::Undefined(vm);
88 }
89 
SetOnReachEnd(ArkUIRuntimeCallInfo * runtimeCallInfo)90 ArkUINativeModuleValue ScrollableBridge::SetOnReachEnd(ArkUIRuntimeCallInfo* runtimeCallInfo)
91 {
92     EcmaVM* vm = runtimeCallInfo->GetVM();
93     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
94     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
95     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
96     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
97     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
98         GetArkUINodeModifiers()->getScrollableModifier()->resetOnReachEndCallBack(nativeNode);
99         return panda::JSValueRef::Undefined(vm);
100     }
101     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
102     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
103     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
104     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
105         panda::LocalScope pandaScope(vm);
106         panda::TryCatch trycatch(vm);
107         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
108         func->Call(vm, func.ToLocal(), nullptr, 0);
109     };
110 
111     GetArkUINodeModifiers()->getScrollableModifier()->setOnReachEndCallBack(
112         nativeNode, reinterpret_cast<void*>(&callback));
113     return panda::JSValueRef::Undefined(vm);
114 }
115 
ResetOnReachEnd(ArkUIRuntimeCallInfo * runtimeCallInfo)116 ArkUINativeModuleValue ScrollableBridge::ResetOnReachEnd(ArkUIRuntimeCallInfo* runtimeCallInfo)
117 {
118     EcmaVM* vm = runtimeCallInfo->GetVM();
119     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
120     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
121     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
122     GetArkUINodeModifiers()->getScrollableModifier()->resetOnReachEndCallBack(nativeNode);
123     return panda::JSValueRef::Undefined(vm);
124 }
125 } // namespace OHOS::Ace::NG
126