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