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_styles.h" 23 24 namespace OHOS::Ace::NG { 25 26 struct FlexItemProperties { 27 float totalShrink = 0.0f; 28 float totalGrow = 0.0f; 29 RefPtr<LayoutWrapper> lastShrinkChild; 30 RefPtr<LayoutWrapper> lastGrowChild; 31 }; 32 33 struct MagicLayoutNode { 34 LayoutConstraintF layoutConstraint; 35 RefPtr<LayoutWrapper> layoutWrapper; 36 OptionalSizeF calcSize; 37 bool needSecondMeasure = false; 38 bool needKeepMinCalcSize = false; 39 }; 40 41 struct BaselineProperties { 42 float maxBaselineDistance = 0.0f; 43 float maxDistanceAboveBaseline = 0.0f; 44 float maxDistanceBelowBaseline = 0.0f; 45 ResetBaselineProperties46 void Reset() 47 { 48 maxBaselineDistance = 0.0f; 49 maxDistanceAboveBaseline = 0.0f; 50 maxDistanceBelowBaseline = 0.0f; 51 } 52 }; 53 54 class ACE_FORCE_EXPORT FlexLayoutAlgorithm : public LayoutAlgorithm { 55 DECLARE_ACE_TYPE(FlexLayoutAlgorithm, LayoutAlgorithm); 56 57 public: 58 FlexLayoutAlgorithm() = default; 59 ~FlexLayoutAlgorithm() override = default; 60 61 void Measure(LayoutWrapper* layoutWrapper) override; 62 63 void Layout(LayoutWrapper* layoutWrapper) override; 64 SetLinearLayoutFeature()65 void SetLinearLayoutFeature() 66 { 67 isLinearLayoutFeature_ = true; 68 } 69 70 private: 71 void InitFlexProperties(LayoutWrapper* layoutWrapper); 72 void TravelChildrenFlexProps(LayoutWrapper* layoutWrapper); 73 void UpdateAllocatedSize(const RefPtr<LayoutWrapper>& layoutWrapper, float& crossAxisSize); 74 float GetChildMainAxisSize(const RefPtr<LayoutWrapper>& layoutWrapper) const; 75 float GetChildCrossAxisSize(const RefPtr<LayoutWrapper>& layoutWrapper) const; 76 float GetSelfCrossAxisSize(const RefPtr<LayoutWrapper>& layoutWrapper) const; 77 void CheckSizeValidity(const RefPtr<LayoutWrapper>& layoutWrapper); 78 void CheckBaselineProperties(const RefPtr<LayoutWrapper>& layoutWrapper); 79 void CalculateSpace(float remainSpace, float& frontSpace, float& betweenSpace) const; 80 void PlaceChildren( 81 LayoutWrapper* layoutWrapper, float frontSpace, float betweenSpace, const OffsetF& paddingOffset); 82 FlexAlign GetSelfAlign(const RefPtr<LayoutWrapper>& layoutWrapper) const; 83 float GetStretchCrossAxisLimit() const; 84 void MeasureOutOfLayoutChildren(LayoutWrapper* layoutWrapper); 85 void MeasureAdaptiveLayoutChildren(LayoutWrapper* layoutWrapper, const SizeF& realSize); 86 void MeasureAndCleanMagicNodes(LayoutWrapper* containerLayoutWrapper, FlexItemProperties& flexItemProperties); 87 bool HandleBlankFirstTimeMeasure(const MagicLayoutNode& child, FlexItemProperties& flexItemProperties); 88 void UpdateFlexProperties(FlexItemProperties& flexItemProperties, const RefPtr<LayoutWrapper>& layoutWrapper); 89 void SecondaryMeasureByProperty(FlexItemProperties& flexItemProperties, LayoutWrapper* layoutWrapper); 90 void UpdateLayoutConstraintOnMainAxis(LayoutConstraintF& layoutConstraint, float size); 91 void UpdateLayoutConstraintOnCrossAxis(LayoutConstraintF& layoutConstraint, float size); 92 void AdjustTotalAllocatedSize(LayoutWrapper* layoutWrapper); 93 void CheckIsGrowOrShrink(std::function<float(const RefPtr<LayoutWrapper>&)>& getFlex, float remainSpace, 94 float& spacePerFlex, FlexItemProperties& flexItemProperties, RefPtr<LayoutWrapper>& lastChild); 95 void CheckBlankAndKeepMin(const RefPtr<LayoutWrapper>& childLayoutWrapper, float& flexSize); 96 float MainAxisMinValue(LayoutWrapper* layoutWrapper); 97 bool MarginOnMainAxisNegative(LayoutWrapper* layoutWrapper); 98 bool IsKeepMinSize(const RefPtr<LayoutWrapper>& childLayoutWrapper, float& flexSize); 99 bool CheckSetConstraint(const std::unique_ptr<MeasureProperty>& propertyPtr); 100 void CheckMainAxisSizeAuto(const std::unique_ptr<MeasureProperty>& calcLayoutConstraint); 101 102 void SetInitMainAxisSize(LayoutWrapper* layoutWrapper); 103 void SetFinalRealSize(LayoutWrapper* layoutWrapper, SizeF& realSize); 104 void SetCrossPos(const RefPtr<LayoutWrapper>& layoutWrapper, float& crossPos); 105 void AddElementIntoMagicNodes(int32_t childDisplayPriority, MagicLayoutNode node, float childLayoutWeight); 106 bool AddElementIntoLayoutPolicyChildren(LayoutWrapper* layoutWrapper, RefPtr<LayoutWrapper> child); 107 std::map<int32_t, std::list<MagicLayoutNode>>::reverse_iterator FirstMeasureInWeightMode(); 108 void SecondMeasureInWeightMode(std::map<int32_t, std::list<MagicLayoutNode>>::reverse_iterator firstLoopIter); 109 void FinalMeasureInWeightMode(); 110 void MeasureInPriorityMode(FlexItemProperties& flexItemProperties); 111 void SecondMeasureInGrowOrShrink(); 112 113 OptionalSizeF realSize_; 114 float mainAxisSize_ = 0.0f; 115 float crossAxisSize_ = 0.0f; 116 float selfIdealCrossAxisSize_ = -1.0f; 117 float allocatedSize_ = 0.0f; 118 float space_ = 0.0f; 119 float totalFlexWeight_ = 0.0f; 120 int32_t maxDisplayPriority_ = 0; 121 int32_t validSizeCount_ = 0; 122 FlexAlign crossAxisAlign_ = FlexAlign::FLEX_START; 123 FlexAlign mainAxisAlign_ = FlexAlign::FLEX_START; 124 125 std::map<int32_t, std::list<MagicLayoutNode>> magicNodes_; 126 std::map<int32_t, float> magicNodeWeights_; 127 std::list<MagicLayoutNode> secondaryMeasureList_; 128 std::list<RefPtr<LayoutWrapper>> outOfLayoutChildren_; 129 std::list<RefPtr<LayoutWrapper>> layoutPolicyChildren_; 130 131 FlexDirection direction_ = FlexDirection::ROW; 132 friend class LinearLayoutUtils; 133 BaselineProperties baselineProperties_; 134 bool isLinearLayoutFeature_ = false; 135 bool isInfiniteLayout_ = false; 136 bool selfAdaptive_ = false; 137 TextDirection textDir_ = TextDirection::LTR; 138 bool childrenHasAlignSelfBaseLine_ = false; 139 140 ACE_DISALLOW_COPY_AND_MOVE(FlexLayoutAlgorithm); 141 }; 142 } // namespace OHOS::Ace::NG 143 144 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_ALGORITHM_H 145