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_RELATIVE_CONTAINER_RELATIVE_CONTAINER_LAYOUT_ALGORITHM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_RELATIVE_CONTAINER_RELATIVE_CONTAINER_LAYOUT_ALGORITHM_H 18 19 #include <cstdint> 20 #include <map> 21 #include <optional> 22 23 #include "core/components_ng/layout/layout_algorithm.h" 24 #include "core/components_ng/layout/layout_wrapper.h" 25 26 namespace OHOS::Ace::NG { 27 28 using AlignRulesItem = std::map<AlignDirection, AlignRule>; 29 using TwoAlignedValues = std::pair<std::optional<float>, std::optional<float>>; 30 using ChildIdealSize = TwoAlignedValues; 31 using GuidelineParams = std::pair<LineDirection, float>; 32 using BarrierParams = std::pair<BarrierDirection, std::vector<std::string>>; 33 34 35 class ACE_EXPORT RelativeContainerLayoutAlgorithm : public LayoutAlgorithm { 36 DECLARE_ACE_TYPE(RelativeContainerLayoutAlgorithm, LayoutAlgorithm); 37 38 public: 39 RelativeContainerLayoutAlgorithm() = default; 40 ~RelativeContainerLayoutAlgorithm() override = default; 41 42 void Measure(LayoutWrapper* layoutWrapper) override; 43 void Layout(LayoutWrapper* layoutWrapper) override; 44 45 struct ChildMeasureWrapper { 46 RefPtr<LayoutWrapper> layoutWrapper; 47 // used to prevent concatenating tag + id for nodes 48 // who does not have inspector id set in ets 49 std::string id; 50 }; 51 52 struct BarrierRect 53 { 54 float minLeft = Infinity<float>(); 55 float maxRight = 0.0f; 56 float minTop = Infinity<float>(); 57 float maxBottom = 0.0f; 58 }; 59 60 struct ChainParam 61 { 62 std::vector<std::string> ids; 63 std::map<std::string, std::optional<float>> itemSize; 64 AlignRule anchorHead; 65 AlignRule anchorTail; 66 ChainStyle chainStyle; 67 BiasPair bias; 68 float totalChainWeight; 69 float remainingSpace = 0.0f; // default 70 bool isCalculated = false; 71 bool isWeightCalculated = false; 72 }; 73 74 private: 75 void DetermineTopologicalOrder(LayoutWrapper* layoutWrapper); 76 void MeasureSelf(LayoutWrapper* layoutWrapper); 77 void CollectNodesById(LayoutWrapper* layoutWrapper); 78 bool IsAlignRuleInChain(const AlignDirection& direction, const std::string& nodeName); 79 void InsertToReliedOnMap(const std::string& anchorName, const std::string& nodeName); 80 void GetDependencyRelationship(); 81 void GetDependencyRelationshipInChain(const std::string& anchor, const std::string& nodeName); 82 void GetDependencyRelationshipInBarrier(); 83 void CalcHorizontalGuideline(std::optional<CalcSize>& selfIdealSize, float containerHeight, 84 const GuidelineInfo& guidelineInfo); 85 void CalcVerticalGuideline(std::optional<CalcSize>& selfIdealSize, float containerWidth, 86 const GuidelineInfo& guidelineInfo); 87 void CalcGuideline(LayoutWrapper* layoutWrapper); 88 void CalcBarrier(LayoutWrapper* layoutWrapper); 89 bool IsGuideline(const std::string& id); 90 bool IsBarrier(const std::string& id); 91 BarrierRect GetBarrierRectByReferencedIds(const std::vector<std::string>& referencedIds); 92 void MeasureBarrier(const std::string& barrierName); 93 void CheckNodeInHorizontalChain(std::string& currentNode, 94 AlignRulesItem& currentAlignRules, std::vector<std::string>& chainNodes, 95 AlignRule& rightAnchor, float& totalChainWeight); 96 void CheckHorizontalChain(const ChildMeasureWrapper& measureParam); 97 void CheckNodeInVerticalChain(std::string& currentNode, AlignRulesItem& currentAlignRules, 98 std::vector<std::string>& chainNodes, AlignRule& bottomAnchor, float& totalChainWeight); 99 void CheckVerticalChain(const ChildMeasureWrapper& measureParam); 100 void CheckChain(LayoutWrapper* layoutWrapper); 101 void RecordSizeInChain(const std::string& nodeName); 102 bool IsNodeInHorizontalChain(const std::string& nodeName, std::string& chainName); 103 bool IsNodeInVerticalChain(const std::string& nodeName, std::string& chainName); 104 float GetHorizontalAnchorValueByAlignRule(AlignRule& alignRule); 105 float GetVerticalAnchorValueByAlignRule(AlignRule& alignRule); 106 std::pair<float, float> CalcOffsetInChainGetStart(const float& anchorDistance, const float& contentSize, 107 int32_t itemCount, const ChainParam& chainParam, LineDirection direction); 108 void RecordOffsetInChain(float offset, float spaceSize, const std::string& chainName, LineDirection direction); 109 bool CalcOffsetInChain(const std::string& chainName, LineDirection direction); 110 void PreTopologicalLoopDetectionGetAnchorSet( 111 const std::string& nodeName, const AlignRulesItem& alignRulesItem, std::set<std::string>& anchorSet); 112 bool PreTopologicalLoopDetection(); 113 void TopologicalSort(std::list<std::string>& renderList); 114 void CalcSizeParam(LayoutWrapper* layoutWrapper, const std::string& nodeName); 115 void CalcOffsetParam(LayoutWrapper* layoutWrapper, const std::string& nodeName); 116 void CalcHorizontalLayoutParam(AlignDirection alignDirection, const AlignRule& alignRule, 117 LayoutWrapper* layoutWrapper, const std::string& nodeName); 118 void CalcVerticalLayoutParam(AlignDirection alignDirection, const AlignRule& alignRule, 119 LayoutWrapper* layoutWrapper, const std::string& nodeName); 120 float CalcHorizontalOffsetAlignLeft(const HorizontalAlign& alignRule, float& anchorWidth); 121 float CalcHorizontalOffsetAlignMiddle(const HorizontalAlign& alignRule, float& anchorWidth, float& flexItemWidth); 122 float CalcHorizontalOffsetAlignRight(const HorizontalAlign& alignRule, float& anchorWidth, float& flexItemWidth); 123 float CalcHorizontalOffset( 124 AlignDirection alignDirection, const AlignRule& alignRule, float containerWidth, const std::string& nodeName); 125 float CalcVerticalOffsetAlignTop(const VerticalAlign& alignRule, float& anchorHeight); 126 float CalcVerticalOffsetAlignCenter(const VerticalAlign& alignRule, float& anchorHeight, float& flexItemHeight); 127 float CalcVerticalOffsetAlignBottom(const VerticalAlign& alignRule, float& anchorHeight, float& flexItemHeight); 128 float CalcVerticalOffset( 129 AlignDirection alignDirection, const AlignRule& alignRule, float containerHeight, const std::string& nodeName); 130 bool IsValidBias(float bias); 131 void CalcBiasTowDirection(std::pair<TwoAlignedValues, TwoAlignedValues>& alignedValuesOnTwoDirections, 132 ChildIdealSize& childIdealSize, BiasPair& biasPair, float& horizontalOffset, float& verticalOffset); 133 OffsetF CalcBias(const std::string& nodeName); 134 std::pair<TwoAlignedValues, TwoAlignedValues> GetFirstTwoAlignValues(const RefPtr<LayoutWrapper>& childWrapper, 135 const std::unique_ptr<FlexItemProperty>& flexItemProperty, const ChildIdealSize& childIdealSize); 136 void UpdateTwoAlignValues(TwoAlignedValues& twoAlignedValues, AlignRule alignRule, LineDirection direction); 137 void UpdateSizeWhenChildrenEmpty(LayoutWrapper* layoutWrapper); 138 bool IsAnchorLegal(const std::string& anchorName); 139 void MeasureChild(LayoutWrapper* layoutWrapper); 140 void MeasureChainWeight(LayoutWrapper* layoutWrapper); 141 void InitRemainingSpace(const std::string & chainName, LineDirection direction); 142 BarrierDirection BarrierDirectionRtl(BarrierDirection barrierDirection); 143 void CalcChainWeightSize(const std::unique_ptr<FlexItemProperty>& flexItem, 144 LayoutConstraintF& childConstraint, const std::string & chainName, LineDirection direction); 145 bool HasWeight(const std::unique_ptr<FlexItemProperty>& flexItem, LineDirection direction); 146 void AdjustOffsetRtl(LayoutWrapper* layoutWrapper); 147 bool versionGreatorOrEqualToEleven_ = false; 148 bool isHorizontalRelyOnContainer_ = false; 149 bool isVerticalRelyOnContainer_ = false; 150 bool isChainWeightMode_ = false; 151 std::list<std::string> renderList_; 152 std::unordered_map<std::string, ChildMeasureWrapper> idNodeMap_; 153 std::unordered_map<std::string, uint32_t> incomingDegreeMap_; 154 std::unordered_map<std::string, std::set<std::string>> reliedOnMap_; 155 std::unordered_map<std::string, OffsetF> recordOffsetMap_; 156 std::unordered_map<std::string, BarrierParams> barriers_; 157 std::unordered_map<std::string, GuidelineParams> guidelines_; 158 std::unordered_map<std::string, ChainParam> horizontalChains_; 159 std::unordered_map<std::string, ChainParam> verticalChains_; 160 std::unordered_map<std::string, std::string> horizontalChainNodeMap_; 161 std::unordered_map<std::string, std::string> verticalChainNodeMap_; 162 PaddingPropertyF padding_; 163 SizeF containerSizeWithoutPaddingBorder_; 164 }; 165 166 } // namespace OHOS::Ace::NG 167 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_RELATIVE_CONTAINER_RELATIVE_CONTAINER_LAYOUT_ALGORITHM_H