1 /*
2  * Copyright (c) 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 "core/components_ng/event/pan_event.h"
17 
18 #include "base/utils/utils.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/components_ng/event/gesture_event_hub.h"
21 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
22 
23 namespace OHOS::Ace::NG {
24 
PanEventActuator(const WeakPtr<GestureEventHub> & gestureEventHub,PanDirection direction,int32_t fingers,float distance,bool isOverrideDistance)25 PanEventActuator::PanEventActuator(const WeakPtr<GestureEventHub>& gestureEventHub, PanDirection direction,
26     int32_t fingers, float distance, bool isOverrideDistance)
27     : gestureEventHub_(gestureEventHub), direction_(direction), fingers_(fingers), distance_(distance)
28 {
29     if (fingers_ < DEFAULT_PAN_FINGER) {
30         fingers_ = DEFAULT_PAN_FINGER;
31     }
32 
33     if (!isOverrideDistance && LessOrEqual(distance_, DEFAULT_PAN_DISTANCE.ConvertToPx())) {
34         distance_ = DEFAULT_PAN_DISTANCE.ConvertToPx();
35     }
36 
37     auto gestureHub = gestureEventHub_.Upgrade();
38     CHECK_NULL_VOID(gestureHub);
39     auto frameNode = gestureHub->GetFrameNode();
40     CHECK_NULL_VOID(frameNode);
41     panRecognizer_ = MakeRefPtr<PanRecognizer>(fingers_, direction_, distance_);
42 }
43 
OnCollectTouchTarget(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,const GetEventTargetImpl & getEventTargetImpl,TouchTestResult & result,ResponseLinkResult & responseLinkResult)44 void PanEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
45     const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result, ResponseLinkResult& responseLinkResult)
46 {
47     if (panEvents_.empty() && !userCallback_) {
48         return;
49     }
50 
51     auto actionStart = [weak = WeakClaim(this)](GestureEvent& info) {
52         auto actuator = weak.Upgrade();
53         CHECK_NULL_VOID(actuator);
54         // In the actionStart callback, actuator->panEvents_ may be modified
55         auto copyPanEvents = actuator->panEvents_;
56         for (const auto& panEvent : copyPanEvents) {
57             auto actionStart = panEvent->GetActionStartEventFunc();
58             if (actionStart) {
59                 actionStart(info);
60             }
61         }
62 
63         // Trigger pan start event setted by user.
64         auto userCallback = actuator->userCallback_;
65         CHECK_NULL_VOID(userCallback);
66         auto userActionStart = userCallback->GetActionStartEventFunc();
67         if (userActionStart) {
68             userActionStart(info);
69         }
70     };
71     panRecognizer_->SetOnActionStart(actionStart);
72 
73     auto actionUpdate = [weak = WeakClaim(this)](GestureEvent& info) {
74         auto actuator = weak.Upgrade();
75         CHECK_NULL_VOID(actuator);
76         // In the actionUpdate callback, actuator->panEvents_ may be modified
77         auto copyPanEvents = actuator->panEvents_;
78         for (const auto& panEvent : copyPanEvents) {
79             auto actionUpdate = panEvent->GetActionUpdateEventFunc();
80             if (actionUpdate) {
81                 actionUpdate(info);
82             }
83         }
84 
85         // Trigger pan update event  setted by user.
86         auto userCallback = actuator->userCallback_;
87         CHECK_NULL_VOID(userCallback);
88         auto userActionUpdate = userCallback->GetActionUpdateEventFunc();
89         if (userActionUpdate) {
90             userActionUpdate(info);
91         }
92     };
93     panRecognizer_->SetOnActionUpdate(actionUpdate);
94 
95     auto actionEnd = [weak = WeakClaim(this)](GestureEvent& info) {
96         auto actuator = weak.Upgrade();
97         CHECK_NULL_VOID(actuator);
98         auto copyPanEvents = actuator->panEvents_;
99         for (const auto& panEvent : copyPanEvents) {
100             auto actionEnd = panEvent->GetActionEndEventFunc();
101             if (actionEnd) {
102                 actionEnd(info);
103             }
104         }
105 
106         // Trigger pan end event  setted by user.
107         auto userCallback = actuator->userCallback_;
108         CHECK_NULL_VOID(userCallback);
109         auto userActionEnd = userCallback->GetActionEndEventFunc();
110         if (userActionEnd) {
111             userActionEnd(info);
112         }
113     };
114     panRecognizer_->SetOnActionEnd(actionEnd);
115 
116     auto actionCancel = [weak = WeakClaim(this)]() {
117         auto actuator = weak.Upgrade();
118         CHECK_NULL_VOID(actuator);
119         // In the actionCancel callback, actuator->panEvents_ may be modified
120         auto copyPanEvents = actuator->panEvents_;
121         for (const auto& panEvent : copyPanEvents) {
122             auto actionCancel = panEvent->GetActionCancelEventFunc();
123             if (actionCancel) {
124                 actionCancel();
125             }
126         }
127 
128         // Trigger pan end event  setted by user.
129         auto userCallback = actuator->userCallback_;
130         CHECK_NULL_VOID(userCallback);
131         auto userActionCancel = userCallback->GetActionCancelEventFunc();
132         if (userActionCancel) {
133             userActionCancel();
134         }
135     };
136     panRecognizer_->SetOnActionCancel(actionCancel);
137     panRecognizer_->SetIsSystemGesture(true);
138     panRecognizer_->SetRecognizerType(GestureTypeName::PAN_GESTURE);
139 
140     panRecognizer_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
141     panRecognizer_->SetGetEventTargetImpl(getEventTargetImpl);
142     result.emplace_back(panRecognizer_);
143     responseLinkResult.emplace_back(panRecognizer_);
144 }
145 
SetPanEventType(GestureTypeName typeName)146 void PanEventActuator::SetPanEventType(GestureTypeName typeName)
147 {
148     if (panEvents_.empty()) {
149         return;
150     }
151     auto gestureInfo = panRecognizer_->GetOrCreateGestureInfo();
152     CHECK_NULL_VOID(gestureInfo);
153     gestureInfo->SetType(typeName);
154     gestureInfo->SetIsSystemGesture(true);
155 }
156 
157 } // namespace OHOS::Ace::NG
158