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 } 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 * @note To deactivate all children, set @c start and @c end to -1 156 */ 157 virtual void SetActiveChildRange(int32_t start, int32_t end, int32_t cacheStart = 0, int32_t cacheEnd = 0) = 0; 158 virtual void SetActiveChildRange(const std::optional<ActiveChildSets>& activeChildSets, 159 const std::optional<ActiveChildRange>& activeChildRange = std::nullopt) 160 {} 161 virtual void RecycleItemsByIndex(int32_t start, int32_t end) = 0; 162 SetActiveChildRange(const std::set<int32_t> & activeIndexes,const std::set<int32_t> & cachedIndexes)163 virtual void SetActiveChildRange(const std::set<int32_t>& activeIndexes, const std::set<int32_t>& cachedIndexes) {} RecycleItemsByIndex(const std::set<int32_t> & indexes)164 virtual void RecycleItemsByIndex(const std::set<int32_t>& indexes) {} 165 166 RefPtr<FrameNode> GetHostNode() const; 167 virtual const std::string& GetHostTag() const = 0; 168 virtual bool IsActive() const = 0; 169 virtual void SetActive(bool active = true, bool needRebuildRenderContext = false) = 0; 170 IsRootMeasureNode()171 bool IsRootMeasureNode() const 172 { 173 return isRootNode_; 174 } 175 176 void SetRootMeasureNode(bool isRoot = true) 177 { 178 isRootNode_ = isRoot; 179 } 180 IsOutOfLayout()181 virtual bool IsOutOfLayout() const 182 { 183 return false; 184 } 185 186 OffsetF GetParentGlobalOffsetWithSafeArea(bool checkBoundary = false, bool checkPosition = false) const; 187 188 virtual bool SkipMeasureContent() const; 189 190 virtual void SetCacheCount( 191 int32_t cacheCount = 0, const std::optional<LayoutConstraintF>& itemConstraint = std::nullopt) = 0; 192 virtual float GetBaselineDistance() const = 0; CheckShouldRunOnMain()193 virtual bool CheckShouldRunOnMain() 194 { 195 return true; 196 } 197 198 virtual bool CheckNeedForceMeasureAndLayout() = 0; 199 SetIsOverlayNode(bool isOverlayNode)200 void SetIsOverlayNode(bool isOverlayNode) 201 { 202 isOverlayNode_ = isOverlayNode; 203 } 204 205 // ------------------------------------------------------------------------ 206 // performance check 207 void AddNodeFlexLayouts(); 208 void AddNodeLayoutTime(int64_t time); 209 // ------------------------------------------------------------------------ 210 BuildLazyItem()211 virtual void BuildLazyItem() {} 212 IsConstraintNoChanged()213 bool IsConstraintNoChanged() const 214 { 215 return isConstraintNotChanged_; 216 } GetConstraintChanges()217 const ConstraintFlags& GetConstraintChanges() const 218 { 219 return constraintChanges_; 220 } GetContentChanges()221 const ConstraintFlags& GetContentChanges() const 222 { 223 return contentConstraintChanges_; 224 } 225 SetLongPredictTask()226 virtual void SetLongPredictTask() {} 227 228 static void ApplySafeArea(const SafeAreaInsets& insets, LayoutConstraintF& constraint); 229 230 // apply keyboard avoidance on content rootNodes 231 bool AvoidKeyboard(bool isFocusOnPage = true); 232 // expand the SafeArea of expansive nodes, which are previously recorded during Layout traversal 233 void ExpandSafeArea(); 234 void AdjustNotExpandNode(); 235 void AdjustFixedSizeNode(RectF& frame); 236 void ExpandHelper(const std::unique_ptr<SafeAreaExpandOpts>& opts, RectF& frame); 237 SkipSyncGeometryNode()238 bool SkipSyncGeometryNode() const 239 { 240 return needSkipSyncGeometryNode_; 241 } 242 243 void SetSkipSyncGeometryNode(bool needSkip = true) 244 { 245 needSkipSyncGeometryNode_ = needSkip; 246 } 247 248 RectF GetFrameRectWithoutSafeArea() const; 249 RectF GetFrameRectWithSafeArea(bool checkPosition = false) const; 250 void AddChildToExpandListIfNeeded(const WeakPtr<FrameNode>& node); 251 void ApplyConstraintWithoutMeasure(const std::optional<LayoutConstraintF>& constraint); 252 253 protected: 254 void CreateRootConstraint(); 255 void ApplyConstraint(LayoutConstraintF constraint); 256 257 void OffsetNodeToSafeArea(); 258 // keyboard avoidance is done by offsetting, to expand into keyboard area, reverse the offset. 259 OffsetF ExpandIntoKeyboard(); 260 bool CheckValidSafeArea(); 261 float GetPageCurrentOffset(); 262 263 WeakPtr<FrameNode> hostNode_; 264 265 ConstraintFlags constraintChanges_; 266 ConstraintFlags contentConstraintChanges_; 267 268 bool isConstraintNotChanged_ = false; 269 bool isRootNode_ = false; 270 bool isOverlayNode_ = false; 271 bool needSkipSyncGeometryNode_ = false; 272 std::optional<bool> skipMeasureContent_; 273 std::optional<bool> needForceMeasureAndLayout_; 274 275 private: 276 void AdjustChildren(const OffsetF& offset, bool parentScrollable); 277 void AdjustChild(RefPtr<UINode> node, const OffsetF& offset, bool parentScrollable); 278 279 ACE_DISALLOW_COPY_AND_MOVE(LayoutWrapper); 280 }; 281 } // namespace OHOS::Ace::NG 282 283 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_LAYOUTS_LAYOUT_WRAPPER_H 284