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_GRID_GRID_LAYOUT_INFO_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_INFO_H 18 19 #include <map> 20 #include <optional> 21 22 #include "base/geometry/axis.h" 23 #include "base/geometry/ng/rect_t.h" 24 #include "core/components/scroll/scroll_controller_base.h" 25 26 namespace OHOS::Ace::NG { 27 28 // Try not to add more variables in [GridLayoutInfo] because the more state variables, the more problematic and the 29 // harder it is to maintain 30 struct GridLayoutInfo { GetTotalHeightOfItemsInViewGridLayoutInfo31 float GetTotalHeightOfItemsInView(float mainGap) 32 { 33 float lengthOfItemsInViewport = 0.0; 34 for (auto i = startMainLineIndex_; i <= endMainLineIndex_; i++) { 35 if (GreatOrEqual(lineHeightMap_[i], 0)) { 36 lengthOfItemsInViewport += (lineHeightMap_[i] + mainGap); 37 } 38 } 39 return lengthOfItemsInViewport - mainGap; 40 } 41 UpdateStartIndexByStartLineGridLayoutInfo42 void UpdateStartIndexByStartLine() 43 { 44 auto startLine = gridMatrix_.find(startMainLineIndex_); 45 if (startLine == gridMatrix_.end()) { 46 return; 47 } 48 if (startLine->second.empty()) { 49 return; 50 } 51 startIndex_ = startLine->second.begin()->second; 52 } 53 54 void UpdateEndLine(float mainSize, float mainGap); 55 56 void SwapItems(int32_t itemIndex, int32_t insertIndex); 57 int32_t GetOriginalIndex() const; 58 void ClearDragState(); 59 GetAverageLineHeightGridLayoutInfo60 float GetAverageLineHeight() 61 { 62 float totalHeight = 0; 63 int32_t totalRow = 0; 64 for (const auto& record : lineHeightMap_) { 65 if (record.second > 0) { 66 totalRow++; 67 totalHeight += record.second; 68 } 69 } 70 return totalRow > 0 ? totalHeight / totalRow : 0; 71 } 72 73 // should only be used when all children of Grid are in gridMatrix_ GetStartLineOffsetGridLayoutInfo74 float GetStartLineOffset(float mainGap) const 75 { 76 float totalHeight = 0; 77 for (auto iter = lineHeightMap_.begin(); iter != lineHeightMap_.end() && iter->first < startMainLineIndex_; 78 ++iter) { 79 totalHeight += (iter->second + mainGap); 80 } 81 return totalHeight - currentOffset_; 82 } 83 ResetPositionFlagsGridLayoutInfo84 void ResetPositionFlags() 85 { 86 reachEnd_ = false; 87 reachStart_ = false; 88 offsetEnd_ = false; 89 } 90 IsResettedGridLayoutInfo91 bool IsResetted() const 92 { 93 return startIndex_ != 0 && gridMatrix_.empty(); 94 } 95 SetScrollAlignGridLayoutInfo96 void SetScrollAlign(ScrollAlign align) 97 { 98 scrollAlign_ = align; 99 } 100 101 Axis axis_ = Axis::VERTICAL; 102 103 float currentOffset_ = 0.0f; 104 float prevOffset_ = 0.0f; 105 float lastMainSize_ = 0.0f; 106 float totalHeightOfItemsInView_ = 0.0f; 107 108 std::optional<int32_t> lastCrossCount_; 109 // index of first and last GridItem in viewport 110 int32_t startIndex_ = 0; 111 int32_t endIndex_ = -1; 112 113 // index of first row and last row in viewport (assuming it's a vertical Grid) 114 int32_t startMainLineIndex_ = 0; 115 int32_t endMainLineIndex_ = 0; 116 117 int32_t jumpIndex_ = -1; 118 int32_t crossCount_ = 0; 119 int32_t childrenCount_ = 0; 120 ScrollAlign scrollAlign_ = ScrollAlign::AUTO; 121 122 bool reachEnd_ = false; 123 bool reachStart_ = false; 124 125 bool offsetEnd_ = false; 126 127 // Map structure: [mainIndex, [crossIndex, index]], 128 // when vertical, mainIndex is rowIndex and crossIndex is columnIndex. 129 std::map<int32_t, std::map<int32_t, int32_t>> gridMatrix_; 130 // in vertical grid, this map is like: [rowIndex: rowHeight] 131 std::map<int32_t, float> lineHeightMap_; 132 133 // Map structure: [index, last cell] 134 std::map<int32_t, int32_t> irregularItemsPosition_; 135 136 // rect of grid item dragged in 137 RectF currentRect_; 138 139 // Grid has GridItem whose columnEnd - columnStart > 0 140 bool hasBigItem_; 141 142 private: 143 int32_t GetItemIndexByPosition(int32_t position); 144 int32_t GetPositionByItemIndex(int32_t itemIndex); 145 void MoveItemsBack(int32_t from, int32_t to, int32_t itemIndex); 146 void MoveItemsForward(int32_t from, int32_t to, int32_t itemIndex); 147 int32_t currentMovingItemPosition_ = -1; 148 std::map<int32_t, int32_t> positionItemIndexMap_; 149 }; 150 151 } // namespace OHOS::Ace::NG 152 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GRID_GRID_LAYOUT_ALGORITHM_H 153