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; SetActiveChildRange(int32_t start,int32_t end)121 void SetActiveChildRange(int32_t start, int32_t end) override {} 122 123 void ResetHostNode(); 124 125 const std::string& GetHostTag() const override; 126 int32_t GetHostDepth() const; 127 IsActive()128 bool IsActive() const override 129 { 130 return isActive_; 131 } 132 133 void SetActive(bool active = true) override 134 { 135 isActive_ = active; 136 } 137 IsRootMeasureNode()138 bool IsRootMeasureNode() const 139 { 140 return isRootNode_; 141 } 142 SetRootMeasureNode()143 void SetRootMeasureNode() 144 { 145 isRootNode_ = true; 146 } 147 CheckShouldRunOnMain()148 bool CheckShouldRunOnMain() override 149 { 150 return (CanRunOnWhichThread() & MAIN_TASK) == MAIN_TASK; 151 } 152 CanRunOnWhichThread()153 TaskThread CanRunOnWhichThread() 154 { 155 if (layoutWrapperBuilder_) { 156 return MAIN_TASK; 157 } 158 TaskThread taskThread = UNDEFINED_TASK; 159 if (layoutAlgorithm_) { 160 taskThread = taskThread | layoutAlgorithm_->CanRunOnWhichThread(); 161 } 162 if ((taskThread & MAIN_TASK) == MAIN_TASK) { 163 return MAIN_TASK; 164 } 165 for (const auto& child : children_) { 166 taskThread = taskThread | child->CanRunOnWhichThread(); 167 } 168 return taskThread; 169 } 170 171 bool SkipMeasureContent() const override; 172 IsContraintNoChanged()173 bool IsContraintNoChanged() const 174 { 175 return isConstraintNotChanged_; 176 } 177 178 // dirty layoutBox mount to host and switch layoutBox. 179 // Notice: only the cached layoutWrapper (after call GetChildLayoutWrapper) will update the host. 180 void MountToHostOnMainThread(); 181 void SwapDirtyLayoutWrapperOnMainThread(); 182 void SwapDirtyLayoutWrapperOnMainThreadForChild(RefPtr<LayoutWrapperNode> child); 183 IsForceSyncRenderTree()184 bool IsForceSyncRenderTree() const 185 { 186 return needForceSyncRenderTree_; 187 } 188 GetBaselineDistance()189 float GetBaselineDistance() const override 190 { 191 if (children_.empty()) { 192 return geometryNode_->GetBaselineDistance(); 193 } 194 float distance = 0.0; 195 for (const auto& child : children_) { 196 float childBaseline = child->GetBaselineDistance(); 197 distance = NearZero(distance) ? childBaseline : std::min(distance, childBaseline); 198 } 199 return distance; 200 } 201 IsOutOfLayout()202 bool IsOutOfLayout() const override 203 { 204 return outOfLayout_; 205 } 206 SetOutOfLayout(bool outOfLayout)207 void SetOutOfLayout(bool outOfLayout) 208 { 209 outOfLayout_ = outOfLayout; 210 } 211 212 // Check the flag attribute with descendant node 213 bool CheckNeedForceMeasureAndLayout() override; 214 215 bool CheckChildNeedForceMeasureAndLayout(); 216 217 void SetCacheCount( 218 int32_t cacheCount = 0, const std::optional<LayoutConstraintF>& itemConstraint = std::nullopt) override; 219 220 void BuildLazyItem() override; 221 222 std::pair<int32_t, int32_t> GetLazyBuildRange(); 223 void SetLongPredictTask() override; 224 225 private: 226 void LayoutOverlay(); 227 // Used to save a persist wrapper created by child, ifElse, ForEach, the map stores [index, Wrapper]. 228 std::list<RefPtr<LayoutWrapperNode>> children_; 229 // Speed up the speed of getting child by index. 230 std::unordered_map<int32_t, RefPtr<LayoutWrapperNode>> childrenMap_; 231 RefPtr<LayoutWrapperNode> overlayChild_; 232 // cached for GetAllChildrenWithBuild function. 233 std::list<RefPtr<LayoutWrapper>> cachedList_; 234 235 // The Wrapper Created by LazyForEach stores in the LayoutWrapperBuilder object. 236 RefPtr<LayoutWrapperBuilder> layoutWrapperBuilder_; 237 238 RefPtr<GeometryNode> geometryNode_; 239 RefPtr<LayoutProperty> layoutProperty_; 240 RefPtr<LayoutAlgorithmWrapper> layoutAlgorithm_; 241 242 int32_t currentChildCount_ = 0; 243 bool isActive_ = false; 244 bool needForceSyncRenderTree_ = false; 245 bool isRootNode_ = false; 246 std::optional<bool> skipMeasureContent_; 247 std::optional<bool> needForceMeasureAndLayout_; 248 249 LazyBuildFunction lazyBuildFunction_; 250 251 // When the location property is set, it departs from the layout flow. 252 bool outOfLayout_ = false; 253 254 ACE_DISALLOW_COPY_AND_MOVE(LayoutWrapperNode); 255 }; 256 } // namespace OHOS::Ace::NG 257 258 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_LAYOUTS_LAYOUT_WRAPPER_NODE_H 259