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 struct LayoutedItemInfo { 28 int32_t startIndex = 0; 29 float startPos = 0.0f; 30 int32_t endIndex = 0; 31 float endPos = 0.0f; 32 }; 33 34 // TextLayoutAlgorithm acts as the underlying text layout. 35 class ACE_EXPORT ListItemGroupLayoutAlgorithm : public LayoutAlgorithm { 36 DECLARE_ACE_TYPE(ListItemGroupLayoutAlgorithm, LayoutAlgorithm); 37 public: 38 using PositionMap = std::map<int32_t, std::pair<float, float>>; 39 40 static const int32_t LAST_ITEM = -1; 41 ListItemGroupLayoutAlgorithm(int32_t headerIndex,int32_t footerIndex,int32_t itemStartIndex)42 ListItemGroupLayoutAlgorithm(int32_t headerIndex, int32_t footerIndex, int32_t itemStartIndex) 43 :headerIndex_(headerIndex), footerIndex_(footerIndex), itemStartIndex_(itemStartIndex) {} 44 45 void Measure(LayoutWrapper* layoutWrapper) override; 46 47 void Layout(LayoutWrapper* layoutWrapper) override; 48 GetItemPosition()49 const PositionMap& GetItemPosition() const 50 { 51 return itemPosition_; 52 } 53 SetItemsPosition(const PositionMap & itemPosition)54 void SetItemsPosition(const PositionMap& itemPosition) 55 { 56 itemPosition_ = itemPosition; 57 } 58 59 void ClearItemPosition(LayoutWrapper* layoutWrapper); 60 GetSpaceWidth()61 float GetSpaceWidth() const 62 { 63 return spaceWidth_; 64 } 65 GetAxis()66 Axis GetAxis() const 67 { 68 return axis_; 69 } 70 GetLanes()71 int32_t GetLanes() const 72 { 73 return lanes_; 74 } 75 GetLaneGutter()76 float GetLaneGutter() const 77 { 78 return laneGutter_; 79 } 80 GetLanesFloor(int32_t index)81 int32_t GetLanesFloor(int32_t index) const 82 { 83 if (lanes_ <= 1) { 84 return index; 85 } 86 return index - index % lanes_; 87 } 88 GetLanesCeil(int32_t index)89 int32_t GetLanesCeil(int32_t index) const 90 { 91 int32_t tmpIndex = (lanes_ <= 1) ? index : (index - index % lanes_ + lanes_ - 1); 92 tmpIndex = tmpIndex >= totalItemCount_ ? totalItemCount_ - 1 : tmpIndex; 93 return tmpIndex; 94 } 95 SetListMainSize(float startPos,float endPos,float referencePos,bool forwardLayout)96 void SetListMainSize(float startPos, float endPos, float referencePos, bool forwardLayout) 97 { 98 startPos_ = startPos; 99 endPos_ = endPos; 100 referencePos_ = referencePos; 101 forwardLayout_ = forwardLayout; 102 } 103 SetContentOffset(float contentStartOffset,float contentEndOffset)104 void SetContentOffset(float contentStartOffset, float contentEndOffset) 105 { 106 contentStartOffset_ = contentStartOffset; 107 contentEndOffset_ = contentEndOffset; 108 } 109 SetListLayoutProperty(RefPtr<ListLayoutProperty> layoutProperty)110 void SetListLayoutProperty(RefPtr<ListLayoutProperty> layoutProperty) 111 { 112 listLayoutProperty_ = std::move(layoutProperty); 113 } 114 SetJumpIndex(int32_t index)115 void SetJumpIndex(int32_t index) 116 { 117 jumpIndex_ = index; 118 } 119 SetTargetIndex(int32_t index)120 void SetTargetIndex(int32_t index) 121 { 122 targetIndex_ = index; 123 } 124 GetStartIndex()125 int32_t GetStartIndex() const 126 { 127 return itemPosition_.empty() ? 0 : itemPosition_.begin()->first; 128 } 129 GetEndIndex()130 int32_t GetEndIndex() const 131 { 132 return itemPosition_.empty() ? 0 : itemPosition_.rbegin()->first; 133 } 134 GetStartPosition()135 float GetStartPosition() const 136 { 137 if (itemPosition_.empty()) { 138 return 0.0f; 139 } 140 if (GetStartIndex() == 0) { 141 return itemPosition_.begin()->second.first; 142 } 143 return itemPosition_.begin()->second.first - spaceWidth_; 144 } 145 GetEndPosition()146 float GetEndPosition() const 147 { 148 if (itemPosition_.empty()) { 149 return 0.0f; 150 } 151 if (GetEndIndex() == totalItemCount_ - 1) { 152 return itemPosition_.rbegin()->second.second; 153 } 154 return itemPosition_.rbegin()->second.second + spaceWidth_; 155 } 156 GetTotalItemCount()157 int32_t GetTotalItemCount() const 158 { 159 return totalItemCount_; 160 } 161 162 float GetChildMaxCrossSize(LayoutWrapper* layoutWrapper, Axis axis); 163 164 void CheckRecycle(const RefPtr<LayoutWrapper>& layoutWrapper, float startPos, float endPos, float referencePos, 165 bool forwardLayout); 166 SetNeedAllLayout()167 void SetNeedAllLayout() 168 { 169 needAllLayout_ = true; 170 } 171 SetScrollAlign(ScrollAlign align)172 void SetScrollAlign(ScrollAlign align) 173 { 174 scrollAlign_ = align; 175 } 176 177 std::pair<float, float> GetItemGroupPosition(int32_t index); 178 GetHeaderMainSize()179 float GetHeaderMainSize() const 180 { 181 return headerMainSize_; 182 } 183 GetFooterMainSize()184 float GetFooterMainSize() const 185 { 186 return footerMainSize_; 187 } 188 189 float GetItemHeight(int32_t index); 190 GetItemStartIndex()191 int32_t GetItemStartIndex() 192 { 193 return itemStartIndex_; 194 } 195 SetLayoutedItemInfo(const std::optional<LayoutedItemInfo> & itemInfo)196 void SetLayoutedItemInfo(const std::optional<LayoutedItemInfo>& itemInfo) 197 { 198 layoutedItemInfo_ = itemInfo; 199 } 200 GetLayoutedItemInfo()201 std::optional<LayoutedItemInfo> GetLayoutedItemInfo() const 202 { 203 return layoutedItemInfo_; 204 } 205 206 private: 207 float CalculateLaneCrossOffset(float crossSize, float childCrossSize); 208 void UpdateListItemConstraint(const OptionalSizeF& selfIdealSize, LayoutConstraintF& contentConstraint); 209 void LayoutListItem(LayoutWrapper* layoutWrapper, const OffsetF& paddingOffset, float crossSize); 210 void LayoutListItemAll(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, float startPos); 211 void LayoutHeaderFooter(LayoutWrapper* layoutWrapper, const OffsetF& paddingOffset, float crossSize); 212 void LayoutIndex(const RefPtr<LayoutWrapper>& wrapper, const OffsetF& paddingOffset, 213 float crossSize, float startPos); GetListItem(LayoutWrapper * layoutWrapper,int32_t index)214 inline RefPtr<LayoutWrapper> GetListItem(LayoutWrapper* layoutWrapper, int32_t index) const 215 { 216 return layoutWrapper->GetOrCreateChildByIndex(index + itemStartIndex_); 217 } RecycleListItem(const RefPtr<LayoutWrapper> & layoutWrapper,int32_t index)218 inline void RecycleListItem(const RefPtr<LayoutWrapper>& layoutWrapper, int32_t index) const 219 { 220 layoutWrapper->RemoveChildInRenderTree(index + itemStartIndex_); 221 } 222 void CalculateLanes(const RefPtr<ListLayoutProperty>& layoutProperty, 223 const LayoutConstraintF& layoutConstraint, std::optional<float> crossSizeOptional, Axis axis); 224 225 void MeasureListItem(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint); 226 int32_t MeasureALineForward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, 227 int32_t& currentIndex, float startPos, float& endPos); 228 int32_t MeasureALineBackward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, 229 int32_t& currentIndex, float endPos, float& startPos); 230 int32_t MeasureALineCenter(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, 231 int32_t currentIndex); 232 int32_t MeasureALineAuto(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, 233 int32_t currentIndex); 234 void MeasureForward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, 235 int32_t startIndex, float startPos); 236 void MeasureBackward(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, 237 int32_t endIndex, float endPos); 238 void MeasureJumpToItemForward(LayoutWrapper* layoutWrapper, 239 const LayoutConstraintF& layoutConstraint, int32_t startIndex, float startPos); 240 void MeasureJumpToItemBackward(LayoutWrapper* layoutWrapper, 241 const LayoutConstraintF& layoutConstraint, int32_t endIndex, float endPos); 242 void MeasureCenter(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex); 243 void MeasureStart(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex); 244 void MeasureEnd(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex); 245 void MeasureAuto(LayoutWrapper* layoutWrapper, const LayoutConstraintF& layoutConstraint, int32_t startIndex); 246 float UpdateReferencePos(RefPtr<LayoutProperty> layoutProperty, bool forwardLayout, float referencePos); 247 bool NeedMeasureItem() const; 248 static void SetListItemIndex(const LayoutWrapper* groupLayoutWrapper, 249 const RefPtr<LayoutWrapper>& itemLayoutWrapper, int32_t indexInGroup); 250 bool IsCardStyleForListItemGroup(const LayoutWrapper* groupLayoutWrapper); 251 float GetListItemGroupMaxWidth(const OptionalSizeF& parentIdealSize, RefPtr<LayoutProperty> layoutProperty); 252 void AdjustItemPosition(); 253 254 bool isCardStyle_ = false; 255 int32_t headerIndex_; 256 int32_t footerIndex_; 257 int32_t itemStartIndex_; 258 RefPtr<ListLayoutProperty> listLayoutProperty_; 259 float paddingBeforeContent_ = 0.0f; 260 float paddingAfterContent_ = 0.0f; 261 262 PositionMap itemPosition_; 263 Axis axis_ = Axis::VERTICAL; 264 int32_t lanes_ = 1; 265 float laneGutter_ = 0.0f; 266 std::optional<float> minLaneLength_; 267 std::optional<float> maxLaneLength_; 268 V2::ListItemAlign itemAlign_ = V2::ListItemAlign::START; 269 float spaceWidth_ = 0.0f; 270 271 std::optional<int32_t> jumpIndex_; 272 std::optional<int32_t> targetIndex_; 273 ScrollAlign scrollAlign_ = ScrollAlign::NONE; 274 int32_t totalItemCount_ = 0; 275 float totalMainSize_ = 0.0f; 276 float headerMainSize_ = 0.0f; 277 float footerMainSize_ = 0.0f; 278 float startPos_ = 0.0f; 279 float prevStartPos_ = 0.0f; 280 float prevEndPos_ = 0.0f; 281 float endPos_ = 0.0f; 282 float referencePos_ = 0.0f; 283 float contentStartOffset_ = 0.0f; 284 float contentEndOffset_ = 0.0f; 285 bool forwardLayout_ = true; 286 bool needAllLayout_ = false; 287 288 std::optional<LayoutedItemInfo> layoutedItemInfo_; 289 }; 290 } // namespace OHOS::Ace::NG 291 292 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_LIST_LIST_LAYOUT_ALGORITHM_H 293