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 void AppendChild(const RefPtr<LayoutWrapperNode>& child, bool isOverlayNode = false); 65 SetLayoutWrapperBuilder(const RefPtr<LayoutWrapperBuilder> & builder)66 void SetLayoutWrapperBuilder(const RefPtr<LayoutWrapperBuilder>& builder) 67 { 68 CHECK_NULL_VOID(builder); 69 builder->SetStartIndex(currentChildCount_); 70 currentChildCount_ += builder->GetTotalCount(); 71 layoutWrapperBuilder_ = builder; 72 } 73 SetLayoutAlgorithm(const RefPtr<LayoutAlgorithmWrapper> & layoutAlgorithm)74 void SetLayoutAlgorithm(const RefPtr<LayoutAlgorithmWrapper>& layoutAlgorithm) 75 { 76 layoutAlgorithm_ = layoutAlgorithm; 77 } 78 79 const RefPtr<LayoutAlgorithmWrapper>& GetLayoutAlgorithm(bool needReset = false) override 80 { 81 return layoutAlgorithm_; 82 } 83 84 // This will call child and self measure process. 85 void Measure(const std::optional<LayoutConstraintF>& parentConstraint) override; 86 87 // Called to perform layout children. 88 void Layout() override; 89 GetGeometryNode()90 const RefPtr<GeometryNode>& GetGeometryNode() const override 91 { 92 return geometryNode_; 93 } 94 GetLayoutProperty()95 const RefPtr<LayoutProperty>& GetLayoutProperty() const override 96 { 97 return layoutProperty_; 98 } 99 100 // Calling these two method will mark the node as in use by default, nodes marked as use state will be added to the 101 // render area, and nodes in the render area will be mounted on the render tree after the layout is complete. You 102 // can call the RemoveChildInRenderTree method to explicitly remove the node from the area to be rendered. 103 RefPtr<LayoutWrapper> GetOrCreateChildByIndex( 104 uint32_t index, bool addToRenderTree = true, bool isCache = false) override; 105 ChildrenListWithGuard GetAllChildrenWithBuild(bool addToRenderTree = true) override; 106 RefPtr<LayoutWrapper> GetChildByIndex(uint32_t index, bool isCache = false) override 107 { 108 return nullptr; 109 } 110 GetTotalChildCount()111 int32_t GetTotalChildCount() const override 112 { 113 return currentChildCount_; 114 } 115 116 std::list<RefPtr<FrameNode>> GetChildrenInRenderArea() const; 117 118 void RemoveChildInRenderTree(uint32_t index) override; 119 void RemoveAllChildInRenderTree() override; 120 void SetActiveChildRange( 121 int32_t start, int32_t end, int32_t cacheStart = 0, int32_t cacheEnd = 0, bool showCached = false) override 122 {} RecycleItemsByIndex(int32_t start,int32_t end)123 void RecycleItemsByIndex(int32_t start, int32_t end) override {} 124 125 void ResetHostNode(); 126 127 const std::string& GetHostTag() const override; 128 int32_t GetHostDepth() const; 129 IsActive()130 bool IsActive() const override 131 { 132 return isActive_; 133 } 134 135 void SetActive(bool active = true, bool needRebuildRenderContext = false) override 136 { 137 isActive_ = active; 138 } 139 IsRootMeasureNode()140 bool IsRootMeasureNode() const 141 { 142 return isRootNode_; 143 } 144 SetRootMeasureNode()145 void SetRootMeasureNode() 146 { 147 isRootNode_ = true; 148 } 149 CheckShouldRunOnMain()150 bool CheckShouldRunOnMain() override 151 { 152 return (CanRunOnWhichThread() & MAIN_TASK) == MAIN_TASK; 153 } 154 CanRunOnWhichThread()155 TaskThread CanRunOnWhichThread() 156 { 157 if (layoutWrapperBuilder_) { 158 return MAIN_TASK; 159 } 160 TaskThread taskThread = UNDEFINED_TASK; 161 if (layoutAlgorithm_) { 162 taskThread = taskThread | layoutAlgorithm_->CanRunOnWhichThread(); 163 } 164 if ((taskThread & MAIN_TASK) == MAIN_TASK) { 165 return MAIN_TASK; 166 } 167 for (const auto& child : children_) { 168 taskThread = taskThread | child->CanRunOnWhichThread(); 169 } 170 return taskThread; 171 } 172 173 bool SkipMeasureContent() const override; 174 IsConstraintNoChanged()175 bool IsConstraintNoChanged() const 176 { 177 return isConstraintNotChanged_; 178 } 179 180 // dirty layoutBox mount to host and switch layoutBox. 181 // Notice: only the cached layoutWrapper (after call GetChildLayoutWrapper) will update the host. 182 void MountToHostOnMainThread(); 183 void SwapDirtyLayoutWrapperOnMainThread(); 184 void SwapDirtyLayoutWrapperOnMainThreadForChild(RefPtr<LayoutWrapperNode> child); 185 IsForceSyncRenderTree()186 bool IsForceSyncRenderTree() const 187 { 188 return needForceSyncRenderTree_; 189 } 190 GetBaselineDistance()191 float GetBaselineDistance() const override 192 { 193 if (children_.empty()) { 194 return geometryNode_->GetBaselineDistance(); 195 } 196 float distance = 0.0; 197 for (const auto& child : children_) { 198 float childBaseline = child->GetBaselineDistance(); 199 distance = NearZero(distance) ? childBaseline : std::min(distance, childBaseline); 200 } 201 return distance; 202 } 203 IsOutOfLayout()204 bool IsOutOfLayout() const override 205 { 206 return outOfLayout_; 207 } 208 SetOutOfLayout(bool outOfLayout)209 void SetOutOfLayout(bool outOfLayout) 210 { 211 outOfLayout_ = outOfLayout; 212 } 213 214 // Check the flag attribute with descendant node 215 bool CheckNeedForceMeasureAndLayout() override; 216 217 bool CheckChildNeedForceMeasureAndLayout(); 218 219 void SetCacheCount( 220 int32_t cacheCount = 0, const std::optional<LayoutConstraintF>& itemConstraint = std::nullopt) override; 221 222 void BuildLazyItem() override; 223 224 std::pair<int32_t, int32_t> GetLazyBuildRange(); 225 void SetLongPredictTask() override; 226 227 private: 228 void Build(bool addToRenderTree); 229 void LayoutOverlay(); 230 // Used to save a persist wrapper created by child, ifElse, ForEach, the map stores [index, Wrapper]. 231 std::list<RefPtr<LayoutWrapperNode>> children_; 232 // Speed up the speed of getting child by index. 233 std::unordered_map<int32_t, RefPtr<LayoutWrapperNode>> childrenMap_; 234 RefPtr<LayoutWrapperNode> overlayChild_; 235 // cached for GetAllChildrenWithBuild function. 236 std::list<RefPtr<LayoutWrapper>> cachedList_; 237 238 // The Wrapper Created by LazyForEach stores in the LayoutWrapperBuilder object. 239 RefPtr<LayoutWrapperBuilder> layoutWrapperBuilder_; 240 241 RefPtr<GeometryNode> geometryNode_; 242 RefPtr<LayoutProperty> layoutProperty_; 243 RefPtr<LayoutAlgorithmWrapper> layoutAlgorithm_; 244 245 int32_t currentChildCount_ = 0; 246 bool isActive_ = false; 247 bool needForceSyncRenderTree_ = false; 248 bool isRootNode_ = false; 249 std::optional<bool> skipMeasureContent_; 250 std::optional<bool> needForceMeasureAndLayout_; 251 252 LazyBuildFunction lazyBuildFunction_; 253 254 // When the location property is set, it departs from the layout flow. 255 bool outOfLayout_ = false; 256 257 ACE_DISALLOW_COPY_AND_MOVE(LayoutWrapperNode); 258 }; 259 } // namespace OHOS::Ace::NG 260 261 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_LAYOUTS_LAYOUT_WRAPPER_NODE_H 262