1 /*
2  * Copyright (c) 2021-2022 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_pan_handler.h"
17 
18 #include "base/log/ace_scoring_log.h"
19 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
20 #include "core/components_ng/base/view_stack_processor.h"
21 
22 namespace OHOS::Ace::Framework {
23 
CreateComponent(const JSCallbackInfo & args)24 RefPtr<OHOS::Ace::SingleChild> JSPanHandler::CreateComponent(const JSCallbackInfo& args)
25 {
26     auto gestureComponent = ViewStackProcessor::GetInstance()->GetPanGestureListenerComponent();
27     WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
28     if (jsOnStartFunc_) {
29         auto dragStartId = EventMarker(
30             [execCtx = args.GetExecutionContext(), func = std::move(jsOnStartFunc_), node = frameNode](
31                 const BaseEventInfo* info) {
32                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
33                 const DragStartInfo* dragStartInfo = static_cast<const DragStartInfo*>(info);
34 
35                 if (!dragStartInfo) {
36                     LOGE("Error processing event. Not an instance of DragStartInfo");
37                     return;
38                 }
39                 ACE_SCORING_EVENT("PanHandler.onDragStart");
40                 PipelineContext::SetCallBackNode(node);
41                 func->Execute(*dragStartInfo);
42             },
43             "dragStart", 0);
44         gestureComponent->SetOnVerticalDragStartId(dragStartId);
45     }
46 
47     if (jsOnUpdateFunc_) {
48         auto dragUpdateId = EventMarker(
49             [execCtx = args.GetExecutionContext(), func = std::move(jsOnUpdateFunc_), node = frameNode](
50                 const BaseEventInfo* info) {
51                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
52                 const DragUpdateInfo* dragUpdateInfo = static_cast<const DragUpdateInfo*>(info);
53 
54                 if (!dragUpdateInfo) {
55                     LOGE("Error processing event. Not an instance of DragUpdateInfo");
56                     return;
57                 }
58                 ACE_SCORING_EVENT("PanHandler.onDragUpdate");
59                 PipelineContext::SetCallBackNode(node);
60                 func->Execute(*dragUpdateInfo);
61             },
62             "dragUpdate", 0);
63         gestureComponent->SetOnVerticalDragUpdateId(dragUpdateId);
64     }
65 
66     if (jsOnEndFunc_) {
67         auto dragEndId = EventMarker(
68             [execCtx = args.GetExecutionContext(), func = std::move(jsOnEndFunc_), node = frameNode](
69                 const BaseEventInfo* info) {
70                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
71                 const DragEndInfo* dragEndInfo = static_cast<const DragEndInfo*>(info);
72 
73                 if (!dragEndInfo) {
74                     LOGE("Error processing event. Not an instance of DragEndInfo");
75                     return;
76                 }
77                 ACE_SCORING_EVENT("PanHandler.onDragEnd");
78                 PipelineContext::SetCallBackNode(node);
79                 func->Execute(*dragEndInfo);
80             },
81             "dragEnd", 0);
82         gestureComponent->SetOnVerticalDragEndId(dragEndId);
83     }
84 
85     if (jsOnCancelFunc_) {
86         auto dragCancelId = EventMarker(
87             [execCtx = args.GetExecutionContext(), func = std::move(jsOnCancelFunc_), node = frameNode](
88                 const BaseEventInfo* info) {
89                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
90                 ACE_SCORING_EVENT("PanHandler.onDragCancel");
91                 PipelineContext::SetCallBackNode(node);
92                 func->Execute();
93             },
94             "dragCancel", 0);
95         gestureComponent->SetOnVerticalDragCancelId(dragCancelId);
96     }
97 
98     return gestureComponent;
99 }
100 
JsHandlerOnPan(PanEvent action,const JSCallbackInfo & args)101 void JSPanHandler::JsHandlerOnPan(PanEvent action, const JSCallbackInfo& args)
102 {
103     if (args[0]->IsFunction()) {
104         JSRef<JSFunc> jsFunction = JSRef<JSFunc>::Cast(args[0]);
105         RefPtr<JsPanFunction> handlerFunc = AceType::MakeRefPtr<JsPanFunction>(jsFunction);
106         switch (action) {
107             case PanEvent::START:
108                 jsOnStartFunc_ = handlerFunc;
109                 break;
110             case PanEvent::UPDATE:
111                 jsOnUpdateFunc_ = handlerFunc;
112                 break;
113             case PanEvent::END:
114                 jsOnEndFunc_ = handlerFunc;
115                 break;
116             case PanEvent::CANCEL:
117                 jsOnCancelFunc_ = handlerFunc;
118                 break;
119             default:
120                 break;
121         }
122     }
123     args.ReturnSelf();
124 }
125 
JsHandlerOnStart(const JSCallbackInfo & args)126 void JSPanHandler::JsHandlerOnStart(const JSCallbackInfo& args)
127 {
128     JSPanHandler::JsHandlerOnPan(PanEvent::START, args);
129 }
130 
JsHandlerOnUpdate(const JSCallbackInfo & args)131 void JSPanHandler::JsHandlerOnUpdate(const JSCallbackInfo& args)
132 {
133     JSPanHandler::JsHandlerOnPan(PanEvent::UPDATE, args);
134 }
135 
JsHandlerOnEnd(const JSCallbackInfo & args)136 void JSPanHandler::JsHandlerOnEnd(const JSCallbackInfo& args)
137 {
138     JSPanHandler::JsHandlerOnPan(PanEvent::END, args);
139 }
140 
JsHandlerOnCancel(const JSCallbackInfo & args)141 void JSPanHandler::JsHandlerOnCancel(const JSCallbackInfo& args)
142 {
143     JSPanHandler::JsHandlerOnPan(PanEvent::CANCEL, args);
144 }
145 
JSBind(BindingTarget globalObj)146 void JSPanHandler::JSBind(BindingTarget globalObj)
147 {
148     JSClass<JSPanHandler>::Declare("PanHandler");
149     JSClass<JSPanHandler>::CustomMethod("onStart", &JSPanHandler::JsHandlerOnStart);
150     JSClass<JSPanHandler>::CustomMethod("onUpdate", &JSPanHandler::JsHandlerOnUpdate);
151     JSClass<JSPanHandler>::CustomMethod("onEnd", &JSPanHandler::JsHandlerOnEnd);
152     JSClass<JSPanHandler>::CustomMethod("onCancel", &JSPanHandler::JsHandlerOnCancel);
153     JSClass<JSPanHandler>::Bind<>(globalObj);
154 }
155 }; // namespace OHOS::Ace::Framework
156