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