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 <cstdint>
20 #include <map>
21 #include <optional>
22 #include <set>
23 #include <string>
24 #include <unordered_map>
25 
26 #include "base/memory/referenced.h"
27 #include "base/utils/macros.h"
28 #include "base/utils/noncopyable.h"
29 #include "core/components_ng/base/geometry_node.h"
30 #include "core/components_ng/layout/layout_algorithm.h"
31 #include "core/components_ng/layout/layout_property.h"
32 #include "core/components_ng/layout/layout_wrapper_builder.h"
33 #include "core/components_ng/property/constraint_flags.h"
34 #include "core/components_ng/property/geometry_property.h"
35 #include "core/components_ng/property/layout_constraint.h"
36 #include "core/components_ng/property/magic_layout_property.h"
37 #include "core/components_ng/property/measure_property.h"
38 #include "core/components_ng/property/position_property.h"
39 #include "core/components_ng/property/property.h"
40 #include "core/components_v2/inspector/inspector_constants.h"
41 
42 namespace OHOS::Ace::NG {
43 class FrameNode;
44 
45 class RecursiveLock {
46 public:
Lock()47     virtual void Lock() {}
Unlock()48     virtual void Unlock() {}
49 };
50 
51 class RecursionGuard final {
52 public:
RecursionGuard(RecursiveLock & lock)53     RecursionGuard(RecursiveLock& lock) : lock_(lock)
54     {
55         lock_.Lock();
56     }
~RecursionGuard()57     ~RecursionGuard()
58     {
59         lock_.Unlock();
60     }
RecursionGuard(const RecursionGuard & rhs)61     RecursionGuard(const RecursionGuard& rhs) : lock_(rhs.lock_)
62     {
63         lock_.Lock();
64     }
65 
66 private:
67     RecursiveLock& lock_;
68 };
69 
70 class ChildrenListWithGuard final {
71 public:
ChildrenListWithGuard(const std::list<RefPtr<LayoutWrapper>> & children,RecursiveLock & lock)72     ChildrenListWithGuard(const std::list<RefPtr<LayoutWrapper>>& children, RecursiveLock& lock)
73         : children_(children), guard_(lock)
74     {}
begin()75     auto begin() const
76     {
77         return children_.begin();
78     }
end()79     auto end() const
80     {
81         return children_.end();
82     }
rbegin()83     auto rbegin() const
84     {
85         return children_.rbegin();
86     }
rend()87     auto rend() const
88     {
89         return children_.rend();
90     }
empty()91     auto empty() const
92     {
93         return children_.empty();
94     }
size()95     auto size() const
96     {
97         return children_.size();
98     }
front()99     auto& front() const
100     {
101         return children_.front();
102     }
back()103     auto& back() const
104     {
105         return children_.back();
106     }
list()107     operator std::list<RefPtr<LayoutWrapper>>() const
108     {
109         return children_;
110     }
111 
112 private:
113     const std::list<RefPtr<LayoutWrapper>>& children_;
114     RecursionGuard guard_;
115 };
116 
117 struct ActiveChildRange {
118     int32_t start = -1;
119     int32_t end = -1;
120     int32_t cacheStart = 0;
121     int32_t cacheEnd = 0;
122 };
123 
124 struct ActiveChildSets {
125     std::set<int32_t> activeItems;
126     std::set<int32_t> cachedItems;
127 };
128 
129 class ACE_FORCE_EXPORT LayoutWrapper : public virtual AceType {
DECLARE_ACE_TYPE(LayoutWrapper,AceType)130     DECLARE_ACE_TYPE(LayoutWrapper, AceType)
131 public:
132     LayoutWrapper(WeakPtr<FrameNode> hostNode) : hostNode_(std::move(hostNode)) {}
133     ~LayoutWrapper() override = default;
134 
135     virtual const RefPtr<LayoutAlgorithmWrapper>& GetLayoutAlgorithm(bool needReset = false) = 0;
136     // This will call child and self measure process.
137     virtual void Measure(const std::optional<LayoutConstraintF>& parentConstraint) = 0;
138 
139     // Called to perform layout children.
140     virtual void Layout() = 0;
141 
142     virtual int32_t GetTotalChildCount() const = 0;
143     virtual const RefPtr<GeometryNode>& GetGeometryNode() const = 0;
144     virtual const RefPtr<LayoutProperty>& GetLayoutProperty() const = 0;
145 
146     virtual RefPtr<LayoutWrapper> GetOrCreateChildByIndex(
147         uint32_t index, bool addToRenderTree = true, bool isCache = false) = 0;
148     virtual RefPtr<LayoutWrapper> GetChildByIndex(uint32_t index, bool isCache = false) = 0;
149     virtual ChildrenListWithGuard GetAllChildrenWithBuild(bool addToRenderTree = true) = 0;
150     virtual void RemoveChildInRenderTree(uint32_t index) = 0;
151     virtual void RemoveAllChildInRenderTree() = 0;
152     /**
153      * @param cacheStart number of items to cache before @c start
154      * @param cacheEnd number of items to cache after @c end
155      * @param showCached whether to set cached items as active
156      * @note To deactivate all children, set @c start and @c end to -1
157      */
158     virtual void SetActiveChildRange(
159         int32_t start, int32_t end, int32_t cacheStart = 0, int32_t cacheEnd = 0, bool showCached = false) = 0;
160     virtual void SetActiveChildRange(const std::optional<ActiveChildSets>& activeChildSets,
161         const std::optional<ActiveChildRange>& activeChildRange = std::nullopt)
162     {}
163     virtual void RecycleItemsByIndex(int32_t start, int32_t end) = 0;
164 
SetActiveChildRange(const std::set<int32_t> & activeIndexes,const std::set<int32_t> & cachedIndexes)165     virtual void SetActiveChildRange(const std::set<int32_t>& activeIndexes, const std::set<int32_t>& cachedIndexes) {}
RecycleItemsByIndex(const std::set<int32_t> & indexes)166     virtual void RecycleItemsByIndex(const std::set<int32_t>& indexes) {}
167 
168     RefPtr<FrameNode> GetHostNode() const;
169     virtual const std::string& GetHostTag() const = 0;
170     virtual bool IsActive() const = 0;
171     virtual void SetActive(bool active = true, bool needRebuildRenderContext = false) = 0;
172 
IsRootMeasureNode()173     bool IsRootMeasureNode() const
174     {
175         return isRootNode_;
176     }
177 
178     void SetRootMeasureNode(bool isRoot = true)
179     {
180         isRootNode_ = isRoot;
181     }
182 
IsOutOfLayout()183     virtual bool IsOutOfLayout() const
184     {
185         return false;
186     }
187 
188     OffsetF GetParentGlobalOffsetWithSafeArea(bool checkBoundary = false, bool checkPosition = false) const;
189 
190     virtual bool SkipMeasureContent() const;
191 
192     virtual void SetCacheCount(
193         int32_t cacheCount = 0, const std::optional<LayoutConstraintF>& itemConstraint = std::nullopt) = 0;
194     virtual float GetBaselineDistance() const = 0;
CheckShouldRunOnMain()195     virtual bool CheckShouldRunOnMain()
196     {
197         return true;
198     }
199 
200     virtual bool CheckNeedForceMeasureAndLayout() = 0;
201 
SetIsOverlayNode(bool isOverlayNode)202     void SetIsOverlayNode(bool isOverlayNode)
203     {
204         isOverlayNode_ = isOverlayNode;
205     }
206 
207     // ------------------------------------------------------------------------
208     // performance check
209     void AddNodeFlexLayouts();
210     void AddNodeLayoutTime(int64_t time);
211     // ------------------------------------------------------------------------
212 
BuildLazyItem()213     virtual void BuildLazyItem() {}
214 
IsConstraintNoChanged()215     bool IsConstraintNoChanged() const
216     {
217         return isConstraintNotChanged_;
218     }
GetConstraintChanges()219     const ConstraintFlags& GetConstraintChanges() const
220     {
221         return constraintChanges_;
222     }
GetContentChanges()223     const ConstraintFlags& GetContentChanges() const
224     {
225         return contentConstraintChanges_;
226     }
227 
SetLongPredictTask()228     virtual void SetLongPredictTask() {}
229 
230     static void ApplySafeArea(const SafeAreaInsets& insets, LayoutConstraintF& constraint);
231 
232     // apply keyboard avoidance on content rootNodes
233     bool AvoidKeyboard(bool isFocusOnPage = true);
234     // expand the SafeArea of expansive nodes, which are previously recorded during Layout traversal
235     void ExpandSafeArea();
236     void AdjustNotExpandNode();
237     void AdjustFixedSizeNode(RectF& frame);
238     void ExpandHelper(const std::unique_ptr<SafeAreaExpandOpts>& opts, RectF& frame);
239     ExpandEdges GetAccumulatedSafeAreaExpand(bool includingSelf = false);
240     void ResetSafeAreaPadding();
241 
SkipSyncGeometryNode()242     bool SkipSyncGeometryNode() const
243     {
244         return needSkipSyncGeometryNode_;
245     }
246 
247     void SetSkipSyncGeometryNode(bool needSkip = true)
248     {
249         needSkipSyncGeometryNode_ = needSkip;
250     }
251 
252     RectF GetFrameRectWithoutSafeArea() const;
253     RectF GetFrameRectWithSafeArea(bool checkPosition = false) const;
254     void AddChildToExpandListIfNeeded(const WeakPtr<FrameNode>& node);
255     void ApplyConstraintWithoutMeasure(const std::optional<LayoutConstraintF>& constraint);
256 
257 protected:
258     void CreateRootConstraint();
259     void ApplyConstraint(LayoutConstraintF constraint);
260 
261     void OffsetNodeToSafeArea();
262     // keyboard avoidance is done by offsetting, to expand into keyboard area, reverse the offset.
263     OffsetF ExpandIntoKeyboard();
264     bool CheckValidSafeArea();
265     float GetPageCurrentOffset();
266     bool AccumulateExpandCacheHit(ExpandEdges& totalExpand, const PaddingPropertyF& innerSpace);
267     void GetAccumulatedSafeAreaExpandHelper(RectF& adjustingRect, ExpandEdges& totalExpand, bool fromSelf = false);
268     void ParseSafeAreaPaddingSides(const PaddingPropertyF& parentSafeAreaPadding,
269         const PaddingPropertyF& parentInnerSpace, const RectF& adjustingRect, ExpandEdges& rollingExpand);
270 
271     WeakPtr<FrameNode> hostNode_;
272 
273     ConstraintFlags constraintChanges_;
274     ConstraintFlags contentConstraintChanges_;
275 
276     bool isConstraintNotChanged_ = false;
277     bool isRootNode_ = false;
278     bool isOverlayNode_ = false;
279     bool needSkipSyncGeometryNode_ = false;
280     std::optional<bool> skipMeasureContent_;
281     std::optional<bool> needForceMeasureAndLayout_;
282 
283 private:
284     void AdjustChildren(const OffsetF& offset, bool parentScrollable);
285     void AdjustChild(RefPtr<UINode> node, const OffsetF& offset, bool parentScrollable);
286 
287     ACE_DISALLOW_COPY_AND_MOVE(LayoutWrapper);
288 };
289 } // namespace OHOS::Ace::NG
290 
291 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_LAYOUTS_LAYOUT_WRAPPER_H
292