1 /* 2 * Copyright (c) 2022-2023 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_LIST_LIST_ITEM_GROUP_LAYOUT_ALGORITHM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_ITEM_GROUP_LAYOUT_ALGORITHM_H 18 19 #include <optional> 20 #include "base/geometry/axis.h" 21 #include "core/components_ng/layout/layout_algorithm.h" 22 #include "core/components_ng/layout/layout_wrapper.h" 23 #include "core/components_ng/pattern/list/list_layout_property.h" 24 #include "core/components_v2/list/list_properties.h" 25 26 namespace OHOS::Ace::NG { 27 28 // TextLayoutAlgorithm acts as the underlying text layout. 29 class ACE_EXPORT ListItemGroupLayoutAlgorithm : public LayoutAlgorithm { 30 DECLARE_ACE_TYPE(ListItemGroupLayoutAlgorithm, LayoutAlgorithm); 31 public: 32 using PositionMap = std::map<int32_t, std::pair<float, float>>; 33 34 static const int32_t LAST_ITEM = -1; 35 ListItemGroupLayoutAlgorithm(int32_t headerIndex,int32_t footerIndex,int32_t itemStartIndex)36 ListItemGroupLayoutAlgorithm(int32_t headerIndex, int32_t footerIndex, int32_t itemStartIndex) 37 :headerIndex_(headerIndex), footerIndex_(footerIndex), itemStartIndex_(itemStartIndex) {} 38 39 void Measure(LayoutWrapper* layoutWrapper) override; 40 41 void Layout(LayoutWrapper* layoutWrapper) override; 42 GetItemPosition()43 const PositionMap& GetItemPosition() const 44 { 45 return itemPosition_; 46 } 47 SetItemsPosition(const PositionMap & itemPosition)48 void SetItemsPosition(const PositionMap& itemPosition) 49 { 50 itemPosition_ = itemPosition; 51 } 52 GetSpaceWidth()53 float GetSpaceWidth() const 54 { 55 return spaceWidth_; 56 } 57 GetAxis()58 Axis GetAxis() const 59 { 60 return axis_; 61 } 62 GetLanes()63 int32_t GetLanes() const 64 { 65 return lanes_; 66 } 67 GetLaneGutter()68 float GetLaneGutter() const 69 { 70 return laneGutter_; 71 } 72 GetLanesFloor(int32_t index)73 int32_t GetLanesFloor(int32_t index) const 74 { 75 if (lanes_ <= 1) { 76 return index; 77 } 78 return index - index % lanes_; 79 } 80 SetListMainSize(float startPos,float endPos,float referencePos,bool forwardLayout)81 void SetListMainSize(float startPos, float endPos, float referencePos, bool forwardLayout) 82 { 83 startPos_ = startPos; 84 endPos_ = endPos; 85 referencePos_ = referencePos; 86 forwardLayout_ = forwardLayout; 87 } 88 SetListLayoutProperty(RefPtr<ListLayoutProperty> layoutProperty)89 void SetListLayoutProperty(RefPtr<ListLayoutProperty> layoutProperty) 90 { 91 listLayoutProperty_ = std::move(layoutProperty); 92 } 93 SetJumpIndex(int32_t index)94 void SetJumpIndex(int32_t index) 95 { 96 jumpIndex_ = index; 97 } 98 SetTargetIndex(int32_t index)99 void SetTargetIndex(int32_t index) 100 { 101 targetIndex_ = index; 102 } 103 GetStartIndex()104 int32_t GetStartIndex() const 105 { 106 return itemPosition_.empty() ? 0 : itemPosition_.begin()->first; 107 } 108 GetEndIndex()109 int32_t GetEndIndex() const 110 { 111 return itemPosition_.empty() ? 0 : itemPosition_.rbegin()->first; 112 } 113 GetStartPosition()114 float GetStartPosition() const 115 { 116 if (itemPosition_.empty()) { 117 return 0.0f; 118 } 119 if (GetStartIndex() == 0) { 120 return itemPosition_.begin()->second.first; 121 } 122 return itemPosition_.begin()->second.first - spaceWidth_; 123 } 124 GetEndPosition()125 float GetEndPosition() const 126 { 127 if (itemPosition_.empty()) { 128 return 0.0f; 129 } 130 if (GetEndIndex() == totalItemCount_ - 1) { 131 return itemPosition_.rbegin()->second.second; 132 } 133 return itemPosition_.rbegin()->second.second + spaceWidth_; 134 } 135 GetTotalItemCount()136 int32_t GetTotalItemCount() const 137 { 138 return totalItemCount_; 139 } 140 141 float GetChildMaxCrossSize(LayoutWrapper* layoutWrapper, Axis axis); 142 143 void CheckRecycle(const RefPtr<LayoutWrapper>& layoutWrapper, float startPos, float endPos, float referencePos, 144 bool forwardLayout); 145 SetNeedAllLayout()146 void SetNeedAllLayout() 147 { 148 needAllLayout_ = true; 149 } 150 private: 151 float CalculateLaneCrossOffset(float crossSize, float childCrossSize); 152 void UpdateListItemConstraint(const OptionalSizeF& selfIdealSize, LayoutConstraintF& contentConstraint); 153 void LayoutListItem(LayoutWrapper* layoutWrapper, const OffsetF& paddingOffset, float crossSize); 154 void LayoutListItemAll(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, float startPos); 155 void LayoutHeaderFooter(LayoutWrapper* layoutWrapper, const OffsetF& paddingOffset, float crossSize); 156 void LayoutIndex(const RefPtr<LayoutWrapper>& wrapper, const OffsetF& paddingOffset, 157 float crossSize, float startPos); GetListItem(LayoutWrapper * layoutWrapper,int32_t index)158 inline RefPtr<LayoutWrapper> GetListItem(LayoutWrapper* layoutWrapper, int32_t index) const 159 { 160 return layoutWrapper->GetOrCreateChildByIndex(index + itemStartIndex_); 161 } 162 void CalculateLanes(const RefPtr<ListLayoutProperty>& layoutProperty, 163 const LayoutConstraintF& layoutConstraint, std::optional<float> crossSizeOptional, Axis axis); 164 165 void MeasureListItem(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint); 166 int32_t MeasureALineForward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, 167 int32_t& currentIndex, float startPos, float& endPos); 168 int32_t MeasureALineBackward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, 169 int32_t& currentIndex, float endPos, float& startPos); 170 void MeasureForward( 171 LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex, float startPos); 172 void MeasureBackward( 173 LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t endIndex, float endPos); 174 void UpdateReferencePos(RefPtr<LayoutProperty> layoutProperty); 175 bool NeedMeasureItem() const; 176 static void SetListItemIndex(const LayoutWrapper* groupLayoutWrapper, 177 const RefPtr<LayoutWrapper>& itemLayoutWrapper, int32_t indexInGroup); 178 bool IsCardStyleForListItemGroup(const LayoutWrapper* groupLayoutWrapper); 179 float GetListItemGroupMaxWidth(const OptionalSizeF& parentIdealSize, RefPtr<LayoutProperty> layoutProperty); 180 181 bool isCardStyle_ = false; 182 int32_t headerIndex_; 183 int32_t footerIndex_; 184 int32_t itemStartIndex_; 185 RefPtr<ListLayoutProperty> listLayoutProperty_; 186 187 PositionMap itemPosition_; 188 Axis axis_ = Axis::VERTICAL; 189 int32_t lanes_ = 1; 190 float laneGutter_ = 0.0f; 191 std::optional<float> minLaneLength_; 192 std::optional<float> maxLaneLength_; 193 V2::ListItemAlign itemAlign_ = V2::ListItemAlign::START; 194 float spaceWidth_ = 0.0f; 195 196 std::optional<int32_t> jumpIndex_; 197 std::optional<int32_t> targetIndex_; 198 int32_t totalItemCount_ = 0; 199 float totalMainSize_ = 0.0f; 200 float headerMainSize_ = 0.0f; 201 float footerMainSize_ = 0.0f; 202 float startPos_ = 0.0f; 203 float prevStartPos_ = 0.0f; 204 float prevEndPos_ = 0.0f; 205 float endPos_ = 0.0f; 206 float referencePos_ = 0.0f; 207 bool forwardLayout_ = true; 208 bool needAllLayout_ = false; 209 }; 210 } // namespace OHOS::Ace::NG 211 212 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H 213