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