1 /*
2 * Copyright (c) 2021-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/pan_recognizer.h"
17 #include <map>
18
19 #include "base/geometry/offset.h"
20 #include "base/log/log.h"
21 #include "base/ressched/ressched_report.h"
22 #include "base/utils/utils.h"
23 #include "core/components_ng/gestures/gesture_referee.h"
24 #include "core/components_ng/gestures/recognizers/gesture_recognizer.h"
25 #include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
26 #include "core/event/axis_event.h"
27 #include "core/pipeline_ng/pipeline_context.h"
28
29 namespace OHOS::Ace::NG {
30
31 namespace {
32
33 constexpr int32_t MAX_PAN_FINGERS = 10;
34 constexpr int32_t DEFAULT_PAN_FINGERS = 1;
35 constexpr Dimension DISTANCE_PER_MOUSE_DEGREE = LINE_HEIGHT_DESKTOP * LINE_NUMBER_DESKTOP / MOUSE_WHEEL_DEGREES;
36 constexpr int32_t AXIS_PAN_FINGERS = 1;
37
38 } // namespace
39
PanRecognizer(int32_t fingers,const PanDirection & direction,double distance)40 PanRecognizer::PanRecognizer(int32_t fingers, const PanDirection& direction, double distance)
41 : MultiFingersRecognizer(fingers), direction_(direction), distance_(distance), mouseDistance_(distance),
42 newFingers_(fingers_), newDistance_(distance_), newDirection_(direction_)
43 {
44 if ((direction_.type & PanDirection::VERTICAL) == 0) {
45 velocityTracker_ = VelocityTracker(Axis::HORIZONTAL);
46 } else if ((direction_.type & PanDirection::HORIZONTAL) == 0) {
47 velocityTracker_ = VelocityTracker(Axis::VERTICAL);
48 }
49 if (fingers_ > MAX_PAN_FINGERS || fingers_ < DEFAULT_PAN_FINGERS) {
50 LOGW("panRecognizer fingers_ is illegal, change to DEFAULT_PAN_FINGERS.");
51 fingers_ = DEFAULT_PAN_FINGERS;
52 }
53 }
54
PanRecognizer(const RefPtr<PanGestureOption> & panGestureOption)55 PanRecognizer::PanRecognizer(const RefPtr<PanGestureOption>& panGestureOption) : panGestureOption_(panGestureOption)
56 {
57 auto context = PipelineContext::GetCurrentContext();
58 CHECK_NULL_VOID(context);
59 uint32_t directNum = panGestureOption->GetDirection().type;
60 double distanceNumber = panGestureOption->GetDistance();
61 int32_t fingersNumber = panGestureOption->GetFingers();
62
63 distance_ = LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PAN_DISTANCE.ConvertToPx() : distanceNumber;
64 fingers_ = fingersNumber;
65 if (fingers_ > MAX_PAN_FINGERS || fingers_ < DEFAULT_PAN_FINGERS) {
66 LOGW("panRecognizer fingers_ is illegal, change to DEFAULT_PAN_FINGERS.");
67 fingers_ = DEFAULT_PAN_FINGERS;
68 }
69
70 if (directNum >= PanDirection::NONE && directNum <= PanDirection::ALL) {
71 direction_.type = directNum;
72 }
73
74 newFingers_ = fingers_;
75 newDistance_ = distance_;
76 mouseDistance_ = distance_;
77 newDirection_ = direction_;
78
79 PanFingersFuncType changeFingers = [weak = AceType::WeakClaim(this)](int32_t fingers) {
80 auto panRecognizer = weak.Upgrade();
81 CHECK_NULL_VOID_NOLOG(panRecognizer);
82 panRecognizer->ChangeFingers(fingers);
83 };
84 onChangeFingers_ = OnPanFingersFunc(changeFingers);
85 panGestureOption_->SetOnPanFingersId(onChangeFingers_);
86
87 PanDirectionFuncType changeDirection = [weak = AceType::WeakClaim(this)](const PanDirection& direction) {
88 auto panRecognizer = weak.Upgrade();
89 CHECK_NULL_VOID_NOLOG(panRecognizer);
90 panRecognizer->ChangeDirection(direction);
91 };
92 onChangeDirection_ = OnPanDirectionFunc(changeDirection);
93 panGestureOption_->SetOnPanDirectionId(onChangeDirection_);
94
95 PanDistanceFuncType changeDistance = [weak = AceType::WeakClaim(this)](double distance) {
96 auto panRecognizer = weak.Upgrade();
97 CHECK_NULL_VOID_NOLOG(panRecognizer);
98 panRecognizer->ChangeDistance(distance);
99 };
100 onChangeDistance_ = OnPanDistanceFunc(changeDistance);
101 panGestureOption_->SetOnPanDistanceId(onChangeDistance_);
102 }
103
OnAccepted()104 void PanRecognizer::OnAccepted()
105 {
106 refereeState_ = RefereeState::SUCCEED;
107 SendCallbackMsg(onActionStart_);
108 SendCallbackMsg(onActionUpdate_);
109 }
110
OnRejected()111 void PanRecognizer::OnRejected()
112 {
113 LOGD("pan gesture has been rejected!");
114 // fix griditem drag interrupted by click while pull moving
115 if (refereeState_ != RefereeState::SUCCEED) {
116 refereeState_ = RefereeState::FAIL;
117 }
118 }
119
UpdateTouchPointInVelocityTracker(const TouchEvent & event,bool end)120 void PanRecognizer::UpdateTouchPointInVelocityTracker(const TouchEvent& event, bool end)
121 {
122 PointF originPoint(event.x, event.y);
123 PointF windowPoint = originPoint;
124 Transform(windowPoint, originPoint);
125
126 TouchEvent transformEvent = event;
127 transformEvent.x = windowPoint.GetX();
128 transformEvent.y = windowPoint.GetY();
129 velocityTracker_.UpdateTouchPoint(transformEvent, end);
130 }
131
HandleTouchDownEvent(const TouchEvent & event)132 void PanRecognizer::HandleTouchDownEvent(const TouchEvent& event)
133 {
134 LOGI("pan recognizer receives %{public}d touch down event, begin to detect pan event", event.id);
135 fingers_ = newFingers_;
136 distance_ = newDistance_;
137 direction_ = newDirection_;
138
139 if (direction_.type == PanDirection::NONE) {
140 LOGI("the direction type is none");
141 Adjudicate(Claim(this), GestureDisposal::REJECT);
142 return;
143 }
144 if (event.sourceType == SourceType::MOUSE && !isAllowMouse_) {
145 LOGI("mouse pan is not allowed");
146 Adjudicate(Claim(this), GestureDisposal::REJECT);
147 return;
148 }
149
150 deviceId_ = event.deviceId;
151 deviceType_ = event.sourceType;
152 lastTouchEvent_ = event;
153 touchPoints_[event.id] = event;
154 touchPointsDistance_[event.id] = Offset(0.0, 0.0);
155 if (event.sourceType == SourceType::MOUSE) {
156 inputEventType_ = InputEventType::MOUSE_BUTTON;
157 } else {
158 inputEventType_ = InputEventType::TOUCH_SCREEN;
159 }
160
161 auto fingerNum = static_cast<int32_t>(touchPoints_.size());
162
163 if (fingerNum == fingers_) {
164 velocityTracker_.Reset();
165 UpdateTouchPointInVelocityTracker(event);
166 refereeState_ = RefereeState::DETECTING;
167 }
168 }
169
HandleTouchDownEvent(const AxisEvent & event)170 void PanRecognizer::HandleTouchDownEvent(const AxisEvent& event)
171 {
172 LOGI("pan recognizer receives axis start event, begin to detect pan event");
173 fingers_ = newFingers_;
174 distance_ = newDistance_;
175 direction_ = newDirection_;
176
177 if (fingers_ != AXIS_PAN_FINGERS) {
178 Adjudicate(Claim(this), GestureDisposal::REJECT);
179 return;
180 }
181
182 if (direction_.type == PanDirection::NONE) {
183 LOGI("the direction type is none");
184 Adjudicate(Claim(this), GestureDisposal::REJECT);
185 return;
186 }
187
188 touchPoints_[event.id] = TouchEvent();
189 touchPoints_[event.id].id = event.id;
190 touchPoints_[event.id].x = event.x;
191 touchPoints_[event.id].y = event.y;
192 touchPoints_[event.id].sourceType = event.sourceType;
193 touchPoints_[event.id].sourceTool = event.sourceTool;
194 deviceId_ = event.deviceId;
195 deviceType_ = event.sourceType;
196 lastAxisEvent_ = event;
197 inputEventType_ = InputEventType::AXIS;
198 refereeState_ = RefereeState::DETECTING;
199 }
200
HandleTouchUpEvent(const TouchEvent & event)201 void PanRecognizer::HandleTouchUpEvent(const TouchEvent& event)
202 {
203 LOGI("pan recognizer receives %{public}d touch up event", event.id);
204 if (currentFingers_ < fingers_) {
205 LOGW("PanGesture current finger number is less than requiried finger number.");
206 return;
207 }
208 ResSchedReport::GetInstance().ResSchedDataReport("click");
209 globalPoint_ = Point(event.x, event.y);
210 lastTouchEvent_ = event;
211 UpdateTouchPointInVelocityTracker(event, true);
212
213 if ((refereeState_ != RefereeState::SUCCEED) && (refereeState_ != RefereeState::FAIL)) {
214 Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
215 #ifdef ENABLE_DRAG_FRAMEWORK
216 if (isForDrag_ && onActionCancel_ && *onActionCancel_) {
217 (*onActionCancel_)();
218 }
219 #endif // ENABLE_DRAG_FRAMEWORK
220 return;
221 }
222
223 if (refereeState_ == RefereeState::SUCCEED) {
224 if (static_cast<int32_t>(touchPoints_.size()) == fingers_) {
225 // last one to fire end.
226 SendCallbackMsg(onActionEnd_);
227 }
228 }
229 }
230
HandleTouchUpEvent(const AxisEvent & event)231 void PanRecognizer::HandleTouchUpEvent(const AxisEvent& event)
232 {
233 LOGI("pan recognizer receives axis end event");
234 globalPoint_ = Point(event.x, event.y);
235 if ((refereeState_ != RefereeState::SUCCEED) && (refereeState_ != RefereeState::FAIL)) {
236 Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
237 return;
238 }
239
240 if (refereeState_ == RefereeState::SUCCEED) {
241 // AxisEvent is single one.
242 SendCallbackMsg(onActionEnd_);
243 }
244 }
245
HandleTouchMoveEvent(const TouchEvent & event)246 void PanRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
247 {
248 LOGD("pan recognizer receives touch move event");
249 if (currentFingers_ < fingers_) {
250 LOGW("PanGesture current finger number is less than requiried finger number.");
251 return;
252 }
253 globalPoint_ = Point(event.x, event.y);
254 lastTouchEvent_ = event;
255 PointF originPoint(event.GetOffset().GetX(), event.GetOffset().GetY());
256 PointF originTouchPoint(touchPoints_[event.id].GetOffset().GetX(), touchPoints_[event.id].GetOffset().GetY());
257 PointF windowPoint = originPoint;
258 PointF windowTouchPoint = originTouchPoint;
259 Transform(windowPoint, originPoint);
260 Transform(windowTouchPoint, originTouchPoint);
261 delta_ =
262 (Offset(windowPoint.GetX(), windowPoint.GetY()) - Offset(windowTouchPoint.GetX(), windowTouchPoint.GetY()));
263 mainDelta_ = GetMainAxisDelta();
264 UpdateTouchPointInVelocityTracker(event);
265 averageDistance_ += delta_;
266 touchPoints_[event.id] = event;
267 touchPointsDistance_[event.id] += delta_;
268 time_ = event.time;
269
270 if (static_cast<int32_t>(touchPoints_.size()) < fingers_) {
271 return;
272 }
273 if (refereeState_ == RefereeState::DETECTING) {
274 auto result = IsPanGestureAccept();
275 if (result == GestureAcceptResult::ACCEPT) {
276 Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
277 } else if (result == GestureAcceptResult::REJECT) {
278 LOGW("pan recognizer reject");
279 Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
280 }
281 } else if (refereeState_ == RefereeState::SUCCEED) {
282 if ((direction_.type & PanDirection::VERTICAL) == 0) {
283 averageDistance_.SetY(0.0);
284 for (auto& element : touchPointsDistance_) {
285 element.second.SetY(0.0);
286 }
287 } else if ((direction_.type & PanDirection::HORIZONTAL) == 0) {
288 averageDistance_.SetX(0.0);
289 for (auto& element : touchPointsDistance_) {
290 element.second.SetX(0.0);
291 }
292 }
293 LOGD("pan recognizer detected successful");
294 if (isFlushTouchEventsEnd_) {
295 SendCallbackMsg(onActionUpdate_);
296 }
297 }
298 }
299
OnFlushTouchEventsBegin()300 void PanRecognizer::OnFlushTouchEventsBegin()
301 {
302 isFlushTouchEventsEnd_ = false;
303 }
304
OnFlushTouchEventsEnd()305 void PanRecognizer::OnFlushTouchEventsEnd()
306 {
307 isFlushTouchEventsEnd_ = true;
308 }
309
HandleTouchMoveEvent(const AxisEvent & event)310 void PanRecognizer::HandleTouchMoveEvent(const AxisEvent& event)
311 {
312 LOGD("pan recognizer receives axis update event");
313 if (fingers_ != AXIS_PAN_FINGERS) {
314 return;
315 }
316 globalPoint_ = Point(event.x, event.y);
317 auto distancePerMouseDegreePx = DISTANCE_PER_MOUSE_DEGREE.ConvertToPx();
318 if (direction_.type == PanDirection::ALL || (direction_.type & PanDirection::HORIZONTAL) == 0) {
319 // PanRecognizer Direction: Vertical or ALL
320 delta_ =
321 Offset(-event.horizontalAxis * distancePerMouseDegreePx, -event.verticalAxis * distancePerMouseDegreePx);
322 } else if ((direction_.type & PanDirection::VERTICAL) == 0) {
323 // PanRecognizer Direction: Horizontal
324 if (NearZero(event.horizontalAxis)) {
325 delta_ = Offset(-event.verticalAxis * distancePerMouseDegreePx, 0);
326 } else {
327 delta_ = Offset(
328 -event.horizontalAxis * distancePerMouseDegreePx, -event.verticalAxis * distancePerMouseDegreePx);
329 }
330 }
331
332 mainDelta_ = GetMainAxisDelta();
333 averageDistance_ += delta_;
334 lastAxisEvent_ = event;
335 time_ = event.time;
336
337 if (refereeState_ == RefereeState::DETECTING) {
338 auto result = IsPanGestureAccept();
339 if (result == GestureAcceptResult::ACCEPT) {
340 Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
341 } else if (result == GestureAcceptResult::REJECT) {
342 LOGW("pan recognizer reject");
343 Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
344 }
345 } else if (refereeState_ == RefereeState::SUCCEED) {
346 if ((direction_.type & PanDirection::VERTICAL) == 0) {
347 averageDistance_.SetY(0.0);
348 } else if ((direction_.type & PanDirection::HORIZONTAL) == 0) {
349 averageDistance_.SetX(0.0);
350 }
351
352 LOGD("pan recognizer detected successful");
353 SendCallbackMsg(onActionUpdate_);
354 }
355 }
356
HandleTouchCancelEvent(const TouchEvent &)357 void PanRecognizer::HandleTouchCancelEvent(const TouchEvent& /*event*/)
358 {
359 LOGD("pan recognizer receives touch cancel event");
360 if ((refereeState_ != RefereeState::SUCCEED) && (refereeState_ != RefereeState::FAIL)) {
361 Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
362 return;
363 }
364
365 if (refereeState_ == RefereeState::SUCCEED) {
366 // AxisEvent is single one.
367 SendCancelMsg();
368 }
369 }
370
HandleTouchCancelEvent(const AxisEvent &)371 void PanRecognizer::HandleTouchCancelEvent(const AxisEvent& /*event*/)
372 {
373 LOGD("pan recognizer receives touch cancel event");
374 if ((refereeState_ != RefereeState::SUCCEED) && (refereeState_ != RefereeState::FAIL)) {
375 Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
376 return;
377 }
378
379 if (refereeState_ == RefereeState::SUCCEED) {
380 SendCancelMsg();
381 }
382 }
383
CalculateTruthFingers(bool isDirectionUp) const384 bool PanRecognizer::CalculateTruthFingers(bool isDirectionUp) const
385 {
386 int32_t totalFingers = 0;
387 float totalDistance = 0.0f;
388 for (auto& element : touchPointsDistance_) {
389 auto each_point_move = element.second.GetY();
390 if (GreatNotEqual(each_point_move, 0.0) && isDirectionUp) {
391 totalFingers++;
392 totalDistance += each_point_move;
393 } else if (LessNotEqual(each_point_move, 0.0) && !isDirectionUp) {
394 totalFingers++;
395 totalDistance -= each_point_move;
396 }
397 }
398 auto judgeDistance = distance_;
399 if (deviceType_ == SourceType::MOUSE) {
400 judgeDistance = mouseDistance_;
401 }
402 return GreatNotEqual(totalDistance, judgeDistance) && totalFingers >= fingers_;
403 }
404
IsPanGestureAccept() const405 PanRecognizer::GestureAcceptResult PanRecognizer::IsPanGestureAccept() const
406 {
407 auto judgeDistance = distance_;
408 if (deviceType_ == SourceType::MOUSE) { // use mouseDistance_
409 judgeDistance = mouseDistance_;
410 }
411
412 if ((direction_.type & PanDirection::ALL) == PanDirection::ALL) {
413 double offset = averageDistance_.GetDistance();
414 if (fabs(offset) < judgeDistance) {
415 return GestureAcceptResult::DETECTING;
416 }
417 return GestureAcceptResult::ACCEPT;
418 }
419
420 if (fabs(averageDistance_.GetX()) > fabs(averageDistance_.GetY())) {
421 if ((direction_.type & PanDirection::HORIZONTAL) != 0) {
422 double offset = averageDistance_.GetX();
423 if (fabs(offset) < judgeDistance) {
424 return GestureAcceptResult::DETECTING;
425 }
426 if ((direction_.type & PanDirection::LEFT) == 0 && offset < 0) {
427 return GestureAcceptResult::REJECT;
428 }
429 if ((direction_.type & PanDirection::RIGHT) == 0 && offset > 0) {
430 return GestureAcceptResult::REJECT;
431 }
432 return GestureAcceptResult::ACCEPT;
433 }
434 return GestureAcceptResult::DETECTING;
435 }
436 if ((direction_.type & PanDirection::VERTICAL) != 0) {
437 double offset = averageDistance_.GetY();
438 if (fabs(offset) < judgeDistance) {
439 return GestureAcceptResult::DETECTING;
440 }
441 if ((direction_.type & PanDirection::UP) == 0) {
442 return CalculateTruthFingers(true) ? GestureAcceptResult::ACCEPT : GestureAcceptResult::REJECT;
443 }
444 if ((direction_.type & PanDirection::DOWN) == 0) {
445 return CalculateTruthFingers(false) ? GestureAcceptResult::ACCEPT : GestureAcceptResult::REJECT;
446 }
447 return GestureAcceptResult::ACCEPT;
448 }
449 return GestureAcceptResult::DETECTING;
450 }
451
OnResetStatus()452 void PanRecognizer::OnResetStatus()
453 {
454 MultiFingersRecognizer::OnResetStatus();
455 touchPoints_.clear();
456 averageDistance_.Reset();
457 touchPointsDistance_.clear();
458 }
459
OnSucceedCancel()460 void PanRecognizer::OnSucceedCancel()
461 {
462 SendCancelMsg();
463 }
464
SendCallbackMsg(const std::unique_ptr<GestureEventFunc> & callback)465 void PanRecognizer::SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback)
466 {
467 if (callback && *callback) {
468 GestureEvent info;
469 info.SetTimeStamp(time_);
470 UpdateFingerListInfo(coordinateOffset_);
471 info.SetFingerList(fingerList_);
472 info.SetOffsetX(averageDistance_.GetX());
473 info.SetOffsetY(averageDistance_.GetY());
474 TouchEvent touchPoint = {};
475 if (!touchPoints_.empty()) {
476 touchPoint = touchPoints_.begin()->second;
477 }
478 #ifdef ENABLE_DRAG_FRAMEWORK
479 info.SetPointerId(touchPoint.id);
480 #endif // ENABLE_DRAG_FRAMEWORK
481 info.SetGlobalPoint(globalPoint_)
482 .SetLocalLocation(Offset(globalPoint_.GetX(), globalPoint_.GetY()) - coordinateOffset_);
483 info.SetDeviceId(deviceId_);
484 info.SetSourceDevice(deviceType_);
485 info.SetTargetDisplayId(touchPoint.targetDisplayId);
486 info.SetDelta(delta_);
487 info.SetMainDelta(mainDelta_);
488 if (inputEventType_ == InputEventType::AXIS) {
489 info.SetScreenLocation(lastAxisEvent_.GetScreenOffset());
490 info.SetVelocity(Velocity());
491 info.SetMainVelocity(0.0);
492 info.SetSourceTool(lastAxisEvent_.sourceTool);
493 } else {
494 info.SetScreenLocation(lastTouchEvent_.GetScreenOffset());
495 info.SetVelocity(velocityTracker_.GetVelocity());
496 info.SetMainVelocity(velocityTracker_.GetMainAxisVelocity());
497 info.SetSourceTool(lastTouchEvent_.sourceTool);
498 }
499 info.SetTarget(GetEventTarget().value_or(EventTarget()));
500 if (recognizerTarget_.has_value()) {
501 info.SetTarget(recognizerTarget_.value());
502 }
503 info.SetInputEventType(inputEventType_);
504 info.SetForce(lastTouchEvent_.force);
505 if (lastTouchEvent_.tiltX.has_value()) {
506 info.SetTiltX(lastTouchEvent_.tiltX.value());
507 }
508 if (lastTouchEvent_.tiltY.has_value()) {
509 info.SetTiltY(lastTouchEvent_.tiltY.value());
510 }
511 (*callback)(info);
512 }
513 }
514
ReconcileFrom(const RefPtr<NGGestureRecognizer> & recognizer)515 bool PanRecognizer::ReconcileFrom(const RefPtr<NGGestureRecognizer>& recognizer)
516 {
517 RefPtr<PanRecognizer> curr = AceType::DynamicCast<PanRecognizer>(recognizer);
518 if (!curr) {
519 ResetStatus();
520 return false;
521 }
522
523 if (curr->fingers_ != fingers_ || curr->priorityMask_ != priorityMask_) {
524 ResetStatus();
525 return false;
526 }
527
528 direction_.type = curr->direction_.type;
529 newDirection_.type = curr->newDirection_.type;
530 distance_ = curr->distance_;
531 newDistance_ = curr->newDistance_;
532 mouseDistance_ = curr->mouseDistance_;
533
534 onActionStart_ = std::move(curr->onActionStart_);
535 onActionUpdate_ = std::move(curr->onActionUpdate_);
536 onActionEnd_ = std::move(curr->onActionEnd_);
537 onActionCancel_ = std::move(curr->onActionCancel_);
538
539 return true;
540 }
541
SetDirection(const PanDirection & direction)542 void PanRecognizer::SetDirection(const PanDirection& direction)
543 {
544 ChangeDirection(direction);
545 if ((direction_.type & PanDirection::VERTICAL) == 0) {
546 velocityTracker_.SetMainAxis(Axis::HORIZONTAL);
547 } else if ((direction_.type & PanDirection::HORIZONTAL) == 0) {
548 velocityTracker_.SetMainAxis(Axis::VERTICAL);
549 }
550 }
551
ChangeFingers(int32_t fingers)552 void PanRecognizer::ChangeFingers(int32_t fingers)
553 {
554 if (fingers_ != fingers) {
555 newFingers_ = fingers;
556 }
557 }
558
ChangeDirection(const PanDirection & direction)559 void PanRecognizer::ChangeDirection(const PanDirection& direction)
560 {
561 if (direction_.type != direction.type) {
562 direction_.type = direction.type;
563 newDirection_.type = direction.type;
564 }
565 }
566
ChangeDistance(double distance)567 void PanRecognizer::ChangeDistance(double distance)
568 {
569 if (distance_ != distance) {
570 if (refereeState_ == RefereeState::READY || refereeState_ == RefereeState::DETECTING) {
571 distance_ = distance;
572 }
573 newDistance_ = distance;
574 mouseDistance_ = distance;
575 }
576 }
577
GetMainAxisDelta()578 double PanRecognizer::GetMainAxisDelta()
579 {
580 switch (direction_.type) {
581 case PanDirection::ALL:
582 return delta_.GetDistance();
583 case PanDirection::HORIZONTAL:
584 return delta_.GetX();
585 case PanDirection::VERTICAL:
586 return delta_.GetY();
587 default:
588 return 0.0;
589 }
590 }
591
592 } // namespace OHOS::Ace::NG
593