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