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