• 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.h"
17 
18 #include "components/root_view.h"
19 #include "core/render_manager.h"
20 #include "dfx/ui_view_bounds.h"
21 #include "dock/focus_manager.h"
22 #include "draw/draw_utils.h"
23 #include "engines/gfx/gfx_engine_manager.h"
24 #include "gfx_utils/graphic_log.h"
25 #include "gfx_utils/mem_api.h"
26 #include "securec.h"
27 #include "themes/theme_manager.h"
28 
29 namespace OHOS {
UIView()30 UIView::UIView()
31     : touchable_(false),
32       visible_(true),
33       draggable_(false),
34       dragParentInstead_(true),
35       isViewGroup_(false),
36       needRedraw_(false),
37       styleAllocFlag_(false),
38       isIntercept_(false),
39 #if ENABLE_FOCUS_MANAGER
40       focusable_(false),
41 #endif
42       opaScale_(OPA_OPAQUE),
43       index_(0),
44       id_(nullptr),
45       parent_(nullptr),
46       nextSibling_(nullptr),
47       style_(nullptr),
48       transMap_(nullptr),
49       onClickListener_(nullptr),
50       onLongPressListener_(nullptr),
51       onDragListener_(nullptr),
52       onTouchListener_(nullptr),
53 #if ENABLE_FOCUS_MANAGER
54       onFocusListener_(nullptr),
55 #endif
56 #if ENABLE_ROTATE_INPUT
57       onRotateListener_(nullptr),
58 #endif
59       viewExtraMsg_(nullptr),
60       rect_(0, 0, 0, 0),
61       visibleRect_(nullptr)
62 {
63     SetupThemeStyles();
64 }
65 
~UIView()66 UIView::~UIView()
67 {
68     if (transMap_ != nullptr) {
69         delete transMap_;
70         transMap_ = nullptr;
71     }
72     if (visibleRect_ != nullptr) {
73         delete visibleRect_;
74         visibleRect_ = nullptr;
75     }
76     if (styleAllocFlag_) {
77         delete style_;
78         style_ = nullptr;
79         styleAllocFlag_ = false;
80     }
81 }
82 
OnPreDraw(Rect & invalidatedArea) const83 bool UIView::OnPreDraw(Rect& invalidatedArea) const
84 {
85     Rect rect(GetRect());
86     int16_t r = style_->borderRadius_;
87     if (r == COORD_MAX) {
88         return true;
89     }
90     if (r != 0) {
91         r = ((r & 0x1) == 0) ? (r >> 1) : ((r + 1) >> 1);
92         rect.SetLeft(rect.GetX() + r);
93         rect.SetWidth(rect.GetWidth() - r);
94         rect.SetTop(rect.GetY() + r);
95         rect.SetHeight(rect.GetHeight() - r);
96     }
97     if (rect.IsContains(invalidatedArea)) {
98         return true;
99     }
100     invalidatedArea.Intersect(invalidatedArea, rect);
101     return false;
102 }
103 
OnDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)104 void UIView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
105 {
106     uint8_t opa = GetMixOpaScale();
107     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, GetOrigRect(), invalidatedArea, *style_, opa);
108 }
109 
OnPostDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)110 void UIView::OnPostDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
111 {
112     DrawViewBounds(gfxDstBuffer, invalidatedArea);
113 }
114 
DrawViewBounds(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)115 void UIView::DrawViewBounds(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
116 {
117 #if ENABLE_DEBUG
118     if (!UIViewBounds::GetInstance()->GetShowState()) {
119         return;
120     }
121     Style* style = new Style();
122     style->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
123     style->SetStyle(STYLE_BORDER_COLOR, Color::Red().full);
124     style->SetStyle(STYLE_BORDER_WIDTH, 1);
125     style->SetStyle(STYLE_BORDER_OPA, OPA_OPAQUE / 2); // 2: half opacity
126     Rect viewRect(GetRect());
127     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, viewRect, invalidatedArea, *style, OPA_OPAQUE);
128 
129     style->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
130     style->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full);
131     style->SetStyle(STYLE_BORDER_WIDTH, 0);
132     Rect tmpRect(viewRect);
133     int16_t length = 10; // 10: corner length
134 
135     // left top corner
136     tmpRect.SetRight(viewRect.GetLeft() + length);
137     tmpRect.SetBottom(viewRect.GetTop());
138     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
139     tmpRect.SetRight(viewRect.GetLeft());
140     tmpRect.SetBottom(viewRect.GetTop() + length);
141     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
142 
143     // left bottom corner
144     tmpRect.SetLeft(viewRect.GetLeft());
145     tmpRect.SetTop(viewRect.GetBottom() - length);
146     tmpRect.SetRight(viewRect.GetLeft());
147     tmpRect.SetBottom(viewRect.GetBottom());
148     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
149     tmpRect.SetTop(viewRect.GetBottom());
150     tmpRect.SetRight(viewRect.GetLeft() + length);
151     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
152 
153     // right top corner
154     tmpRect.SetLeft(viewRect.GetRight() - length);
155     tmpRect.SetTop(viewRect.GetTop());
156     tmpRect.SetRight(viewRect.GetRight());
157     tmpRect.SetBottom(viewRect.GetTop());
158     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
159     tmpRect.SetLeft(viewRect.GetRight());
160     tmpRect.SetBottom(viewRect.GetTop() + length);
161     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
162 
163     // right bottom corner
164     tmpRect = viewRect;
165     tmpRect.SetLeft(viewRect.GetRight());
166     tmpRect.SetTop(viewRect.GetBottom() - length);
167     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
168     tmpRect.SetLeft(viewRect.GetRight() - length);
169     tmpRect.SetTop(viewRect.GetBottom());
170     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
171     delete style;
172 #endif // ENABLE_DEBUG
173 }
174 
SetupThemeStyles()175 void UIView::SetupThemeStyles()
176 {
177     Theme* theme = ThemeManager::GetInstance().GetCurrent();
178     if (theme != nullptr) {
179         style_ = &(theme->GetMainStyle());
180     } else {
181         style_ = &(StyleDefault::GetDefaultStyle());
182     }
183 }
184 
SetStyle(Style & style)185 void UIView::SetStyle(Style& style)
186 {
187     if (styleAllocFlag_) {
188         delete style_;
189         styleAllocFlag_ = false;
190     }
191     style_ = &style;
192 }
193 
SetStyle(uint8_t key,int64_t value)194 void UIView::SetStyle(uint8_t key, int64_t value)
195 {
196     if (!styleAllocFlag_) {
197         style_ = new Style(*style_);
198         if (style_ == nullptr) {
199             GRAPHIC_LOGE("new Style fail");
200             return;
201         }
202         styleAllocFlag_ = true;
203     }
204     int16_t width = GetWidth();
205     int16_t height = GetHeight();
206     int16_t x = GetX();
207     int16_t y = GetY();
208     style_->SetStyle(key, value);
209     Rect rect(x, y, x + width - 1, y + height -  1);
210     UpdateRectInfo(key, rect);
211 }
212 
UpdateRectInfo(uint8_t key,const Rect & rect)213 void UIView::UpdateRectInfo(uint8_t key, const Rect& rect)
214 {
215     switch (key) {
216         case STYLE_BORDER_WIDTH: {
217             SetWidth(rect.GetWidth());
218             SetHeight(rect.GetHeight());
219             break;
220         }
221         case STYLE_PADDING_LEFT:
222         case STYLE_PADDING_RIGHT: {
223             SetWidth(rect.GetWidth());
224             break;
225         }
226         case STYLE_PADDING_TOP:
227         case STYLE_PADDING_BOTTOM: {
228             SetHeight(rect.GetHeight());
229             break;
230         }
231         case STYLE_MARGIN_LEFT: {
232             SetX(rect.GetX());
233             break;
234         }
235         case STYLE_MARGIN_TOP: {
236             SetY(rect.GetY());
237             break;
238         }
239         default:
240             break;
241     }
242 }
243 
Rotate(int16_t angle,const Vector2<float> & pivot)244 void UIView::Rotate(int16_t angle, const Vector2<float>& pivot)
245 {
246     Vector3<float> pivotStart3D = Vector3<float>(pivot.x_, pivot.y_, 0);
247     Vector3<float> pivotEnd3D = Vector3<float>(pivot.x_, pivot.y_, 1.0f);
248     Rotate(angle, pivotStart3D, pivotEnd3D);
249 }
250 
Rotate(int16_t angle,const Vector3<float> & pivotStart,const Vector3<float> & pivotEnd)251 void UIView::Rotate(int16_t angle, const Vector3<float>& pivotStart, const Vector3<float>& pivotEnd)
252 {
253     if (transMap_ == nullptr) {
254         ReMeasure();
255         transMap_ = new TransformMap();
256     }
257     bool firstTrans = transMap_->IsInvalid();
258     Rect joinRect = transMap_->GetBoxRect();
259     transMap_->SetTransMapRect(GetOrigRect());
260     transMap_->Rotate(angle, pivotStart, pivotEnd);
261     if (firstTrans) {
262         joinRect = transMap_->GetBoxRect();
263     } else {
264         joinRect.Join(joinRect, transMap_->GetBoxRect());
265     }
266     joinRect.Join(joinRect, GetOrigRect());
267     InvalidateRect(joinRect);
268 }
269 
Scale(const Vector2<float> & scale,const Vector2<float> & pivot)270 void UIView::Scale(const Vector2<float>& scale, const Vector2<float>& pivot)
271 {
272     Vector3<float> scale3D = Vector3<float>(scale.x_, scale.y_, 1.0f);
273     Vector3<float> pivot3D = Vector3<float>(pivot.x_, pivot.y_, 0);
274     Scale(scale3D, pivot3D);
275 }
276 
Scale(const Vector3<float> & scale,const Vector3<float> & pivot)277 void UIView::Scale(const Vector3<float>& scale, const Vector3<float>& pivot)
278 {
279     if (transMap_ == nullptr) {
280         ReMeasure();
281         transMap_ = new TransformMap();
282     }
283     bool firstTrans = transMap_->IsInvalid();
284     Rect joinRect = transMap_->GetBoxRect();
285     transMap_->SetTransMapRect(GetOrigRect());
286     transMap_->Scale(scale, pivot);
287     if (firstTrans) {
288         joinRect = transMap_->GetBoxRect();
289     } else {
290         joinRect.Join(joinRect, transMap_->GetBoxRect());
291     }
292     joinRect.Join(joinRect, GetOrigRect());
293     InvalidateRect(joinRect);
294 }
295 
Shear(const Vector2<float> & shearX,const Vector2<float> & shearY,const Vector2<float> & shearZ)296 void UIView::Shear(const Vector2<float>& shearX, const Vector2<float>& shearY, const Vector2<float>& shearZ)
297 {
298     if (transMap_ == nullptr) {
299         ReMeasure();
300         transMap_ = new TransformMap();
301     }
302     bool firstTrans = transMap_->IsInvalid();
303     Rect joinRect = transMap_->GetBoxRect();
304     transMap_->SetTransMapRect(GetOrigRect());
305     transMap_->Shear(shearX, shearY, shearZ);
306     if (firstTrans) {
307         joinRect = transMap_->GetBoxRect();
308     } else {
309         joinRect.Join(joinRect, transMap_->GetBoxRect());
310     }
311     joinRect.Join(joinRect, GetOrigRect());
312     InvalidateRect(joinRect);
313 }
314 
Translate(const Vector2<int16_t> & trans)315 void UIView::Translate(const Vector2<int16_t>& trans)
316 {
317     Vector3<int16_t> trans3D = Vector3<int16_t>(trans.x_, trans.y_, 0);
318     Translate(trans3D);
319 }
320 
Translate(const Vector3<int16_t> & trans)321 void UIView::Translate(const Vector3<int16_t>& trans)
322 {
323     if (transMap_ == nullptr) {
324         ReMeasure();
325         transMap_ = new TransformMap();
326     }
327     bool firstTrans = transMap_->IsInvalid();
328     Rect joinRect = transMap_->GetBoxRect();
329     transMap_->SetTransMapRect(GetOrigRect());
330     transMap_->Translate(trans);
331     if (firstTrans) {
332         joinRect = transMap_->GetBoxRect();
333     } else {
334         joinRect.Join(joinRect, transMap_->GetBoxRect());
335     }
336     joinRect.Join(joinRect, GetOrigRect());
337     InvalidateRect(joinRect);
338 }
339 
IsTransInvalid()340 bool UIView::IsTransInvalid()
341 {
342     if (transMap_ == nullptr) {
343         return true;
344     }
345     return transMap_->IsInvalid();
346 }
347 
SetCameraDistance(int16_t distance)348 void UIView::SetCameraDistance(int16_t distance)
349 {
350     if (transMap_ == nullptr) {
351         ReMeasure();
352         transMap_ = new TransformMap();
353     }
354     Rect joinRect = transMap_->GetBoxRect();
355     transMap_->SetTransMapRect(GetOrigRect());
356     transMap_->SetCameraDistance(distance);
357     joinRect.Join(joinRect, transMap_->GetBoxRect());
358     joinRect.Join(joinRect, GetOrigRect());
359     InvalidateRect(joinRect);
360 }
361 
SetCameraPosition(const Vector2<float> & position)362 void UIView::SetCameraPosition(const Vector2<float>& position)
363 {
364     if (transMap_ == nullptr) {
365         ReMeasure();
366         transMap_ = new TransformMap();
367     }
368     Rect joinRect = transMap_->GetBoxRect();
369     transMap_->SetTransMapRect(GetOrigRect());
370     transMap_->SetCameraPosition(position);
371     joinRect.Join(joinRect, transMap_->GetBoxRect());
372     joinRect.Join(joinRect, GetOrigRect());
373     InvalidateRect(joinRect);
374 }
375 
ResetTransParameter()376 void UIView::ResetTransParameter()
377 {
378     if (transMap_ != nullptr) {
379         delete transMap_;
380         transMap_ = nullptr;
381         Invalidate();
382     }
383 }
384 
385 #if ENABLE_ROTATE_INPUT
RequestFocus()386 void UIView::RequestFocus()
387 {
388     FocusManager::GetInstance()->RequestFocus(this);
389 }
390 
ClearFocus()391 void UIView::ClearFocus()
392 {
393     FocusManager::GetInstance()->ClearFocus();
394 }
395 #endif
396 
Invalidate()397 void UIView::Invalidate()
398 {
399     InvalidateRect(GetRect());
400 }
401 
InvalidateRect(const Rect & invalidatedArea)402 void UIView::InvalidateRect(const Rect& invalidatedArea)
403 {
404     if (!visible_) {
405         if (needRedraw_) {
406             needRedraw_ = false;
407         } else {
408             return;
409         }
410     }
411 
412     Rect trunc(invalidatedArea);
413     bool isIntersect = true;
414     UIView* par = parent_;
415     UIView* cur = this;
416 
417     while (par != nullptr) {
418         if (!par->visible_) {
419             return;
420         }
421 
422         isIntersect = trunc.Intersect(par->GetContentRect(), trunc);
423         if (!isIntersect) {
424             break;
425         }
426 
427         cur = par;
428         par = par->parent_;
429     }
430 
431     if (isIntersect && (cur->GetViewType() == UI_ROOT_VIEW)) {
432         RootView* rootView = reinterpret_cast<RootView*>(cur);
433         rootView->AddInvalidateRectWithLock(trunc, this);
434     }
435 }
436 
OnLongPressEvent(const LongPressEvent & event)437 bool UIView::OnLongPressEvent(const LongPressEvent& event)
438 {
439     if (onLongPressListener_ != nullptr) {
440         /* To ensure version compatibility, the listeners of both versions are invoked. */
441         bool isConsumed = onLongPressListener_->OnLongPress(*this, event);
442         return isConsumed;
443     }
444     return isIntercept_;
445 }
446 
OnDragStartEvent(const DragEvent & event)447 bool UIView::OnDragStartEvent(const DragEvent& event)
448 {
449     if (onDragListener_ != nullptr) {
450         /* To ensure version compatibility, the listeners of both versions are invoked. */
451         bool isConsumed = onDragListener_->OnDragStart(*this, event);
452         return isConsumed;
453     }
454     return isIntercept_;
455 }
456 
OnDragEvent(const DragEvent & event)457 bool UIView::OnDragEvent(const DragEvent& event)
458 {
459     if (onDragListener_ != nullptr) {
460         /* To ensure version compatibility, the listeners of both versions are invoked. */
461         bool isConsumed = onDragListener_->OnDrag(*this, event);
462         return isConsumed;
463     }
464     return isIntercept_;
465 }
466 
OnDragEndEvent(const DragEvent & event)467 bool UIView::OnDragEndEvent(const DragEvent& event)
468 {
469     if (onDragListener_ != nullptr) {
470         /* To ensure version compatibility, the listeners of both versions are invoked. */
471         bool isConsumed = onDragListener_->OnDragEnd(*this, event);
472         return isConsumed;
473     }
474     return isIntercept_;
475 }
476 
OnClickEvent(const ClickEvent & event)477 bool UIView::OnClickEvent(const ClickEvent& event)
478 {
479     if (onClickListener_ != nullptr) {
480         /* To ensure version compatibility, the listeners of both versions are invoked. */
481         bool isConsumed = onClickListener_->OnClick(*this, event);
482         return isConsumed;
483     }
484     return isIntercept_;
485 }
486 
OnPressEvent(const PressEvent & event)487 bool UIView::OnPressEvent(const PressEvent& event)
488 {
489     if (onTouchListener_ != nullptr) {
490         /* To ensure version compatibility, the listeners of both versions are invoked. */
491         bool isConsumed = onTouchListener_->OnPress(*this, event);
492         return isConsumed;
493     }
494     return isIntercept_;
495 }
496 
OnReleaseEvent(const ReleaseEvent & event)497 bool UIView::OnReleaseEvent(const ReleaseEvent& event)
498 {
499     if (onTouchListener_ != nullptr) {
500         /* To ensure version compatibility, the listeners of both versions are invoked. */
501         bool isConsumed = onTouchListener_->OnRelease(*this, event);
502         return isConsumed;
503     }
504     return isIntercept_;
505 }
506 
OnCancelEvent(const CancelEvent & event)507 bool UIView::OnCancelEvent(const CancelEvent& event)
508 {
509     if (onTouchListener_ != nullptr) {
510         /* To ensure version compatibility, the listeners of both versions are invoked. */
511         bool isConsumed = onTouchListener_->OnCancel(*this, event);
512         return isConsumed;
513     }
514     return isIntercept_;
515 }
516 
517 #if ENABLE_ROTATE_INPUT
OnRotateStartEvent(const RotateEvent & event)518 bool UIView::OnRotateStartEvent(const RotateEvent& event)
519 {
520     if (onRotateListener_ != nullptr) {
521         return onRotateListener_->OnRotateStart(*this, event);
522     }
523     return false;
524 }
525 
OnRotateEvent(const RotateEvent & event)526 bool UIView::OnRotateEvent(const RotateEvent& event)
527 {
528     if (onRotateListener_ != nullptr) {
529         return onRotateListener_->OnRotate(*this, event);
530     }
531     return isIntercept_;
532 }
533 
OnRotateEndEvent(const RotateEvent & event)534 bool UIView::OnRotateEndEvent(const RotateEvent& event)
535 {
536     if (onRotateListener_ != nullptr) {
537         return onRotateListener_->OnRotateEnd(*this, event);
538     }
539     return false;
540 }
541 #endif
542 
GetTargetView(const Point & point,UIView ** last)543 void UIView::GetTargetView(const Point& point, UIView** last)
544 {
545     if (last == nullptr) {
546         return;
547     }
548     UIView* par = parent_;
549     Rect rect = GetRect();
550 
551     if (par != nullptr) {
552         rect.Intersect(par->GetContentRect(), rect);
553     }
554 
555     if (visible_ && touchable_ && rect.IsContains(point)) {
556         *last = this;
557     }
558 }
559 
GetTargetView(const Point & point,UIView ** current,UIView ** target)560 void UIView::GetTargetView(const Point& point, UIView** current, UIView** target)
561 {
562     if (current == nullptr) {
563         return;
564     }
565     UIView* par = parent_;
566     Rect rect = GetRect();
567 
568     if (par != nullptr) {
569         rect.Intersect(par->GetContentRect(), rect);
570     }
571 
572     if (visible_ && rect.IsContains(point)) {
573         if (touchable_) {
574             *current = this;
575         }
576         *target = this;
577     }
578 }
579 
580 #if ENABLE_FOCUS_MANAGER
Focus()581 void UIView::Focus()
582 {
583     if (focusable_ && onFocusListener_ != nullptr) {
584         onFocusListener_->OnFocus(*this);
585     }
586 }
587 
Blur()588 void UIView::Blur()
589 {
590     if (onFocusListener_ != nullptr) {
591         onFocusListener_->OnBlur(*this);
592     }
593 }
594 #endif
595 
GetRect() const596 Rect UIView::GetRect() const
597 {
598     if ((transMap_ != nullptr) && !transMap_->IsInvalid()) {
599         Rect r = transMap_->GetBoxRect();
600         Rect origRect = GetOrigRect();
601         r.SetX(r.GetX() + origRect.GetX() - transMap_->GetTransMapRect().GetX());
602         r.SetY(r.GetY() + origRect.GetY() - transMap_->GetTransMapRect().GetY());
603         return r;
604     }
605     return GetOrigRect();
606 }
607 
GetContentRect()608 Rect UIView::GetContentRect()
609 {
610     if ((transMap_ != nullptr) && !transMap_->IsInvalid()) {
611         Rect r = transMap_->GetBoxRect();
612         Rect origRect = GetOrigRect();
613         r.SetX(r.GetX() + origRect.GetX() - transMap_->GetTransMapRect().GetX());
614         r.SetY(r.GetY() + origRect.GetY() - transMap_->GetTransMapRect().GetY());
615         return r;
616     }
617 
618     Rect contentRect = GetRect();
619     contentRect.SetX(contentRect.GetX() + style_->paddingLeft_ + style_->borderWidth_);
620     contentRect.SetY(contentRect.GetY() + style_->paddingTop_ + style_->borderWidth_);
621     contentRect.SetWidth(GetWidth());
622     contentRect.SetHeight(GetHeight());
623     return contentRect;
624 }
625 
GetOrigRect() const626 Rect UIView::GetOrigRect() const
627 {
628     int16_t x = rect_.GetX();
629     int16_t y = rect_.GetY();
630     UIView* par = parent_;
631     while (par != nullptr) {
632         x += par->GetRelativeRect().GetX() + par->GetStyle(STYLE_PADDING_LEFT) + par->GetStyle(STYLE_BORDER_WIDTH);
633         y += par->GetRelativeRect().GetY() + par->GetStyle(STYLE_PADDING_TOP) + par->GetStyle(STYLE_BORDER_WIDTH);
634         par = par->parent_;
635     }
636     return Rect(x, y, x + rect_.GetWidth() - 1, y + rect_.GetHeight() - 1);
637 }
638 
GetMaskedRect() const639 Rect UIView::GetMaskedRect() const
640 {
641     Rect mask;
642     if (visibleRect_ != nullptr) {
643         mask.Intersect(GetRect(), GetVisibleRect());
644     } else {
645         mask = GetRect();
646     }
647     return mask;
648 }
649 
GetVisibleRect() const650 Rect UIView::GetVisibleRect() const
651 {
652     if (visibleRect_ == nullptr) {
653         return GetRect();
654     }
655     Rect absoluteRect;
656     int16_t x = visibleRect_->GetX();
657     int16_t y = visibleRect_->GetY();
658     UIView* par = parent_;
659     while (par != nullptr) {
660         x += par->GetX();
661         y += par->GetY();
662         par = par->parent_;
663     }
664     absoluteRect.SetX(x);
665     absoluteRect.SetY(y);
666     absoluteRect.SetWidth(visibleRect_->GetWidth());
667     absoluteRect.SetHeight(visibleRect_->GetHeight());
668     return absoluteRect;
669 }
670 
SetTransformMap(const TransformMap & transMap)671 void UIView::SetTransformMap(const TransformMap& transMap)
672 {
673     if ((transMap_ != nullptr) && (*transMap_ == transMap)) {
674         return;
675     }
676 
677     if (transMap_ == nullptr) {
678         transMap_ = new TransformMap();
679     }
680     Rect preRect = GetRect();
681     *transMap_ = transMap;
682     transMap_->SetTransMapRect(GetOrigRect());
683 
684     Rect joinRect;
685     joinRect.Join(preRect, transMap_->GetBoxRect());
686     InvalidateRect(joinRect);
687 }
688 
SetWidthPercent(float widthPercent)689 void UIView::SetWidthPercent(float widthPercent)
690 {
691     if (IsInvalid(widthPercent)) {
692         return;
693     }
694     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1)) {
695         int16_t newWidth = static_cast<int16_t>(GetParent()->GetWidth() * widthPercent);
696         SetWidth(newWidth);
697     }
698 }
699 
SetHeightPercent(float heightPercent)700 void UIView::SetHeightPercent(float heightPercent)
701 {
702     if (IsInvalid(heightPercent)) {
703         return;
704     }
705     if ((GetParent() != nullptr) && (GetParent()->GetHeight() > 1)) {
706         int16_t newHeight = static_cast<int16_t>(GetParent()->GetHeight() * heightPercent);
707         SetHeight(newHeight);
708     }
709 }
710 
ResizePercent(float widthPercent,float heightPercent)711 void UIView::ResizePercent(float widthPercent, float heightPercent)
712 {
713     if (IsInvalid(widthPercent) || IsInvalid(heightPercent)) {
714         return;
715     }
716     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1) && (GetParent()->GetHeight() > 1)) {
717         int16_t newWidth = static_cast<int16_t>(GetParent()->GetWidth() * widthPercent);
718         int16_t newHeight = static_cast<int16_t>(GetParent()->GetHeight() * heightPercent);
719         Resize(newWidth, newHeight);
720     }
721 }
722 
SetXPercent(float xPercent)723 void UIView::SetXPercent(float xPercent)
724 {
725     if (IsInvalid(xPercent)) {
726         return;
727     }
728     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1)) {
729         int16_t newX = static_cast<int16_t>(GetParent()->GetWidth() * xPercent);
730         SetX(newX);
731     }
732 }
733 
SetYPercent(float yPercent)734 void UIView::SetYPercent(float yPercent)
735 {
736     if (IsInvalid(yPercent)) {
737         return;
738     }
739     if ((GetParent() != nullptr) && (GetParent()->GetHeight() > 1)) {
740         int16_t newY = static_cast<int16_t>(GetParent()->GetHeight() * yPercent);
741         SetY(newY);
742     }
743 }
744 
SetPositionPercent(float xPercent,float yPercent)745 void UIView::SetPositionPercent(float xPercent, float yPercent)
746 {
747     if (IsInvalid(xPercent) || IsInvalid(yPercent)) {
748         return;
749     }
750     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1) && (GetParent()->GetHeight() > 1)) {
751         int16_t newX = static_cast<int16_t>(GetParent()->GetWidth() * xPercent);
752         int16_t newY = static_cast<int16_t>(GetParent()->GetHeight() * yPercent);
753         SetPosition(newX, newY);
754     }
755 }
756 
SetPositionPercent(float xPercent,float yPercent,float widthPercent,float heightPercent)757 void UIView::SetPositionPercent(float xPercent, float yPercent, float widthPercent, float heightPercent)
758 {
759     if (IsInvalid(xPercent) || IsInvalid(yPercent) || IsInvalid(widthPercent) || IsInvalid(heightPercent)) {
760         return;
761     }
762     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1) && (GetParent()->GetHeight() > 1)) {
763         int16_t newX = static_cast<int16_t>(GetParent()->GetWidth() * xPercent);
764         int16_t newY = static_cast<int16_t>(GetParent()->GetHeight() * yPercent);
765         int16_t newWidth = static_cast<int16_t>(GetParent()->GetWidth() * widthPercent);
766         int16_t newHeight = static_cast<int16_t>(GetParent()->GetHeight() * heightPercent);
767         SetPosition(newX, newY, newWidth, newHeight);
768     }
769 }
770 
IsInvalid(float percent)771 bool UIView::IsInvalid(float percent)
772 {
773     if ((percent < 1) && (percent > 0)) {
774         return false;
775     }
776     return true;
777 }
778 
LayoutCenterOfParent(int16_t xOffset,int16_t yOffset)779 void UIView::LayoutCenterOfParent(int16_t xOffset, int16_t yOffset)
780 {
781     if (parent_ == nullptr) {
782         return;
783     }
784 
785     int16_t topMargin = style_->marginTop_;
786     int16_t leftMargin = style_->marginLeft_;
787     int16_t rightMargin = style_->marginRight_;
788     int16_t bottomMargin = style_->marginBottom_;
789     // 2: half
790     int16_t posX = parent_->GetWidth() / 2 - (rect_.GetWidth() - leftMargin + rightMargin) / 2 + xOffset;
791     // 2: half
792     int16_t posY = parent_->GetHeight() / 2 - (rect_.GetHeight() - topMargin + bottomMargin) / 2 + yOffset;
793     SetPosition(posX, posY);
794 }
795 
LayoutLeftOfParent(int16_t offset)796 void UIView::LayoutLeftOfParent(int16_t offset)
797 {
798     if (parent_ == nullptr) {
799         return;
800     }
801 
802     int16_t leftMargin = style_->marginLeft_;
803     SetPosition(leftMargin + offset, GetY());
804 }
805 
LayoutRightOfParent(int16_t offset)806 void UIView::LayoutRightOfParent(int16_t offset)
807 {
808     if (parent_ == nullptr) {
809         return;
810     }
811 
812     int16_t rightMargin = style_->marginRight_;
813     SetPosition(parent_->GetWidth() - offset - rect_.GetWidth() - rightMargin, GetY());
814 }
815 
LayoutTopOfParent(int16_t offset)816 void UIView::LayoutTopOfParent(int16_t offset)
817 {
818     if (parent_ == nullptr) {
819         return;
820     }
821 
822     int16_t topMargin = style_->marginTop_;
823     SetPosition(GetX(), topMargin + offset);
824 }
825 
LayoutBottomOfParent(int16_t offset)826 void UIView::LayoutBottomOfParent(int16_t offset)
827 {
828     if (parent_ == nullptr) {
829         return;
830     }
831 
832     int16_t bottomMargin = style_->marginBottom_;
833     SetPosition(GetX(), parent_->GetHeight() - offset - rect_.GetHeight() - bottomMargin);
834 }
835 
AlignLeftToSibling(const char * id,int16_t offset)836 void UIView::AlignLeftToSibling(const char* id, int16_t offset)
837 {
838     if (parent_ == nullptr) {
839         return;
840     }
841     UIView* sib = parent_->GetChildById(id);
842     if (sib != nullptr) {
843         int16_t margin = sib->style_->marginLeft_ - style_->marginLeft_;
844         SetPosition(sib->GetX() - margin + offset, GetY());
845     }
846 }
847 
AlignRightToSibling(const char * id,int16_t offset)848 void UIView::AlignRightToSibling(const char* id, int16_t offset)
849 {
850     if (parent_ == nullptr) {
851         return;
852     }
853     UIView* sib = parent_->GetChildById(id);
854     if (sib != nullptr) {
855         int16_t margin = sib->style_->marginRight_ - style_->marginRight_;
856         SetPosition(sib->GetX() + sib->rect_.GetWidth() - rect_.GetWidth() - offset + margin, GetY());
857     }
858 }
859 
AlignTopToSibling(const char * id,int16_t offset)860 void UIView::AlignTopToSibling(const char* id, int16_t offset)
861 {
862     if (parent_ == nullptr) {
863         return;
864     }
865     UIView* sib = parent_->GetChildById(id);
866     if (sib != nullptr) {
867         int16_t margin = sib->style_->marginTop_ - style_->marginTop_;
868         SetPosition(GetX(), sib->GetY() + offset - margin);
869     }
870 }
871 
AlignBottomToSibling(const char * id,int16_t offset)872 void UIView::AlignBottomToSibling(const char* id, int16_t offset)
873 {
874     if (parent_ == nullptr) {
875         return;
876     }
877     UIView* sib = parent_->GetChildById(id);
878     if (sib != nullptr) {
879         int16_t margin = sib->style_->marginBottom_ - style_->marginBottom_;
880         SetPosition(GetX(), sib->GetY() + sib->rect_.GetHeight() - rect_.GetHeight() - offset + margin);
881     }
882 }
883 
AlignHorCenterToSibling(const char * id,int16_t offset)884 void UIView::AlignHorCenterToSibling(const char* id, int16_t offset)
885 {
886     if (parent_ == nullptr) {
887         return;
888     }
889     UIView* sib = parent_->GetChildById(id);
890     if (sib != nullptr) {
891         int16_t margin =
892             (sib->style_->marginRight_ - sib->style_->marginLeft_ - style_->marginRight_ + style_->marginLeft_) /
893             2; // 2 : half
894         SetPosition(sib->GetX() + sib->rect_.GetWidth() / 2 - rect_.GetWidth() / 2 + margin + offset, GetY());
895     }
896 }
AlignVerCenterToSibling(const char * id,int16_t offset)897 void UIView::AlignVerCenterToSibling(const char* id, int16_t offset)
898 {
899     if (parent_ == nullptr) {
900         return;
901     }
902     UIView* sib = parent_->GetChildById(id);
903     if (sib != nullptr) {
904         int16_t margin =
905             (sib->style_->marginBottom_ - sib->style_->marginTop_ - style_->marginBottom_ + style_->marginTop_) /
906             2; // 2 : half
907         SetPosition(GetX(), sib->GetY() + sib->rect_.GetHeight() / 2 - rect_.GetHeight() / 2 + margin + offset);
908     }
909 }
910 
LayoutLeftToSibling(const char * id,int16_t offset)911 void UIView::LayoutLeftToSibling(const char* id, int16_t offset)
912 {
913     if (parent_ == nullptr) {
914         return;
915     }
916     UIView* sib = parent_->GetChildById(id);
917     if (sib != nullptr) {
918         int16_t margin = sib->style_->marginLeft_ + style_->marginRight_;
919         SetPosition(sib->GetX() - offset - rect_.GetWidth() - margin, GetY());
920     }
921 }
922 
LayoutRightToSibling(const char * id,int16_t offset)923 void UIView::LayoutRightToSibling(const char* id, int16_t offset)
924 {
925     if (parent_ == nullptr) {
926         return;
927     }
928     UIView* sib = parent_->GetChildById(id);
929     if (sib != nullptr) {
930         int16_t margin = sib->style_->marginRight_ + style_->marginLeft_;
931         SetPosition(sib->GetX() + sib->rect_.GetWidth() + offset + margin, GetY());
932     }
933 }
934 
LayoutTopToSibling(const char * id,int16_t offset)935 void UIView::LayoutTopToSibling(const char* id, int16_t offset)
936 {
937     if (parent_ == nullptr) {
938         return;
939     }
940     UIView* sib = parent_->GetChildById(id);
941     if (sib != nullptr) {
942         int16_t margin = sib->style_->marginTop_ + style_->marginBottom_;
943         SetPosition(GetX(), sib->GetY() - offset - rect_.GetHeight() - margin);
944     }
945 }
946 
LayoutBottomToSibling(const char * id,int16_t offset)947 void UIView::LayoutBottomToSibling(const char* id, int16_t offset)
948 {
949     if (parent_ == nullptr) {
950         return;
951     }
952     UIView* sib = parent_->GetChildById(id);
953     if (sib != nullptr) {
954         int16_t margin = sib->style_->marginBottom_ + style_->marginTop_;
955         SetPosition(GetX(), sib->GetY() + sib->rect_.GetHeight() + offset + margin);
956     }
957 }
958 
GetMixOpaScale() const959 uint8_t UIView::GetMixOpaScale() const
960 {
961     uint8_t opaMix = opaScale_;
962     UIView* parent = parent_;
963     uint8_t opaParent;
964     while (parent != nullptr) {
965         opaParent = parent->GetOpaScale();
966         // 8: Shift right 8 bits
967         opaMix = (opaParent == OPA_OPAQUE) ? opaMix : ((static_cast<uint16_t>(opaParent) * opaMix) >> 8);
968         parent = parent->GetParent();
969     }
970     return opaMix;
971 }
972 
GetBitmap(ImageInfo & bitmap)973 bool UIView::GetBitmap(ImageInfo& bitmap)
974 {
975     UIView* tempSibling = nextSibling_;
976     UIView* tempParent = parent_;
977     int16_t tempX = rect_.GetX();
978     int16_t tempY = rect_.GetY();
979     nextSibling_ = nullptr;
980     parent_ = nullptr;
981 
982     rect_.SetPosition(0, 0);
983     Rect mask = GetRect();
984     uint16_t bufferWidth = static_cast<uint16_t>(mask.GetWidth());
985     uint16_t bufferHeight = static_cast<uint16_t>(mask.GetHeight());
986     bitmap.header.colorMode = ARGB8888;
987     bitmap.dataSize = bufferWidth * bufferHeight * DrawUtils::GetByteSizeByColorMode(bitmap.header.colorMode);
988     bitmap.header.width = bufferWidth;
989     bitmap.header.height = bufferHeight;
990     bitmap.header.reserved = 0;
991 
992     void* viewBitmapBuffer = ImageCacheMalloc(bitmap);
993     if (viewBitmapBuffer == nullptr) {
994         GRAPHIC_LOGE("GetBitmap buffer alloc failed.");
995         nextSibling_ = tempSibling;
996         parent_ = tempParent;
997         rect_.SetPosition(tempX, tempY);
998         return false;
999     }
1000     bitmap.data = reinterpret_cast<uint8_t*>(viewBitmapBuffer);
1001     if (memset_s(viewBitmapBuffer, bitmap.dataSize, 0, bitmap.dataSize) != EOK) {
1002         GRAPHIC_LOGE("GetBitmap buffer memset failed.");
1003         ImageCacheFree(bitmap);
1004         bitmap.data = nullptr;
1005         return false;
1006     }
1007 
1008     BufferInfo newBufferInfo;
1009     newBufferInfo.virAddr = viewBitmapBuffer;
1010     newBufferInfo.phyAddr = newBufferInfo.virAddr;
1011     newBufferInfo.rect = mask;
1012     newBufferInfo.width = bufferWidth;
1013     newBufferInfo.height = bufferHeight;
1014     newBufferInfo.mode = ARGB8888;
1015     newBufferInfo.stride = bufferWidth *  DrawUtils::GetByteSizeByColorMode(bitmap.header.colorMode);
1016 
1017     RootView::GetInstance()->SaveDrawContext();
1018     RootView::GetInstance()->UpdateBufferInfo(&newBufferInfo);
1019     RootView::GetInstance()->MeasureView(this);
1020     RootView::GetInstance()->DrawTop(this, mask);
1021     RootView::GetInstance()->RestoreDrawContext();
1022     nextSibling_ = tempSibling;
1023     parent_ = tempParent;
1024     rect_.SetPosition(tempX, tempY);
1025     return true;
1026 }
1027 
IsOnViewTree()1028 bool UIView::IsOnViewTree()
1029 {
1030     UIView* par = this;
1031     while (par->GetParent() != nullptr) {
1032         par = par->GetParent();
1033     }
1034     if (par->GetViewType() != UI_ROOT_VIEW) {
1035         return false;
1036     }
1037     return true;
1038 }
1039 } // namespace OHOS
1040