1 /* 2 * Copyright (c) 2024 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_WATERFLOW_WATER_FLOW_SEGMENTED_LAYOUT_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_SEGMENTED_LAYOUT_H 18 19 #include "core/components_ng/pattern/waterflow/layout/top_down/water_flow_layout_info.h" 20 #include "core/components_ng/pattern/waterflow/layout/water_flow_layout_algorithm_base.h" 21 #include "core/components_ng/pattern/waterflow/water_flow_layout_property.h" 22 23 namespace OHOS::Ace::NG { 24 // inherited by SegmentedLayout and SWLayout 25 class WaterFlowSegmentLayoutBase : public WaterFlowLayoutBase { 26 DECLARE_ACE_TYPE(WaterFlowSegmentLayoutBase, WaterFlowLayoutBase); 27 28 protected: 29 /** 30 * @brief init member variables for segmented WaterFlow with section info. 31 * 32 * @param options vector of SectionInfo 33 * @param margins of each section. 34 * @param frameSize of WaterFlow. 35 */ 36 void SegmentedInit(const std::vector<WaterFlowSections::Section>& options, 37 const std::vector<PaddingPropertyF>& margins, const SizeF& frameSize); 38 39 /** 40 * @brief Check if Sections info align with actual children and if internal data structures are consistent. 41 */ 42 static bool IsSectionValid(const RefPtr<WaterFlowLayoutInfoBase>& info, int32_t childrenCnt); 43 44 LayoutWrapper* wrapper_ {}; 45 Axis axis_ = Axis::VERTICAL; 46 // [segmentIdx, [crossIdx, item's width]] 47 std::vector<std::vector<float>> itemsCrossSize_; 48 49 // rowGap and columnGap for each segment 50 std::vector<float> crossGaps_; 51 std::vector<float> mainGaps_; 52 }; 53 54 class WaterFlowSegmentedLayout : public WaterFlowSegmentLayoutBase { 55 DECLARE_ACE_TYPE(WaterFlowSegmentedLayout, WaterFlowSegmentLayoutBase); 56 57 public: WaterFlowSegmentedLayout(const RefPtr<WaterFlowLayoutInfo> & layoutInfo)58 explicit WaterFlowSegmentedLayout(const RefPtr<WaterFlowLayoutInfo>& layoutInfo) : info_(layoutInfo) {} 59 ~WaterFlowSegmentedLayout() override = default; 60 61 void Measure(LayoutWrapper* layoutWrapper) override; 62 63 void Layout(LayoutWrapper* layoutWrapper) override; 64 SetCanOverScroll(bool value)65 void SetCanOverScroll(bool value) override 66 { 67 overScroll_ = value; 68 } 69 70 bool PreloadItem(LayoutWrapper* host, int32_t itemIdx, int64_t deadline) override; 71 72 private: 73 /** 74 * @brief Initialize member variables from LayoutProperty. 75 * 76 * @param frameSize of WaterFlow component. 77 */ 78 void Init(const SizeF& frameSize); 79 80 /** 81 * @brief check if any items in view have changed height. 82 * 83 * @return index of the first dirty item. -1 if no dirty item found. 84 */ 85 int32_t CheckDirtyItem() const; 86 87 /** 88 * @brief init regular WaterFlow with a single segment. 89 * 90 * @param frameSize 91 */ 92 void RegularInit(const SizeF& frameSize); 93 void InitFooter(float crossSize); 94 95 /** 96 * @brief Measure self after measuring children. Only when pre-measure failed. 97 * 98 * @param size ideal content size from parent. 99 */ 100 void PostMeasureSelf(SizeF size); 101 102 void MeasureOnOffset(); 103 104 /** 105 * @brief Fills the viewport with new items. 106 * 107 * WaterFlow's item map only supports orderly forward layout, 108 * because the position of a new item always depends on previous items. 109 * 110 * @param startIdx index of the first new FlowItem. 111 */ 112 void Fill(int32_t startIdx); 113 114 /** 115 * @brief Obtain sizes of new FlowItems up to [targetIdx] and record them in ItemMap. 116 * 117 * If user has defined a size for any FlowItem, use that size instead of calling child->Measure. 118 * 119 * @param targetIdx index of the last FlowItem to measure. 120 * @param cacheDeadline when called during a cache layout, return early if deadline is reached. 121 * @param force explicitly measure items even if their heights are user-defined. 122 */ 123 void MeasureToTarget(int32_t targetIdx, std::optional<int64_t> cacheDeadline, bool force = false); 124 125 /** 126 * @brief Helper to measure a single FlowItems. 127 * 128 * @param props LayoutProps. 129 * @param idx index of the FlowItem. 130 * @param crossIdx column (when vertical) index of the target FlowItem. 131 * @param userDefMainSize user-defined main-axis size of the FlowItem. 132 * @return LayoutWrapper of the FlowItem. 133 */ 134 RefPtr<LayoutWrapper> MeasureItem(const RefPtr<WaterFlowLayoutProperty>& props, int32_t idx, int32_t crossIdx, 135 float userDefMainSize, bool isCache) const; 136 137 /** 138 * @brief Layout a FlowItem at [idx]. 139 * 140 * @param idx FlowItem index. 141 * @param padding top-left padding of WaterFlow component. 142 * @param isReverse need to layout in reverse. 143 */ 144 void LayoutItem(int32_t idx, float crossPos, const OffsetF& padding, bool isReverse); 145 146 void MeasureOnJump(int32_t jumpIdx); 147 148 /** 149 * @brief Parse AUTO align value. If jump item is above viewport, use START; if it's below viewport, use END. 150 * 151 * @param item ItemInfo of the FlowItem to jump to. 152 * @return transformed ScrollAlign value. 153 */ 154 ScrollAlign TransformAutoScroll(const WaterFlowLayoutInfo::ItemInfo& item) const; 155 156 /** 157 * @brief Calculate the new offset after jumping to the target item. 158 * 159 * @param item ItemInfo of the FlowItem to jump to. 160 * @return new offset after jumping. 161 */ 162 float SolveJumpOffset(const WaterFlowLayoutInfo::ItemInfo& item) const; 163 164 void SyncPreloadItem(LayoutWrapper* host, int32_t itemIdx) override; 165 166 RefPtr<WaterFlowSections> sections_; 167 168 // WaterFlow node's main-axis length 169 float mainSize_ = 0.0f; 170 171 // offset to apply after a ResetAndJump 172 std::optional<float> postJumpOffset_; 173 174 RefPtr<WaterFlowLayoutInfo> info_; 175 176 // true if WaterFlow can be overScrolled 177 bool overScroll_ = false; 178 179 ACE_DISALLOW_COPY_AND_MOVE(WaterFlowSegmentedLayout); 180 }; 181 } // namespace OHOS::Ace::NG 182 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_SEGMENTED_LAYOUT_H 183