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_LAYOUT_INFO_BASE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_INFO_BASE_H 18 19 #include "base/memory/ace_type.h" 20 #include "base/utils/noncopyable.h" 21 #include "core/components/scroll/scroll_controller_base.h" 22 #include "core/components_ng/pattern/scrollable/scrollable.h" 23 #include "core/components_ng/pattern/waterflow/water_flow_sections.h" 24 #include "core/components_ng/property/measure_property.h" 25 26 namespace OHOS::Ace::NG { 27 constexpr int32_t EMPTY_JUMP_INDEX = -2; 28 29 enum class WaterFlowLayoutMode; 30 31 class WaterFlowLayoutInfoBase : public AceType { 32 DECLARE_ACE_TYPE(WaterFlowLayoutInfoBase, AceType); 33 34 public: 35 WaterFlowLayoutInfoBase() = default; 36 ~WaterFlowLayoutInfoBase() override = default; 37 38 /* Factory method */ 39 static RefPtr<WaterFlowLayoutInfoBase> Create(WaterFlowLayoutMode mode); 40 41 /* PURE GETTERs */ 42 virtual WaterFlowLayoutMode Mode() const = 0; 43 virtual float Offset() const = 0; // total offset of content 44 virtual int32_t FirstIdx() const = 0; // for compatibility 45 46 virtual void UpdateOffset(float delta) = 0; 47 48 /** 49 * @brief try calibrating total offset to an accurate value. 50 * 51 * @return amount of adjustment to total offset of content 52 */ 53 virtual float CalibrateOffset() = 0; 54 55 /** 56 * @brief Get which cross-axis lane the item is in. 57 * 58 * @param itemIndex 59 * @return lane index 60 */ 61 virtual int32_t GetCrossIndex(int32_t itemIndex) const = 0; 62 63 // implementation of WaterFlowPattern::GetOverScrollOffset 64 // returns the portion of [delta] that's in overScroll range 65 virtual OverScrollOffset GetOverScrolledDelta(float delta) const = 0; 66 67 /** 68 * @param mainSize of viewport. 69 * @param delta change in content offset. 70 * @return amount of overScroll (distance to edge) after applying delta. 71 */ 72 virtual float CalcOverScroll(float mainSize, float delta) const = 0; 73 74 /** 75 * @brief Check if WaterFlow just reached content top from the recent layout. 76 * For triggering events. 77 * 78 * @param prevPos previous layout position. 79 * @param firstLayout check this to emit ReachStart on the initial layout. 80 * @return true if current position just reached content top. 81 */ 82 virtual bool ReachStart(float prevPos, bool firstLayout) const = 0; 83 /** 84 * @brief Check if WaterFlow just reached content bottom from the recent layout. 85 * For triggering events. 86 * 87 * @param prevPos previous layout position. 88 * @return true if current position just reached content bottom. 89 */ 90 virtual bool ReachEnd(float prevPos, bool firstLayout) const = 0; 91 92 virtual bool OutOfBounds() const = 0; 93 94 /** 95 * @return total height of all recorded items. 96 */ 97 virtual float GetContentHeight() const = 0; 98 99 /** 100 * @brief Get target item's position in order to perform scrollTo animation. 101 * 102 * @param idx item's index. 103 * @param crossIdx item's cross-axis lane index. 104 * @return absolute position to scroll to. 105 */ 106 virtual float CalcTargetPosition(int32_t idx, int32_t crossIdx) const = 0; 107 108 /** 109 * @return change in position, comparing to [prevPos] 110 */ 111 virtual float GetDelta(float prevPos) const = 0; 112 113 virtual int32_t GetMainCount() const = 0; 114 virtual int32_t GetCrossCount() const = 0; 115 116 /* ======== provide position info for spring effect animation ========= */ 117 virtual float CurrentPos() const = 0; 118 /** 119 * @return final position to bounce back to after over-scrolling from top. 120 */ 121 virtual float TopFinalPos() const = 0; 122 /** 123 * @param viewHeight height of the viewport. 124 * @return final position to bounce back to after over-scrolling from bottom. 125 */ 126 virtual float BottomFinalPos(float viewHeight) const = 0; 127 /* ========================================== */ 128 129 virtual void Reset() = 0; 130 131 // for compatibility UpdateStartIndex()132 virtual void UpdateStartIndex() {}; 133 134 /** 135 * @brief Check if the layout is misaligned. 136 * 137 * If we jump and scroll back to top, the staring items might not be aligned with the top boundary. 138 * @return true if 1. any lane misaligned with top boundary. 139 * 2. the first item is not in the first lane. 140 */ 141 virtual bool IsMisaligned() const = 0; 142 143 /** 144 * @brief Initialize variables based on incoming section data. 145 * 146 * @param sections section data. 147 * @param start first updated section. 148 */ 149 virtual void InitSegments(const std::vector<WaterFlowSections::Section>& sections, int32_t start) = 0; 150 151 /** 152 * @brief Get the Segment index of a FlowItem 153 * 154 * @param itemIdx 155 * @return segment index, guaranteed within range [0, total sections). 156 */ 157 int32_t GetSegment(int32_t itemIdx) const; 158 159 // convert FlowItem's index to children node index. NodeIdx(int32_t idx)160 inline int32_t NodeIdx(int32_t idx) const 161 { 162 return idx + footerIndex_ + 1; 163 } 164 165 /** 166 * @brief obtain true total number of FlowItems by filtering out the footer node. 167 */ ItemCnt(int32_t childrenCount)168 inline int32_t ItemCnt(int32_t childrenCount) const 169 { 170 return childrenCount - footerIndex_ - 1; 171 } 172 173 /** 174 * @brief Initialize margin of each section, along with segmentStartPos_, which depends on margin_. 175 * 176 * @param sections vector of Sections info. 177 * @param scale for calculating margins in PX. 178 * @param percentWidth for calculating margins in PX. 179 */ 180 void InitMargins( 181 const std::vector<WaterFlowSections::Section>& sections, const ScaleProperty& scale, float percentWidth); 182 183 virtual void NotifyDataChange(int32_t index, int32_t count) = 0; 184 virtual void InitSegmentsForKeepPositionMode(const std::vector<WaterFlowSections::Section>& sections, 185 const std::vector<WaterFlowSections::Section>& prevSections, int32_t start) = 0; 186 187 void UpdateDefaultCachedCount(); 188 189 bool itemStart_ = false; 190 /** 191 * @brief last item is partially in viewport. 192 * With footer, footer should be considered the last item. 193 */ 194 bool itemEnd_ = false; 195 bool offsetEnd_ = false; // last item's bottom is in viewport 196 bool isDataValid_ = true; 197 198 Axis axis_ = Axis::VERTICAL; 199 200 int32_t jumpIndex_ = EMPTY_JUMP_INDEX; 201 ScrollAlign align_ = ScrollAlign::START; 202 std::optional<int32_t> targetIndex_; 203 std::optional<float> extraOffset_; 204 205 int32_t startIndex_ = 0; 206 int32_t endIndex_ = -1; 207 int32_t footerIndex_ = -1; 208 209 float lastMainSize_ = 0.0f; 210 211 // store offset for distributed migration 212 float storedOffset_ = 0.0f; 213 float restoreOffset_ = 0.0f; 214 215 // Stores the tail item index of each segment. 216 std::vector<int32_t> segmentTails_; 217 // K: item index; V: corresponding segment index 218 mutable std::unordered_map<int32_t, int32_t> segmentCache_; 219 // margin of each segment 220 std::vector<PaddingPropertyF> margins_; 221 // default cached count 222 int32_t defCachedCount_ = 1; 223 224 ACE_DISALLOW_COPY_AND_MOVE(WaterFlowLayoutInfoBase); 225 }; 226 227 } // namespace OHOS::Ace::NG 228 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WATERFLOW_WATER_FLOW_LAYOUT_INFO_BASE_H 229