• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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