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