1 /* 2 * Copyright (c) 2023 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_NG_LAYOUTS_LAYOUT_WRAPPER_NODE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_LAYOUTS_LAYOUT_WRAPPER_NODE_H 18 19 #include <map> 20 #include <optional> 21 #include <string> 22 #include <unordered_map> 23 24 #include "base/geometry/offset.h" 25 #include "base/memory/ace_type.h" 26 #include "base/memory/referenced.h" 27 #include "base/thread/cancelable_callback.h" 28 #include "base/utils/macros.h" 29 #include "base/utils/noncopyable.h" 30 #include "core/components_ng/base/geometry_node.h" 31 #include "core/components_ng/layout/box_layout_algorithm.h" 32 #include "core/components_ng/layout/layout_algorithm.h" 33 #include "core/components_ng/layout/layout_property.h" 34 #include "core/components_ng/layout/layout_wrapper.h" 35 #include "core/components_ng/layout/layout_wrapper_builder.h" 36 #include "core/components_ng/property/geometry_property.h" 37 #include "core/components_ng/property/layout_constraint.h" 38 #include "core/components_ng/property/magic_layout_property.h" 39 #include "core/components_ng/property/measure_property.h" 40 #include "core/components_ng/property/position_property.h" 41 #include "core/components_ng/property/property.h" 42 #include "core/components_v2/inspector/inspector_constants.h" 43 44 namespace OHOS::Ace::NG { 45 class FrameNode; 46 class LayoutWrapperNode; 47 48 using LazyBuildFunction = std::function<void(RefPtr<LayoutWrapperNode>)>; 49 50 class ACE_EXPORT LayoutWrapperNode : public LayoutWrapper { 51 DECLARE_ACE_TYPE(LayoutWrapperNode, LayoutWrapper) 52 public: 53 LayoutWrapperNode( 54 WeakPtr<FrameNode> hostNode, RefPtr<GeometryNode> geometryNode, RefPtr<LayoutProperty> layoutProperty); 55 LayoutWrapperNode(LazyBuildFunction && fun)56 LayoutWrapperNode(LazyBuildFunction&& fun) 57 : LayoutWrapper(nullptr), geometryNode_(MakeRefPtr<GeometryNode>()), 58 layoutProperty_(MakeRefPtr<LayoutProperty>()), lazyBuildFunction_(fun) 59 {} 60 ~LayoutWrapperNode() override = default; 61 62 void Update(WeakPtr<FrameNode> hostNode, RefPtr<GeometryNode> geometryNode, RefPtr<LayoutProperty> layoutProperty); 63 64 65 void AppendChild(const RefPtr<LayoutWrapperNode>& child, bool isOverlayNode = false); 66 67 SetLayoutWrapperBuilder(const RefPtr<LayoutWrapperBuilder> & builder)68 void SetLayoutWrapperBuilder(const RefPtr<LayoutWrapperBuilder>& builder) 69 { 70 CHECK_NULL_VOID(builder); 71 builder->SetStartIndex(currentChildCount_); 72 currentChildCount_ += builder->GetTotalCount(); 73 layoutWrapperBuilder_ = builder; 74 } 75 SetLayoutAlgorithm(const RefPtr<LayoutAlgorithmWrapper> & layoutAlgorithm)76 void SetLayoutAlgorithm(const RefPtr<LayoutAlgorithmWrapper>& layoutAlgorithm) 77 { 78 layoutAlgorithm_ = layoutAlgorithm; 79 } 80 81 const RefPtr<LayoutAlgorithmWrapper>& GetLayoutAlgorithm(bool needReset = false) override 82 { 83 return layoutAlgorithm_; 84 } 85 86 // This will call child and self measure process. 87 void Measure(const std::optional<LayoutConstraintF>& parentConstraint) override; 88 89 // Called to perform layout children. 90 void Layout() override; 91 GetGeometryNode()92 const RefPtr<GeometryNode>& GetGeometryNode() const override 93 { 94 return geometryNode_; 95 } 96 GetLayoutProperty()97 const RefPtr<LayoutProperty>& GetLayoutProperty() const override 98 { 99 return layoutProperty_; 100 } 101 102 // Calling these two method will mark the node as in use by default, nodes marked as use state will be added to the 103 // render area, and nodes in the render area will be mounted on the render tree after the layout is complete. You 104 // can call the RemoveChildInRenderTree method to explicitly remove the node from the area to be rendered. 105 RefPtr<LayoutWrapper> GetOrCreateChildByIndex(uint32_t index, bool addToRenderTree = true) override; 106 const std::list<RefPtr<LayoutWrapper>>& GetAllChildrenWithBuild(bool addToRenderTree = true) override; GetChildByIndex(uint32_t index)107 RefPtr<LayoutWrapper> GetChildByIndex(uint32_t index) override 108 { 109 return nullptr; 110 } 111 GetTotalChildCount()112 int32_t GetTotalChildCount() const override 113 { 114 return currentChildCount_; 115 } 116 117 std::list<RefPtr<FrameNode>> GetChildrenInRenderArea() const; 118 119 void RemoveChildInRenderTree(uint32_t index) override; 120 void RemoveAllChildInRenderTree() override; 121 122 void ResetHostNode(); 123 124 const std::string& GetHostTag() const override; 125 int32_t GetHostDepth() const; 126 IsActive()127 bool IsActive() const override 128 { 129 return isActive_; 130 } 131 132 void SetActive(bool active = true) override 133 { 134 isActive_ = active; 135 } 136 IsRootMeasureNode()137 bool IsRootMeasureNode() const 138 { 139 return isRootNode_; 140 } 141 SetRootMeasureNode()142 void SetRootMeasureNode() 143 { 144 isRootNode_ = true; 145 } 146 CheckShouldRunOnMain()147 bool CheckShouldRunOnMain() override 148 { 149 return (CanRunOnWhichThread() & MAIN_TASK) == MAIN_TASK; 150 } 151 CanRunOnWhichThread()152 TaskThread CanRunOnWhichThread() 153 { 154 if (layoutWrapperBuilder_) { 155 return MAIN_TASK; 156 } 157 TaskThread taskThread = UNDEFINED_TASK; 158 if (layoutAlgorithm_) { 159 taskThread = taskThread | layoutAlgorithm_->CanRunOnWhichThread(); 160 } 161 if ((taskThread & MAIN_TASK) == MAIN_TASK) { 162 return MAIN_TASK; 163 } 164 for (const auto& child : children_) { 165 taskThread = taskThread | child->CanRunOnWhichThread(); 166 } 167 return taskThread; 168 } 169 170 bool SkipMeasureContent() const override; 171 IsContraintNoChanged()172 bool IsContraintNoChanged() const 173 { 174 return isConstraintNotChanged_; 175 } 176 177 // dirty layoutBox mount to host and switch layoutBox. 178 // Notice: only the cached layoutWrapper (after call GetChildLayoutWrapper) will update the host. 179 void MountToHostOnMainThread(); 180 void SwapDirtyLayoutWrapperOnMainThread(); 181 void SwapDirtyLayoutWrapperOnMainThreadForChild(RefPtr<LayoutWrapperNode> child); 182 IsForceSyncRenderTree()183 bool IsForceSyncRenderTree() const 184 { 185 return needForceSyncRenderTree_; 186 } 187 GetBaselineDistance()188 float GetBaselineDistance() const override 189 { 190 if (children_.empty()) { 191 return geometryNode_->GetBaselineDistance(); 192 } 193 float distance = 0.0; 194 for (const auto& child : children_) { 195 float childBaseline = child->GetBaselineDistance(); 196 distance = NearZero(distance) ? childBaseline : std::min(distance, childBaseline); 197 } 198 return distance; 199 } 200 IsOutOfLayout()201 bool IsOutOfLayout() const override 202 { 203 return outOfLayout_; 204 } 205 SetOutOfLayout(bool outOfLayout)206 void SetOutOfLayout(bool outOfLayout) 207 { 208 outOfLayout_ = outOfLayout; 209 } 210 211 // Check the flag attribute with descendant node 212 bool CheckNeedForceMeasureAndLayout() override; 213 214 bool CheckChildNeedForceMeasureAndLayout(); 215 216 void SetCacheCount( 217 int32_t cacheCount = 0, const std::optional<LayoutConstraintF>& itemConstraint = std::nullopt) override; 218 219 void BuildLazyItem() override; 220 221 std::pair<int32_t, int32_t> GetLazyBuildRange(); 222 void SetLongPredictTask() override; 223 224 private: 225 void LayoutOverlay(); 226 // Used to save a persist wrapper created by child, ifElse, ForEach, the map stores [index, Wrapper]. 227 std::list<RefPtr<LayoutWrapperNode>> children_; 228 // Speed up the speed of getting child by index. 229 std::unordered_map<int32_t, RefPtr<LayoutWrapperNode>> childrenMap_; 230 RefPtr<LayoutWrapperNode> overlayChild_; 231 // cached for GetAllChildrenWithBuild function. 232 std::list<RefPtr<LayoutWrapper>> cachedList_; 233 234 // The Wrapper Created by LazyForEach stores in the LayoutWrapperBuilder object. 235 RefPtr<LayoutWrapperBuilder> layoutWrapperBuilder_; 236 237 RefPtr<GeometryNode> geometryNode_; 238 RefPtr<LayoutProperty> layoutProperty_; 239 RefPtr<LayoutAlgorithmWrapper> layoutAlgorithm_; 240 241 int32_t currentChildCount_ = 0; 242 bool isActive_ = false; 243 bool needForceSyncRenderTree_ = false; 244 bool isRootNode_ = false; 245 std::optional<bool> skipMeasureContent_; 246 std::optional<bool> needForceMeasureAndLayout_; 247 248 LazyBuildFunction lazyBuildFunction_; 249 250 // When the location property is set, it departs from the layout flow. 251 bool outOfLayout_ = false; 252 253 ACE_DISALLOW_COPY_AND_MOVE(LayoutWrapperNode); 254 }; 255 } // namespace OHOS::Ace::NG 256 257 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_LAYOUTS_LAYOUT_WRAPPER_NODE_H 258