• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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