1 /*
2 * Copyright (c) 2020-2021 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 "components/ui_view_group.h"
17
18 #include <cstring>
19
20 #include "components/root_view.h"
21 #include "components/ui_tree_manager.h"
22 #include "gfx_utils/graphic_log.h"
23
24 namespace OHOS {
UIViewGroup()25 UIViewGroup::UIViewGroup()
26 : childrenHead_(nullptr),
27 childrenRenderHead_(nullptr),
28 childrenTail_(nullptr),
29 childrenNum_(0),
30 isDragging_(false),
31 disallowIntercept_(false),
32 isAutoSize_(false)
33 {
34 isViewGroup_ = true;
35 #if ENABLE_FOCUS_MANAGER
36 isInterceptFocus_ = false;
37 #endif
38 }
39
~UIViewGroup()40 UIViewGroup::~UIViewGroup() {}
41
Add(UIView * view)42 void UIViewGroup::Add(UIView* view)
43 {
44 if ((view == this) || (view == nullptr)) {
45 GRAPHIC_LOGE("view can not be nullptr and added to self");
46 return;
47 }
48 if (view->GetParent() != nullptr) {
49 GRAPHIC_LOGE("can not add view multi times");
50 return;
51 }
52
53 if (childrenHead_ == nullptr) {
54 childrenHead_ = view;
55 } else {
56 if (childrenTail_ == nullptr) {
57 return;
58 }
59 childrenTail_->SetNextSibling(view);
60 }
61 view->SetParent(this);
62 view->SetNextSibling(nullptr);
63 childrenTail_ = view;
64 childrenNum_++;
65 if (isAutoSize_) {
66 AutoResize();
67 }
68 UpdateRenderView(view);
69 OnChildChanged();
70 }
71
Insert(UIView * prevView,UIView * insertView)72 void UIViewGroup::Insert(UIView* prevView, UIView* insertView)
73 {
74 if ((insertView == nullptr) || (insertView == this)) {
75 GRAPHIC_LOGE("insertView can not be nullptr and insert to self");
76 return;
77 }
78
79 if (insertView->GetParent() != nullptr) {
80 GRAPHIC_LOGE("can not insert view multi times");
81 return;
82 }
83
84 if (childrenHead_ == nullptr) {
85 Add(insertView);
86 UpdateRenderView(insertView);
87 return;
88 }
89
90 if (prevView == nullptr) {
91 insertView->SetNextSibling(childrenHead_);
92 insertView->SetParent(this);
93 childrenHead_ = insertView;
94 } else {
95 UIView* nextView = prevView->GetNextSibling();
96 prevView->SetNextSibling(insertView);
97 insertView->SetNextSibling(nextView);
98 insertView->SetParent(this);
99 }
100 if (childrenTail_ == prevView) {
101 childrenTail_ = insertView;
102 }
103 childrenNum_++;
104 if (isAutoSize_) {
105 AutoResize();
106 }
107 UpdateRenderView(insertView);
108 OnChildChanged();
109 }
110
Remove(UIView * view)111 void UIViewGroup::Remove(UIView* view)
112 {
113 if ((childrenHead_ == nullptr) || (view == nullptr)) {
114 return;
115 }
116 UITreeManager::GetInstance().OnLifeEvent(view, UITreeManager::REMOVE);
117
118 #if LOCAL_RENDER
119 RootView::GetInstance()->RemoveViewFromInvalidMap(view);
120 InvalidateRect(view->GetRect());
121 #endif
122 if (childrenHead_ == view) {
123 RemoveRenderView(view);
124 childrenHead_ = childrenHead_->GetNextSibling();
125 view->SetParent(nullptr);
126 view->SetNextSibling(nullptr);
127 if (childrenTail_ == view) {
128 childrenTail_ = nullptr;
129 }
130 childrenNum_--;
131 OnChildChanged();
132 return;
133 }
134 UIView* node = childrenHead_;
135 while (node->GetNextSibling() != nullptr) {
136 if (node->GetNextSibling() == view) {
137 RemoveRenderView(view);
138 node->SetNextSibling(view->GetNextSibling());
139 view->SetParent(nullptr);
140 view->SetNextSibling(nullptr);
141 if (childrenTail_ == view) {
142 childrenTail_ = node;
143 }
144 childrenNum_--;
145 OnChildChanged();
146 return;
147 }
148 node = node->GetNextSibling();
149 }
150 }
151
RemoveAll()152 void UIViewGroup::RemoveAll()
153 {
154 UIView* node = childrenHead_;
155 childrenHead_ = nullptr;
156 childrenTail_ = nullptr;
157 childrenRenderHead_ = nullptr;
158 childrenNum_ = 0;
159 UIView* tmp = nullptr;
160 while (node != nullptr) {
161 tmp = node;
162 UITreeManager::GetInstance().OnLifeEvent(node, UITreeManager::REMOVE);
163 node = node->GetNextSibling();
164 tmp->SetParent(nullptr);
165 tmp->SetNextSibling(nullptr);
166 tmp->SetNextRenderSibling(nullptr);
167 }
168 OnChildChanged();
169 }
170
GetTargetView(const Point & point,UIView ** last)171 void UIViewGroup::GetTargetView(const Point& point, UIView** last)
172 {
173 if (last == nullptr) {
174 return;
175 }
176
177 Rect rect = GetRect();
178 if (disallowIntercept_) {
179 *last = nullptr;
180 return;
181 }
182 if (!rect.IsContains(point)) {
183 return;
184 }
185 if (!visible_) {
186 return;
187 }
188 if (touchable_) {
189 *last = this;
190 }
191 if (isDragging_) {
192 return;
193 }
194 UIView* view = GetChildrenRenderHead();
195 while (view != nullptr) {
196 if (!view->IsViewGroup()) {
197 rect = view->GetRect();
198 if (rect.IsContains(point)) {
199 view->GetTargetView(point, last);
200 }
201 } else {
202 UIViewGroup* viewGroup = static_cast<UIViewGroup*>(view);
203 viewGroup->GetTargetView(point, last);
204 }
205 view = view->GetNextRenderSibling();
206 }
207 }
208
GetTargetView(const Point & point,UIView ** current,UIView ** target)209 void UIViewGroup::GetTargetView(const Point& point, UIView** current, UIView** target)
210 {
211 if ((current == nullptr) || (target == nullptr)) {
212 return;
213 }
214
215 Rect rect = GetRect();
216 if (disallowIntercept_) {
217 *current = nullptr;
218 *target = nullptr;
219 return;
220 }
221 if (!rect.IsContains(point)) {
222 return;
223 }
224 if (!visible_) {
225 return;
226 }
227 *target = this;
228 if (touchable_) {
229 *current = this;
230 }
231 if (isDragging_) {
232 return;
233 }
234 UIView* view = GetChildrenRenderHead();
235 while (view != nullptr) {
236 if (!view->IsViewGroup()) {
237 rect = view->GetRect();
238 if (rect.IsContains(point)) {
239 view->GetTargetView(point, current, target);
240 }
241 } else {
242 UIViewGroup* viewGroup = static_cast<UIViewGroup*>(view);
243 viewGroup->GetTargetView(point, current, target);
244 }
245 view = view->GetNextRenderSibling();
246 }
247 }
248
GetAllChildRelativeRect() const249 Rect UIViewGroup::GetAllChildRelativeRect() const
250 {
251 Rect rect = {0, 0, 0, 0};
252 UIView* view = childrenHead_;
253 bool isRectValid = false;
254 while (view != nullptr) {
255 if (!view->IsVisible()) {
256 view = view->GetNextSibling();
257 continue;
258 }
259 Rect rectChild = view->GetRelativeRect();
260 if (!isRectValid) {
261 rect = rectChild;
262 isRectValid = true;
263 } else {
264 rect.Join(rect, rectChild);
265 }
266 view = view->GetNextSibling();
267 }
268 return rect;
269 }
270
GetChildrenRenderHead() const271 UIView* UIViewGroup::GetChildrenRenderHead() const
272 {
273 return childrenRenderHead_;
274 }
275
SetChildrenRenderHead(UIView * renderHead)276 void UIViewGroup::SetChildrenRenderHead(UIView* renderHead)
277 {
278 if ((renderHead != nullptr) && (renderHead->GetParent() != this)) {
279 GRAPHIC_LOGE("can not set as render head if it is not a child view");
280 return;
281 }
282 childrenRenderHead_ = renderHead;
283 }
284
GetChildById(const char * id) const285 UIView* UIViewGroup::GetChildById(const char* id) const
286 {
287 if (id == nullptr || childrenHead_ == nullptr) {
288 return nullptr;
289 }
290 UIView* child = childrenHead_;
291 while (child != nullptr) {
292 if ((child->GetViewId() != nullptr) && !strcmp(child->GetViewId(), id)) {
293 return child;
294 } else if (child->IsViewGroup() && static_cast<UIViewGroup*>(child)->GetChildrenHead() != nullptr) {
295 child = static_cast<UIViewGroup*>(child)->GetChildrenHead();
296 continue;
297 } else if (child->GetNextSibling() != nullptr) {
298 child = child->GetNextSibling();
299 continue;
300 }
301 while (child->GetParent() != this && child->GetParent()->GetNextSibling() == nullptr) {
302 child = child->GetParent();
303 }
304 if (child->GetParent() != this) {
305 child = child->GetParent()->GetNextSibling();
306 continue;
307 }
308 break;
309 }
310 return nullptr;
311 }
312
MoveChildByOffset(int16_t xOffset,int16_t yOffset)313 void UIViewGroup::MoveChildByOffset(int16_t xOffset, int16_t yOffset)
314 {
315 UIView* view = childrenHead_;
316 while (view != nullptr) {
317 int16_t x = view->GetX() + xOffset;
318 int16_t y = view->GetY() + yOffset;
319 view->SetPosition(x, y);
320 view = view->GetNextSibling();
321 }
322 }
323
AutoResize()324 void UIViewGroup::AutoResize()
325 {
326 Rect rect = GetAllChildRelativeRect();
327 SetWidth(rect.GetWidth() + rect.GetLeft());
328 SetHeight(rect.GetHeight() + rect.GetTop());
329 }
330
RemoveRenderView(UIView * targetView)331 void UIViewGroup::RemoveRenderView(UIView* targetView)
332 {
333 if (targetView == nullptr) {
334 return;
335 }
336
337 if (targetView->GetParent() == nullptr) {
338 return;
339 }
340
341 UIViewGroup* viewGroup = reinterpret_cast<UIViewGroup*>(targetView->GetParent());
342 UIView* node = viewGroup->GetChildrenRenderHead();
343 if (node == nullptr) {
344 return;
345 }
346 if (node == targetView) {
347 viewGroup->SetChildrenRenderHead(node->GetNextRenderSibling());
348 targetView->SetNextRenderSibling(nullptr);
349 } else {
350 while (node->GetNextRenderSibling() != nullptr) {
351 if (node->GetNextRenderSibling() == targetView) {
352 node->SetNextRenderSibling(targetView->GetNextRenderSibling());
353 targetView->SetNextRenderSibling(nullptr);
354 break;
355 }
356 node = node->GetNextRenderSibling();
357 }
358 }
359 }
360
UpdateRenderView(UIView * targetView)361 void UIViewGroup::UpdateRenderView(UIView* targetView)
362 {
363 if (targetView == nullptr) {
364 return;
365 }
366
367 if (targetView->GetParent() == nullptr) {
368 return;
369 }
370 RemoveRenderView(targetView);
371
372 UIViewGroup* viewGroup = reinterpret_cast<UIViewGroup*>(targetView->GetParent());
373 UIView* curView = viewGroup->GetChildrenRenderHead();
374 if (curView == nullptr) {
375 viewGroup->SetChildrenRenderHead(targetView);
376 targetView->SetNextRenderSibling(nullptr);
377 return;
378 }
379
380 int16_t curZIndex = curView->GetZIndex();
381 int16_t targetZIndex = targetView->GetZIndex();
382 UIView* nextView = curView->GetNextRenderSibling();
383 UIView* preView = nullptr;
384
385 if (curZIndex > targetZIndex) {
386 targetView->SetNextRenderSibling(curView);
387 viewGroup->SetChildrenRenderHead(targetView);
388 return;
389 }
390
391 if (nextView == nullptr) {
392 curView->SetNextRenderSibling(targetView);
393 targetView->SetNextRenderSibling(nullptr);
394 return;
395 }
396
397 while (nextView != nullptr) {
398 curZIndex = curView->GetZIndex();
399 int16_t nextZIndex = nextView->GetZIndex();
400 if (curZIndex == targetZIndex) {
401 InsertRenderView(curView, preView, targetView);
402 return;
403 }
404 if ((curZIndex < targetZIndex) && (targetZIndex < nextZIndex)) {
405 curView->SetNextRenderSibling(targetView);
406 targetView->SetNextRenderSibling(nextView);
407 return;
408 }
409 preView = curView;
410 curView = nextView;
411 nextView = nextView->GetNextRenderSibling();
412 }
413
414 curView->SetNextRenderSibling(targetView);
415 targetView->SetNextRenderSibling(nullptr);
416 }
417
InsertRenderView(UIView * archorView,UIView * anchorPreView,UIView * targetView)418 void UIViewGroup::InsertRenderView(UIView* archorView, UIView* anchorPreView, UIView* targetView)
419 {
420 if ((targetView == nullptr) || (archorView == nullptr)) {
421 return;
422 }
423
424 if (archorView->GetParent() == nullptr) {
425 return;
426 }
427
428 UIViewGroup* viewGroup = reinterpret_cast<UIViewGroup*>(archorView->GetParent());
429 UIView* node = viewGroup->GetChildrenHead();
430 if (node == nullptr) {
431 return;
432 }
433
434 int16_t targetZIndex = targetView->GetZIndex();
435 UIView* newArchorView = nullptr;
436
437 if (node == targetView) {
438 targetView->SetNextRenderSibling(viewGroup->GetChildrenRenderHead());
439 viewGroup->SetChildrenRenderHead(targetView);
440 return;
441 }
442
443 while (node->GetNextSibling() != nullptr) {
444 int16_t curZIndex = node->GetNextSibling()->GetZIndex();
445 if (curZIndex == targetZIndex) {
446 if ((node->GetNextSibling() == targetView) && (newArchorView == nullptr)) {
447 targetView->SetNextRenderSibling(archorView);
448 if (viewGroup->GetChildrenRenderHead() == archorView) {
449 viewGroup->SetChildrenRenderHead(targetView);
450 }
451 if (anchorPreView != nullptr) {
452 anchorPreView->SetNextRenderSibling(targetView);
453 }
454 break;
455 }
456 if (node->GetNextSibling() != targetView) {
457 newArchorView = node->GetNextSibling();
458 }
459 }
460 if (node->GetNextSibling() == targetView) {
461 if (newArchorView != nullptr) {
462 targetView->SetNextRenderSibling(newArchorView->GetNextRenderSibling());
463 newArchorView->SetNextRenderSibling(targetView);
464 }
465 break;
466 }
467 node = node->GetNextSibling();
468 }
469 }
470 } // namespace OHOS
471