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, const SizeF& realSize); 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 MeasureAndCleanMagicNodes(LayoutWrapper* containerLayoutWrapper, FlexItemProperties& flexItemProperties); 86 bool HandleBlankFirstTimeMeasure(const MagicLayoutNode& child, FlexItemProperties& flexItemProperties); 87 void UpdateFlexProperties(FlexItemProperties& flexItemProperties, const RefPtr<LayoutWrapper>& layoutWrapper); 88 void SecondaryMeasureByProperty(FlexItemProperties& flexItemProperties, LayoutWrapper* layoutWrapper); 89 void UpdateLayoutConstraintOnMainAxis(LayoutConstraintF& layoutConstraint, float size); 90 void UpdateLayoutConstraintOnCrossAxis(LayoutConstraintF& layoutConstraint, float size); 91 void AdjustTotalAllocatedSize(LayoutWrapper* layoutWrapper); 92 void CheckIsGrowOrShrink(std::function<float(const RefPtr<LayoutWrapper>&)>& getFlex, float remainSpace, 93 float& spacePerFlex, FlexItemProperties& flexItemProperties, RefPtr<LayoutWrapper>& lastChild); 94 void CheckBlankAndKeepMin(const RefPtr<LayoutWrapper>& childLayoutWrapper, float& flexSize); 95 float MainAxisMinValue(LayoutWrapper* layoutWrapper); 96 bool MarginOnMainAxisNegative(LayoutWrapper* layoutWrapper); 97 bool IsKeepMinSize(const RefPtr<LayoutWrapper>& childLayoutWrapper, float& flexSize); 98 bool CheckSetConstraint(const std::unique_ptr<MeasureProperty>& propertyPtr); 99 void CheckMainAxisSizeAuto(const std::unique_ptr<MeasureProperty>& calcLayoutConstraint); 100 101 OptionalSizeF realSize_; 102 float mainAxisSize_ = 0.0f; 103 float crossAxisSize_ = 0.0f; 104 float selfIdealCrossAxisSize_ = -1.0f; 105 float allocatedSize_ = 0.0f; 106 float space_ = 0.0f; 107 float totalFlexWeight_ = 0.0f; 108 int32_t maxDisplayPriority_ = 0; 109 int32_t validSizeCount_ = 0; 110 FlexAlign crossAxisAlign_ = FlexAlign::FLEX_START; 111 FlexAlign mainAxisAlign_ = FlexAlign::FLEX_START; 112 113 std::map<int32_t, std::list<MagicLayoutNode>> magicNodes_; 114 std::map<int32_t, float> magicNodeWeights_; 115 std::list<MagicLayoutNode> secondaryMeasureList_; 116 std::list<RefPtr<LayoutWrapper>> outOfLayoutChildren_; 117 118 FlexDirection direction_ = FlexDirection::ROW; 119 friend class LinearLayoutUtils; 120 BaselineProperties baselineProperties_; 121 bool isLinearLayoutFeature_ = false; 122 bool isInfiniteLayout_ = false; 123 bool selfAdaptive_ = false; 124 TextDirection textDir_ = TextDirection::LTR; 125 bool childrenHasAlignSelfBaseLine_ = false; 126 127 ACE_DISALLOW_COPY_AND_MOVE(FlexLayoutAlgorithm); 128 }; 129 } // namespace OHOS::Ace::NG 130 131 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_FLEX_FLEX_LAYOUT_ALGORITHM_H 132