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/gestures/recognizers/recognizer_group.h"
17
18 #include "base/memory/ace_type.h"
19 #include "base/memory/referenced.h"
20 #include "base/utils/utils.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/gestures/recognizers/gesture_recognizer.h"
23 #include "core/components_ng/gestures/gesture_group.h"
24
25 namespace OHOS::Ace::NG {
26
OnBeginGestureReferee(int32_t touchId,bool needUpdateChild)27 void RecognizerGroup::OnBeginGestureReferee(int32_t touchId, bool needUpdateChild)
28 {
29 MultiFingersRecognizer::OnBeginGestureReferee(touchId);
30 if (!needUpdateChild) {
31 return;
32 }
33 for (const auto& child : recognizers_) {
34 if (child) {
35 child->BeginReferee(touchId, needUpdateChild);
36 }
37 }
38 }
39
CreateGestureFromRecognizer() const40 RefPtr<Gesture> RecognizerGroup::CreateGestureFromRecognizer() const
41 {
42 GestureMode mode = GetGestureMode();
43 RefPtr<GestureGroup> gestureGroup = AceType::MakeRefPtr<GestureGroup>(mode);
44 for (const auto& child : recognizers_) {
45 if (!child) {
46 continue;
47 }
48 RefPtr<Gesture> gesture = child->CreateGestureFromRecognizer();
49 if (gesture) {
50 gestureGroup->AddGesture(gesture);
51 }
52 }
53 return gestureGroup;
54 }
55
OnFinishGestureReferee(int32_t touchId,bool isBlocked)56 void RecognizerGroup::OnFinishGestureReferee(int32_t touchId, bool isBlocked)
57 {
58 for (const auto& child : recognizers_) {
59 if (child) {
60 child->FinishReferee(touchId, isBlocked);
61 }
62 }
63 MultiFingersRecognizer::OnFinishGestureReferee(touchId, isBlocked);
64 }
65
GetGroupRecognizer()66 const std::list<RefPtr<NGGestureRecognizer>>& RecognizerGroup::GetGroupRecognizer()
67 {
68 return recognizers_;
69 }
70
AddChildren(const std::list<RefPtr<NGGestureRecognizer>> & recognizers)71 void RecognizerGroup::AddChildren(const std::list<RefPtr<NGGestureRecognizer>>& recognizers)
72 {
73 for (const auto& child : recognizers) {
74 if (child && !Existed(child) && child->SetGestureGroup(AceType::WeakClaim(this))) {
75 recognizers_.emplace_back(child);
76 }
77 }
78 }
79
CheckStates(size_t touchId)80 RefereeState RecognizerGroup::CheckStates(size_t touchId)
81 {
82 int count = 0;
83 for (auto& recognizer : recognizers_) {
84 if (AceType::InstanceOf<MultiFingersRecognizer>(recognizer) && !recognizer->CheckTouchId(touchId)) {
85 continue;
86 }
87 if (!AceType::InstanceOf<RecognizerGroup>(recognizer)) {
88 if (recognizer->GetRefereeState() != RefereeState::SUCCEED_BLOCKED &&
89 recognizer->GetRefereeState() != RefereeState::SUCCEED &&
90 recognizer->GetRefereeState() != RefereeState::FAIL &&
91 recognizer->GetRefereeState() != RefereeState::READY) {
92 count++;
93 break;
94 }
95 continue;
96 }
97 auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
98 if (group) {
99 auto state = group->CheckStates(touchId);
100 if (state == RefereeState::PENDING) {
101 count++;
102 break;
103 }
104 }
105 }
106 if (count > 0) {
107 return RefereeState::PENDING;
108 } else {
109 return RefereeState::READY;
110 }
111 }
112
ForceReject()113 void RecognizerGroup::ForceReject()
114 {
115 for (auto& recognizer : recognizers_) {
116 if (!AceType::InstanceOf<RecognizerGroup>(recognizer)) {
117 if (recognizer->IsBridgeMode()) {
118 continue;
119 }
120 if (recognizer->GetRefereeState() != RefereeState::SUCCEED_BLOCKED &&
121 recognizer->GetRefereeState() != RefereeState::SUCCEED &&
122 recognizer->GetRefereeState() != RefereeState::FAIL) {
123 recognizer->OnRejected();
124 recognizer->OnRejectBridgeObj();
125 }
126 continue;
127 }
128 auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
129 if (group) {
130 group->ForceReject();
131 }
132 }
133 if (GetRefereeState() != RefereeState::FAIL) {
134 OnRejected();
135 }
136 }
137
Existed(const RefPtr<NGGestureRecognizer> & recognizer)138 bool RecognizerGroup::Existed(const RefPtr<NGGestureRecognizer>& recognizer)
139 {
140 CHECK_NULL_RETURN(recognizer, false);
141
142 if (recognizers_.empty()) {
143 return false;
144 }
145 auto result = std::find(recognizers_.cbegin(), recognizers_.cend(), recognizer);
146 return result != recognizers_.cend();
147 }
148
OnFlushTouchEventsBegin()149 void RecognizerGroup::OnFlushTouchEventsBegin()
150 {
151 for (const auto& recognizer : recognizers_) {
152 if (recognizer) {
153 recognizer->OnFlushTouchEventsBegin();
154 }
155 }
156 }
157
OnFlushTouchEventsEnd()158 void RecognizerGroup::OnFlushTouchEventsEnd()
159 {
160 for (const auto& recognizer : recognizers_) {
161 if (recognizer) {
162 recognizer->OnFlushTouchEventsEnd();
163 }
164 }
165 }
166
OnResetStatus()167 void RecognizerGroup::OnResetStatus()
168 {
169 MultiFingersRecognizer::OnResetStatus();
170 if (!remainChildOnResetStatus_) {
171 for (const auto& child : recognizers_) {
172 if (child) {
173 child->SetGestureGroup(nullptr);
174 child->ResetEventImportGestureGroup();
175 }
176 }
177 recognizers_.clear();
178 }
179 }
180
CheckAllFailed()181 bool RecognizerGroup::CheckAllFailed()
182 {
183 auto notFailMember =
184 std::find_if(std::begin(recognizers_), std::end(recognizers_), [](const RefPtr<NGGestureRecognizer>& member) {
185 return member && member->GetRefereeState() != RefereeState::FAIL;
186 });
187
188 return notFailMember == recognizers_.end();
189 }
190
GroupAdjudicate(const RefPtr<NGGestureRecognizer> & recognizer,GestureDisposal disposal)191 void RecognizerGroup::GroupAdjudicate(const RefPtr<NGGestureRecognizer>& recognizer, GestureDisposal disposal)
192 {
193 disposal_ = disposal;
194 NGGestureRecognizer::BatchAdjudicate(recognizer, disposal);
195 }
196
SetRecognizerInfoRecursively(const Offset & coordinateOffset,const RefPtr<NG::FrameNode> & node,const RefPtr<NG::TargetComponent> & targetComponent,const GetEventTargetImpl & getEventTargetImpl)197 void RecognizerGroup::SetRecognizerInfoRecursively(const Offset& coordinateOffset, const RefPtr<NG::FrameNode>& node,
198 const RefPtr<NG::TargetComponent>& targetComponent, const GetEventTargetImpl& getEventTargetImpl)
199 {
200 for (const auto& item : recognizers_) {
201 item->SetCoordinateOffset(coordinateOffset);
202 item->AttachFrameNode(WeakPtr<FrameNode>(node));
203 item->SetTargetComponent(targetComponent);
204 item->SetGetEventTargetImpl(getEventTargetImpl);
205 auto group = AceType::DynamicCast<RecognizerGroup>(item);
206 if (group) {
207 group->SetRecognizerInfoRecursively(coordinateOffset, node, targetComponent, getEventTargetImpl);
208 }
209 }
210 }
211
AddHittedRecognizerType(std::map<std::string,std::list<TouchTestResultInfo>> & hittedRecognizerInfo)212 void RecognizerGroup::AddHittedRecognizerType(
213 std::map<std::string, std::list<TouchTestResultInfo>>& hittedRecognizerInfo)
214 {
215 for (const auto& item : recognizers_) {
216 if (AceType::InstanceOf<NG::MultiFingersRecognizer>(item) && !AceType::InstanceOf<NG::RecognizerGroup>(item)) {
217 auto node = item->GetAttachedNode().Upgrade();
218 if (!node) {
219 hittedRecognizerInfo.emplace(AceType::TypeName(item), std::list<NG::TouchTestResultInfo>());
220 continue;
221 }
222 auto frameNode = AceType::DynamicCast<NG::FrameNode>(node);
223 if (!frameNode) {
224 hittedRecognizerInfo.emplace(AceType::TypeName(item), std::list<NG::TouchTestResultInfo>());
225 continue;
226 }
227 hittedRecognizerInfo[AceType::TypeName(item)].emplace_back(NG::TouchTestResultInfo {
228 frameNode->GetId(), frameNode->GetTag(), frameNode->GetInspectorIdValue("") });
229 }
230 auto group = AceType::DynamicCast<RecognizerGroup>(item);
231 if (group) {
232 group->AddHittedRecognizerType(hittedRecognizerInfo);
233 }
234 }
235 }
236
CleanRecognizerState()237 void RecognizerGroup::CleanRecognizerState()
238 {
239 for (const auto& child : recognizers_) {
240 if (child) {
241 child->CleanRecognizerState();
242 }
243 }
244 if ((refereeState_ == RefereeState::SUCCEED ||
245 refereeState_ == RefereeState::FAIL ||
246 refereeState_ == RefereeState::DETECTING) &&
247 currentFingers_ == 0) {
248 refereeState_ = RefereeState::READY;
249 disposal_ = GestureDisposal::NONE;
250 }
251 }
252
IsReady()253 bool RecognizerGroup::IsReady()
254 {
255 if (refereeState_ != RefereeState::READY) {
256 return false;
257 }
258 for (const auto& child : recognizers_) {
259 if (child && !child->IsReady()) {
260 return false;
261 }
262 }
263 return true;
264 }
265 } // namespace OHOS::Ace::NG
266