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/gestures/timeout_recognizer.h"
17
18 namespace OHOS::Ace {
SingleChildGestureRecognizer(WeakPtr<PipelineBase> context)19 SingleChildGestureRecognizer::SingleChildGestureRecognizer(WeakPtr<PipelineBase> context)
20 : context_(std::move(context))
21 {
22 }
23
SingleChildGestureRecognizer(WeakPtr<PipelineBase> context,RefPtr<GestureRecognizer> child)24 SingleChildGestureRecognizer::SingleChildGestureRecognizer(WeakPtr<PipelineBase> context,
25 RefPtr<GestureRecognizer> child)
26 : child_(std::move(child)),
27 context_(std::move(context))
28 {
29 child_->SetGestureGroup(AceType::WeakClaim(this));
30 child_->SetIsExternalGesture(true);
31 }
32
~SingleChildGestureRecognizer()33 SingleChildGestureRecognizer::~SingleChildGestureRecognizer()
34 {
35 }
36
SetChild(RefPtr<GestureRecognizer> recognizer)37 void SingleChildGestureRecognizer::SetChild(RefPtr<GestureRecognizer> recognizer)
38 {
39 child_ = recognizer;
40 child_->SetGestureGroup(AceType::WeakClaim(this));
41 child_->SetIsExternalGesture(true);
42 }
43
ReconcileFrom(const RefPtr<GestureRecognizer> & recognizer)44 bool SingleChildGestureRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
45 {
46 auto rhs = AceType::DynamicCast<SingleChildGestureRecognizer>(recognizer);
47 if (!rhs) {
48 return false;
49 }
50
51 if (child_ == nullptr || rhs->child_ == nullptr) {
52 return false;
53 }
54
55 if (!child_->ReconcileFrom(rhs->GetChild())) {
56 return false;
57 }
58
59 return MultiFingersRecognizer::ReconcileFrom(recognizer);
60 }
61
AddToReferee(size_t touchId,const RefPtr<GestureRecognizer> & recognizer)62 void SingleChildGestureRecognizer::AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
63 {
64 MultiFingersRecognizer::AddToReferee(touchId, AceType::Claim(this));
65 }
66
DelFromReferee(size_t touchId,const RefPtr<GestureRecognizer> & recognizer)67 void SingleChildGestureRecognizer::DelFromReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
68 {
69 MultiFingersRecognizer::DelFromReferee(touchId, AceType::Claim(this));
70 }
71
GetChild() const72 RefPtr<GestureRecognizer> SingleChildGestureRecognizer::GetChild() const
73 {
74 return child_;
75 }
76
TimeoutRecognizer(WeakPtr<PipelineBase> context,std::chrono::duration<float> timeout)77 TimeoutRecognizer::TimeoutRecognizer(WeakPtr<PipelineBase> context,
78 std::chrono::duration<float> timeout)
79 : SingleChildGestureRecognizer(context),
80 context_(context),
81 timeout_(timeout)
82 {
83 }
84
TimeoutRecognizer(WeakPtr<PipelineBase> context,RefPtr<GestureRecognizer> child,std::chrono::duration<float> timeout)85 TimeoutRecognizer::TimeoutRecognizer(WeakPtr<PipelineBase> context,
86 RefPtr<GestureRecognizer> child, std::chrono::duration<float> timeout)
87 : SingleChildGestureRecognizer(context, std::move(child)),
88 context_(context),
89 timeout_(timeout)
90 {
91 }
92
OnAccepted(size_t touchId)93 void TimeoutRecognizer::OnAccepted(size_t touchId)
94 {
95 start_.reset();
96 if (GetChild()->GetDetectState() == DetectState::DETECTED) {
97 GetChild()->SetCoordinateOffset(coordinateOffset_);
98 GetChild()->OnAccepted(touchId);
99 }
100
101 SingleChildGestureRecognizer::OnAccepted(touchId);
102 }
103
OnRejected(size_t touchId)104 void TimeoutRecognizer::OnRejected(size_t touchId)
105 {
106 GetChild()->OnRejected(touchId);
107
108 SingleChildGestureRecognizer::OnRejected(touchId);
109 }
110
ReconcileFrom(const RefPtr<GestureRecognizer> & recognizer)111 bool TimeoutRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
112 {
113 auto rhs = AceType::DynamicCast<TimeoutRecognizer>(recognizer);
114 if (!rhs) {
115 return false;
116 }
117
118 timeout_ = rhs->timeout_;
119
120 return SingleChildGestureRecognizer::ReconcileFrom(recognizer);
121 }
122
BatchAdjudicate(const std::set<size_t> & touchIds,const RefPtr<GestureRecognizer> & recognizer,GestureDisposal disposal)123 void TimeoutRecognizer::BatchAdjudicate(const std::set<size_t>& touchIds,
124 const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal)
125 {
126 if (disposal == GestureDisposal::ACCEPT) {
127 start_.reset();
128 touchIds_.clear();
129 GetChild()->SetRefereeState(RefereeState::SUCCEED);
130 for (const auto& touchId : touchIds) {
131 GetChild()->OnAccepted(touchId);
132 }
133
134 state_ = DetectState::DETECTED;
135 Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
136 } else if (disposal == GestureDisposal::REJECT) {
137 touchIds_.clear();
138 start_.reset();
139
140 GetChild()->SetRefereeState(RefereeState::FAIL);
141 for (const auto& touchId : touchIds) {
142 GetChild()->OnRejected(touchId);
143 }
144
145 state_ = DetectState::READY;
146 GetChild()->SetRefereeState(RefereeState::DETECTING);
147
148 Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
149 } else if (disposal == GestureDisposal::PENDING) {
150 touchIds_.clear();
151 start_.reset();
152
153 GetChild()->SetRefereeState(RefereeState::PENDING);
154 Adjudicate(AceType::Claim(this), GestureDisposal::PENDING);
155 }
156 }
157
HandleTouchDownEvent(const TouchEvent & event)158 void TimeoutRecognizer::HandleTouchDownEvent(const TouchEvent& event)
159 {
160 if (!start_) {
161 start_ = event.time;
162 touchIds_.insert(event.id);
163 GetChild()->HandleEvent(event);
164 return;
165 }
166
167 if (!CheckTimeout(event.time)) {
168 return;
169 }
170 }
171
HandleTouchUpEvent(const TouchEvent & event)172 void TimeoutRecognizer::HandleTouchUpEvent(const TouchEvent& event)
173 {
174 if (!CheckTimeout(event.time)) {
175 return;
176 }
177
178 GetChild()->HandleEvent(event);
179 }
180
HandleTouchMoveEvent(const TouchEvent & event)181 void TimeoutRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
182 {
183 if (!CheckTimeout(event.time)) {
184 return;
185 }
186
187 GetChild()->HandleEvent(event);
188 }
189
HandleTouchCancelEvent(const TouchEvent & event)190 void TimeoutRecognizer::HandleTouchCancelEvent(const TouchEvent& event)
191 {
192 if (!CheckTimeout(event.time)) {
193 return;
194 }
195
196 GetChild()->HandleEvent(event);
197 }
198
HandleTouchDownEvent(const AxisEvent & event)199 void TimeoutRecognizer::HandleTouchDownEvent(const AxisEvent& event)
200 {
201 if (!start_) {
202 start_ = event.time;
203 touchIds_.insert(0);
204 GetChild()->HandleEvent(event);
205 return;
206 }
207
208 if (!CheckTimeout(event.time)) {
209 return;
210 }
211 }
212
HandleTouchUpEvent(const AxisEvent & event)213 void TimeoutRecognizer::HandleTouchUpEvent(const AxisEvent& event)
214 {
215 if (!CheckTimeout(event.time)) {
216 return;
217 }
218
219 GetChild()->HandleEvent(event);
220 }
221
HandleTouchMoveEvent(const AxisEvent & event)222 void TimeoutRecognizer::HandleTouchMoveEvent(const AxisEvent& event)
223 {
224 if (!CheckTimeout(event.time)) {
225 return;
226 }
227
228 GetChild()->HandleEvent(event);
229 }
230
HandleTouchCancelEvent(const AxisEvent & event)231 void TimeoutRecognizer::HandleTouchCancelEvent(const AxisEvent& event)
232 {
233 if (!CheckTimeout(event.time)) {
234 return;
235 }
236
237 GetChild()->HandleEvent(event);
238 }
239
CheckTimeout(TimeStamp time)240 bool TimeoutRecognizer::CheckTimeout(TimeStamp time)
241 {
242 if (start_ && time > (*start_ + timeout_)) {
243 start_.reset();
244
245 std::set<size_t> ids;
246 std::swap(ids, touchIds_);
247 GetChild()->SetRefereeState(RefereeState::FAIL);
248 for (auto const& touchId : touchIds_) {
249 GetChild()->OnRejected(touchId);
250 }
251
252 state_ = DetectState::READY;
253 GetChild()->SetRefereeState(RefereeState::DETECTING);
254
255 BatchAdjudicate(ids, GetChild(), GestureDisposal::REJECT);
256
257 return false;
258 }
259
260 return true;
261 }
262 } // namespace OHOS::Ace
263