1 /*
2 * Copyright (c) 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/gesture_group.h"
17
18 #include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
19 #include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
20 #include "core/components_ng/gestures/recognizers/sequenced_recognizer.h"
21
22 namespace OHOS::Ace::NG {
23
CreateRecognizer()24 RefPtr<NGGestureRecognizer> GestureGroup::CreateRecognizer()
25 {
26 std::vector<RefPtr<NGGestureRecognizer>> recognizers;
27 for (auto& subGesture : gestures_) {
28 auto recognizer = subGesture->CreateRecognizer();
29 if (recognizer) {
30 recognizers.emplace_back(recognizer);
31 }
32 }
33
34 RefPtr<NGGestureRecognizer> groupRecognizer;
35 switch (mode_) {
36 case GestureMode::Sequence:
37 groupRecognizer = AceType::MakeRefPtr<SequencedRecognizer>(recognizers);
38 if (onActionCancelId_) {
39 groupRecognizer->SetOnActionCancel(*onActionCancelId_);
40 }
41 break;
42 case GestureMode::Parallel:
43 groupRecognizer = AceType::MakeRefPtr<ParallelRecognizer>(recognizers);
44 break;
45 case GestureMode::Exclusive:
46 groupRecognizer = AceType::MakeRefPtr<ExclusiveRecognizer>(recognizers);
47 break;
48 default:
49 return nullptr;
50 }
51 DynamicCast<RecognizerGroup>(groupRecognizer)->RemainChildOnResetStatus();
52 groupRecognizer->SetPriority(priority_);
53 groupRecognizer->SetPriorityMask(gestureMask_);
54 groupRecognizer->SetGestureInfo(gestureInfo_);
55 return groupRecognizer;
56 }
57
Deserialize(const char * buff)58 int32_t GestureGroup::Deserialize(const char* buff)
59 {
60 if (buff == nullptr) {
61 return -1;
62 }
63 int32_t* plen = reinterpret_cast<int32_t*>(const_cast<char*>(buff) + sizeof(GestureType));
64 int32_t total = *plen;
65 if (total <= 0 || total >= MAX_BYTES_SIZE) {
66 return -1;
67 }
68 auto ret = total;
69 total -= sizeof(int32_t);
70 if (total < 0) {
71 return -1;
72 }
73 total -= sizeof(GestureType);
74 if (total < 0) {
75 return -1;
76 }
77 buff += sizeof(GestureType) + sizeof(int32_t);
78 mode_ = *reinterpret_cast<GestureMode*>(const_cast<char*>(buff));
79 total -= sizeof(GestureMode);
80 if (total < 0) {
81 return -1;
82 }
83 buff += sizeof(GestureMode);
84 while (total != 0) {
85 auto gesture = MakeGesture(*(GestureType*)buff);
86 auto len = gesture->Deserialize(buff);
87 buff += len;
88 total -= len;
89 if (total < 0) {
90 return -1;
91 }
92 gestures_.push_back(gesture);
93 }
94 return ret;
95 }
96
SizeofMe()97 int32_t GestureGroup::SizeofMe()
98 {
99 int32_t total = 0;
100 for (auto& i : gestures_) {
101 total += i->SizeofMe();
102 }
103 total += sizeof(int32_t);
104 total += sizeof(GestureType);
105 total += sizeof(GestureMode);
106 return total;
107 }
108
MakeGesture(GestureType type)109 RefPtr<Gesture> GestureGroup::MakeGesture(GestureType type)
110 {
111 if (type == GestureType::PAN) {
112 PanDirection panDirection;
113 panDirection.type = PanDirection::VERTICAL;
114 return AceType::MakeRefPtr<PanGesture>(1, panDirection, 0);
115 } else if (type == GestureType::GROUP) {
116 return AceType::MakeRefPtr<GestureGroup>(GestureMode::Parallel);
117 }
118 return nullptr;
119 }
120
Serialize(char * buff)121 int32_t GestureGroup::Serialize(char* buff)
122 {
123 if (buff == nullptr) {
124 return -1;
125 }
126 auto total = SizeofMe();
127 buff = SetHeader(buff, GestureType::GROUP, total);
128 *reinterpret_cast<GestureMode*>(buff) = mode_;
129 buff += sizeof(GestureMode);
130 for (auto& i : gestures_) {
131 int32_t len = i->Serialize(buff);
132 buff += len;
133 }
134 return total;
135 }
136
RemoveChildrenByTag(const std::string & gestureTag,bool & needRecollect)137 void GestureGroup::RemoveChildrenByTag(const std::string& gestureTag, bool& needRecollect)
138 {
139 for (auto iter = gestures_.begin(); iter != gestures_.end();) {
140 auto tag = (*iter)->GetTag();
141 if (tag.has_value() && tag.value() == gestureTag) {
142 iter = gestures_.erase(iter);
143 needRecollect = true;
144 } else {
145 auto group = AceType::DynamicCast<GestureGroup>(*iter);
146 if (group) {
147 group->RemoveChildrenByTag(gestureTag, needRecollect);
148 }
149 iter++;
150 }
151 }
152 }
153
RemoveGesture(RefPtr<Gesture> gesture)154 void GestureGroup::RemoveGesture(RefPtr<Gesture> gesture)
155 {
156 for (auto iter = gestures_.begin(); iter != gestures_.end();) {
157 if (*iter == gesture) {
158 iter = gestures_.erase(iter);
159 } else {
160 auto group = AceType::DynamicCast<GestureGroup>(*iter);
161 if (group) {
162 group->RemoveGesture(gesture);
163 }
164 iter++;
165 }
166 }
167 }
168 } // namespace OHOS::Ace::NG
169