• 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;
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