• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     Point pointTran = point;
235     if (transMap_ != nullptr && !GetTransformMap().IsInvalid()) {
236         Rect relativeRect = GetOrigRect();
237         pointTran = GetTransformMap().GetOrigPoint(point, relativeRect);
238     }
239     UIView* view = GetChildrenRenderHead();
240     while (view != nullptr) {
241         if (!view->IsViewGroup()) {
242             rect = view->GetRect();
243             if (rect.IsContains(pointTran)) {
244                 view->GetTargetView(pointTran, current, target);
245             }
246         } else {
247             UIViewGroup* viewGroup = static_cast<UIViewGroup*>(view);
248             viewGroup->GetTargetView(pointTran, current, target);
249         }
250         view = view->GetNextRenderSibling();
251     }
252 }
253 
GetAllChildRelativeRect() const254 Rect UIViewGroup::GetAllChildRelativeRect() const
255 {
256     Rect rect = {0, 0, 0, 0};
257     UIView* view = childrenHead_;
258     bool isRectValid = false;
259     while (view != nullptr) {
260         if (!view->IsVisible()) {
261             view = view->GetNextSibling();
262             continue;
263         }
264         Rect rectChild = view->GetRelativeRect();
265         if (!isRectValid) {
266             rect = rectChild;
267             isRectValid = true;
268         } else {
269             rect.Join(rect, rectChild);
270         }
271         view = view->GetNextSibling();
272     }
273     return rect;
274 }
275 
GetChildrenRenderHead() const276 UIView* UIViewGroup::GetChildrenRenderHead() const
277 {
278     return childrenRenderHead_;
279 }
280 
SetChildrenRenderHead(UIView * renderHead)281 void UIViewGroup::SetChildrenRenderHead(UIView* renderHead)
282 {
283     if ((renderHead != nullptr) && (renderHead->GetParent() != this)) {
284         GRAPHIC_LOGE("can not set as render head if it is not a child view");
285         return;
286     }
287     childrenRenderHead_ = renderHead;
288 }
289 
GetChildById(const char * id) const290 UIView* UIViewGroup::GetChildById(const char* id) const
291 {
292     if (id == nullptr || childrenHead_ == nullptr) {
293         return nullptr;
294     }
295     UIView* child = childrenHead_;
296     while (child != nullptr) {
297         if ((child->GetViewId() != nullptr) && !strcmp(child->GetViewId(), id)) {
298             return child;
299         } else if (child->IsViewGroup() && static_cast<UIViewGroup*>(child)->GetChildrenHead() != nullptr) {
300             child = static_cast<UIViewGroup*>(child)->GetChildrenHead();
301             continue;
302         } else if (child->GetNextSibling() != nullptr) {
303             child = child->GetNextSibling();
304             continue;
305         }
306         while (child->GetParent() != this && child->GetParent()->GetNextSibling() == nullptr) {
307             child = child->GetParent();
308         }
309         if (child->GetParent() != this) {
310             child = child->GetParent()->GetNextSibling();
311             continue;
312         }
313         break;
314     }
315     return nullptr;
316 }
317 
MoveChildByOffset(int16_t xOffset,int16_t yOffset)318 void UIViewGroup::MoveChildByOffset(int16_t xOffset, int16_t yOffset)
319 {
320     UIView* view = childrenHead_;
321     while (view != nullptr) {
322         int16_t x = view->GetX() + xOffset;
323         int16_t y = view->GetY() + yOffset;
324         view->SetPosition(x, y);
325         view = view->GetNextSibling();
326     }
327 }
328 
AutoResize()329 void UIViewGroup::AutoResize()
330 {
331     Rect rect = GetAllChildRelativeRect();
332     SetWidth(rect.GetWidth() + rect.GetLeft());
333     SetHeight(rect.GetHeight() + rect.GetTop());
334 }
335 
RemoveRenderView(UIView * targetView)336 void UIViewGroup::RemoveRenderView(UIView* targetView)
337 {
338     if (targetView == nullptr) {
339         return;
340     }
341 
342     if (targetView->GetParent() == nullptr) {
343         return;
344     }
345 
346     UIViewGroup* viewGroup = reinterpret_cast<UIViewGroup*>(targetView->GetParent());
347     UIView* node = viewGroup->GetChildrenRenderHead();
348     if (node == nullptr) {
349         return;
350     }
351     if (node == targetView) {
352         viewGroup->SetChildrenRenderHead(node->GetNextRenderSibling());
353         targetView->SetNextRenderSibling(nullptr);
354     } else {
355         while (node->GetNextRenderSibling() != nullptr) {
356             if (node->GetNextRenderSibling() == targetView) {
357                 node->SetNextRenderSibling(targetView->GetNextRenderSibling());
358                 targetView->SetNextRenderSibling(nullptr);
359                 break;
360             }
361             node = node->GetNextRenderSibling();
362         }
363     }
364 }
365 
UpdateRenderView(UIView * targetView)366 void UIViewGroup::UpdateRenderView(UIView* targetView)
367 {
368     if (targetView == nullptr) {
369         return;
370     }
371 
372     if (targetView->GetParent() == nullptr) {
373         return;
374     }
375     RemoveRenderView(targetView);
376 
377     UIViewGroup* viewGroup = reinterpret_cast<UIViewGroup*>(targetView->GetParent());
378     UIView* curView = viewGroup->GetChildrenRenderHead();
379     if (curView == nullptr) {
380         viewGroup->SetChildrenRenderHead(targetView);
381         targetView->SetNextRenderSibling(nullptr);
382         return;
383     }
384 
385     int16_t curZIndex = curView->GetZIndex();
386     int16_t targetZIndex = targetView->GetZIndex();
387     UIView* nextView = curView->GetNextRenderSibling();
388     UIView* preView = nullptr;
389 
390     if (curZIndex > targetZIndex) {
391         targetView->SetNextRenderSibling(curView);
392         viewGroup->SetChildrenRenderHead(targetView);
393         return;
394     }
395 
396     if (nextView == nullptr) {
397         curView->SetNextRenderSibling(targetView);
398         targetView->SetNextRenderSibling(nullptr);
399         return;
400     }
401 
402     while (nextView != nullptr) {
403         curZIndex = curView->GetZIndex();
404         int16_t nextZIndex = nextView->GetZIndex();
405         if (curZIndex == targetZIndex) {
406             InsertRenderView(curView, preView, targetView);
407             return;
408         }
409         if ((curZIndex < targetZIndex) && (targetZIndex < nextZIndex)) {
410             curView->SetNextRenderSibling(targetView);
411             targetView->SetNextRenderSibling(nextView);
412             return;
413         }
414         preView = curView;
415         curView = nextView;
416         nextView = nextView->GetNextRenderSibling();
417     }
418 
419     curView->SetNextRenderSibling(targetView);
420     targetView->SetNextRenderSibling(nullptr);
421 }
422 
InsertRenderView(UIView * archorView,UIView * anchorPreView,UIView * targetView)423 void UIViewGroup::InsertRenderView(UIView* archorView, UIView* anchorPreView, UIView* targetView)
424 {
425     if ((targetView == nullptr) || (archorView == nullptr)) {
426         return;
427     }
428 
429     if (archorView->GetParent() == nullptr) {
430         return;
431     }
432 
433     UIViewGroup* viewGroup = reinterpret_cast<UIViewGroup*>(archorView->GetParent());
434     UIView* node = viewGroup->GetChildrenHead();
435     if (node == nullptr) {
436         return;
437     }
438 
439     int16_t targetZIndex = targetView->GetZIndex();
440     UIView* newArchorView = nullptr;
441 
442     if (node == targetView) {
443         targetView->SetNextRenderSibling(viewGroup->GetChildrenRenderHead());
444         viewGroup->SetChildrenRenderHead(targetView);
445         return;
446     }
447 
448     while (node->GetNextSibling() != nullptr) {
449         int16_t curZIndex = node->GetNextSibling()->GetZIndex();
450         if (curZIndex == targetZIndex) {
451             if ((node->GetNextSibling() == targetView) && (newArchorView == nullptr)) {
452                 targetView->SetNextRenderSibling(archorView);
453                 if (viewGroup->GetChildrenRenderHead() == archorView) {
454                     viewGroup->SetChildrenRenderHead(targetView);
455                 }
456                 if (anchorPreView != nullptr) {
457                     anchorPreView->SetNextRenderSibling(targetView);
458                 }
459                 break;
460             }
461             if (node->GetNextSibling() != targetView) {
462                 newArchorView = node->GetNextSibling();
463             }
464         }
465         if (node->GetNextSibling() == targetView) {
466             if (newArchorView != nullptr) {
467                 targetView->SetNextRenderSibling(newArchorView->GetNextRenderSibling());
468                 newArchorView->SetNextRenderSibling(targetView);
469             }
470             break;
471         }
472         node = node->GetNextSibling();
473     }
474 }
475 } // namespace OHOS
476