1 /* 2 * Copyright (c) 2021-2022 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_RENDER_NODE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_RENDER_NODE_H 18 19 #include <list> 20 21 #include "base/geometry/dimension.h" 22 #include "base/geometry/matrix4.h" 23 #include "base/geometry/rect.h" 24 #include "base/memory/ace_type.h" 25 #include "base/utils/macros.h" 26 #include "base/utils/system_properties.h" 27 #include "core/accessibility/accessibility_manager.h" 28 #include "core/animation/animatable_properties.h" 29 #include "core/animation/keyframe_animation.h" 30 #include "core/animation/property_animatable.h" 31 #include "core/common/draw_delegate.h" 32 #include "core/components/common/layout/align_declaration.h" 33 #include "core/components/common/layout/constants.h" 34 #include "core/components/common/layout/layout_param.h" 35 #include "core/components/common/properties/motion_path_option.h" 36 #include "core/components/common/properties/state_attributes.h" 37 #include "core/components/common/properties/text_style.h" 38 #include "core/components_v2/extensions/events/event_extensions.h" 39 #include "core/components_v2/inspector/inspector_node.h" 40 #include "core/event/axis_event.h" 41 #include "core/event/mouse_raw_recognizer.h" 42 #include "core/event/touch_event.h" 43 #include "core/gestures/click_recognizer.h" 44 #include "core/gestures/drag_recognizer.h" 45 #include "core/pipeline/base/render_context.h" 46 #include "core/pipeline/base/render_layer.h" 47 #include "core/pipeline/pipeline_context.h" 48 49 namespace OHOS::Ace { 50 51 extern const Dimension FOCUS_BOUNDARY; 52 53 class Component; 54 55 // If no insertion location is specified, new child will be added to the end of children list by default. 56 constexpr int32_t DEFAULT_RENDER_NODE_SLOT = -1; 57 constexpr int32_t PRESS_DURATION = 100; 58 constexpr int32_t HOVER_DURATION = 250; 59 constexpr uint32_t FIND_MAX_COUNT = 64; 60 61 using HoverAndPressCallback = std::function<void(const Color&)>; 62 using Rosen::RSNode; 63 64 // RenderNode is the base class for different render backend, represent a render unit for render pipeline. 65 class ACE_EXPORT RenderNode : public PropertyAnimatable, public AnimatableProperties, public virtual AceType { 66 DECLARE_ACE_TYPE(RenderNode, PropertyAnimatable, AceType); 67 68 public: 69 using OpacityCallback = std::function<void(uint8_t)>; 70 using SlipFactorSetting = std::function<void(double)>; 71 ~RenderNode() override = default; 72 73 static void MarkTreeRender(const RefPtr<RenderNode>& root, bool& meetHole, bool needFlush); 74 75 static void MarkWholeRender(const WeakPtr<RenderNode>& nodeWeak, bool needFlush); 76 SetZIndex(int32_t zIndex)77 void SetZIndex(int32_t zIndex) 78 { 79 zIndex_ = zIndex; 80 } 81 GetZIndex()82 int32_t GetZIndex() const 83 { 84 return zIndex_; 85 } 86 SetIsPercentSize(bool isPercentSize)87 void SetIsPercentSize(bool isPercentSize) 88 { 89 isPercentSize_ = isPercentSize; 90 } 91 GetIsPercentSize()92 bool GetIsPercentSize() const 93 { 94 return isPercentSize_; 95 } 96 97 void AddChild(const RefPtr<RenderNode>& child, int32_t slot = DEFAULT_RENDER_NODE_SLOT); 98 99 void RemoveChild(const RefPtr<RenderNode>& child); 100 101 void MovePosition(int32_t slot); 102 103 void ClearChildren(); 104 105 virtual void MoveWhenOutOfViewPort(bool hasEffect); 106 107 bool IsPointInBox(const TouchEvent& point); 108 void Attach(const WeakPtr<PipelineContext>& context); 109 110 // unmount from render tree Unmount()111 void Unmount() 112 { 113 RefPtr<RenderNode> parent = parent_.Upgrade(); 114 if (parent) { 115 parent->MarkNeedLayout(); 116 parent->RemoveChild(AceType::Claim(this)); 117 } 118 parent_ = nullptr; 119 } 120 121 // Update node with attr, style, event, method and so on. 122 // This method will call Update virtual function. 123 void UpdateAll(const RefPtr<Component>& component); 124 AddToScene()125 virtual void AddToScene() {} 126 127 virtual void Update(const RefPtr<Component>& component) = 0; 128 129 // Called when page context attached, subclass can initialize object which needs page context. OnAttachContext()130 virtual void OnAttachContext() {} 131 FinishRender(const std::unique_ptr<DrawDelegate> & delegate,const Rect & dirty)132 virtual void FinishRender(const std::unique_ptr<DrawDelegate>& delegate, const Rect& dirty) {} 133 134 virtual void UpdateTouchRect(); 135 136 void SetTouchRectList(std::vector<Rect>& touchRectList); 137 bool CompareTouchRect(const Rect& parentTouchRect, const Rect& childTouchRect); 138 void CompareTouchRectList(std::vector<Rect>& touchRectList, 139 const std::vector<Rect>& childTouchRectList, const std::vector<Rect>& parentTouchRectList); 140 NeedLayout()141 bool NeedLayout() const 142 { 143 return needLayout_; 144 } 145 SetNeedLayout(bool needLayout)146 void SetNeedLayout(bool needLayout) 147 { 148 needLayout_ = needLayout; 149 } 150 151 void MarkNeedLayout(bool selfOnly = false, bool forceParent = false); 152 153 /** 154 * \brief check in mark need layout progress if parent need layout again. 155 * \return true if need layout again. 156 */ CheckIfNeedLayoutAgain()157 virtual bool CheckIfNeedLayoutAgain() 158 { 159 return true; 160 } 161 162 void MarkNeedPredictLayout(); 163 164 void OnLayout(); 165 166 // deadline : The remaining time until the next vsync. (unit: microsecond) OnPredictLayout(int64_t deadline)167 virtual void OnPredictLayout(int64_t deadline) {} 168 GetChildViewPort()169 virtual Size GetChildViewPort() 170 { 171 return viewPort_; 172 } 173 174 // Called by parent to perform layout. Layout(const LayoutParam & layoutParam)175 void Layout(const LayoutParam& layoutParam) 176 { 177 auto pipeline = context_.Upgrade(); 178 if (!pipeline) { 179 LOGE("pipeline is null when layout"); 180 return; 181 } 182 183 bool dipScaleChange = !NearEqual(pipeline->GetDipScale(), dipScale_); 184 dipScale_ = pipeline->GetDipScale(); 185 if (dipScaleChange || layoutParam_ != layoutParam) { 186 layoutParam_ = layoutParam; 187 layoutParamChanged_ = true; 188 SetNeedLayout(true); 189 } 190 191 if (onChangeCallback_) { 192 onChangeCallback_(); 193 } 194 OnLayout(); 195 } 196 197 // Called by parent to update layout param without PerformLayout. SetLayoutParam(const LayoutParam & layoutParam)198 void SetLayoutParam(const LayoutParam& layoutParam) 199 { 200 if (layoutParam_ != layoutParam) { 201 layoutParam_ = layoutParam; 202 layoutParamChanged_ = true; 203 MarkNeedLayout(); 204 } 205 } 206 GetLayoutParam()207 const LayoutParam& GetLayoutParam() const 208 { 209 return layoutParam_; 210 } 211 212 // Each subclass should override this function for actual layout operation. 213 virtual void PerformLayout() = 0; 214 GetPosition()215 Offset GetPosition() const 216 { 217 return paintRect_.GetOffset(); 218 } 219 220 void SetPosition(const Offset& offset); 221 SetAbsolutePosition(const Offset & offset)222 void SetAbsolutePosition(const Offset& offset) 223 { 224 SetPositionInternal(offset); 225 } 226 GetLayoutSize()227 Size GetLayoutSize() const 228 { 229 return paintRect_.GetSize(); 230 } 231 232 Rect GetRectWithShadow() const; 233 SetShadow(const Shadow & shadow)234 void SetShadow(const Shadow& shadow) 235 { 236 shadow_ = shadow; 237 hasShadow_ = true; 238 } 239 240 void SetLayoutSize(const Size& size); 241 GetRectBasedWindowTopLeft()242 Rect GetRectBasedWindowTopLeft() 243 { 244 return Rect(GetGlobalOffset(), paintRect_.GetSize()); 245 } 246 GetTouchRect()247 virtual const Rect& GetTouchRect() 248 { 249 if (needUpdateTouchRect_) { 250 needUpdateTouchRect_ = false; 251 UpdateTouchRect(); 252 } 253 return touchRect_; 254 } 255 GetTouchRectList()256 virtual const std::vector<Rect>& GetTouchRectList() 257 { 258 if (needUpdateTouchRect_) { 259 needUpdateTouchRect_ = false; 260 touchRectList_.clear(); 261 UpdateTouchRect(); 262 } 263 return touchRectList_; 264 } 265 ChangeTouchRectList(std::vector<Rect> & touchRectList)266 void ChangeTouchRectList(std::vector<Rect>& touchRectList) 267 { 268 touchRectList_ = touchRectList; 269 } 270 InTouchRectList(const Point & parentLocalPoint,const std::vector<Rect> & touchRectList)271 bool InTouchRectList(const Point& parentLocalPoint, const std::vector<Rect>& touchRectList) const 272 { 273 for (auto& rect : touchRectList) { 274 if (rect.IsInRegion(parentLocalPoint)) { 275 return true; 276 } 277 } 278 return false; 279 } 280 IsUseOnly()281 virtual bool IsUseOnly() 282 { 283 return false; 284 } 285 IsNotSiblingAddRecognizerToResult()286 virtual bool IsNotSiblingAddRecognizerToResult() 287 { 288 return isNotSiblingAddRecognizerToResult_; 289 } 290 MarkIsNotSiblingAddRecognizerToResult(bool isNotSiblingAddRecognizerToResult)291 void MarkIsNotSiblingAddRecognizerToResult(bool isNotSiblingAddRecognizerToResult) 292 { 293 isNotSiblingAddRecognizerToResult_ = isNotSiblingAddRecognizerToResult; 294 } 295 GetTransformPoint(const Point & point)296 virtual Point GetTransformPoint(const Point& point) 297 { 298 return point; 299 } 300 GetTransformRect(const Rect & rect)301 virtual Rect GetTransformRect(const Rect& rect) 302 { 303 return rect; 304 } 305 306 const Rect& GetPaintRect() const; 307 308 Rect GetTransitionPaintRect() const; 309 310 Offset GetTransitionGlobalOffset() const; 311 312 void SetPaintRect(const Rect& rect); 313 SetTouchRect(const Rect & rect)314 void SetTouchRect(const Rect& rect) 315 { 316 touchRect_ = rect; 317 needUpdateTouchRect_ = false; 318 } 319 MarkNeedUpdateTouchRect(bool needUpdateTouchRect)320 void MarkNeedUpdateTouchRect(bool needUpdateTouchRect) 321 { 322 needUpdateTouchRect_ = needUpdateTouchRect; 323 } 324 OnChildAdded(const RefPtr<RenderNode> & child)325 virtual void OnChildAdded(const RefPtr<RenderNode>& child) 326 { 327 if (slipFactorSetting_) { 328 child->SetSlipFactorSetting(slipFactorSetting_); 329 } 330 } 331 OnChildRemoved(const RefPtr<RenderNode> & child)332 virtual void OnChildRemoved(const RefPtr<RenderNode>& child) {} 333 OnRemove()334 virtual void OnRemove() {} 335 GetAccessibilityText()336 const std::string& GetAccessibilityText() const 337 { 338 return accessibilityText_; 339 } 340 SetAccessibilityText(const std::string & accessibilityText)341 void SetAccessibilityText(const std::string& accessibilityText) 342 { 343 accessibilityText_ = accessibilityText; 344 } 345 346 virtual void DumpTree(int32_t depth); 347 348 virtual void Dump(); 349 350 enum class BridgeType { NONE, ROSEN, FLUTTER }; 351 GetBridgeType()352 virtual BridgeType GetBridgeType() const 353 { 354 return BridgeType::NONE; 355 } 356 SetNeedRender(bool needRender)357 void SetNeedRender(bool needRender) 358 { 359 needRender_ = needRender; 360 } 361 362 void MarkNeedRender(bool overlay = false); 363 NeedRender()364 bool NeedRender() const 365 { 366 return needRender_; 367 } 368 369 void SetDepth(int32_t depth); 370 SetPositionType(PositionType type)371 void SetPositionType(PositionType type) 372 { 373 positionParam_.type = type; 374 } 375 GetDepth()376 int32_t GetDepth() const 377 { 378 return depth_; 379 } 380 GetPositionType()381 PositionType GetPositionType() const 382 { 383 return positionParam_.type; 384 } 385 GetLeft()386 virtual const Dimension& GetLeft() const 387 { 388 return positionParam_.left.first; 389 } 390 GetRight()391 virtual const Dimension& GetRight() const 392 { 393 return positionParam_.right.first; 394 } 395 GetTop()396 virtual const Dimension& GetTop() const 397 { 398 return positionParam_.top.first; 399 } 400 GetBottom()401 virtual const Dimension& GetBottom() const 402 { 403 return positionParam_.bottom.first; 404 } 405 GetAnchorX()406 const Dimension& GetAnchorX() const 407 { 408 return positionParam_.anchor.first; 409 } 410 GetAnchorY()411 const Dimension& GetAnchorY() const 412 { 413 return positionParam_.anchor.second; 414 } 415 HasLeft()416 virtual bool HasLeft() const 417 { 418 return positionParam_.left.second; 419 } 420 HasRight()421 virtual bool HasRight() const 422 { 423 return positionParam_.right.second; 424 } 425 HasTop()426 virtual bool HasTop() const 427 { 428 return positionParam_.top.second; 429 } 430 HasBottom()431 virtual bool HasBottom() const 432 { 433 return positionParam_.bottom.second; 434 } 435 SetLeft(const Dimension & left)436 virtual void SetLeft(const Dimension& left) // add for animation 437 { 438 if (positionParam_.left.first != left) { 439 positionParam_.left = std::make_pair(left, true); 440 MarkNeedLayout(); 441 } 442 } 443 SetTop(const Dimension & top)444 virtual void SetTop(const Dimension& top) // add for animation 445 { 446 if (positionParam_.top.first != top) { 447 positionParam_.top = std::make_pair(top, true); 448 MarkNeedLayout(); 449 } 450 } 451 SetRight(const Dimension & right)452 virtual void SetRight(const Dimension& right) // add for animation 453 { 454 if (positionParam_.right.first != right) { 455 positionParam_.top = std::make_pair(right, true); 456 MarkNeedLayout(); 457 } 458 } 459 SetBottom(const Dimension & bottom)460 virtual void SetBottom(const Dimension& bottom) // add for animation 461 { 462 if (positionParam_.bottom.first != bottom) { 463 positionParam_.bottom = std::make_pair(bottom, true); 464 MarkNeedLayout(); 465 } 466 } 467 GetParent()468 WeakPtr<RenderNode> GetParent() const 469 { 470 return parent_; 471 } 472 GetContext()473 WeakPtr<PipelineContext> GetContext() const 474 { 475 return context_; 476 } 477 GetRenderLayer()478 virtual RenderLayer GetRenderLayer() 479 { 480 return nullptr; 481 } 482 483 virtual void SetVisible(bool visible, bool inRecursion = false); 484 GetVisible()485 virtual bool GetVisible() const 486 { 487 return visible_; 488 } 489 490 virtual void SetHidden(bool hidden, bool inRecursion = false) 491 { 492 if (hidden_ != hidden) { 493 hidden_ = hidden; 494 AddDirtyRenderBoundaryNode(); 495 OnHiddenChanged(hidden); 496 if (!inRecursion && SystemProperties::GetRosenBackendEnabled()) { 497 MarkParentNeedRender(); 498 } 499 if (hidden_) { 500 disableTouchEvent_ = true; 501 } else { 502 disableTouchEvent_ = false; 503 } 504 } 505 for (auto& child : children_) { 506 child->SetHidden(hidden, true); 507 } 508 } 509 SetSelfHidden(bool hidden)510 void SetSelfHidden(bool hidden) 511 { 512 if (hidden_ != hidden) { 513 hidden_ = hidden; 514 AddDirtyRenderBoundaryNode(); 515 OnHiddenChanged(hidden); 516 if (SystemProperties::GetRosenBackendEnabled()) { 517 MarkParentNeedRender(); 518 } 519 } 520 } 521 GetHidden()522 bool GetHidden() const 523 { 524 return hidden_; 525 } 526 IsTakenBoundary()527 bool IsTakenBoundary() const 528 { 529 return takeBoundary_; 530 } 531 IsRepaintBoundary()532 virtual bool IsRepaintBoundary() const 533 { 534 return IsHeadRenderNode(); 535 } 536 GetChildren()537 virtual const std::list<RefPtr<RenderNode>>& GetChildren() const 538 { 539 return children_; 540 } 541 542 virtual void NotifyPaintFinish(); 543 544 virtual void RenderWithContext(RenderContext& context, const Offset& offset); 545 virtual void Paint(RenderContext& context, const Offset& offset); 546 void PaintChildList(const std::list<RefPtr<RenderNode>>& childList, RenderContext& context, const Offset& offset); 547 virtual void PaintChild(const RefPtr<RenderNode>& child, RenderContext& context, const Offset& offset); 548 OnPaintFinish()549 virtual void OnPaintFinish() {} 550 551 virtual bool TouchTest(const Point& globalPoint, const Point& parentLocalPoint, const TouchRestrict& touchRestrict, 552 TouchTestResult& result); 553 554 virtual void MouseTest(const Point& globalPoint, const Point& parentLocalPoint, MouseRawResult& result); 555 556 virtual bool MouseHoverTest(const Point& parentLocalPoint); 557 558 virtual bool MouseDetect(const Point& globalPoint, const Point& parentLocalPoint, MouseHoverTestList& result, 559 WeakPtr<RenderNode>& hoverNode); 560 561 virtual bool AxisDetect(const Point& globalPoint, const Point& parentLocalPoint, WeakPtr<RenderNode>& axisNode, 562 const AxisDirection direction); 563 HandleMouseHoverEvent(const MouseState mouseState)564 virtual void HandleMouseHoverEvent(const MouseState mouseState) {} 565 HandleMouseEvent(const MouseEvent & event)566 virtual bool HandleMouseEvent(const MouseEvent& event) 567 { 568 return false; 569 } 570 HandleAxisEvent(const AxisEvent & event)571 virtual void HandleAxisEvent(const AxisEvent& event) {} 572 573 virtual bool RotationMatchTest(const RefPtr<RenderNode>& requestRenderNode); 574 575 virtual bool RotationTest(const RotationEvent& event); 576 577 virtual bool RotationTestForward(const RotationEvent& event); 578 579 virtual double GetBaselineDistance(TextBaseline textBaseline); 580 581 virtual Size GetContentSize(); 582 583 virtual bool ScrollPageByChild(Offset& delta, int32_t source); 584 585 // Change render nodes' status ChangeStatus(RenderStatus renderStatus)586 void ChangeStatus(RenderStatus renderStatus) 587 { 588 // Myself status should be changed and function achieved by derived class which is component 589 OnStatusChanged(renderStatus); 590 591 // Deep traversal 592 for (auto& child : children_) { 593 child->ChangeStatus(renderStatus); 594 } 595 } 596 597 virtual void OnStatusStyleChanged(VisualState state); 598 599 Offset GetOffsetFromOrigin(const Offset& offset) const; 600 601 virtual Offset GetGlobalOffset() const; 602 603 virtual Offset GetGlobalOffsetExternal() const; 604 605 RefPtr<RenderNode> GetHeadRenderNode(); 606 607 // Whether |rect| is in the paint rect of render tree recursively. 608 bool IsVisible(const Rect& rect, bool totally = false) const; 609 SetOnChangeCallback(std::function<void ()> && onChangeCallback)610 void SetOnChangeCallback(std::function<void()>&& onChangeCallback) 611 { 612 onChangeCallback_ = std::move(onChangeCallback); 613 } 614 SetDisableTouchEvent(bool disableTouchEvent)615 void SetDisableTouchEvent(bool disableTouchEvent) 616 { 617 disableTouchEvent_ = disableTouchEvent; 618 } 619 GetDisableTouchEvent()620 bool GetDisableTouchEvent() const 621 { 622 return disableTouchEvent_; 623 } 624 IsChildrenTouchEnable()625 virtual bool IsChildrenTouchEnable() 626 { 627 return true; 628 } 629 SetTextDirection(TextDirection textDirection)630 void SetTextDirection(TextDirection textDirection) 631 { 632 textDirection_ = textDirection; 633 } 634 GetTextDirection()635 TextDirection GetTextDirection() const 636 { 637 return textDirection_; 638 } 639 640 // Transfer any other dimension unit to logical px. 641 // NOTE: context_ MUST be initialized before call this method. 642 double NormalizeToPx(Dimension dimension) const; 643 644 // Mainly use this function to convert Percent to Px. Do not call this function in Update(). 645 double NormalizePercentToPx(const Dimension& dimension, bool isVertical, bool referSelf = false) const; 646 647 // for accessibility SetAccessibilityNode(const WeakPtr<AccessibilityNode> & accessibilityNode)648 void SetAccessibilityNode(const WeakPtr<AccessibilityNode>& accessibilityNode) 649 { 650 accessibilityNode_ = accessibilityNode; 651 } 652 GetAccessibilityNode()653 const WeakPtr<AccessibilityNode>& GetAccessibilityNode() const 654 { 655 return accessibilityNode_; 656 } 657 GetAccessibilityNodeId()658 int32_t GetAccessibilityNodeId() const 659 { 660 auto accessibilityNode = accessibilityNode_.Upgrade(); 661 if (accessibilityNode) { 662 return accessibilityNode->GetNodeId(); 663 } 664 return 0; 665 } 666 ClearAccessibilityRect()667 void ClearAccessibilityRect() 668 { 669 auto node = accessibilityNode_.Upgrade(); 670 if (node) { 671 node->ClearRect(); 672 } 673 for (auto& child : children_) { 674 child->ClearAccessibilityRect(); 675 } 676 } 677 void SetAccessibilityRect(const Rect& rect); 678 SetNeedUpdateAccessibility(bool needUpdate)679 void SetNeedUpdateAccessibility(bool needUpdate) 680 { 681 needUpdateAccessibility_ = needUpdate; 682 for (auto& child : children_) { 683 child->SetNeedUpdateAccessibility(needUpdate); 684 } 685 } 686 SetAccessibilityVisible(bool visible)687 void SetAccessibilityVisible(bool visible) 688 { 689 auto node = accessibilityNode_.Upgrade(); 690 if (node) { 691 node->SetVisible(visible); 692 } 693 for (auto& child : children_) { 694 child->SetAccessibilityVisible(visible); 695 } 696 } 697 698 RefPtr<RenderNode> GetLastChild() const; 699 700 RefPtr<RenderNode> GetFirstChild() const; 701 GetOffsetToStage()702 Offset GetOffsetToStage() const 703 { 704 auto offset = GetGlobalOffset(); 705 auto context = GetContext().Upgrade(); 706 if (context) { 707 offset = offset - context->GetStageRect().GetOffset(); 708 } 709 return offset; 710 } 711 712 Offset GetOffsetToPage() const; 713 GetFlexWeight()714 double GetFlexWeight() const 715 { 716 return flexWeight_; 717 } 718 GetDisplayIndex()719 int32_t GetDisplayIndex() const 720 { 721 return displayIndex_; 722 } 723 GetDisplayIndexSetted()724 bool GetDisplayIndexSetted() const 725 { 726 return displayIndexSetted_; 727 } 728 729 OpacityCallback GetOpacityCallback(int32_t domId); 730 731 virtual bool SupportOpacity(); 732 733 void GetDomOpacityCallbacks(int32_t domId, std::list<OpacityCallback>& result); 734 735 int32_t GetNodeId() const; 736 737 uint8_t GetOpacity() const; 738 739 virtual void UpdateOpacity(uint8_t opacity); 740 InterceptTouchEvent()741 bool InterceptTouchEvent() const 742 { 743 return interceptTouchEvent_; 744 } 745 SetInterceptTouchEvent(bool interceptTouchEvent)746 void SetInterceptTouchEvent(bool interceptTouchEvent) 747 { 748 interceptTouchEvent_ = interceptTouchEvent; 749 } 750 DispatchCancelPressAnimation()751 void DispatchCancelPressAnimation() 752 { 753 OnCancelPressAnimation(); 754 for (const auto& child : children_) { 755 child->DispatchCancelPressAnimation(); 756 } 757 } 758 CheckAxisNode()759 virtual WeakPtr<RenderNode> CheckAxisNode() 760 { 761 return nullptr; 762 } MouseHoverEnterTest()763 virtual void MouseHoverEnterTest() {} MouseHoverExitTest()764 virtual void MouseHoverExitTest() {} AnimateMouseHoverEnter()765 virtual void AnimateMouseHoverEnter() {} AnimateMouseHoverExit()766 virtual void AnimateMouseHoverExit() {} OnCancelPressAnimation()767 virtual void OnCancelPressAnimation() {} OnMouseHoverEnterAnimation()768 virtual void OnMouseHoverEnterAnimation() {} OnMouseHoverExitAnimation()769 virtual void OnMouseHoverExitAnimation() {} OnMouseClickDownAnimation()770 virtual void OnMouseClickDownAnimation() {} OnMouseClickUpAnimation()771 virtual void OnMouseClickUpAnimation() {} StopMouseHoverAnimation()772 virtual void StopMouseHoverAnimation() {} IsAxisScrollable(AxisDirection direction)773 virtual bool IsAxisScrollable(AxisDirection direction) 774 { 775 return false; 776 } 777 OnVisibleChanged()778 virtual void OnVisibleChanged() {} 779 780 void CreateMouseAnimation(RefPtr<KeyframeAnimation<Color>>& animation, const Color& from, const Color& to); SetHoverAndPressCallback(const HoverAndPressCallback & callback)781 void SetHoverAndPressCallback(const HoverAndPressCallback& callback) 782 { 783 hoveAndPressCallback_ = callback; 784 } 785 GetEventEffectColor()786 Color GetEventEffectColor() const 787 { 788 return eventEffectColor_; 789 } 790 791 void UpdateWindowBlurRRect(bool clear = false); 792 793 void WindowBlurTest(); 794 GetWindowBlurRRect()795 virtual RRect GetWindowBlurRRect() const 796 { 797 return RRect::MakeRRect(Rect(Offset::Zero(), GetLayoutSize()), Radius(0.0)); 798 } 799 800 RRect GetGlobalWindowBlurRRect(std::vector<RRect>& coords) const; 801 MarkNeedWindowBlur(bool flag)802 void MarkNeedWindowBlur(bool flag) 803 { 804 if (needWindowBlur_ != flag) { 805 needWindowBlur_ = flag; 806 if (!needWindowBlur_) { 807 UpdateWindowBlurProgress(0.0f); 808 SetWindowBlurStyle(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT); 809 } 810 OnWindowBlurChanged(); 811 } 812 } 813 NeedWindowBlur()814 bool NeedWindowBlur() const 815 { 816 return needWindowBlur_; 817 } 818 UpdateWindowBlurProgress(float progress)819 void UpdateWindowBlurProgress(float progress) 820 { 821 windowBlurProgress_ = progress; 822 } 823 GetWindowBlurProgress()824 float GetWindowBlurProgress() const 825 { 826 return windowBlurProgress_; 827 } 828 SetWindowBlurStyle(WindowBlurStyle style)829 void SetWindowBlurStyle(WindowBlurStyle style) 830 { 831 windowBlurStyle_ = style; 832 } 833 GetWindowBlurStyle()834 WindowBlurStyle GetWindowBlurStyle() const 835 { 836 return windowBlurStyle_; 837 } 838 SetSlipFactorSetting(const SlipFactorSetting & slipFactorSetting)839 void SetSlipFactorSetting(const SlipFactorSetting& slipFactorSetting) 840 { 841 slipFactorSetting_ = slipFactorSetting; 842 } 843 IsInfiniteLayout()844 bool IsInfiniteLayout() const 845 { 846 return GetLayoutSize().Width() > INT32_MAX || GetLayoutSize().Height() > INT32_MAX; 847 } 848 IsIgnored()849 bool IsIgnored() const 850 { 851 return isIgnored_; 852 } 853 SetIsIgnored(bool ignore)854 void SetIsIgnored(bool ignore) 855 { 856 isIgnored_ = ignore; 857 } 858 SetGlobalPoint(const Point & point)859 void SetGlobalPoint(const Point& point) 860 { 861 globalPoint_ = point; 862 } 863 GetGlobalPoint()864 const Point& GetGlobalPoint() 865 { 866 return globalPoint_; 867 } 868 SetCoordinatePoint(const Point & point)869 void SetCoordinatePoint(const Point& point) 870 { 871 coordinatePoint_ = point; 872 } 873 GetCoordinatePoint()874 const Point& GetCoordinatePoint() 875 { 876 return coordinatePoint_; 877 } 878 IsTouchable()879 bool IsTouchable() const 880 { 881 return touchable_; 882 } 883 GetHitTestMode()884 HitTestMode GetHitTestMode() const 885 { 886 return hitTestMode_; 887 } 888 IsDisabled()889 bool IsDisabled() const 890 { 891 return disabled_; 892 } 893 OnAppShow()894 virtual void OnAppShow() 895 { 896 isAppOnShow_ = true; 897 for (const auto& child : children_) { 898 child->OnAppShow(); 899 } 900 } 901 OnAppHide()902 virtual void OnAppHide() 903 { 904 isAppOnShow_ = false; 905 for (const auto& child : children_) { 906 child->OnAppHide(); 907 } 908 } 909 IsAppShow()910 bool IsAppShow() 911 { 912 return isAppOnShow_; 913 } 914 915 template<typename T> GetTheme()916 RefPtr<T> GetTheme() const 917 { 918 auto context = context_.Upgrade(); 919 if (!context) { 920 return nullptr; 921 } 922 auto themeManager = context->GetThemeManager(); 923 if (!themeManager) { 924 return nullptr; 925 } 926 return themeManager->GetTheme<T>(); 927 } 928 929 virtual bool HasEffectiveTransform() const; 930 OnTransition(TransitionType type,int32_t id)931 virtual void OnTransition(TransitionType type, int32_t id) {} 932 933 bool IsDisappearing(); 934 virtual bool HasDisappearingTransition(int32_t nodeId); 935 void NotifyTransition(TransitionType type, int32_t nodeId); SetPendingAppearingTransition()936 virtual void SetPendingAppearingTransition() {} 937 938 Rect GetDirtyRect() const; 939 std::function<void(const DragUpdateInfo&)> onDomDragEnter_ = nullptr; 940 std::function<void(const DragUpdateInfo&)> onDomDragOver_ = nullptr; 941 std::function<void(const DragUpdateInfo&)> onDomDragLeave_ = nullptr; 942 std::function<void(const DragEndInfo&)> onDomDragDrop_ = nullptr; 943 virtual bool GetAlignDeclarationOffset(AlignDeclarationPtr alignDeclarationPtr, Offset& offset) const; 944 945 // Each subclass override this to return touch target object which is used to receive touch event. 946 // For convenience, it is recommended to return directly to the corresponding gesture recognizer. 947 // Sees gestures directory. 948 // Uses coordinateOffset for recognizer to calculate the local location of the touch point. 949 // Uses touchRestrict for restrict gesture recognition in some sense. OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)950 virtual void OnTouchTestHit( 951 const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) 952 {} OnPreDraw()953 virtual void OnPreDraw() {} 954 955 template<typename T> FindChildNodeOfClass(const Point & globalPoint,const Point & parentLocalPoint)956 RefPtr<T> FindChildNodeOfClass(const Point& globalPoint, const Point& parentLocalPoint) 957 { 958 Point transformPoint = GetTransformPoint(parentLocalPoint); 959 if (!InTouchRectList(transformPoint, GetTouchRectList())) { 960 return nullptr; 961 } 962 963 // Calculates the local point location in this node. 964 const auto localPoint = transformPoint - GetPaintRect().GetOffset(); 965 const auto& children = GetChildren(); 966 for (auto iter = children.rbegin(); iter != children.rend(); ++iter) { 967 auto& child = *iter; 968 if (!child->GetVisible()) { 969 continue; 970 } 971 972 if (child->InterceptTouchEvent()) { 973 continue; 974 } 975 976 auto target = child->FindChildNodeOfClass<T>(globalPoint, localPoint); 977 if (target) { 978 return target; 979 } 980 } 981 982 for (auto& rect : GetTouchRectList()) { 983 if (touchable_ && rect.IsInRegion(transformPoint)) { 984 RefPtr<RenderNode> renderNode = AceType::Claim<RenderNode>(this); 985 if (AceType::InstanceOf<T>(renderNode)) { 986 return AceType::DynamicCast<T>(renderNode); 987 } 988 } 989 } 990 return nullptr; 991 } 992 993 template<typename T> FindTargetRenderNode(const RefPtr<PipelineContext> context,const GestureEvent & info)994 RefPtr<T> FindTargetRenderNode(const RefPtr<PipelineContext> context, const GestureEvent& info) 995 { 996 if (!context) { 997 return nullptr; 998 } 999 1000 auto pageRenderNode = context->GetLastPageRender(); 1001 if (!pageRenderNode) { 1002 return nullptr; 1003 } 1004 1005 return pageRenderNode->FindChildNodeOfClass<T>(info.GetGlobalPoint(), info.GetGlobalPoint()); 1006 } 1007 1008 template<class T> FindChildOfClass(const RefPtr<RenderNode> & parent)1009 RefPtr<T> FindChildOfClass(const RefPtr<RenderNode>& parent) 1010 { 1011 // BFS to find child in tree. 1012 uint32_t findCount = 0; 1013 auto searchQueue = parent->GetChildren(); // copy children to a queue 1014 while (++findCount <= FIND_MAX_COUNT && !searchQueue.empty()) { 1015 const auto child = searchQueue.front(); 1016 searchQueue.pop_front(); 1017 if (!child) { 1018 continue; 1019 } 1020 if (AceType::InstanceOf<T>(child)) { 1021 return AceType::DynamicCast<T>(child); 1022 } 1023 searchQueue.insert(searchQueue.end(), child->GetChildren().begin(), child->GetChildren().end()); 1024 } 1025 return RefPtr<T>(); 1026 } 1027 1028 void SaveExplicitAnimationOption(const AnimationOption& option); 1029 1030 const AnimationOption& GetExplicitAnimationOption() const; 1031 1032 void ClearExplicitAnimationOption(); 1033 1034 void ClearDisappearingNode(RefPtr<RenderNode> child); 1035 1036 void CreateLayoutTransition(); 1037 1038 void CreatePathAnimation(); 1039 IsExclusiveEventForChild()1040 bool IsExclusiveEventForChild() const 1041 { 1042 return exclusiveEventForChild_; 1043 } SetExclusiveEventForChild(bool exclusiveEventForChild)1044 void SetExclusiveEventForChild(bool exclusiveEventForChild) 1045 { 1046 exclusiveEventForChild_ = exclusiveEventForChild; 1047 } 1048 1049 void MarkUpdateType(const RefPtr<Component>& component); 1050 GetComponent()1051 virtual RefPtr<Component> GetComponent() 1052 { 1053 return nullptr; 1054 } 1055 1056 virtual void NotifySizeTransition(const AnimationOption& option, Size fromSize, Size toSize, int32_t nodeId); 1057 void CreateGeometryTransitionFrom(const RefPtr<RenderNode>& targetNode, AnimationOption& sharedOption); 1058 void CreateGeometryTransitionTo(const RefPtr<RenderNode>& targetNode, AnimationOption& sharedOption); 1059 void SetIsPaintGeometryTransition(bool isPaintGeometryTransition); 1060 void SetPaintOutOfParent(bool isPaintOutOfParent); 1061 bool IsPaintOutOfParent(); 1062 void UpdatePosition(); 1063 SetHasSubWindow(bool hasSubWindow)1064 void SetHasSubWindow(bool hasSubWindow) 1065 { 1066 hasSubWindow_ = hasSubWindow; 1067 } 1068 GetHasSubWindow()1069 bool GetHasSubWindow() const 1070 { 1071 return hasSubWindow_; 1072 } 1073 1074 // mark JSview boundary, create/destroy RSNode if need 1075 void SyncRSNodeBoundary(bool isHead, bool isTail, const RefPtr<Component>& component = nullptr); 1076 bool ProcessExternalRSNode(const RefPtr<Component>& component); 1077 void SyncRSNode(const std::shared_ptr<RSNode>& rsNode); GetRSNode()1078 const std::shared_ptr<RSNode>& GetRSNode() const 1079 { 1080 return rsNode_; 1081 } 1082 // sync geometry properties to ROSEN backend 1083 virtual void SyncGeometryProperties(); 1084 IsResponseRegion()1085 bool IsResponseRegion() const 1086 { 1087 return isResponseRegion_; 1088 } 1089 1090 double GetPxValue(double standard, const Dimension& value); 1091 GetResponseRegionList()1092 const std::vector<Rect>& GetResponseRegionList() const 1093 { 1094 return responseRegionList_; 1095 } 1096 GetInspectorNode()1097 const WeakPtr<V2::InspectorNode>& GetInspectorNode() const 1098 { 1099 return inspector_; 1100 } 1101 SetInspectorNode(const RefPtr<V2::InspectorNode> & inspectorNode)1102 void SetInspectorNode(const RefPtr<V2::InspectorNode>& inspectorNode) 1103 { 1104 inspector_ = inspectorNode; 1105 } 1106 SetNeedClip(bool needClip)1107 virtual void SetNeedClip(bool needClip) 1108 { 1109 needClip_ = needClip; 1110 } 1111 GetNeedClip()1112 bool GetNeedClip() 1113 { 1114 return needClip_; 1115 } 1116 1117 RefPtr<RenderNode> FindDropChild(const Point& globalPoint, const Point& parentLocalPoint); 1118 static constexpr size_t DEFAULT_INDEX = -1; 1119 ProvideRestoreInfo()1120 virtual std::string ProvideRestoreInfo() 1121 { 1122 return ""; 1123 } 1124 SetRestoreInfo(const std::string & restoreInfo)1125 void SetRestoreInfo(const std::string& restoreInfo) 1126 { 1127 restoreInfo_ = restoreInfo; 1128 } 1129 GetRestoreInfo()1130 const std::string& GetRestoreInfo() const 1131 { 1132 return restoreInfo_; 1133 } 1134 1135 // JSview boundary, all nodes in [head, tail] share the same RSNode IsHeadRenderNode()1136 bool IsHeadRenderNode() const 1137 { 1138 #ifdef ENABLE_ROSEN_BACKEND 1139 return SystemProperties::GetRosenBackendEnabled() ? isHeadRenderNode_ : false; 1140 #else 1141 return false; 1142 #endif 1143 } 1144 1145 protected: 1146 explicit RenderNode(bool takeBoundary = false); 1147 virtual void ClearRenderObject(); 1148 OnMouseTestHit(const Offset & coordinateOffset,MouseRawResult & result)1149 virtual void OnMouseTestHit(const Offset& coordinateOffset, MouseRawResult& result) {} OnMouseHoverEnterTest()1150 virtual void OnMouseHoverEnterTest() {} OnMouseHoverExitTest()1151 virtual void OnMouseHoverExitTest() {} 1152 void SendAccessibilityEvent(const std::string& eventType); 1153 void SetAccessibilityClick(RefPtr<ClickRecognizer> clickRecognizer); 1154 bool DispatchTouchTestToChildren(const Point& localPoint, const Point& globalPoint, 1155 const TouchRestrict& touchRestrict, TouchTestResult& result); 1156 1157 void PrepareLayout(); 1158 SetParent(const WeakPtr<RenderNode> & parent)1159 void SetParent(const WeakPtr<RenderNode>& parent) 1160 { 1161 parent_ = parent; 1162 } 1163 1164 void TakeBoundary(bool taken = true) 1165 { 1166 takeBoundary_ = taken; 1167 } 1168 IsLayoutParamChanged()1169 bool IsLayoutParamChanged() const 1170 { 1171 return layoutParamChanged_; 1172 } 1173 OnGlobalPositionChanged()1174 virtual void OnGlobalPositionChanged() 1175 { 1176 MarkNeedSyncGeometryProperties(); 1177 if (IsTailRenderNode()) { 1178 return; 1179 } 1180 for (const auto& child : children_) { 1181 if (child) { 1182 child->OnGlobalPositionChanged(); 1183 } 1184 } 1185 }; OnPositionChanged()1186 virtual void OnPositionChanged() {} OnSizeChanged()1187 virtual void OnSizeChanged() {} OnRenderFinish(RenderContext & context)1188 virtual void OnRenderFinish(RenderContext& context) {} OnStatusChanged(RenderStatus renderStatus)1189 virtual void OnStatusChanged(RenderStatus renderStatus) {} OnHiddenChanged(bool hidden)1190 virtual void OnHiddenChanged(bool hidden) {} OnWindowBlurChanged()1191 virtual void OnWindowBlurChanged() {} 1192 virtual bool MarkNeedRenderSpecial(); 1193 1194 double GetHighestChildBaseline(TextBaseline baseline); 1195 double GetFirstChildBaseline(TextBaseline baseline); 1196 Size GetLargestChildContentSize(); 1197 void UpdateAccessibilityPosition(); 1198 void UpdateAccessibilityEnable(bool isEnabled); 1199 void CheckIfNeedUpdateTouchRect(); 1200 GetThemeManager()1201 RefPtr<ThemeManager> GetThemeManager() const 1202 { 1203 auto context = context_.Upgrade(); 1204 if (!context) { 1205 return nullptr; 1206 } 1207 return context->GetThemeManager(); 1208 } 1209 GetUpdateType()1210 uint32_t GetUpdateType() 1211 { 1212 return updateType_; 1213 } 1214 1215 virtual std::shared_ptr<RSNode> CreateRSNode() const; OnRSTransition(TransitionType type)1216 virtual void OnRSTransition(TransitionType type) {} IsTailRenderNode()1217 bool IsTailRenderNode() const 1218 { 1219 return isTailRenderNode_; 1220 } 1221 Offset GetPaintOffset() const; HasGeometryProperties()1222 virtual bool HasGeometryProperties() const 1223 { 1224 return IsTailRenderNode(); 1225 } 1226 void MarkNeedSyncGeometryProperties(); 1227 1228 bool hasSubWindow_ = false; 1229 bool needClip_ = false; 1230 WeakPtr<PipelineContext> context_; 1231 Size viewPort_; 1232 Point globalPoint_; 1233 Point coordinatePoint_; 1234 WeakPtr<V2::InspectorNode> inspector_; 1235 WeakPtr<AccessibilityNode> accessibilityNode_; 1236 1237 // Used for RS extra case. 1238 bool isFirstNode_ = false; 1239 1240 Rect touchRect_; // Self touch rect 1241 std::vector<Rect> touchRectList_; // Self and all children touch rect 1242 std::vector<DimensionRect> responseRegion_; 1243 std::vector<Rect> responseRegionList_; 1244 PositionParam positionParam_; 1245 uint8_t opacity_ = 255; 1246 Shadow shadow_; 1247 1248 float windowBlurProgress_ = 0.0f; 1249 WindowBlurStyle windowBlurStyle_ = WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT; 1250 bool touchable_ = true; 1251 bool interceptTouchEvent_ = false; 1252 bool needWindowBlur_ = false; 1253 bool needUpdateAccessibility_ = true; 1254 bool disabled_ = false; 1255 bool isResponseRegion_ = false; 1256 HoverAnimationType hoverAnimationType_ = HoverAnimationType::UNKNOWN; 1257 int32_t minPlatformVersion_ = 0; 1258 1259 MouseState mouseState_ = MouseState::NONE; 1260 SlipFactorSetting slipFactorSetting_; 1261 1262 HoverAndPressCallback hoveAndPressCallback_; 1263 1264 // hover or press color 1265 Color eventEffectColor_ = Color::TRANSPARENT; 1266 std::function<void(const std::string&)> onLayoutReady_; 1267 1268 bool isAppOnShow_ = true; 1269 AnimationOption nonStrictOption_; // clear after transition done 1270 MotionPathOption motionPathOption_; 1271 RefPtr<V2::EventExtensions> eventExtensions_; 1272 1273 // Compute multiSelect zone 1274 Rect ComputeSelectedZone(const Offset& startOffset, const Offset& endOffset); 1275 1276 private: AddDirtyRenderBoundaryNode()1277 void AddDirtyRenderBoundaryNode() 1278 { 1279 if (visible_ && !hidden_ && IsRepaintBoundary()) { 1280 auto pipelineContext = context_.Upgrade(); 1281 if (pipelineContext == nullptr) { 1282 return; 1283 } 1284 pipelineContext->AddDirtyRenderNode(AceType::Claim(this)); 1285 } 1286 } 1287 1288 void SetPositionInternal(const Offset& offset); 1289 bool InLayoutTransition() const; 1290 // Sync view hierarchy to RSNode 1291 void RSNodeAddChild(const RefPtr<RenderNode>& child); 1292 void MarkParentNeedRender() const; 1293 static std::shared_ptr<RSNode> ExtractExternalRSNode(const RefPtr<Component>& component); 1294 1295 std::list<RefPtr<RenderNode>> hoverChildren_; 1296 std::list<RefPtr<RenderNode>> children_; 1297 std::string accessibilityText_; 1298 LayoutParam layoutParam_; 1299 Rect paintRect_; 1300 WeakPtr<RenderNode> parent_; 1301 int32_t depth_ = 0; 1302 bool needRender_ = false; 1303 bool needLayout_ = false; 1304 bool visible_ = true; 1305 bool takeBoundary_ = false; 1306 bool layoutParamChanged_ = false; 1307 bool pendingDispatchLayoutReady_ = false; 1308 bool disableTouchEvent_ = false; 1309 bool needUpdateTouchRect_ = false; 1310 bool hasShadow_ = false; 1311 1312 double flexWeight_ = 0.0; 1313 int32_t displayIndex_ = 1; 1314 bool displayIndexSetted_ = false; 1315 1316 double dipScale_ = 0.0; 1317 1318 TextDirection textDirection_ { TextDirection::LTR }; 1319 Offset selfOffset_ { 0, 0 }; 1320 1321 bool hidden_ = false; 1322 bool isIgnored_ = false; 1323 std::function<void()> onChangeCallback_; 1324 std::list<RefPtr<RenderNode>> disappearingNodes_; 1325 AnimatableDimension paintX_; 1326 AnimatableDimension paintY_; 1327 AnimatableDimension paintW_; 1328 AnimatableDimension paintH_; 1329 Size transitionPaintRectSize_; 1330 Rect nonStrictPaintRect_; 1331 bool isFirstSizeAssign_ = true; 1332 bool isFirstPositionAssign_ = true; 1333 1334 // for container, this flag controls only the last child in touch area is consuming event. 1335 bool exclusiveEventForChild_ = false; 1336 int32_t zIndex_ = 0; 1337 bool isPercentSize_ = false; 1338 uint32_t updateType_ = 0; 1339 1340 std::shared_ptr<RSNode> rsNode_ = nullptr; 1341 bool isHeadRenderNode_ = false; 1342 bool isTailRenderNode_ = false; 1343 1344 bool isPaintGeometryTransition_ = false; 1345 bool isPaintOutOfParent_ = false; 1346 1347 std::string restoreInfo_; 1348 bool isNotSiblingAddRecognizerToResult_ = true; 1349 HitTestMode hitTestMode_ = HitTestMode::HTMDEFAULT; 1350 1351 ACE_DISALLOW_COPY_AND_MOVE(RenderNode); 1352 }; 1353 1354 } // namespace OHOS::Ace 1355 1356 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_RENDER_NODE_H 1357