1 /*
2  * Copyright (c) 2022-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 "core/components_ng/event/click_event.h"
17 
18 #include "base/utils/utils.h"
19 #include "core/accessibility/accessibility_utils.h"
20 #include "core/components/common/layout/constants.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/event/gesture_event_hub.h"
23 #include "core/components_ng/event/gesture_info.h"
24 #include "core/components_ng/gestures/recognizers/click_recognizer.h"
25 
26 namespace OHOS::Ace::NG {
27 
ClickEventActuator(const WeakPtr<GestureEventHub> & gestureEventHub)28 ClickEventActuator::ClickEventActuator(const WeakPtr<GestureEventHub>& gestureEventHub)
29     : gestureEventHub_(gestureEventHub)
30 {}
31 
OnCollectTouchTarget(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,const GetEventTargetImpl & getEventTargetImpl,TouchTestResult & result,ResponseLinkResult & responseLinkResult)32 void ClickEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
33     const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result, ResponseLinkResult& responseLinkResult)
34 {
35     if (clickEvents_.empty() && !clickAfterEvents_ && !userCallback_ && !jsFrameNodeCallback_) {
36         return;
37     }
38     auto gestureHub = gestureEventHub_.Upgrade();
39     CHECK_NULL_VOID(gestureHub);
40     auto frameNode = gestureHub->GetFrameNode();
41     CHECK_NULL_VOID(frameNode);
42 
43     if (!clickRecognizer_) {
44         clickRecognizer_ = MakeRefPtr<ClickRecognizer>();
45     }
46     clickRecognizer_->SetGestureInfo(MakeRefPtr<GestureInfo>(GestureTypeName::CLICK, true));
47     clickRecognizer_->SetRecognizerType(GestureTypeName::CLICK);
48     clickRecognizer_->SetOnAction(GetClickEvent());
49     clickRecognizer_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
50     clickRecognizer_->SetGetEventTargetImpl(getEventTargetImpl);
51     clickRecognizer_->SetDistanceThreshold(distanceThreshold_);
52     auto sysJudgeFunc = GetSysJudgeFunc();
53     if (sysJudgeFunc.has_value()) {
54         clickRecognizer_->SetSysGestureJudge(sysJudgeFunc.value());
55     }
56     result.emplace_back(clickRecognizer_);
57     responseLinkResult.emplace_back(clickRecognizer_);
58 }
59 
GetSysJudgeFunc() const60 std::optional<GestureJudgeFunc> ClickEventActuator::GetSysJudgeFunc() const
61 {
62     for (const auto& callback : clickEvents_) {
63         if (callback->HasSysGestureJudge()) {
64             return callback->GetSysJudge();
65         }
66     }
67     return nullptr;
68 }
69 
GetClickEvent()70 GestureEventFunc ClickEventActuator::GetClickEvent()
71 {
72     auto callback = [weak = WeakClaim(this)](GestureEvent& info) {
73         auto actuator = weak.Upgrade();
74         CHECK_NULL_VOID(actuator);
75         auto clickEvents = actuator->clickEvents_;
76         for (const auto& callback : clickEvents) {
77             if (callback) {
78                 (*callback)(info);
79             }
80         }
81         if (actuator->userCallback_) {
82             // actuator->userCallback_ may be overwritten in its invoke so we copy it first
83             auto userCallback = actuator->userCallback_;
84             (*userCallback)(info);
85         }
86         if (actuator->clickAfterEvents_) {
87             auto clickAfterEvents = actuator->clickAfterEvents_;
88             (*clickAfterEvents)(info);
89         }
90         if (actuator->jsFrameNodeCallback_) {
91             auto jsFrameNodeCallback = actuator->jsFrameNodeCallback_;
92             (*jsFrameNodeCallback)(info);
93         }
94         if (actuator->onAccessibilityEventFunc_) {
95             actuator->onAccessibilityEventFunc_(AccessibilityEventType::CLICK);
96         }
97     };
98     return callback;
99 }
100 
101 } // namespace OHOS::Ace::NG
102