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_PATTERN_FLEX_FLEX_LAYOUT_ALGORITHM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_ALGORITHM_H 18 19 #include "core/components/common/layout/constants.h" 20 #include "core/components_ng/layout/layout_algorithm.h" 21 #include "core/components_ng/layout/layout_wrapper.h" 22 #include "core/components_ng/pattern/flex/flex_layout_property.h" 23 #include "core/components_ng/pattern/flex/flex_layout_styles.h" 24 25 namespace OHOS::Ace::NG { 26 27 struct FlexItemProperties { 28 float totalShrink = 0.0f; 29 float totalGrow = 0.0f; 30 RefPtr<LayoutWrapper> lastShrinkChild; 31 RefPtr<LayoutWrapper> lastGrowChild; 32 }; 33 34 struct MagicLayoutNode { 35 LayoutConstraintF layoutConstraint; 36 RefPtr<LayoutWrapper> layoutWrapper; 37 OptionalSizeF calcSize; 38 bool needSecondMeasure = false; 39 bool needKeepMinCalcSize = false; 40 }; 41 42 struct BaselineProperties { 43 float maxBaselineDistance = 0.0f; 44 float maxDistanceAboveBaseline = 0.0f; 45 float maxDistanceBelowBaseline = 0.0f; 46 ResetBaselineProperties47 void Reset() 48 { 49 maxBaselineDistance = 0.0f; 50 maxDistanceAboveBaseline = 0.0f; 51 maxDistanceBelowBaseline = 0.0f; 52 } 53 }; 54 55 class ACE_FORCE_EXPORT FlexLayoutAlgorithm : public LayoutAlgorithm { 56 DECLARE_ACE_TYPE(FlexLayoutAlgorithm, LayoutAlgorithm); 57 58 public: 59 FlexLayoutAlgorithm() = default; 60 ~FlexLayoutAlgorithm() override = default; 61 62 void Measure(LayoutWrapper* layoutWrapper) override; 63 64 void Layout(LayoutWrapper* layoutWrapper) override; 65 SetLinearLayoutFeature()66 void SetLinearLayoutFeature() 67 { 68 isLinearLayoutFeature_ = true; 69 } 70 71 private: 72 float UpdateChildPositionWidthIgnoreLayoutSafeArea(const RefPtr<FrameNode>& host, 73 const RefPtr<LayoutWrapper>& childLayoutWrapper, const OffsetF& originOffset, const OffsetF& paddingOffset, 74 bool needExpandMainAxis); 75 void InitFlexProperties(LayoutWrapper* layoutWrapper); 76 void TravelChildrenFlexProps(LayoutWrapper* layoutWrapper); 77 void UpdateAllocatedSize(const RefPtr<LayoutWrapper>& layoutWrapper, float& crossAxisSize); 78 float GetChildMainAxisSize(const RefPtr<LayoutWrapper>& layoutWrapper) const; 79 float GetChildCrossAxisSize(const RefPtr<LayoutWrapper>& layoutWrapper) const; 80 float GetSelfCrossAxisSize(const RefPtr<LayoutWrapper>& layoutWrapper) const; 81 void CheckSizeValidity(const RefPtr<LayoutWrapper>& layoutWrapper); 82 void CheckBaselineProperties(const RefPtr<LayoutWrapper>& layoutWrapper); 83 void CalculateSpace(float remainSpace, float& frontSpace, float& betweenSpace) const; 84 void PlaceChildren( 85 LayoutWrapper* layoutWrapper, float frontSpace, float betweenSpace, const OffsetF& paddingOffset); 86 FlexAlign GetSelfAlign(const RefPtr<LayoutWrapper>& layoutWrapper) const; 87 float GetStretchCrossAxisLimit() const; 88 void MeasureOutOfLayoutChildren(LayoutWrapper* layoutWrapper); 89 void MeasureAdaptiveLayoutChildren(LayoutWrapper* layoutWrapper, SizeF& realSize); 90 void MeasureAndCleanMagicNodes(LayoutWrapper* containerLayoutWrapper, FlexItemProperties& flexItemProperties); 91 bool HandleBlankFirstTimeMeasure(const MagicLayoutNode& child, FlexItemProperties& flexItemProperties); 92 bool CheckBlankIllegality(const RefPtr<LayoutProperty>& blankLayoutProperty); 93 void UpdateFlexProperties(FlexItemProperties& flexItemProperties, const RefPtr<LayoutWrapper>& layoutWrapper); 94 void SecondaryMeasureByProperty(FlexItemProperties& flexItemProperties, LayoutWrapper* layoutWrapper); 95 void UpdateLayoutConstraintOnMainAxis(LayoutConstraintF& layoutConstraint, float size); 96 void UpdateLayoutConstraintOnCrossAxis(LayoutConstraintF& layoutConstraint, float size); 97 void AdjustTotalAllocatedSize(LayoutWrapper* layoutWrapper, bool includeLayoutPolicyChildren = false); 98 void CheckIsGrowOrShrink(std::function<float(const RefPtr<LayoutWrapper>&)>& getFlex, float remainSpace, 99 float& spacePerFlex, FlexItemProperties& flexItemProperties, RefPtr<LayoutWrapper>& lastChild); 100 void CheckBlankAndKeepMin(const RefPtr<LayoutWrapper>& childLayoutWrapper, float& flexSize); 101 float MainAxisMinValue(LayoutWrapper* layoutWrapper); 102 bool MarginOnMainAxisNegative(LayoutWrapper* layoutWrapper); 103 bool IsKeepMinSize(const RefPtr<LayoutWrapper>& childLayoutWrapper, float& flexSize); 104 bool CheckSetConstraint(const std::unique_ptr<MeasureProperty>& propertyPtr); 105 void CheckMainAxisSizeAuto( 106 LayoutWrapper* layoutWrapper, const std::unique_ptr<MeasureProperty>& calcLayoutConstraint); 107 void ApplyPatternOperation(LayoutWrapper* layoutWrapper, FlexOperatorType operation, uintptr_t addr = 0, 108 FlexLayoutResult layoutResult = {}); 109 void SetInitMainAxisSize(LayoutWrapper* layoutWrapper); 110 void SetFinalRealSize( 111 LayoutWrapper* layoutWrapper, SizeF& realSize, std::optional<NG::LayoutPolicyProperty> layoutPolicy); 112 void SetCrossPos(const RefPtr<LayoutWrapper>& layoutWrapper, float& crossPos, const float& crossAxisSize); 113 void AddElementIntoMagicNodes(int32_t childDisplayPriority, MagicLayoutNode node, float childLayoutWeight); 114 bool AddElementIntoLayoutPolicyChildren(LayoutWrapper* layoutWrapper, RefPtr<LayoutWrapper> child); 115 std::map<int32_t, std::list<MagicLayoutNode>>::reverse_iterator FirstMeasureInWeightMode(); 116 void SecondMeasureInWeightMode(std::map<int32_t, std::list<MagicLayoutNode>>::reverse_iterator firstLoopIter); 117 void FinalMeasureInWeightMode(); 118 void MeasureInPriorityMode(FlexItemProperties& flexItemProperties); 119 void SecondMeasureInGrowOrShrink(); 120 void PopOutOfDispayMagicNodesInPriorityMode( 121 const std::list<MagicLayoutNode>& childList, FlexItemProperties& flexItemProperties); 122 void CalcMainExpand( 123 const ExpandEdges& mainExpand, ExpandEdges& sae, bool isHorizontal, bool isExpandConstraintNeeded); 124 bool CheckReCalcMainExpand(const FlexAlign& crossAlign); 125 126 template<typename T> PatternOperator(T pattern,FlexOperatorType operation,FlexMeasureResult & measureResult,FlexLayoutResult layoutResult,uintptr_t addr)127 void PatternOperator(T pattern, FlexOperatorType operation, FlexMeasureResult& measureResult, 128 FlexLayoutResult layoutResult, uintptr_t addr) 129 { 130 switch (operation) { 131 case FlexOperatorType::RESTORE_MEASURE_RESULT: 132 measureResult = pattern->GetFlexMeasureResult(); 133 break; 134 case FlexOperatorType::UPDATE_MEASURE_RESULT: 135 pattern->SetFlexMeasureResult( 136 { .allocatedSize = allocatedSize_, .validSizeCount = validSizeCount_ }, addr); 137 break; 138 case FlexOperatorType::UPDATE_LAYOUT_RESULT: 139 pattern->SetFlexLayoutResult(layoutResult, addr); 140 break; 141 default: 142 break; 143 } 144 } 145 146 OptionalSizeF realSize_; 147 float mainAxisSize_ = 0.0f; 148 float crossAxisSize_ = 0.0f; 149 float selfIdealCrossAxisSize_ = -1.0f; 150 float allocatedSize_ = 0.0f; 151 float space_ = 0.0f; 152 float totalFlexWeight_ = 0.0f; 153 int32_t maxDisplayPriority_ = 0; 154 int32_t validSizeCount_ = 0; 155 FlexAlign crossAxisAlign_ = FlexAlign::FLEX_START; 156 FlexAlign mainAxisAlign_ = FlexAlign::FLEX_START; 157 158 std::map<int32_t, std::list<MagicLayoutNode>> magicNodes_; 159 std::map<int32_t, float> magicNodeWeights_; 160 std::list<MagicLayoutNode> secondaryMeasureList_; 161 std::list<RefPtr<LayoutWrapper>> outOfLayoutChildren_; 162 std::list<RefPtr<LayoutWrapper>> layoutPolicyChildren_; 163 164 FlexDirection direction_ = FlexDirection::ROW; 165 friend class LinearLayoutUtils; 166 BaselineProperties baselineProperties_; 167 bool isLinearLayoutFeature_ = false; 168 bool isInfiniteLayout_ = false; 169 bool selfAdaptive_ = false; 170 TextDirection textDir_ = TextDirection::LTR; 171 bool childrenHasAlignSelfBaseLine_ = false; 172 173 ACE_DISALLOW_COPY_AND_MOVE(FlexLayoutAlgorithm); 174 }; 175 } // namespace OHOS::Ace::NG 176 177 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_ALGORITHM_H 178