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 "components/ui_view_group.h"
20 #include "core/render_manager.h"
21 #include "dfx/ui_view_bounds.h"
22 #include "dock/focus_manager.h"
23 #include "draw/draw_utils.h"
24 #include "engines/gfx/gfx_engine_manager.h"
25 #include "gfx_utils/graphic_log.h"
26 #include "gfx_utils/mem_api.h"
27 #include "securec.h"
28 #include "themes/theme_manager.h"
29 
30 namespace OHOS {
UIView()31 UIView::UIView()
32     : touchable_(false),
33       visible_(true),
34       draggable_(false),
35       dragParentInstead_(true),
36       isViewGroup_(false),
37       needRedraw_(false),
38       styleAllocFlag_(false),
39       isIntercept_(false),
40 #if ENABLE_FOCUS_MANAGER
41       focusable_(false),
42 #endif
43       opaScale_(OPA_OPAQUE),
44       index_(0),
45       zIndex_(0),
46       id_(nullptr),
47       parent_(nullptr),
48       nextSibling_(nullptr),
49       nextRenderSibling_(nullptr),
50       style_(nullptr),
51       transMap_(nullptr),
52       onClickListener_(nullptr),
53       onLongPressListener_(nullptr),
54       onDragListener_(nullptr),
55       onTouchListener_(nullptr),
56 #if ENABLE_FOCUS_MANAGER
57       onFocusListener_(nullptr),
58 #endif
59 #if ENABLE_ROTATE_INPUT
60       onRotateListener_(nullptr),
61 #endif
62       viewExtraMsg_(nullptr),
63       rect_(0, 0, 0, 0),
64       visibleRect_(nullptr)
65 {
66     SetupThemeStyles();
67 }
68 
~UIView()69 UIView::~UIView()
70 {
71     if (transMap_ != nullptr) {
72         delete transMap_;
73         transMap_ = nullptr;
74     }
75     if (visibleRect_ != nullptr) {
76         delete visibleRect_;
77         visibleRect_ = nullptr;
78     }
79     if (styleAllocFlag_) {
80         delete style_;
81         style_ = nullptr;
82         styleAllocFlag_ = false;
83     }
84 }
85 
OnPreDraw(Rect & invalidatedArea) const86 bool UIView::OnPreDraw(Rect& invalidatedArea) const
87 {
88     Rect rect(GetRect());
89     uint16_t r = style_->borderRadius_; // radius must be positive
90     if (r == COORD_MAX) {
91         return true;
92     }
93     if (r != 0) {
94         r = ((r & 0x1) == 0) ? (r >> 1) : ((r + 1) >> 1);
95         rect.SetLeft(rect.GetX() + r);
96         rect.SetWidth(rect.GetWidth() - r);
97         rect.SetTop(rect.GetY() + r);
98         rect.SetHeight(rect.GetHeight() - r);
99     }
100     if (rect.IsContains(invalidatedArea)) {
101         return true;
102     }
103     invalidatedArea.Intersect(invalidatedArea, rect);
104     return false;
105 }
106 
OnDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)107 void UIView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
108 {
109     uint8_t opa = GetMixOpaScale();
110     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, GetOrigRect(), invalidatedArea, *style_, opa);
111 }
112 
OnPostDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)113 void UIView::OnPostDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
114 {
115     DrawViewBounds(gfxDstBuffer, invalidatedArea);
116 }
117 
DrawViewBounds(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)118 void UIView::DrawViewBounds(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
119 {
120 #if ENABLE_DEBUG
121     if (!UIViewBounds::GetInstance()->GetShowState()) {
122         return;
123     }
124     Style* style = new Style();
125     style->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);
126     style->SetStyle(STYLE_BORDER_COLOR, Color::Red().full);
127     style->SetStyle(STYLE_BORDER_WIDTH, 1);
128     style->SetStyle(STYLE_BORDER_OPA, OPA_OPAQUE / 2); // 2: half opacity
129     Rect viewRect(GetRect());
130     BaseGfxEngine* baseGfxEngine = BaseGfxEngine::GetInstance();
131     baseGfxEngine->DrawRect(gfxDstBuffer, viewRect, invalidatedArea, *style, OPA_OPAQUE);
132 
133     style->SetStyle(STYLE_BACKGROUND_OPA, OPA_OPAQUE);
134     style->SetStyle(STYLE_BACKGROUND_COLOR, Color::Blue().full);
135     style->SetStyle(STYLE_BORDER_WIDTH, 0);
136     Rect tmpRect(viewRect);
137     int16_t length = 10; // 10: corner length
138 
139     // left top corner
140     tmpRect.SetRight(viewRect.GetLeft() + length);
141     tmpRect.SetBottom(viewRect.GetTop());
142     baseGfxEngine->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
143     tmpRect.SetRight(viewRect.GetLeft());
144     tmpRect.SetBottom(viewRect.GetTop() + length);
145     baseGfxEngine->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
146 
147     // left bottom corner
148     tmpRect.SetLeft(viewRect.GetLeft());
149     tmpRect.SetTop(viewRect.GetBottom() - length);
150     tmpRect.SetRight(viewRect.GetLeft());
151     tmpRect.SetBottom(viewRect.GetBottom());
152     baseGfxEngine->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
153     tmpRect.SetTop(viewRect.GetBottom());
154     tmpRect.SetRight(viewRect.GetLeft() + length);
155     baseGfxEngine->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
156 
157     // right top corner
158     tmpRect.SetLeft(viewRect.GetRight() - length);
159     tmpRect.SetTop(viewRect.GetTop());
160     tmpRect.SetRight(viewRect.GetRight());
161     tmpRect.SetBottom(viewRect.GetTop());
162     baseGfxEngine->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
163     tmpRect.SetLeft(viewRect.GetRight());
164     tmpRect.SetBottom(viewRect.GetTop() + length);
165     baseGfxEngine->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
166 
167     // right bottom corner
168     tmpRect = viewRect;
169     tmpRect.SetLeft(viewRect.GetRight());
170     tmpRect.SetTop(viewRect.GetBottom() - length);
171     baseGfxEngine->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
172     tmpRect.SetLeft(viewRect.GetRight() - length);
173     tmpRect.SetTop(viewRect.GetBottom());
174     baseGfxEngine->DrawRect(gfxDstBuffer, tmpRect, invalidatedArea, *style, OPA_OPAQUE);
175     delete style;
176 #endif // ENABLE_DEBUG
177 }
178 
SetupThemeStyles()179 void UIView::SetupThemeStyles()
180 {
181     Theme* theme = ThemeManager::GetInstance().GetCurrent();
182     if (theme != nullptr) {
183         style_ = &(theme->GetMainStyle());
184     } else {
185         style_ = &(StyleDefault::GetDefaultStyle());
186     }
187 }
188 
SetStyle(Style & style)189 void UIView::SetStyle(Style& style)
190 {
191     if (styleAllocFlag_) {
192         delete style_;
193         styleAllocFlag_ = false;
194     }
195     style_ = &style;
196 }
197 
SetStyle(uint8_t key,int64_t value)198 void UIView::SetStyle(uint8_t key, int64_t value)
199 {
200     if (!styleAllocFlag_) {
201         style_ = new Style(*style_);
202         if (style_ == nullptr) {
203             GRAPHIC_LOGE("new Style fail");
204             return;
205         }
206         styleAllocFlag_ = true;
207     }
208     int16_t width = GetWidth();
209     int16_t height = GetHeight();
210     int16_t x = GetX();
211     int16_t y = GetY();
212     style_->SetStyle(key, value);
213     Rect rect(x, y, x + width - 1, y + height - 1);
214     UpdateRectInfo(key, rect);
215 }
216 
UpdateRectInfo(uint8_t key,const Rect & rect)217 void UIView::UpdateRectInfo(uint8_t key, const Rect& rect)
218 {
219     switch (key) {
220         case STYLE_BORDER_WIDTH: {
221             SetWidth(rect.GetWidth());
222             SetHeight(rect.GetHeight());
223             break;
224         }
225         case STYLE_PADDING_LEFT:
226         case STYLE_PADDING_RIGHT: {
227             SetWidth(rect.GetWidth());
228             break;
229         }
230         case STYLE_PADDING_TOP:
231         case STYLE_PADDING_BOTTOM: {
232             SetHeight(rect.GetHeight());
233             break;
234         }
235         case STYLE_MARGIN_LEFT: {
236             SetX(rect.GetX());
237             break;
238         }
239         case STYLE_MARGIN_TOP: {
240             SetY(rect.GetY());
241             break;
242         }
243         default:
244             break;
245     }
246 }
247 
GetStyle(uint8_t key) const248 int64_t UIView::GetStyle(uint8_t key) const
249 {
250     return style_->GetStyle(key);
251 }
252 
GetStyleConst() const253 const Style& UIView::GetStyleConst() const
254 {
255     return *style_;
256 }
257 
SetOpaScale(uint8_t opaScale)258 void UIView::SetOpaScale(uint8_t opaScale)
259 {
260     opaScale_ = opaScale;
261 }
262 
GetOpaScale() const263 uint8_t UIView::GetOpaScale() const
264 {
265     return opaScale_;
266 }
267 
GetExtraMsg()268 UIView::ViewExtraMsg* UIView::GetExtraMsg()
269 {
270     return viewExtraMsg_;
271 }
272 
SetExtraMsg(ViewExtraMsg * extraMsg)273 void UIView::SetExtraMsg(ViewExtraMsg* extraMsg)
274 {
275     viewExtraMsg_ = extraMsg;
276 }
277 
Rotate(int16_t angle,const Vector2<float> & pivot)278 void UIView::Rotate(int16_t angle, const Vector2<float>& pivot)
279 {
280     Vector3<float> pivotStart3D = Vector3<float>(pivot.x_, pivot.y_, 0);
281     Vector3<float> pivotEnd3D = Vector3<float>(pivot.x_, pivot.y_, 1.0f);
282     Rotate(angle, pivotStart3D, pivotEnd3D);
283 }
284 
Rotate(int16_t angle,const Vector3<float> & pivotStart,const Vector3<float> & pivotEnd)285 void UIView::Rotate(int16_t angle, const Vector3<float>& pivotStart, const Vector3<float>& pivotEnd)
286 {
287     if (transMap_ == nullptr) {
288         ReMeasure();
289         transMap_ = new TransformMap();
290     }
291     bool firstTrans = transMap_->IsInvalid();
292     Rect joinRect = transMap_->GetBoxRect();
293     transMap_->SetTransMapRect(GetOrigRect());
294     transMap_->Rotate(angle, pivotStart, pivotEnd);
295     if (firstTrans) {
296         joinRect = transMap_->GetBoxRect();
297     } else {
298         joinRect.Join(joinRect, transMap_->GetBoxRect());
299     }
300     joinRect.Join(joinRect, GetOrigRect());
301     InvalidateRect(joinRect);
302 }
303 
Scale(const Vector2<float> & scale,const Vector2<float> & pivot)304 void UIView::Scale(const Vector2<float>& scale, const Vector2<float>& pivot)
305 {
306     Vector3<float> scale3D = Vector3<float>(scale.x_, scale.y_, 1.0f);
307     Vector3<float> pivot3D = Vector3<float>(pivot.x_, pivot.y_, 0);
308     Scale(scale3D, pivot3D);
309 }
310 
Scale(const Vector3<float> & scale,const Vector3<float> & pivot)311 void UIView::Scale(const Vector3<float>& scale, const Vector3<float>& pivot)
312 {
313     if (transMap_ == nullptr) {
314         ReMeasure();
315         transMap_ = new TransformMap();
316     }
317     bool firstTrans = transMap_->IsInvalid();
318     Rect joinRect = transMap_->GetBoxRect();
319     transMap_->SetTransMapRect(GetOrigRect());
320     transMap_->Scale(scale, pivot);
321     if (firstTrans) {
322         joinRect = transMap_->GetBoxRect();
323     } else {
324         joinRect.Join(joinRect, transMap_->GetBoxRect());
325     }
326     joinRect.Join(joinRect, GetOrigRect());
327     InvalidateRect(joinRect);
328 }
329 
Shear(const Vector2<float> & shearX,const Vector2<float> & shearY,const Vector2<float> & shearZ)330 void UIView::Shear(const Vector2<float>& shearX, const Vector2<float>& shearY, const Vector2<float>& shearZ)
331 {
332     if (transMap_ == nullptr) {
333         ReMeasure();
334         transMap_ = new TransformMap();
335         if (transMap_ == nullptr) {
336             return;
337         }
338     }
339     bool firstTrans = transMap_->IsInvalid();
340     Rect joinRect = transMap_->GetBoxRect();
341     transMap_->SetTransMapRect(GetOrigRect());
342     transMap_->Shear(shearX, shearY, shearZ);
343     if (firstTrans) {
344         joinRect = transMap_->GetBoxRect();
345     } else {
346         joinRect.Join(joinRect, transMap_->GetBoxRect());
347     }
348     joinRect.Join(joinRect, GetOrigRect());
349     InvalidateRect(joinRect);
350 }
351 
Translate(const Vector2<int16_t> & trans)352 void UIView::Translate(const Vector2<int16_t>& trans)
353 {
354     Vector3<int16_t> trans3D = Vector3<int16_t>(trans.x_, trans.y_, 0);
355     Translate(trans3D);
356 }
357 
Translate(const Vector3<int16_t> & trans)358 void UIView::Translate(const Vector3<int16_t>& trans)
359 {
360     if (transMap_ == nullptr) {
361         ReMeasure();
362         transMap_ = new TransformMap();
363     }
364     bool firstTrans = transMap_->IsInvalid();
365     Rect joinRect = transMap_->GetBoxRect();
366     transMap_->SetTransMapRect(GetOrigRect());
367     transMap_->Translate(trans);
368     if (firstTrans) {
369         joinRect = transMap_->GetBoxRect();
370     } else {
371         joinRect.Join(joinRect, transMap_->GetBoxRect());
372     }
373     joinRect.Join(joinRect, GetOrigRect());
374     InvalidateRect(joinRect);
375 }
376 
IsTransInvalid()377 bool UIView::IsTransInvalid()
378 {
379     if (transMap_ == nullptr) {
380         return true;
381     }
382     return transMap_->IsInvalid();
383 }
384 
SetCameraDistance(int16_t distance)385 void UIView::SetCameraDistance(int16_t distance)
386 {
387     if (transMap_ == nullptr) {
388         ReMeasure();
389         transMap_ = new TransformMap();
390     }
391     Rect joinRect = transMap_->GetBoxRect();
392     transMap_->SetTransMapRect(GetOrigRect());
393     transMap_->SetCameraDistance(distance);
394     joinRect.Join(joinRect, transMap_->GetBoxRect());
395     joinRect.Join(joinRect, GetOrigRect());
396     InvalidateRect(joinRect);
397 }
398 
SetCameraPosition(const Vector2<float> & position)399 void UIView::SetCameraPosition(const Vector2<float>& position)
400 {
401     if (transMap_ == nullptr) {
402         ReMeasure();
403         transMap_ = new TransformMap();
404     }
405     Rect joinRect = transMap_->GetBoxRect();
406     transMap_->SetTransMapRect(GetOrigRect());
407     transMap_->SetCameraPosition(position);
408     joinRect.Join(joinRect, transMap_->GetBoxRect());
409     joinRect.Join(joinRect, GetOrigRect());
410     InvalidateRect(joinRect);
411 }
412 
ResetTransParameter()413 void UIView::ResetTransParameter()
414 {
415     if (transMap_ != nullptr) {
416         delete transMap_;
417         transMap_ = nullptr;
418         Invalidate();
419     }
420 }
421 
422 #if ENABLE_ROTATE_INPUT
RequestFocus()423 void UIView::RequestFocus()
424 {
425     FocusManager::GetInstance()->RequestFocus(this);
426 }
427 
ClearFocus()428 void UIView::ClearFocus()
429 {
430     FocusManager::GetInstance()->ClearFocus();
431 }
432 #endif
433 
Invalidate()434 void UIView::Invalidate()
435 {
436     UIView* view = this;
437     while (view != nullptr) {
438         if (view->transMap_ != nullptr && !view->GetTransformMap().IsInvalid() && view != this) {
439             InvalidateRect(view->GetRect(), view);
440             return;
441         }
442         view = view->parent_;
443     }
444     InvalidateRect(GetRect());
445 }
446 
InvalidateRect(const Rect & invalidatedArea,UIView * view)447 void UIView::InvalidateRect(const Rect& invalidatedArea, UIView* view)
448 {
449     if (!visible_) {
450         if (needRedraw_) {
451             needRedraw_ = false;
452         } else {
453             return;
454         }
455     }
456 
457     if (view == nullptr) {
458         view = this;
459     }
460     Rect trunc(invalidatedArea);
461     bool isIntersect = true;
462     UIView* par = view->parent_;
463     UIView* cur = view;
464 
465     while (par != nullptr) {
466         if (!par->visible_) {
467             return;
468         }
469 
470         isIntersect = trunc.Intersect(par->GetContentRect(), trunc);
471         if (!isIntersect) {
472             break;
473         }
474 
475         cur = par;
476         par = par->parent_;
477     }
478 
479     if (isIntersect && (cur->GetViewType() == UI_ROOT_VIEW)) {
480         RootView* rootView = reinterpret_cast<RootView*>(cur);
481         rootView->AddInvalidateRectWithLock(trunc, view);
482     }
483 }
484 
OnLongPressEvent(const LongPressEvent & event)485 bool UIView::OnLongPressEvent(const LongPressEvent& event)
486 {
487     if (onLongPressListener_ != nullptr) {
488         /* To ensure version compatibility, the listeners of both versions are invoked. */
489         bool isConsumed = onLongPressListener_->OnLongPress(*this, event);
490         return isConsumed;
491     }
492     return isIntercept_;
493 }
494 
OnDragStartEvent(const DragEvent & event)495 bool UIView::OnDragStartEvent(const DragEvent& event)
496 {
497     if (onDragListener_ != nullptr) {
498         /* To ensure version compatibility, the listeners of both versions are invoked. */
499         bool isConsumed = onDragListener_->OnDragStart(*this, event);
500         return isConsumed;
501     }
502     return isIntercept_;
503 }
504 
OnDragEvent(const DragEvent & event)505 bool UIView::OnDragEvent(const DragEvent& event)
506 {
507     if (onDragListener_ != nullptr) {
508         /* To ensure version compatibility, the listeners of both versions are invoked. */
509         bool isConsumed = onDragListener_->OnDrag(*this, event);
510         return isConsumed;
511     }
512     return isIntercept_;
513 }
514 
OnDragEndEvent(const DragEvent & event)515 bool UIView::OnDragEndEvent(const DragEvent& event)
516 {
517     if (onDragListener_ != nullptr) {
518         /* To ensure version compatibility, the listeners of both versions are invoked. */
519         bool isConsumed = onDragListener_->OnDragEnd(*this, event);
520         return isConsumed;
521     }
522     return isIntercept_;
523 }
524 
OnClickEvent(const ClickEvent & event)525 bool UIView::OnClickEvent(const ClickEvent& event)
526 {
527     if (onClickListener_ != nullptr) {
528         /* To ensure version compatibility, the listeners of both versions are invoked. */
529         bool isConsumed = onClickListener_->OnClick(*this, event);
530         return isConsumed;
531     }
532     return isIntercept_;
533 }
534 
OnPressEvent(const PressEvent & event)535 bool UIView::OnPressEvent(const PressEvent& event)
536 {
537     if (onTouchListener_ != nullptr) {
538         /* To ensure version compatibility, the listeners of both versions are invoked. */
539         bool isConsumed = onTouchListener_->OnPress(*this, event);
540         return isConsumed;
541     }
542     return isIntercept_;
543 }
544 
OnReleaseEvent(const ReleaseEvent & event)545 bool UIView::OnReleaseEvent(const ReleaseEvent& event)
546 {
547     if (onTouchListener_ != nullptr) {
548         /* To ensure version compatibility, the listeners of both versions are invoked. */
549         bool isConsumed = onTouchListener_->OnRelease(*this, event);
550         return isConsumed;
551     }
552     return isIntercept_;
553 }
554 
OnCancelEvent(const CancelEvent & event)555 bool UIView::OnCancelEvent(const CancelEvent& event)
556 {
557     if (onTouchListener_ != nullptr) {
558         /* To ensure version compatibility, the listeners of both versions are invoked. */
559         bool isConsumed = onTouchListener_->OnCancel(*this, event);
560         return isConsumed;
561     }
562     return isIntercept_;
563 }
564 
SetOnDragListener(OnDragListener * onDragListener)565 void UIView::SetOnDragListener(OnDragListener* onDragListener)
566 {
567     onDragListener_ = onDragListener;
568 }
569 
GetOnDragListener()570 UIView::OnDragListener*& UIView::GetOnDragListener()
571 {
572     return onDragListener_;
573 }
574 
SetOnClickListener(OnClickListener * onClickListener)575 void UIView::SetOnClickListener(OnClickListener* onClickListener)
576 {
577     onClickListener_ = onClickListener;
578 }
579 
GetOnClickListener()580 UIView::OnClickListener*& UIView::GetOnClickListener()
581 {
582     return onClickListener_;
583 }
584 
SetOnLongPressListener(OnLongPressListener * onLongPressListener)585 void UIView::SetOnLongPressListener(OnLongPressListener* onLongPressListener)
586 {
587     onLongPressListener_ = onLongPressListener;
588 }
589 
GetOnLongPressListener()590 UIView::OnLongPressListener*& UIView::GetOnLongPressListener()
591 {
592     return onLongPressListener_;
593 }
594 
SetOnTouchListener(OnTouchListener * onTouchListener)595 void UIView::SetOnTouchListener(OnTouchListener* onTouchListener)
596 {
597     onTouchListener_ = onTouchListener;
598 }
599 
GetTouchListener()600 UIView::OnTouchListener*& UIView::GetTouchListener()
601 {
602     return onTouchListener_;
603 }
604 
SetParent(UIView * parent)605 void UIView::SetParent(UIView* parent)
606 {
607     parent_ = parent;
608 }
609 
GetParent() const610 UIView* UIView::GetParent() const
611 {
612     return parent_;
613 }
614 
SetNextSibling(UIView * sibling)615 void UIView::SetNextSibling(UIView* sibling)
616 {
617     nextSibling_ = sibling;
618 }
619 
GetNextSibling() const620 UIView* UIView::GetNextSibling() const
621 {
622     return nextSibling_;
623 }
624 
SetNextRenderSibling(UIView * renderSibling)625 void UIView::SetNextRenderSibling(UIView* renderSibling)
626 {
627     nextRenderSibling_ = renderSibling;
628 }
629 
GetNextRenderSibling() const630 UIView* UIView::GetNextRenderSibling() const
631 {
632     return nextRenderSibling_;
633 }
634 
SetVisible(bool visible)635 void UIView::SetVisible(bool visible)
636 {
637     if (visible_ != visible) {
638         visible_ = visible;
639         needRedraw_ = true;
640         Invalidate();
641     }
642 }
643 
IsVisible() const644 bool UIView::IsVisible() const
645 {
646     return visible_;
647 }
648 
SetTouchable(bool touch)649 void UIView::SetTouchable(bool touch)
650 {
651     touchable_ = touch;
652 }
653 
IsTouchable() const654 bool UIView::IsTouchable() const
655 {
656     return touchable_;
657 }
658 
SetDraggable(bool draggable)659 void UIView::SetDraggable(bool draggable)
660 {
661     draggable_ = draggable;
662     dragParentInstead_ = !draggable;
663 }
664 
IsDraggable() const665 bool UIView::IsDraggable() const
666 {
667     return draggable_;
668 }
669 
SetDragParentInstead(bool dragParentInstead)670 void UIView::SetDragParentInstead(bool dragParentInstead)
671 {
672     dragParentInstead_ = dragParentInstead;
673 }
674 
IsDragParentInstead() const675 bool UIView::IsDragParentInstead() const
676 {
677     return dragParentInstead_;
678 }
679 
680 #if ENABLE_ROTATE_INPUT
OnRotateStartEvent(const RotateEvent & event)681 bool UIView::OnRotateStartEvent(const RotateEvent& event)
682 {
683     if (onRotateListener_ != nullptr) {
684         return onRotateListener_->OnRotateStart(*this, event);
685     }
686     return false;
687 }
688 
OnRotateEvent(const RotateEvent & event)689 bool UIView::OnRotateEvent(const RotateEvent& event)
690 {
691     if (onRotateListener_ != nullptr) {
692         return onRotateListener_->OnRotate(*this, event);
693     }
694     return isIntercept_;
695 }
696 
OnRotateEndEvent(const RotateEvent & event)697 bool UIView::OnRotateEndEvent(const RotateEvent& event)
698 {
699     if (onRotateListener_ != nullptr) {
700         return onRotateListener_->OnRotateEnd(*this, event);
701     }
702     return false;
703 }
704 
SetOnRotateListener(OnRotateListener * onRotateListener)705 void UIView::SetOnRotateListener(OnRotateListener* onRotateListener)
706 {
707     onRotateListener_ = onRotateListener;
708 }
709 
710 #endif
711 
GetTargetView(const Point & point,UIView ** last)712 void UIView::GetTargetView(const Point& point, UIView** last)
713 {
714     if (last == nullptr) {
715         return;
716     }
717     UIView* par = parent_;
718     Rect rect = GetRect();
719 
720     if (par != nullptr) {
721         rect.Intersect(par->GetContentRect(), rect);
722     }
723 
724     if (visible_ && touchable_ && rect.IsContains(point)) {
725         *last = this;
726     }
727 }
728 
GetTargetView(const Point & point,UIView ** current,UIView ** target)729 void UIView::GetTargetView(const Point& point, UIView** current, UIView** target)
730 {
731     if (current == nullptr) {
732         return;
733     }
734     UIView* par = parent_;
735     Rect rect = GetRect();
736 
737     if (par != nullptr) {
738         rect.Intersect(par->GetOrigContentRect(), rect);
739     }
740 
741     if (visible_ && rect.IsContains(point)) {
742         if (touchable_) {
743             *current = this;
744         }
745         *target = this;
746     }
747 }
748 
749 #if ENABLE_FOCUS_MANAGER
SetFocusable(bool focusable)750 void UIView::SetFocusable(bool focusable)
751 {
752     focusable_ = focusable;
753 }
754 
IsFocusable() const755 bool UIView::IsFocusable() const
756 {
757     return focusable_;
758 }
759 
Focus()760 void UIView::Focus()
761 {
762     if (focusable_ && onFocusListener_ != nullptr) {
763         onFocusListener_->OnFocus(*this);
764     }
765 }
766 
Blur()767 void UIView::Blur()
768 {
769     if (onFocusListener_ != nullptr) {
770         onFocusListener_->OnBlur(*this);
771     }
772 }
773 
SetOnFocusListener(OnFocusListener * onFocusListener)774 void UIView::SetOnFocusListener(OnFocusListener* onFocusListener)
775 {
776     onFocusListener_ = onFocusListener;
777 }
778 
GetOnFocusListener() const779 UIView::OnFocusListener* UIView::GetOnFocusListener() const
780 {
781     return onFocusListener_;
782 }
783 
784 #endif
785 
GetRect() const786 Rect UIView::GetRect() const
787 {
788     if ((transMap_ != nullptr) && !transMap_->IsInvalid()) {
789         Rect r = transMap_->GetBoxRect();
790         Rect origRect = GetOrigRect();
791         r.SetX(r.GetX() + origRect.GetX() - transMap_->GetTransMapRect().GetX());
792         r.SetY(r.GetY() + origRect.GetY() - transMap_->GetTransMapRect().GetY());
793         return r;
794     }
795     return GetOrigRect();
796 }
797 
GetContentRect()798 Rect UIView::GetContentRect()
799 {
800     if ((transMap_ != nullptr) && !transMap_->IsInvalid()) {
801         Rect r = transMap_->GetBoxRect();
802         Rect origRect = GetOrigRect();
803         r.SetX(r.GetX() + origRect.GetX() - transMap_->GetTransMapRect().GetX());
804         r.SetY(r.GetY() + origRect.GetY() - transMap_->GetTransMapRect().GetY());
805         return r;
806     }
807 
808     Rect contentRect = GetRect();
809     contentRect.SetX(contentRect.GetX() + style_->paddingLeft_ + style_->borderWidth_);
810     contentRect.SetY(contentRect.GetY() + style_->paddingTop_ + style_->borderWidth_);
811     contentRect.SetWidth(GetWidth());
812     contentRect.SetHeight(GetHeight());
813     return contentRect;
814 }
815 
GetOrigContentRect()816 Rect UIView::GetOrigContentRect()
817 {
818     Rect contentRect = GetOrigRect();
819     contentRect.SetX(contentRect.GetX() + style_->paddingLeft_ + style_->borderWidth_);
820     contentRect.SetY(contentRect.GetY() + style_->paddingTop_ + style_->borderWidth_);
821     contentRect.SetWidth(GetWidth());
822     contentRect.SetHeight(GetHeight());
823     return contentRect;
824 }
825 
GetOrigRect() const826 Rect UIView::GetOrigRect() const
827 {
828     int16_t x = rect_.GetX();
829     int16_t y = rect_.GetY();
830     UIView* par = parent_;
831     while (par != nullptr) {
832         x += par->GetRelativeRect().GetX() + par->GetStyle(STYLE_PADDING_LEFT) + par->GetStyle(STYLE_BORDER_WIDTH);
833         y += par->GetRelativeRect().GetY() + par->GetStyle(STYLE_PADDING_TOP) + par->GetStyle(STYLE_BORDER_WIDTH);
834         par = par->parent_;
835     }
836     return Rect(x, y, x + rect_.GetWidth() - 1, y + rect_.GetHeight() - 1);
837 }
838 
GetMaskedRect() const839 Rect UIView::GetMaskedRect() const
840 {
841     Rect mask;
842     if (visibleRect_ != nullptr) {
843         mask.Intersect(GetRect(), GetVisibleRect());
844     } else {
845         mask = GetRect();
846     }
847     return mask;
848 }
849 
GetVisibleRect() const850 Rect UIView::GetVisibleRect() const
851 {
852     if (visibleRect_ == nullptr) {
853         return GetRect();
854     }
855     Rect absoluteRect;
856     int16_t x = visibleRect_->GetX();
857     int16_t y = visibleRect_->GetY();
858     UIView* par = parent_;
859     while (par != nullptr) {
860         x += par->GetX();
861         y += par->GetY();
862         par = par->parent_;
863     }
864     absoluteRect.SetX(x);
865     absoluteRect.SetY(y);
866     absoluteRect.SetWidth(visibleRect_->GetWidth());
867     absoluteRect.SetHeight(visibleRect_->GetHeight());
868     return absoluteRect;
869 }
870 
SetTransformMap(const TransformMap & transMap)871 void UIView::SetTransformMap(const TransformMap& transMap)
872 {
873     if ((transMap_ != nullptr) && (*transMap_ == transMap)) {
874         return;
875     }
876 
877     if (transMap_ == nullptr) {
878         transMap_ = new TransformMap();
879     }
880     Rect preRect = GetRect();
881     *transMap_ = transMap;
882     transMap_->SetTransMapRect(GetOrigRect());
883 
884     Rect joinRect;
885     joinRect.Join(preRect, transMap_->GetBoxRect());
886     InvalidateRect(joinRect);
887 }
888 
SetWidth(int16_t width)889 void UIView::SetWidth(int16_t width)
890 {
891     if (GetWidth() != width) {
892         int16_t newWidth = width + style_->paddingLeft_ + style_->paddingRight_ +
893                            (style_->borderWidth_ * 2); /* 2: left and right border */
894         rect_.SetWidth(newWidth);
895     }
896 }
897 
SetWidthPercent(float widthPercent)898 void UIView::SetWidthPercent(float widthPercent)
899 {
900     if (IsInvalid(widthPercent)) {
901         return;
902     }
903     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1)) {
904         int16_t newWidth = static_cast<int16_t>(GetParent()->GetWidth() * widthPercent);
905         SetWidth(newWidth);
906     }
907 }
908 
GetWidth()909 int16_t UIView::GetWidth()
910 {
911     return rect_.GetWidth() - (style_->paddingLeft_ + style_->paddingRight_) -
912            (style_->borderWidth_ * 2); /* 2: left and right border */
913 }
914 
SetHeight(int16_t height)915 void UIView::SetHeight(int16_t height)
916 {
917     if (GetHeight() != height) {
918         int16_t newHeight = height + style_->paddingTop_ + style_->paddingBottom_ +
919                             (style_->borderWidth_ * 2); /* 2: top and bottom border */
920         rect_.SetHeight(newHeight);
921     }
922 }
923 
SetHeightPercent(float heightPercent)924 void UIView::SetHeightPercent(float heightPercent)
925 {
926     if (IsInvalid(heightPercent)) {
927         return;
928     }
929     if ((GetParent() != nullptr) && (GetParent()->GetHeight() > 1)) {
930         int16_t newHeight = static_cast<int16_t>(GetParent()->GetHeight() * heightPercent);
931         SetHeight(newHeight);
932     }
933 }
934 
GetHeight()935 int16_t UIView::GetHeight()
936 {
937     return rect_.GetHeight() - (style_->paddingTop_ + style_->paddingBottom_) -
938            (style_->borderWidth_ * 2); /* 2: top and bottom border */
939 }
940 
Resize(int16_t width,int16_t height)941 void UIView::Resize(int16_t width, int16_t height)
942 {
943     SetWidth(width);
944     SetHeight(height);
945 }
946 
ResizePercent(float widthPercent,float heightPercent)947 void UIView::ResizePercent(float widthPercent, float heightPercent)
948 {
949     if (IsInvalid(widthPercent) || IsInvalid(heightPercent)) {
950         return;
951     }
952     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1) && (GetParent()->GetHeight() > 1)) {
953         int16_t newWidth = static_cast<int16_t>(GetParent()->GetWidth() * widthPercent);
954         int16_t newHeight = static_cast<int16_t>(GetParent()->GetHeight() * heightPercent);
955         Resize(newWidth, newHeight);
956     }
957 }
958 
SetX(int16_t x)959 void UIView::SetX(int16_t x)
960 {
961     if (GetX() != x) {
962         rect_.SetX(x + GetStyle(STYLE_MARGIN_LEFT));
963     }
964 }
965 
SetXPercent(float xPercent)966 void UIView::SetXPercent(float xPercent)
967 {
968     if (IsInvalid(xPercent)) {
969         return;
970     }
971     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1)) {
972         int16_t newX = static_cast<int16_t>(GetParent()->GetWidth() * xPercent);
973         SetX(newX);
974     }
975 }
976 
GetX() const977 int16_t UIView::GetX() const
978 {
979     return rect_.GetX() - GetStyle(STYLE_MARGIN_LEFT);
980 }
981 
SetY(int16_t y)982 void UIView::SetY(int16_t y)
983 {
984     if (GetY() != y) {
985         rect_.SetY(y + GetStyle(STYLE_MARGIN_TOP));
986     }
987 }
988 
SetYPercent(float yPercent)989 void UIView::SetYPercent(float yPercent)
990 {
991     if (IsInvalid(yPercent)) {
992         return;
993     }
994     if ((GetParent() != nullptr) && (GetParent()->GetHeight() > 1)) {
995         int16_t newY = static_cast<int16_t>(GetParent()->GetHeight() * yPercent);
996         SetY(newY);
997     }
998 }
999 
GetY() const1000 int16_t UIView::GetY() const
1001 {
1002     return rect_.GetY() - GetStyle(STYLE_MARGIN_TOP);
1003 }
1004 
SetPosition(int16_t x,int16_t y)1005 void UIView::SetPosition(int16_t x, int16_t y)
1006 {
1007     SetX(x);
1008     SetY(y);
1009 }
1010 
SetPositionPercent(float xPercent,float yPercent)1011 void UIView::SetPositionPercent(float xPercent, float yPercent)
1012 {
1013     if (IsInvalid(xPercent) || IsInvalid(yPercent)) {
1014         return;
1015     }
1016     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1) && (GetParent()->GetHeight() > 1)) {
1017         int16_t newX = static_cast<int16_t>(GetParent()->GetWidth() * xPercent);
1018         int16_t newY = static_cast<int16_t>(GetParent()->GetHeight() * yPercent);
1019         SetPosition(newX, newY);
1020     }
1021 }
1022 
SetPosition(int16_t x,int16_t y,int16_t width,int16_t height)1023 void UIView::SetPosition(int16_t x, int16_t y, int16_t width, int16_t height)
1024 {
1025     SetPosition(x, y);
1026     SetWidth(width);
1027     SetHeight(height);
1028 }
1029 
SetPositionPercent(float xPercent,float yPercent,float widthPercent,float heightPercent)1030 void UIView::SetPositionPercent(float xPercent, float yPercent, float widthPercent, float heightPercent)
1031 {
1032     if (IsInvalid(xPercent) || IsInvalid(yPercent) || IsInvalid(widthPercent) || IsInvalid(heightPercent)) {
1033         return;
1034     }
1035     if ((GetParent() != nullptr) && (GetParent()->GetWidth() > 1) && (GetParent()->GetHeight() > 1)) {
1036         int16_t newX = static_cast<int16_t>(GetParent()->GetWidth() * xPercent);
1037         int16_t newY = static_cast<int16_t>(GetParent()->GetHeight() * yPercent);
1038         int16_t newWidth = static_cast<int16_t>(GetParent()->GetWidth() * widthPercent);
1039         int16_t newHeight = static_cast<int16_t>(GetParent()->GetHeight() * heightPercent);
1040         SetPosition(newX, newY, newWidth, newHeight);
1041     }
1042 }
1043 
IsViewGroup() const1044 bool UIView::IsViewGroup() const
1045 {
1046     return isViewGroup_;
1047 }
1048 
SetIntercept(bool isIntercept)1049 void UIView::SetIntercept(bool isIntercept)
1050 {
1051     isIntercept_ = isIntercept;
1052 }
1053 
IsIntercept()1054 bool UIView::IsIntercept()
1055 {
1056     return isIntercept_;
1057 }
1058 
IsInvalid(float percent)1059 bool UIView::IsInvalid(float percent)
1060 {
1061     if ((percent < 1) && (percent > 0)) {
1062         return false;
1063     }
1064     return true;
1065 }
1066 
GetTransformMap()1067 TransformMap& UIView::GetTransformMap()
1068 {
1069     if (transMap_ == nullptr) {
1070         transMap_ = new TransformMap();
1071     }
1072     return *transMap_;
1073 }
1074 
GetChildById(const char * id) const1075 UIView* UIView::GetChildById(const char* id) const
1076 {
1077     return nullptr;
1078 }
1079 
SetViewId(const char * id)1080 void UIView::SetViewId(const char* id)
1081 {
1082     id_ = id;
1083 }
1084 
GetViewId() const1085 const char* UIView::GetViewId() const
1086 {
1087     return id_;
1088 }
1089 
SetViewIndex(int16_t index)1090 void UIView::SetViewIndex(int16_t index)
1091 {
1092     index_ = index;
1093 }
1094 
GetViewIndex() const1095 int16_t UIView::GetViewIndex() const
1096 {
1097     return index_;
1098 }
1099 
GetViewType() const1100 UIViewType UIView::GetViewType() const
1101 {
1102     return UI_NUMBER_MAX;
1103 }
1104 
LayoutCenterOfParent(int16_t xOffset,int16_t yOffset)1105 void UIView::LayoutCenterOfParent(int16_t xOffset, int16_t yOffset)
1106 {
1107     if (parent_ == nullptr) {
1108         return;
1109     }
1110 
1111     int16_t topMargin = style_->marginTop_;
1112     int16_t leftMargin = style_->marginLeft_;
1113     int16_t rightMargin = style_->marginRight_;
1114     int16_t bottomMargin = style_->marginBottom_;
1115     // 2: half
1116     int16_t posX = parent_->GetWidth() / 2 - (rect_.GetWidth() - leftMargin + rightMargin) / 2 + xOffset;
1117     // 2: half
1118     int16_t posY = parent_->GetHeight() / 2 - (rect_.GetHeight() - topMargin + bottomMargin) / 2 + yOffset;
1119     SetPosition(posX, posY);
1120 }
1121 
LayoutLeftOfParent(int16_t offset)1122 void UIView::LayoutLeftOfParent(int16_t offset)
1123 {
1124     if (parent_ == nullptr) {
1125         return;
1126     }
1127 
1128     int16_t leftMargin = style_->marginLeft_;
1129     SetPosition(leftMargin + offset, GetY());
1130 }
1131 
LayoutRightOfParent(int16_t offset)1132 void UIView::LayoutRightOfParent(int16_t offset)
1133 {
1134     if (parent_ == nullptr) {
1135         return;
1136     }
1137 
1138     int16_t rightMargin = style_->marginRight_;
1139     SetPosition(parent_->GetWidth() - offset - rect_.GetWidth() - rightMargin, GetY());
1140 }
1141 
LayoutTopOfParent(int16_t offset)1142 void UIView::LayoutTopOfParent(int16_t offset)
1143 {
1144     if (parent_ == nullptr) {
1145         return;
1146     }
1147 
1148     int16_t topMargin = style_->marginTop_;
1149     SetPosition(GetX(), topMargin + offset);
1150 }
1151 
LayoutBottomOfParent(int16_t offset)1152 void UIView::LayoutBottomOfParent(int16_t offset)
1153 {
1154     if (parent_ == nullptr) {
1155         return;
1156     }
1157 
1158     int16_t bottomMargin = style_->marginBottom_;
1159     SetPosition(GetX(), parent_->GetHeight() - offset - rect_.GetHeight() - bottomMargin);
1160 }
1161 
AlignLeftToSibling(const char * id,int16_t offset)1162 void UIView::AlignLeftToSibling(const char* id, int16_t offset)
1163 {
1164     if (parent_ == nullptr) {
1165         return;
1166     }
1167     UIView* sib = parent_->GetChildById(id);
1168     if (sib != nullptr) {
1169         int16_t margin = sib->style_->marginLeft_ - style_->marginLeft_;
1170         SetPosition(sib->GetX() - margin + offset, GetY());
1171     }
1172 }
1173 
AlignRightToSibling(const char * id,int16_t offset)1174 void UIView::AlignRightToSibling(const char* id, int16_t offset)
1175 {
1176     if (parent_ == nullptr) {
1177         return;
1178     }
1179     UIView* sib = parent_->GetChildById(id);
1180     if (sib != nullptr) {
1181         int16_t margin = sib->style_->marginRight_ - style_->marginRight_;
1182         SetPosition(sib->GetX() + sib->rect_.GetWidth() - rect_.GetWidth() - offset + margin, GetY());
1183     }
1184 }
1185 
AlignTopToSibling(const char * id,int16_t offset)1186 void UIView::AlignTopToSibling(const char* id, int16_t offset)
1187 {
1188     if (parent_ == nullptr) {
1189         return;
1190     }
1191     UIView* sib = parent_->GetChildById(id);
1192     if (sib != nullptr) {
1193         int16_t margin = sib->style_->marginTop_ - style_->marginTop_;
1194         SetPosition(GetX(), sib->GetY() + offset - margin);
1195     }
1196 }
1197 
AlignBottomToSibling(const char * id,int16_t offset)1198 void UIView::AlignBottomToSibling(const char* id, int16_t offset)
1199 {
1200     if (parent_ == nullptr) {
1201         return;
1202     }
1203     UIView* sib = parent_->GetChildById(id);
1204     if (sib != nullptr) {
1205         int16_t margin = sib->style_->marginBottom_ - style_->marginBottom_;
1206         SetPosition(GetX(), sib->GetY() + sib->rect_.GetHeight() - rect_.GetHeight() - offset + margin);
1207     }
1208 }
1209 
AlignHorCenterToSibling(const char * id,int16_t offset)1210 void UIView::AlignHorCenterToSibling(const char* id, int16_t offset)
1211 {
1212     if (parent_ == nullptr) {
1213         return;
1214     }
1215     UIView* sib = parent_->GetChildById(id);
1216     if (sib != nullptr) {
1217         int16_t margin =
1218             (sib->style_->marginRight_ - sib->style_->marginLeft_ - style_->marginRight_ + style_->marginLeft_) /
1219             2; // 2 : half
1220         SetPosition(sib->GetX() + sib->rect_.GetWidth() / 2 - rect_.GetWidth() / 2 + margin + offset, GetY());
1221     }
1222 }
AlignVerCenterToSibling(const char * id,int16_t offset)1223 void UIView::AlignVerCenterToSibling(const char* id, int16_t offset)
1224 {
1225     if (parent_ == nullptr) {
1226         return;
1227     }
1228     UIView* sib = parent_->GetChildById(id);
1229     if (sib != nullptr) {
1230         int16_t margin =
1231             (sib->style_->marginBottom_ - sib->style_->marginTop_ - style_->marginBottom_ + style_->marginTop_) /
1232             2; // 2 : half
1233         SetPosition(GetX(), sib->GetY() + sib->rect_.GetHeight() / 2 - rect_.GetHeight() / 2 + margin + offset);
1234     }
1235 }
1236 
LayoutLeftToSibling(const char * id,int16_t offset)1237 void UIView::LayoutLeftToSibling(const char* id, int16_t offset)
1238 {
1239     if (parent_ == nullptr) {
1240         return;
1241     }
1242     UIView* sib = parent_->GetChildById(id);
1243     if (sib != nullptr) {
1244         int16_t margin = sib->style_->marginLeft_ + style_->marginRight_;
1245         SetPosition(sib->GetX() - offset - rect_.GetWidth() - margin, GetY());
1246     }
1247 }
1248 
LayoutRightToSibling(const char * id,int16_t offset)1249 void UIView::LayoutRightToSibling(const char* id, int16_t offset)
1250 {
1251     if (parent_ == nullptr) {
1252         return;
1253     }
1254     UIView* sib = parent_->GetChildById(id);
1255     if (sib != nullptr) {
1256         int16_t margin = sib->style_->marginRight_ + style_->marginLeft_;
1257         SetPosition(sib->GetX() + sib->rect_.GetWidth() + offset + margin, GetY());
1258     }
1259 }
1260 
LayoutTopToSibling(const char * id,int16_t offset)1261 void UIView::LayoutTopToSibling(const char* id, int16_t offset)
1262 {
1263     if (parent_ == nullptr) {
1264         return;
1265     }
1266     UIView* sib = parent_->GetChildById(id);
1267     if (sib != nullptr) {
1268         int16_t margin = sib->style_->marginTop_ + style_->marginBottom_;
1269         SetPosition(GetX(), sib->GetY() - offset - rect_.GetHeight() - margin);
1270     }
1271 }
1272 
LayoutBottomToSibling(const char * id,int16_t offset)1273 void UIView::LayoutBottomToSibling(const char* id, int16_t offset)
1274 {
1275     if (parent_ == nullptr) {
1276         return;
1277     }
1278     UIView* sib = parent_->GetChildById(id);
1279     if (sib != nullptr) {
1280         int16_t margin = sib->style_->marginBottom_ + style_->marginTop_;
1281         SetPosition(GetX(), sib->GetY() + sib->rect_.GetHeight() + offset + margin);
1282     }
1283 }
1284 
GetMixOpaScale() const1285 uint8_t UIView::GetMixOpaScale() const
1286 {
1287     uint8_t opaMix = opaScale_;
1288     UIView* parent = parent_;
1289     while (parent != nullptr) {
1290         uint8_t opaParent = parent->GetOpaScale();
1291         // 8: Shift right 8 bits
1292         opaMix = (opaParent == OPA_OPAQUE) ? opaMix : ((static_cast<uint16_t>(opaParent) * opaMix) >> 8);
1293         parent = parent->GetParent();
1294     }
1295     return opaMix;
1296 }
1297 
GetBitmap(ImageInfo & imageInfo,ColorMode colorMode)1298 bool UIView::GetBitmap(ImageInfo& imageInfo, ColorMode colorMode)
1299 {
1300     UIView* tempRenderSibling = nextRenderSibling_;
1301     nextRenderSibling_ = nullptr;
1302     UIView* tempParent = parent_;
1303     parent_ = nullptr;
1304     int16_t tempX = rect_.GetX();
1305     int16_t tempY = rect_.GetY();
1306     rect_.SetPosition(0, 0);
1307 
1308     Rect mask = GetRect();
1309     BufferInfo bufInfo{mask, 0, nullptr, nullptr, 0, 0, colorMode, 0};
1310     bufInfo.width = mask.GetWidth();
1311     bufInfo.height = mask.GetHeight();
1312     bufInfo.stride = bufInfo.width * DrawUtils::GetByteSizeByColorMode(bufInfo.mode);
1313     BaseGfxEngine::GetInstance()->AdjustLineStride(bufInfo);
1314     imageInfo.header.colorMode = bufInfo.mode;
1315     imageInfo.dataSize = bufInfo.stride * bufInfo.height;
1316     imageInfo.header.width = bufInfo.width;
1317     imageInfo.header.height = bufInfo.height;
1318     imageInfo.header.reserved = 0;
1319 
1320     bufInfo.virAddr = ImageCacheMalloc(imageInfo);
1321     if (bufInfo.virAddr == nullptr) {
1322         GRAPHIC_LOGE("GetBitmap buffer alloc failed.");
1323         nextRenderSibling_ = tempRenderSibling;
1324         parent_ = tempParent;
1325         rect_.SetPosition(tempX, tempY);
1326         return false;
1327     }
1328     imageInfo.data = reinterpret_cast<uint8_t*>(bufInfo.virAddr);
1329     if (memset_s(bufInfo.virAddr, imageInfo.dataSize, 0, imageInfo.dataSize) != EOK) {
1330         GRAPHIC_LOGE("GetBitmap buffer memset failed.");
1331         ImageCacheFree(imageInfo);
1332         imageInfo.data = nullptr;
1333         return false;
1334     }
1335     bufInfo.phyAddr = bufInfo.virAddr;
1336     RootView* rootView = RootView::GetInstance();
1337     rootView->SaveDrawContext();
1338     rootView->UpdateBufferInfo(&bufInfo);
1339     rootView->MeasureView(this);
1340     rootView->DrawTop(this, mask);
1341     rootView->RestoreDrawContext();
1342 
1343     nextRenderSibling_ = tempRenderSibling;
1344     parent_ = tempParent;
1345     rect_.SetPosition(tempX, tempY);
1346     return true;
1347 }
1348 
IsOnViewTree()1349 bool UIView::IsOnViewTree()
1350 {
1351     UIView* par = this;
1352     while (par->GetParent() != nullptr) {
1353         par = par->GetParent();
1354     }
1355     if (par->GetViewType() != UI_ROOT_VIEW) {
1356         return false;
1357     }
1358     return true;
1359 }
1360 
GetWidthWithMargin()1361 int16_t UIView::GetWidthWithMargin()
1362 {
1363     return GetRelativeRect().GetWidth() + GetStyle(STYLE_MARGIN_LEFT) + GetStyle(STYLE_MARGIN_RIGHT);
1364 }
1365 
GetHeightWithMargin()1366 int16_t UIView::GetHeightWithMargin()
1367 {
1368     return GetRelativeRect().GetHeight() + GetStyle(STYLE_MARGIN_TOP) + GetStyle(STYLE_MARGIN_BOTTOM);
1369 }
1370 
GetRelativeRect() const1371 Rect UIView::GetRelativeRect() const
1372 {
1373     return rect_;
1374 }
1375 
ResizeVisibleArea(int16_t x,int16_t y,int16_t width,int16_t height)1376 void UIView::ResizeVisibleArea(int16_t x, int16_t y, int16_t width, int16_t height)
1377 {
1378     if (visibleRect_ == nullptr) {
1379         visibleRect_ = new Rect();
1380         if (visibleRect_ == nullptr) {
1381             GRAPHIC_LOGE("new Rect fail");
1382             return;
1383         }
1384     }
1385     visibleRect_->SetWidth(width);
1386     visibleRect_->SetHeight(height);
1387     visibleRect_->SetPosition(x, y);
1388 }
1389 
SetZIndex(int16_t zIndex)1390 void UIView::SetZIndex(int16_t zIndex)
1391 {
1392     if (zIndex_ == zIndex) {
1393         return;
1394     }
1395 
1396     zIndex_ = zIndex;
1397     if (parent_ != nullptr) {
1398         reinterpret_cast<UIViewGroup*>(parent_)->UpdateRenderView(this);
1399     }
1400 }
1401 
GetZIndex()1402 int16_t UIView::GetZIndex()
1403 {
1404     return zIndex_;
1405 }
1406 } // namespace OHOS
1407