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 30namespace OHOS { 31UIView::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 69UIView::~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 86bool 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 107void UIView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) 108{ 109 uint8_t opa = GetMixOpaScale(); 110 BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, GetOrigRect(), invalidatedArea, *style_, opa); 111} 112 113void UIView::OnPostDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) 114{ 115 DrawViewBounds(gfxDstBuffer, invalidatedArea); 116} 117 118void 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 179void 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 189void UIView::SetStyle(Style& style) 190{ 191 if (styleAllocFlag_) { 192 delete style_; 193 styleAllocFlag_ = false; 194 } 195 style_ = &style; 196} 197 198void 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 217void 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 248int64_t UIView::GetStyle(uint8_t key) const 249{ 250 return style_->GetStyle(key); 251} 252 253const Style& UIView::GetStyleConst() const 254{ 255 return *style_; 256} 257 258void UIView::SetOpaScale(uint8_t opaScale) 259{ 260 opaScale_ = opaScale; 261} 262 263uint8_t UIView::GetOpaScale() const 264{ 265 return opaScale_; 266} 267 268UIView::ViewExtraMsg* UIView::GetExtraMsg() 269{ 270 return viewExtraMsg_; 271} 272 273void UIView::SetExtraMsg(ViewExtraMsg* extraMsg) 274{ 275 viewExtraMsg_ = extraMsg; 276} 277 278void 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 285void 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 304void 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 311void 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 330void 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 352void 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 358void 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 377bool UIView::IsTransInvalid() 378{ 379 if (transMap_ == nullptr) { 380 return true; 381 } 382 return transMap_->IsInvalid(); 383} 384 385void 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 399void 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 413void UIView::ResetTransParameter() 414{ 415 if (transMap_ != nullptr) { 416 delete transMap_; 417 transMap_ = nullptr; 418 Invalidate(); 419 } 420} 421 422#if ENABLE_ROTATE_INPUT 423void UIView::RequestFocus() 424{ 425 FocusManager::GetInstance()->RequestFocus(this); 426} 427 428void UIView::ClearFocus() 429{ 430 FocusManager::GetInstance()->ClearFocus(); 431} 432#endif 433 434void 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 447void 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 485bool 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 495bool 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 505bool 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 515bool 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 525bool 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 535bool 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 545bool 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 555bool 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 565void UIView::SetOnDragListener(OnDragListener* onDragListener) 566{ 567 onDragListener_ = onDragListener; 568} 569 570UIView::OnDragListener*& UIView::GetOnDragListener() 571{ 572 return onDragListener_; 573} 574 575void UIView::SetOnClickListener(OnClickListener* onClickListener) 576{ 577 onClickListener_ = onClickListener; 578} 579 580UIView::OnClickListener*& UIView::GetOnClickListener() 581{ 582 return onClickListener_; 583} 584 585void UIView::SetOnLongPressListener(OnLongPressListener* onLongPressListener) 586{ 587 onLongPressListener_ = onLongPressListener; 588} 589 590UIView::OnLongPressListener*& UIView::GetOnLongPressListener() 591{ 592 return onLongPressListener_; 593} 594 595void UIView::SetOnTouchListener(OnTouchListener* onTouchListener) 596{ 597 onTouchListener_ = onTouchListener; 598} 599 600UIView::OnTouchListener*& UIView::GetTouchListener() 601{ 602 return onTouchListener_; 603} 604 605void UIView::SetParent(UIView* parent) 606{ 607 parent_ = parent; 608} 609 610UIView* UIView::GetParent() const 611{ 612 return parent_; 613} 614 615void UIView::SetNextSibling(UIView* sibling) 616{ 617 nextSibling_ = sibling; 618} 619 620UIView* UIView::GetNextSibling() const 621{ 622 return nextSibling_; 623} 624 625void UIView::SetNextRenderSibling(UIView* renderSibling) 626{ 627 nextRenderSibling_ = renderSibling; 628} 629 630UIView* UIView::GetNextRenderSibling() const 631{ 632 return nextRenderSibling_; 633} 634 635void UIView::SetVisible(bool visible) 636{ 637 if (visible_ != visible) { 638 visible_ = visible; 639 needRedraw_ = true; 640 Invalidate(); 641 } 642} 643 644bool UIView::IsVisible() const 645{ 646 return visible_; 647} 648 649void UIView::SetTouchable(bool touch) 650{ 651 touchable_ = touch; 652} 653 654bool UIView::IsTouchable() const 655{ 656 return touchable_; 657} 658 659void UIView::SetDraggable(bool draggable) 660{ 661 draggable_ = draggable; 662 dragParentInstead_ = !draggable; 663} 664 665bool UIView::IsDraggable() const 666{ 667 return draggable_; 668} 669 670void UIView::SetDragParentInstead(bool dragParentInstead) 671{ 672 dragParentInstead_ = dragParentInstead; 673} 674 675bool UIView::IsDragParentInstead() const 676{ 677 return dragParentInstead_; 678} 679 680#if ENABLE_ROTATE_INPUT 681bool UIView::OnRotateStartEvent(const RotateEvent& event) 682{ 683 if (onRotateListener_ != nullptr) { 684 return onRotateListener_->OnRotateStart(*this, event); 685 } 686 return false; 687} 688 689bool UIView::OnRotateEvent(const RotateEvent& event) 690{ 691 if (onRotateListener_ != nullptr) { 692 return onRotateListener_->OnRotate(*this, event); 693 } 694 return isIntercept_; 695} 696 697bool UIView::OnRotateEndEvent(const RotateEvent& event) 698{ 699 if (onRotateListener_ != nullptr) { 700 return onRotateListener_->OnRotateEnd(*this, event); 701 } 702 return false; 703} 704 705void UIView::SetOnRotateListener(OnRotateListener* onRotateListener) 706{ 707 onRotateListener_ = onRotateListener; 708} 709 710#endif 711 712void 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 729void 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 750void UIView::SetFocusable(bool focusable) 751{ 752 focusable_ = focusable; 753} 754 755bool UIView::IsFocusable() const 756{ 757 return focusable_; 758} 759 760void UIView::Focus() 761{ 762 if (focusable_ && onFocusListener_ != nullptr) { 763 onFocusListener_->OnFocus(*this); 764 } 765} 766 767void UIView::Blur() 768{ 769 if (onFocusListener_ != nullptr) { 770 onFocusListener_->OnBlur(*this); 771 } 772} 773 774void UIView::SetOnFocusListener(OnFocusListener* onFocusListener) 775{ 776 onFocusListener_ = onFocusListener; 777} 778 779UIView::OnFocusListener* UIView::GetOnFocusListener() const 780{ 781 return onFocusListener_; 782} 783 784#endif 785 786Rect 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 798Rect 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 816Rect 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 826Rect 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 839Rect 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 850Rect 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 871void 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 889void 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 898void 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 909int16_t UIView::GetWidth() 910{ 911 return rect_.GetWidth() - (style_->paddingLeft_ + style_->paddingRight_) - 912 (style_->borderWidth_ * 2); /* 2: left and right border */ 913} 914 915void 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 924void 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 935int16_t UIView::GetHeight() 936{ 937 return rect_.GetHeight() - (style_->paddingTop_ + style_->paddingBottom_) - 938 (style_->borderWidth_ * 2); /* 2: top and bottom border */ 939} 940 941void UIView::Resize(int16_t width, int16_t height) 942{ 943 SetWidth(width); 944 SetHeight(height); 945} 946 947void 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 959void UIView::SetX(int16_t x) 960{ 961 if (GetX() != x) { 962 rect_.SetX(x + GetStyle(STYLE_MARGIN_LEFT)); 963 } 964} 965 966void 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 977int16_t UIView::GetX() const 978{ 979 return rect_.GetX() - GetStyle(STYLE_MARGIN_LEFT); 980} 981 982void UIView::SetY(int16_t y) 983{ 984 if (GetY() != y) { 985 rect_.SetY(y + GetStyle(STYLE_MARGIN_TOP)); 986 } 987} 988 989void 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 1000int16_t UIView::GetY() const 1001{ 1002 return rect_.GetY() - GetStyle(STYLE_MARGIN_TOP); 1003} 1004 1005void UIView::SetPosition(int16_t x, int16_t y) 1006{ 1007 SetX(x); 1008 SetY(y); 1009} 1010 1011void 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 1023void 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 1030void 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 1044bool UIView::IsViewGroup() const 1045{ 1046 return isViewGroup_; 1047} 1048 1049void UIView::SetIntercept(bool isIntercept) 1050{ 1051 isIntercept_ = isIntercept; 1052} 1053 1054bool UIView::IsIntercept() 1055{ 1056 return isIntercept_; 1057} 1058 1059bool UIView::IsInvalid(float percent) 1060{ 1061 if ((percent < 1) && (percent > 0)) { 1062 return false; 1063 } 1064 return true; 1065} 1066 1067TransformMap& UIView::GetTransformMap() 1068{ 1069 if (transMap_ == nullptr) { 1070 transMap_ = new TransformMap(); 1071 } 1072 return *transMap_; 1073} 1074 1075UIView* UIView::GetChildById(const char* id) const 1076{ 1077 return nullptr; 1078} 1079 1080void UIView::SetViewId(const char* id) 1081{ 1082 id_ = id; 1083} 1084 1085const char* UIView::GetViewId() const 1086{ 1087 return id_; 1088} 1089 1090void UIView::SetViewIndex(int16_t index) 1091{ 1092 index_ = index; 1093} 1094 1095int16_t UIView::GetViewIndex() const 1096{ 1097 return index_; 1098} 1099 1100UIViewType UIView::GetViewType() const 1101{ 1102 return UI_NUMBER_MAX; 1103} 1104 1105void 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 1122void 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 1132void 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 1142void 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 1152void 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 1162void 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 1174void 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 1186void 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 1198void 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 1210void 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} 1223void 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 1237void 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 1249void 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 1261void 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 1273void 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 1285uint8_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 1298bool 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 1349bool 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 1361int16_t UIView::GetWidthWithMargin() 1362{ 1363 return GetRelativeRect().GetWidth() + GetStyle(STYLE_MARGIN_LEFT) + GetStyle(STYLE_MARGIN_RIGHT); 1364} 1365 1366int16_t UIView::GetHeightWithMargin() 1367{ 1368 return GetRelativeRect().GetHeight() + GetStyle(STYLE_MARGIN_TOP) + GetStyle(STYLE_MARGIN_BOTTOM); 1369} 1370 1371Rect UIView::GetRelativeRect() const 1372{ 1373 return rect_; 1374} 1375 1376void 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 1390void 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 1402int16_t UIView::GetZIndex() 1403{ 1404 return zIndex_; 1405} 1406} // namespace OHOS 1407