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