• 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/multi_fingers_recognizer.h"
17 
18 #include "base/memory/ace_type.h"
19 #include "core/components_ng/gestures/recognizers/recognizer_group.h"
20 
21 namespace OHOS::Ace::NG {
22 namespace {
23 constexpr int32_t DEFAULT_MAX_FINGERS = 10;
24 } // namespace
25 
MultiFingersRecognizer(int32_t fingers,bool isLimitFingerCount)26 MultiFingersRecognizer::MultiFingersRecognizer(int32_t fingers, bool isLimitFingerCount)
27 {
28     if (fingers > DEFAULT_MAX_FINGERS || fingers <= 0) {
29         fingers_ = 1;
30     } else {
31         fingers_ = fingers;
32     }
33     isLimitFingerCount_ = isLimitFingerCount;
34 }
35 
UpdateFingerListInfo()36 void MultiFingersRecognizer::UpdateFingerListInfo()
37 {
38     fingerList_.clear();
39     lastPointEvent_.reset();
40     auto maxTimeStamp = TimeStamp::min().time_since_epoch().count();
41     for (const auto& point : touchPoints_) {
42         PointF localPoint(point.second.x, point.second.y);
43         NGGestureRecognizer::Transform(
44             localPoint, GetAttachedNode(), false, isPostEventResult_, point.second.postEventNodeId);
45         FingerInfo fingerInfo = { point.second.originalId, point.second.operatingHand, point.second.GetOffset(),
46             Offset(localPoint.GetX(), localPoint.GetY()),
47             point.second.GetScreenOffset(), point.second.sourceType, point.second.sourceTool };
48         fingerList_.emplace_back(fingerInfo);
49         if (maxTimeStamp <= point.second.GetTimeStamp().time_since_epoch().count()
50             && point.second.pointers.size() >= touchPoints_.size()) {
51             lastPointEvent_ = point.second.pointerEvent;
52             maxTimeStamp = point.second.GetTimeStamp().time_since_epoch().count();
53         }
54     }
55 }
56 
IsNeedResetStatus()57 bool MultiFingersRecognizer::IsNeedResetStatus()
58 {
59     if (GetValidFingersCount() != 0) {
60         return false;
61     }
62 
63     auto ref = AceType::Claim(this);
64     auto group = AceType::DynamicCast<RecognizerGroup>(ref);
65     if (!group) {
66         return true;
67     }
68 
69     auto groupList = group->GetGroupRecognizer();
70     for (auto &recognizer : groupList) {
71         auto multiFingersRecognizer = AceType::DynamicCast<MultiFingersRecognizer>(recognizer);
72         if (!multiFingersRecognizer) {
73             continue;
74         }
75 
76         if (!multiFingersRecognizer->IsNeedResetStatus()) {
77             return false;
78         }
79     }
80 
81     return true;
82 }
83 
OnFinishGestureReferee(int32_t touchId,bool isBlocked)84 void MultiFingersRecognizer::OnFinishGestureReferee(int32_t touchId, bool isBlocked)
85 {
86     touchPoints_.erase(touchId);
87     activeFingers_.remove(touchId);
88     if (IsNeedResetStatus()) {
89         ResetStatusOnFinish(isBlocked);
90     }
91 }
92 
CleanRecognizerState()93 void MultiFingersRecognizer::CleanRecognizerState()
94 {
95     if ((refereeState_ == RefereeState::SUCCEED ||
96         refereeState_ == RefereeState::FAIL ||
97         refereeState_ == RefereeState::DETECTING) &&
98         currentFingers_ == 0) {
99         refereeState_ = RefereeState::READY;
100         disposal_ = GestureDisposal::NONE;
101     }
102 }
103 
UpdateTouchPointWithAxisEvent(const AxisEvent & event)104 void MultiFingersRecognizer::UpdateTouchPointWithAxisEvent(const AxisEvent& event)
105 {
106     // Update touchPointInfo with axisEvent.
107     touchPoints_[event.id].id = event.id;
108     touchPoints_[event.id].x = event.x;
109     touchPoints_[event.id].y = event.y;
110     touchPoints_[event.id].screenX = event.screenX;
111     touchPoints_[event.id].screenY = event.screenY;
112     touchPoints_[event.id].sourceType = event.sourceType;
113     touchPoints_[event.id].sourceTool = event.sourceTool;
114     touchPoints_[event.id].originalId = event.originalId;
115     TouchPoint point;
116     point.id = event.id;
117     point.x = event.x;
118     point.y = event.y;
119     point.screenX = event.screenX;
120     point.screenY = event.screenY;
121     point.sourceTool = event.sourceTool;
122     point.originalId = event.originalId;
123     touchPoints_[event.id].pointers = { point };
124     touchPoints_[event.id].pointerEvent = event.pointerEvent;
125 }
126 
DumpGestureInfo() const127 std::string MultiFingersRecognizer::DumpGestureInfo() const
128 {
129     std::string infoStr;
130     infoStr.append("allowedTypes: [");
131     std::set<SourceTool> allowedTypes = {};
132     if (gestureInfo_) {
133         allowedTypes = gestureInfo_->GetAllowedTypes();
134     }
135     if (allowedTypes.empty()) {
136         infoStr.append("all]");
137         return infoStr;
138     }
139 
140     auto it = allowedTypes.begin();
141     while (it != allowedTypes.end()) {
142         infoStr.append(std::to_string(static_cast<int32_t>(*it)));
143         it++;
144         if (it != allowedTypes.end()) {
145             infoStr.append(", ");
146         }
147     }
148     infoStr.append("]");
149     return infoStr;
150 }
151 } // namespace OHOS::Ace::NG
152