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_wrapper_builder.h" 32 #include "core/components_ng/property/constraint_flags.h" 33 #include "core/components_ng/property/layout_constraint.h" 34 35 namespace OHOS::Ace::NG { 36 class FrameNode; 37 class UINode; 38 class LayoutProperty; 39 struct SafeAreaInsets; 40 struct SafeAreaExpandOpts; 41 42 class RecursiveLock { 43 public: Lock()44 virtual void Lock() {} Unlock()45 virtual void Unlock() {} 46 }; 47 48 class RecursionGuard final { 49 public: RecursionGuard(RecursiveLock & lock)50 RecursionGuard(RecursiveLock& lock) : lock_(lock) 51 { 52 lock_.Lock(); 53 } ~RecursionGuard()54 ~RecursionGuard() 55 { 56 lock_.Unlock(); 57 } RecursionGuard(const RecursionGuard & rhs)58 RecursionGuard(const RecursionGuard& rhs) : lock_(rhs.lock_) 59 { 60 lock_.Lock(); 61 } 62 63 private: 64 RecursiveLock& lock_; 65 }; 66 67 class ChildrenListWithGuard final { 68 public: ChildrenListWithGuard(const std::list<RefPtr<LayoutWrapper>> & children,RecursiveLock & lock)69 ChildrenListWithGuard(const std::list<RefPtr<LayoutWrapper>>& children, RecursiveLock& lock) 70 : children_(children), guard_(lock) 71 {} begin()72 auto begin() const 73 { 74 return children_.begin(); 75 } end()76 auto end() const 77 { 78 return children_.end(); 79 } rbegin()80 auto rbegin() const 81 { 82 return children_.rbegin(); 83 } rend()84 auto rend() const 85 { 86 return children_.rend(); 87 } empty()88 auto empty() const 89 { 90 return children_.empty(); 91 } size()92 auto size() const 93 { 94 return children_.size(); 95 } front()96 auto& front() const 97 { 98 return children_.front(); 99 } back()100 auto& back() const 101 { 102 return children_.back(); 103 } 104 operator std::list<RefPtr<LayoutWrapper>>() const 105 { 106 return children_; 107 } 108 109 private: 110 const std::list<RefPtr<LayoutWrapper>>& children_; 111 RecursionGuard guard_; 112 }; 113 114 struct ActiveChildRange { 115 int32_t start = -1; 116 int32_t end = -1; 117 int32_t cacheStart = 0; 118 int32_t cacheEnd = 0; 119 }; 120 121 struct ActiveChildSets { 122 std::set<int32_t> activeItems; 123 std::set<int32_t> cachedItems; 124 }; 125 126 class ACE_FORCE_EXPORT LayoutWrapper : public virtual AceType { DECLARE_ACE_TYPE(LayoutWrapper,AceType)127 DECLARE_ACE_TYPE(LayoutWrapper, AceType) 128 public: 129 LayoutWrapper(WeakPtr<FrameNode> hostNode) : hostNode_(std::move(hostNode)) {} 130 ~LayoutWrapper() override = default; 131 132 virtual const RefPtr<LayoutAlgorithmWrapper>& GetLayoutAlgorithm(bool needReset = false) = 0; 133 // This will call child and self measure process. 134 virtual void Measure(const std::optional<LayoutConstraintF>& parentConstraint) = 0; 135 136 // Called to perform layout children. 137 virtual void Layout() = 0; 138 139 virtual int32_t GetTotalChildCount() const = 0; 140 virtual const RefPtr<GeometryNode>& GetGeometryNode() const = 0; 141 virtual const RefPtr<LayoutProperty>& GetLayoutProperty() const = 0; 142 143 virtual RefPtr<LayoutWrapper> GetOrCreateChildByIndex( 144 uint32_t index, bool addToRenderTree = true, bool isCache = false) = 0; 145 /** 146 * @param isCache if false, child is added to render tree and AttachToMainTree is called. 147 */ 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 ConstraintChanged()215 bool ConstraintChanged() 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