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 void InitFlexProperties(LayoutWrapper* layoutWrapper); 73 void TravelChildrenFlexProps(LayoutWrapper* layoutWrapper); 74 void UpdateAllocatedSize(const RefPtr<LayoutWrapper>& layoutWrapper, float& crossAxisSize); 75 float GetChildMainAxisSize(const RefPtr<LayoutWrapper>& layoutWrapper) const; 76 float GetChildCrossAxisSize(const RefPtr<LayoutWrapper>& layoutWrapper) const; 77 float GetSelfCrossAxisSize(const RefPtr<LayoutWrapper>& layoutWrapper) const; 78 void CheckSizeValidity(const RefPtr<LayoutWrapper>& layoutWrapper); 79 void CheckBaselineProperties(const RefPtr<LayoutWrapper>& layoutWrapper); 80 void CalculateSpace(float remainSpace, float& frontSpace, float& betweenSpace) const; 81 void PlaceChildren( 82 LayoutWrapper* layoutWrapper, float frontSpace, float betweenSpace, const OffsetF& paddingOffset); 83 FlexAlign GetSelfAlign(const RefPtr<LayoutWrapper>& layoutWrapper) const; 84 float GetStretchCrossAxisLimit() const; 85 void MeasureOutOfLayoutChildren(LayoutWrapper* layoutWrapper); 86 void MeasureAdaptiveLayoutChildren(LayoutWrapper* layoutWrapper, const SizeF& realSize); 87 void MeasureAndCleanMagicNodes(LayoutWrapper* containerLayoutWrapper, FlexItemProperties& flexItemProperties); 88 bool HandleBlankFirstTimeMeasure(const MagicLayoutNode& child, FlexItemProperties& flexItemProperties); 89 void UpdateFlexProperties(FlexItemProperties& flexItemProperties, const RefPtr<LayoutWrapper>& layoutWrapper); 90 void SecondaryMeasureByProperty(FlexItemProperties& flexItemProperties, LayoutWrapper* layoutWrapper); 91 void UpdateLayoutConstraintOnMainAxis(LayoutConstraintF& layoutConstraint, float size); 92 void UpdateLayoutConstraintOnCrossAxis(LayoutConstraintF& layoutConstraint, float size); 93 void AdjustTotalAllocatedSize(LayoutWrapper* layoutWrapper); 94 void CheckIsGrowOrShrink(std::function<float(const RefPtr<LayoutWrapper>&)>& getFlex, float remainSpace, 95 float& spacePerFlex, FlexItemProperties& flexItemProperties, RefPtr<LayoutWrapper>& lastChild); 96 void CheckBlankAndKeepMin(const RefPtr<LayoutWrapper>& childLayoutWrapper, float& flexSize); 97 float MainAxisMinValue(LayoutWrapper* layoutWrapper); 98 bool MarginOnMainAxisNegative(LayoutWrapper* layoutWrapper); 99 bool IsKeepMinSize(const RefPtr<LayoutWrapper>& childLayoutWrapper, float& flexSize); 100 bool CheckSetConstraint(const std::unique_ptr<MeasureProperty>& propertyPtr); 101 void CheckMainAxisSizeAuto(const std::unique_ptr<MeasureProperty>& calcLayoutConstraint); 102 void ApplyPatternOperation(LayoutWrapper* layoutWrapper, FlexOperatorType operation, uintptr_t addr = 0, 103 FlexLayoutResult layoutResult = {}); 104 void SetInitMainAxisSize(LayoutWrapper* layoutWrapper); 105 void SetFinalRealSize(LayoutWrapper* layoutWrapper, SizeF& realSize); 106 void SetCrossPos(const RefPtr<LayoutWrapper>& layoutWrapper, float& crossPos); 107 void AddElementIntoMagicNodes(int32_t childDisplayPriority, MagicLayoutNode node, float childLayoutWeight); 108 bool AddElementIntoLayoutPolicyChildren(LayoutWrapper* layoutWrapper, RefPtr<LayoutWrapper> child); 109 std::map<int32_t, std::list<MagicLayoutNode>>::reverse_iterator FirstMeasureInWeightMode(); 110 void SecondMeasureInWeightMode(std::map<int32_t, std::list<MagicLayoutNode>>::reverse_iterator firstLoopIter); 111 void FinalMeasureInWeightMode(); 112 void MeasureInPriorityMode(FlexItemProperties& flexItemProperties); 113 void SecondMeasureInGrowOrShrink(); 114 void PopOutOfDispayMagicNodesInPriorityMode(const std::list<MagicLayoutNode>& childList, 115 FlexItemProperties& flexItemProperties); 116 117 template<typename T> PatternOperator(T pattern,FlexOperatorType operation,FlexMeasureResult & measureResult,FlexLayoutResult layoutResult,uintptr_t addr)118 void PatternOperator(T pattern, FlexOperatorType operation, FlexMeasureResult& measureResult, 119 FlexLayoutResult layoutResult, uintptr_t addr) 120 { 121 switch (operation) { 122 case FlexOperatorType::RESTORE_MEASURE_RESULT: 123 measureResult = pattern->GetFlexMeasureResult(); 124 break; 125 case FlexOperatorType::UPDATE_MEASURE_RESULT: 126 pattern->SetFlexMeasureResult( 127 { .allocatedSize = allocatedSize_, .validSizeCount = validSizeCount_ }, addr); 128 break; 129 case FlexOperatorType::UPDATE_LAYOUT_RESULT: 130 pattern->SetFlexLayoutResult(layoutResult, addr); 131 break; 132 default: 133 break; 134 } 135 } 136 137 OptionalSizeF realSize_; 138 float mainAxisSize_ = 0.0f; 139 float crossAxisSize_ = 0.0f; 140 float selfIdealCrossAxisSize_ = -1.0f; 141 float allocatedSize_ = 0.0f; 142 float space_ = 0.0f; 143 float totalFlexWeight_ = 0.0f; 144 int32_t maxDisplayPriority_ = 0; 145 int32_t validSizeCount_ = 0; 146 FlexAlign crossAxisAlign_ = FlexAlign::FLEX_START; 147 FlexAlign mainAxisAlign_ = FlexAlign::FLEX_START; 148 149 std::map<int32_t, std::list<MagicLayoutNode>> magicNodes_; 150 std::map<int32_t, float> magicNodeWeights_; 151 std::list<MagicLayoutNode> secondaryMeasureList_; 152 std::list<RefPtr<LayoutWrapper>> outOfLayoutChildren_; 153 std::list<RefPtr<LayoutWrapper>> layoutPolicyChildren_; 154 155 FlexDirection direction_ = FlexDirection::ROW; 156 friend class LinearLayoutUtils; 157 BaselineProperties baselineProperties_; 158 bool isLinearLayoutFeature_ = false; 159 bool isInfiniteLayout_ = false; 160 bool selfAdaptive_ = false; 161 TextDirection textDir_ = TextDirection::LTR; 162 bool childrenHasAlignSelfBaseLine_ = false; 163 164 ACE_DISALLOW_COPY_AND_MOVE(FlexLayoutAlgorithm); 165 }; 166 } // namespace OHOS::Ace::NG 167 168 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_ALGORITHM_H 169