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_GRID_GRID_SCROLL_GRID_SCROLL_LAYOUT_ALGORITHM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_SCROLL_GRID_SCROLL_LAYOUT_ALGORITHM_H 18 19 #include "core/components_ng/layout/layout_wrapper.h" 20 #include "core/components_ng/pattern/grid/grid_item_layout_property.h" 21 #include "core/components_ng/pattern/grid/grid_layout_base_algorithm.h" 22 #include "core/components_ng/pattern/grid/grid_layout_info.h" 23 #include "core/components_ng/pattern/grid/grid_layout_property.h" 24 25 namespace OHOS::Ace::NG { 26 27 class ACE_EXPORT GridScrollLayoutAlgorithm : public GridLayoutBaseAlgorithm { 28 DECLARE_ACE_TYPE(GridScrollLayoutAlgorithm, GridLayoutBaseAlgorithm); 29 30 public: GridScrollLayoutAlgorithm(GridLayoutInfo gridLayoutInfo,uint32_t crossCount,uint32_t mainCount)31 GridScrollLayoutAlgorithm(GridLayoutInfo gridLayoutInfo, uint32_t crossCount, uint32_t mainCount) 32 : GridLayoutBaseAlgorithm(std::move(gridLayoutInfo)), crossCount_(crossCount), mainCount_(mainCount) {}; 33 ~GridScrollLayoutAlgorithm() override = default; 34 35 void Measure(LayoutWrapper* layoutWrapper) override; 36 void Layout(LayoutWrapper* layoutWrapper) override; 37 38 static void PrintGridMatrix( 39 const std::map<int32_t, std::map<int32_t, int32_t>>& gridMatrix, const std::map<int32_t, float>& positions); 40 static void PrintLineHeightMap(const std::map<int32_t, float>& lineHeightMap); SetCanOverScroll(bool canOverScroll)41 void SetCanOverScroll(bool canOverScroll) 42 { 43 canOverScroll_ = canOverScroll; 44 } 45 46 protected: 47 void SkipForwardLines(float mainSize, LayoutWrapper* layoutWrapper); 48 void SkipBackwardLines(float mainSize, LayoutWrapper* layoutWrapper); 49 50 private: 51 void FillGridViewportAndMeasureChildren(float mainSize, float crossSize, LayoutWrapper* layoutWrapper); 52 float MeasureRecordedItems(float mainSize, float crossSize, LayoutWrapper* layoutWrapper); 53 bool UseCurrentLines(float mainSize, float crossSize, LayoutWrapper* layoutWrapper, float& mainLength); 54 virtual void SkipLargeOffset(float mainSize, LayoutWrapper* layoutWrapper); 55 56 // fill start of viewport 57 bool FillBlankAtStart(float mainSize, float crossSize, LayoutWrapper* layoutWrapper); 58 float FillNewLineForward(float crossSize, float mainSize, LayoutWrapper* layoutWrapper); 59 void AddForwardLines(int32_t currentIndex, float crossSize, float mainSize, LayoutWrapper* layoutWrapper); 60 void UpdateMatrixForAddedItems(); 61 62 // fill end of viewport 63 void FillBlankAtEnd(float mainSize, float crossSize, LayoutWrapper* layoutWrapper, float& mainLength); 64 float FillNewLineBackward(float crossSize, float mainSize, LayoutWrapper* layoutWrapper, bool reverse); 65 66 // Measure grid item which not exist in grid matrix already, need to place it and save to grid matrix. 67 int32_t MeasureNewChild(const SizeF& frameSize, int32_t itemIndex, LayoutWrapper* layoutWrapper, 68 const RefPtr<LayoutWrapper>& childLayoutWrapper, bool reverse); 69 // Measure grid item which exist in grid matrix already, needn't to place it again. 70 int32_t MeasureChildPlaced(const SizeF& frameSize, int32_t itemIndex, int32_t crossStart, 71 LayoutWrapper* layoutWrapper, const RefPtr<LayoutWrapper>& childLayoutWrapper); 72 void MeasureChild(LayoutWrapper* layoutWrapper, const SizeF& frameSize, 73 const RefPtr<LayoutWrapper>& childLayoutWrapper, int32_t crossStart, int32_t crossSpan); 74 75 // Compote position of grid item in cross axis. 76 float ComputeItemCrossPosition(LayoutWrapper* layoutWrapper, int32_t crossStart) const; 77 virtual void LargeItemLineHeight(const RefPtr<LayoutWrapper>& itemWrapper, bool& hasNormalItem); 78 // Find next valid cell when current is not valid. 79 bool GetNextGrid(int32_t& curMain, int32_t& curCross, bool reverse) const; 80 // Find a valid cell to place grid item and save to grid matrix. 81 bool CheckGridPlaced(int32_t index, int32_t main, int32_t cross, int32_t mainSpan, int32_t crossSpan); 82 LayoutConstraintF CreateChildConstraint(float mainSize, float crossSize, 83 const RefPtr<GridLayoutProperty>& gridLayoutProperty, int32_t crossStart, int32_t crossSpan) const; 84 void ModifyCurrentOffsetWhenReachEnd(float mainSize); 85 void InitialItemsCrossSize( 86 const RefPtr<GridLayoutProperty>& layoutProperty, const SizeF& frameSize, int32_t childrenCount); 87 bool IsIndexInMatrix(int32_t index, int32_t& startLine); 88 void UpdateGridLayoutInfo(LayoutWrapper* layoutWrapper, float mainSize); 89 virtual void GetTargetIndexInfoWithBenchMark( 90 LayoutWrapper* layoutWrapper, bool isTargetBackward, int32_t targetIndex); 91 92 void UpdateOffsetOnVirtualKeyboardHeightChange(LayoutWrapper* layoutWrapper, float mainSize); 93 void AdaptToChildMainSize(LayoutWrapper* layoutWrapper, RefPtr<GridLayoutProperty>& gridLayoutProperty, 94 float mainSize, const SizeF& idealSize); 95 96 int32_t GetStartingItem(LayoutWrapper* layoutWrapper, int32_t currentIndex); 97 98 OffsetF CalculateLargeItemOffset( 99 OffsetF currOffset, int32_t itemIndex, int32_t currLineIndex, int32_t currentCrossIndex); 100 bool NeedAdjust(const RefPtr<GridItemLayoutProperty>& itemLayoutWrapper); 101 virtual void AdjustRowColSpan( 102 const RefPtr<LayoutWrapper>& itemLayoutWrapper, LayoutWrapper* layoutWrapper, int32_t itemIndex); 103 void LargeItemNextLineHeight(int32_t currentLineIndex, LayoutWrapper* layoutWrapper); 104 void LargeItemForwardLineHeight(int32_t currentLineIndex, LayoutWrapper* LayoutWrapper); 105 int32_t CalculateLineIndexForLargeItem(std::map<int32_t, std::map<int32_t, int32_t>>::iterator gridMatrixIter, 106 int32_t currentIndex, int32_t lineIndex, LayoutWrapper* layoutWrapper); 107 void CalculateLineHeightForLargeItem(int32_t lineIndex, int32_t currentLineIndex, 108 std::map<int32_t, std::map<int32_t, int32_t>>::iterator gridMatrixIter, LayoutWrapper* layoutWrapper); 109 void ScrollToIndexStart(LayoutWrapper* layoutWrapper, int32_t targetIndex); 110 void ScrollToIndexAuto(LayoutWrapper* layoutWrapper, float mainSize, int32_t targetIndex); 111 void UpdateCurrentOffsetForJumpTo(LayoutWrapper* layoutWrapper, float mainSize); 112 113 protected: 114 uint32_t crossCount_ = 0; 115 uint32_t mainCount_ = 0; 116 int32_t currentItemRowSpan_ = 0; 117 int32_t currentItemColSpan_ = 0; 118 int32_t currentItemRowStart_ = -1; 119 int32_t currentItemColStart_ = -1; 120 int32_t currentItemRowEnd_ = -1; 121 int32_t currentItemColEnd_ = -1; 122 float cellAveLength_ = -1.0f; 123 124 private: 125 int32_t currentMainLineIndex_ = 0; // it equals to row index in vertical grid 126 int32_t moveToEndLineIndex_ = -1; // place index in the last line when scroll to index after matrix 127 std::map<int32_t, float> itemsCrossSize_; // grid item's size in cross axis. 128 Axis axis_ = Axis::VERTICAL; 129 130 float mainGap_ = 0; 131 float crossGap_ = 0; 132 float crossPaddingOffset_ = 0; 133 int32_t lastCross_ = 0; 134 bool isChildrenUpdated_ = false; 135 136 // Map structure: [index, crossPosition], store cross position of each item. 137 std::map<int32_t, float> itemsCrossPosition_; 138 bool canOverScroll_ = false; 139 140 ACE_DISALLOW_COPY_AND_MOVE(GridScrollLayoutAlgorithm); 141 }; 142 143 } // namespace OHOS::Ace::NG 144 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_SCROLL_GRID_SCROLL_LAYOUT_ALGORITHM_H 145